Skip to content

Commit

Permalink
Merge branch 'NeuralEnsemble:master' into enh/array_anno_types
Browse files Browse the repository at this point in the history
  • Loading branch information
JuliaSprenger authored May 23, 2023
2 parents 95d6ad2 + 29d73f6 commit 8d2ac21
Show file tree
Hide file tree
Showing 54 changed files with 595 additions and 343 deletions.
113 changes: 113 additions & 0 deletions codemeta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"@context": "https://doi.org/10.5063/schema/codemeta-2.0",
"@type": "SoftwareSourceCode",
"license": "https://spdx.org/licenses/BSD-3-Clause",
"codeRepository": "https://github.com/NeuralEnsemble/python-neo",
"contIntegration": "https://github.com/NeuralEnsemble/python-neo/actions",
"dateModified": "2023-04-04",
"downloadUrl": "https://files.pythonhosted.org/packages/4d/95/e79e05c9bc8ef61d89a8a6b949db03adb2046b9fca38422d570c7add543d/neo-0.12.0.tar.gz",
"issueTracker": "https://github.com/NeuralEnsemble/python-neo/issues",
"name": "Neo",
"version": "0.12.0",
"identifier": "RRID:SCR_000634",
"description": "Neo is a Python package for working with electrophysiology data in Python, together with support for reading a wide range of neurophysiology file formats, including Spike2, NeuroExplorer, AlphaOmega, Axon, Blackrock, Plexon, Tdt, and support for writing to a subset of these formats plus non-proprietary formats including HDF5.\n\nThe goal of Neo is to improve interoperability between Python tools for analyzing, visualizing and generating electrophysiology data by providing a common, shared object model. In order to be as lightweight a dependency as possible, Neo is deliberately limited to represention of data, with no functions for data analysis or visualization.\n\nNeo is used by a number of other software tools, including SpykeViewer (data analysis and visualization), Elephant (data analysis), the G-node suite (databasing), PyNN (simulations), tridesclous_ (spike sorting) and ephyviewer (data visualization).\n\nNeo implements a hierarchical data model well adapted to intracellular and extracellular electrophysiology and EEG data with support for multi-electrodes (for example tetrodes). Neo's data objects build on the quantities package, which in turn builds on NumPy by adding support for physical dimensions. Thus Neo objects behave just like normal NumPy arrays, but with additional metadata, checks for dimensional consistency and automatic unit conversion.",
"applicationCategory": "neuroscience",
"releaseNotes": "https://neo.readthedocs.io/en/stable/releases/0.12.0.html",
"funding": "https://cordis.europa.eu/project/id/945539",
"developmentStatus": "active",
"referencePublication": "https://doi.org/10.3389/fninf.2014.00010",
"funder": {
"@type": "Organization",
"name": "European Commission"
},
"programmingLanguage": ["Python"],
"operatingSystem": ["Linux", "Windows", "macOS"],
"softwareRequirements": [
"Python (version 3.8+)",
"see https://github.com/NeuralEnsemble/python-neo/blob/master/pyproject.toml"
],
"relatedLink": [
"https://neo.readthedocs.io",
"https://neuralensemble.org/community"
],
"author": [
{ "@type": "Person", "givenName": "Samuel", "familyName": "Garcia" },
{
"@type": "Person",
"@id": "http://orcid.org/0000-0002-4793-7541",
"givenName": "Andrew P.",
"familyName": "Davison"
},
{ "@type": "Person", "givenName": "Chris", "familyName": "Rodgers" },
{ "@type": "Person", "givenName": "Pierre", "familyName": "Yger" },
{ "@type": "Person", "givenName": "Yann", "familyName": "Mahnoun" },
{ "@type": "Person", "givenName": "Luc", "familyName": "Estabanez" },
{ "@type": "Person", "givenName": "Andrey", "familyName": "Sobolev" },
{ "@type": "Person", "givenName": "Thierry", "familyName": "Brizzi" },
{ "@type": "Person", "givenName": "Florent", "familyName": "Jaillet" },
{ "@type": "Person", "givenName": "Philipp", "familyName": "Rautenberg" },
{ "@type": "Person", "givenName": "Thomas", "familyName": "Wachtler" },
{ "@type": "Person", "givenName": "Cyril", "familyName": "Dejean" },
{ "@type": "Person", "givenName": "Robert", "familyName": "Pröpper" },
{ "@type": "Person", "givenName": "Domenico", "familyName": "Guarino" },
{ "@type": "Person", "givenName": "Achilleas", "familyName": "Koutsou" },
{ "@type": "Person", "givenName": "Erik", "familyName": "Li" },
{ "@type": "Person", "givenName": "Georg", "familyName": "Raiser" },
{ "@type": "Person", "givenName": "Joffrey", "familyName": "Gonin" },
{ "@type": "Person", "givenName": "Kyler", "familyName": "Brown" },
{ "@type": "Person", "givenName": "Mikkel Elle", "familyName": "Lepperød" },
{ "@type": "Person", "givenName": "C Daniel", "familyName": "Meliza" },
{ "@type": "Person", "givenName": "Julia", "familyName": "Sprenger" },
{ "@type": "Person", "givenName": "Maximilian", "familyName": "Schmidt" },
{ "@type": "Person", "givenName": "Johanna", "familyName": "Senk" },
{ "@type": "Person", "givenName": "Carlos", "familyName": "Canova" },
{ "@type": "Person", "givenName": "Hélissande", "familyName": "Fragnaud" },
{ "@type": "Person", "givenName": "Mark", "familyName": "Hollenbeck" },
{ "@type": "Person", "givenName": "Mieszko", "familyName": "Grodzicki" },
{ "@type": "Person", "givenName": "Rick", "familyName": "Gerkin" },
{ "@type": "Person", "givenName": "Matthieu", "familyName": "Sénoville" },
{ "@type": "Person", "givenName": "Chadwick", "familyName": "Boulay" },
{ "@type": "Person", "givenName": "Björn", "familyName": "Müller" },
{ "@type": "Person", "givenName": "William", "familyName": "Hart" },
{ "@type": "Person", "alternateName": "erikli(github)" },
{ "@type": "Person", "givenName": "Jeffrey", "familyName": "Gill" },
{
"@type": "Person",
"givenName": "Lucas",
"alternateName": "lkoelman@github"
},
{ "@type": "Person", "givenName": "Mark", "familyName": "Histed" },
{ "@type": "Person", "givenName": "Mike", "familyName": "Sintsov" },
{ "@type": "Person", "givenName": "Scott W", "familyName": "Harden" },
{
"@type": "Person",
"givenName": "Chek Yin",
"familyName": "Choi",
"alternateName": "hkchekc@github"
},
{ "@type": "Person", "givenName": "Corentin", "familyName": "Fragnaud" },
{
"@type": "Person",
"givenName": "Alexander",
"familyName": "Kleinjohann"
},
{ "@type": "Person", "givenName": "Christian", "familyName": "Kothe" },
{ "@type": "Person", "alternateName": "rishidhingra@github" },
{ "@type": "Person", "givenName": "Hugo", "familyName": "van Kemenade" },
{
"@type": "Person",
"givenName": "Aitor",
"familyName": "Morales-Gregorio"
},
{ "@type": "Person", "givenName": "Peter N", "familyName": "Steinmetz" },
{ "@type": "Person", "givenName": "Shashwat", "familyName": "Sridhar" },
{ "@type": "Person", "givenName": "Alessio", "familyName": "Buccino" },
{ "@type": "Person", "givenName": "Regimantas", "familyName": "Jurkus" },
{ "@type": "Person", "givenName": "Steffen", "familyName": "Buergers" },
{ "@type": "Person", "givenName": "Etienne", "familyName": "Combrisson" },
{ "@type": "Person", "givenName": "Ben", "familyName": "Dichter" },
{ "@type": "Person", "givenName": "Elodie", "familyName": "Legouée" },
{ "@type": "Person", "givenName": "Heberto", "familyName": "Mayorquin" },
{ "@type": "Person", "givenName": "Thomas", "familyName": "Perret" }
]
}
4 changes: 0 additions & 4 deletions doc/old_stuffs/grouping.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ Using :class:`ChannelIndex`::

