-
Notifications
You must be signed in to change notification settings - Fork 260
Description
Describe the bug
I'm trying to merge two blocks together, each having one segment, into one block with two segments. But I have problems calling merge since I have spike trains in groups. Why am I told SpikeTrain can only have Segment, not Group parents? No errors popped up before merging. From what I understand, an object can be in more than one container, but only have one parent.
To Reproduce
#%%
import neo
#%%
blocks = []
for i in range(2):
block = neo.Block()
seg = neo.Segment(name=f'segment {i}')
block.segments.append(seg)
g = neo.Group()
st = neo.SpikeTrain([1,2,3], t_stop=4, units='ms')
g.spiketrains.append(st)
block.groups.append(g)
seg.spiketrains.append(st)
blocks.append(block)
blocks
# %%
blocks[0].merge(blocks[1])
blocks[0]
Output:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/kyle/scratch/python-neo/test.py in line 2
[16](file:///home/kyle/scratch/python-neo/test.py?line=15) # %%
----> [17](file:///home/kyle/scratch/python-neo/test.py?line=16) blocks[0].merge(blocks[1])
[18](file:///home/kyle/scratch/python-neo/test.py?line=17) blocks[0]
File [~/scratch/python-neo/neo/core/container.py:491](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/kyle/scratch/python-neo/~/scratch/python-neo/neo/core/container.py:491), in Container.merge(self, other)
[489](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=488) continue
[490](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=489) if obj.name in lookup:
--> [491](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=490) lookup[obj.name].merge(obj)
[492](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=491) else:
[493](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=492) lookup[obj.name] = obj
File [~/scratch/python-neo/neo/core/container.py:519](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/kyle/scratch/python-neo/~/scratch/python-neo/neo/core/container.py:519), in Container.merge(self, other)
[516](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=515) getattr(self, container).append(obj)
[517](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=516) # if self.__class__.__name__ in obj._parent_objects:
[518](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=517) # obj.set_parent(self)
--> [519](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=518) obj.set_parent(self)
[521](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=520) # use the BaseNeo merge as well
[522](file:///home/kyle/scratch/python-neo/neo/core/container.py?line=521) super().merge(other)
File [~/scratch/python-neo/neo/core/baseneo.py:369](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/kyle/scratch/python-neo/~/scratch/python-neo/neo/core/baseneo.py:369), in BaseNeo.set_parent(self, obj)
[364](file:///home/kyle/scratch/python-neo/neo/core/baseneo.py?line=363) """
[365](file:///home/kyle/scratch/python-neo/neo/core/baseneo.py?line=364) Set the appropriate "parent" attribute of this object
[366](file:///home/kyle/scratch/python-neo/neo/core/baseneo.py?line=365) according to the type of "obj"
[367](file:///home/kyle/scratch/python-neo/neo/core/baseneo.py?line=366) """
[368](file:///home/kyle/scratch/python-neo/neo/core/baseneo.py?line=367) if obj.__class__.__name__ not in self._parent_objects:
--> [369](file:///home/kyle/scratch/python-neo/neo/core/baseneo.py?line=368) raise TypeError("{} can only have parents of type {}, not {}".format(
[370](file:///home/kyle/scratch/python-neo/neo/core/baseneo.py?line=369) self.__class__.__name__, self._parent_objects, obj.__class__.__name__))
[371](file:///home/kyle/scratch/python-neo/neo/core/baseneo.py?line=370) loc = self._parent_objects.index(obj.__class__.__name__)
[372](file:///home/kyle/scratch/python-neo/neo/core/baseneo.py?line=371) parent_attr = self._parent_attrs[loc]
TypeError: SpikeTrain can only have parents of type ('Segment',), not Group
Expected behaviour
The blocks to merge with set_parent
on children objects only applied to the true parent. I don't know enough of the codebase to know if this will cause problems anywhere else, but changing obj.set_parent(self)
in Container.merge()
to this does the trick:
if self.__class__.__name__ in obj._parent_objects:
obj.set_parent(self)
Then I get what I expected out of the MRE:
Block with 2 segments, 1 groups
# segments (N=2)
0: Segment with 1 spiketrains name: 'segment 0' # analogsignals (N=0)
1: Segment with 1 spiketrains name: 'segment 1' # analogsignals (N=0)
Environment:
- OS: Linux
- Python version: 3.9
- Neo version: 0.13.0.dev0
- NumPy version: 1.25.1
Additional context
Add any other context about the problem here.