Example #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);
        }
Example #2
0
 public void computeDose()
 {
     // Create prescription //
     currPln.SetPrescription(1, new DoseValue(800.0, DoseValue.DoseUnit.cGy), 1.0);
     // Compute dose //
     currPln.CalculateDose();
 }
Example #3
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;
        }
Example #4
0
        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();
            }
        }
 // Create verification plan
 public ExternalPlanSetup CreateVerificationPlan(StructureSet pStructSt, Course verifCrs, String verifPlnID)
 {
     verifPln    = verifCrs.AddExternalPlanSetupAsVerificationPlan(pStructSt, currPln);
     verifPln.Id = verifPlnID;
     // Copy and set prescription info//
     verifPln.SetPrescription(1, currPln.DosePerFraction, currPln.TreatmentPercentage);
     // Remove target structure if available (needed for v 16)
     verifPln.SetTargetStructureIfNoDose(null, null);
     return(verifPln);
 }
Example #6
0
        public static Tuple <List <List <Structure> >, List <List <Structure> >, List <List <string> >, bool> StartOptimizer(ScriptContext context, HNPlan hnPlan, List <List <Structure> > matchingStructures, int numIterations, List <Tuple <bool, double[], string> > features, Tuple <string, string, bool> beamParams) //Returns list of matching structures
        {
            // Check for patient plan loaded
            ExternalPlanSetup plan = context.ExternalPlanSetup;


            Patient      patient = context.Patient;
            StructureSet ss      = context.StructureSet;
            Course       course  = context.Course;
            Image        image3d = context.Image;


            //Create two VMAT beams
            BeamMaker(ref plan, ss, plan.TotalDose.Dose, beamParams);
            //set prescriptions dose
            int numFractions    = hnPlan.Fractions;
            int dosePerFraction = (int)hnPlan.PrescriptionDose / numFractions;

            plan.SetPrescription(numFractions, new DoseValue(dosePerFraction, "cGy"), 1);


            //matchingStructures is the same length as hnPlan.ROIs.count
            //Now set optimization constraints
            List <List <Structure> >  optimizedStructures = OptObjectivesEditing.SetConstraints(ref plan, hnPlan, matchingStructures, true); //true to check for opti structures, returns new matching list of structures
            List <List <double[, ]> > choppedContours;
            List <double[]>           planes;
            string contraParName;

            if (features[0].Item1 == true) //parotid segmentation feature
            {
                Tuple <List <List <double[, ]> >, string, List <double[]> > choppedAndName = ParotidChop(ref plan, hnPlan, matchingStructures, ss, context);
                choppedContours = choppedAndName.Item1;
                contraParName   = choppedAndName.Item2;
                planes          = choppedAndName.Item3;
            }
            else
            {
                choppedContours = new List <List <double[, ]> >();
                contraParName   = "";
                planes          = new List <double[]>();
            }
            Tuple <bool, List <List <string> > > optimData = Optimize(choppedContours, planes, ref plan, ref ss, hnPlan, context, optimizedStructures, matchingStructures, contraParName, numIterations, features, beamParams);
            bool isPassed = optimData.Item1;
            List <List <string> > updatesLog = optimData.Item2;

            return(Tuple.Create(optimizedStructures, matchingStructures, updatesLog, isPassed));
        }
        /// <summary>
        /// Create PTV from CTV and fit collimator jaws to the target.
        /// </summary>
        public static void GenerateBeamGeometry(ExternalPlanSetup plan, double dosePerFraction, int numberOfFractions, double ptvMargin, string ctvId)
        {
            // Prescription
            const double prescribedPercentage = 1.0; // Note: 100% corresponds to 1.0
            var          dose = new DoseValue(dosePerFraction, DoseValue.DoseUnit.Gy);

            plan.SetPrescription(numberOfFractions, dose, prescribedPercentage);

            Trace.WriteLine("\nCreating PTV from CTV...");
            CreatePTVFromCTV(plan, ptvMargin, ctvId);

            // Match plan structures to model structures
            var structureMatches = GetStructureMatches(plan);

            if (!structureMatches.Any())
            {
                MessageBox.Show("Structure match could not be found", "No model structures found", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            // Generate PTV that does not overlap with OARs.
            // Identify the structures to be spared by their IDs in the RapidPlan model.
            Trace.WriteLine("Subtracting OARs from PTV...");
            var sparedOrgans = new List <string> {
                "Rectum"
            };

            structureMatches = SubtractOARsFromPTV(plan, structureMatches, sparedOrgans);

            var ptvId = structureMatches.Single(x => x.Value.StructureType == ModelStructureType.Target).Key;
            var ptv   = plan.StructureSet.Structures.Single(x => x.Id == ptvId);

            Trace.WriteLine("PTV successfully generated.\n");

            // Fit jaws to target and add treatment fields.
            const double collRtn      = 0.0;
            var          jawPositions = GantryAngles.ToDictionary(angle => angle, angle => FitJawsToTarget(plan, ptv, angle, collRtn, MarginForJawFittingInMM));
            var          isocenter    = ptv.CenterPoint;

            foreach (var item in jawPositions)
            {
                plan.AddStaticBeam(MachineParameters, item.Value, CollimatorAngle, item.Key, PatientSupportAngle, isocenter);
            }

            Trace.WriteLine("\nJaws successfully fitted to target.\n");
        }
Example #8
0
        /// <summary>
        /// Copies a already created verification plan to:
        /// 1. The same structure set if one is not inpput
        /// 2. A new phantom structure set if one is input
        /// </summary>
        /// <param name="planToCopy"></param>
        /// <param name="course"></param>
        /// <param name="phantomStructureSetId"></param>
        /// <param name="phantomPatientId"></param>
        /// <param name="phantomStudyId"></param>
        /// <returns></returns>
        public static ExternalPlanSetup CopyVerificationPlan(ExternalPlanSetup planToCopy, Course course, string phantomStructureSetId, string phantomPatientId, string phantomStudyId)
        {
            if (course.PlanSetups.Any(p => p.Id == planToCopy.Id))
            {
                GlobalLogger.Instance.Trace($"A plan with ID {planToCopy.Id} already exists in course {course.Id}.");
                throw new Exception("A plan with the same ID as the source plan already exists in the destination course.");
            }

            if (String.IsNullOrWhiteSpace(phantomStructureSetId))
            {
                return((ExternalPlanSetup)course.CopyPlanSetup(planToCopy));
            }
            else
            {
                StructureSet structureSet;
                if (String.IsNullOrWhiteSpace(phantomPatientId))
                {
                    structureSet = planToCopy.Course.Patient.StructureSets.Where(s => s.Id == phantomStructureSetId).Single();
                }
                else
                {
                    structureSet = planToCopy.Course.Patient.CopyImageFromOtherPatient(phantomPatientId, phantomStudyId, phantomStructureSetId);
                    GlobalLogger.Instance.Trace($"New phantom structure set {structureSet.Id} created from structure set {phantomStructureSetId} in patient ID {phantomPatientId}");
                }

                ExternalPlanSetup verifiedPlan = (ExternalPlanSetup)planToCopy.VerifiedPlan;
                ExternalPlanSetup copyPlan     = course.AddExternalPlanSetupAsVerificationPlan(structureSet, verifiedPlan);
                copyPlan.Id = planToCopy.Id;
                copyPlan.SetPrescription((int)planToCopy.NumberOfFractions, planToCopy.DosePerFraction, planToCopy.TreatmentPercentage);
                GlobalLogger.Instance.Trace($"Added verification plan created from {verifiedPlan.Id} (Course {verifiedPlan.Course.Id}) using phantom structure set {structureSet.Id}");

                foreach (Beam b in planToCopy.Beams)
                {
                    VVector iso = b.IsocenterPosition - planToCopy.StructureSet.Image.UserOrigin;
                    iso += structureSet.Image.UserOrigin;
                    BeamCopier.CopyBeamToPlan(b, copyPlan, iso);// setup beam isocenters to user origin of the QA device
                    GlobalLogger.Instance.Trace($"Copied {b.Id} to verification plan");
                }
                return(copyPlan);
            }
        }
        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);
            }
        }
Example #11
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());
        }
Example #12
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");
        }
Example #13
0
        private void set_beams(List <VVector> isoLocations)
        {
            //DRR parameters (dummy parameters to generate DRRs for each field)
            DRRCalculationParameters DRR = new DRRCalculationParameters();

            DRR.DRRSize           = 500.0;
            DRR.FieldOutlines     = true;
            DRR.StructureOutlines = true;
            DRR.SetLayerParameters(1, 1.0, 100.0, 1000.0);

            //place the beams for the VMAT plan
            //unfortunately, all of Nataliya's requirements for beam placement meant that this process couldn't simply draw from beam placement templates. Some of the beam placements for specific isocenters
            //and under certain conditions needed to be hard-coded into the script. I'm not really a fan of this, but it was the only way to satisify Nataliya's requirements.
            int            count = 0;
            string         beamName;
            VRect <double> jp;

            for (int i = 0; i < numVMATIsos; i++)
            {
                for (int j = 0; j < numBeams[i]; j++)
                {
                    //second isocenter and third beam requires the x-jaw positions to be mirrored about the y-axis (these jaw positions are in the fourth element of the jawPos list)
                    //this is generally the isocenter located in the pelvis and we want the beam aimed at the kidneys-area
                    if (i == 1 && j == 2)
                    {
                        jp = jawPos.ElementAt(j + 1);
                    }
                    else if (i == 1 && j == 3)
                    {
                        jp = jawPos.ElementAt(j - 1);
                    }
                    else
                    {
                        jp = jawPos.ElementAt(j);
                    }
                    Beam b;
                    beamName  = "";
                    beamName += String.Format("{0} ", count + 1);
                    //zero collimator rotations of two main fields for beams in isocenter immediately superior to matchline. Adjust the third beam such that collimator rotation is 90 degrees. Do not adjust 4th beam
                    double coll = collRot[j];
                    if ((numIsos > numVMATIsos) && (i == (numVMATIsos - 1)))
                    {
                        if (j < 2)
                        {
                            coll = 0.0;
                        }
                        else if (j == 2)
                        {
                            coll = 90.0;
                        }
                    }
                    //all even beams (e.g., 2, 4, etc.) will be CCW and all odd beams will be CW
                    if (count % 2 == 0)
                    {
                        b = plan.AddArcBeam(ebmpArc, jp, coll, CCW[0], CCW[1], GantryDirection.CounterClockwise, 0, isoLocations.ElementAt(i));
                        if (j >= 2)
                        {
                            beamName += String.Format("CCW {0}{1}", isoNames.ElementAt(i), 90);
                        }
                        else
                        {
                            beamName += String.Format("CCW {0}{1}", isoNames.ElementAt(i), "");
                        }
                    }
                    else
                    {
                        b = plan.AddArcBeam(ebmpArc, jp, coll, CW[0], CW[1], GantryDirection.Clockwise, 0, isoLocations.ElementAt(i));
                        if (j >= 2)
                        {
                            beamName += String.Format("CW {0}{1}", isoNames.ElementAt(i), 90);
                        }
                        else
                        {
                            beamName += String.Format("CW {0}{1}", isoNames.ElementAt(i), "");
                        }
                    }
                    b.Id = beamName;
                    b.CreateOrReplaceDRR(DRR);
                    count++;
                }
            }

            //add additional plan for ap/pa legs fields (all ap/pa isocenter fields will be contained within this plan)
            if (numIsos > numVMATIsos)
            {
                //6-10-2020 EAS, checked if exisiting _Legs plan is present in createPlan method
                legs_planUpper = tbi.AddExternalPlanSetup(selectedSS);
                if (singleAPPAplan)
                {
                    legs_planUpper.Id = String.Format("_Legs");
                }
                else
                {
                    legs_planUpper.Id = String.Format("{0} Upper Legs", numVMATIsos + 1);
                }
                //100% dose prescribed in plan
                legs_planUpper.SetPrescription(prescription.Item1, prescription.Item2, 1.0);
                legs_planUpper.SetCalculationModel(CalculationType.PhotonVolumeDose, calculationModel);

                Structure target;
                if (useFlash)
                {
                    target = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "ts_flash_target");
                }
                else
                {
                    target = selectedSS.Structures.FirstOrDefault(x => x.Id.ToLower() == "ptv_body");
                }

                //adjust x2 jaw (furthest from matchline) so that it covers edge of target volume
                double x2 = isoLocations.ElementAt(numVMATIsos).z - (target.MeshGeometry.Positions.Min(p => p.Z) - 20.0);
                if (x2 > 200.0)
                {
                    x2 = 200.0;
                }
                else if (x2 < 10.0)
                {
                    x2 = 10.0;
                }

                //AP field
                //set MLC positions. First row is bank number 0 (X1 leaves) and second row is bank number 1 (X2).
                float[,] MLCpos = new float[2, 60];
                for (int i = 0; i < 60; i++)
                {
                    MLCpos[0, i] = (float)-200.0;
                    MLCpos[1, i] = (float)(x2);
                }
                Beam b = legs_planUpper.AddMLCBeam(ebmpStatic, MLCpos, new VRect <double>(-200.0, -200.0, x2, 200.0), 90.0, 0.0, 0.0, isoLocations.ElementAt(numVMATIsos));
                b.Id = String.Format("{0} AP Upper Legs", ++count);
                b.CreateOrReplaceDRR(DRR);

                //PA field
                b    = legs_planUpper.AddMLCBeam(ebmpStatic, MLCpos, new VRect <double>(-200.0, -200.0, x2, 200.0), 90.0, 180.0, 0.0, isoLocations.ElementAt(numVMATIsos));
                b.Id = String.Format("{0} PA Upper Legs", ++count);
                b.CreateOrReplaceDRR(DRR);

                if ((numIsos - numVMATIsos) == 2)
                {
                    VVector infIso = new VVector();
                    //the element at numVMATIsos in isoLocations vector is the first AP/PA isocenter
                    infIso.x = isoLocations.ElementAt(numVMATIsos).x;
                    infIso.y = isoLocations.ElementAt(numVMATIsos).y;

                    double x1 = -200.0;
                    //if the distance between the matchline and the inferior edge of the target is < 600 mm, set the beams in the second isocenter (inferior-most) to be half-beam blocks
                    if (selectedSS.Structures.First(x => x.Id.ToLower() == "matchline").CenterPoint.z - target.MeshGeometry.Positions.Min(p => p.Z) < 600.0)
                    {
                        infIso.z = isoLocations.ElementAt(numVMATIsos).z - 200.0;
                        x1       = 0.0;
                    }
                    else
                    {
                        infIso.z = isoLocations.ElementAt(numVMATIsos).z - 390.0;
                    }
                    //fit x1 jaw to extend of patient
                    x2 = infIso.z - (target.MeshGeometry.Positions.Min(p => p.Z) - 20.0);
                    if (x2 > 200.0)
                    {
                        x2 = 200.0;
                    }
                    else if (x2 < 10.0)
                    {
                        x2 = 10.0;
                    }

                    //set MLC positions
                    MLCpos = new float[2, 60];
                    for (int i = 0; i < 60; i++)
                    {
                        MLCpos[0, i] = (float)(x1);
                        MLCpos[1, i] = (float)(x2);
                    }
                    //AP field
                    if (singleAPPAplan)
                    {
                        b    = legs_planUpper.AddMLCBeam(ebmpStatic, MLCpos, new VRect <double>(x1, -200.0, x2, 200.0), 90.0, 0.0, 0.0, infIso);
                        b.Id = String.Format("{0} AP Lower Legs", ++count);
                        b.CreateOrReplaceDRR(DRR);

                        //PA field
                        b    = legs_planUpper.AddMLCBeam(ebmpStatic, MLCpos, new VRect <double>(x1, -200.0, x2, 200.0), 90.0, 180.0, 0.0, infIso);
                        b.Id = String.Format("{0} PA Lower Legs", ++count);
                        b.CreateOrReplaceDRR(DRR);
                    }
                    else
                    {
                        //create a new legs plan if the user wants to separate the two APPA isocenters into separate plans
                        ExternalPlanSetup legs_planLower = tbi.AddExternalPlanSetup(selectedSS);
                        legs_planLower.Id = String.Format("{0} Lower Legs", numIsos);
                        legs_planLower.SetPrescription(prescription.Item1, prescription.Item2, 1.0);
                        legs_planLower.SetCalculationModel(CalculationType.PhotonVolumeDose, calculationModel);

                        b    = legs_planLower.AddMLCBeam(ebmpStatic, MLCpos, new VRect <double>(x1, -200.0, x2, 200.0), 90.0, 0.0, 0.0, infIso);
                        b.Id = String.Format("{0} AP Lower Legs", ++count);
                        b.CreateOrReplaceDRR(DRR);

                        //PA field
                        b    = legs_planLower.AddMLCBeam(ebmpStatic, MLCpos, new VRect <double>(x1, -200.0, x2, 200.0), 90.0, 180.0, 0.0, infIso);
                        b.Id = String.Format("{0} PA Lower Legs", ++count);
                        b.CreateOrReplaceDRR(DRR);
                    }
                }
                //MessageBox.Show("calculating dose");
                //legs_planUpper.CalculateDose();
                //const int nChars = 256;
                //StringBuilder Buff = new StringBuilder(nChars);
                //IntPtr handle = GetForegroundWindow();

                //if (GetWindowText(handle, Buff, nChars) > 0)
                //{
                //    MessageBox.Show(Buff.ToString());

                //}
            }
            MessageBox.Show("Beams placed successfully!\nPlease proceed to the optimization setup tab!");
        }
Example #14
0
        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);
        }