Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
97c36dd
make install -e work
cattabiani May 26, 2025
fad6ae6
wip
cattabiani May 26, 2025
d1f5220
nodesets in correct folder
cattabiani May 26, 2025
b0b3871
new license?
cattabiani May 26, 2025
48ea649
add compartment_sets_file to SimulationConfig
cattabiani May 26, 2025
543dc90
WIP
cattabiani May 26, 2025
f7d3c0c
empty CompartmentSets. It should pass CI
cattabiani May 27, 2025
5b2bfb4
WIP
cattabiani May 28, 2025
9475c90
before clang-format
cattabiani May 30, 2025
a68a388
formatted, WIP
cattabiani May 30, 2025
bf2b6d9
fix clang-format9?
cattabiani May 30, 2025
bb7ca75
CompartmentLocation
cattabiani Jun 3, 2025
807ce4c
before python api for compartmentSet
cattabiani Jun 3, 2025
b529ff4
WIP decoupled iterator
cattabiani Jun 3, 2025
b993670
WIP
cattabiani Jun 3, 2025
3aed13c
WIP
cattabiani Jun 3, 2025
03b4a39
CompartmentSet ready for python api
cattabiani Jun 4, 2025
4f8e417
added pybinds and tests for CompartmentSet
cattabiani Jun 4, 2025
5566239
Merge branch 'master' into katta/install_dev
cattabiani Jun 4, 2025
e5bd13a
completed detail::CompartmentSets
cattabiani Jun 4, 2025
07a7bf8
add equality CompartmentSet
cattabiani Jun 4, 2025
6b76b22
done ctests
cattabiani Jun 4, 2025
64c0622
done with pytests. no format
cattabiani Jun 4, 2025
02295b5
format?
cattabiani Jun 4, 2025
0bbaa3a
remove test
cattabiani Jun 4, 2025
8f3c6ce
some fixes from Mike
cattabiani Jun 5, 2025
f79a012
format
cattabiani Jun 5, 2025
c56031a
gid -> node_id
cattabiani Jun 5, 2025
bdf9596
format
cattabiani Jun 5, 2025
b84755e
more Mike's comments resolved
cattabiani Jun 5, 2025
d0ac13a
format
cattabiani Jun 5, 2025
4fb9a1b
remove glob
cattabiani Jun 5, 2025
2bce919
fixup! selection.contains: ranges are not sorted for sure
cattabiani Jun 5, 2025
c909944
format
cattabiani Jun 5, 2025
9d76a4c
keys -> names
cattabiani Jun 5, 2025
b91ed52
py::str -> fmt::format
cattabiani Jun 5, 2025
ed789f6
format
cattabiani Jun 5, 2025
d4b729a
remove iter copy and deepcopy
cattabiani Jun 5, 2025
6ada577
CompartmentLocation unification impl and public api
cattabiani Jun 5, 2025
452be67
format
cattabiani Jun 5, 2025
54586c5
values -> getAllCompartmentSets
cattabiani Jun 5, 2025
32f0779
format
cattabiani Jun 5, 2025
4ff96a2
simplify CompartmentLocation to plain struct
cattabiani Jun 6, 2025
bb0353c
format
cattabiani Jun 6, 2025
6208c8e
remove commented code
cattabiani Jun 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ endif()

