QA Procedures - TrueBeam

Open Field

The OpenField procedure creates a simple rectangular open field beam, commonly used for output calibration, flatness, and symmetry measurements. The field can be defined either by MLC positions or by jaw positions, with automatic padding applied to ensure proper field coverage.

Basic Usage

The simplest way to create an open field is to specify the field edges in millimeters:

from conjuror.plans.truebeam import OpenField

# Create a 10x20 cm field centered at isocenter
procedure = OpenField(x1=-50, x2=50, y1=-100, y2=100, mu=100)

The following visualizations show the MLC animation and fluence map for an open field:

Field Definition Modes

By default, fields are defined by MLC positions (defined_by_mlc=True), which means the MLCs form the field edges and the jaws are opened with padding. Alternatively, you can define the field by jaw positions.

In both modes, padding is applied to the non-defining device to avoid clipping:

  • MLC-defined (defined_by_mlc=True): the jaws open to (x1, x2, y1, y2) plus padding on each side.

  • Jaw-defined (defined_by_mlc=False): the MLC opens to (x1, x2, y1, y2) plus padding on each side.

# Field defined by MLCs (default)
procedure_mlc = OpenField(x1=-50, x2=50, y1=-100, y2=100, defined_by_mlc=True, padding=20)
# MLCs form the field edges; jaws open 20 mm beyond on each side.

# Field defined by jaws
procedure_jaws = OpenField(x1=-50, x2=50, y1=-100, y2=100, defined_by_mlc=False, padding=20)
# Jaws form the field edges; MLC opens 20 mm beyond on each side.

The following visualizations show the MLC positions for each field definition mode:

MLC Alignment Modes

MLC leaves have discrete leaf boundaries along the y-axis. If y1 or y2 do not land exactly on a leaf boundary, the requested field edge must be resolved according to a rule.

  • MLC-defined fields (defined_by_mlc=True): mlc_mode controls how the y-edges are aligned to the nearest leaf boundaries.

  • Jaw-defined fields (defined_by_mlc=False): mlc_mode is ignored; the MLC is always treated as OUTWARD so it will not clip the jaw-defined opening.

The following alignment modes apply to MLC-defined fields:

OUTWARD (default)

If y1 or y2 falls between MLC leaf boundaries, the intermediate leaf band is treated as “infield” and included in the field. This results in a larger field size in the y-direction. This is the default mode and is suitable for most general-purpose applications where slight field size variations are acceptable.

INWARD

If y1 or y2 falls between MLC leaf boundaries, the intermediate leaf band is treated as “outfield” and excluded from the field. This results in a smaller field size in the y-direction. Use this mode when you want to ensure the field does not exceed the specified dimensions.

ROUND

If y1 or y2 falls between MLC leaf boundaries, the field edges are rounded to the nearest MLC boundary. This provides a balanced approach that minimizes field size deviation.

EXACT

Both y1 and y2 must coincide exactly with an MLC leaf boundary. If either edge does not align exactly, a ValueError is raised. This mode ensures precise field size matching and is required for applications that depend on exact field dimensions, such as output calibration or field size verification measurements.

Warning

If you are using this procedure for an application that requires exact y-dimensions (for example output calibration or field-size verification), select EXACT mode. The other modes (ROUND, INWARD, OUTWARD) can change the delivered y-size whenever the requested edges do not align with MLC leaf boundaries.

from conjuror.plans.truebeam import OpenField, MLCLeafBoundaryAlignmentMode

# OUTWARD: Include intermediate boundaries in the field (larger field, default)
procedure_outward = OpenField(..., mlc_mode=MLCLeafBoundaryAlignmentMode.OUTWARD)

# INWARD: Exclude intermediate boundaries from the field (smaller field)
procedure_inward = OpenField(..., mlc_mode=MLCLeafBoundaryAlignmentMode.INWARD)

# ROUND: Round to nearest MLC boundary
procedure_round = OpenField(..., mlc_mode=MLCLeafBoundaryAlignmentMode.ROUND)

# EXACT: Field edges must align exactly with MLC boundaries
procedure_exact = OpenField(..., mlc_mode=MLCLeafBoundaryAlignmentMode.EXACT)

The following visualizations show the MLC positions for each alignment mode using y2=51:

Customizing Parameters

You can adjust the field size/position (x1, x2, y1, y2) along with beam settings such as monitor units, energy, fluence mode, dose rate, gantry/collimator angles, couch positions, and beam naming.

from conjuror.plans.machine import FluenceMode

# High-energy open field with custom monitor units
procedure = OpenField(
    x1=-100, x2=100, y1=-100, y2=100,   # 20x20 cm field (all values in mm)
    mu=200,                             # Monitor units
    energy=15,                          # 15 MV
    fluence_mode=FluenceMode.FFF,       # Flattening filter free
    dose_rate=600,                      # MU/min
    gantry_angle=270,                   # Gantry at 270 degrees
    coll_angle=90,                      # Collimator at 90 degrees
    couch_vrt=0,                        # Couch vertical position (mm)
    couch_lng=1000,                     # Couch longitudinal position (mm)
    couch_lat=0,                        # Couch lateral position (mm)
    couch_rot=0,                        # Couch rotation (degrees)
    beam_name="Open 15XFFF"
)

Complete Example

import pydicom
from conjuror.plans.plan_generator import PlanGenerator
from conjuror.plans.truebeam import OpenField, MLCLeafBoundaryAlignmentMode

# Create generator from base plan
base_plan = pydicom.dcmread(r"C:\path\to\base_plan.dcm")
generator = PlanGenerator(base_plan, plan_name="Output Calibration", plan_label="Output")

# Add multiple open fields for different energies
for energy in [6, 10, 15]:
    procedure = OpenField(
        x1=-100, x2=100, y1=-100, y2=100,
        energy=energy,
        mu=100,
        mlc_mode=MLCLeafBoundaryAlignmentMode.EXACT,
        beam_name=f"Open {energy}MV"
    )
    generator.add_procedure(procedure)

# Export plan
generator.to_file("output_calibration_plan.dcm")

MLC Transmission

The MLCTransmission procedure generates a small set of beams intended to support MLC transmission measurements. It adds:

  • Reference: a jaw-defined open field.

  • Bank A: a transmission beam configured to isolate Bank A transmission under a jaw-defined opening.

  • Bank B: a transmission beam configured to isolate Bank B transmission under a jaw-defined opening.

This construction allows you to measure transmission from each bank separately by comparing the transmission images to the reference image.

Basic Usage

To include an MLC transmission test in a generated plan, add MLCTransmission to your PlanGenerator:

import pydicom
from conjuror.plans.plan_generator import PlanGenerator
from conjuror.plans.truebeam import MLCTransmission

base_plan = pydicom.dcmread(r"C:\path\to\base_plan.dcm")
generator = PlanGenerator(base_plan, plan_name="MLC Transmission", plan_label="Tx")

# Default: 10x10 cm reference, 100 MU reference, 1000 MU per bank
procedure = MLCTransmission()
generator.add_procedure(procedure)

generator.to_file("mlc_transmission_plan.dcm")

The following visualizations show the MLC positions for the reference, Bank A, and Bank B beams:

Customizing Parameters

You can adjust the reference field size (width, height), MU per beam (mu_per_ref, mu_per_bank), bank overreach, and beam names, along with beam settings such as energy, fluence mode, dose rate, gantry/collimator angles, and couch positions.

from conjuror.plans.machine import FluenceMode
from conjuror.plans.truebeam import MLCTransmission

procedure = MLCTransmission(
    width=200,          # mm (20 cm)
    height=200,         # mm (20 cm)
    mu_per_ref=100,     # reference open field MU
    mu_per_bank=500 ,   # MU for each bank transmission beam
    overreach=10,       # mm; shifts the closed MLC bank further under the jaw
    beam_names=["Tx Ref", "Tx Bank-A", "Tx Bank-B"],
    energy=15,                          # 15 MV
    fluence_mode=FluenceMode.FFF,       # Flattening filter free
    dose_rate=600,                      # MU/min
    gantry_angle=0,                     # Gantry angle
    coll_angle=0,                       # Collimator angle
    couch_vrt=0,                        # Couch vertical
    couch_lng=1000,                     # Couch longitudinal
    couch_lat=0,                        # Couch lateral
    couch_rot=0,                        # Couch rotation
)
generator.add_procedure(procedure)

Dosimetric Leaf Gap

The DosimetricLeafGap procedure creates a set of fields with sliding MLC gaps beams for measuring the dosimetric leaf gap (DLG). For each gap width in gap_widths, it generates one beam with two control points: the gap starts at start_position and ends at final_position (both in mm).

Warning

For a clean DLG measurement, ensure the sweeping gap is fully occluded by the X jaws at both the start and end positions for the largest gap width. The procedure will emit a warning if:

  • min(start_position, final_position) + max(gap_widths)/2 > x1 or

  • max(start_position, final_position) - max(gap_widths)/2 < x2

If the gap is not fully occluded at the endpoints, extra transmission can bias the DLG calculation.

Basic Usage

import pydicom
from conjuror.plans.plan_generator import PlanGenerator
from conjuror.plans.truebeam import DosimetricLeafGap

base_plan = pydicom.dcmread(r"C:\path\to\base_plan.dcm")
generator = PlanGenerator(base_plan, plan_name="DLG", plan_label="DLG")

procedure = DosimetricLeafGap()
generator.add_procedure(procedure)

generator.to_file("dlg_plan.dcm")

The following visualizations show example MLC motion for two different gap widths:

Customizing Parameters

You can adjust gap widths and sweep extent (gap_widths, start_position, final_position), MU (mu), jaw size (x1, x2, y1, y2), and beam settings such as energy, fluence mode, dose rate, gantry/collimator angles, and couch positions.

from conjuror.plans.machine import FluenceMode
from conjuror.plans.truebeam import DosimetricLeafGap

procedure = DosimetricLeafGap(
    gap_widths=(2, 4, 6, 10, 14, 16, 20),
    start_position=-60,
    final_position=60,
    mu=100,
    x1=-50, x2=50, y1=-50, y2=50,
    energy=6,
    fluence_mode=FluenceMode.STANDARD,
    dose_rate=600,
    gantry_angle=0,
    coll_angle=0,
    couch_vrt=0,
    couch_lng=1000,
    couch_lat=0,
    couch_rot=0,
)

Winston-Lutz

The WinstonLutz procedure generates a set of open rectangular fields (one beam per axis position: gantry, collimator, couch) to support Winston-Lutz imaging and analysis.

Conceptually, this is a thin wrapper around OpenField. For each WinstonLutzField it creates one open field beam using the same beam parameters you set on the procedure. The only values that vary per beam are the axis angles (and optional name) provided via WinstonLutzField.

Basic Usage

import pydicom
from conjuror.plans.plan_generator import PlanGenerator
from conjuror.plans.truebeam import WinstonLutz, WinstonLutzField

base_plan = pydicom.dcmread(r"C:\path\to\base_plan.dcm")
generator = PlanGenerator(base_plan, plan_name="Winston-Lutz", plan_label="WL")

fields = [
    WinstonLutzField(0, 0, 0),
    WinstonLutzField(90, 0, 0),
    WinstonLutzField(180, 0, 0),
    WinstonLutzField(270, 0, 0),
]
procedure = WinstonLutz(fields=fields)
generator.add_procedure(procedure)

generator.to_file("winston_lutz_plan.dcm")

Customizing Parameters

You can adjust the field size/position (x1, x2, y1, y2), MU (mu), whether the field is defined by the MLC or jaws (defined_by_mlc), padding (padding), MLC y-edge alignment (mlc_mode), and the list of axis positions (fields).

See Open Field for additional context on open field geometry.

from conjuror.plans.machine import FluenceMode
from conjuror.plans.truebeam import (
    MLCLeafBoundaryAlignmentMode,
    WinstonLutz,
    WinstonLutzField,
)

