Skip to content

refactor lazy arrays, upgrade to fpl.NDWidget#190

Open
kushalkolar wants to merge 50 commits into
mainfrom
xarray-compatability
Open

refactor lazy arrays, upgrade to fpl.NDWidget#190
kushalkolar wants to merge 50 commits into
mainfrom
xarray-compatability

Conversation

@kushalkolar

@kushalkolar kushalkolar commented Mar 4, 2026

Copy link
Copy Markdown
Collaborator

closes #189

  • ndw NDWidget compatability by adding __array__
  • sequester index parsing logic onto base ArrayLike
  • lazy outputs no longer squeeze the output, since if we index with a slice of size 1, i.e. slice(start, start + 1, 1) the dim on which the slice was used must remain in the array with size. Ex: we need [t, m, n] -> [1, m, n] not [m, n].
  • Make a "v1" of a single-session viewer.
    • Add functionality for standard demixing video generation
    • Add functionality for trace generation (click a pixel, show which signals are generally in that area.
    • Every click event should (potentially?) display a linear selector (or crosshairs?) so the user knows where they clicked
    • Once you click a specific region, it should be possible to "scroll through" each individual footprint over "time". This should be a new widget. It has a num_neurons x time x spatial fov height x spatial fov width shape. The num_neurons slider dimension determines which neuron is "on" (i.e. visible) -- all others are off. The purpose of this is to allow you to scroll the neural activity traces of individual neurons at a time.
  • Make a "v1" of a multi-session viewer. Use case: you've run ROICaT on a sequence of masknmf.DemixingResults objects. You have tracked neural signals across the sessions and want to see these signals.
    • Add functionality to view color-matched neurons across sessions
    • Add click-event functionality to click a given signal. This event will show the neural activity across all sessions.
    • Decide how to support the following use case: users will want to input their own experimental traces to view alongside the session-matched traces. Is it worth supporting a widget that directly allows this?
  • Make a "v1" of a comparison viewer to compare masknmf outputs with those of any other signal extraction pipeline. Make a ndwidget-style viewer that allows you to compare the two methods very clearly. Let's keep this simple for now and update based on Samuel Picard's feedback.
    • Provide a basic widget that shows (a) masknmf's AC video and the "AC video" from the other method. regular AC panels and colorful AC panels
    • Include logic that greedily matches signals from the two methods and color-codes the matches. Decide whether to include this as a separate panel or not.
    • Include a trace viewer for both methods. Here, we just want to look at the "net signal estimate" at each location -- don't need to show individual trace estimates.
  • Make a "v1" of an "ordering segregated" signal viewer. The goal here is to separate signals based on various metrics (stimulus responsiveness, brightness, whatever) and view signals that belong to different quantiles based on this ordering.
    • Add an option to show customized traces that are synchronized with the time axis of the imaging expt.
    • Add an option to click pixels in the data and view ROI averages of specific panels. The goal here is to give the user the ability to see traces of arbitrary panels.

Don't know if this breaks other parts of the codebase, but I checked that the basics work with NDWidget.

Is the FactorizedVideo mainly for instance checks? It doesn't have any functionality beyond ArrayLike?

@kushalkolar

kushalkolar commented Mar 4, 2026

Copy link
Copy Markdown
Collaborator Author

docs failing because this breaks compatability with old imagewidget that's used for the docs gallery

@apasarkar apasarkar force-pushed the xarray-compatability branch from 2c2c34f to c999384 Compare March 22, 2026 14:33
Comment thread masknmf/visualization/motion_vis.py Outdated
Comment thread masknmf/visualization/motion_vis.py
Comment thread masknmf/visualization/motion_vis.py Outdated
Comment thread masknmf/visualization/motion_vis.py
Comment thread masknmf/visualization/motion_vis.py Outdated
Comment thread masknmf/visualization/motion_vis.py Outdated
Comment thread masknmf/visualization/motion_vis.py Outdated
Comment thread masknmf/visualization/demixing_vis.py Outdated
background_trace = np.mean(self._fluctuating_background_array[:, row_start:row_stop, col_start:col_stop], axis = (1, 2))
ac_trace = np.mean(self._ac_array[:, row_start:row_stop, col_start:col_stop], axis = (1, 2))

self._ndw[self._trace_panels[0]][self._trace_panels[0]].data = fpl.utils.functions.heatmap_to_positions(pmd_trace[None, :], x_data)

@apasarkar apasarkar Mar 25, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@kushalkolar updating data in NDWidget is nice. You can access an NDImage or NDPositions object (like I've done here). It's data setter will access the underlying NDProcessor data and update it, and there's a re-draw that gets triggered. All good.

I find it weird that in order to auto-scale the subplot, I can't do the analogous thing: access the NDSubplot like:
self._ndw[self._trace_panels[0]].auto_scale()

I need to actually directly access the underlying figure subplot (like below). Think this is something we should change in the API?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Can chat later about API. The "subplot" access that's direct from ndw is just access to the add_<ndg> methods. To get the actual subplot you need to do ndw.figure["subplot"].

Comment thread masknmf/visualization/demixing_vis.py Outdated
@apasarkar apasarkar force-pushed the xarray-compatability branch from f9fe6a0 to 4fdea43 Compare March 29, 2026 21:46
@kushalkolar kushalkolar changed the title xarray compatability, remove squeeze, refactor lazy arrays xarray compatability, refactor lazy arrays, upgrade to fpl.NDWidget Mar 29, 2026
Comment thread masknmf/visualization/demixing_vis.py Outdated
Comment thread masknmf/visualization/demixing_vis.py Outdated
@apasarkar apasarkar mentioned this pull request Apr 2, 2026
14 tasks
@kushalkolar kushalkolar changed the title xarray compatability, refactor lazy arrays, upgrade to fpl.NDWidget refactor lazy arrays, upgrade to fpl.NDWidget Apr 10, 2026
* shift shape better block centers included

* Includes code to do piecewise rigid moco visualization
* Fixes more bugs in AC Array

* Fixes bug with centers and also massively accelerates the set roi average function by about 100x

* Removes print

* Initial commit containing some of the tracking code
* Fixes a small if vs elif statement in array interfaces

* Includes code for constructing and using the graph laplacian to correct background vs signal misattribution

* Includes full joint compression and detrending pipeline

* Includes the option to rescale the a matrix that gets exported in ac array

* Adds option to rescale export a in ac array and also adds all the filter steps
* Updates to the gradient motion corrector and fixes some issues with the standard 2p calcium pipeline on the infrastructure front

* Updates the deletion threshold again
* Includes better representation for contours in ac array

* Includes options for what summary image to display in demixing visualization, includes demixing overlay
@kushalkolar

kushalkolar commented May 8, 2026

Copy link
Copy Markdown
Collaborator Author

Random 4am adhd thoughts:

I think the NDWidget instancd or ReferenceIndex instance should be exposed as a property on all the viz so they can be composed by any other viz, ex: directly attach it to a behavior viz. So stuff like this is possible (I think this is the most elegant way to do it):

some_mask_nmf_viz = ...

# read-only property
some_mask_nmf_viz.ref_index

# user creates some other ndwidgets, or other libs that use NDWidget accept a `ReferenceIndex` instance
ndw_beh = NDWidget(ref_index=some_mask_nmf_viz.ref_index)
# this is now sycned with the calcium

For this to work, the non-spatial dim names have to be:

  • the same across all the viz the user is creating. If masknmf called it "time", then the non-masknmf viz you want to compose it with should also call it "time". For example, it can't be "t".
  • Or we allow reference index names to be mutable, I can see if this works
  • masknmf viz constructors have an optional kwarg for "time_ref_name", and any other ndwidget viz from other libs (such as behavior) will also have settable names for any reference dimensions that are created internally

apasarkar added 7 commits May 8, 2026 09:10
* Includes code for running detrending in PMD, including mean reassignment

* Returns the old filter code and makes the mask expansion much better

* Includes min thresholding code implementation and update to the pipeline for 2p somatic data

* Faster code for merging components, avoids quadratic runtime

* Faster support expansion code

* Further optimizations that accelerate the demixer by reusing computations across hals updates and reducing the number of fully expanded dense matrices

* Broad commit that ensures the demixing vis shows correctly scaled traces, threholded data only looks at positive neg or unconstrained parts in mad thresholding and other improvements to calcium pipeline

* Includes the right detrending code for 2p and 1p calcium data

* Includes pipeline updates including multiunit stuff etc
rgb_dim="c",
name=image_panels[2])

return ndw_corr.show()

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

better to return the ndw instance to the user for customization and so it can be closed later

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Minimal compatability with xarray, cleanup inheritance of lazy arrays

2 participants