sequencing
MLC leaf sequencing algorithms for converting fluence maps to deliverable photon IMRT plans.
- class matRad_PhotonLeafSequencerEngel(pln)
Bases:
matRad_PhotonLeafSequencerAbstract- Property Summary
- name = 'Photons Engel Leaf Sequencer'
- shortName = 'engel'
- possibleRadiationModes = {'photons'}
- Method Summary
- sequence(this, w, stf)
- pragma Justify(metric, “cnest”,“grandfathered: pre-existing nesting depth of the ported Engel algorithm”);
- static isAvailable(pln, machine)
see superclass for information
- class matRad_ParticleScanningSequencerSpill(pln)
Bases:
matRad_SequencerBasematRad_ParticleScanningSequencerSpill: Sequencer for scanned particle delivery. Computes the spot delivery order and timing (spill / lateral scanning model), e.g. for 4D dose calculation. It does not modify the fluence.
Constructor, forwards to the base class. An explicit constructor chain is required so that property assignment from pln persists under Octave.
- Property Summary
- name = 'Particle Spill Scanning Sequencer'
- shortName = 'IMPT'
- possibleRadiationModes = {'protons','helium','carbon','oxygen'}
- weightPencilBeam = 1e6
- esTime = 3*10^6
[mu s] time required for synchrotron to recharge it’ spill
- spillRechargeTime = 2*10^6
[mu s] number of particles generated in each spill
- spillSize = 4*10^10
- scanSpeed = 10
[m/s] speed of synchrotron’s lateral scanning in an IES
- spillIntensity = 4*10^8
number of particles per second
- Method Summary
- sequence(this, w, stf)
- calcSpotOrder(~, stf)
- calcSpotTime(this, sequence, w, stf)
- static isAvailable(pln, machine)
see superclass for information
- static makePhaseMatrix(sequence, numOfPhases, motionPeriod)
- matRad_enforceDeliveryConstraints(apertureInfo, fast)
matRad: make an arc plan deliverable within the machine limits
Slows the gantry (and with it the dose rate) at each DAO control point until the realized leaf speed and monitor unit rate fit the machine constraints in apertureInfo.deliveryConstraints.
- call
apertureInfo = matRad_enforceDeliveryConstraints(apertureInfo, fast)
- input
- apertureInfo: aperture shape info struct from DAO/sequencing
(requires apertureInfo.arc)
- fast: 1 => fastest possible delivery
0 => multiply delivery time by 10%
- output
apertureInfo: aperture shape info struct
Copyright 2016 the matRad development team.
This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
- class matRad_PhotonLeafSequencerXia(pln)
- class matRad_PhotonLeafSequencerVMATAbstract(pln)
Bases:
matRad_PhotonLeafSequencerAbstract- Property Summary
- isVMATCapable = true
cheap tag for isprop-style capability checks
- runVMAT = false
toggle VMAT (dynamic/arc) delivery
- continuousAperture = false
interpolate leaf positions between DAO angles
- arcFluenceSmoothing = 'gaussian'
fluence smoothing kernel applied before stratification, see availableArcFluenceSmoothing
- apertureSelection = 'doseAreaProduct'
how surplus apertures are discarded, see availableApertureSelection
- weightToMU = 1
bixel weight -> MU conversion factor (from dij.weightToMU)
- Method Summary
- smoothFluenceForArc(this, fluenceMx)
Fluence smoothing prior to stratification, selected by the arcFluenceSmoothing property. Only applied for VMAT: it alters the fluence that is decomposed, so the sequenced result no longer reproduces the optimized fluence, which is exactly what static/IMRT sequencing relies on.
It defaults to ‘gaussian’ because VMAT needs one aperture per DAO control point: the graded field rim the blur produces is what lets the stratification yield more apertures as the level count is raised. A perfectly flat fluence decomposes into a single aperture at any number of levels, which no amount of re-stratification can fix (see sequenceDynamic).
- applyArcSequencing(this, sequence, stf)
Spreads the shapes generated at each FMO-anchor beam across its DAO-angle children and computes gantry rotation speed / MU rate. arcSequencing needs sequence.deliveryConstraints to be set.
- arcSequencing(this, sequencing, stf)
Distributes the shapes generated at each FMO-anchor beam to its DAO-angle children according to the sweep trajectory, then computes per-beam gantry rotation speed, MU rate and rescaled shape weights. Assumes shapes are already ordered in increasing (left to right) leaf position.
- Input:
sequencing – shape sequencing structure (needs .beam and .deliveryConstraints)
stf – matRad steering struct (beam geometry etc.)
- Output:
beam – beam struct with shapes and weights distributed to the correct optimized gantry angles
- getMachineConstraints(~, stf)
Loads the machine delivery constraints (gantry rotation speed, leaf speed, MU rate) referenced by the given stf, falling back to generic defaults if the machine file doesn’t define any.
- buildVMATApertureInfo(this, sequence, stf)
Ports the VMAT branch of the former matRad_sequencing2ApertureInfo.m to build the full apertureInfo struct including apertureInfo.arc.*, then converts it to the DAO vector representation via matRad_OptimizationProblemVMAT.
- postProcessVMATApertureInfo(~, apertureInfo)
Interpolates sub-child gantry segments, then runs the leaf-speed/dose-rate limiting pass (optDelivery).
- static availableArcFluenceSmoothing()
Fluence smoothing kernels a VMAT sequencer can apply before stratifying an FMO fluence map into apertures.
- class matRad_PhotonLeafSequencerSiochi(pln)
Bases:
matRad_PhotonLeafSequencerVMATAbstract- Property Summary
- name = 'Photons Siochi Leaf Sequencer'
- shortName = 'siochi'
- possibleRadiationModes = {'photons'}
- Method Summary
- sequence(this, w, stf)
- sequenceStatic(this, w, stf)
- sequenceDynamic(this, w, stf)
VMAT (dynamic/arc) sequencing: gates to FMO-anchor beams, optionally smooths the fluence before decomposition (see arcFluenceSmoothing), keeps re-decomposing at increasing numLevels until enough shapes exist for this beam’s DAO-angle children, then spreads the result across those children and builds the VMAT apertureInfo. Ported from the former matRad_siochiLeafSequencing.m functional implementation.
- decomposePort(this, map)
Returns tops and bases of a fluence matrix “map” for Siochi leaf sequencing algorithm (rod pushing part). Accounts for collisions and tongue and groove (Tng) effects.
- fixTnGPass(~, tops, bases, map, i, jRange, neighborOffset)
One directional tongue-and-groove correction pass over jRange, matching each rod j against its neighbor j+neighborOffset. Shared by decomposePort’s “down” (neighborOffset=1, comparing against j+1) and “up” (neighborOffset=-1, comparing against j-1) passes, which are otherwise identical.
- convertToSegments(this, shapes, shapesWeight, k, tops, bases)
Convert tops and bases to shape matrices. These are taken as to be the shapes of uniform level/elevation after the rods are pushed.
- differentSlab(~, tops, bases, level)
Returns 1 if slab level is different than slab level-1 0 otherwise
- static isAvailable(pln, machine)
see superclass for information
- matRad_calcMaxLeafSpeed(apertureInfo)
matRad calculation of maximum leaf speed
Records the leaf speed realized by an arc plan, per DAO control point and over the whole arc. This is the reporting/limiting computation used after sequencing; the differentiable leaf speed constraint used during DAO is computed separately in matRad_OptimizationProblemVMAT.
- call
apertureInfo = matRad_calcMaxLeafSpeed(apertureInfo)
- input
apertureInfo: aperture info struct (requires apertureInfo.arc)
- output
- apertureInfo: aperture info struct, with maxLeafSpeed set on each DAO
beam and on the struct itself
Copyright 2015 the matRad development team.
This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
- class matRad_PhotonLeafSequencerAbstract(pln)
Bases:
matRad_SequencerBaseConstructor, forwards to the base class. An explicit constructor chain is required so that property assignment from pln persists under Octave.
- Property Summary
- numOfMLCLeafPairs = 80
- numLevels = 5
number of fluence stratification levels for leaf sequencing (for VMAT only a
- preconditioner = false
it is increased automatically until every FMO beam yields at least as many apertures as it has DAO child angles)
- Type:
starting value
- sequencingLevel
deprecated alias for numLevels
- Method Summary
- sequence(this, w, stf)
- initBeam(this, stf, wCurr)
- sequencing2ApertureInfo(this, sequence, stf)
MLC parameters:
- plotSegments(this, sequencing)
create the sequencing figure
- static isAvailable(pln, machine)
- static aperture2collimation(pln, stf, sequence, visBool)
- static getMLCGeometry(stfBeam, numOfMLCLeafPairs, bixelIndOffset)
Derive the per-beam MLC geometry from an stf beam’s ray positions: bixel index map, leaf position limits, active leaf pairs and MLC window. Shared by aperture-info construction in the photon sequencers and the fine-angle recalculation.
- Input:
stfBeam – single stf beam entry (stf(i))
numOfMLCLeafPairs – total number of physical MLC leaf pairs
bixelIndOffset – index of the last bixel of the preceding beams; the beam’s rays are numbered starting from bixelIndOffset + 1
- Output:
geometry – struct with fields numOfActiveLeafPairs, leafPairPos, isActiveLeafPair, centralLeafPair, limLeft, limRight, bixelIndMap, posOfCornerBixel, MLCWindow
bixelIndOffset – updated offset (input + stfBeam.numOfRays)
- static discardApertures(beam, numToKeep, selection)
The sequencing algorithm generates an a priori unknown number of apertures. We only want to keep a certain number of them (numToKeep), see availableApertureSelection for how they are picked. The kept shapes are preserved in their original trajectory order and get new weights.
- Input:
beam – beam struct containing original shapes and intensities
numToKeep – number of apertures to keep
selection – ‘doseAreaProduct’ (default) or ‘leastSquares’
- Output:
newBeam – beam struct with shapes and re-scaled intensities
- static availableApertureSelection()
Strategies for reducing the generated apertures of a beam to the number that can actually be delivered:
doseAreaProduct keep the apertures with the highest product of open area and weight, and rescale them so that the total dose-area product is maintained. Since the stratification gives every segment the same weight, this ranks by open area. leastSquares keep the apertures that best reconstruct the fluence the full decomposition would deliver, with the weights refit to that fluence.
- static selectByDoseAreaProduct(beam, numToKeep)
Original selection: highest open-area x weight, rescaled to preserve the total dose-area product.
- static selectByLeastSquares(beam, numToKeep)
Pick the subset of apertures that best reproduces the fluence the full decomposition delivers, and refit their weights to it.
Forward stepwise selection: in each step try every aperture that is not selected yet, refit ALL weights by non-negative least squares, and keep the candidate with the smallest residual. Refitting before choosing matters - picking by the residual reduction of a single aperture (plain matching pursuit) commits to an aperture before the weights of the others can adapt, and then never recovers from overshooting.
Cost is numToKeep x numOfShapes tiny least squares solves, which is nothing next to the decomposition itself.
- static solveNonNegativeLeastSquares(designMx, rhs)
Minimal non-negative least squares for the handful of columns used here: solve unconstrained, drop the most negative coefficient, repeat. Not a full Lawson-Hanson (coefficients are never re-admitted), which is adequate for numToKeep columns.
- matRad_aperture2collimation(pln, stf, sequencing, apertureInfo)
matRad function to convert sequencing information / aperture information into collimation information in pln and stf for field-based dose calculation
call
[pln,stf] = matRad_aperture2collimation(pln,stf,sequencing,apertureInfo)
- Input:
pln – pln file used to generate the sequenced plan
stf – stf file used to generate the sequenced plan
sequencing – sequencing information (from resultGUI)
apertureInfo – apertureInfo (from resultGUI)
- Output:
pln – matRad pln struct with collimation information
stf – matRad stf struct with shapes instead of beamlets
- References
Copyright 2022-2026 the matRad development team. Author: wahln
This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
- matRad_leafTouching(apertureInfo)
matRad function to improve instances of leaf touching by moving leaves from the centre to sweep with the non-touching leaves.
Currently only works with VMAT, add option to work with IMRT (not as crucial)
- call
apertureInfo = matRad_leafTouching(apertureInfo)
- input
- apertureInfo: matRad aperture weight and shape info struct (requires
apertureInfo.arc)
- output
apertureInfo: matRad aperture weight and shape info struct
Note on the two sampling modes below: the function dispatches on whether shape(1) already carries leftLeafPosInitial/Final, sampling the trajectory either once (beam centre) or twice (dose sector borders) per DAO beam. Only the once-per-beam mode has ever run. The sole call site (matRad_PhotonLeafSequencerVMATAbstract) does not set those fields beforehand – this function creates them itself, at the end of its own run – and that has been true since the function was first added. The twice-per-beam mode was presumably written for a second, post-DAO cleanup invocation that was never wired up; it read a field that never existed on apertureInfo.beam, so it would have errored on its first execution. Its output has therefore never been validated: do not enable a second invocation without checking the sweep-reset semantics (the limLeft/limRight substitution at FMO sector borders) against intent.
References
Copyright 2015 the matRad development team.
This file is part of the matRad project. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution and at https://github.com/e0404/matRad/LICENSE.md. No part of the matRad project, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
- class matRad_SequencerBase(pln)
Bases:
handlematRad_SequencerBase: Abstract base class for all matRad sequencers. Defines the common interface and the factory/lookup machinery (see getSequencerFromPln / getAvailableSequencers) shared by the photon leaf sequencers and the particle spot sequencer.
Constructs standalone sequencer with or without pln
- Property Summary
- isSequencer = true
const boolean for inheritance quick check
- name
Descriptive Name
- shortName
Short name for referencing
- possibleRadiationModes
Possible radiation modes for the respective Sequencer
- radiationMode
Radiation Mode
- visMode = 0
vis bool
- Method Summary
- setDefaults(this)
set default values from MatRad_Config
- warnDeprecatedProperty(this, oldProp, msg, newProp)
- assignPropertiesFromPln(this, pln, warnWhenPropertyChanged)
Assign properties from pln.propSeq to the sequencer
- sequence(this, w, stf)
- static getSequencerFromPln(pln, warnDefault)
Returns a sequencer instance selected from the given pln struct, falling back to the configured default sequencer if none fits.
- static getAvailableSequencers(pln, optionalPaths)
- static isAvailable(pln, machine)