procedure = WinstonLutz(
    x1=-10, x2=10, y1=-10, y2=10,  # mm
    mu=10,
    defined_by_mlc=True,
    mlc_mode=MLCLeafBoundaryAlignmentMode.OUTWARD,
    padding=5,
    fields=[
        WinstonLutzField(0, 0, 0, name="Iso"),
        WinstonLutzField(0, 0, 90),
        WinstonLutzField(0, 0, 270),
    ],
    energy=6,
    fluence_mode=FluenceMode.STANDARD,
    dose_rate=600,
    couch_vrt=0,
    couch_lng=1000,
    couch_lat=0,
)

Picket Fence

pydantic model conjuror.plans.truebeam.PicketFence[source]

Bases: QAProcedure

Add a picket fence beam to the plan.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Fields:
field beam_name: str = 'Picket fence'

The name of the beam.

field coll_angle: float = 0

The collimator angle of the beam.

field couch_lat: float = 0

The couch lateral position.

field couch_lng: float = 1000

The couch longitudinal position.

field couch_rot: float = 0

The couch rotation.

field couch_vrt: float = 0

The couch vertical position.

field dose_rate: int = 600

The dose rate of the beam.

field energy: float = 6

The energy of the beam.

field fluence_mode: FluenceMode = FluenceMode.STANDARD

The fluence mode of the beam.

field gantry_angle: float = 0

The gantry angle of the beam.

field jaw_padding: float = 10

The padding to add to the X jaws.

field mu_per_picket: float = 10

The monitor units for each picket.

field mu_per_transition: float = 2

The monitor units for MLC transitions between pickets.

field picket_positions: Sequence[float] = (-75, -60, -45, -30, -15, 0, 15, 30, 45, 60, 75)

The positions of the pickets relative to the center of the image.

field picket_width: float = 1

The width of the pickets.

field skip_first_picket: bool = True

Whether to skip the first picket.

classmethod PicketFence.from_varian_reference() Self[source]

Add a picket fence that replicates Varian’s T0.2_PicketFenceStatic_M120_TB_Rev02.dcm

Warning

This method is intended to approximate Varian-provided reference plans. Exact replication is not guaranteed.

Small discrepancies may occur in one or more axes (e.g., gantry, collimator, couch, jaw, or MLC positions) due to rounding, or limitations in what can be customized by the PlanGenerator.

Dose Rate

pydantic model conjuror.plans.truebeam.DoseRate[source]

Bases: QAProcedure

Create a single-image dose rate test. Multiple ROIs are generated. A reference beam is also created where all ROIs are delivered at the default dose rate for comparison. The field names are generated automatically based on the min and max dose rates tested.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Fields:
field coll_angle: float = 0

The collimator angle of the beam.

field couch_lat: float = 0

The couch lateral position.

field couch_lng: float = 1000

The couch longitudinal position.

field couch_rot: float = 0

The couch rotation.

field couch_vrt: float = 0

The couch vertical position.

field default_dose_rate: int = 600

The default dose rate. Typically, this is the clinical default. The reference beam will be delivered at this dose rate for all ROIs.

field desired_mu: int = 50

The desired monitor units to deliver. Based on the dose rates requested, the actual MU required might be higher than this value.

field dose_rates: tuple[int, ...] = (100, 300, 500, 600)

The dose rates to test. Each dose rate will have its own ROI.

field energy: float = 6

The energy of the beam.

field fluence_mode: FluenceMode = FluenceMode.STANDARD

The fluence mode of the beam.

field gantry_angle: float = 0

The gantry angle of the beam.

field jaw_padding_mm: float = 5

The padding to add to the X jaws. The X-jaws will close around the ROIs plus this padding.

field max_sacrificial_move_mm: float = 50

The maximum distance the sacrificial leaves can move in a given control point. Smaller values generate more control points and more back-and-forth movement. Too large of values may cause deliverability issues.

Constraints:
  • gt = 0

field roi_size_mm: float = 25

The width of the ROIs.

field y1: float = -100

The bottom jaw position. Usually negative. More negative is lower.

field y2: float = 100

The top jaw position. Usually positive. More positive is higher.

MLC Speed

pydantic model conjuror.plans.truebeam.MLCSpeed[source]

Bases: QAProcedure

Create a single-image MLC speed test. Multiple speeds are generated. A reference beam is also generated. The reference beam is delivered at the maximum MLC speed.

