-
Notifications
You must be signed in to change notification settings - Fork 0
Raymondwchang/streaming init cnmfe attrs #52
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
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 |
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 am not exactly sure what i am reviewing for here, this seems fine?
|
||
|
||
@dataclass | ||
class SpatialInitializationResult: |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
Signed-off-by: Raymond W. Chang <[email protected]>
📝 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 componentmeasurement
traits 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
ManagerInterface
works as a decorator interface. it takes care of all interactions withComponentManager
, so thatComponentManager
can focus on creating/updating/removing components, while thetransformers
can 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:
ComponentManager
manages all stored data, and works as the interface for all data manipulationsmeasurement
arrays and their attributes are stored inFootprintsManager
andTracesManager
. (More to be added as we add noise arrays, residual arrays, etc.)source
(the fluorescing thing) of themeasurements
(footprint and trace) is either aNeuron
or aBackground
objectsource
andmeasurement array
are linked by SourceID-ArrayIndex, where IDs are generated by Python'sid
function.ComponentManager
.The proposed workflow is:
new_frame
comes inTransformer
that will turn it into a usable dataTransformer
, it hitsManagerInterface
, which wraps around theTransformer
.ManagerInterface
grabs bothComponentManager
andnew_frame
ManagerInterface
looks at theTransformer
and determines what already-collected data it needs fromComponentManager
ManagerInterface
relays only the relevant data to theTransformer
(i.e.FootprintInitializer
)Transformer
to only do the standardlearn
andtransform
ManagerInterface
ManagerInterface
knows what kind of data theTransformer
returned, and asksComponentManager
to update its components.🧪 Testing
🛠️ Dependencies
✅ Checklist
🔗 Additional Resources