Пример #1
0
        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);
        }
        // Compute dose
        public void ComputeDose()
        {
            // Set normalization value
            verifPln.PlanNormalizationValue = currPln.PlanNormalizationValue;
            // Set the plan calculation model
            verifPln.SetCalculationModel(CalculationType.PhotonVolumeDose, currPln.PhotonCalculationModel);
            Dictionary <String, String> currPlnCalcModels = currPln.GetCalculationOptions(currPln.PhotonCalculationModel);

            foreach (KeyValuePair <String, String> calcModel in currPlnCalcModels)
            {
                verifPln.SetCalculationOption(currPln.PhotonCalculationModel, calcModel.Key, calcModel.Value);
            }
            // Compute dose
            // For plan containing non-IMRT beams
            if (verifPln.Beams.Any(b => b.MLCPlanType == MLCPlanType.ArcDynamic || b.MLCPlanType == MLCPlanType.Static))
            {
                verifPln.CalculateDose();  // Compute dose for non-IMRT type beams
                // Correct for MU by changing beam weighting
                foreach (Beam verifBm in verifPln.Beams)
                {
                    BeamParameters verifBmParam = verifBm.GetEditableParameters();
                    verifBmParam.WeightFactor = muValues.First(mv => mv.Key == verifBm.Id).Value.Value / verifBm.Meterset.Value;
                    verifBm.ApplyParameters(verifBmParam);
                }
            }
            // For all other IMRT plans
            else
            {
                verifPln.CalculateDoseWithPresetValues(muValues);  // Compute dose for IMRT type beams
            }
        }
Пример #3
0
 public void computeDose()
 {
     // Create prescription //
     currPln.SetPrescription(1, new DoseValue(800.0, DoseValue.DoseUnit.cGy), 1.0);
     // Compute dose //
     currPln.CalculateDose();
 }
Пример #4
0
        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;
        }
Пример #5
0
        /// <summary>
        /// Calculate dose for a given plan.
        /// </summary>
        public static void CalculateDose(ExternalPlanSetup plan)
        {
            plan.SetCalculationModel(CalculationType.PhotonVolumeDose, DoseCalculationAlgorithm);
            Trace.WriteLine("\nCalculating dose...\n");
            var res = plan.CalculateDose();

            if (!res.Success)
            {
                var message = string.Format("Dose calculation failed for plan '{0}'. Output:\n{1}", plan.Id, res);
                Trace.WriteLine(message);
            }
        }
Пример #6
0
        public static string calcularDosis(ExternalPlanSetup plan)
        {
            var watch = Stopwatch.StartNew();

            plan.SetCalculationModel(CalculationType.PhotonVolumeDose, Configuracion.DoseCalculationAlgorithm);
            var res = plan.CalculateDose();

            if (!res.Success)
            {
                return(string.Format("Falló el cálculo de dosis para el plan '{0}'. Output:\n{1}", plan.Id, res));
                //throw new Exception(message);
            }
            else
            {
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                return(string.Format("Finalizó el cálculo de dosis para el plan '{0}'. Demoró " + elapsedMs.ToString() + "ms", plan.Id));
            }
        }