set(SONATA_SRC
src/common.cpp
src/compartment_sets.cpp
src/config.cpp
src/edge_index.cpp
src/edges.cpp
Expand Down
189 changes: 189 additions & 0 deletions include/bbp/sonata/compartment_sets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
#pragma once

#include <bbp/sonata/nodes.h>

#include <nlohmann/json.hpp>

namespace bbp {
namespace sonata {
namespace detail {
class CompartmentSetFilteredIterator;
class CompartmentSet;
class CompartmentSets;
} // namespace detail

/**
* CompartmentLocation.
*
* This struct uniquely identifies a compartment by a set of node_id, section_index and offset:
*
* - node_id: Global ID of the cell (Neuron) to which the compartment belongs. No
* overlaps among populations.
* - section_index: Absolute section index. Progressive index that uniquely identifies the section.
* There is a mapping between neuron section names (i.e. dend[10]) and this index.
* - offset: Offset of the compartment along the section. The offset is a value between 0 and 1
*
* Note: it cannot go inside CompartmentSet because then CompartmentSetFilteredIterator needs the
* full definition of CompartmentSet and CompartmentSet needs the full definition of
* CompartmentSetFilteredIterator.
*/
struct CompartmentLocation {
public:
uint64_t nodeId = 0;
uint64_t sectionIndex = 0;
double offset = 0.0;

/// Comparator. Used to compare vectors in CompartmentSet. More idiomatic than defining a
/// comaprator on the fly
bool operator==(const CompartmentLocation& other) const {
return nodeId == other.nodeId && sectionIndex == other.sectionIndex &&
offset == other.offset;
}

bool operator!=(const CompartmentLocation& other) const {
return !(*this == other);
}
};

/// Ostream << operator used by catch2 when there are problems for example
inline std::ostream& operator<<(std::ostream& os, const CompartmentLocation& cl) {
os << "CompartmentLocation("
<< "nodeId: " << cl.nodeId << ", "
<< "sectionIndex: " << cl.sectionIndex << ", "
<< "offset: " << cl.offset << ")";
return os;
}

class SONATA_API CompartmentSetFilteredIterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = CompartmentLocation;
using difference_type = std::ptrdiff_t;
using pointer = const CompartmentLocation*;
using reference = const CompartmentLocation&;

explicit CompartmentSetFilteredIterator(
std::unique_ptr<detail::CompartmentSetFilteredIterator> impl);
CompartmentSetFilteredIterator(const CompartmentSetFilteredIterator& other);
CompartmentSetFilteredIterator& operator=(const CompartmentSetFilteredIterator& other);
CompartmentSetFilteredIterator(CompartmentSetFilteredIterator&&) noexcept;
CompartmentSetFilteredIterator& operator=(CompartmentSetFilteredIterator&&) noexcept;
~CompartmentSetFilteredIterator();

const CompartmentLocation& operator*() const;
const CompartmentLocation* operator->() const;

CompartmentSetFilteredIterator& operator++(); // prefix ++
CompartmentSetFilteredIterator operator++(int); // postfix ++
bool operator==(const CompartmentSetFilteredIterator& other) const;
bool operator!=(const CompartmentSetFilteredIterator& other) const;

private:
std::unique_ptr<detail::CompartmentSetFilteredIterator> impl_;
};


/**
* CompartmentSet public API.
*
* This class represents a set of compartment locations associated with a neuron population.
* Each compartment is uniquely defined by a (node_id, section_index, offset) triplet.
* This API supports filtering based on a node_id selection.
*/
class SONATA_API CompartmentSet
{
public:
CompartmentSet() = delete;

explicit CompartmentSet(const std::string& json_content);
explicit CompartmentSet(std::shared_ptr<detail::CompartmentSet>&& impl);

std::pair<CompartmentSetFilteredIterator, CompartmentSetFilteredIterator> filtered_crange(
Selection selection = Selection({})) const;

/// Size of the set, optionally filtered by selection
std::size_t size(const Selection& selection = Selection({})) const;

// Is empty?
bool empty() const;

/// Population name
const std::string& population() const;

/// Access element by index. It returns a copy!
CompartmentLocation operator[](std::size_t index) const;

Selection nodeIds() const;

CompartmentSet filter(const Selection& selection = Selection({})) const;

/// Serialize to JSON string
std::string toJSON() const;

bool operator==(const CompartmentSet& other) const;
bool operator!=(const CompartmentSet& other) const;

private:
std::shared_ptr<detail::CompartmentSet> impl_;
};


/**
* @class CompartmentSets
* @brief A container class that manages a collection of named CompartmentSet objects.
*
* This class provides methods for accessing, querying, and serializing a collection of
* compartment sets identified by string keys. It supports construction from a JSON string
* or a file, and encapsulates its internal implementation using the PIMPL idiom.
*
* The class is non-copyable but movable, and offers value-style accessors for ease of use.
*/
class SONATA_API CompartmentSets
{
public:

CompartmentSets(const std::string& content);
CompartmentSets(std::unique_ptr<detail::CompartmentSets>&& impl);
CompartmentSets(detail::CompartmentSets&& impl);
CompartmentSets(CompartmentSets&&) noexcept;
CompartmentSets(const CompartmentSets& other) = delete;
CompartmentSets& operator=(CompartmentSets&&) noexcept;
~CompartmentSets();

/// Create new CompartmentSets from file. In this way we distinguish from
/// the basic string constructor.
static CompartmentSets fromFile(const std::string& path);

/// Access element by key (throws if not found)
CompartmentSet getCompartmentSet(const std::string& key) const;

/// Number of compartment sets
std::size_t size() const;

/// Is empty?
bool empty() const;

/// Check if key exists
bool contains(const std::string& key) const;

/// Get names of CompartmentSet(s) as a vector
std::vector<std::string> names() const;

/// Get all compartment sets as vector
std::vector<CompartmentSet> getAllCompartmentSets() const;

/// Get items (key + compartment set) as vector of pairs
std::vector<std::pair<std::string, CompartmentSet>> items() const;

/// Serialize all compartment sets to JSON string
std::string toJSON() const;

bool operator==(const CompartmentSets& other) const;
bool operator!=(const CompartmentSets& other) const;

private:
std::unique_ptr<detail::CompartmentSets> impl_;
};

} // namespace sonata
} // namespace bbp
12 changes: 12 additions & 0 deletions include/bbp/sonata/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ class SONATA_API CircuitConfig
*/
const std::string& getNodeSetsPath() const;

