-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(api): runtime parameters in Python API 2.18 (#14677)
# Overview Full documentation for setting up and using runtime parameters in Python protocols. Closes RTC-416, RTC-428, RTC-429, RTC-430, RTC-451 # Test Plan - Check content and formatting of all pages in the [sandbox](http://sandbox.docs.opentrons.com/docs-rtp/v2/runtime_parameters.html) - Simulate all [code from use case pages](https://gist.github.com/ecormany/9f4d871851ec4baceb9fae177663dd00). # Changelog - New landing page for Runtime Parameters - 6 new subpages - Unhide `ProtocolContext.params` in API Reference. ~Note, this still needs a docstring, either here or in a separate PR.~ Added [docstring](http://sandbox.docs.opentrons.com/docs-rtp/v2/new_protocol_api.html#opentrons.protocol_api.ProtocolContext.params). # Review requests Read some or all of it, try the code, tell me what can be better. # Risk assessment None --------- Co-authored-by: Sanniti Pimpley <[email protected]>
- Loading branch information
Showing
12 changed files
with
888 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
:og:description: Advice on choosing effective parameters in Opentrons Python protocols. | ||
|
||
.. _good-rtps: | ||
|
||
************************ | ||
Choosing Good Parameters | ||
************************ | ||
|
||
The first decision you need to make when adding parameters to your protocol is "What should be parameterized?" Your goals in adding parameters should be the following: | ||
|
||
1. **Add flexibility.** Accommodate changes from run to run or from lab to lab. | ||
2. **Work efficiently.** Don't burden run setup with too many choices or confusing options. | ||
3. **Avoid errors.** Ensure that every combination of parameters produces an analyzable, runnable protocol. | ||
|
||
The trick to choosing good parameters is reasoning through the choices the protocol's users may make. If any of them lead to nonsensical outcomes or errors, adjust the parameters — or how your protocol :ref:`uses parameter values <using-rtp>` — to avoid those situations. | ||
|
||
Build on a Task | ||
=============== | ||
|
||
Consider what scientific task is at the heart of your protocol, and build parameters that contribute to, rather than diverge from it. | ||
|
||
For example, it makes sense to add a parameter for number of samples to a DNA prep protocol that uses a particular reagent kit. But it wouldn't make sense to add a parameter for *which reagent kit* to use for DNA prep. That kind of parameter would affect so many aspects of the protocol that it would make more sense to maintain a separate protocol for each kit. | ||
|
||
Also consider how a small number of parameters can combine to produce many useful outputs. Take the serial dilution task from the :ref:`tutorial` as an example. We could add just three parameters to it: number of dilutions, dilution factor, and number of rows. Now that single protocol can produce a whole plate that gradually dilutes, a 2×4 grid that rapidly dilutes, and *thousands* of other combinations. | ||
|
||
Consider Contradictions | ||
======================= | ||
|
||
Here's a common time-saving use of parameters: your protocol requires a 1-channel pipette and an 8-channel pipette, but it doesn't matter which mount they're attached to. Without parameters, you would have to assign the mounts in your protocol. Then if the robot is set up in the reverse configuration, you'd have to either physically swap the pipettes or modify your protocol. | ||
|
||
One way to get this information is to ask which mount the 1-channel pipette is on, and which mount the 8-channel pipette is on. But if a technician answers "left" to both questions — even by accident — the API will raise an error, because you can't load two pipettes on a single mount. It's no better to flip things around by asking which pipette is on the left mount, and which pipette is on the right mount. Now the technician can say that both mounts have a 1-channel pipette. This is even more dangerous, because it *might not* raise any errors in analysis. The protocol could run "successfully" on a robot with two 1-channel pipettes, but produce completely unintended results. | ||
|
||
The best way to avoid these contradictions is to collapse the two questions into one, with limited choices. Where are the pipettes mounted? Either the 1-channel is on the left and the 8-channel on the right, or the 8-channel is on the left and the 1-channel is on the right. This approach is best for several reasons: | ||
|
||
- It avoids analysis errors. | ||
- It avoids potentially dangerous execution errors. | ||
- It only requires answering one question instead of two. | ||
- The :ref:`phrasing of the question and answer <rtp-style>` makes it clear that the protocol requires exactly one of each pipette type. | ||
|
||
Set Boundaries | ||
============== | ||
|
||
Numerical parameters support minimum and maximum values, which you should set to avoid incorrect inputs that are outside of your protocol's possibile actions. | ||
|
||
Consider our earlier example of parameterizing serial dilution. Each of the three numerical parameters have logical upper and lower bounds, which we need to enforce to get sensible results. | ||
|
||
- *Number of dilutions* must be between 0 and 11 on a 96-well plate. And it may make sense to require at least 1 dilution. | ||
- *Dilution factor* is a ratio, which we can express as a decimal number that must be between 0 and 1. | ||
- *Number of rows* must be between 1 and 8 on a 96-well plate. | ||
|
||
What if you wanted to perform a dilution with 20 repetitions? It's possible with two 96-well plates, or with a 384-well plate. You could set the maximum for the number of dilutions to 24 and allow for these possibilities — either switching the plate type or loading an additional plate based on the provided value. | ||
|
||
But what if the technician wanted to do just 8 repetitions on a 384-well plate? That would require an additional parameter, an additional choice by the technician, and additional logic in your protocol code. It's up to you as the protocol author to decide if adding more parameters will make protocol setup overly difficult. Sometimes it's more efficient to work with two or three simple protocols rather than one that's long and complex. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
:og:description: Define and set possible values for parameters in Opentrons Python protocols. | ||
|
||
.. _defining-rtp: | ||
|
||
******************* | ||
Defining Parameters | ||
******************* | ||
|
||
To use parameters, you need to define them in :ref:`a separate function <add-parameters>` within your protocol. Each parameter definition has two main purposes: to specify acceptable values, and to inform the protocol user what the parameter does. | ||
|
||
Depending on the :ref:`type of parameter <rtp-types>`, you'll need to specify some or all of the following. | ||
|
||
.. list-table:: | ||
:header-rows: 1 | ||
|
||
* - Attribute | ||
- Details | ||
* - ``variable_name`` | ||
- | ||
- A unique name for :ref:`referencing the parameter value <using-rtp>` elsewhere in the protocol. | ||
- Must meet the usual requirements for `naming objects in Python <https://docs.python.org/3/reference/lexical_analysis.html#identifiers>`__. | ||
* - ``display_name`` | ||
- | ||
- A label for the parameter shown in the Opentrons App or on the touchscreen. | ||
- Maximum 30 characters. | ||
* - ``description`` | ||
- | ||
- An optional longer explanation of what the parameter does, or how its values will affect the execution of the protocol. | ||
- Maximum 100 characters. | ||
* - ``default`` | ||
- | ||
- The value the parameter will have if the technician makes no changes to it during run setup. | ||
* - ``minimum`` and ``maximum`` | ||
- | ||
- For numeric parameters only. | ||
- Allows free entry of any value within the range (inclusive). | ||
- Both values are required. | ||
- Can't be used at the same time as ``choices``. | ||
* - ``choices`` | ||
- | ||
- For numeric or string parameters. | ||
- Provides a fixed list of values to choose from. | ||
- Each choice has its own display name and value. | ||
- Can't be used at the same time as ``minimum`` and ``maximum``. | ||
* - ``units`` | ||
- | ||
- Optional, for numeric parameters with ``minimum`` and ``maximum`` only. | ||
- Displays after the number during run setup. | ||
- Does not affect the parameter's value or protocol execution. | ||
- Maximum 10 characters. | ||
|
||
|
||
|
||
.. _add-parameters: | ||
|
||
The ``add_parameters()`` Function | ||
================================= | ||
|
||
All parameter definitions are contained in a Python function, which must be named ``add_parameters`` and takes a single argument. Define ``add_parameters()`` before the ``run()`` function that contains protocol commands. | ||
|
||
The examples on this page assume the following definition, which uses the argument name ``parameters``. The type specification of the argument is optional. | ||
|
||
.. code-block:: | ||
def add_parameters(parameters: protocol_api.ProtocolContext.Parameters): | ||
Within this function definition, call methods on ``parameters`` to define parameters. The next section demonstrates how each type of parameter has its own method. | ||
|
||
.. _rtp-types: | ||
|
||
Types of Parameters | ||
=================== | ||
|
||
The API supports four types of parameters: Boolean (:py:class:`bool`), integer (:py:class:`int`), floating point number (:py:class:`float`), and string (:py:class:`str`). It is not possible to mix types within a single parameter. | ||
|
||
Boolean Parameters | ||
------------------ | ||
|
||
Boolean parameters are ``True`` or ``False`` only. | ||
|
||
.. code-block:: | ||
parameters.add_bool( | ||
variable_name="dry_run", | ||
display_name="Dry Run", | ||
description="Skip incubation delays and shorten mix steps.", | ||
default=False | ||
) | ||
During run setup, the technician can toggle between the two values. In the Opentrons App, Boolean parameters appear as a toggle switch. On the touchscreen, they appear as *On* or *Off*, for ``True`` and ``False`` respectively. | ||
|
||
.. versionadded:: 2.18 | ||
|
||
Integer Parameters | ||
------------------ | ||
|
||
Integer parameters either accept a range of numbers or a list of numbers. You must specify one or the other; you can't create an open-ended prompt that accepts any integer. | ||
|
||
To specify a range, include ``minimum`` and ``maximum``. | ||
|
||
.. code-block:: | ||
parameters.add_int( | ||
variable_name="volume", | ||
display_name="Aspirate volume", | ||
description="How much to aspirate from each sample.", | ||
default=20, | ||
minimum=10, | ||
maximum=100, | ||
unit="µL" | ||
) | ||
During run setup, the technician can enter any integer value from the minimum up to the maximum. Entering a value outside of the range will show an error. At that point, they can correct their custom value or restore the default value. | ||
|
||
To specify a list of numbers, include ``choices``. Each choice is a dictionary with entries for display name and value. The display names let you briefly explain the effect each choice will have. | ||
|
||
.. code-block:: | ||
parameters.add_int( | ||
variable_name="volume", | ||
display_name="Aspirate volume", | ||
description="How much to aspirate from each sample.", | ||
default=20, | ||
choices=[ | ||
{"display_name": "Low (10 µL)", "value": 10}, | ||
{"display_name": "Medium (20 µL)", "value": 20}, | ||
{"display_name": "High (50 µL)", "value": 50}, | ||
] | ||
) | ||
During run setup, the technician can choose from a menu of the provided choices. | ||
|
||
.. versionadded:: 2.18 | ||
|
||
Float Parameters | ||
---------------- | ||
|
||
Float parameters either accept a range of numbers or a list of numbers. You must specify one or the other; you can't create an open-ended prompt that accepts any floating point number. | ||
|
||
Specifying a range or list is done exactly the same as in the integer examples above. The only difference is that all values must be floating point numbers. | ||
|
||
.. code-block:: | ||
parameters.add_float( | ||
variable_name="volume", | ||
display_name="Aspirate volume", | ||
description="How much to aspirate from each sample.", | ||
default=5.0, | ||
choices=[ | ||
{"display_name": "Low (2.5 µL)", "value": 2.5}, | ||
{"display_name": "Medium (5 µL)", "value": 5.0}, | ||
{"display_name": "High (10 µL)", "value": 10.0}, | ||
] | ||
) | ||
.. versionadded:: 2.18 | ||
|
||
String Parameters | ||
----------------- | ||
|
||
String parameters only accept a list of values. You can't currently prompt for free text entry of a string value. | ||
|
||
To specify a list of strings, include ``choices``. Each choice is a dictionary with entries for display name and value. Only the display name will appear during run setup. | ||
|
||
A common use for string display names is to provide an easy-to-read version of an API load name. You can also use them to briefly explain the effect each choice will have. | ||
|
||
.. code-block:: | ||
parameters.add_str( | ||
variable_name="pipette", | ||
display_name="Pipette type", | ||
choices=[ | ||
{"display_name": "1-Channel 50 µL", "value": "flex_1channel_50"}, | ||
{"display_name": "8-Channel 50 µL", "value": "flex_8channel_50"}, | ||
], | ||
default="flex_1channel_50", | ||
) | ||
During run setup, the technician can choose from a menu of the provided choices. | ||
|
||
.. versionadded:: 2.18 |
Oops, something went wrong.