Skip to content

Add a standard way to get plate occupied height including lid? #1061

@hazlamshamin

Description

@hazlamshamin

I was on making plate readers more understanding about plates when the lid is on. But stumbled upon this issue where the full height of a plate when the lid is on does not share a standardised API. PLR currently models lids as child resources of Plate. That makes sense because lids can be moved separately, but it also means the usual size APIs only report the plate body height, not the full height taken up by the plate + lid.

For example, Cor_96_wellplate_360ul_Fb(..., with_lid=True) creates the lid separately:

The lid is then placed using the nesting height here:

But Resource.get_absolute_size_z() only looks at the resource's own rotated corners, not child resources:

So for a covered plate, these all return the plate body height:

plate.get_size_z()
plate.get_absolute_size_z()
plate.get_absolute_location(z="t").z

They do not return the actual top height including the lid.

Example with Cor_96_wellplate_360ul_Fb("plate", with_lid=True):

plate.get_size_z()                  = 14.2 mm
plate.get_absolute_size_z()         = 14.2 mm
plate.get_absolute_location(z="t")  = 14.2 mm

lid.get_size_z()                    = 8.9 mm
lid.nesting_z_height                = 7.6 mm
lid.location.z                      = 6.6 mm
occupied height with lid            = 15.5 mm

The lid-aware height calculation already exists in a few places, but it is done manually each time.

In pylabrobot/resources/resource_stack.py#L90-L95:

if isinstance(resource, Plate) and resource.lid is not None:
  return resource.get_size_z() + resource.lid.get_size_z() - resource.lid.nesting_z_height
return resource.get_size_z()

In pylabrobot/plate_reading/agilent/biotek_backend.py#L321-L323:

plate_size_z = plate.get_size_z()
if plate.lid is not None:
  plate_size_z += plate.lid.get_size_z() - plate.lid.nesting_z_height

There is also an approximate version in the incubator placement logic, with a TODO saying the PLR nesting height should be used:

pylabrobot/storage/incubator.py#L90-L95

def _plate_height(p: Plate):
  if p.has_lid():
    # TODO: we can use plr nesting height
    # lid.location.z + lid.get_anchor(z="t").z
    return p.get_size_z() + 3
  return p.get_size_z()

Would it make sense for PLR to expose one standard helper for the occupied height / top Z including the lid?

Some possible API names:

plate.get_size_z_with_lid()
plate.get_occupied_size_z()
plate.get_top_z(include_children=True)

I do not think get_size_z() itself should change, since it currently seems to mean the resource's own local geometry. Changing that could break stuffs. But having one official helper would make storage, stacking, plate-reader clearance checks, and backend plate geometry handling less error-prone.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions