Skip to content

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

Open
wants to merge 36 commits into
base: main
Choose a base branch
from

Conversation

JoeZiminski
Copy link
Collaborator

@JoeZiminski JoeZiminski commented May 17, 2024

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:

  1. The handle drift page was rewritten as a sphinx-gallery. It is now linked to, from the 'How To' page, similar to the existing page on which it is based, but with 'NEW' at the end of the name.
  2. Some code is added to the 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 to git.

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.

@alejoe91 alejoe91 added the documentation Improvements or additions to documentation label May 20, 2024
@JoeZiminski JoeZiminski force-pushed the drift_docs_to_sphinx_gallery branch from 6f3aaf7 to c674c6f Compare June 21, 2024 16:04
@JoeZiminski JoeZiminski force-pushed the drift_docs_to_sphinx_gallery branch from 0d66e88 to 4f2bb24 Compare June 21, 2024 16:17
@JoeZiminski
Copy link
Collaborator Author

OK this is ready for review now.

}

if tags.has("handle_drift") or tags.has("all_long_plot"):
Copy link
Member

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:

Suggested change
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())

Copy link
Collaborator Author

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!

@chrishalcrow
Copy link
Member

chrishalcrow commented Jun 26, 2024

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!)

Copy link
Member

@zm711 zm711 left a 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.

Copy link
Collaborator Author

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.
Copy link
Member

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.

Copy link
Collaborator Author

@JoeZiminski JoeZiminski Jul 2, 2024

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).

JoeZiminski and others added 5 commits June 27, 2024 18:14
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 JoeZiminski requested a review from cwindolf June 27, 2024 17:21
JoeZiminski and others added 8 commits June 27, 2024 18:25
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>
@h-mayorquin
Copy link
Collaborator

@JoeZiminski it is in my to-do list to review this. Just a ping

@chrishalcrow
Copy link
Member

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??

@JoeZiminski
Copy link
Collaborator Author

JoeZiminski commented Jun 28, 2024

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:

Screenshot 2024-06-28 at 10 44 55

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.

Screenshot 2024-06-28 at 10 46 17

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.

@chrishalcrow
Copy link
Member

I think an additional section 'when to apply motion correction' would be useful before the summary....

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.

JoeZiminski and others added 3 commits July 2, 2024 11:41
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com>
@JoeZiminski
Copy link
Collaborator Author

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!)

@JoeZiminski JoeZiminski linked an issue Jul 2, 2024 that may be closed by this pull request
Copy link
Collaborator

@h-mayorquin h-mayorquin left a 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:

  1. We have things that are static files and code like some of the how-to
  2. We have things that are fully built in the gallery because they run in a reasonable time.
  3. 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',
Copy link
Collaborator

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

Copy link
Member

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 .svgs 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_',
Copy link
Collaborator

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())

Copy link
Collaborator

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.
Copy link
Collaborator

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)
Copy link
Collaborator

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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

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?

Copy link
Collaborator

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?

Copy link
Collaborator

@h-mayorquin h-mayorquin Jul 2, 2024

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handling documentation that takes a long time to build
5 participants