Пример #7
0
        public bool runCoverageCheck(List <Tuple <string, string, double, double, int> > optParams, ExternalPlanSetup plan, int percentCompletion, double relativeDose, double targetVolCoverage, bool useFlash)
        {
            //zero all optimization objectives except those in the target
            List <Tuple <string, string, double, double, int> > targetOnlyObj = new List <Tuple <string, string, double, double, int> > {
            };
            int    priority;
            string message = optObjHeader;

            foreach (Tuple <string, string, double, double, int> opt in optParams)
            {
                if (opt.Item1.ToLower().Contains("ptv") || opt.Item1.ToLower().Contains("ts_jnx"))
                {
                    priority = opt.Item5;
                }
                else
                {
                    priority = 0;
                }
                targetOnlyObj.Add(Tuple.Create(opt.Item1, opt.Item2, opt.Item3, opt.Item4, priority));
                //record the optimization constraints for each structure after zero-ing the priorities. This information will be reported to the user in a progress update
                message += String.Format(" {0, -15} | {1, -16} | {2,-10:N1} | {3,-10:N1} | {4,-8} |" + System.Environment.NewLine, opt.Item1, opt.Item2, opt.Item3, opt.Item4, priority);
            }
            //update the constraints and provide an update to the user
            op.updateConstraints(targetOnlyObj, plan);
            Dispatcher.BeginInvoke((Action)(() => { provideUpdate((int)(100 * (++percentCompletion) / calcItems), message); }));

            //run one optimization with NO intermediate dose.
            plan.OptimizeVMAT(new OptimizationOptionsVMAT(OptimizationIntermediateDoseOption.NoIntermediateDose, MLCmodel));
            if (abortOpt)
            {
                return(false);
            }
            //provide update
            Dispatcher.BeginInvoke((Action)(() => { provideUpdate((int)(100 * (++percentCompletion) / calcItems), " Optimization finished on coverage check! Calculating dose!"); }));
            Dispatcher.BeginInvoke((Action)(() => { provideUpdate(String.Format(" Elapsed time: {0}", currentTime)); }));

            //calculate dose (using AAA algorithm)
            plan.CalculateDose();
            if (abortOpt)
            {
                return(false);
            }
            Dispatcher.BeginInvoke((Action)(() => { provideUpdate((int)(100 * (++percentCompletion) / calcItems), " Dose calculated for coverage check, normalizing plan!"); }));

            //normalize plan
            op.normalizePlan(plan, relativeDose, targetVolCoverage, useFlash);
            if (abortOpt)
            {
                return(false);
            }
            Dispatcher.BeginInvoke((Action)(() => { provideUpdate((int)(100 * (++percentCompletion) / calcItems), " Plan normalized!"); }));

            //print useful info about target coverage and global dmax
            Structure target;

            if (useFlash)
            {
                target = plan.StructureSet.Structures.First(x => x.Id.ToLower() == "ts_ptv_flash");
            }
            else
            {
                target = plan.StructureSet.Structures.First(x => x.Id.ToLower() == "ts_ptv_vmat");
            }
            message = " Additional plan infomation: " + System.Environment.NewLine +
                      String.Format(" Plan global Dmax = {0:0.0}%", 100 * (plan.Dose.DoseMax3D.Dose / plan.TotalDose.Dose)) + System.Environment.NewLine +
                      String.Format(" {0} Dmax = {1:0.0}%", target.Id, plan.GetDoseAtVolume(target, 0.0, VolumePresentation.Relative, DoseValuePresentation.Relative).Dose) + System.Environment.NewLine +
                      String.Format(" {0} Dmin = {1:0.0}%", target.Id, plan.GetDoseAtVolume(target, 100.0, VolumePresentation.Relative, DoseValuePresentation.Relative).Dose) + System.Environment.NewLine +
                      String.Format(" {0} V90% = {1:0.0}%", target.Id, plan.GetVolumeAtDose(target, new DoseValue(90.0, DoseValue.DoseUnit.Percent), VolumePresentation.Relative)) + System.Environment.NewLine +
                      String.Format(" {0} V110% = {1:0.0}%", target.Id, plan.GetVolumeAtDose(target, new DoseValue(110.0, DoseValue.DoseUnit.Percent), VolumePresentation.Relative)) + System.Environment.NewLine +
                      String.Format(" {0} V120% = {1:0.0}%", target.Id, plan.GetVolumeAtDose(target, new DoseValue(120.0, DoseValue.DoseUnit.Percent), VolumePresentation.Relative));
            Dispatcher.BeginInvoke((Action)(() => { provideUpdate(message); }));

            //calculate global Dmax expressed as a percent of the prescription dose (if dose has been calculated)
            if (plan.IsDoseValid && ((plan.Dose.DoseMax3D.Dose / plan.TotalDose.Dose) > 1.40))
            {
                return(true);
            }
            //else MessageBox.Show(String.Format("max dose: {0}%", 100 * (plan.Dose.DoseMax3D.Dose / plan.TotalDose.Dose)));
            return(false);
        }
Пример #8
0
        static void Planning(Application curapp, Patient curpat, StructureSet curstructset, List <Tuple <string, string, float, string> > TargetStructures, List <string> AllowedNonTargetStructures, float RxDose, int NFractions)
        {
            curpat.BeginModifications();

            string IDofptv_low  = string.Empty;
            string IDofptv_high = string.Empty; //

            StringBuilder sb = new StringBuilder();

            //Check structure nameing
            sb.AppendLine("Check Structure Naming");
            sb.AppendLine("Structure ID        \tIs Standard Name?");
            foreach (Structure curstruct in curstructset.Structures.OrderBy(x => x.Id))
            {
                if (curstruct.DicomType == "PTV" | curstruct.DicomType == "CTV" | curstruct.DicomType == "GTV")
                {
                    if (TargetStructures.Where(x => x.Item1 == curstruct.Id).Any() || TargetStructures.Where(x => curstruct.DicomType.ToString() + "_" + x.Item3 + (x.Item4 == "Gy" ? "00" : string.Empty) == curstruct.Id).Any())
                    {
                        sb.AppendLine(curstruct.Id.PadRight(curstruct.Id.Length < 20 ? 20 - curstruct.Id.Length : 0) + "\tYes");
                    }
                    else
                    {
                        sb.AppendLine(curstruct.Id.PadRight(curstruct.Id.Length < 20 ? 20 - curstruct.Id.Length : 0) + "\tNo");
                    }
                }
                else
                {
                    if (AllowedNonTargetStructures.Where(x => x == curstruct.Id).Any() || curstruct.Id.ToString().StartsWith("z"))
                    {
                        sb.AppendLine(curstruct.Id.PadRight(curstruct.Id.Length < 20 ? 20 - curstruct.Id.Length : 0) + "\tYes");
                    }
                    else
                    {
                        sb.AppendLine(curstruct.Id.PadRight(curstruct.Id.Length < 20 ? 20 - curstruct.Id.Length : 0) + "\tNo");
                    }
                }
            }
            sb.AppendLine();
            sb.AppendLine("Press OK to continue with creating optimization structures");
            System.Windows.MessageBox.Show(sb.ToString());



            //Create optimization structures
            if (TargetStructures.Where(x => x.Item1 == "PTV_Low").Any())
            {
                IDofptv_low = TargetStructures.Where(x => x.Item1 == "PTV_Low").Select(x => x.Item2).First();                                                      //Get the ID of the structure identified as PTV_Low
            }
            if (TargetStructures.Where(x => x.Item1 == "PTV_High").Any())
            {
                IDofptv_high = TargetStructures.Where(x => x.Item1 == "PTV_High").Select(x => x.Item2).First();                                                      //Get the ID of the structure identified as PTV_High
            }
            Structure ptv_low  = null;
            Structure ptv_high = null;


            //Check that PT_High structure exists, issue warning if it does not.
            if (curstructset.Structures.Where(x => x.Id == IDofptv_low).Any())
            {
                ptv_low = curstructset.Structures.Where(x => x.Id == IDofptv_low).First();
            }
            else
            {
                System.Windows.MessageBox.Show("Did not find a PTV_High Structure. Fix before proceeding");
            }

            //Check that PT_Low structure exists, issue warning if it does not.
            if (curstructset.Structures.Where(x => x.Id == IDofptv_high).Any())
            {
                ptv_high = curstructset.Structures.Where(x => x.Id == IDofptv_high).First();
            }
            else
            {
                System.Windows.MessageBox.Show("Did not find a PTV_Low Structure. Fix before proceeding");
            }


            //Creation of optimization structures. If a copy already exitst delete it first.

            //Optimization structure for the PTV_Low volume is named zPTV_Low^Opt
            if (curstructset.Structures.Where(x => x.Id.Contains("zPTV_Low^Opt")).Any())
            {
                curstructset.RemoveStructure(curstructset.Structures.Where(x => x.Id.Contains("zPTV_Low^Opt")).First());
            }
            Structure zptvlowopt = curstructset.AddStructure("ORGAN", "zPTV_Low^Opt");

            //Dose limiting annulus (DLA) structure is used to make the prescribed dose conformal. DLA for PTV_Low is named zDLA_Low
            if (curstructset.Structures.Where(x => x.Id.Contains("zDLA__Low")).Any())
            {
                curstructset.RemoveStructure(curstructset.Structures.Where(x => x.Id.Contains("zDLA__Low")).First());
            }
            Structure zdlalow = curstructset.AddStructure("ORGAN", "zDLA__Low");

            //Optimization structure for the PTV_High volume is named zPTV_High^Opt
            if (curstructset.Structures.Where(x => x.Id.Contains("zPTV_High^Opt")).Any())
            {
                curstructset.RemoveStructure(curstructset.Structures.Where(x => x.Id.Contains("zPTV_High^Opt")).First());
            }
            Structure zptvhighopt = curstructset.AddStructure("ORGAN", "zPTV_High^Opt");


            //Dose limiting annulus (DLA) structure is used to make the prescribed dose conformal. DLA for PTV_High is named zDLA_High
            if (curstructset.Structures.Where(x => x.Id.Contains("zDLA__High")).Any())
            {
                curstructset.RemoveStructure(curstructset.Structures.Where(x => x.Id.Contains("zDLA__High")).First());
            }
            Structure zdlahigh = curstructset.AddStructure("ORGAN", "zDLA__High");

            //Make zPTV_High^Opt from PTV_High and boolean out the rectum
            zptvhighopt.SegmentVolume = ptv_high.Margin(0.0f);
            zptvhighopt.SegmentVolume = zptvhighopt.Sub(curstructset.Structures.Where(x => x.Id.Contains("Rectum")).Single());//Boolean the Rectum out of the high dose ptv optimization structure


            //Make zPTV_Low^Opt from PTV_Low and boolean out the PTV_High structure
            zptvlowopt.SegmentVolume = ptv_low.Margin(0.0f);
            zptvlowopt.SegmentVolume = zptvlowopt.Sub(ptv_high.Margin(1.0f));//Boolean the ptv_high out of ptv_low optimization structure


            //Make a dose limiting annulus arround the low dose ptv optimization structure
            zdlalow.SegmentVolume = zptvlowopt.SegmentVolume;
            zdlalow.SegmentVolume = zdlalow.Margin(10.0f);
            zdlalow.SegmentVolume = zdlalow.Sub(zptvlowopt.Margin(1.0f));
            zdlalow.SegmentVolume = zdlalow.Sub(zptvhighopt.Margin(5.0f));

            //Make a dose limiting annulus arround the high dose ptv optimization structure
            zdlahigh.SegmentVolume = zptvhighopt.SegmentVolume;
            zdlahigh.SegmentVolume = zdlahigh.Margin(10.0f);
            zdlahigh.SegmentVolume = zdlahigh.Sub(zptvhighopt.Margin(1.0f));

            sb = new StringBuilder();
            sb.AppendLine("Done with creating optimization strutures");
            sb.AppendLine("Click OK to proceed with setting up course and VMAT plan");
            System.Windows.MessageBox.Show(sb.ToString());

            //Add course
            Course curcourse;

            if (curpat.Courses.Where(x => x.Id == "AutoPlan").Any())
            {
                curcourse = curpat.Courses.Where(x => x.Id == "AutoPlan").Single();
            }
            else
            {
                curcourse    = curpat.AddCourse();
                curcourse.Id = "AutoPlan";
            }

            //Remove PlanSetup if it exists then create new plan setup

            if (curcourse.PlanSetups.Where(x => x.Id == "AutoPlanVMAT").Any())
            {
                curcourse.RemovePlanSetup(curcourse.PlanSetups.Where(x => x.Id == "AutoPlanVMAT").Single());
            }
            ExternalPlanSetup cureps = curcourse.AddExternalPlanSetup(curstructset);

            cureps.Id = "AutoPlanVMAT";



            //Add VMAT Beams
            VVector isocenter = new VVector(Math.Round(ptv_high.CenterPoint.x / 10.0f) * 10.0f, Math.Round(ptv_high.CenterPoint.y / 10.0f) * 10.0f, Math.Round(ptv_high.CenterPoint.z / 10.0f) * 10.0f);
            ExternalBeamMachineParameters ebmp = new ExternalBeamMachineParameters("Truebeam", "6X", 600, "ARC", null);
            Beam VMAT1 = cureps.AddArcBeam(ebmp, new VRect <double>(-100, -100, 100, 100), 30, 181, 179, GantryDirection.Clockwise, 0, isocenter);
            Beam VMAT2 = cureps.AddArcBeam(ebmp, new VRect <double>(-100, -100, 100, 100), 330, 179, 181, GantryDirection.CounterClockwise, 0, isocenter);

            VMAT1.Id = "CW";
            VMAT2.Id = "CCW";

            VMAT1.FitCollimatorToStructure(new FitToStructureMargins(10), ptv_low, true, true, false);
            VMAT2.FitCollimatorToStructure(new FitToStructureMargins(10), ptv_low, true, true, false);



            cureps.SetCalculationModel(CalculationType.PhotonVMATOptimization, "PO_15014");
            cureps.SetPrescription(NFractions, new DoseValue(RxDose / NFractions, "Gy"), 1);

            curapp.SaveModifications();

            sb = new StringBuilder();
            sb.AppendLine("Done with setting up course and VMAT plan");
            sb.AppendLine("Click OK to proceed with plan optimization");
            System.Windows.MessageBox.Show(sb.ToString());

            float doseobjectivevalue_low  = TargetStructures.Where(x => x.Item1 == "PTV_Low").Select(x => x.Item3).First();
            float doseobjectivevalue_high = TargetStructures.Where(x => x.Item1 == "PTV_High").Select(x => x.Item3).First();


            cureps.OptimizationSetup.AddPointObjective(zptvlowopt, OptimizationObjectiveOperator.Lower, new DoseValue(doseobjectivevalue_low, "Gy"), 100, 100);
            cureps.OptimizationSetup.AddPointObjective(zptvlowopt, OptimizationObjectiveOperator.Upper, new DoseValue(doseobjectivevalue_low + 3.0f, "Gy"), 30, 50);
            cureps.OptimizationSetup.AddPointObjective(zdlalow, OptimizationObjectiveOperator.Upper, new DoseValue(doseobjectivevalue_low, "Gy"), 0, 50);

            cureps.OptimizationSetup.AddPointObjective(zptvhighopt, OptimizationObjectiveOperator.Lower, new DoseValue(doseobjectivevalue_high, "Gy"), 100, 120);
            cureps.OptimizationSetup.AddPointObjective(zptvhighopt, OptimizationObjectiveOperator.Upper, new DoseValue(doseobjectivevalue_high + 2.0f, "Gy"), 0, 100);
            cureps.OptimizationSetup.AddPointObjective(zdlahigh, OptimizationObjectiveOperator.Upper, new DoseValue(doseobjectivevalue_high, "Gy"), 0, 50);

            cureps.OptimizationSetup.AddNormalTissueObjective(80.0f, 0.0f, 100.0f, 40.0f, 0.05f);
            OptimizerResult optresult = cureps.OptimizeVMAT(new OptimizationOptionsVMAT(OptimizationIntermediateDoseOption.NoIntermediateDose, string.Empty));



            sb = new StringBuilder();
            sb.AppendLine("VMAT optimization is done");
            sb.AppendLine("NIterattions:" + optresult.NumberOfIMRTOptimizerIterations.ToString() + " , ObjectiveFunctionValue: " + optresult.TotalObjectiveFunctionValue.ToString());
            sb.AppendLine("Click OK to proceed with optimization");

            cureps.OptimizeVMAT();

            curapp.SaveModifications();

            sb = new StringBuilder();
            sb.AppendLine("Done with optimization");
            sb.AppendLine("Click OK to proceed with dose calculation");
            System.Windows.MessageBox.Show(sb.ToString());

            cureps.CalculateDose();
            //cureps.PlanNormalizationValue = 99.0f;

            curapp.SaveModifications();
            sb = new StringBuilder();
            sb.AppendLine("Done with dose calculation");

            if (cureps.StructureSet.Structures.Where(x => x.Id == "Rectum").Any())
            {
                Structure reportstructure = cureps.StructureSet.Structures.Where(x => x.Id == "Rectum").First();
                sb.AppendLine("Rectum:V65Gy[%]:" + cureps.GetVolumeAtDose(reportstructure, new DoseValue(65.0f, DoseValue.DoseUnit.Gy), VolumePresentation.Relative).ToString());
            }

            sb.AppendLine("PTV_High:D95%[Gy]:" + cureps.GetDoseAtVolume(ptv_high, 95.0f, VolumePresentation.Relative, DoseValuePresentation.Absolute).ToString());


            sb.AppendLine("Click OK to finish script");
            System.Windows.MessageBox.Show(sb.ToString());
        }
Пример #9
0
        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");
        }
Пример #10
0
        public static Tuple <bool, List <List <string> > > Optimize(List <List <double[, ]> > choppedContours, List <double[]>
                                                                    planes, ref ExternalPlanSetup plan, ref StructureSet ss, HNPlan hnPlan, ScriptContext context, List <List <Structure> > optimizedStructures, List <List <Structure> > matchingStructures, string contraName, int numIterations, List <Tuple <bool, double[], string> > features, Tuple <string, string, bool> beamParams)
        //return a list of strings which is the log of constraint updates during optimization.
        {
            //Only make parotid structures if that feature has been selected

            if (features[0].Item1 == true)
            {
                double priorityRatio = features[0].Item2[0];
                Segmentation.MakeParotidStructures(choppedContours, planes, ref plan, ref ss, hnPlan, context, matchingStructures, contraName, priorityRatio);
            }
            else
            {
                //remove previously segmented structures if there
                foreach (Structure structure in ss.Structures.ToList())
                {
                    if (structure.Name.ToLower().Contains("cpg_subseg"))
                    {
                        ss.RemoveStructure(structure);
                    }
                }
            }

            //Now run the first VMAT optimization.
            plan.SetCalculationModel(CalculationType.PhotonVMATOptimization, "PO_13623");
            plan.SetCalculationModel(CalculationType.DVHEstimation, "DVH Estimation Algorithm [15.6.06]");
            plan.SetCalculationModel(CalculationType.PhotonVolumeDose, "AAA_13623");
            plan.OptimizationSetup.AddNormalTissueObjective(100, 3, 95, 50, 0.2);
            bool jawTracking = beamParams.Item3;

            //use jaw tracking
            if (jawTracking)
            {
                try
                {
                    plan.OptimizationSetup.UseJawTracking = true;
                } catch
                {
                    System.Windows.MessageBox.Show("Could not use jaw tracking. Proceeding without.");
                }
            }

            // plan.OptimizeVMAT();
            plan.CalculateDose();
            string treatmentCenter = beamParams.Item1;
            string treatmentArea   = beamParams.Item2;
            string mlcId           = "";
            int    areaNum         = Int32.Parse(Regex.Match(treatmentArea, @"\d+").Value);

            if (treatmentCenter == "BC Cancer - Surrey")
            {
                switch (areaNum)
                {
                case 2:
                    mlcId = "";
                    break;

                case 3:
                    mlcId = "";
                    break;

                case 4:
                    mlcId = "";
                    break;

                case 5:
                    mlcId = "";
                    break;

                case 6:
                    mlcId = "";
                    break;
                }
            }
            else if (treatmentCenter == "BC Cancer - Vancouver")
            {
                switch (areaNum)
                {
                case 1:
                    mlcId = "1";
                    break;

                case 2:
                    mlcId = "HHM0767";
                    break;

                case 3:
                    mlcId = "";
                    break;

                case 4:
                    mlcId = "";
                    break;

                case 5:
                    mlcId = "";
                    break;

                case 6:
                    mlcId = "HML0990";
                    break;

                case 7:
                    mlcId = "MLC0987";
                    break;
                }
            }
            string mlcID     = "HML0990";
            int    numCycles = 1;
            OptimizationOptionsVMAT oov;

            ;
            bool isPassed = false;
            List <List <string> > updateLog = new List <List <string> >();

            for (int iter = 0; iter < numIterations; iter++)
            {
                //mlcID = plan.Beams.FirstOrDefault<Beam>().MLC.Id;
                oov = new OptimizationOptionsVMAT(numCycles, mlcID);
                plan.OptimizeVMAT(oov);
                plan.CalculateDose();

                //Now need to perform a plan check and iteratively adjust constraints based on whether they passed or failed, and whether they passed with flying colours or failed miserably.
                //Going to find the percentage by which the constraint failed or passed, and adjust both the priority and dose constraint based on this.
                updateLog.Add(OptObjectivesEditing.UpdateConstraints(ref plan, ref ss, ref hnPlan, context, optimizedStructures, matchingStructures, numCycles));
                if (features[0].Item1 == true)
                {
                    Segmentation.MakeParotidStructures(choppedContours, planes, ref plan, ref ss, hnPlan, context, matchingStructures, contraName, features[0].Item2[0]);
                }
            }
            numCycles = 4;
            oov       = new OptimizationOptionsVMAT(numCycles, mlcID);
            //Now for a maximum of 3 tries, perform 4-cycle vmat optimization followed by constraint updating until a plan is passed
            for (int i = 0; i < 3; i++)
            {
                plan.OptimizeVMAT(oov);
                plan.CalculateDose();
                updateLog.Add(OptObjectivesEditing.UpdateConstraints(ref plan, ref ss, ref hnPlan, context, optimizedStructures, matchingStructures, numCycles));
                if (features[0].Item1 == true)
                {
                    Segmentation.MakeParotidStructures(choppedContours, planes, ref plan, ref ss, hnPlan, context, matchingStructures, contraName, features[0].Item2[0]);
                }
                isPassed = Check.EvaluatePlan(context, hnPlan, matchingStructures, optimizedStructures).Item1;
                if (isPassed)
                {
                    break;
                }
            }


            return(Tuple.Create(isPassed, updateLog));
        }
Пример #11
0
        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");
        }