Resources in v1

there are several problems/practicalities that are ideally addressed before releasing v1, particularly when we think about making PLR distributed

based on discussions with @burnpanck @koeng @CamilloMoschner @aferrari-unt and others

name vs identifier

right now name serves as the unique identifier for a resource in a given tree. there are two problems with this: 1. people want to use names for logical names like "source_plate", 2. it shifts the burden of choosing unique names onto users. Resources should have a unique identifier, semantically there is only one resource of a given type and that’s what the identifier should refer to. I suggest moving name into metadata (we can keep the convenience syntax) and introducing an identifier which is automatically created as a uuid unless overridden.

equivalence classes

what should == and is in python mean? should two plates of the same model but different instances (physically and in code) be equal?

information

we should differentiate 3 groups of information that are currently all mixed into one Resource class:

  1. semantic type: what is a Plate? we can define it further than we currently do, for example by fixing it always has a rectangular grid layout. we could then make dx an actual property of the Plate class, rather than a convenience parameter for instantiating / recomputing it on query
  2. model: what specific model is this? this sets many parameters like size_{x,y,z} etc.
  3. identity + metadata: a given instance of a model of a given type. see identity above, but also metadata

this is important for for example storing definitions.See Toml instead of .py files for labware. We should have one toml format per semantic type, and it would just contain the model information.

type = "Plate"
model = "cor_96_wellplate_360uL_Fb" 
manufacturer = "Corning"
catalog_number = "3603" 

size_x = 127.76 
size_y = 85.48
size_z = 14.2 

[grid]
num_items_x = 12
num_items_y = 8 
item_dx = 9.0 
item_dy = 9.0 

dx = 10.87
dy = 7.77 
dz = 3.03 

[well]
size_x = 6.86
size_y = 6.86
size_z = 10.67
material_z_thickness = 0.5
bottom_type = "flat"
cross_section_type = "circle"
max_volume = 360.0

a toml file is fundamentally specifying “level 2”/model information.

see Thoughts on having a compact “save format” for a deck/a resource that isn’t just the built-in .serialize? this is essentially talking about compression, and we can compress it easily by referencing an external source of information, for example what semantic types we have and what models we have. It depends on how much the consumer knows, the most efficient would be identity + model_reference because model_reference already is surjective onto semantic types.

I imagine resource.serialize(include_type=True, include_model=True) as the python interface


there are downstream niceties of this, but I think these are the fundamental problems/improvements we should make

2 Likes

to clarify: state, including children + parents, should also be ‘level 3’ information.

1 Like

I think your name vs identifier makes a ton of sense. We are doing a botched version of this at Until (look at our compact serialization system. not particularly proud of this implementation but it served our use case in a pinch)

Regarding your equivalence I think the == should be level 3, so two plates of the same model but different instances should not be equal. It should basically be resource_a.identifier == resource_b.identifier. If a protocol requires model equivalence the check can be plate_a.model == plate_b.model.

For is we’ll just have to accept that serializing and deserializing might change the value of a is b just like it does in python’s json library:

import json

shared = {"model": "Corning 3603"}
original = [shared, shared]

restored = json.loads(json.dumps(original))

original[0] is original[1]  # True
restored[0] is restored[1]  # False
restored == original       # True: equal values

The alternative is to keep an identity map in our serialization format, which I don’t think we have a need for.

Formally defining state could also be useful in v1. For example right now ‘state’ refers to location+rotation and instance specific things like liquid amount or tip occupancy, which clearly should be serialized, but serializing children+parent means creating a double source of truth for the tree: the json structure and the state both define the same (hopefully) relationships.

3 Likes