-
Notifications
You must be signed in to change notification settings - Fork 179
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
feat(api): support flow rate (uL/sec) in JSON protocols #2123
Conversation
- update JSON protocol schema in shared-data - add "default-values" field to PD saved files - support flow rate in JSON protocol executor
"description": "Special keyword specifying the model of the pipette. TODO finalize these model names they are still TBD", | ||
"type": "string", | ||
"enum": [ | ||
"p10_single_v1", |
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 would like these _v*
version suffixes to go away in JSON protocols (I have an WIP PR that's been up for a while to do this), but if flow rate changes between pipette model versions, then we do indeed need the version suffix in the "default-values"
-- but it's fine if it's not in the pipette itself. So the version suffix would only be relevant when applying default values, and that could be determined at runtime... wish there was a nicer way though
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.
@IanLondon and @b-cooper does my comment I added in #1825 sum up what we discussed a while back to the best of y'all's knowledge?
Also (perhaps @andySigler could jump in here): what are the advantages / disadvantages to locking a default flow rate to a given pipette configuration rather than a specific model? It might be nice to say all p300_single
s have the same default flow rate if we could get away with it
@@ -163,18 +219,7 @@ | |||
"enum": ["left", "right"] | |||
}, | |||
"model": { | |||
"description": "Special keyword specifying the model of the pipette. TODO finalize these model names they are still TBD", |
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 moved to a "definition"
above (and added v1.3 suffix set)
raise ValueError( | ||
'Command tried to use labware "{}", but that ID does not exist ' + | ||
'in protocol\'s "labware" section'.format(labwareId)) | ||
return labware.wells(well) |
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.
Laura pointed out that Placeable.get
is a confusing alias for Placeable.wells
so I'm going with the more explicit here -- shouldn't change anything
Codecov Report
@@ Coverage Diff @@
## edge #2123 +/- ##
=========================================
+ Coverage 32.18% 33.6% +1.42%
=========================================
Files 455 456 +1
Lines 7336 7698 +362
=========================================
+ Hits 2361 2587 +226
- Misses 4975 5111 +136
Continue to review full report at Codecov.
|
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.
🥇
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 PR is also serving as its own ticket.
overview
JSON protocol schema + JSON protocol executor (in Python API) + PD all updated to support setting flow rate for aspirate and dispense commands.
This overview is gonna get a little long, but please think it through, because we need a pattern of managing implicit/default values in protocols that permits "reproducibility by default, and flexibility by choice" for protocol creation, editing, and execution.
Background context: In an upcoming ticket (#1323), PD will allow user to specify "Use default flow rate" vs "Use flow rate of __ uL/sec", for each step.
For "use specified flow rate", it's a straightforward problem. This PR allows JSON protocols to include a
flow-rate
parameter in aspirate and dispense commands that sets the flow rate for that command only.But what does "use default flow rate" mean in PD? Specifically, where do these values come from (and at what point in the revision history)?
A protocol that is working fine shouldn't suddenly & silently change its operation when we update the defaults. So this PR introduces the key
"default-values"
which has inner keys"aspirate-flow-rate"
and"dispense-flow-rate"
for each pipette model. When a user is saving a protocol, PD will include the flow rate defaults fromshared-data/robot-data/pipette-config.json
(whatever the values were when that version of PD was built). Other 3rd party protocol creators will be expected to do the same thing.When a user goes to run a protocol, the JSON protocol executor will use these saved values for that protocol. With this PR, the JSON protocol executor will never use the API default values for flow-rate.
(Note: Default flow rate values used by the API also come from pipette-config.json. But they can mis-match -- the API can be built with a newer or older version of that file, than the version of the file built into the version of PD which the protocol was saved with. Whoof that is hard to put in a sentence)
In the future, by saving flow rate default values in the JSON protocol, we'll be able to do things like:
I think the
"default-values"
key will expand to encompass more of those implicit constant values that go into executing a protocol. But there is a limit to it -- otherwise we'll wind up having to detail every constant value in the Python API/server and save it in every protocol! We have to be choosy about what really matters to the protocol, and what can be left implicit and a pure responsibility of the API.changelog
review requests
You can also change the flow rates for specific pipettes under the
"default-values"
key. These values are used when the"flow-rate"
param is unspecified.How do you make sure that the flow rate is actually changed? Unfortunately I think the best way is to use a significantly fast (4x) or slow (1/4x) flow rate value and test with water on a robot... it's hard to even use print statements to see that it's really working in Pipette. But
set_speed
is a decent place to put a debugging print statement, keep in mind it will get called 2x once with aspirate and once with dispense, for eachPipette.set_flow_rate
😢