Notes

The desired speed can be achieved through the following formula:

speed = roi_size_mm * max dose rate / MU * 60

We solve for MU with the desired speed. The 60 is for converting the dose rate as MU/min to MU/sec. Thus,

MU = roi_size_mm * max dose rate / speed * 60

MUs are calculated automatically based on the speed and the ROI size.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Fields:
field beam_name: str = 'MLC Speed'

The name of the beam. The reference beam will be named ‘{beam_name} Ref’.

field coll_angle: float = 0

The collimator angle of the beam.

field couch_lat: float = 0

The couch lateral position.

field couch_lng: float = 1000

The couch longitudinal position.

field couch_rot: float = 0

The couch rotation.

field couch_vrt: float = 0

The couch vertical position.

field default_dose_rate: int = 600

The dose rate used for the reference beam.

field energy: float = 6

The energy of the beam.

field fluence_mode: FluenceMode = FluenceMode.STANDARD

The fluence mode of the beam.

field gantry_angle: float = 0

The gantry angle of the beam.

field jaw_padding_mm: float = 5

The padding to add to the X jaws. The X-jaws will close around the ROIs plus this padding.

field max_sacrificial_move_mm: float = 50

The maximum distance the sacrificial leaves can move in a given control point. Smaller values generate more control points and more back-and-forth movement. Too large of values may cause deliverability issues.

Constraints:
  • gt = 0

field mu: int = 50

The monitor units to deliver.

field roi_size_mm: float = 20

The width of the ROIs.

field speeds: tuple[float, ...] = (5, 10, 15, 20)

The speeds to test. Each speed will have its own ROI.

field y1: float = -100

The bottom jaw position. Usually negative. More negative is lower.

field y2: float = 100

The top jaw position. Usually positive. More positive is higher.

Gantry Speed

pydantic model conjuror.plans.truebeam.GantrySpeed[source]

Bases: QAProcedure

Create a single-image gantry speed test. Multiple speeds are generated. A reference beam is also generated. The reference beam is delivered without gantry movement.

Notes

The gantry angle to cover can be determined via the following:

gantry speed = gantry_range * max_dose_rate / (MU * 60)

We can thus solve for the gantry range:

gantry_range = gantry_speed * MU * 60 / max_dose_rate

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Fields:
field beam_name: str = 'GS'

The name of the beam.

field coll_angle: float = 0

The collimator angle of the beam.

field couch_lat: float = 0

The couch lateral position.

field couch_lng: float = 1000

The couch longitudinal position.

field couch_rot: float = 0

The couch rotation.

field couch_vrt: float = 0

The couch vertical position.

field energy: float = 6

The energy of the beam.

field fluence_mode: FluenceMode = FluenceMode.STANDARD

The fluence mode of the beam.

field gantry_rot_dir: GantryDirection = GantryDirection.CLOCKWISE

The direction of gantry rotation.

field jaw_padding_mm: float = 5

The padding to add to the X jaws. The X-jaws will close around the ROIs plus this padding.

field max_dose_rate: int = 600

The max dose rate clinically allowed for the energy.

field mu: int = 120

The monitor units of the beam.

field roi_size_mm: float = 30

The width of the ROIs.

field speeds: tuple[float, ...] = (2, 3, 4, 4.8)

The gantry speeds to test. Each speed will have its own ROI.

field start_gantry_angle: float = 179

The starting gantry angle. The gantry will rotate around this point. It is up to the user to know the machine’s limitations (e.g. don’t go through 180 for Varian machines). The ending gantry angle will be the starting angle plus the sum of the gantry deltas generated by the speed ROIs. Slower speeds require more gantry angle to reach the same MU.

field y1: float = -100

The bottom jaw position. Usually negative. More negative is lower.

field y2: float = 100

The top jaw position. Usually positive. More positive is higher.

VMAT Dose Rate & Gantry Speed

pydantic model conjuror.plans.truebeam.VMATDRGS[source]

Bases: QAProcedure

Create beams like Clif Ling VMAT DRGS tests. The defaults use an optimized selection for a TrueBeam.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Fields:
field correct_fluence: bool = True

The original DRGS plans have an incorrect fluence on the initial and final transitions. Use False to replicate the original plans, otherwise use True to have a more uniform fluence.

field couch_lat: float = 0

The couch lateral position.

field couch_lng: float = 1000

The couch longitudinal position.

field couch_rot: float = 0

The couch rotation.

field couch_vrt: float = 0

The couch vertical position.

field dose_rates: tuple[float, ...] = (600, 600, 600, 600, 500, 400, 200)

The dose rates to test. Each dose rate will have its own ROI.

field dynamic_delivery_at_static_gantry: tuple[float, ...] = ()

There is one beam created for each static gantry angle. These beams contain the same control point sequence as the dynamic beam, but the gantry angle is replaced by a single value. There will be no modulation of dose rate and gantry speeds, and can be used as an alternative reference beam.

field energy: float = 6

The energy of the beam.

field fluence_mode: FluenceMode = FluenceMode.STANDARD

The fluence mode of the beam.

field gantry_motion_per_transition: float = 10.0

The number of degrees that the gantry should rotate while the MLCs move from one ROI to the next.

field gantry_rotation_clockwise: bool = True

The direction of the gantry rotation. If True, the gantry will rotate clockwise.

field gantry_speeds: tuple[float, ...] = (3, 4, 5, 6, 6, 6, 6)

The gantry speeds to test. Each gantry speed will have its own ROI.

field initial_gantry_offset: float = 1.0

The initial gantry offset. E.g. if initial_gantry_offset=1 and gantry_rotation_clockwise=True, then start angle = 181 IEC. If gantry_rotation_clockwise=False, then start angle = 179 IEC.

field jaw_padding: float = 0.0

The added jaw position with respect to the initial/final MLC positions.

field max_dose_rate: int = 600

The max dose rate. This is used to compute the control point sequence to achieve the test dose_rates.

field mlc_gap: float = 2.0

The MLC gap between ROIs. This creates a darker region to help visualize the ROIs boundaries.

field mlc_motion_reverse: bool = True

The direction of MLC motion. If False, the leaves move in positive direction (IEC) from -mlc_span/2 to +mlc_span/2. If True, the leaves move in negative direction (IEC) from +mlc_span/2 to -mlc_span/2.

field mlc_span: float = 138.0

The total size of the field. Initial/final MLC position = +/- mlc_span/2.

field mu_per_segment: float = 48.0

The number of MUs to deliver to each ROI.

field mu_per_transition: float = 8.0

The number of MUs to deliver while the MLCs move from one ROI to the next.

field reference_beam_add_before: bool = False

Whether to add the reference_beam before or after the dynamic beam. If True, the gantry angle is set to the initial gantry angle of the dynamic beam. If False, the gantry angle is set to the final gantry angle of the dynamic beam.

field reference_beam_mu: float = 100.0

The number of MU’s to be delivered in the reference beam (static beam).

classmethod VMATDRGS.from_varian_reference() Self[source]

Add two beams that replicates Varian’s T2_DoseRateGantrySpeed_M120_TB_Rev02.dcm

Warning

This method is intended to approximate Varian-provided reference plans. Exact replication is not guaranteed.

Small discrepancies may occur in one or more axes (e.g., gantry, collimator, couch, jaw, or MLC positions) due to rounding, or limitations in what can be customized by the PlanGenerator.

VMAT MLC Speed

pydantic model conjuror.plans.truebeam.VMATDRMLC[source]

Bases: QAProcedure

Create beams like Clif Ling VMAT DRMLC tests. The defaults use an optimized selection for a TrueBeam.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Fields:
field couch_lat: float = 0

The couch lateral position.

field couch_lng: float = 1000

The couch longitudinal position.

field couch_rot: float = 0

The couch rotation.

field couch_vrt: float = 0

The couch vertical position.

field dynamic_delivery_at_static_gantry: tuple[float, ...] = ()

There is one beam created for each static gantry angle. These beams contain the same control point sequence as the dynamic beam, but the gantry angle is replaced by a single value. There will be no modulation of dose rate and gantry speeds, and can be used as an alternative reference beam.

field energy: float = 6

The energy of the beam.

field fluence_mode: FluenceMode = FluenceMode.STANDARD

The fluence mode of the beam.

field gantry_rotation_clockwise: bool = False

The direction of the gantry rotation. If True, the gantry will rotate clockwise.

field gantry_speeds: tuple[float, ...] | None = None

The gantry speeds. When None it will default to max gantry speed for all segments.

field initial_gantry_offset: float = 10.0

The initial gantry offset. E.g. if initial_gantry_offset=1 and gantry_rotation_clockwise=True, then start angle = 181 IEC. If gantry_rotation_clockwise=False, then start angle = 179 IEC.

field interpolation_factor: int = 1

Interpolation factor to create control points with finer resolution.

field jaw_padding: float = 0.0

The added jaw position with respect to the initial/final MLC positions.

field max_dose_rate: int = 600

The max dose rate. This is used to compute the control point sequence to achieve the test dose_rates.

field mlc_motion_reverse: bool = False

The direction of MLC motion. If False, the leaves move in positive direction (IEC) from -mlc_span/2 to +mlc_span/2. If True, the leaves move in negative direction (IEC) from +mlc_span/2 to -mlc_span/2.

field mlc_speeds: tuple[float, ...] = (15.0, 20.0, 10.0, 5.0)

The MLC speeds to test. Each speed will have its own ROI.

field reference_beam_add_before: bool = False

Whether to add the reference_beam before or after the dynamic beam. If True, the gantry angle is set to the initial gantry angle of the dynamic beam. If False, the gantry angle is set to the final gantry angle of the dynamic beam.

field reference_beam_mu: float = 100.0

The number of MU’s to be delivered in the reference beam (static beam).

field segment_width: float = 30.0

The width of each exposed segment.

classmethod VMATDRMLC.from_varian_reference() Self[source]

Add two beams that replicates Varian’s T3_MLCSpeed_M120_TB_Rev02.dcm

Warning

This method is intended to approximate Varian-provided reference plans. Exact replication is not guaranteed.

Small discrepancies may occur in one or more axes (e.g., gantry, collimator, couch, jaw, or MLC positions) due to rounding, or limitations in what can be customized by the PlanGenerator.

API Reference

pydantic model conjuror.plans.truebeam.OpenField[source]

Bases: QAProcedure

Create an open field beam.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Fields:
field beam_name: str = 'Open'

The name of the beam.

field coll_angle: float = 0

The collimator angle of the beam.

field couch_lat: float = 0

The couch lateral position.

field couch_lng: float = 1000

The couch longitudinal position.

field couch_rot: float = 0

The couch rotation.

field couch_vrt: float = 0

The couch vertical position.

field defined_by_mlc: bool = True

Whether the field edges are defined by the MLCs or the jaws.

field dose_rate: int = 600

The dose rate of the beam.

field energy: float = 6

The energy of the beam.

field fluence_mode: FluenceMode = FluenceMode.STANDARD

The fluence mode of the beam.

field gantry_angle: float = 0

The gantry angle of the beam.

field mlc_mode: MLCLeafBoundaryAlignmentMode = MLCLeafBoundaryAlignmentMode.OUTWARD

Controls how the open field aligns with MLC leaf boundaries along the y-axis. EXACT: Both y1 and y2 must coincide with an MLC leaf boundary; raises an error otherwise. ROUND: Limits are rounded to the nearest boundary. INWARD: Non-aligned leaf bands are treated as outfield, resulting in a smaller field in y. OUTWARD: Non-aligned leaf bands are treated as infield, resulting in a larger field in y.

field mu: float = 100.0

The monitor units of the beam.

field outside_strip_width: float = 5

The width of the strip of MLCs outside the field. The MLCs will be placed to the left, under the X1 jaw by 20mm.

field padding: float = 5

The padding to add to the jaws or MLCs.

field x1: float [Required]

The left edge position.

field x2: float [Required]

The right edge position.

field y1: float [Required]

The bottom edge position.

field y2: float [Required]

The top edge position.

pydantic model conjuror.plans.truebeam.MLCTransmission[source]

Bases: QAProcedure