/**
* Returns the path to the compartment sets file.
*/
const std::string& getCompartmentSetsPath() const;

/**
* Returns a set with all available population names across all the node networks.
*/
Expand Down Expand Up @@ -782,6 +787,11 @@ class SONATA_API SimulationConfig
*/
const std::string& getNodeSetsFile() const noexcept;

/**
* Returns the path of compartment sets file
*/
const std::string& getCompartmentSetsFile() const noexcept;

/**
* Returns the name of node set to be instantiated for the simulation, default = None
*/
Expand Down Expand Up @@ -828,6 +838,8 @@ class SONATA_API SimulationConfig
SimulatorType _targetSimulator;
// Path of node sets file
std::string _nodeSetsFile;
// Path of compartment sets file
std::string _compartmentSetsFile;
// Name of node set
nonstd::optional<std::string> _nodeSet{nonstd::nullopt};
// Remarks on the simulation
Expand Down
11 changes: 11 additions & 0 deletions include/bbp/sonata/selection.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ class SONATA_API Selection
using Range = std::array<Value, 2>;
using Ranges = std::vector<Range>;

/**
* Create Selection from a list of ranges
* @param ranges is a list of ranges constituting Selection
*/
Selection(Ranges ranges);

template <typename Iterator>
Expand All @@ -40,6 +44,13 @@ class SONATA_API Selection

bool empty() const;

/**
* Check if Selection contains a given node id
* @param node id to check
* @return true if Selection contains the node id, false otherwise
*/
bool contains(Value node_id) const;

private:
Ranges ranges_;
};
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ build-backend = "setuptools.build_meta"

[tool.pytest.ini_options]
testpaths = ["python/tests"]

[tool.setuptools_scm]
version_scheme = "guess-next-dev"
local_scheme = "no-local-version"
1 change: 1 addition & 0 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ target_link_libraries(sonata_python
PRIVATE HighFive
PRIVATE fmt::fmt-header-only
PRIVATE pybind11::module
PRIVATE nlohmann_json::nlohmann_json
)
Loading
Loading