aggregate_channels writes an aggregation_key property back onto every input recording before building the combined one (channelsaggregationrecording.py:39-40 calls recording.set_property("aggregation_key", ...) inside the constructor, on the originals, not on copies). This is visible as a side effect on the caller's references: after one aggregate_channels call the input recordings carry a property they did not have before, and a second aggregate_channels call with a different grouping (for example, passing the same recordings as a dict instead of a list) silently overwrites the previous label. Callers that inspect, cache, or serialize the original recordings after aggregating therefore see unexpected state.
from spikeinterface.core import generate_recording, aggregate_channels
rec_A = generate_recording(num_channels=4, durations=[1.0], set_probe=False)
rec_B = generate_recording(num_channels=2, durations=[1.0], set_probe=False)
print("rec_A property keys before:", rec_A.get_property_keys())
print("rec_B property keys before:", rec_B.get_property_keys())
_ = aggregate_channels([rec_A, rec_B])
print("rec_A property keys after:", rec_A.get_property_keys())
print("rec_A aggregation_key:", rec_A.get_property("aggregation_key"))
_ = aggregate_channels({"X": rec_A, "Y": rec_B})
print("rec_A aggregation_key after second aggregate:", rec_A.get_property("aggregation_key"))
Expected: the input recordings are unchanged by aggregate_channels.
Observed on main:
rec_A property keys before: []
rec_B property keys before: []
rec_A property keys after: ['aggregation_key']
rec_A aggregation_key: [0 0 0 0]
rec_A aggregation_key after second aggregate: ['X' 'X' 'X' 'X']
aggregate_channelswrites anaggregation_keyproperty back onto every input recording before building the combined one (channelsaggregationrecording.py:39-40 callsrecording.set_property("aggregation_key", ...)inside the constructor, on the originals, not on copies). This is visible as a side effect on the caller's references: after oneaggregate_channelscall the input recordings carry a property they did not have before, and a secondaggregate_channelscall with a different grouping (for example, passing the same recordings as a dict instead of a list) silently overwrites the previous label. Callers that inspect, cache, or serialize the original recordings after aggregating therefore see unexpected state.Expected: the input recordings are unchanged by
aggregate_channels.Observed on
main: