Creating Scripts for Eclipse Automation
You can use the Eclipse Automation features in the Eclipse Scripting API for the tasks listed in this chapter.
Adding and Modifying Structures
You can add, remove, and modify structures by using the classes described below.
Adding and Removing Structures
Use the StructureSet
class to add and remove structures:
- Add structures with the
AddStructure
method. You can use theCanAddStructure
method to check if the script is able to add a new structure to the structure set.
Tip
To specify the type of structure to add, give the string representation of the DICOM type as a
parameter to the AddStructure
method. Example values are EXTERNAL, ORGAN, and PTV.
For a complete list of allowed values, refer to Eclipse Scripting API Online Help.
Add structure code information with
AddStructure(StructureCodeInfo)
.
To constructStructureCodeInfo
, you need to pass coding scheme and structure code, for exampleStructureCodeInfo scInfo = new StructureCodeInfo("99VMS_STRUCTCODE", "Support");
Remove structures with the
RemoveStructure
method.You can convert an isodose surface to a structure. See
Structure.ConvertDoseLevelToStructure
.
Modifying Structures
Use the Structure
class to modify structures:
- Add contours to a structure with the
AddContourOnImagePlane
method.
Input parameters
- List of points defining the contour
- Index of the image plane where the contours are to be added.
- Subtract contours with the
SubtractContourOnImagePlane
method.
Input parameters
- List of points defining the contour
- Index of the image plane where the contours are to be subtracted.
- Clear all contours for a structure with the
ClearAllContoursOnImagePlane
method. - Set a structure to the result of a Boolean operation with the
And
,Or
, Not, andXor
methods. These methods are available also on theSegmentVolume
class, which allows you to execute a combination of Boolean operations with an intermediate variable of theSegmentVolume
type before assigning the final result to aStructure
object. For more information, see theSegmentVolume
property getter and setter of theStructure
class. - Set a three-dimensional symmetric or asymmetric margin around a structure. First call the
Margin
orAsymmetricMargin
method. Then set the resultingSegmentVolume
object to theStructure
object using theSegmentVolume
property. For more information, see the get and set accessors of theSegmentVolume
property of theStructure
class.
Adding and Removing Artificial Phantom Images
Use Patient
class to add and remove artificial phantom images:
- Add a phantom image with the
AddEmptyPhantom
method.
Input parameters
- Patient orientation
- Size of the image set in X- and Y-directions in pixels and in millimeters
- Number of image planes
- Separation between image planes in millimeters.
Note
Image
is created to a new Study
.
Return value of the AddEmptyPhantom
is a new StructureSet
where you can add structures and their contours.
You can access the created Image
using the Image
property of the StructureSet
class.
- Remove a phantom image and associated
StructureSet
with theRemoveEmptyPhantom
method.
Input parameter
StructureSet
. TheStructureSet
must not contain any Structures.
- Before removing the phantom, you can use the
CanRemoveEmptyPhantom
method to check if the script is able to remove the phantom Image.
Copying an Image from Another Patient
Use the Patient
class to copy a 3D image from another patient. This must only be used when creating Verification Plans with a script.
- Specify the identifiers of the other patient, the study of the other patient, and the 3D image of the other patient. Validate the identifiers using the method
CanCopyImageFromOtherPatient
. Copy the image using the methodCopyImageFromOtherPatient
.
Input parameters:
- Identifier of the other patient
- Identifier of the study of the other patient
- Identifier of the 3D image of the other patient.
Creating and Modifying Plans and Fields
You can create and modify external beam photon plans and fields by using the classes described below. For brachytherapy plans, no modifications are supported.
Adding and Removing Plans
Use the Course
class to add and remove plans:
- Add a new external beam photon plan with the
AddExternalPlanSetup
method.
Input parameter
StructureSet
- A new primary reference point without a location is automatically created for the plan, or alternatively you can specify an existing reference point that will be used as primary.
- You can use the
CanAddPlanSetup
method to check if the script is able to add a new plan to the course. - Add a new external beam photon plan as a verification plan with
AddExternalPlanSetupAsVerificationPlan
.
Input parameters
StructureSet
and- Plan to verify.
- Use AddIonPlanSetup for creating a proton treatment plan.
- Use AddIonPlanSetupAsVerificationPlan for creating a proton verification plan.
- Remove a plan with the
RemovePlanSetup
method.
Input parameter
- You can use
CanRemovePlanSetup
to check if the script is able to remove the plan from the course. - Copy a plan with
CopyPlanSetup
to create a plan in another image that is not registered.
Adding Fields
Use the ExternalPlanSetup
class to add photon fields:
- Add a new static open field to the plan with the
AddStaticBeam
method. - Add a new arc field to the plan with the
AddArcBeam
method. - Add a field with static
MLC
shape with theAddMLCBeam
orAddMLCArcBeam
method. - Add an arc field with dynamic
MLC
shape using theAddConformalArcBeam
method. - Add an IMRT field with the Multiple Static Segment delivery method using the
AddMultipleStaticSegmentBeam
method. - Add an IMRT field with the Sliding Windows delivery method using the
AddSlidingWindowBeam
method. - Add a VMAT field with the
AddVMATBeam
method.
Define the TreatmentMachine configuration for added fields:
- Create an
ExternalBeamMachineParameters
object and use it as input for the above mentioned beam adding methods of theExternalPlanSetup
class.
Input parameters
- Treatment machine identifier
- Energy mode identifier
- Field technique identifier
- Dose rate, and optionally,
- Primary fluence mode identifier.
For information about other input parameters for the beam adding methods of the ExternalPlanSetup
class, refer to Eclipse Scripting API Online Help.
Use the IonPlanSetup.AddModulatedScanningBeam
to add modulated scanning fields to a proton plan.
Modifying Photon Fields
Use the BeamParameters
class to modify a Beam
:
- Call the
GetEditableParameters
method.- Modify the returned
BeamParameters
object. - Call
ApplyParameters
. If the call succeeds, the beam parameter data is updated.
- Modify the returned
- Set the optimal fluence of an IMRT field with the
SetOptimalFluence
method. - Modify ControlPoints using the ControlPoints property of the
BeamParameters
class. Each ControlPoint has oneControlPointParameters
object. CallApplyParameters
. If the call succeeds, the beam data is updated. - Methods to perform
MLC
fitting are available. SeeBeam.FitMLCToStructure
andBeam.FitMLCToOutline
.
Modifying Proton Fields
The following can be adjusted in a proton field:
Proximal target margin
IonBeam.ProximalTargetMargin
.Distal target margin
IonBeam.DistalTargetMargin
.Lateral margins
IonBeam.ProximalTargetMargin
.
Modifying Proton Scanning Spots
Use the IonBeamParameters
class to modify the scanning spots of an IonBeam
:
Call the
IonBeam.GetEditableParameters
.With the returned
IonBeamParameters
object, get propertyIonControlPointPairs
to get collection of editable control point pairs.Iterate over the list of control point pairs and get the editable spot lists using method
IonControlPointPair.RawSpotList
orIonControlPointPair.FinalSpotList
.Iterate over the scanning spot list and set the position or weight of each spot using setter properties
IonSpotParameters.Weight
,IonSpotParameters.X
orIonSpotParameters.Y
.When the scanning spots have been changed as desired, call
IonBeam.ApplyParameters(IonBeamParameters)
. If the call succeeds, the proton beam / control point / scanning spot data resident in Eclipse memory has been updated.
// unrealistic example shows how to edit the raw scanning spot lists
foreach (IonBeam ionBeam in context.IonPlanSetup.IonBeams)
{
IonBeamParameters beamParams = ionBeam.GetEditableParameters();
IonControlPointPairCollection cpList = beamParams.IonControlPointPairs;
foreach (IonControlPointPair icpp in cpList)
{
IonSpotParametersCollection rawSpotList = icpp.RawSpotList;
foreach (IonSpotParameters spot in rawSpotList)
{
spot.Weight = 1; // set weight to desired
spot.X = 1; // set X position of scanning spot
spot.Y = 1; // set Y position of scanning spot
}
}
// apply scan spot changes to Eclipse
ionBeam.ApplyParameters(beamParams)
}
Figure 13 Sample Script Code to Edit Raw Scanning Spots
- Methods
IonControlPointPair.ResizeFinalSpotList
andIonControlPointPair.ResizeRawSpotList
allow resizing the proton raw and final scanning spot lists.
Modifying Proton Range Shifter Settings
Use the IonBeamParameters
class to modify the range shifter settings of an IonBeam
:
Call the
IonBeam.GetEditableParameters
method.With the returned
IonBeamParameters
object- Set
PreSelectedRangeShifter1Id, PreSelectedRangeShifter2Id
for range shifter IDs and - Set
PreSelectedRangeShifter1Setting, PreSelectedRangeShifter2Setting
for range shifter settings.
- Set
When the range shifter settings have been changed as desired, call IonBeam.ApplyParameters(IonBeamParameters)
. If the call succeeds, range shifter beam line modifier settings have been updated.
DECT Features for Proton Plans
You can use the following Dual-Energy CT (DECT) specific methods:
Image.CalculateDectProtonStoppingPowers
, that calculates the pixel-wise proton stopping powers from the planning CT and DECT Rho (relative electron density) and Z (effective atomic number) images.IonPlanSetup.CreateDectVerificationPlan
, that can be used to evaluate the dose distribution of a proton treatment plan using DECT stopping power information.Use
Image.GetProtonStoppingPowerCurve
method for reading the proton stopping power curve of the CT scanner associated with an image.
Adding Prescriptions
- Set the prescription with the
SetPrescription
method of thePlanSetup
object.
Input parameters
- Number of fractions
- Prescribed dose per fraction (using the dose unit defined for your system in the Varian Service Portal, and
- Prescribed percentage.
Using Calculation Algorithms
You can use the classes described below for IMRT and VMAT optimization, leaf motion calculation, and dose calculation.
Setting Calculation Models
Use the PlanSetup
class to set the calculation models:
- Set the calculation model with the
SetCalculationModel
method.
Input parameters
- Calculation type and
- Calculation model name.
Current calculation model can be retrieved with the GetCalculationModel
method.
All available models can be read with the GetModelsForCalculationType
method of the ExternalPlanSetup
class.
- Set the calculation options using the
SetCalculationOption
method. The available options and their allowed values depend on the calculation model. Before setting the calculation options, set the calculation model. - Clear the calculation model of a plan with the
ClearCalculationModel
method.
Viewing Calculation Logs
Use the following classes to read the messages from the algorithms:
Beam
System.Diagnostics.Trace
Tip
Access calculation logs after calculation with CalculationLogs
property which holds a collection of BeamCalculationLog
objects that can be filtered using Category
property. The category for the optimization log is Optimization.
Use the Trace class of the .NET framework to receive messages from the algorithms during the calculation. For more information about how to use Trace Listeners, consult the Microsoft Developer Network (MSDN) documentation.
Executing DVH Estimation
Use the ExternalPlanSetup
class or IonPlanSetup
class for executing DVH estimation.
- Run DVH estimation with the
CalculateDVHEstimates
method.
Input parameters
- Identifier of the DVH estimation model
Dose
level(s) for target structure(s) and the mapping between the structures of the estimation model and the structure set of the plan.
- Use Success property of
OptimizerResult
to check if the algorithm executed without errors.
Optimizing IMRT and VMAT Plans
Use the following classes for optimizing IMRT and VMAT plans:
Setting up the Plan
- Before starting the optimization, create open fields for the plan with the
AddStaticBeam
orAddArcBeam
method of theExternalPlanSetup
class. - Use the
OptimizationSetup
property of thePlanSetup
class to access theOptimizationSetup
object.
Adding and Modifying Optimization Objectives
Use the OptimizationSetup
object to add and modify optimization objectives:
- Add point objectives with the
AddPointObjective
method. - Add mean dose or gEUD objectives with the
AddMeanDoseObjective
orAddEUDObjective
methods. - Add beam-specific parameters with the
AddBeamSpecificParameter
method. - Add a Normal Tissue
Objective
with theAddNormalTissueObjective
method. - Remove optimization objectives with the
RemoveObjective
method. - Remove optimization parameters with the
RemoveParameter
method.
Optimizing an IMRT Plan
Use the ExternalPlanSetup
class to optimize an IMRT plan:
- Run the IMRT optimization algorithm with the
Optimize
method.
Input parameter
- Maximum number of iterations.
- All existing optimal fluences are removed.
- As a result of Optimize, the
OptimizerResult
object is returned. - Use the Success property of
OptimizerResult
to check if the algorithm executed without errors.- You can continue IMRT optimization with the overloaded version of the
Optimize
method, for which you can give theOptimizationOption
as a parameter. To continue optimization with existing optimal fluences, use theOptimizationOption.ContinueOptimization
as a parameter. - You can continue IMRT optimization with the existing plan dose as an intermediate dose. To do this, use the overloaded version of the
Optimize
method, and define theOptimizationOption.ContinueOptimizationWithPlanDoseAsIntermediateDose
as a parameter. - You can terminate IMRT optimization upon convergence. To do this, use the
Optimize
method that does not take any input parameters, or the overloaded version of theOptimize
method that takes anOptimizationOptionsIMRT
object as an input. Construct theOptimizationOptionsIMRT
object using theOptimizationConvergenceOption.TerminateIfConverged
option. After optimization you can read the actual number of iterations fromOptimizerResult.NumberOfIMRTOptimizerIterations
. - You can use intermediate dose calculation during IMRT optimization. To do this, create an
OptimizationOptionsIMRT
object and specify thenumberOfStepsBeforeIntermediateDose
. Then use the overloaded version ofOptimize
method that takes anOptimizationOptionsIMRT
object as an input.
- You can continue IMRT optimization with the overloaded version of the
Optimizing a VMAT Plan
Use the ExternalPlanSetup
class to optimize a VMAT plan:
Run the VMAT optimization algorithm with the
OptimizeVMAT
method. As a result of Optimize, theOptimizerResult
object is returned. Use the Success property ofOptimizerResult
to check if the algorithm executed without errors.You can use intermediate dose calculation during VMAT optimization. To do this, create an
OptimizationOptionsVMAT
object by specifying either the option OptimizationIntermediateDoseOption.UseIntermediateDose or the number of optimization cycles. Then use the overloaded version of methodOptimizeVMAT
that takes anOptimizationOptionsVMAT
object as an input parameter.
Accessing Dose Volume Histograms
Use the OptimizerResult
class to access the results of the optimization:
- Use the Structure DVHs property to access the Dose Volume Histograms after optimization.
- The returned collection contains an
OptimizerDVH
object for eachStructure
that had optimization objectives defined. - Use the CurveData property of the
OptimizerDVH
class to access the points of the Dose Volume Histogram.
- The returned collection contains an
Accessing Optimal Fluences after IMRT Optimization
Use the Beam
class to access the optimal fluence information:
- Read the optimal fluence matrix after optimization with the
GetOptimalFluence
method.
Using Trade-Off Exploration
Use the TradeoffExplorationContext
class and its methods and properties for exploring trade-offs in plans:
- Start from an optimized and calculated plan by using the
TradeoffExplorationContext
class. - Select the trade-off objectives by using the
AddTradeoffObjective(Structure)
method. At least one objective is needed. - Query if all pre-conditions to generate the plan collection are met by calling the CanCreatePlanCollection property.
- If CanCreatePlanCollection is true, generate the plan collection by calling the
CreatePlanCollection
method. - If the plan collection is generated successfully, the HasPlanCollection property is set to true. The class is now ready for exploring different trade-offs.
- To evaluate the current trade-off, use the
GetObjectiveCost
, CurrentDose, andGetStructureDvh
methods. - To explore different trade-offs:
- Use the
SetObjectiveCost
method to reduce the cost of any objective. - Use the
SetObjectiveUpperRestrictor
method to prevent the cost of an objective from exceeding a specified limit.
- Use the
- Save the trade-off exploration results by calling the ApplyTradeoffExplorationResult method. The method also applies the trade-off exploration result to the plan setup for IMRT plans.
- In case of a VMAT plan, call the
CreateDeliverableVmatPlan
method to apply the trade-off exploration result to the plan setup. - To resume the trade-off exploration from a saved plan collection, call the
LoadSavedPlanCollection
method.
Calculating Leaf Motions after IMRT Optimization
Use the ExternalPlanSetup
class to execute the leaf motion calculation algorithm:
- Calculate leaf motions with the
CalculateLeafMotions
method. - The method uses the default calculation options of the leaf motion calculation model set in the plan.
- The method returns a
CalculationResult
object which has a Success property, which you can use to check if the algorithm executed without errors. - To run the Varian Leaf Motion Calculator algorithm, use the overloaded
CalculateLeafMotions
method.
Input parameter
LMCVOptions
object.
- In
LMCVOptions
, you can specify the usage of fixed jaws. - Check that the leaf motion calculation model of the plan is Varian Leaf Motion Calculator.
- To run the Varian Smart LMC algorithm, use the overloaded
CalculateLeafMotions
method.
Input parameter
SmartLMCOptions
object
- In
SmartLMCOptions
, you can specify the usage of fixed field borders and jaw tracking. - Check that the leaf motion calculation model of the plan is Varian Smart LMC.
- To run the non-Varian MSS Leaf Motion Calculator algorithm, use the overloaded
CalculateLeafMotions
method.
Input parameter
LMCMSSOptions
object.
- In
LMCMSSOptions
, you can specify the number of calculation iterations. Check that the leaf motion calculation model of the plan is MSS Leaf Motion Calculator.
Calculating Photon Plan Dose
Use the ExternalPlanSetup
class for dose calculation:
Calculate the volume dose using the CalculateDose method. The method returns a
CalculationResult
object. This object has a Success property that you can use to check if the algorithm executed without errors.Calculate the volume dose with preset MUs using the
CalculateDoseWithPresetValues
method.
Input parameter
- List of Beam identifier and
MeterSetValue
pairs.
Calculating Proton Plan Dose
Use the IonPlanSetup
class for proton dose calculation:
Calculate DVH Estimates and generate optimization objectives based on a proton DVH Estimation model with the
IonPlanSetup.CalculateDVHEstimates
method.Calculate the beamline with the
IonPlanSetup.CalculateBeamLine
method. method.Optimize a proton modulated scanning plan with the
IonPlanSetup.OptimizeIMPT
method.Calculate the volume dose using the
CalculateDose
method. The method returns aCalculationResult
object. This object has aSuccess
property that you can use to check if the algorithm executed without errors.
Additionally, the proton plan has the following new methods:
IonPlanSetup.SetNormalization
for modifying Plan normalization mode.IonPlanSetup.SetOptimizationMode
for changing plan normalization mode (Multi-field/single field optimization).IonPlanSetup.PatientSupportDevice
for retrieving details of the patient support device.
Creating an Evaluation Dose
Use the ExternalPlanSetup
or IonPlanSetup
class:
Create a new
EvaluationDose
using the CreateEvaluationDose method. The method returns anEvaluationDose
object. This object has aSetVoxels
method that is called to set the content of the dose grid.Create a new
EvaluationDose
using theCopyEvaluationDose
method. The method copies an existingDose
and returns it as anEvaluationDose
object. Use theSetVoxels
method to change the content of the dose grid.
Creating Halcyon Plans
Halcyon plans have additional requirements beyond standard photon plans before they can be approved. Halcyon plans need to have imaging setups and couch structures attached before they can be considered valid. To create a Halcyon plan with ESAPI automation,
- Create a plan with
Course.AddExternalPlanSetup
, - Add an imaging setup with
ExternalPlanSetup.AddImagingPlanSetup
- Insert a couch with
StructureSet.AddCouchStructures
. - Check the validity of the plan with
ExternalPlanSetup.IsValidForPlanApproval
.
See the code sample below:
public void Execute(ScriptContext context)
{
context.Patient.BeginModifications();
Course c = context.Patient.AddCourse();
c.Id = "halcyon";
var ptv = context.StructureSet.Structures.First(s => s.DicomType == "PTV");
var eps = c.AddExternalPlanSetup(context.StructureSet, ptv, ptv, "refpt1");
var machineparameters = new ExternalBeamMachineParameters("Hal2_SX2_D5");
var flat = eps.AddFixedSequenceBeam(machineparameters, 20, 45, new VVector(0, 0, 0));
var imagingparameters = new ImagingBeamSetupParameters(ImagingSetup.MVCBCT_Low_Dose, 0, 0, 0, 0, 140, 140);
eps.AddImagingSetup(machineparameters, imagingparameters, ptv);
IReadOnlyList<Structure> addedStructures;
bool imageResized;
context.StructureSet.AddCouchStructures("RDS_Couch_Top", PatientOrientation.HeadFirstSupine, RailPosition.In, RailPosition.In, null, null, null, out addedStructures, out imageResized, out error);
eps.CalculateDose();
IEnumerable<PlanValidationResultDetail> reasons;
if (!eps.IsValidForPlanApproval(out reasons))
{
string message = "";
foreach (PlanValidationResultDetail pvrd in reasons)
{
message += pvrd.MessageForUser + "\n";
}
MessageBox.Show("Halcyon plan is not valid for approval.Messages = n" + message);
}
else
{
MessageBox.Show("Halcyon plan is valid for approval");
}
}