block = Block()
segment = Segment()
segment.block = block
block.segments.append(segment)

for i in (0, 1):
Expand All @@ -55,7 +54,6 @@ Using array annotations, we annotate the channels of the :class:`AnalogSignal` d

block = Block()
segment = Segment()
segment.block = block
block.segments.append(segment)

for i in (0, 1):
Expand All @@ -77,7 +75,6 @@ Each :class:`ChannelIndex` also contains the list of channels on which that neur

block = Block(name="probe data")
segment = Segment()
segment.block = block
block.segments.append(segment)

# create 4-channel AnalogSignal with dummy data
Expand Down Expand Up @@ -119,7 +116,6 @@ Using :class:`ChannelView` and :class:`Group`::

block = Block(name="probe data")
segment = Segment()
segment.block = block
block.segments.append(segment)

# create 4-channel AnalogSignal with dummy data
Expand Down
1 change: 0 additions & 1 deletion doc/old_stuffs/io_developers_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ Miscellaneous
=============

* If your IO supports several versions of a format (like ABF1, ABF2), upload to the gin.g-node.org test file repository all file versions possible. (for test coverage).
* :py:func:`neo.core.Block.create_many_to_one_relationship` offers a utility to complete the hierarchy when all one-to-many relationships have been created.
* In the docstring, explain where you obtained the file format specification if it is a closed one.
* If your IO is based on a database mapper, keep in mind that the returned object MUST be detached,
because this object can be written to another url for copying.
Expand Down
15 changes: 1 addition & 14 deletions doc/source/images/generate_diagram.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ def get_rect_height(name, obj):
nlines = 1.5
nlines += len(getattr(obj, '_all_attrs', []))
nlines += len(getattr(obj, '_single_child_objects', []))
nlines += len(getattr(obj, '_multi_child_objects', []))
return nlines * line_heigth


