diff --git a/api/docs/v2/modules/stacker.rst b/api/docs/v2/modules/stacker.rst new file mode 100644 index 00000000000..73b8037a2ec --- /dev/null +++ b/api/docs/v2/modules/stacker.rst @@ -0,0 +1,124 @@ +:og:description: How to use the Flex Stacker Module in a Python protocol. + +.. _stacker: + +******************* +Flex Stacker Module +******************* + +The Flex Stacker is an external module that provides automated storage of well plates, Flex tip racks, or reservoirs. The Stacker's attached shuttle moves labware from the stack to the deck for use during a protocol. + +The Stacker is represented in code by a ``StackerContext`` object that includes methods for storing and retrieving labware. You can also use helper commands in your protocol to calculate how many labware the Stacker can store at once. + +Loading and Deck Slots +======================== + +Up to four Stacker Modules can be attached to the right side of your Flex, creating deck slots A4--D4. Each Stacker occupies a deck slot in column 4, with the shuttle in column 3. + +Start by loading each Stacker as you would any other module: + +.. code-block:: python + + stacker_1 = protocol.load_module( + module_name="flexStackerModuleV1", + location="A4" + ) + stacker_2 = protocol.load_module( + module_name="flexStackerModuleV1", + location="C4" + ) + +Each Stacker occupies a deck slot in column 4, with the attached shuttle in column 3. In this example, Stacker shuttles occupy deck slots A3 and C3. + +Adding Labware to the Stacker +============================== + +Next, you'll need to define the *type* and amount of labware the Stacker will store. Throughout yor protocol, the Flex automatically moves labware, like well plates or tip racks, from inside the Stacker to the deck. + +Each Stacker can hold a labware stack of up to: + +- 7 Flex tipracks (6 in the Stacker and 1 on the shuttle) +- 48 PCR plates, like +- 16 deep well plates, like + +You'll need to use :py:meth:`~.FlexStackerContext.set_stored_labware` to configure the Stacker before adding or removing labware during a protocol. Only one type of labware can be stored in each Stacker at one time. + +.. code-block:: python + + stacker_1.set_stored_labware( + load_name="opentrons_flex_96_tiprack_200ul", + count=6, + lid="opentrons_flex_tiprack_lid" + ) + stacker_2.set_stored_labware( + load_name="opentrons_96_wellplate_200ul_pcr_full_skirt", + count=12 + ) + +In this example, `stacker_1` is configured to hold 6 Flex tip racks, each with a compatible lid. Flex tip racks must have lids to be properly stored in the Stacker. `stacker_2` is configured to hold 12 PCR plates without lids. + +Configuring the Stacker assigns a labware stack to this deck slot. You can use the Stacker and shuttle as a normal deck slot earlier in your protocol with :py:meth:`~.ProtocolContext.load_labware()`. You'll need to move this labware elsewhere on the deck before configuring and using the Stacker for storage. + +.. note:: + Different labware have varying `z` heights. One well plate might be 2 mm taller than another, affecting the number of plates the Stacker can store at once. The API includes helper commands to calculate how many labware the Stacker can hold: + + - `.ModuleContext.get_max_storable_labware()` + - `.ModuleContext.get_current_storable_labware()` + - `.ModuleContext.get_stored_labware()` + + Use ``get_max_storable_labware()`` or ``get_current_storable_labware()`` to calculate the maximum or current number of labware the Stacker can store, based on either the labware definition or the Stacker's current storage conditions. + + Like other hardware modules, the Stacker doesn't verify the labware you place inside it. If your Stacker is configured correctly, you can use ``get_stored_labware()`` throughout your protocol to check an updated list of labware stored inside. + +Using Stacker Labware +====================== +During a protocol, use `~.FlexStackerContext.retrieve()` to automatically access a single piece of labware to use on the Flex deck. + +.. code-block:: python + + stacker_1.retrieve() + protocol.move_labware( + labware="opentrons_flex_96_tiprack_200ul", + new_location="B2", + use_gripper="True" + ) + +Here, the Flex tip rack at the bottom of the labware stack is moved to the shuttle in slot A3. Then, use the Flex Gripper or manually move the new tip rack elsewhere on the deck. + +To add more labware to a Stacker, use `~.FlexStackerContext.store()`:: + + protocol.move_labware( + labware="opentrons_96_wellplate_200ul_pcr_full_skirt", + new_location=stacker_2, + use_gripper="True" + ) + stacker_2.store() + +After placing labware on the shuttle in slot C3, ``stacker_2`` stores another well plate on the bottom of the stack. + +To mark a Stacker as completely full or empty, use `~.FlexStackerContext.fill()` or `~.FlexStackerContext.empty()`:: + + # mark the second Stacker as empty + stacker_2.empty() + + # configure the second Stacker and fill with new labware + stacker_2.set_stored_labware( + load_name="nest_12_reservoir_15ml", + count=8 + ) + stacker_2.fill(8, "Add 8 reservoirs to stacker_2.") + +Both ``fill()`` and ``empty()`` pause the protocol and allow you to manually add or remove labware from the Stacker. Each method assumes labware is loaded or moved ``off_deck``. + + + + + + + + + + + + + diff --git a/api/docs/v2/new_modules.rst b/api/docs/v2/new_modules.rst index 594ceca3867..63a1ea51350 100644 --- a/api/docs/v2/new_modules.rst +++ b/api/docs/v2/new_modules.rst @@ -8,6 +8,7 @@ Hardware Modules .. toctree:: modules/setup + modules/stacker modules/absorbance_plate_reader modules/heater_shaker modules/magnetic_block diff --git a/api/docs/v2/new_protocol_api.rst b/api/docs/v2/new_protocol_api.rst index 3ca71ea99a9..750b2d93765 100644 --- a/api/docs/v2/new_protocol_api.rst +++ b/api/docs/v2/new_protocol_api.rst @@ -65,6 +65,14 @@ Absorbance Plate Reader :inherited-members: +Flex Stacker +------------ + +.. autoclass:: opentrons.protocol_api.FlexStackerContext + :members: + :exclude-members: calibrate, broker, geometry, load_labware_object, load_labware + :inherited-members: + Heater-Shaker ------------- diff --git a/api/src/opentrons/protocol_api/module_contexts.py b/api/src/opentrons/protocol_api/module_contexts.py index b3d9e805049..cf267bef240 100644 --- a/api/src/opentrons/protocol_api/module_contexts.py +++ b/api/src/opentrons/protocol_api/module_contexts.py @@ -248,7 +248,7 @@ def load_labware_by_name( ) -> Labware: """ .. deprecated:: 2.0 - Use :py:meth:`load_labware` instead. + Use ``load_labware`` instead. """ _log.warning("load_labware_by_name is deprecated. Use load_labware instead.") return self.load_labware( @@ -1141,7 +1141,9 @@ def serial_number(self) -> str: @requires_version(2, 25) def retrieve(self) -> Labware: - """Retrieve a labware from the Flex Stacker and place it on the shuttle. + """Retrieve a labware from the Flex Stacker and move it onto the shuttle. + + The Stacker will retrieve the bottom-most labware in the stack. :returns: The retrieved :py:class:`Labware` object. This will always be the main labware, even if the Flex Stacker contains labware on an adapter. To get the adapter object, @@ -1159,7 +1161,10 @@ def retrieve(self) -> Labware: @requires_version(2, 25) def store(self) -> None: - """Move the labware currently on the Flex Stacker shuttle into the Flex Stacker.""" + """Move a labware currently on the Flex Stacker shuttle into the Flex Stacker. + + The labware must be the same type the Stacker is configured to store using :py:meth:`.set_stored_labware()`. If labware is currently stacked inside the module, this method moves the new labware to the bottom-most position of the stack. + """ self._core.store() def _labware_to_cores(self, labware: Sequence[Labware]) -> list[LabwareCore]: @@ -1186,22 +1191,22 @@ def get_max_storable_labware_from_list( """Limit a list of labware instances to the number that can be stored in a Flex Stacker. A Flex Stacker has a limited amount of internal space and computes the number of labware - (or labware with lids or adapters) that it can store based on the heights of the labware - and the amount they overlap when placed on top of each other. To know how many of a given - labware the Flex Stacker can store, the Flex Stacker must know what labware it is. + (or labware with lids or adapters) that it can store based on the ``z`` heights of the labware + and the amount they overlap when stacked. To calculate how many of a given + labware the Stacker can store, the labware type must be specified. - You can use this function to take a list of labware and return the elements that the - stacker can currently store from it. The returned list is then guaranteed to be suitable + Provide a list of labware to this function to return the maximum number of labware of the given type that the + Stacker can store. The returned list is guaranteed to be suitable for passing to :py:meth:`.set_stored_labware_items`. - This function limits the list of labware based on the overall maximum number the stacker + This function limits the list of labware based on the overall maximum number the Stacker can hold and will not change as labware is added or removed. To limit a list of labware to the amount that will currently fit in the Flex Stacker, use :py:meth:`.get_current_storable_labware_from_list`. .. note:: - If a stacking offset is provided, make sure the same value is used when + If a ``z`` stacking offset is provided, be sure to specify the same value when configuring the Flex Stacker with :py:meth:`.set_stored_labware_items`. See :py:meth:`.set_stored_labware_items` for more details on stacking offset. @@ -1220,11 +1225,13 @@ def get_current_storable_labware_from_list( """Limit a list of labware instances to the number that the Flex Stacker currently has space for, based on the labware that is already stored in the Flex Stacker. - You can use this function to take a list of labware and return the elements that the - stacker can currently store from it. The returned list is then guaranteed to be suitable + A Flex Stacker has a limited amount of internal space and computes the number of labware that it can store based on the ``z`` height of the labware and the amount they overlap when stacked. + + Provide a list of labware to this function to return the elements that the + Stacker can currently store from it. The returned list is then guaranteed to be suitable for passing to :py:meth:`.fill`. - The number of elements in the returned list will change as labware is added to or removed from + The number of elements in the returned list will change as labware is added or removed from the Flex Stacker. To get a list limited to the overall maximum number of labware the Flex Stacker can store, use :py:meth:`.get_max_storable_labware_from_list`. """ @@ -1236,11 +1243,13 @@ def get_current_storable_labware_from_list( @requires_version(2, 25) def get_max_storable_labware(self) -> int: - """Get the number of labware that the Flex Stacker can store with its current stored labware configuration. + """Get the maximum number of labware that the Flex Stacker can store. - You can use this function to get the total number of labware that the Flex Stacker can store. This - number is the overall maximum and will not change as labware is added or removed. To get the space - currently available in the Flex Stacker, use :py:meth:`.get_current_storable_labware`. + Use this function to return the total number of labware that the Flex Stacker can store. A Stacker has a limited amount of internal space and calculates the total number of labware that can be stored based on the ``z`` height of the labware and the amount they overlap when stacked. + + The total number is calculated based on the labware definition for the type of labware the Stacker is currently configured to store using :py:meth:`.set_stored_labware()`. This + number is the overall maximum and will not change as labware is added or removed. To get the number of labware that can + be stored in the Flex Stacker based on its current conditions, use :py:meth:`.get_current_storable_labware`. """ return self._core.get_max_storable_labware() @@ -1248,7 +1257,9 @@ def get_max_storable_labware(self) -> int: def get_current_storable_labware(self) -> int: """Get the number of labware that the Flex Stacker currently has space for. - The number will change as labware is added or removed. To get the overall maximum number of labware the + Use this function to return the total number of labware that the Flex Stacker can store. A Stacker has a limited amount of internal space and calculates the number of labware that can be stored based on the ``z`` height of the labware and the amount they overlap when stacked. + + The number is calculated based on the labware definition for the type of labware the Stacker is currently configured to store using :py:meth:`.set_stored_labware()`. This function returns a number based on the current storage conditions of the Stacker, and will change as labware is added or removed. To get the overall maximum number of labware the Flex Stacker can store, use :py:meth:`.get_max_storable_labware`. """ return self._core.get_current_storable_labware() @@ -1259,43 +1270,42 @@ def set_stored_labware_items( labware: list[Labware], stacking_offset_z: float | None, ) -> None: - """Configure a Flex Stacker by providing an initial list of stored labware objects. + """Configure the labware the Flex Stacker will store during a protocol by providing an initial list of stored labware objects. The kind of labware stored by the Flex Stacker will be calculated from the list of labware specified here. You can use this to store labware objects that you have already created so that, for instance, you can set their liquid state or nicknames. There are several restrictions on the values of the ``labware`` argument: - - ``labware`` must have at least one element - - Elements of ``labware`` will be stored along with their lid, if any, and an adapter they - rest on, if any. These must be compatible with the Flex Stacker. - - All elements of ``labware`` must be loaded :py:obj:`OFF_DECK`. - - All elements of ``labware`` must be the same kind of labware. If any of them have lids, they - must all have lids, and the lids must be the same. If any of them are on adapters, they all - must be on adapters, and the adapters must be the same. - - The number of labware objects must fit in the stacker physically. To make sure the labware - will fit, use the return value of :py:method:`.get_max_storable_labware_from_list`. + + - ``labware`` must have at least one element + - Elements of ``labware`` will be stored along with their lid, if any, and an adapter they + rest on, if any. These must be compatible with the Flex Stacker. + - All elements of ``labware`` must be loaded :py:obj:`OFF_DECK`. + - All elements of ``labware`` must be the same kind of labware. If any of them have lids, they + must all have lids, and the lids must be the same. If any of them are on adapters, they all + must be on adapters, and the adapters must be the same. + - The number of labware objects must fit in the stacker physically. To make sure the labware + will fit, use the return value of :py:meth:`.get_max_storable_labware_from_list`. :param labware: A list of labware to load into the stacker. - :param stacking_offset_z: Stacking offset in mm between labware units to override the + :param stacking_offset_z: Stacking ``z`` offset in mm of stored labware. If specified, this overrides the calculated value from labware definitions. .. note:: - The stacking offset is the amount of vertical overlap (in mm) between the bottomside of a - labware unit and the topside of the unit below. This offset is used to determine how many - units can fit in the stacker and calculates the Z position of the shuttle when retrieving - or storing labware. The stacking offset is calculated automatically from the labware - definitions, but you can override it by providing a value here. + The stacking offset is the amount of vertical overlap (in mm) between the bottom side of a + labware unit and the top side of the unit below. This offset is used to determine how many + units can fit in the stacker and calculates the ``z`` position of the shuttle when retrieving + or storing labware. - There are four possible stacking configurations, each with a different way of calculating + There are four possible stacking configurations, each with a different method of calculating the stacking offset: - - Bare labware: labware (bottomside) overlaps with labware (topside) - - Labware on adapter: the adapter (bottomside) of the upper unit overlaps with labware (topside) - of the unit below. - - Labware with lid: the labware (bottomside) of the upper unit overlaps the lid (topside) - of the unit below. - - Labware with lid and adapter: the adapter (bottomside) of the upper unit overlaps the - lid (topside) of the unit below. + + - Bare labware: labware (bottom side) overlaps with the top side of the labware below. + - Labware on adapter: the adapter (bottom side) of the upper labware unit overlaps with the top side of the labware below. + - Labware with lid: the labware (bottom side) of the upper unit overlaps with the lid (top side) of the unit below. + - Labware with lid and adapter: the adapter (bottom side) of the upper unit overlaps with the + lid (top side) of the unit below. """ self._core.set_stored_labware_items( @@ -1314,7 +1324,9 @@ def set_stored_labware( count: int | None = None, stacking_offset_z: float | None = None, ) -> None: - """Configure what kind of labware the Flex Stacker will store. + """Configure the type and starting quantity of labware the Flex Stacker will store during a protocol. This is the only type of labware you'll be able to store in the Stacker until it's reconfigured. + + You must use this method to load a labware stack stored inside the Stacker before you're able to ``retrieve()`` or ``store()`` additional labware. :param str load_name: A string to use for looking up a labware definition. You can find the ``load_name`` for any Opentrons-verified labware on the @@ -1337,32 +1349,28 @@ def set_stored_labware( adapter will use the same namespace as the labware, and the API will choose the adapter's version automatically. :param lid: A lid to load the on top of the main labware. Accepts the same - values as the ``load_name`` parameter of :py:meth:`.load_lid_stack`. The + values as the ``load_name`` parameter of :py:meth:`~.ProtocolContext.load_lid_stack`. The lid will use the same namespace as the labware, and the API will choose the lid's version automatically. - :param count: The number of labware that the Flex Stacker should start the protocol - storing. If not specified, this will be the maximum amount of this kind of + :param count: The number of labware that the Flex Stacker should store at the beginning of the protocol. If not specified, this will be the maximum amount of this kind of labware that the Flex Stacker is capable of storing. - :param stacking_offset_z: Stacking offset in mm between labware units to override the - calculated value from labware definitions. + :param stacking_offset_z: Stacking ``z`` offset in mm of stored labware. If specified, this overrides the + calculated value in the labware definition. .. note:: - The stacking offset is the amount of vertical overlap (in mm) between the bottomside of a - labware unit and the topside of the unit below. This offset is used to determine how many - units can fit in the stacker and calculates the Z position of the shuttle when retrieving - or storing labware. The stacking offset is calculated automatically from the labware - definitions, but you can override it by providing a value here. + The stacking offset is the amount of vertical overlap (in mm) between the bottom side of a + labware unit and the top side of the unit below. This offset is used to determine how many + units can fit in the Stacker and calculates the ``z`` position of the shuttle when retrieving + or storing labware. - There are four possible stacking configurations, each with a different way of calculating + There are four possible stacking configurations, each with a different method of calculating the stacking offset: - - Bare labware: labware (bottomside) overlaps with labware (topside) - - Labware on adapter: the adapter (bottomside) of the upper unit overlaps with labware (topside) - of the unit below. - - Labware with lid: the labware (bottomside) of the upper unit overlaps the lid (topside) - of the unit below. - - Labware with lid and adapter: the adapter (bottomside) of the upper unit overlaps the - lid (topside) of the unit below. + + - Bare labware: labware (bottom side) overlaps with the top side of the labware below. + - Labware on adapter: the adapter (bottom side) of the upper labware unit overlaps with the top side of the labware below. + - Labware with lid: the labware (bottom side) of the upper labware unit overlaps with the lid (top side) of the unit below. + - Labware with lid and adapter: the adapter (bottom side) of the upper labware unit overlaps with the lid (top side) of the unit below. """ self._core.set_stored_labware( @@ -1381,9 +1389,13 @@ def set_stored_labware( @requires_version(2, 25) def fill(self, count: int | None = None, message: str | None = None) -> None: - """Pause the protocol to add more labware to the Flex Stacker. + """Pause the protocol to add labware to the Flex Stacker. + + The labware must be the same type the Stacker is configured to store using :py:meth:`.set_stored_labware()`. - :param message: A message to display in the Opentrons App to note what kind of labware to add. + This method assumes that labware to fill the Stacker is loaded :py:obj:`OFF_DECK`. + + :param message: A message to display in the Opentrons App noting what kind of labware to fill the Stacker with. :param count: The amount of labware the Flex Stacker should hold after this command is executed. If not specified, the Flex Stacker should be full after this command is executed. """ @@ -1394,19 +1406,21 @@ def fill_items(self, labware: list[Labware], message: str | None = None) -> None """Pause the protocol to add a specific list of labware to the Flex Stacker. The ``labware`` argument must follow certain rules: - - It should have at least one item - - Its elements should be the same kind of labware previously passed to - :py:meth:`.set_stored_labware_items` or loaded by :py:meth:`.set_stored_labware` - - Its elements should all be loaded :py:obj:`OFF_DECK` + - It should contain at least one item. + - Its elements should be the same kind of labware previously passed to + :py:meth:`.set_stored_labware_items` or loaded by :py:meth:`.set_stored_labware`. + - Its elements should all be loaded :py:obj:`OFF_DECK`. - :param message: A message to display in the Opentrons App. + :param message: A message to display in the Opentrons App noting the labware to fill the Stacker with. :param labware: The list of labware to add, following the rules above. """ self._core.fill_items(self._labware_to_cores(labware), message) @requires_version(2, 25) def empty(self, message: str | None = None) -> None: - """Pause the protocol to remove labware from the Flex Stacker. + """Pause the protocol to remove all labware stored in the Flex Stacker. + + This method assumes that labware removed from the Stacker is moved :py:obj:`OFF_DECK`. :param message: A message to display in the Opentrons App to note what should be removed from the Flex Stacker. @@ -1417,9 +1431,11 @@ def empty(self, message: str | None = None) -> None: @requires_version(2, 25) def get_stored_labware(self) -> list[Labware]: - """Get the list of labware currently stored inside the stacker. + """Get the list of labware currently stored inside the Stacker. + + This function returns a list of all labware stored in the Stacker based on the labware intially stored using :py:meth:`.set_stored_labware` and any labware added or removed during the protocol. - The first element of the list is on the bottom and will be the item retrieved by a call to + The first element of the list occupies the bottom-most position in the labware stack and would be the labware retrieved by a call to :py:meth:`.retrieve`. """ return self._cores_to_labware(self._core.get_stored_labware())