Add thermocycler module
Checking in work here for the thermocycling module. Still in progress
@rickwierenga How do we want to handle slot assignments for the PCR module? In my test script I'm assigning it to slot 7, which works fine, but then lh.summary() yields:
Deck: 624.3mm x 565.2mm
+-----------------+-----------------+-----------------+
| | | |
| 10: Empty | 11: Empty | 12: trash_co... |
| | | |
+-----------------+-----------------+-----------------+
| | | |
| 7: pcr | 8: Empty | 9: Empty |
| | | |
+-----------------+-----------------+-----------------+
| | | |
| 4: Empty | 5: Empty | 6: Empty |
| | | |
+-----------------+-----------------+-----------------+
| | | |
| 1: Empty | 2: Empty | 3: Empty |
| | | |
+-----------------+-----------------+-----------------+
In reality, the module covers all of slot 7, all of slot 9, and some of slot 8 & 11 such that you couldn't put a tip rack on there (water beaker would be fine). Do we want to add some custom logic so that the thermocycler automatically takes up slot 7&10 or just leave it as is?
how does OT do it in their official software? It seems that slide 10 needs to be blocked too, and probably 8 and 11 as well.
I'm not sure how to best model this in PLR. The collision checker is easy, but how Opentrons handles this in the API will unfortunately have to impact our decision. We also have to make the summary look nice.
I'm not sure how to best model this in PLR. The collision checker is easy, but how Opentrons handles this in the API will > unfortunately have to impact our decision. We also have to make the summary look nice.
Yea - I'm going to implement an MVP version of this first without deck modifications, but I agree that we need to include those changes.
@rickwierenga It's working giving the Opentrons docs on the thermocycler a read. They have a few nice methods that we should discuss implementing, including:
- Block Max Voume (high priority)
- "The Thermocycler’s block temperature controller varies its behavior based on the amount of liquid in the wells of its labware. Accurately specifying the liquid volume allows the Thermocycler to more precisely control the temperature of the samples. You should set the
block_max_volumeparameter to the amount of liquid in the fullest well, measured in µL. If not specified, the Thermocycler will assume samples of 25 µL."
- "The Thermocycler’s block temperature controller varies its behavior based on the amount of liquid in the wells of its labware. Accurately specifying the liquid volume allows the Thermocycler to more precisely control the temperature of the samples. You should set the
- Hold Time
- "You can optionally instruct the Thermocycler to hold its block temperature for a specific amount of time. You can specify
hold_time_minutes,hold_time_seconds, or both (in which case they will be added together)." - This would be nice to add to the temperature controller as well.
- "You can optionally instruct the Thermocycler to hold its block temperature for a specific amount of time. You can specify
It would also be good to discuss how to implement good cycling logic - the Opentons solution seems quite elegant to me.
Block Max Voume (high priority)
should be doable using PLR volume trackers
Hold Time
this is perhaps something that can be implemented in the frontend
It would also be good to discuss how to implement good cycling logic - the Opentons solution seems quite elegant to me.
I like the explicit Python version in the docs over the list of dictionaries. A core assumption with PLR is that protocols are best expressed as Python code (because it's Turing complete and integrates well). We should definitely provide basic utilities for the basic PCR cycling steps, as a frontend Python method.
I'm not a fan of expressing this in a list as much. This is very much a secondary and worse way to use it, and unnecessarily increases complexity of PLR. (PLR users can implement this easily themselves in their scripts, if they prefer)
The "this code would generate 60 lines in the protocol’s run log" (from OT docs) seems an advantage, not a disadvantage, as logs are supposed to be explicit imo.
+you get type checking, which you don't get with lists/dicts
I added an implementation for running profiles, but have not tested it yet. @rickwierenga Could you review for a sanity check?
Something else to consider is that the OT API also lets you define repetitions like tc_mod.execute_profile(steps=profile, repetitions=20, block_max_volume=32) (docs) where you can repeat a specific profile. Thoughts on adding this vs just having the user assemble complete profiles beforehand?
Hi everyone,
I am just reading through this PR and have to familiarize myself more with the PLR-integration of the OT-2.
But, more generally speaking, I believe the agnostic ThermocyclerBackend class should have a .set_ramp_rate method and a self.ramp_rate attribute.
Not all thermocyclers allow modifications of their ramp rate but many do, and it can be very beneficial for different assays to control this parameter, particularly for in vitro+ex vivo applications like DNA origami. This guide, TF: Thermal Cycler Features—Six Key Considerations is very nice to check broadly what the class should cover.
Good flag @BioCam. I plan to resume work on this PR in a couple weeks and can look to integrate this.