Add MLC transmission beams to the plan. The beam is delivered with the MLCs closed and moved to one side underneath the jaws.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Fields:
field beam_names: list[str] = ['MLC Tx - Ref', 'MLC Tx - Bank-A', 'MLC Tx - Bank-B']

A list containing the names of the beams to use in the following order: reference beam, transmission beam bank A, transmission beam bank B.

field coll_angle: float = 0

The collimator angle of the beam.

field couch_lat: float = 0

The couch lateral position.

field couch_lng: float = 1000

The couch longitudinal position.

field couch_rot: float = 0

The couch rotation.

field couch_vrt: float = 0

The couch vertical position.

field dose_rate: int = 600

The dose rate of the beam.

field energy: int = 6

The energy of the beam.

field fluence_mode: FluenceMode = FluenceMode.STANDARD

The fluence mode of the beam.

field gantry_angle: float = 0

The gantry angle of the beam.

field height: float = 100

The height of the reference field.

field mu_per_bank: int = 100

The monitor units to deliver for each bank transmission test.

field mu_per_ref: int = 100

The monitor units to deliver for the reference open field.

field overreach: float = 10

The amount to tuck the MLCs under the jaws.

field width: float = 100

The width of the reference field.

pydantic model conjuror.plans.truebeam.DosimetricLeafGap[source]

Bases: QAProcedure

Add beams to measure the Dosimetric Leaf Gap (DLG).

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Fields:
field coll_angle: float = 0

The collimator angle of the beam.

field couch_lat: float = 0

The couch lateral position.

field couch_lng: float = 1000

The couch longitudinal position.

field couch_rot: float = 0

The couch rotation.

field couch_vrt: float = 0

The couch vertical position.

field dose_rate: int = 600

The dose rate of the beam.

field energy: float = 6

The energy of the beam.

field final_position: float = 60

The final position of the MLC gap.

field fluence_mode: FluenceMode = FluenceMode.STANDARD

The fluence mode of the beam.

field gantry_angle: float = 0

The gantry angle of the beam.

field gap_widths: Sequence[float] = (2, 4, 6, 10, 14, 16, 20)

The gap widths for the MLC sweeps.

field mu: int = 100

The monitor units of each beam.

field start_position: float = -60

The start position of the MLC gap.

field x1: float = -50

The left edge position.

field x2: float = 50

The right edge position.

field y1: float = -50

The bottom edge position.

field y2: float = 50

The top edge position.

pydantic model conjuror.plans.truebeam.WinstonLutz[source]

Bases: QAProcedure

Add Winston-Lutz beams to the plan. Will create a beam for each set of axes positions. Field names are generated automatically based on the axes positions.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Fields:
field couch_lat: float = 0

The couch lateral position.

field couch_lng: float = 1000

The couch longitudinal position.

field couch_vrt: float = 0

The couch vertical position.

field defined_by_mlc: bool = True

Whether the field edges are defined by the MLCs or the jaws.

field dose_rate: int = 600

The dose rate of the beam.

field energy: float = 6

The energy of the beam.

field fields: Iterable[WinstonLutzField] = (WinstonLutzField(gantry=0.0, collimator=0.0, couch=0.0, name=None),)

The positions of the axes.

field fluence_mode: FluenceMode = FluenceMode.STANDARD

The fluence mode of the beam.

field mlc_mode: MLCLeafBoundaryAlignmentMode = MLCLeafBoundaryAlignmentMode.OUTWARD

Controls how the open field aligns with MLC leaf boundaries along the y-axis. EXACT: Both y1 and y2 must coincide with an MLC leaf boundary; raises an error otherwise. ROUND: Limits are rounded to the nearest boundary. INWARD: Non-aligned leaf bands are treated as outfield, resulting in a smaller field in y. OUTWARD: Non-aligned leaf bands are treated as infield, resulting in a larger field in y.

field mu: float = 10.0

The monitor units of the beam.

field padding: float = 5

The padding to add to the jaws or MLCs.

field x1: float = -10.0

The left edge position.

field x2: float = 10.0

The right edge position.

field y1: float = -10.0

The bottom edge position.

field y2: float = 10.0

The top edge position.