open-ephys / open-ephys-python-tools

Python code for interacting with the Open Ephys GUI
MIT License
29 stars 18 forks source link

synchronizing between separate recordings #34

Open danielpollak opened 3 months ago

danielpollak commented 3 months ago

Hello, I am trying to synchronize my neuropixel recordings with my USB-6221 (BNC) NI board. I have two separate recording nodes for these devices. I would like to synchronize them, but the synchronization tutorial seems to assume all processors are on the same recording.

These sources share a physical sync pulse and they are recorded using digital IO. However, the following does not work because the NIDAQ_processor timestamps are not recorded on the NPIX_recording.events dataframe.

# Get recordings
NPIX_recording = session.recordnodes[0].recordings[0]
NIDAQ_recording = session.recordnodes[1].recordings[0]

# Get processors
NPIX_processor = NPIX_recording.events.processor_id.unique()[0]
NIDAQ_processor = NIDAQ_recording.events.processor_id.unique()[0]

# Get NIDAQ_stream
NPIX_recording.add_sync_line(1, NPIX_processor, "ProbeA-AP", main=True)
NIDAQ_stream = NIDAQ_recording.events.stream_name.unique()[0]
NPIX_recording.add_sync_line(1, NIDAQ_processor, NIDAQ_stream, main=False)

NPIX_recording.compute_global_timestamps()

This dataframe attribute is protected so I cannot merge them like so:

# Add events from NIDAQ to NIDAQ
# NPIX_recording.events = pd.concat([NPIX_recording.events, NIDAQ_recording.events])

Is there some way to proceed and synchronize these timestamps?

medengineer commented 3 months ago

Two options:

  1. Consolidate the contents of each continuous and events directories into one of your Record Node directories. You’ll also have to modify the structure.oebin file accordingly, and remove the resulting empty Record Node. Then you can use the python-tools compute_global_timestamps() directly as described in the tutorial.

  2. To avoid modifying the original data, you’ll have to copy the python-tools alignment functions into a separate file, rather than using the Recording class directly.