Skip to content

Environment Application

Environment blocks bind execution conditions to enclosed steps.

text
with env(thermal = 37C, duration = 10min) {
    hold(reactor);
}

Environment blocks describe operational conditions. They do not predict biological or chemical outcomes.

The environment example protocol is:

text
examples/env_readout_protocol.culs

Scalar Thermal Environment

Scalar thermal authoring uses a temperature and, for pure holds, a duration.

text
with env(thermal = 37C, duration = 10min) {
    hold(reactor);
}

For scalar thermal = ..., duration is required only when the environment block is a pure hold. When the block contains executable work, duration may be omitted; the environment applies while the body executes.

Pure Hold

Use hold(target) to declare the target kept under the environment condition. Inside with env(...), hold(...) is a target marker rather than an executable step.

text
with env(thermal = 37C, duration = 10min) {
    hold(reactor);
}

Rules:

  • hold(target) is only valid as a direct statement inside a with env body.
  • Direct hold(...) markers may appear anywhere in the immediate env body.
  • A pure hold block must write at least one hold(...) explicitly.
  • A pure scalar thermal hold must provide duration.
  • An empty with env(...) {} block is not valid.
  • hold(...) is not valid inside nested if, repeat, or with constraint blocks.

Container Structure Targets

Use a container target view when an environment controls the container structure rather than the contained material.

text
with env(thermal = 105C, duration = 5min) {
    hold(pcr_tube.structure.top);

    with env(thermal = thermal_program(from = 95C, duration = 30s)) {
        hold(pcr_tube);
    }
}

Supported structure facets are top, bottom, and sidewall. A bare container target such as hold(pcr_tube) is content-facing.

Thermal Programs

For programmatic thermal control, use thermal_program(...).

text
let ramp = thermal_program(from = 60C, to = 95C, duration = 350s);

with env(thermal = ramp) {
    hold(reactor);
}

Supported source shapes:

text
thermal_program(from = 37C, duration = 120min)
thermal_program(from = 60C, to = 95C, duration = 350s)

thermal_program(...) defines a single thermal segment. It does not carry cycles or staged PCR logic by itself. Multi-segment workflows compose thermal programs with explicit control flow.

When thermal is a thermal_program(...), the outer with env(...) must not also define duration.

Field Environment

Environment can also bind a field condition:

text
with env(field = mz_separation) {
    ...
}

Field environments do not use the scalar thermal duration rule.

Environment Around Actions

Use with env(...) to bind temperature and time to an enclosed action when the action surface does not own a duration field. For example, centrifuge duration is environment-scoped rather than a centrifuge_program(...) parameter:

text
with env(thermal = 4C, duration = 5min) {
    let g = sep(sample = lysate, program = centrifuge_program(drive = 12000g));
}

When no explicit time window is intended, an active scalar thermal environment can omit duration:

text
with env(thermal = 4C) {
    let g = sep(sample = lysate, program = centrifuge_program(drive = 12000g));
}

Thermal Modifiers

co2 and rh are thermal-environment modifiers.

They require thermal and are not valid when thermal is a thermal_program(...).

Body Semantics

The body of with env(...) { ... } executes once in lexical order. If work must repeat, use an explicit repeat.

An environment block scopes execution conditions. It does not mean "simulate what happens biologically during this time."

Released under the Apache-2.0 license.