https://github.com/bluebrain/libsonata

A python and C++ interface to the SONATA format

https://github.com/bluebrain/libsonata

Science Score: 23.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
    9 of 25 committers (36.0%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (13.3%) to scientific vocabulary

Keywords

circuit modelling simulation sonata

Keywords from Contributors

neuron morphologies neuroscience reticulum mitochondria glia spack radiuss hpsf build-tools
Last synced: 5 months ago · JSON representation

Repository

A python and C++ interface to the SONATA format

Basic Info
Statistics
  • Stars: 12
  • Watchers: 12
  • Forks: 13
  • Open Issues: 28
  • Releases: 0
Archived
Topics
circuit modelling simulation sonata
Created almost 7 years ago · Last pushed 12 months ago
Metadata Files
Readme Changelog License Authors

README.rst

.. warning::
   The Blue Brain Project concluded in December 2024, so development has ceased under the BlueBrain GitHub organization.
   Future development will take place at: https://github.com/openbraininstitute/libsonata

|banner|

|license| |coverage| |docs|

libsonata
=========

C++ / Python reader for SONATA circuit files:
`SONATA guide `__

Installation
------------

Installing from PyPI
~~~~~~~~~~~~~~~~~~~~

.. code-block:: shell

   pip install libsonata

Installing as a Python package, directly from GitHub
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: shell

   pip install git+https://github.com/BlueBrain/libsonata

Building the C++ library
~~~~~~~~~~~~~~~~~~~~~~~~

.. code-block:: shell

   git clone git@github.com:BlueBrain/libsonata.git --recursive
   cd libsonata
   mkdir build && cd build
   cmake -DCMAKE_BUILD_TYPE=Release -DEXTLIB_FROM_SUBMODULES=ON ..
   make -j

Since `libsonata` uses backports for `std::optional` and `std::variant` which
turn into their actual STL implementation once available, it's recommended to compile
`libsonata` with the same C++ standard as the project linking to `libsonata`. This
is done by passing `-DCMAKE_CXX_STANDARD={14,17}` to the `cmake` command above.

Usage (Python)
--------------

Nodes
~~~~~

NodeStorage
+++++++++++

.. code-block:: pycon

   >>> import libsonata

   >>> nodes = libsonata.NodeStorage('path/to/H5/file')

   # list populations
   >>> nodes.population_names

   # open population
   >>> population = nodes.open_population()


NodePopulation
++++++++++++++

.. code-block:: pycon

   # total number of nodes in the population
   >>> population.size

   # attribute names
   >>> population.attribute_names

   # get attribute value for single node, say 42
   >>> population.get_attribute('mtype', 42)

   # ...or Selection of nodes (see below) => returns NumPy array with corresponding values
   >>> selection = libsonata.Selection(values=[1, 5, 9, 42])  # nodes 1, 5, 9, 42
   >>> mtypes = population.get_attribute('mtype', selection)
   >>> list(zip(selection.flatten(), mtypes))
   [(1, u'mtype_of_1'), (5, u'mtype_of_5'), (9, u'mtype_of_9'), (42, u'mtype_of_42')]


Selection
+++++++++

List of element IDs (either `node_id`, or `edge_id`) where adjacent IDs are grouped for the sake of efficient HDF5 file access.
For instance, `{1, 2, 3, 5}` sequence becomes `{[1, 4), [5, 6)}`.

`Selection` can be instantiated from:
 - a sequence of scalar values (works for NumPy arrays as well)
 - a sequence of pairs (interpreted as ranges above, works for N x 2 NumPy arrays as well)

`EdgePopulation` connectivity queries (see below) return ``Selection``\ s as well.

.. code-block:: pycon

   >>> selection = libsonata.Selection([1, 2, 3, 5])
   >>> selection.ranges
   [(1, 4), (5, 6)]


.. code-block:: pycon

   >>> selection = libsonata.Selection([(1, 4), (5, 6)])
   >>> selection.flatten()
   [1, 2, 3, 5]
   >>> selection.flat_size
   4
   >>> bool(selection)
   True


Node Sets
+++++++++

libsonata can work with the Node Set concept, as described here: `SONATA guide: Node Sets File `__
This allows the definition of names for groups of cells, and a way to query them.
libsonata also allows for extended expressions, such as Regular expressions,and floating point tests, as described here: `SONATA extension: Node Sets `__

.. code-block:: pycon

   # load a node set JSON file
   >>> node_sets = libsonata.NodeSets.from_file('node_sets.json')

   # list node sets
   >>> node_sets.names
   {'L6_UPC', 'Layer1', 'Layer2', 'Layer3', ....}

   # get the selection of nodes that match in population
   >>> selection = node_sets.materialize('Layer1', population)

   # node sets can also be loaded from a JSON string
   >>> node_sets_manual = libsonata.NodeSets(json.dumps({"SLM_PPA_and_SP_PC": {"mtype": ["SLM_PPA", "SP_PC"]}}))
   >>> node_sets_manual.names
   {'SLM_PPA_and_SP_PC'}


Edges
~~~~~

EdgeStorage
+++++++++++

Population handling for `EdgeStorage` is analogous to `NodeStorage`:

.. code-block:: pycon

   >>> edges = libsonata.EdgeStorage('path/to/H5/file')

   # list populations
   >>> edges.population_names

   # open population
   >>> population = edges.open_population()


EdgePopulation
++++++++++++++

.. code-block:: pycon

   # total number of edges in the population
   >>> population.size

   # attribute names
   >>> population.attribute_names

   # get attribute value for single edge, say 123
   >>> population.get_attribute('delay', 123)

   # ...or Selection of edges => returns NumPy array with corresponding values
   >>> selection = libsonata.Selection([1, 5, 9])
   >>> population.get_attribute('delay', selection) # returns delays for edges 1, 5, 9


...with additional methods for querying connectivity, where the results are selections that can be applied like above

.. code-block:: pycon

   # get source / target node ID for the 42nd edge:
   >>> population.source_node(42)
   >>> population.target_node(42)

   # query connectivity (result is Selection object)
   >>> selection_to_1 = population.afferent_edges(1)  # all edges with target node_id 1
   >>> population.target_nodes(selection_to_1)  # since selection only contains edges
                                                # targeting node_id 1 the result will be a
                                                # numpy array of all 1's
   >>> selection_from_2 = population.efferent_edges(2)  # all edges sourced from node_id 2
   >>> selection = population.connecting_edges(2, 1)  # this selection is all edges from
                                                      # node_id 2 to node_id 1

   # ...or their vectorized analogues
   >>> selection = population.afferent_edges([1, 2, 3])
   >>> selection = population.efferent_edges([1, 2, 3])
   >>> selection = population.connecting_edges([1, 2, 3], [4, 5, 6])


Reports
~~~~~~~

SpikeReader
+++++++++++

.. code-block:: pycon

   >>> import libsonata

   >>> spikes = libsonata.SpikeReader('path/to/H5/file')

   # list populations
   >>> spikes.get_population_names()

   # open population
   >>> population = spikes['']


SpikePopulation
+++++++++++++++

.. code-block:: pycon

   # get all spikes [(node_id, timestep)]
   >>> population.get()
   [(5, 0.1), (2, 0.2), (3, 0.3), (2, 0.7), (3, 1.3)]

   # get all spikes betwen tstart and tstop
   >>> population.get(tstart=0.2, tstop=1.0)
   [(2, 0.2), (3, 0.3), (2, 0.7)]

   # get spikes attribute sorting (by_time, by_id, none)
   >>> population.sorting
   'by_time'

   Pandas can be used to create a dataframe and get a better representation of the data

.. code-block:: pycon

   >>> import pandas

   data = population.get()
   df = pandas.DataFrame(data=data, columns=['ids', 'times']).set_index('times')
   print(df)
          ids
   times
   0.1      5
   0.2      2
   0.3      3
   0.7      2
   1.3      3


SomaReportReader
++++++++++++++++

.. code-block:: pycon

   >>> somas = libsonata.SomaReportReader('path/to/H5/file')

   # list populations
   >>> somas.get_population_names()

   # open population
   >>> population_somas = somas['']


SomaReportPopulation
++++++++++++++++++++

.. code-block:: pycon

   # get times (tstart, tstop, dt)
   >>> population_somas.times
   (0.0, 1.0, 0.1)

   # get unit attributes
   >>> population_somas.time_units
   'ms'
   >>> population_somas.data_units
   'mV'

   # node_ids sorted?
   >>> population_somas.sorted
   True

   # get a list of all node ids in the selected population
   >>> population_somas.get_node_ids()
   [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

   # get the DataFrame of the node_id values for the timesteps between tstart and tstop
   >>> data_frame = population_somas.get(node_ids=[13, 14], tstart=0.8, tstop=1.0)

   # get the data values
   >>> data_frame.data
   [[13.8, 14.8], [13.9, 14.9]]

   # get the list of timesteps
   >>> data_frame.times
   [0.8, 0.9]

   # get the list of node ids
   >>> data_frame.ids
   [13, 14]


Once again, pandas can be used to create a dataframe using the data, ids and times lists

.. code-block:: pycon

   >>> import pandas

   df = pandas.DataFrame(data_frame.data, columns=data_frame.ids, index=data_frame.times)
   print(df)
          13    14
   0.8  13.8  14.8
   0.9  13.9  14.9


ElementReportReader
+++++++++++++++++++

.. code-block:: pycon

   >>> elements = libsonata.ElementReportReader('path/to/H5/file')

   # list populations
   >>> elements.get_population_names()

   # open population
   >>> population_elements = elements['']


ElementReportPopulation
+++++++++++++++++++++++

.. code-block:: pycon

   # get times (tstart, tstop, dt)
   >>> population_elements.times
   (0.0, 4.0, 0.2)

   >>> population_elements.get_node_ids()
   [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

   # get the DataFrame of the node_id values for the timesteps between tstart and tstop
   >>> data_frame = population_elements.get(node_ids=[13, 14], tstart=0.8, tstop=1.0)

   # get the data values (list of list of floats with data[time_index][element_index])
   >>> data_frame.data
   [[46.0, 46.1, 46.2, 46.3, 46.4, 46.5, 46.6, 46.7, 46.8, 46.9], [56.0, 56.1, 56.2, 56.3, 56.4, 56.5, 56.6, 56.7, 56.8, 56.9]]

   # get the list of timesteps
   >>> data_frame.times
   [0.8, 1.0]

   # get the list of (node id, element_id)
   >>> data_frame.ids
   [(13, 30), (13, 30), (13, 31), (13, 31), (13, 32), (14, 32), (14, 33), (14, 33), (14, 34), (14, 34)]


The same way than with spikes and soma reports, pandas can be used to get a better representation of the data

.. code-block:: pycon

   >>> import pandas

   df = pandas.DataFrame(data_frame.data, columns=pandas.MultiIndex.from_tuples(data_frame.ids), index=data_frame.times)
   print(df)
          13                            14
          30    30    31    31    32    32    33    33    34    34
   0.8  46.0  46.1  46.2  46.3  46.4  46.5  46.6  46.7  46.8  46.9
   1.0  56.0  56.1  56.2  56.3  56.4  56.5  56.6  56.7  56.8  56.9

For big datasets, using numpy arrays could greatly improve the performance

.. code-block:: pycon

   >>> import numpy

   np_data = numpy.asarray(data_frame.data)
   np_ids = numpy.asarray(data_frame.ids).T
   np_times = numpy.asarray(data_frame.times)

   df = pandas.DataFrame(np_data, columns=pandas.MultiIndex.from_arrays(np_ids), index=np_times)


Acknowledgements
----------------
The development of this software was supported by funding to the Blue Brain Project, a research center of the École polytechnique fédérale de Lausanne (EPFL), from the Swiss government’s ETH Board of the Swiss Federal Institutes of Technology.

This research was supported by the EBRAINS research infrastructure, funded from the European Union’s Horizon 2020 Framework Programme for Research and Innovation under the Specific Grant Agreement No. 945539 (Human Brain Project SGA3).
This project/research has received funding from the European Union’s Horizon 2020 Framework Programme for Research and Innovation under the Specific Grant Agreement No. 785907 (Human Brain Project SGA2).


License
-------

libsonata is distributed under the terms of the GNU Lesser General Public License version 3,
unless noted otherwise, for example, for external dependencies.
Refer to `COPYING.LESSER` and `COPYING` files for details.

Copyright (c) 2018-2022 Blue Brain Project/EPFL

libsonata is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
as published by the Free Software Foundation.

libsonata is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with libsonata.  If not, see .


.. |license| image:: https://img.shields.io/pypi/l/libsonata
                :target: https://github.com/BlueBrain/libsonata/blob/master/COPYING.LESSER

.. |coverage| image:: https://coveralls.io/repos/github/BlueBrain/libsonata/badge.svg
                 :target: https://coveralls.io/github/BlueBrain/libsonata

.. |docs| image:: https://readthedocs.org/projects/libsonata/badge/?version=latest
             :target: https://libsonata.readthedocs.io/
             :alt: documentation status

.. substitutions
.. |banner| image:: docs/source/_images/libSonataLogo.jpg

Owner

  • Name: The Blue Brain Project
  • Login: BlueBrain
  • Kind: organization
  • Email: bbp.opensource@epfl.ch
  • Location: Geneva, Switzerland

Open Source Software produced and used by the Blue Brain Project

GitHub Events

Total
  • Create event: 7
  • Issues event: 2
  • Release event: 1
  • Watch event: 1
  • Delete event: 4
  • Issue comment event: 7
  • Push event: 7
  • Pull request review event: 5
  • Pull request event: 9
  • Fork event: 1
Last Year
  • Create event: 7
  • Issues event: 2
  • Release event: 1
  • Watch event: 1
  • Delete event: 4
  • Issue comment event: 7
  • Push event: 7
  • Pull request review event: 5
  • Pull request event: 9
  • Fork event: 1

Committers

Last synced: about 2 years ago

All Time
  • Total Commits: 247
  • Total Committers: 25
  • Avg Commits per committer: 9.88
  • Development Distribution Score (DDS): 0.555
Past Year
  • Commits: 73
  • Committers: 6
  • Avg Commits per committer: 12.167
  • Development Distribution Score (DDS): 0.507
Top Committers
Name Email Commits
MikeG m****t@e****h 110
Arseny V. Povolotsky a****y@e****h 28
Luc Grosheintz l****z@g****m 27
WeinaJi w****i@e****h 15
Jorge Blanco Alonso 4****a 9
Benoit Coste b****e@e****h 9
Nicolas Cornu n****u@e****h 8
Matthias Wolf m****f@e****h 6
haleepfl 4****l 6
Sergio s****z@e****h 5
Fernando Pereira f****e@g****m 3
Benoit Coste b****e@p****m 3
Matthias Wolf m****t@s****t 3
Arseny V. Povolotsky c****s@y****u 2
Gianluca Ficarelli 2****i 2
Nadir Román Guerrero N****e 2
jdcourcol j****l@e****h 1
Eduard Šubert 6****t 1
Judit j****c 1
asanin-epfl 5****l 1
bbpgithubaudit 8****t 1
tomdele 4****e 1
Julien Francioli j****i@e****h 1
Ioannis Magkanaris i****s@g****m 1
Ankur Sinha s****r@g****m 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 45
  • Total pull requests: 166
  • Average time to close issues: 3 months
  • Average time to close pull requests: 9 days
  • Total issue authors: 18
  • Total pull request authors: 17
  • Average comments per issue: 3.13
  • Average comments per pull request: 1.08
  • Merged pull requests: 138
  • Bot issues: 0
  • Bot pull requests: 1
Past Year
  • Issues: 2
  • Pull requests: 9
  • Average time to close issues: N/A
  • Average time to close pull requests: 2 days
  • Issue authors: 2
  • Pull request authors: 7
  • Average comments per issue: 0.5
  • Average comments per pull request: 0.89
  • Merged pull requests: 4
  • Bot issues: 0
  • Bot pull requests: 1
Top Authors
Issue Authors
  • 1uc (17)
  • mgeplf (8)
  • joni-herttuainen (4)
  • GianlucaFicarelli (1)
  • seirios (1)
  • ferdonline (1)
  • MikeWazoWski123 (1)
  • olupton (1)
  • KeremKurban (1)
  • markovg (1)
  • anilbey (1)
  • sanjayankur31 (1)
  • matz-e (1)
  • a-vartenkov (1)
  • WeinaJi (1)
Pull Request Authors
  • mgeplf (75)
  • 1uc (37)
  • WeinaJi (26)
  • jorblancoa (13)
  • bbpgithubaudit (10)
  • alkino (6)
  • sergiorg-hpc (4)
  • matz-e (4)
  • GianlucaFicarelli (3)
  • tchaikov (2)
  • Adrien4193 (2)
  • musicinmybrain (2)
  • dependabot[bot] (2)
  • edasubert (1)
  • jplanasc (1)
Top Labels
Issue Labels
enhancement (2) bug (1)
Pull Request Labels
WIP (2) dependencies (2)

Packages

  • Total packages: 1
  • Total downloads: unknown
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 0
  • Total maintainers: 1
spack.io: py-libsonata

SONATA files reader

  • Versions: 0
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent repos count: 0.0%
Average: 27.6%
Dependent packages count: 55.3%
Maintainers (1)
Last synced: 6 months ago

Dependencies

.github/workflows/clang_format_check.yaml actions
  • actions/checkout v1 composite
.github/workflows/coverage_test.yaml actions
  • actions/checkout v2 composite
  • coverallsapp/github-action master composite
.github/workflows/docstring_check.yaml actions
  • actions/checkout v2.1.0 composite
.github/workflows/publish-sdist-wheels.yml actions
  • actions/checkout v2 composite
  • actions/download-artifact v2 composite
  • actions/setup-python v2 composite
  • actions/upload-artifact v2 composite
  • pypa/gh-action-pypi-publish master composite
.github/workflows/run-tests.yml actions
  • actions/checkout v2 composite
  • actions/setup-python v2 composite
setup.py pypi
  • But *
  • NumPy *
  • We *
  • here ,
  • numpy *
  • there *
.github/workflows/mirror-ebrains.yml actions
  • wei/git-sync v3 composite
pyproject.toml pypi