Skip to content

Commit

Permalink
line edit; add default data tip
Browse files Browse the repository at this point in the history
  • Loading branch information
ecormany committed Aug 16, 2024
1 parent dc3acb5 commit 349606e
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 14 deletions.
5 changes: 4 additions & 1 deletion api/docs/v2/parameters/defining.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Types of Parameters

The API supports four types of parameters that correspond to Python built-in types: 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.

In addition, starting in version 2.20, the API supports CSV files as parameters. All data contained in CSV parameters, including numeric data, is initially interpreted as strings. See :ref:`using-rtp-types` for more information on manipulating CSV values.
In addition, starting in version 2.20, the API supports CSV files as parameters. All data contained in CSV parameters, including numeric data, is initially interpreted as strings. See :ref:`rtp-csv-data` for more information.

Boolean Parameters
------------------
Expand Down Expand Up @@ -199,4 +199,7 @@ Briefly describe the purpose of your CSV parameter when defining it.
During run setup, the technician can use the Flex touchscreen to select from files already stored on the robot or on an attached USB drive. Or in the Opentrons App, they can choose any file on their computer.

.. note::
The touchscreen and app currently limit you to selecting one CSV file per run. To match this limitation, the API will raise an error if you define more than one CSV parameter.

.. versionadded:: 2.20
24 changes: 14 additions & 10 deletions api/docs/v2/parameters/use_case_cherrypicking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Parameter Use Case – Cherrypicking
**********************************

Cherrypicking is a common liquid handling task: pipetting liquid from only certain wells on a source plate and placing them in order on a destination plate. This use case demonstrates how to use a CSV runtime parameter to automate this process and to customize it on every run — without having to modify the Python protocol itself.
A common liquid handling task is `cherrypicking`: pipetting liquid from only certain wells on a source plate and placing them in order on a destination plate. This use case demonstrates how to use a CSV runtime parameter to automate this process and to customize it on every run — without having to modify the Python protocol itself.

In this simple example, the CSV will only control:

Expand Down Expand Up @@ -44,14 +44,14 @@ Here is an example of a CSV file that fits this format, specifying three wells a
D1,C4,30
D2,H1,50
The technician would select this, or another file with the same structure, during run setup.
The protocol will rely on the data being structured exactly this way, with a header row and the three columns in this order. The technician would select this, or another file with the same structure, during run setup.

Our protocol will use the information contained in the selected CSV for loading labware in the protocol and the cherrypicking transfers themselves. We'll rely on the data being structured exactly this way, with a header row and the three columns in this order.
Our protocol will use the information contained in the selected CSV for loading labware in the protocol and performing the cherrypicking transfers.

Parsing the CSV
===============

To get the most out of the CSV data, we'll use the Python API's :py:meth:`.parse_as_csv` method to allow easy access to different portions of the data at different points in the protocol::
We'll use the Python API's :py:meth:`.parse_as_csv` method to allow easy access to different portions of the CSV data at different points in the protocol::

def run(protocol):

Expand Down Expand Up @@ -88,11 +88,14 @@ Finally, we'll loop over those slot names to load labware::

Note that loading labware in a loop like this doesn't assign each labware instance to a variable. That's fine, because we'll use :py:obj:`.ProtocolContext.deck` to refer to them by slot name later on.

The entire start of the ``run()`` function, including a pipette and fixed labware (i.e., labware not affected by the CSV runtime parameter) will look like this::
The entire start of the ``run()`` function, including a pipette and fixed labware (i.e., labware not affected by the CSV runtime parameter) will look like this:

.. code-block:: python
:substitutions:
from opentrons import protocol_api
requirements = {"robotType": "Flex", "apiLevel": "2.20"}
requirements = {"robotType": "Flex", "apiLevel": "|apiLevel|"}
def add_parameters(parameters):
Expand Down Expand Up @@ -125,7 +128,8 @@ The entire start of the ``run()`` function, including a pipette and fixed labwar
)
# load destination plate in deck slot C2
dest_plate = protocol.load_labware(
load_name="opentrons_96_wellplate_200ul_pcr_full_skirt", location="C2"
load_name="opentrons_96_wellplate_200ul_pcr_full_skirt",
location="C2"
)
# load source plates based on CSV data
for slot in unique_source_slots:
Expand All @@ -141,7 +145,7 @@ Now it's time to transfer liquid based on the data in each row of the CSV.

Once again we'll start by slicing off the header row of ``well_data``. Each remaining row has the source slot, source well, and volume data that we can directly pass to :py:meth:`.transfer`.