Expand Down Expand Up @@ -74,9 +73,7 @@ def generate_diagram(rect_pos, rect_width, figsize):
alpha = [1., 1., 0.3]
for name, pos in rect_pos.items():
obj = objs[name]
relationships = [getattr(obj, '_single_child_objects', []),
getattr(obj, '_multi_child_objects', []),
getattr(obj, '_child_properties', [])]
relationships = [getattr(obj, '_single_child_objects', [])]

for r in range(3):
for ch_name in relationships[r]:
Expand Down Expand Up @@ -122,16 +119,6 @@ def generate_diagram(rect_pos, rect_width, figsize):
facecolor='c', edgecolor='k', alpha=.5)
ax.add_patch(rect)

# multi relationship
relationship = list(getattr(obj, '_multi_child_objects', []))
pos2 = (pos[1] + htotal - line_heigth * (1.5 + len(relationship))
- rect_height)
rect_height = len(relationship) * line_heigth

rect = Rectangle((pos[0], pos2), rect_width, rect_height,
facecolor='m', edgecolor='k', alpha=.5)
ax.add_patch(rect)

# necessary attr
pos2 = (pos[1] + htotal
- line_heigth * (1.5 + len(allrelationship) + len(obj._necessary_attrs)))
Expand Down
4 changes: 0 additions & 4 deletions doc/source/scripts/multi_tetrode_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

# Create dummy data, one segment at a time
for segment in block.segments:
segment.block = block

# create two 4-channel AnalogSignals with dummy data
signals = {
Expand All @@ -46,8 +45,6 @@
}
if store_signals:
segment.analogsignals.extend(signals.values())
for signal in signals:
signal.segment = segment

# create spike trains with dummy data
# we will pretend the spikes have been extracted from the dummy signal
Expand All @@ -56,7 +53,6 @@
spiketrain = SpikeTrain(np.random.uniform(0, 100, size=30) * ms, t_stop=100 * ms)
# assign each spiketrain to the appropriate segment
segment.spiketrains.append(spiketrain)
spiketrain.segment = segment
# assign each spiketrain to a given neuron
current_group = next(iter_group)
current_group.add(spiketrain)
Expand Down
1 change: 0 additions & 1 deletion examples/generated_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ def generate_block(n_segments=3, n_channels=4, n_units=3,
seg.spiketrains.append(train)
u.spiketrains.append(train)

block.create_many_to_one_relationship()
return block


Expand Down
29 changes: 25 additions & 4 deletions neo/core/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
from datetime import datetime

from neo.core.container import Container, unique_objs
from neo.core.group import Group
from neo.core.objectlist import ObjectList
from neo.core.regionofinterest import RegionOfInterest
from neo.core.segment import Segment


class Block(Container):
Expand Down Expand Up @@ -64,7 +68,6 @@ class Block(Container):
'''

_container_child_objects = ('Segment', 'Group')
_child_properties = ()
_recommended_attrs = ((('file_datetime', datetime),
('rec_datetime', datetime),
('index', int)) +
Expand All @@ -86,9 +89,27 @@ def __init__(self, name=None, description=None, file_origin=None,
self.file_datetime = file_datetime
self.rec_datetime = rec_datetime
self.index = index
self.regionsofinterest = [] # temporary workaround.
# the goal is to store all sub-classes of RegionOfInterest in a single list
# but this will need substantial changes to container handling
self._segments = ObjectList(Segment, parent=self)
self._groups = ObjectList(Group, parent=self)
self._regionsofinterest = ObjectList(RegionOfInterest, parent=self)

segments = property(
fget=lambda self: self._get_object_list("_segments"),
fset=lambda self, value: self._set_object_list("_segments", value),
doc="list of Segments contained in this block"
)

groups = property(
fget=lambda self: self._get_object_list("_groups"),
fset=lambda self, value: self._set_object_list("_groups", value),
doc="list of Groups contained in this block"
)

regionsofinterest = property(
fget=lambda self: self._get_object_list("_regionsofinterest"),
fset=lambda self, value: self._set_object_list("_regionsofinterest", value),
doc="list of RegionOfInterest objects contained in this block"
)

@property
def data_children_recur(self):
Expand Down
Loading

0 comments on commit 8d2ac21

Please sign in to comment.