-
Notifications
You must be signed in to change notification settings - Fork 33
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
Masking #172
base: master
Are you sure you want to change the base?
Conversation
- add mask/unmask and apply_mask methods to TreeNeuron, MeshNeuron and Dotprops - add is_masked property for all neurons - add `navis.NeuronMask` class - add __length__ to all neurons - dotprops: clear `_tree` with temporary attributes
- fix NeuronMask doctest - TreeNeuron.un/mask: make sure to re-classify - TreeNeuron.unmask: fix re-connecting
hi @schlegelp - this looks really cool and I'm sure will be useful to have in Navis! I've also been working on generalizing code for doing these kinds of masking operations to arbitrary collections of morphology representations that all have some kind of spatial connection to each other: https://bdpedigo.github.io/morphlink/examples/microns_example/#masking-and-filtering still mostly at the stage of me trying to get feedback on an interface that feels good. More and more I am finding places where I have a collection of arbitrary representations, say:
Since I keep ending up with these arbitrary collections of layers, I am trying to divorce the code that dictates how to map between layers and transfer things like masks between them from the code that does other computations on whatever representation I have. Anyway - I don't think helpful here since it looks like you already have it working, but would be interested in seeing whether we could make the kinds of masking operations like you have here and are in meshparty more general. Hopefully that could also be a framework for building more specific neuron classes with specific features on top |
Cool! I saw you making the FYI: unfortunately, there already is a |
- add .view() methods to neuron objects - by default, do not copy data - bits and pieces
This PR adds an interface for masking neurons for analyses/processing:
NeuronMask
context managerThe interface currently looks like this:
A few additional notes:
mask
can be a boolean array, a neuron property (e.g. a column in the node table), or a function that takes a neuron and returns one of the first twoNeuronMask
context manager is the primary interface but people can also mess around with.mask()
+.unmask()
if they need more control.apply_mask()
method that makes the mask permanent.Modifying masked neurons
By default, unmasking will reset the neuron to its original state. Users can use e.g.
.unmask(reset=False)
orNeuronMask(..., reset=False)
to instead re-combine the masked and unmasked data. That works well for non-destructive operations such as e.g. smoothing or downsampling where the boundary vertices/nodes are not modified:Destructive operations (e.g.
navis.prune_twigs
) are more tricky and I think we may end up having to adjust those functions to deal with masked neurons as special cases. To give you an example: skeletonization of neurons often leaves ugly spikes where the soma is. These could be removed by masking the neuron to within a given radius of the soma and removing all twigs below a given threshold. However, with the current implementation the actual neurites coming off the soma would also look awfully like twigs and might incorrectly get pruned off - which in turn will break the connectivity of the skeleton. Perfectly solvable problem but I'm still thinking about a generalizable approach that would minimize maintenance burden.Comments/thoughts, @ceesem @bdpedigo?