@@ -1574,29 +1574,38 @@ async def aspirate96(
15741574 flow_rate = float (flow_rate ) if flow_rate is not None else None
15751575 blow_out_air_volume = float (blow_out_air_volume ) if blow_out_air_volume is not None else None
15761576
1577+ # Convert Plate to either one Container (single well) or a list of Wells
15771578 containers : Sequence [Container ]
1578- if isinstance (resource , Container ):
1579+ if isinstance (resource , Plate ):
1580+ if resource .has_lid ():
1581+ raise ValueError ("Aspirating from plate with lid" )
1582+ containers = resource .get_all_items () if resource .num_items > 1 else [resource .get_item (0 )]
1583+ elif isinstance (resource , Container ):
1584+ containers = [resource ]
1585+
1586+ if len (containers ) == 1 : # single container
1587+ container = containers [0 ]
15791588 if (
1580- resource .get_absolute_size_x () < 108.0 or resource .get_absolute_size_y () < 70.0
1589+ container .get_absolute_size_x () < 108.0 or container .get_absolute_size_y () < 70.0
15811590 ): # TODO: analyze as attr
15821591 raise ValueError ("Container too small to accommodate 96 head" )
15831592
15841593 for channel in self .head96 .values ():
15851594 # superfluous to have append in two places but the type checker is very angry and does not
15861595 # understand that Optional[Liquid] (remove_liquid) is the same as None from the first case
15871596 liquids : List [Tuple [Optional [Liquid ], float ]]
1588- if resource .tracker .is_disabled or not does_volume_tracking ():
1597+ if container .tracker .is_disabled or not does_volume_tracking ():
15891598 liquids = [(None , volume )]
15901599 all_liquids .append (liquids )
15911600 else :
1592- liquids = resource .tracker .remove_liquid (volume = volume ) # type: ignore
1601+ liquids = container .tracker .remove_liquid (volume = volume ) # type: ignore
15931602 all_liquids .append (liquids )
15941603
15951604 for liquid , vol in reversed (liquids ):
15961605 channel .get_tip ().tracker .add_liquid (liquid = liquid , volume = vol )
15971606
15981607 aspiration = MultiHeadAspirationContainer (
1599- container = resource ,
1608+ container = container ,
16001609 volume = volume ,
16011610 offset = offset ,
16021611 flow_rate = flow_rate ,
@@ -1605,24 +1614,15 @@ async def aspirate96(
16051614 blow_out_air_volume = blow_out_air_volume ,
16061615 liquids = cast (List [List [Tuple [Optional [Liquid ], float ]]], all_liquids ), # stupid
16071616 )
1608-
1609- containers = [resource ]
1610- else :
1611- if isinstance (resource , Plate ):
1612- if resource .has_lid ():
1613- raise ValueError ("Aspirating from plate with lid" )
1614- containers = resource .get_all_items ()
1615- else :
1616- containers = resource
1617-
1618- # ensure that wells are all in the same plate
1619- plate = containers [0 ].parent
1620- for well in containers :
1621- if well .parent != plate :
1622- raise ValueError ("All wells must be in the same plate" )
1617+ else : # multiple containers
1618+ # ensure that wells are all in the same plate
1619+ plate = containers [0 ].parent
1620+ for well in containers :
1621+ if well .parent != plate :
1622+ raise ValueError ("All wells must be in the same plate" )
16231623
16241624 if not len (containers ) == 96 :
1625- raise ValueError (f"aspirate96 expects 96 wells , got { len (containers )} " )
1625+ raise ValueError (f"aspirate96 expects 96 containers when a list , got { len (containers )} " )
16261626
16271627 for well , channel in zip (containers , self .head96 .values ()):
16281628 # superfluous to have append in two places but the type checker is very angry and does not
@@ -1725,29 +1725,38 @@ async def dispense96(
17251725 flow_rate = float (flow_rate ) if flow_rate is not None else None
17261726 blow_out_air_volume = float (blow_out_air_volume ) if blow_out_air_volume is not None else None
17271727
1728+ # Convert Plate to either one Container (single well) or a list of Wells
17281729 containers : Sequence [Container ]
1729- if isinstance (resource , Container ):
1730+ if isinstance (resource , Plate ):
1731+ if resource .has_lid ():
1732+ raise ValueError ("Aspirating from plate with lid" )
1733+ containers = resource .get_all_items () if resource .num_items > 1 else [resource .get_item (0 )]
1734+ elif isinstance (resource , Container ):
1735+ containers = [resource ]
1736+
1737+ if len (containers ) == 1 : # single container
1738+ container = containers [0 ]
17301739 if (
1731- resource .get_absolute_size_x () < 108.0 or resource .get_absolute_size_y () < 70.0
1740+ container .get_absolute_size_x () < 108.0 or container .get_absolute_size_y () < 70.0
17321741 ): # TODO: analyze as attr
17331742 raise ValueError ("Container too small to accommodate 96 head" )
17341743
17351744 for channel in self .head96 .values ():
17361745 # superfluous to have append in two places but the type checker is very angry and does not
17371746 # understand that Optional[Liquid] (remove_liquid) is the same as None from the first case
17381747 reversed_liquids : List [Tuple [Optional [Liquid ], float ]]
1739- if resource .tracker .is_disabled or not does_volume_tracking ():
1748+ if container .tracker .is_disabled or not does_volume_tracking ():
17401749 reversed_liquids = [(None , volume )]
17411750 all_liquids .append (reversed_liquids )
17421751 else :
1743- reversed_liquids = resource .tracker .remove_liquid (volume = volume ) # type: ignore
1752+ reversed_liquids = container .tracker .remove_liquid (volume = volume ) # type: ignore
17441753 all_liquids .append (reversed_liquids )
17451754
17461755 for liquid , vol in reversed (reversed_liquids ):
17471756 channel .get_tip ().tracker .add_liquid (liquid = liquid , volume = vol )
17481757
17491758 dispense = MultiHeadDispenseContainer (
1750- container = resource ,
1759+ container = container ,
17511760 volume = volume ,
17521761 offset = offset ,
17531762 flow_rate = flow_rate ,
@@ -1759,18 +1768,11 @@ async def dispense96(
17591768
17601769 containers = [resource ]
17611770 else :
1762- if isinstance (resource , Plate ):
1763- if resource .has_lid ():
1764- raise ValueError ("Aspirating from plate with lid" )
1765- containers = resource .get_all_items ()
1766- else : # List[Well]
1767- containers = resource
1768-
1769- # ensure that wells are all in the same plate
1770- plate = containers [0 ].parent
1771- for well in containers :
1772- if well .parent != plate :
1773- raise ValueError ("All wells must be in the same plate" )
1771+ # ensure that wells are all in the same plate
1772+ plate = containers [0 ].parent
1773+ for well in containers :
1774+ if well .parent != plate :
1775+ raise ValueError ("All wells must be in the same plate" )
17741776
17751777 if not len (containers ) == 96 :
17761778 raise ValueError (f"dispense96 expects 96 wells, got { len (containers )} " )
0 commit comments