Raymondwchang/streaming init cnmfe attrs#52
Conversation
feat: manager_interface.py now takes care of interfacing with componentmanager.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #52 +/- ##
==========================================
- Coverage 91.90% 89.93% -1.97%
==========================================
Files 55 57 +2
Lines 1420 1510 +90
==========================================
+ Hits 1305 1358 +53
- Misses 115 152 +37
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
|
just read the PR description, haven't read the code yet, but one initial reaction:
The |
|
ohh that makes sense. i was wondering how it was coming up with the integer numbers |
sneakers-the-rat
left a comment
There was a problem hiding this comment.
I am not exactly sure what i am reviewing for here, this seems fine?
|
|
||
|
|
||
| @dataclass | ||
| class SpatialInitializationResult: |
There was a problem hiding this comment.
give these a parent class - the main thing you want from Results classes is a consistent interface. so it seems like atm these are mutually exclusive complements: spatial initialization is x/y coords (right?) and temporal is timeseries. what about the other kinds of initializer types? how will you know how to combine them? will each produce a different kind of output, or will some produce overlapping types with the current result types? having a generic result class that has empty values for each of the possible kinds of things would be better than each initializer type having its own result class
| def learn_one(self, components: ComponentManager, X: xr.DataArray) -> T: | ||
| """Learn step extracts needed data from manager and passes to transformer.""" | ||
| match initializer_type: | ||
| case InitializerType.SPATIAL: |
There was a problem hiding this comment.
yeah immediately see the problems from above^. if each results class is unique, you need wrappers like this. presumably different kinds of transformers take different types of data, so having one results class and then always passing that one class to the transformers seems less fragile than this
There was a problem hiding this comment.
i think you might be suggesting might have been what i had originally. at first there was no decorator and i was just adding/subtracting components directly inside the transformers, but i didn't like how tranformers were not only doing the raw transformations, but also taking on interfacing with the data structure.
| """ | ||
|
|
||
| def decorator(transformer_class: Type[T]) -> Type[T]: | ||
| class ManagerWrappedTransformer(cast(type, transformer_class)): |
There was a problem hiding this comment.
I think that without generic __getattr__s that forward attribute access on to the wrapped class, you're going to get into a pretty tricky spot pretty quick
| spatial_axes: tuple = ("height", "width") | ||
| """Spatial axes for pixel statistics""" | ||
|
|
||
| def validate(self): |
There was a problem hiding this comment.
do this as a __post_init__ or you'll inevitably forget to call it (and needing to call it is a pain in the ass)
… into a single file
…tests need to be updated.
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
Signed-off-by: Raymond W. Chang <raymond.w.jang@gmail.com>
📝 Description
populate transformers that initialize non-fundamental (i.e. anything besides footprints and fluorescence) matrices - sufficient statistics, residual buffers, etc.
as the way these transformers interact with components are varied - some take in footprints and output traces, some take in footprint AND traces and output pixel correlation, etc., I am adding a decorator class that works as an interface between the transformers and
ComponentManager.a little worried about how to ensure a proper plug-in with
ComponentManager,as we keep on adding componentmeasurementtraits and different types oftransformers.📌 Related Issue
🔍 Type of Change
✨ New Feature: Introducing new functionality
🧹 Refactor: Code changes that neither fix a bug nor add a feature
🚀 Implementation Details
ManagerInterfaceworks as a decorator interface. it takes care of all interactions withComponentManager, so thatComponentManagercan focus on creating/updating/removing components, while thetransformerscan be decoupled from how components are structured and solely deal with getting what it needs, transforming it, and returning the results.The current data structure is:
ComponentManagermanages all stored data, and works as the interface for all data manipulationsmeasurementarrays and their attributes are stored inFootprintsManagerandTracesManager. (More to be added as we add noise arrays, residual arrays, etc.)source(the fluorescing thing) of themeasurements(footprint and trace) is either aNeuronor aBackgroundobjectsourceandmeasurement arrayare linked by SourceID-ArrayIndex, where IDs are generated by Python'sidfunction.ComponentManager.The proposed workflow is:
new_framecomes inTransformerthat will turn it into a usable dataTransformer, it hitsManagerInterface, which wraps around theTransformer.ManagerInterfacegrabs bothComponentManagerandnew_frameManagerInterfacelooks at theTransformerand determines what already-collected data it needs fromComponentManagerManagerInterfacerelays only the relevant data to theTransformer(i.e.FootprintInitializer)Transformerto only do the standardlearnandtransformManagerInterfaceManagerInterfaceknows what kind of data theTransformerreturned, and asksComponentManagerto update its components.🧪 Testing
🛠️ Dependencies
✅ Checklist
🔗 Additional Resources