spikeinterface icon indicating copy to clipboard operation
spikeinterface copied to clipboard

"Can't interpolate traces" with int16 dtype in motion_correction

Open avakiai opened this issue 1 year ago • 5 comments

Hello,

I'm trying out a few motion correction algorithms on Neuropixel 1.0 data. I'm currently running through the pipeline with a short (<5 minute) recording. After chaining preprocessing steps, I get the following error when the detect and localize step completes. Any ideas what is causing this behavior?

At first I thought the error may have been caused by one bad channel that had been removed, but the error persists regardless of whether any channels are removed or not. Also, the dtype has not changed through preprocessing - og dtype is and remains int16.

job_kwargs = dict(n_jobs=40, chunk_duration='1s', progress_bar=True)

rec1 = si.highpass_filter(raw_rec, freq_min=400.)
bad_channel_ids, channel_labels = si.detect_bad_channels(rec1)
rec2 = rec1.remove_channels(bad_channel_ids)
print('bad_channel_ids', bad_channel_ids)

rec3 = si.phase_shift(rec1)
rec4 = si.common_reference(rec3, operator="median", reference="global")
rec = rec4

some_presets = ('kilosort_like', 'nonrigid_accurate')
for preset in some_presets:
    print('Computing with', preset)
    folder = anim_dat_dir[2] + '/' + 'motion_folder_dataset1' + '/' + preset

    # if folder.exists():
    #     shutil.rmtree(folder)
    recording_corrected, motion_info = si.correct_motion(rec, preset=preset,
                                                         folder=folder,
                                                         output_motion_info=True, **job_kwargs)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[57], line 6
      3 folder = anim_dat_dir[2] + '/' + 'motion_folder_dataset1' + '/' + preset
      4 # if folder.exists():
      5 #     shutil.rmtree(folder)
----> 6 recording_corrected, motion_info = si.correct_motion(rec, preset=preset,
      7                                                      folder=folder,
      8                                                      output_motion_info=True, **job_kwargs)

File D:\downloads_\spikeinterface\src\spikeinterface\preprocessing\motion.py:386, in correct_motion(recording, preset, folder, output_motion_info, overwrite, detect_kwargs, select_kwargs, localize_peaks_kwargs, estimate_motion_kwargs, interpolate_motion_kwargs, **job_kwargs)
    383 t1 = time.perf_counter()
    384 run_times["estimate_motion"] = t1 - t0
--> 386 recording_corrected = InterpolateMotionRecording(recording, motion, **interpolate_motion_kwargs)
    388 motion_info = dict(
    389     parameters=parameters,
    390     run_times=run_times,
   (...)
    393     motion=motion,
    394 )
    395 if folder is not None:

File D:\downloads_\spikeinterface\src\spikeinterface\sortingcomponents\motion_interpolation.py:343, in InterpolateMotionRecording.__init__(self, recording, motion, border_mode, spatial_interpolation_method, sigma_um, p, num_closest, interpolation_time_bin_centers_s, interpolation_time_bin_size_s, dtype, **spatial_interpolation_kwargs)
    341         dtype = recording.dtype
    342     else:
--> 343         raise ValueError(f"Can't interpolate traces of recording with non-floating dtype={recording.dtype=}.")
    345 dtype_ = fix_dtype(recording, dtype)
    346 BasePreprocessor.__init__(self, recording, channel_ids=channel_ids, dtype=dtype_)

ValueError: Can't interpolate traces of recording with non-floating dtype=recording.dtype=dtype('int16').

Many thanks, ava

avakiai avatar Jul 04 '24 17:07 avakiai

Update: changing dtype to float coming out of preprocessing chain solved the issue and correct_motion runs with both presets now. (Is there any reason why this would alter spike sorting outcomes, and should be changed back to original int16 at some point?)

Note: trying to plot the motion vector as per the documentation now gives an error that the API has been updated, but doesn't specify that recording object now needs to be passed.

for preset in some_presets:
    # load
    folder = anim_dat_dir[2] + '/' + 'motion_folder_dataset1' + '/' + preset
    motion_info = si.load_motion_info(folder)

    # and plot
    fig = plt.figure(figsize=(14, 8))
# as per documentation, as of 2024/7/4
#    si.plot_motion(motion_info, figure=fig, depth_lim=(400, 600),
#                   color_amplitude=True, amplitude_cmap='inferno', scatter_decimate=10)
# now needs:
    si.plot_motion_info(motion_info, figure=fig, depth_lim=(400, 600), 
                        recording = rec,
                   color_amplitude=True, amplitude_cmap='inferno', scatter_decimate=10)

    fig.suptitle(f"{preset=}")
    

avakiai avatar Jul 04 '24 18:07 avakiai

Hi Ava. I guess that you are working with the main branch The motion estimation is totally work-in-progress theses times Doc has not been updated yet. when this #3062 will be merged (new week maybe) you could have even more changes. (but new preset like dredge!) sorry for that. A new doc should availble when merging.

And yes the solution was to dtype as float32 like you said.

For plotting you can do this

motion_info = si.load_motion_info(folder)
motion = motion_info['motion']  #<<< this is the Motion object
print(motion)
plot_motion(motion, mode='map')
plot_motion(motion, mode='line')

samuelgarcia avatar Jul 04 '24 19:07 samuelgarcia

I'll close this but if something else comes up let us know!

zm711 avatar Jul 19 '24 21:07 zm711

Hi, I got same kind of issue when i try to run spikingcircus with correction of motion from recording object in int16


Running 'sc_default'
noise_level (no parallelization): 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████| 20/20 [00:07<00:00,  2.63it/s]
Traceback (most recent call last):
  File "/mnt/ssd/analyse_victor/lauch_sortings.py", line 187, in <module>
    recording_tmp = func(recording_tmp, **p)
                    ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/users/nsr/llobet/miniconda3/envs/lussac/lib/python3.12/site-packages/spikeinterface/preprocessing/motion.py", line 557, in correct_motion
    recording_corrected = interpolate_motion(recording, motion, **interpolate_motion_kwargs)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/users/nsr/llobet/miniconda3/envs/lussac/lib/python3.12/site-packages/spikeinterface/core/core_tools.py", line 35, in source_class_or_dict_of_sources_classes
    return source_class(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/users/nsr/llobet/miniconda3/envs/lussac/lib/python3.12/site-packages/spikeinterface/sortingcomponents/motion/motion_interpolation.py", line 403, in __init__
    raise ValueError(f"Can't interpolate traces of recording with non-floating dtype={recording.dtype=}.")
ValueError: Can't interpolate traces of recording with non-floating dtype=recording.dtype=dtype('int16').

Any idea other than save binaryfile as float32?

Best, Victor

llobetv avatar Nov 20 '25 08:11 llobetv

@yger

alejoe91 avatar Nov 24 '25 11:11 alejoe91