Skip to content

Containers and Content

Containers and content are separate concepts.

A Minimal Container

text
let target = tube(label = "Target", capacity = 100uL);

This creates a logical tube container. The label is human-readable metadata. The capacity is a volume bound.

Container Families

Culsma includes these constructor families:

ConstructorMeaning
container(...)Generic container constructor.
tube(...)Tube-like container.
well(...)Plate-well container.
chamber(...)Chamber-like container.
surface(...)Surface-like target; volume capacity is not allowed.

Common container arguments:

ArgumentMeaning
specContainer specification text.
carrier_kindCarrier type, such as plate context.
carrier_idCarrier identifier.
carrier_positionPosition inside a carrier.
capacityVolume capacity, except for surface(...).
openOpen/closed state flag.
labelHuman-readable label.
barcodeBarcode or stable external identifier.
loadInitial content load list.

tube(...), well(...), chamber(...), and surface(...) inject their container kind implicitly. Authors normally do not write kind when using those sugar forms.

Initial Load

text
let source = tube(
    label = "Source",
    capacity = 100uL,
    load = [content(kind = formulation, type = buffer, code = "BUF01", attrs = { role: wash }):10uL]
);

The load list belongs to the constructor/init boundary. Each item must be a content spec paired with a quantity:

text
load = [content_spec:quantity]

The quantity must carry a physical unit. Load quantities use volume or mass.

Content Specs

Content describes material identity. It is not the container holding the material.

Canonical content constructor:

ConstructorMeaning
content(kind = ..., type = ..., ...)Content form; kind and type are explicit.

Compatibility sugar forms such as blood(...), reagent(...), and buffer(...) are accepted for older source. New example protocols should use content(...) directly.

Common content arguments:

ArgumentMeaning
kindBroad material family; required only for content(...).
typeCanonical material type token for the selected kind.
codeStable content identifier.
nameHuman-readable content name.
attrsStructured metadata record, for details such as role or state.

Kind and Type

kind is the broad material family. type is the material refinement inside that family.

kindCanonical type values
bio_entityorganism, organ, tissue, other_bio_entity
bio_fluidwhole_blood, plasma, serum, buffy_coat, urine, saliva, lymph, cerebrospinal_fluid, tears, semen, ascites, synovial_fluid, bronchoalveolar_lavage_fluid, other_body_fluid
bio_cellularcell_line, primary_cells, cell_population, microbial_cells, other_cellular_material
bio_subcellularorganelle, membrane, vesicle, cytoskeletal_structure, other_subcellular_structure
bio_molecule_or_virusdna, rna, protein, virus, other_biomolecule_or_virus
chemicalorganic_compound, inorganic_compound, solvent, detergent, dye, other_chemical
particulatebeads, resin, particle, other_particulate
formulationmedium, buffer, supplement, master_mix, gradient_medium, other_formulation

Common examples:

text
content(kind = formulation, type = buffer, code = "BUF01", attrs = { role: wash })
content(kind = bio_molecule_or_virus, type = dna, code = "DNA01", attrs = { role: template })
content(kind = chemical, type = solvent, code = "WATER")

For local or uncommon material names, keep kind and type canonical and put the local detail in name, code, or attrs. The attrs value is a record literal, for example { role: wash, state: ready }:

text
content(
    kind = bio_fluid,
    type = other_body_fluid,
    code = "AF01",
    name = "amniotic fluid"
)

Older custom_... or unknown type strings are accepted in compatibility mode with a warning. New source should use the canonical other_* type for the selected kind instead.

Authoring Rule

Content specs appear inside a container load=[...] initializer.

Recommended:

text
let source = tube(
    load = [content(kind = formulation, type = buffer, code = "BUF01", attrs = { role: wash }):10uL]
);

Not recommended as source authoring:

text
let b = content(kind = formulation, type = buffer, code = "BUF01", attrs = { role: wash });
content(kind = formulation, type = buffer, code = "BUF01", attrs = { role: wash });

Constructor/init lowering targets such as DefineContent(...) and LoadContent(...) are not normal source authoring forms.

After Initialization

After the protocol starts executing, content moves through containers with operations such as transfer:

text
target << [source:5uL];

Released under the Apache-2.0 license.