Skip to content

Commit

Permalink
neo v0.8.0 compatible (NeuralEnsemble#256)
Browse files Browse the repository at this point in the history
* fixes for neo v0.8.0

* upd array_annotation comment

* added todo for neo empty array_annotations
  • Loading branch information
dizcza committed Oct 22, 2019
1 parent eac914c commit 5b5a023
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 99 deletions.
19 changes: 8 additions & 11 deletions elephant/neo_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,14 @@ def extract_neo_attrs(obj, parents=True, child_first=True,
"""
attrs = obj.annotations.copy()
if not skip_array:
try:
for a in obj.array_annotations:
# Exclude labels and durations (and maybe other attributes) that are handled as array_annotations
# These would be duplicate
if a not in [_[0] for _ in obj._necessary_attrs + obj._recommended_attrs]:
if "array_annotations" not in attrs:
attrs["array_annotations"] = {}
attrs["array_annotations"][a] = obj.array_annotations[a].copy()
except AttributeError:
pass
if not skip_array and hasattr(obj, "array_annotations"):
# Exclude labels and durations, and any other fields that should not
# be a part of array_annotation.
required_keys = set(obj.array_annotations).difference(dir(obj))
for a in required_keys:
if "array_annotations" not in attrs:
attrs["array_annotations"] = {}
attrs["array_annotations"][a] = obj.array_annotations[a].copy()
for attr in obj._necessary_attrs + obj._recommended_attrs:
if skip_array and len(attr) >= 3 and attr[2]:
continue
Expand Down
101 changes: 15 additions & 86 deletions elephant/test/test_neo_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,29 +444,20 @@ def test__extract_neo_attrs__spiketrain_parents_empty_array(self):
self.assert_dicts_equal(targ, res111)
self.assert_dicts_equal(targ, res211)

@staticmethod
def _fix_neo_issue_749(obj, targ):
# TODO: remove once fixed
# https://github.com/NeuralEnsemble/python-neo/issues/749
num_times = len(targ['times'])
obj = obj[:num_times]
del targ['array_annotations']
return obj

def test__extract_neo_attrs__epoch_parents_empty_array(self):
obj = fake_neo('Epoch', seed=0)
targ = get_fake_values('Epoch', seed=0)

# TODO: Circumvent bug in neo 0.7.1, where fake objects are not
# properly constructed. Here, the returned fake values do not match
# with the corresponding object in terms of the length of the Epoch
# object. We introduce a manual fix, cutting the fake Neo object to the
# number of items returned by the get_fake_values() function.
num_times = len(targ['times'])
array_annotation_save = obj.array_annotations
obj.array_annotations = {
'durations': array_annotation_save['durations'],
'labels': array_annotation_save['labels']}
obj.durations = obj.durations[:num_times]
obj.labels = obj.labels[:num_times]
for k in array_annotation_save:
obj.array_annotations[k] = array_annotation_save[k][:num_times]

# TODO: Fix once inconsistencies in handling array annotations
# are properly fixed in neo
del targ['array_annotations']


obj = self._fix_neo_issue_749(obj, targ)
del targ['times']

res000 = nt.extract_neo_attrs(obj, parents=False)
Expand Down Expand Up @@ -638,25 +629,8 @@ def test__extract_neo_attrs__epoch_noparents_array(self):
obj = self.block.list_children_by_class('Epoch')[0]
targ = get_fake_values('Epoch', seed=obj.annotations['seed'])

# TODO: Circumvent bug in neo 0.7.1, where fake objects are not
# properly constructed. Here, the returned fake values do not match
# with the corresponding object in terms of the length of the Epoch
# object. We introduce a manual fix, cutting the fake Neo object to the
# number of items returned by the get_fake_values() function.
num_times = len(targ['times'])
array_annotation_save = obj.array_annotations
obj.array_annotations = {
'durations': array_annotation_save['durations'],
'labels': array_annotation_save['labels']}
obj.durations = obj.durations[:num_times]
obj.labels = obj.labels[:num_times]
for k in array_annotation_save:
obj.array_annotations[k] = array_annotation_save[k][:num_times]

# TODO: Fix once inconsistencies in handling array annotations
# are properly fixed in neo
del targ['array_annotations']

# 'times' is not in obj._necessary_attrs + obj._recommended_attrs
obj = self._fix_neo_issue_749(obj, targ)
del targ['times']

res00 = nt.extract_neo_attrs(obj, parents=False, skip_array=False)
Expand All @@ -668,15 +642,6 @@ def test__extract_neo_attrs__epoch_noparents_array(self):
res11 = nt.extract_neo_attrs(obj, parents=False, child_first=True)
res21 = nt.extract_neo_attrs(obj, parents=False, child_first=False)

for k in res00:
print(k,res00[k])
print('-=-')
for k in res01:
print(k,res01[k])
print('-=-')
for k in targ:
print(k,targ[k])

del res00['i']
del res10['i']
del res20['i']
Expand Down Expand Up @@ -917,25 +882,7 @@ def test__extract_neo_attrs__epoch_parents_childfirst_array(self):
targ.update(get_fake_values('Segment', seed=seg.annotations['seed']))
targ.update(get_fake_values('Epoch', seed=obj.annotations['seed']))

# TODO: Circumvent bug in neo 0.7.1, where fake objects are not
# properly constructed. Here, the returned fake values do not match
# with the corresponding object in terms of the length of the Epoch
# object. We introduce a manual fix, cutting the fake Neo object to the
# number of items returned by the get_fake_values() function.
num_times = len(targ['times'])
array_annotation_save = obj.array_annotations
obj.array_annotations = {
'durations': array_annotation_save['durations'],
'labels': array_annotation_save['labels']}
obj.durations = obj.durations[:num_times]
obj.labels = obj.labels[:num_times]
for k in array_annotation_save:
obj.array_annotations[k] = array_annotation_save[k][:num_times]

# TODO: Fix once inconsistencies in handling array annotations
# are properly fixed in neo
del targ['array_annotations']

obj = self._fix_neo_issue_749(obj, targ)
del targ['times']

res00 = nt.extract_neo_attrs(obj, parents=True, skip_array=False)
Expand Down Expand Up @@ -1029,26 +976,8 @@ def test__extract_neo_attrs__epoch_parents_parentfirst_array(self):
targ = get_fake_values('Epoch', seed=obj.annotations['seed'])
targ.update(get_fake_values('Segment', seed=seg.annotations['seed']))
targ.update(get_fake_values('Block', seed=blk.annotations['seed']))

# TODO: Circumvent bug in neo 0.7.1, where fake objects are not
# properly constructed. Here, the returned fake values do not match
# with the corresponding object in terms of the length of the Epoch
# object. We introduce a manual fix, cutting the fake Neo object to the
# number of items returned by the get_fake_values() function.
num_times = len(targ['times'])
array_annotation_save = obj.array_annotations
obj.array_annotations = {
'durations': array_annotation_save['durations'],
'labels': array_annotation_save['labels']}
obj.durations = obj.durations[:num_times]
obj.labels = obj.labels[:num_times]
for k in array_annotation_save:
obj.array_annotations[k] = array_annotation_save[k][:num_times]

# TODO: Fix once inconsistencies in handling array annotations
# are properly fixed in neo
del targ['array_annotations']

obj = self._fix_neo_issue_749(obj, targ)
del targ['times']

res0 = nt.extract_neo_attrs(obj, parents=True, skip_array=False,
Expand Down
2 changes: 1 addition & 1 deletion elephant/test/test_unitary_event_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import neo
import numpy as np
import quantities as pq
from neo.rawio.tests.tools import create_local_temp_dir
from neo.test.rawiotest.tools import create_local_temp_dir

try:
from urllib2 import urlopen
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
neo>=0.7.1,<0.8.0
neo>=0.8.0,<0.9.0
numpy>=1.10.1
quantities>=0.12.1
scipy>=0.19.0
Expand Down

0 comments on commit 5b5a023

Please sign in to comment.