-
Notifications
You must be signed in to change notification settings - Fork 216
Try "Handle motion/drift" documentation as a sphinx gallery #2879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Try "Handle motion/drift" documentation as a sphinx gallery #2879
Conversation
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
6f3aaf7
to
c674c6f
Compare
0d66e88
to
4f2bb24
Compare
OK this is ready for review now. |
} | ||
|
||
if tags.has("handle_drift") or tags.has("all_long_plot"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Worth generalising this? Something like:
if tags.has("handle_drift") or tags.has("all_long_plot"): | |
long_tutorial_names = ["handle_drift"] | |
for long_tutorial_name in long_tutorial_names: | |
if tags.has(long_tutorial_name) or tags.has("all_long_plot"): | |
if (tutorial_path := (Path('long_tutorials/'+long_tutorial_name))).is_dir(): | |
shutil.rmtree(tutorial_path) | |
sphinx_gallery_conf['examples_dirs'].append('../examples/long_tutorials/'+long_tutorial_name) | |
sphinx_gallery_conf["gallery_dirs"].append(tutorial_path.as_posix()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is very nice, for now if it works for you I will wait for the upcoming PR tackling the Neuropixels how-to to implement this, just to make checking it's working for multiple cases a bit easier. I'll link to this suggestion in our issue to not forget!
I love this! The local workflow is great: by default you do what you always do, then only need to add the tag when you're working on that doc. Perfect! I also think that sphinx_gallery files are easier to read/edit than the rst files (i.e. plot_handle_drift.py is much easier to edit than handle_drift.rst). By default the CI won't build the long_tutorials, right? And from the discussion in #2881, the plan would be to run all the long tutorials occasionally, maybe before a release? Is that right? (I'll read the actual tutorial soon!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got to run to a meeting, but I did some edits on the first 200 lines. :)
@@ -0,0 +1,342 @@ | |||
""" | |||
=========================================== | |||
Handle probe drift with spikeinterface NEW |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle probe drift with spikeinterface NEW | |
Handle probe drift with SpikeInterface |
Just so we don't forget to remove NEW and we stylize this way for SpikeInterface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, cheers for review @zm711!
# * The preset **nonrigid_accurate** seems to give the best results on this recording. | ||
# The motion vector seems less noisy globally, but it is not 'perfect' (see at the top of the probe 3200um to 3800um). | ||
# Also note that in the first part of the recording before the imposed motion (0-600s) we clearly have a non-rigid motion: | ||
# the upper part of the probe (2000-3000um) experience some drifts, but the lower part (0-1000um) is relatively stable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like "drifts" since I would say this is an uncountable concept, but it may be too late and the field has settled on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I wanted to fix to 'motion', but its hard to use in some senses e.g. 'upper part of the probe may experience some motion' doesn't quite read properly for me. I guess motion may be too general and makes you think that probe is moving (or maybe the probe is moving because the animal is moving! there is 'motion' in the system) whereas 'drift' is a bit more specific and particularly refers to the phenomenon of the signal drifting across the probe (maybe the probe or may be the brain).
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
@JoeZiminski it is in my to-do list to review this. Just a ping |
Hello, I just did the tutorial alongside some of my own data - it was fun! One thing that stuck out: it's not obvious to me when you need to apply draft correction. At the workshop, we saw talks where you could really see the drift in the raw data. But when I look at my traces, I have no idea. And using my data, the three correction methods give pretty different results. The tutorial says "always plot the motion correction information for your recordings, to make sure the correction is behaviour as expected!" but I have no idea what is expected. Anyone have any general tips? @cwindolf @alejoe91 Also, I remember speaking to @Ashkees , who said she spent a while learning about drift before realising her probe didn't need any correction. So maybe it's worth saying which technologies require it and which don't? I don't know which ones do and don't, though! Anyone know which probes are prone to drift? All the high density ones?? |
Thanks @h-mayorquin, no rush! Cheers @chrishalcrow this is a great point, I think an additional section 'when to apply motion correction' would be useful before the summary. For example, I had a case recently (Cambridge Neurotech shank with only 16 channels, which I guess these algorithms were not really designed for) where the motion correction was introducing a lot of artefacts. Also, there was not much motion to begin with as all recording sessions were close together in time and not too long, so it was not as necessary. The output looked like this: ![]() On the top left, the peaks look quite stable. But on the top right after correction, they have been smeared across the probe. Also, there are corresponding jumps in the motion vector where something is obviously going wrong in the estimation. A case of real data with motion in is the pictures of the neuropixels data used in the original version of this tutorial (below). So maybe we can include both to show cases of real data where there is and isn't drift. And this will also show what the motion correction outputs look like when things work / things go wrong. ![]() Good question about the probes! I'm not sure on this, my guess is that for the most part if you have peaks drifting in the data you probably could use some kind of motion correction. But, these algorithms as currently implemented may fail for probes with lower channel number as above? In the KS4 docs I saw ''For probes with fewer channels (around 64 or less) or with sparser spacing (around 50um or more between contacts), drift estimates are not likely to be accurate, so drift correction should be skipped'. (here). Actually, I just properly looked at their drift correction section which has a very nice explainer, we can link to it here I think. |
Thanks @JoeZiminski . Great. The main point I'd missed was: to see if you have drift, you need to apply the drift correction and take a look at the results. And then give some suggestions for what "bad" results would look like: lots of discrete spikes in the motion vectors and a corrected peak depth plot that makes less sense than the original. Kilosort's page is great! Their discussion on timescales also shows why your motion vector shouldn't be trusted, since those spikes are not on timescales of seconds. I don't think you need to include lots of different datasets, just some advice would be good. So Kilosort suggests that only high-density high-channel-count probes should be motion corrected. I would mention this right at the start. |
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Thanks @chrishalcrow great points have updated, let me know what you think (I'm not super happy with what I've written not sure if its clear, all feedback welcome!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, let me see if I understand. We have three types of documents in the docs:
- We have things that are static files and code like some of the how-to
- We have things that are fully built in the gallery because they run in a reasonable time.
- We have gallery items that take too long to build so we just built them manually.
We currently use approach 3 for some documents like get_started
the only thing this approach does is creating a way of calling this automatically through the tag machinery of sphinx. This makes sense to me. I will do a second pass to check on the content.
@@ -130,9 +130,19 @@ | |||
'within_subsection_order': FileNameSortKey, | |||
'ignore_pattern': '/generate_', | |||
'nested_sections': False, | |||
'copyfile_regex': r'.*\.rst|.*\.png|.*\.svg' | |||
'copyfile_regex': r'.*\.rst|.*\.png|.*\.svg', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chrishalcrow can you remind me what this does? I re-read the section and I could not locate this into the context of our project. Would you be so kind?
https://sphinx-gallery.github.io/stable/configuration.html#manually-passing-files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello, sorry I missed this.
This copies any rst, png or svg files from the source sphinx-gallery
directory to the output directory. In this case the source directory is examples/tutorials/
and we would like it to copy waveform_extractor_to_sorting_analyzer.rst
from there to where the gallery is outputted (doc/tutorials
).
This is done so that the tutorial pages (https://spikeinterface.readthedocs.io/en/latest/tutorials/index.html), which is a sphinx-gallery, can include a non-sphinx gallery page (the waveforms page).
The .svg
s were included to copy over the svg of the extension parent/child figure, but this is not kept in doc/_images
since it's repeated in a few places.
@@ -130,9 +130,19 @@ | |||
'within_subsection_order': FileNameSortKey, | |||
'ignore_pattern': '/generate_', | |||
'nested_sections': False, | |||
'copyfile_regex': r'.*\.rst|.*\.png|.*\.svg' | |||
'copyfile_regex': r'.*\.rst|.*\.png|.*\.svg', | |||
'filename_pattern': '/plot_', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a default value, why add it here? If you want to be explicit can we add a small comment and what it does?
|
||
sphinx_gallery_conf['examples_dirs'].append('../examples/long_tutorials/handle_drift') | ||
sphinx_gallery_conf["gallery_dirs"].append(handle_drift_path.as_posix()) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does sphinx knows what goes to where? That is, what things on eample_dirs who to which gallery_dirs? Is that positionally?
# Drift correction may not always be necessary for your data, for | ||
# example, for example when there is not much drift in the data to begin with. | ||
# Further, in some cases (e.g. when the probe has a smaller number of channels, | ||
# e.g. 64 or less) the drift correction algorithms may not perfect well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perform vs perfect
], | ||
) | ||
) | ||
print(raw_recording) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you don't wrap them into print you will get the html representation I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this won't be display with a thumbnail, do we need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this in version control?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this the only one we need in version control? Why do we need the others? We need the zip files so people can download it, right. But what about this one?
This PR adds a sphinx-gallery page version of the current "Handle motion/drift with spikeinterface". It is an implementation of 'method 2' as described in further detail in #2881 . Very keen to get feedback on the general long-docs build approach + the actual content of the page. Currently the new and old version are both there (this version is renamed and appended with NEW) for comparisons sake).
This PR explores how the current 'How To' files that are build manually could be automated, using the Handle Drift page as an example.
The changes are:
conf.py
so that the page is only built with plots when a tag-t handle_drift
is added. It outputs to a 'long_tutorials/handle_drift' folder.So similar to the previous way of doing it, you build these long-to-run pages, it outputs to a specific folder and the images etc. are shared on github. However, now rather than manually rebuilding they are generated with an optional tag on the
sphinx-build
command. To take a look at this documentation you can pull the PR branch and build the docs in the usual way (without the-t handle_drift
) and the page should be there. If you wanted to make a change to the documentation, you would build with-t handle_drift
and push the results togit
.A note on reviewing
This PR keeps the old paragraph on interpreting the motion correction outputs from the previous iteration of this docs. This was based on the kilosort outputs and will not make sense here. However, I thought it made sense to leave this and then figure out the best parameters to use, before re-runnign and writing a new paragraph to interpret the outputs. The section I am referring to is
# A few comments on the figures:
@samuelgarcia @cwindolf this PR swaps out the kilosort recording for the
generate_drifting_recording()
in this example. You can see the generated plots in the PR changelog. It would be great if you could advise on the best settings to use for the synthetic recording.