-
Notifications
You must be signed in to change notification settings - Fork 187
feat(api, shared-data): add dynamic pipetting into liquid classes #20232
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
base: edge
Are you sure you want to change the base?
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## edge #20232 +/- ##
===========================================
- Coverage 56.46% 25.35% -31.12%
===========================================
Files 3626 3632 +6
Lines 301067 302987 +1920
Branches 42309 42633 +324
===========================================
- Hits 170002 76825 -93177
- Misses 130839 226146 +95307
+ Partials 226 16 -210
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
3b83afa to
f3c1a6c
Compare
sfoster1
left a comment
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.
Some inline things; I think we should get naming consistent between defs and code, I think there's some stuff accidentally left in the pr.
In general I'm a little uneasy about the specificity of this implementation. There's a tip position and an override tip position, and the only way to go from override to backup is if specific exceptions about not having liquid height estimation data are thrown. That definitely works for the specific issue where maybe we don't have height data for a variety of reasons. But there's also more reasons we might want different tip positions:
- Maybe we trust filtertips, or some future filter tips, less
- Maybe we want to do different things depending on the volume in the well (for instance, maybe we find some wells where under a certain volume we know our estimations are unreliable)
Adding different kinds of reasons to pick a different position is something that would either take a lot of refactoring from here or require more and more little checks and exceptions to be raised from lower layers and more and more specific named entries in the classes as fallbacks.
That said, I don't know if we need to go all the way to having an embedded conditional in the defs like previously proposed. I think we should give the new position groups some structure. Rather than having the flat entries aspiratePosition, aspirateEndPosition, overrideAspiratePosition, overrideAspirateEndPosition side by side, have aspiratePositions: [{name, start, end}, {name, start, end}] where name is some name like "dynamic" or "static". Then, the implied logic (and the specification in the class schema) is that the code will try and use these positions in order from the array, and if there's an exception go to the next.
That at least means that if we want to add more entries we won't need more schema changes; it avoids the thing I hate most in schemas which is flat entries with specific names, which is really just putting structure in element names when it could be in actual structure; and it gives some nicer specifiable names to things.
| "additionalProperties": false, | ||
| "description": "Properties specific to the aspirate function.", | ||
| "properties": { | ||
| "aspirateEndPosition": { |
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.
this doesn't seem right? there's no corresponding change in the engine aspirate command or dispense command, did there used to be?
| "aspirate": { | ||
| "submerge": { | ||
| "startPosition": { | ||
| "positionReference": "liquid-meniscus", |
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.
we shouldn't need to change the v1 fixtures, right?
| "positionReference": { | ||
| "type": "string", | ||
| "description": "Reference point for positioning.", | ||
| "enum": ["well-bottom", "well-top", "well-center", "liquid-meniscus"] |
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.
we shouldn't need to change the v1 schema, right?
| return self._override_dispense_position or self._dispense_position | ||
|
|
||
| @property | ||
| def dispense_end_position(self) -> Optional[TipPosition]: |
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.
it's a bit confusing that it's endPosition and overrideEndPosition in the class defs, but end_position and fallback_end_position in the code. can we make these the same?
| correction_volume = aspirate_props.correction_by_volume.get_for_volume( | ||
| self._instrument.get_current_volume() + volume | ||
| ) | ||
| print(f"Should be in place {self._target_end_location is None}") |
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.
debug print to remove
| # Will this cause more harm than good? Is there a better alternative to this? | ||
| reference_point = well.get_center() | ||
| case PositionReference.LIQUID_MENISCUS_END | PositionReference.LIQUID_MENISCUS: | ||
| estimated_liquid_height = well.estimate_liquid_height_after_pipetting( |
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.
this is weird, it duplicates the code that's in aspirateWhileTracking doesn't it? i thought we had the capability to call aspirateWhileTracking with end position meniscus-end AND a user-provided offset?
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.
or is the intent to force an exception to raise here rather than in the command? if so, can we add an engine query function that lets us say "hey can you do meniscus-end for this well right now"
| So, for liquid height estimation after an aspirate, well_volume_difference is | ||
| expected to be a -ve value while for a dispense, it will be a +ve value. | ||
| """ | ||
| match position_reference: |
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.
just for diff improvements and indentation levels, instead of the recursion can we
- move the
matchstatement into its own function_match_absolute_point...or something - change
absolute_point_from_position...to first call_match_absolute_point...with the primary, catch the exception, and then call it with the fallback?
|
Note to self/@jbleon95: I haven't read through all of changes yet, but I don't see any edits the public transfer functions in |
Overview
This PR encompases a first pass implementation of allowing dynamic tracking with liquid classes. As is there is
no super convenient waya new way for users to edit positions in transfer properties. There is no default selection for any current liquid classes and is defaulted toNoneeverywhere.But as a first pass this does add a few new features
which will be part of another PRand the minimal implementation of that is enabled for testing