public void Execute(ScriptContext context /*, System.Windows.Window window, ScriptEnvironment environment*/) { // TODO : Add here the code that is called when the script is launched from Eclipse. Patient p = context.Patient; p.BeginModifications();//this line for scripting automation. //find the ctv in the structures. Structure ctv = context.StructureSet.Structures.First(o => o.DicomType == "CTV"); //create on the structureset a PTV from the ctv. Structure ptv = context.StructureSet.AddStructure("PTV", "PTVAuto"); ptv.SegmentVolume = ctv.Margin(8); //create a new plan. Course c_auto = p.AddCourse(); c_auto.Id = "Course_Auto"; ExternalPlanSetup plan = c_auto.AddExternalPlanSetup(context.StructureSet); plan.Id = "Plan_Auto"; //create the fields. //define the externalBeam Parameters ExternalBeamMachineParameters ebmp = new ExternalBeamMachineParameters( "TrueBeam", "6X", 600, "STATIC", null); //set gantry angles double[] g_angles = new double[] { 270, 0, 90, 180 }; foreach (double ga in g_angles) { //add a new beam with intial parametres Beam b = plan.AddMLCBeam( ebmp, new float[2, 60], new VRect <double>(-10, -10, 10, 10), 0, ga, 0, ptv.CenterPoint); //fit the MLC to the structure outline of the PTV. b.FitMLCToStructure(new FitToStructureMargins(10), ptv, false, JawFitting.FitToRecommended, OpenLeavesMeetingPoint.OpenLeavesMeetingPoint_Middle, ClosedLeavesMeetingPoint.ClosedLeavesMeetingPoint_Center); } //Calculate Dose plan.CalculateDose(); //Set Normalization plan.PlanNormalizationValue = plan.Beams.Count() * 100; //Set Prescription. plan.SetPrescription(30, new DoseValue(180, DoseValue.DoseUnit.cGy), 1); }
public static void CopyDynamicMlcPlan(string planId, Course course, ExternalPlanSetup originalPlan) { var structureSet = originalPlan.StructureSet; var plan = course.AddExternalPlanSetup(structureSet); if (course.PlanSetups.Where(p => p.Id == planId).Count() > 0) { throw new ArgumentException($"{planId} already exists"); } plan.Id = planId; var dosePerFraction = originalPlan.UniqueFractionation.PrescribedDosePerFraction; var numberOfFractions = originalPlan.UniqueFractionation.NumberOfFractions != null ? originalPlan.UniqueFractionation.NumberOfFractions.Value : 0; const double prescribedPercentage = 1.0; // Note: 100% corresponds to 1.0 plan.UniqueFractionation.SetPrescription(numberOfFractions, dosePerFraction, prescribedPercentage); foreach (var beam in originalPlan.Beams) { CopyFluenceBeam(beam, plan); } if (originalPlan.Beams.First().NormalizationMethod == "NO_ISQLAW_NORM") { plan.SetCalculationOption("AAA_13623", "FieldNormalizationType", "No field normalization"); } plan.PlanNormalizationValue = originalPlan.PlanNormalizationValue; plan.SetCalculationModel(CalculationType.PhotonLeafMotions, "Varian Leaf Motion Calculator [13.6.23]"); plan.CalculateLeafMotions(new LMCVOptions(true)); plan.CalculateDose(); }
public static ExternalPlanSetup AddNewPlan(Course course, StructureSet structureSet, string planId) { try { var oldPlans = course.PlanSetups.Where(x => x.Id == planId); if (oldPlans.Any()) { var plansToBeRemoved = oldPlans.ToArray(); foreach (var p in plansToBeRemoved) { course.RemovePlanSetup(p); } } } catch { var message = string.Format("Could not cleanup old plans."); throw new Exception(message); } ExternalPlanSetup plan = course.AddExternalPlanSetup(structureSet); plan.Id = planId; return(plan); }
private void OnCalculatePlan() { patient.BeginModifications(); Course course_temp = patient.AddCourse(); ExternalPlanSetup plan_temp = course_temp. AddExternalPlanSetup(patient.StructureSets.FirstOrDefault()); ExternalBeamMachineParameters exBeamParams = new ExternalBeamMachineParameters( "HESN10", "6X", 600, "STATIC", null); foreach (string fs in FieldSizes.Split(';')) { double fsd = Convert.ToDouble(fs); plan_temp.AddStaticBeam(exBeamParams, new VRect <double>(-fsd / 2 * 10, -fsd / 2 * 10, fsd / 2 * 10, fsd / 2 * 10), 0, 0, 0, new VVector(0, -200, 0)); } plan_temp.SetPrescription(1, new DoseValue(100, DoseValue.DoseUnit.cGy), 1); plan_temp.CalculateDose(); _app.SaveModifications(); AddCourses(patient); SelectedCourse = course_temp.Id; SelectedPlan = plan_temp.Id; }
static void Execute(Application app) { Patient pat = app.OpenPatientById("exercise5-0"); try { pat.BeginModifications(); const string courseId = "AutoPlanned"; Course course = pat.Courses.Where(o => o.Id == courseId).SingleOrDefault(); if (course == null) { if (course == null) { course = pat.AddCourse(); course.Id = courseId; } } StructureSet ss = pat.StructureSets.First(x => x.Id == "CT_1"); if (course.CanAddPlanSetup(ss)) { // find the PTV Structure ptv = ss.Structures.First(x => x.Id == "PTV"); // Put isocenter to the center of the ptv. var isocenter = ptv.CenterPoint; //add plan and beams ExternalPlanSetup plan = course.AddExternalPlanSetup(ss); plan.SetPrescription(5, new DoseValue(2, DoseValue.DoseUnit.Gy), 1.0); Beam g0 = plan.AddMLCBeam(MachineParameters, null, new VRect <double>(-10, -10, 10, 10), 0, 0, 0, isocenter); Beam g180 = plan.AddMLCBeam(MachineParameters, null, new VRect <double>(-10, -10, 10, 10), 0, 180.0, 0, isocenter); // fit beam jaws and MLC bool useAsymmetricXJaw = true, useAsymmetricYJaws = true, optimizeCollimatorRotation = true; g0.FitCollimatorToStructure(new FitToStructureMargins(0), ptv, useAsymmetricXJaw, useAsymmetricYJaws, optimizeCollimatorRotation); FitToStructureMargins margins = new FitToStructureMargins(1); JawFitting jawFit = JawFitting.FitToRecommended; OpenLeavesMeetingPoint olmp = OpenLeavesMeetingPoint.OpenLeavesMeetingPoint_Middle; ClosedLeavesMeetingPoint clmp = ClosedLeavesMeetingPoint.ClosedLeavesMeetingPoint_BankOne; g0.FitMLCToStructure(margins, ptv, optimizeCollimatorRotation, jawFit, olmp, clmp); g180.FitMLCToStructure(margins, ptv, optimizeCollimatorRotation, jawFit, olmp, clmp); // format the field ids g0.Id = string.Format("g{0}c{1}", g0.GantryAngleToUser(g0.ControlPoints[0].GantryAngle), g0.CollimatorAngleToUser(g0.ControlPoints[0].CollimatorAngle) ); g180.Id = string.Format("g{0}c{1}", g180.GantryAngleToUser(g180.ControlPoints[0].GantryAngle), g180.CollimatorAngleToUser(g180.ControlPoints[0].CollimatorAngle) ); app.SaveModifications(); } } finally { app.ClosePatient(); } }
private void newPlan_btn_Click(object sender, RoutedEventArgs e) { Course c2 = null; if (p.Courses.Where(x => x.Id == course_txt.Text).Count() == 0) { c2 = p.AddCourse(); c2.Id = course_txt.Text; } else { c2 = p.Courses.First(x => x.Id == course_txt.Text); } ExternalPlanSetup ps2 = c2.AddExternalPlanSetup(ps.StructureSet); //doses should all be the same.t //ps2.DosePerFraction = ps.DosePerFraction; //read only //ps2.TotalDose = ps.TotalDose;//read only ps2.SetPrescription( (int)ps.NumberOfFractions, ps.DosePerFraction, ps.TreatmentPercentage); //I've chnaged this down below. Currently, the calculation will take place with preset monitor units //making it the same as the plan its copied from but then I scale the normaliztation factor by 1.3% because the discover is not in the beam. ps2.PlanNormalizationValue = val * ps.PlanNormalizationValue; //val = (double)Convert.ToDouble(Input.Text); bool valid = double.TryParse(Input.Text.ToString(), out val); ps2.PlanNormalizationValue = val + no_norm; //ps2.TreatmentPercentage = ps.TreatmentPercentage;//read only //ps2.AddMLCBeam() ps2.Id = plan_txt.Text; List <KeyValuePair <string, MetersetValue> > mu_list = new List <KeyValuePair <string, MetersetValue> >(); /*foreach (FieldInfo fi in fields)########################*/ for (int t = 0; t < fields.Count(); t++) { FieldInfo fi = fields[t]; Beam b2; if (fi.gantry_direction == 0) { b2 = ps2.AddSlidingWindowBeam(fi.Ebmp, fi.cpInfos.Select(x => x.meterSet), fi.collAngle, fi.gantry, fi.couch, fi.isocenter); } else { b2 = ps2.AddVMATBeam(fi.Ebmp, fi.cpInfos.Select(x => x.meterSet), fi.collAngle, fi.gantry, fi.gantry_stop, fi.gantry_direction, fi.couch, fi.isocenter); } int cploc = 0; //if (fi.applicator != null) { b2.Applicator = fi.applicator; } BeamParameters beamp = fi.bp; //b2.ApplyParameters(new BeamParameters(ControlPoint cp)) //int cploc = 0; //foreach (cpInfo cpi in fi.cpInfos) //double MU_old = 0; foreach (ControlPointParameters cpp in beamp.ControlPoints) //for(int xx=0; xx< beamp.ControlPoints.Count(); xx++) { /* ControlPointParameters cpp= beamp.ControlPoints[xx];*/ float[,] leafPos = new float[2, 60]; int leafloc = 0; double x1 = cpp.JawPositions.X1; double x2 = cpp.JawPositions.X2; cpInfo cpi = fi.cpInfos[cploc]; //foreach (cpDetail cpd in cpi.cpDetails)##################### for (int dd = 0; dd < cpi.cpDetails.Count(); dd++) { cpDetail cpd = cpi.cpDetails[dd]; //sometimes the errors show that the difference will overlap the leaves. //here we check for the overla[p and if there is n overlap, leaf B just gets set to 0.1 less than the leaf A position. //thus ignoring the deviation fort that leaf pair. if (cpd.leafB + Convert.ToSingle(cpd.deviationB) > cpd.leafA + Convert.ToSingle(cpd.deviationA)) { leafPos[1, leafloc] = cpd.leafA + (float)cpd.deviationA; leafPos[0, leafloc] = leafPos[1, leafloc] - (float)0.1; } else { /*if (cpd.leafA + (float)cpd.deviationA < x1) * { * * leafPos[1, leafloc] = (float)x1 + (float)0.5; * leafPos[0, leafloc] = (float)x1; * } * else if (cpd.leafA + (float)cpd.deviationA > x2) * { * leafPos[1, leafloc] = (float)x2; * if(cpd.leafB + (float)cpd.deviationB > x2) * { * leafPos[0, leafloc] = (float)x2 - (float)0.5; * } * else * { * leafPos[0, leafloc] = cpd.leafB + (float)cpd.deviationB; * } * } * else * { * leafPos[1, leafloc] = cpd.leafA + Convert.ToSingle(cpd.deviationA); * leafPos[0, leafloc] = cpd.leafB + (float)cpd.deviationB; * }*/ leafPos[1, leafloc] = cpd.leafA + (float)cpd.deviationA; leafPos[0, leafloc] = cpd.leafB + (float)cpd.deviationB; //leafPos[0, leafloc] = cpd.leafA + Convert.ToSingle(cpd.deviationA); //leafPos[1, leafloc] = cpd.leafB + Convert.ToSingle(cpd.deviationB); } leafloc++; } ////start with the first leaf position, and then interoplate all the rest. //float leaf_oldA = 0; //float leaf_oldB = 0; //for (int i = 0; i < cpi.cpDetails.Count(); i++) //{ // if (i == 0) // { // leafPos[0, i] = cpi.cpDetails[i].leafA; // leafPos[1, i] = cpi.cpDetails[i + 1].leafB; // leaf_oldA = leafPos[0, i]; // leaf_oldB = leafPos[1, i]; // //mU_old = cpi.meterSet[i]; // } // else // { // //let the interpolation begin. // //first the MU // } //} //beamp.SetAllLeafPositions(leafPos); //ControlPointParameters cpp = beamp.ControlPoints[cploc] cpp.LeafPositions = leafPos; //double check to see if this has to be applied every time. VMAT code is taking a long time. //********************************** b2.ApplyParameters(beamp); //********************************** cploc++; } //calculate the dose for each of the fields. mu_list.Add(new KeyValuePair <string, MetersetValue>(b2.Id, fi.MU)); } ps2.CalculateDoseWithPresetValues(mu_list); //ps2.PlanNormalizationMethod = ps.PlanNormalizationMethod;\ //need to renormalize by 1.3% in order to take into account the Discover that we cannot add to the newly calculated plan. //ps2.PlanNormalizationValue = val * ps2.PlanNormalizationValue; //val = (double)Convert.ToDouble(Input.Text); if (double.TryParse(Input.Text.ToString(), out val)) { ps2.PlanNormalizationValue = val + no_norm; } MessageBox.Show($"{plan_txt.Text} created successfully."); }
public bool CopyAndCreate(Application app, string ptId_Tgt, string crsId_Tgt, string plnId_Tgt, string structId_Tgt, PlanParameters plnParam_Ref) { //Open patient// PatientSummary ptSumm = app.PatientSummaries.FirstOrDefault(ps => ps.Id == ptId_Tgt); if (ptSumm == null) { Console.WriteLine("--Cannot find patient" + ptId_Tgt + "."); return(false); } Patient pt = app.OpenPatient(ptSumm); try { pt.BeginModifications(); //Open or create course// Course crs = pt.Courses.FirstOrDefault(c => c.Id == crsId_Tgt); if (crs == null) { Console.WriteLine("-Create course " + crsId_Tgt + "."); crs = pt.AddCourse(); crs.Id = crsId_Tgt; } //Create plan// ExternalPlanSetup pln = crs.ExternalPlanSetups.FirstOrDefault(p => p.Id == plnId_Tgt); if (pln == null) { StructureSet structSet = pt.StructureSets.FirstOrDefault(ss => ss.Id == structId_Tgt); if (structSet == null) { Console.WriteLine("--Cannot find structure set " + structId_Tgt + ". Plan is not created\n"); app.ClosePatient(); return(false); } pln = crs.AddExternalPlanSetup(structSet); pln.Id = plnId_Tgt; } //Return if there is already a plan with the same name// else { Console.WriteLine("--A plan with name " + plnId_Tgt + " already exists. Plan is not created\n"); app.ClosePatient(); return(false); } Console.WriteLine("-Start creating plan " + plnId_Tgt + "."); //Set plan prescription properties// pln.SetPrescription(plnParam_Ref.N_Fx, plnParam_Ref.DoseperFx, plnParam_Ref.TrtPct); ///////////Create beam by copying from the beams in reference plan parameters//////////// //Create empty list of MU values for each beam// List <KeyValuePair <string, MetersetValue> > muValues = new List <KeyValuePair <string, MetersetValue> >(); foreach (PlanParameters.BmParam bmParam in plnParam_Ref.BmParamLs) { //Add beam, type based on reference MLC beam technique// IEnumerable <double> muSet = bmParam.CtrPtParam.ControlPoints.Select(cp => cp.MetersetWeight).ToList(); switch (bmParam.MLCBmTechnique) { case "StaticMLC": Beam bm = pln.AddMLCBeam(bmParam.MachParam, new float[2, 60], new VRect <double>(-10.0, -10.0, 10.0, 10.0), 0.0, 0.0, 0.0, bmParam.CtrPtParam.Isocenter); bm.Id = bmParam.bmId; bm.ApplyParameters(bmParam.CtrPtParam); break; case "StaticSegWin": bm = pln.AddMultipleStaticSegmentBeam(bmParam.MachParam, muSet, 0.0, 0.0, 0.0, bmParam.CtrPtParam.Isocenter); bm.Id = bmParam.bmId; muValues.Add(new KeyValuePair <string, MetersetValue>(bmParam.bmId, bmParam.mu)); bm.ApplyParameters(bmParam.CtrPtParam); break; case "StaticSlidingWin": bm = pln.AddSlidingWindowBeam(bmParam.MachParam, muSet, 0.0, 0.0, 0.0, bmParam.CtrPtParam.Isocenter); bm.Id = bmParam.bmId; muValues.Add(new KeyValuePair <string, MetersetValue>(bmParam.bmId, bmParam.mu)); bm.ApplyParameters(bmParam.CtrPtParam); break; case "ConformalArc": bm = pln.AddConformalArcBeam(bmParam.MachParam, 0.0, bmParam.CtrPtParam.ControlPoints.Count(), bmParam.CtrPtParam.ControlPoints.First().GantryAngle, bmParam.CtrPtParam.ControlPoints.Last().GantryAngle, bmParam.CtrPtParam.GantryDirection, 0.0, bmParam.CtrPtParam.Isocenter); bm.Id = bmParam.bmId; bm.ApplyParameters(bmParam.CtrPtParam); break; case "VMAT": bm = pln.AddVMATBeam(bmParam.MachParam, muSet, 0.0, bmParam.CtrPtParam.ControlPoints.First().GantryAngle, bmParam.CtrPtParam.ControlPoints.Last().GantryAngle, bmParam.CtrPtParam.GantryDirection, 0.0, bmParam.CtrPtParam.Isocenter); bm.Id = bmParam.bmId; bm.ApplyParameters(bmParam.CtrPtParam); break; default: Console.WriteLine("--At least one of the beams is unidentified, plan is not created.\n"); app.ClosePatient(); return(false); } } //Set the plan normalization value// pln.PlanNormalizationValue = plnParam_Ref.PlnNormFactr; //Set the plan calculation model// pln.SetCalculationModel(CalculationType.PhotonVolumeDose, plnParam_Ref.CalcModel); //If one of the beams is static IMRT, compute dose to enforce MUs to beams// if (plnParam_Ref.BmParamLs.Any(bm => bm.MLCBmTechnique == "StaticSegWin" || bm.MLCBmTechnique == "StaticSlidingWin")) { Console.WriteLine("--Start computing static beam IMRT plan."); pln.CalculateDoseWithPresetValues(muValues); } Console.WriteLine("-Finish plan creation.\n"); app.SaveModifications(); app.ClosePatient(); return(true); } catch (Exception ex) { Console.WriteLine(ex.ToString()); app.ClosePatient(); return(false); } }
public void Execute(ScriptContext context /*, System.Windows.Window window, ScriptEnvironment environment*/) { //USER INPUT double s_ssd = 100; // SSD string cmach = "HESN5"; // MACHINE string[] erg = new string[] { "6X", "10X" }; // ENERGY LIST double[] jaw_sizes = new double[] { 4, 8, 10, 20 }; // FIELD SIZE LIST // Define local _patient, could be pointed to UI Patient _patient = context.Patient; _patient.BeginModifications(); // SET STRUCTURE SET StructureSet _structureSet = _patient.StructureSets.FirstOrDefault(); // DETERMINE EXTERNAL STRUCTURE var bst = _structureSet.Structures.First(x => x.DicomType == "EXTERNAL"); var bst_mgb = bst.MeshGeometry.Bounds; // CREATE NEW COURSE AND NAME IT Course C_Auto = _patient.AddCourse(); C_Auto.Id = string.Format("C_{0}_{1}SSD", cmach, s_ssd.ToString()); // LOOP THROUGH ENERGIES PROVIDED BY USER, CREATE A PLAN FOR EACH ENERGY foreach (var evar in erg) { // CREATE PLAN ExternalPlanSetup eps = C_Auto.AddExternalPlanSetup(_structureSet); // SET PRESCRIPTION eps.SetPrescription(1, new DoseValue(100, "cGy"), 1); eps.Id = evar.ToString(); // SET FIELD PARAMETERS ExternalBeamMachineParameters ebmp = new ExternalBeamMachineParameters(cmach, evar, 600, "STATIC", null); // LOOP THROUGH FIELD SIZES, CREATE A BEAM FOR EACH FIELD SIZE foreach (double js in jaw_sizes) { // SET JAW POSITION BASED ON USER FIELD SIZES - (ASSUMES ALL FIELDS ARE SYMMETRIC) double xjaw = js * 10; double yjaw = js * 10; // DEFINE BEAM PARAMETERS - (ASSUMES NO ANGLES) double coll = 0; double gant_a = 0; double couch_a = 0; // SET ISOCENTER BASED ON USER SSD double iso_x = 0; double iso_y = -10 * (Math.Round(bst_mgb.SizeY / 10) + Math.Round(bst_mgb.Location.Y / 10) + (s_ssd - 100)); double iso_z = 0; VVector isovec = new VVector(iso_x, iso_y, iso_z); // CREATE BEAM Beam b = eps.AddStaticBeam( ebmp, new VRect <double>(-0.5 * xjaw, -0.5 * yjaw, 0.5 * xjaw, 0.5 * yjaw), coll, gant_a, couch_a, isovec); // SET BEAM ID b.Id = String.Format("{0}_{1:F1}x{2:F1}", evar, xjaw / 10, yjaw / 10); } // CALCULATE DOSE eps.CalculateDose(); } MessageBox.Show("DONE"); }
private bool createPlan() { //look for a course name VMAT TBI. If it does not exit, create it, otherwise load it into memory if (!selectedSS.Patient.Courses.Where(x => x.Id == "VMAT TBI").Any()) { if (selectedSS.Patient.CanAddCourse()) { tbi = selectedSS.Patient.AddCourse(); tbi.Id = "VMAT TBI"; } else { MessageBox.Show("Error! \nCan't add a treatment course to the patient!"); return(true); } } else { tbi = selectedSS.Patient.Courses.FirstOrDefault(x => x.Id == "VMAT TBI"); } //6-10-2020 EAS, research system only! //if (tbi.ExternalPlanSetups.Where(x => x.Id == "_VMAT TBI").Any()) if (tbi.CanRemovePlanSetup((tbi.ExternalPlanSetups.First(x => x.Id == "_VMAT TBI")))) tbi.RemovePlanSetup(tbi.ExternalPlanSetups.First(x => x.Id == "_VMAT TBI")); if (tbi.ExternalPlanSetups.Where(x => x.Id == "_VMAT TBI").Any()) { MessageBox.Show("A plan named '_VMAT TBI' Already exists! \nESAPI can't remove plans in the clinical environment! \nPlease manually remove this plan and try again."); return(true); } plan = tbi.AddExternalPlanSetup(selectedSS); //100% dose prescribed in plan and plan ID is _VMAT TBI plan.SetPrescription(prescription.Item1, prescription.Item2, 1.0); plan.Id = "_VMAT TBI"; //ask the user to set the calculation model if not calculation model was set in UI.xaml.cs (up near the top with the global parameters) if (calculationModel == "") { IEnumerable <string> models = plan.GetModelsForCalculationType(CalculationType.PhotonVolumeDose); selectItem SUI = new VMATTBIautoPlan.selectItem(); SUI.title.Text = "No calculation model set!" + Environment.NewLine + "Please select a calculation model!"; foreach (string s in plan.GetModelsForCalculationType(CalculationType.PhotonVolumeDose)) { SUI.itemCombo.Items.Add(s); } SUI.ShowDialog(); if (!SUI.confirm) { return(true); } //get the plan the user chose from the combobox calculationModel = SUI.itemCombo.SelectedItem.ToString(); //just an FYI that the calculation will likely run out of memory and crash the optimization when Acuros is used if (calculationModel.ToLower().Contains("acuros")) { confirmUI CUI = new VMATTBIautoPlan.confirmUI(); CUI.message.Text = "Warning!" + Environment.NewLine + "The optimization will likely crash (i.e., run out of memory) if Acuros is used!" + Environment.NewLine + "Continue?!"; CUI.ShowDialog(); if (!CUI.confirm) { return(true); } } } plan.SetCalculationModel(CalculationType.PhotonVolumeDose, calculationModel); //reference point can only be added for a plan that IS CURRENTLY OPEN //plan.AddReferencePoint(selectedSS.Structures.First(x => x.Id == "TS_PTV_VMAT"), null, "VMAT TBI", "VMAT TBI"); //6-10-2020 EAS, research system only! if ((numIsos > numVMATIsos) && tbi.ExternalPlanSetups.Where(x => x.Id.ToLower().Contains("legs")).Any()) { MessageBox.Show("Plan(s) with the string 'legs' already exists! \nESAPI can't remove plans in the clinical environment! \nPlease manually remove this plan and try again."); return(true); } //these needs to be fixed //v16 of Eclipse allows for the creation of a plan with a named target structure and named primary reference point. Neither of these options are available in v15 //plan.TargetVolumeID = selectedSS.Structures.First(x => x.Id == "TS_PTV_VMAT"); //plan.PrimaryReferencePoint = plan.ReferencePoints.Fisrt(x => x.Id == "VMAT TBI"); return(false); }
public void Execute(ScriptContext context /*, System.Windows.Window window*/) { Patient patient = context.Patient; if (patient == null) { throw new ApplicationException("Please load a patient."); } // Get active structureset StructureSet ss = context.StructureSet; if (ss == null) { throw new ApplicationException("Please load a structure set."); } // Check that unique body structure, PTV and Rectum structures exist Structure body = ss.Structures.Where(o => o.Id == "BODY").FirstOrDefault(); Structure ptv = ss.Structures.Where(o => o.Id == "PTV").FirstOrDefault(); Structure rectum = ss.Structures.Where(o => o.Id == "Rectum1").FirstOrDefault(); if (body == null || ptv == null || rectum == null) { throw new ApplicationException(string.Format("Cannot find required structures (BODY, PTV, Rectum) from Structureset '{0}'", ss.Id)); } // Enable modifications patient.BeginModifications(); // Get or create course with Id 'Superplan' const string courseId = "Superplan"; Course course = patient.Courses.Where(o => o.Id == courseId).SingleOrDefault(); if (course == null) { course = patient.AddCourse(); course.Id = courseId; } // Create a new plan ExternalPlanSetup plan = course.AddExternalPlanSetup(ss); int fractions = 20; double prescribedPercentage = 1.0; DoseValue fractiondose = new DoseValue(2.50, DoseValue.DoseUnit.Gy); // TODO: if needed change to cGy to match your system configuration plan.UniqueFractionation.SetPrescription(fractions, fractiondose, prescribedPercentage); // Add fields const int nfields = 5; ExternalBeamMachineParameters parameters = new ExternalBeamMachineParameters("Varian 23EX", "6X", 600, "STATIC", null); // TODO: change machine id to yours VVector isocenter = ptv.CenterPoint; for (int n = 0; n < nfields; n++) { // add a 10 cm x 10 cm field Beam beam = plan.AddStaticBeam(parameters, new VRect <double>(-50, -50, 50, 50), 0, Math.Round(360.0 / nfields * n, 0), 0, isocenter); } // end of first part. MessageBox.Show("Plan created, open course SuperPlan, Choose Plan1 to view results.", "Varian Developer"); // Set optimization constraints OptimizationSetup optimizationSetup = plan.OptimizationSetup; optimizationSetup.AddPointObjective(ptv, OptimizationObjectiveOperator.Lower, new DoseValue(49.50, DoseValue.DoseUnit.Gy), 100, 100.0); optimizationSetup.AddPointObjective(ptv, OptimizationObjectiveOperator.Upper, new DoseValue(52.00, DoseValue.DoseUnit.Gy), 0, 100.0); optimizationSetup.AddPointObjective(rectum, OptimizationObjectiveOperator.Upper, new DoseValue(20.00, DoseValue.DoseUnit.Gy), 40.0, 100.0); MessageBox.Show("Plan '" + plan.Id + "' in course '" + course.Id + "' for patient '" + patient.Id + "' has been created"); // optimize for 30 iterations if (!plan.Optimize(30).Success) { MessageBox.Show("Optimization failed", "Varian Developer", MessageBoxButton.OK, MessageBoxImage.Error); return; } // run LMC if (!plan.CalculateLeafMotions().Success) { MessageBox.Show("LMC failed", "Varian Developer", MessageBoxButton.OK, MessageBoxImage.Error); return; } // calculate final dose CalculationResult doseCalc = plan.CalculateDose(); if (!doseCalc.Success) { MessageBox.Show("Dose calculation failed, logs shown next.", "Varian Developer", MessageBoxButton.OK, MessageBoxImage.Error); // write calculate logs to a file and show them to the user. string filename = writeCalculationLogs(plan); // 'Start' generated TXT file to launch Notepad window System.Diagnostics.Process.Start(filename); // Sleep for a few seconds to let Excel window start System.Threading.Thread.Sleep(TimeSpan.FromSeconds(3)); return; } MessageBox.Show("Done"); }