We also need to specify the destination well. We want the destinations to proceed in order according to :py:meth:`.Labware.wells`. To track this all in a single loop, we'll wrap our CSV data in an :py:obj:`.enumerate` item that will provide an index that increments each time through the loop. All together, the transfer loop looks like this::
We also need to specify the destination well. We want the destinations to proceed in order according to :py:meth:`.Labware.wells`. To track this all in a single loop, we'll wrap our CSV data in an :py:obj:`.enumerate` object to provide an index that increments each time through the loop. All together, the transfer loop looks like this::

for index, row in enumerate(well_data[1::]):
# get source location from CSV
Expand All @@ -162,12 +166,12 @@ We also need to specify the destination well. We want the destinations to procee
dest=dest_location
)

Let's unpack this. For each time through the loop, we first build the source location from the first (``row[0]``) and second (``row[1]``) item in the row list. We then construct a complete location reference with reference to ``protocol.deck``.
Let's unpack this. For each time through the loop, we build the source location from the first (``row[0]``) and second (``row[1]``) item in the row list. We then construct a complete location with respect to ``protocol.deck``.

Next, we get the volume for the transfer. All CSV data is treated as strings, so we have to cast it to a floating point number.

The last piece of information needed is the destination well. We take the index of the current iteration through the loop, and use that same index with respect to the ordered list of all wells on the destination plate.

With all the information gathered and stored in variables, all that's left is to pass that information as the arguments of ``transfer()``. With our example file, this will execute three transfers. By using a different CSV at run time, this code could complete up to 96 transfers (at which point it would run out of both tips and destination wells).

For more complex transfer behavior — such as setting location within the well — you could extend the CSV format and the associated code to work with additional data. And check out the `verified cherrypicking protocol <https://library.opentrons.com/p/flex-custom-parameters-cherrypicking>`_ in the Opentrons Protocol Library for further automation based on CSV data, including loading different types of plates, automatically loading tip racks, and more.
For more complex transfer behavior — such as adjusting location within the well — you could extend the CSV format and the associated code to work with additional data. And check out the `verified cherrypicking protocol <https://library.opentrons.com/p/flex-custom-parameters-cherrypicking>`_ in the Opentrons Protocol Library for further automation based on CSV data, including loading different types of plates, automatically loading tip racks, and more.
20 changes: 18 additions & 2 deletions api/docs/v2/parameters/using_values.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,30 @@ The :py:obj:`.CSVParameter.contents` parameter returns the entire contents of th

The :py:meth:`.CSVParameter.parse_as_csv` method returns CSV data in a structured format. Specifically, it is a list of lists of strings. This lets you access any "cell" of your tabular data by row and column index. This example parses a runtime parameter named ``csv_data``, stores the parsed data as ``parsed_csv``, and then accesses different portions of the data::

parsed_csv = protocol.params.csv_data
parsed_csv = protocol.params.csv_data.parse_as_csv()
parsed_csv[0] # first row (header, if present)
parsed_csv[1][2] # second row, third column
[row[1] for row in parsed_csv] # second column

.. versionadded:: 2.20

Remember that, like all Python lists, the lists representing your CSVs are zero-indexed.
Like all Python lists, the lists representing your CSVs are zero-indexed.

.. tip::

Remember that CSV parameters don't have default values. Accessing CSV data in any of the above ways will prevent protocol analysis from completing until you select a CSV file and confirm all runtime parameter values during run setup.

You can use a try–except block to work around this and provide the data needed for protocol analysis. First, add ``from opentrons.protocol_api import RuntimeParameterRequiredError`` at the top of your protocol. Then catch the error like this::
try:
parsed_csv = protocol.params.csv_data.parse_as_csv()
except RuntimeParameterRequiredError:
parsed_csv = [
["source slot", "source well", "volume"],
["D1", "A1", "50"],
["D2", "B1", "50"],
]


Limitations
===========
Expand Down
2 changes: 1 addition & 1 deletion api/docs/v2/runtime_parameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ It continues with a selection of use cases and some overall style guidance. When

- :ref:`Use case – sample count <use-case-sample-count>`: Change behavior throughout a protocol based on how many samples you plan to process. Setting sample count exactly saves time, tips, and reagents.
- :ref:`Use case – dry run <use-case-dry-run>`: Test your protocol, rather than perform a live run, just by flipping a toggle.
- :ref:`Use case – cherrypicking <use-case-cherrypicking>`: Use a CSV file to specify locations for a simple cherrypicking protocol.
- :ref:`Use case – cherrypicking <use-case-cherrypicking>`: Use a CSV file to specify locations and volumes for a simple cherrypicking protocol.
- :ref:`Style and usage <rtp-style>`: When you're a protocol author, you write code. When you're a parameter author, you write words. Follow this advice to make things as clear as possible for the technicians who will run your protocol.

0 comments on commit 349606e

Please sign in to comment.