/// <summary>
        /// Create a copy of an existing beam (beams are unique to plans).
        /// </summary>
        public static void CopyStaticMlcBeam(Beam originalBeam, ExternalPlanSetup plan)
        {
            var MachineParameters = new ExternalBeamMachineParameters(originalBeam.TreatmentUnit.Id,
                                                                      originalBeam.EnergyModeDisplayName,
                                                                      originalBeam.DoseRate,
                                                                      originalBeam.Technique.Id, string.Empty);

            // Create a new beam.
            var collimatorAngle     = originalBeam.ControlPoints.First().CollimatorAngle;
            var gantryAngle         = originalBeam.ControlPoints.First().GantryAngle;
            var PatientSupportAngle = originalBeam.ControlPoints.First().PatientSupportAngle;
            var jawPositions        = originalBeam.ControlPoints.First().JawPositions;
            var leafPositions       = originalBeam.ControlPoints.First().LeafPositions;
            var isocenter           = originalBeam.IsocenterPosition;

            var beam = plan.AddMLCBeam(MachineParameters, leafPositions, jawPositions, collimatorAngle, gantryAngle,
                                       PatientSupportAngle, isocenter);

            if (plan.Beams.Where(b => b.Id == originalBeam.Id).Count() > 0)
            {
                throw new InvalidOperationException($"{originalBeam.Id} already exists");
            }

            beam.Id = originalBeam.Id;

            // Copy control points from the original beam.
            var editableParams = beam.GetEditableParameters();

            editableParams.WeightFactor = originalBeam.WeightFactor;
            beam.ApplyParameters(editableParams);
        }
        /// <summary>
        /// Create a copy of an existing beam (beams are unique to plans).
        /// </summary>
        public static void CopyFluenceBeam(Beam originalBeam, ExternalPlanSetup plan)
        {
            var MachineParameters = new ExternalBeamMachineParameters(originalBeam.TreatmentUnit.Id,
                                                                      originalBeam.EnergyModeDisplayName,
                                                                      originalBeam.DoseRate,
                                                                      originalBeam.Technique.Id, string.Empty);

            // Create a new beam.
            var collimatorAngle     = originalBeam.ControlPoints.First().CollimatorAngle;
            var gantryAngle         = originalBeam.ControlPoints.First().GantryAngle;
            var PatientSupportAngle = originalBeam.ControlPoints.First().PatientSupportAngle;
            var isocenter           = originalBeam.IsocenterPosition;
            var metersetWeights     = originalBeam.ControlPoints.Select(cp => cp.MetersetWeight);
            var beam = plan.AddSlidingWindowBeam(MachineParameters, metersetWeights, collimatorAngle, gantryAngle,
                                                 PatientSupportAngle, isocenter);

            beam.Id = originalBeam.Id;

            // Copy control points from the original beam.
            var editableParams = beam.GetEditableParameters();

            for (var i = 0; i < editableParams.ControlPoints.Count(); i++)
            {
                editableParams.ControlPoints.ElementAt(i).LeafPositions = originalBeam.ControlPoints.ElementAt(i).LeafPositions;
                editableParams.ControlPoints.ElementAt(i).JawPositions  = originalBeam.ControlPoints.ElementAt(i).JawPositions;
            }
            editableParams.WeightFactor = originalBeam.WeightFactor;
            beam.ApplyParameters(editableParams);

            var fluence = originalBeam.GetOptimalFluence();

            beam.SetOptimalFluence(fluence);
        }
Exemple #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;
        }
        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);
        }
Exemple #5
0
        public Beam AddStaticBeam(ExternalBeamMachineParameters machineParameters, VRect <double> jawPositions,
                                  double collimatorAngle, double gantryAngle, double patientSupportAngle, VVector isocenter)
        {
            var local  = this;
            var retVal = X.Instance.CurrentContext.GetValue(sc =>
            {
                return(new Beam(local._client.AddStaticBeam(machineParameters, jawPositions, collimatorAngle,
                                                            gantryAngle, patientSupportAngle, isocenter)));
            });

            return(retVal);
        }
Exemple #6
0
        public Beam AddVMATBeam(ExternalBeamMachineParameters machineParameters, IEnumerable <double> metersetWeights,
                                double collimatorAngle, double gantryAngle, double gantryStop, GantryDirection gantryDirection,
                                double patientSupportAngle, VVector isocenter)
        {
            var local  = this;
            var retVal = X.Instance.CurrentContext.GetValue(sc =>
            {
                return(new Beam(local._client.AddVMATBeam(machineParameters, metersetWeights, collimatorAngle,
                                                          gantryAngle, gantryStop, gantryDirection, patientSupportAngle, isocenter)));
            });

            return(retVal);
        }
Exemple #7
0
        public Beam AddConformalArcBeam(ExternalBeamMachineParameters machineParameters, double collimatorAngle,
                                        int controlPointCount, double gantryAngle, double gantryStop, GantryDirection gantryDirection,
                                        double patientSupportAngle, VVector isocenter)
        {
            var local  = this;
            var retVal = X.Instance.CurrentContext.GetValue(sc =>
            {
                return(new Beam(local._client.AddConformalArcBeam(machineParameters, collimatorAngle,
                                                                  controlPointCount, gantryAngle, gantryStop, gantryDirection, patientSupportAngle, isocenter)));
            });

            return(retVal);
        }
Exemple #8
0
        public static void CopyBeamToPlan(Beam beam, ExternalPlanSetup plansetup, VVector isocenter)
        {
            string energyModeDisp = beam.EnergyModeDisplayName;

            Char[] sep        = { '-' };
            string energyMode = energyModeDisp.Split(sep).First();
            string pfm        = energyModeDisp.Split(sep).Count() > 1 ? energyModeDisp.Split(sep).Last() : null;

            ExternalBeamMachineParameters extParams = new ExternalBeamMachineParameters(beam.TreatmentUnit.Id, energyMode, beam.DoseRate, beam.Technique.Id, pfm);
            List <double> metersetWeights           = GetControlPointWeights(beam);
            Beam          copyBeam = null;

            if (beam.MLCPlanType == MLCPlanType.VMAT)
            {
                copyBeam = plansetup.AddVMATBeam(extParams, metersetWeights, beam.ControlPoints[0].CollimatorAngle, beam.ControlPoints[0].GantryAngle, beam.ControlPoints[beam.ControlPoints.Count - 1].GantryAngle,
                                                 beam.GantryDirection, beam.ControlPoints[0].PatientSupportAngle, isocenter);
            }
            else if (beam.MLCPlanType == MLCPlanType.ArcDynamic)
            {
                copyBeam = plansetup.AddConformalArcBeam(extParams, beam.ControlPoints[0].CollimatorAngle, beam.ControlPoints.Count, beam.ControlPoints[0].GantryAngle, beam.ControlPoints[beam.ControlPoints.Count - 1].GantryAngle,
                                                         beam.GantryDirection, beam.ControlPoints[0].PatientSupportAngle, isocenter);
            }
            else if (beam.MLCPlanType == MLCPlanType.DoseDynamic)
            {
                var cppPairs    = metersetWeights.Zip(metersetWeights.Skip(1), (a, b) => new Tuple <double, double>(a, b)).ToList();
                var oddCppPairs = cppPairs.Where((p, i) => i % 2 == 1);

                if (metersetWeights.Count >= 4 && metersetWeights.Count % 2 == 0 && oddCppPairs.All(p => p.Item1 == p.Item2))
                {
                    copyBeam = plansetup.AddMultipleStaticSegmentBeam(extParams, metersetWeights, beam.ControlPoints[0].CollimatorAngle, beam.ControlPoints[0].GantryAngle, beam.ControlPoints[0].PatientSupportAngle, isocenter);
                }
                else
                {
                    copyBeam = plansetup.AddSlidingWindowBeam(extParams, metersetWeights, beam.ControlPoints[0].CollimatorAngle, beam.ControlPoints[0].GantryAngle, beam.ControlPoints[0].PatientSupportAngle, isocenter);
                }
            }
            else
            {
                throw new NotImplementedException("Copying this type of beam not implemented");
            }

            var beamParams = copyBeam.GetEditableParameters();

            CopyJawAndLeafPositions(beam, beamParams);
            beamParams.WeightFactor = beam.WeightFactor;

            copyBeam.ApplyParameters(beamParams);

            copyBeam.Id = beam.Id;
        }
Exemple #9
0
        //[DllImport("user32.dll")]
        //static extern int FindWindow(string lpClassName, string lpWindowName);
        //[DllImport("user32.dll")]
        //public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
        //[DllImport("user32.dll")]
        //private static extern IntPtr GetForegroundWindow();
        //[DllImport("user32.dll")]
        //static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
        //public const int WM_SYSCOMMAND = 0x0112;
        //public const int SC_CLOSE = 0xF060;

        public placeBeams(StructureSet ss, Tuple <int, DoseValue> presc, List <string> i, int iso, int vmatIso, bool appaPlan, int[] beams, string linac, string energy, string calcModel, bool flash)
        {
            selectedSS     = ss;
            pi             = selectedSS.Patient;
            prescription   = presc;
            isoNames       = i;
            numIsos        = iso;
            numVMATIsos    = vmatIso;
            singleAPPAplan = appaPlan;
            numBeams       = beams;
            ebmpArc        = new ExternalBeamMachineParameters(linac, energy, 600, "ARC", null);
            //AP/PA beams always use 6X
            ebmpStatic = new ExternalBeamMachineParameters(linac, "6X", 600, "STATIC", null);
            //copy the calculation model
            calculationModel = calcModel;
            useFlash         = flash;
        }
Exemple #10
0
        private void OnGeneratePlan()
        {
            // This will create a bunch of beams on a 60x60 cm box phantom, with user orign in the exact center (as well as the DICOM origin)
            //Patient Coordinate system:
            // X increases toward patient left
            // y increases toward patient Posterior
            // z increases toward patient inferior
            // and follows patient position


            // System.Windows.MessageBox.Show("Plan Generation Failed");
            string _machineId = ConfigurationManager.AppSettings["machine"];

            CurrentPatient.BeginModifications();
            var autoCourse = CurrentPatient.AddCourse();

            if (CurrentPatient.StructureSets.Count() > 0)
            {
                var autoPlan = autoCourse.AddExternalPlanSetup(CurrentPatient.StructureSets.FirstOrDefault());
                ExternalBeamMachineParameters machineParameters = new ExternalBeamMachineParameters(
                    _machineId,
                    "6X",
                    600,
                    "STATIC",
                    null);
                double[] fs = new double[] { 40.0, 60.0, 80.0, 100.0, 200.0 };  //all units are in mm
                foreach (var field in fs)
                {
                    double jaw = field / 2.0;
                    // add beams (in IEC 1217 DICOM standard)
                    autoPlan.AddStaticBeam(machineParameters,
                                           new VRect <double>(-1.0 * jaw, -1.0 * jaw, jaw, jaw),
                                           0,
                                           0,
                                           0,
                                           new VVector(0, -200.0, 0)
                                           );
                }
                autoPlan.SetPrescription(1, new DoseValue(100, DoseValue.DoseUnit.cGy), 1.0);
                autoPlan.CalculateDose();
                _app.SaveModifications(); //only needed for standalone applications
                Courses.Add(autoCourse);
                SelectedCourse = autoCourse;
                SelectedPlan   = autoPlan;
            }
        }
Exemple #11
0
        public static void GeneratePlan(VMS.TPS.Common.Model.API.Application app,
                                        MLCDefinitions mlcs,
                                        ExternalBeamMachineParameters beamPars,
                                        IMRTGenerator.JSON.Patient patient,
                                        IEnumerable <IMRTGenerator.JSON.Beam> beams
                                        )
        {
            var pat  = app.OpenPatientById(patient.PatientId);
            var sSet = pat.StructureSets.Single(ss => ss.Id == patient.StructureSet);

            pat.BeginModifications();

            var cr = pat.Courses.SingleOrDefault(cr_ => cr_.Id == "DTPCOURSE");

            if (null == cr)
            {
                cr    = pat.AddCourse();
                cr.Id = "DTPCOURSE";
            }
            var plan = cr.AddExternalPlanSetup(sSet);
            //
            // Cannot use target structure
            //
            var targetStructure = sSet.Structures.Single(s => s.Id == plan.TargetVolumeID);
            var isoCenter       = targetStructure.CenterPoint;

            foreach (var bm in beams)
            {
                var beam = plan.AddMLCBeam(beamPars, null, default(VRect <double>), 0.0, bm.GantryAngleInDeg, bm.PatientSupportAngleInDeg, isoCenter);
                beam.FitMLCToStructure(new FitToStructureMargins(bm.MlcMarginInmm),
                                       targetStructure,
                                       true,
                                       JawFitting.FitToRecommended,
                                       OpenLeavesMeetingPoint.OpenLeavesMeetingPoint_Middle,
                                       ClosedLeavesMeetingPoint.ClosedLeavesMeetingPoint_Center);
                adjustJaws(beam, bm.BeamletSizeXInmm, mlcs.MLCs[beam.MLC.Id].LeafWidths());
            }
            if (null == calcModel)
            {
                calcModel = plan.GetModelsForCalculationType(CalculationType.PhotonInfluenceMatrix)?.OrderByDescending(cm => cm, new ModelNameComparer()).First();
                calcModel = calcModel == null ? "" : calcModel;
            }
            plan.SetCalculationModel(CalculationType.PhotonInfluenceMatrix, calcModel);
            app.SaveModifications();
        }
Exemple #12
0
        public SetupBeam(Beam currBm)
        {
            // Create machine parameters
            String energy  = currBm.EnergyModeDisplayName;
            String fluence = null;
            Match  EMode   = Regex.Match(currBm.EnergyModeDisplayName, @"^([0-9]+[A-Z]+)-?([A-Z]+)?", RegexOptions.IgnoreCase); //format is... e.g. 6X(-FFF)

            if (EMode.Success)
            {
                if (EMode.Groups[2].Length > 0)  // fluence mode
                {
                    energy  = EMode.Groups[1].Value;
                    fluence = EMode.Groups[2].Value;
                } // else normal modes uses default in decleration
            }
            bmMachParam = new ExternalBeamMachineParameters(currBm.TreatmentUnit.Id.ToString(), energy, currBm.DoseRate, "STATIC", fluence);
            plnIso      = currBm.IsocenterPosition; // copy isocenter location
        }
        public MainWindow(ScriptContext context)
        {
            InitializeComponent();
            // Copy machine information from current beam //
            currPln = context.ExternalPlanSetup;
            Beam   currBm = currPln.Beams.FirstOrDefault();
            String energy = currBm.EnergyModeDisplayName;
            Match  EMode  = Regex.Match(currBm.EnergyModeDisplayName, @"^([0-9]+[A-Z]+)-?([A-Z]+)?", RegexOptions.IgnoreCase); //format is... e.g. 6X(-FFF)

            if (EMode.Success)
            {
                if (EMode.Groups[2].Length > 0)  // fluence mode, this algorithm only takes flattened beam
                {
                    energy = EMode.Groups[1].Value;
                }
            }
            currMachParam = new ExternalBeamMachineParameters(currBm.TreatmentUnit.Id.ToString(), energy, currBm.DoseRate, "STATIC", null);
            currIsoCtr    = currBm.IsocenterPosition;
        }
Exemple #14
0
        public int xDim, yDim;        // pixel dimensions of the fluence map
        public CreateMLCFields(ExternalPlanSetup pln, ExternalBeamMachineParameters machParam, VVector isoCtr, ImageFactory img, double picWidth, double picLength)
        {
            currPln       = pln;
            currMachParam = machParam;
            currIsoCtr    = isoCtr;
            imgFcty       = img;
            // Resize image based on input pic length and width //
            double nPxWidth  = Math.Floor(picWidth / flncRes);  // number of 2.5mm pixels in planned picture width
            double nPxLength = Math.Floor(picLength / flncRes); // number of 2.5mm pixels in planned picture length
            double mag       = Math.Min(nPxWidth / imgFcty.Image.Width, nPxLength / imgFcty.Image.Height);

            xDim = (int)Math.Floor(mag * imgFcty.Image.Width);
            yDim = (int)Math.Floor(mag * imgFcty.Image.Height);
            // Remove all existing beams //
            int nBeams = currPln.Beams.Count();

            for (int i = 0; i < nBeams; i++)
            {
                Beam currBm = currPln.Beams.First();
                currPln.RemoveBeam(currBm);
            }
        }
 private void OnCalculatePlan()
 {
     if (Patient != null)
     {
         Patient.BeginModifications();
         var      localCourse = Patient.AddCourse();
         var      localPlan   = localCourse.AddExternalPlanSetup(Patient.StructureSets.First());
         double[] fieldSizes  = new double[] { 30, 40, 50, 177, 200 };
         ExternalBeamMachineParameters beamP = new ExternalBeamMachineParameters("HESN10", "6X", 600, "STATIC", null);
         foreach (var fs in fieldSizes)
         {
             var localBeam = localPlan.AddStaticBeam(beamP,
                                                     new VRect <double>(-1.0 * fs / 2.0, -1.0 * fs / 2.0, fs / 2.0, fs / 2.0),
                                                     0,
                                                     0,
                                                     0,
                                                     new VVector(0, -200, 0));
         }
         localPlan.SetPrescription(1, new DoseValue(100, DoseValue.DoseUnit.cGy), 1.0);
         localPlan.CalculateDose();
         _app.SaveModifications();
     }
 }
        static void Main(string[] args)
        {
            var loc   = System.Reflection.Assembly.GetExecutingAssembly().Location;
            var sname = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;

            loc = loc.Substring(0, loc.Length - sname.Length - 4);
            var fileName = @"InputData.json";

            var mlcs = MLCDefinitions.GetInstance();

            using (var app = VMS.TPS.Common.Model.API.Application.CreateApplication())
            {
                JSON.InputData inputData;


                using (var inputFile = new StreamReader(Path.Combine(loc, fileName))) {
                    inputData = JSON.InputData.FromJson(inputFile.ReadToEnd());
                }
                var beamPars = new ExternalBeamMachineParameters(
                    inputData.Machine.MachineId,
                    inputData.Machine.EnergyMode,
                    (int)inputData.Machine.DoseRate,
                    "STATIC",
                    null
                    );


                foreach (var patInfo in inputData.Patients)
                {
                    Generator.GeneratePlan(app,
                                           mlcs,
                                           beamPars,
                                           patInfo,
                                           inputData.Beams);
                }
            }
        }
        /// <summary>
        /// Create a copy of an existing beam (beams are unique to plans).
        /// </summary>
        private static string CopyBeam(Beam originalBeam, ExternalPlanSetup plan, VVector isocenter, bool getCollimatorAndGantryFromBeam)
        {
            ExternalBeamMachineParameters MachineParameters =
                new ExternalBeamMachineParameters(originalBeam.TreatmentUnit.Id, originalBeam.EnergyModeDisplayName, originalBeam.DoseRate, originalBeam.Technique.Id, string.Empty);

            // Create a new beam.
            var collimatorAngle = getCollimatorAndGantryFromBeam ? originalBeam.ControlPoints.First().CollimatorAngle : 0.0;
            var gantryAngle     = getCollimatorAndGantryFromBeam ? originalBeam.ControlPoints.First().GantryAngle : 0.0;
            var couchAngle      = getCollimatorAndGantryFromBeam ? originalBeam.ControlPoints.First().PatientSupportAngle : 0.0;
            var metersetWeights = originalBeam.ControlPoints.Select(cp => cp.MetersetWeight);
            var beam            = plan.AddSlidingWindowBeam(MachineParameters, metersetWeights, collimatorAngle, gantryAngle,
                                                            couchAngle, isocenter);

            // Copy control points from the original beam.
            var editableParams = beam.GetEditableParameters();

            for (var i = 0; i < editableParams.ControlPoints.Count(); i++)
            {
                editableParams.ControlPoints.ElementAt(i).LeafPositions = originalBeam.ControlPoints.ElementAt(i).LeafPositions;
                editableParams.ControlPoints.ElementAt(i).JawPositions  = originalBeam.ControlPoints.ElementAt(i).JawPositions;
            }
            beam.ApplyParameters(editableParams);
            return(beam.Id);
        }
        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");
        }
Exemple #19
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");
        }
        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());
        }
Exemple #21
0
        /// <summary>
        /// Create verifications plans for a given treatment plan.
        /// </summary>
        public static ExternalPlanSetup CreateVerificationPlan(Course course, IEnumerable <Beam> beams, ExternalPlanSetup verifiedPlan, StructureSet verificationStructures,
                                                               bool calculateDose)
        {
            var verificationPlan = course.AddExternalPlanSetupAsVerificationPlan(verificationStructures, verifiedPlan);

            try
            {
                verificationPlan.Id = verifiedPlan.Id;
            }
            catch (System.ArgumentException)
            {
                var message = "Plan already exists in QA course.";
                throw new Exception(message);
            }

            // Put isocenter to the center of the QAdevice
            VVector isocenter = verificationPlan.StructureSet.Image.UserOrigin;
            var     beamList  = verifiedPlan.Beams.ToList(); //used for looping later

            foreach (Beam beam in beams)
            {
                if (beam.IsSetupField)
                {
                    continue;
                }

                ExternalBeamMachineParameters MachineParameters =
                    new ExternalBeamMachineParameters(beam.TreatmentUnit.Id, beam.EnergyModeDisplayName, beam.DoseRate, beam.Technique.Id, string.Empty);

                if (beam.MLCPlanType.ToString() == "VMAT")
                {
                    // Create a new VMAT beam.
                    var collimatorAngle  = beam.ControlPoints.First().CollimatorAngle;
                    var gantryAngleStart = beam.ControlPoints.First().GantryAngle;
                    var gantryAngleEnd   = beam.ControlPoints.Last().GantryAngle;
                    var gantryDirection  = beam.GantryDirection;
                    var metersetWeights  = beam.ControlPoints.Select(cp => cp.MetersetWeight);

                    verificationPlan.AddVMATBeam(MachineParameters, metersetWeights, collimatorAngle, gantryAngleStart,
                                                 gantryAngleEnd, gantryDirection, 0.0, isocenter);
                    continue;
                }
                else
                {
                    if (beam.MLCPlanType.ToString() == "DoseDynamic")
                    {
                        // Create a new IMRT beam.
                        double gantryAngle;
                        double collimatorAngle;
                        if (beam.TreatmentUnit.Name == "Trilogy") //arccheck
                        {
                            gantryAngle     = beam.ControlPoints.First().GantryAngle;
                            collimatorAngle = beam.ControlPoints.First().CollimatorAngle;
                        }

                        else //ix with only mapcheck
                        {
                            gantryAngle     = 0.0;
                            collimatorAngle = 0.0;
                        }

                        var metersetWeights = beam.ControlPoints.Select(cp => cp.MetersetWeight);
                        verificationPlan.AddSlidingWindowBeam(MachineParameters, metersetWeights, collimatorAngle, gantryAngle,
                                                              0.0, isocenter);
                        continue;
                    }
                    else
                    {
                        var message = string.Format("Treatment field {0} is not VMAT or IMRT.", beam);
                        throw new Exception(message);
                    }
                }
            }

            int i = 0;

            foreach (Beam verificationBeam in verificationPlan.Beams)
            {
                verificationBeam.Id = beamList[i].Id;
                i++;
            }

            foreach (Beam verificationBeam in verificationPlan.Beams)
            {
                foreach (Beam beam in verifiedPlan.Beams)
                {
                    if (verificationBeam.Id == beam.Id)
                    {
                        var editableParams = beam.GetEditableParameters();
                        editableParams.Isocenter = verificationPlan.StructureSet.Image.UserOrigin;
                        verificationBeam.ApplyParameters(editableParams);
                        continue;
                    }
                }
            }
            // Set presciption
            const int numberOfFractions = 1;

            verificationPlan.SetPrescription(numberOfFractions, verifiedPlan.DosePerFraction, verifiedPlan.TreatmentPercentage);

            verificationPlan.SetCalculationModel(CalculationType.PhotonVolumeDose, verifiedPlan.GetCalculationModel(CalculationType.PhotonVolumeDose));

            CalculationResult res;

            if (verificationPlan.Beams.FirstOrDefault().MLCPlanType.ToString() == "DoseDynamic")
            {
                var getCollimatorAndGantryAngleFromBeam = beams.Count() > 1;
                var presetValues = (from beam in beams
                                    select new KeyValuePair <string, MetersetValue>(beam.Id, beam.Meterset)).ToList();
                res = verificationPlan.CalculateDoseWithPresetValues(presetValues);
            }
            else //vmat
            {
                res = verificationPlan.CalculateDose();
            }
            if (!res.Success)
            {
                var message = string.Format("Dose calculation failed for verification plan. Output:\n{0}", res);
                throw new Exception(message);
            }
            return(verificationPlan);
        }
Exemple #22
0
        public static void BeamMaker(ref ExternalPlanSetup plan, StructureSet ss, double prescriptionDose, Tuple <string, string, bool> beamParams)
        {
            //First check if beams already exist
            foreach (Beam beam in plan.Beams.ToList())
            {
                plan.RemoveBeam(beam);
            }
            string treatmentCenter = beamParams.Item1;
            string treatmentArea   = beamParams.Item2;
            string beamName        = "";
            int    doseRate        = 600;

            //Get the right beam name
            if (treatmentCenter == "BC Cancer - Surrey")
            {
                beamName = "fv" + treatmentArea.Replace(" ", "") + "TB";
                beamName = beamName.ToUpper();
                doseRate = 400;
            }
            else if (treatmentCenter == "BC Cancer - Vancouver")
            {
                beamName = "Va" + treatmentArea.Replace(" ", "");
            }



            //need to create two arc beams, and make sure they fit to PTVs.
            ExternalBeamMachineParameters ebmp = new ExternalBeamMachineParameters(beamName, "6X", doseRate, "ARC", null);
            //First need to find the isocentre, which will be in the main PTV

            //find all the ptvs
            List <Structure> ptvs     = new List <Structure>();
            List <Structure> mainPTVs = new List <Structure>();

            foreach (Structure structure in ss.Structures)
            {
                if (structure.Name.ToLower().Contains("ptv"))
                {
                    ptvs.Add(structure);
                    if (StringOperations.FindPTVNumber(structure.Name) == prescriptionDose / 100)
                    //Check if receiving prescription dose
                    {
                        mainPTVs.Add(structure);
                    }
                }
            }
            //Check if it's receiving the prescription dose. If so, set isocentre here. If there is more than
            //One receiving the prescription dose, set at the average between the two.
            VVector isocentre;

            if (mainPTVs.Count > 0)
            {
                double x = 0;
                double y = 0;
                double z = 0;
                //Find average x,y,z
                for (int i = 0; i < mainPTVs.Count; i++)
                {
                    x += Math.Round(mainPTVs[i].CenterPoint.x / 10.0f) * 10.0f / mainPTVs.Count;
                    y += Math.Round(mainPTVs[i].CenterPoint.y / 10.0f) * 10.0f / mainPTVs.Count;
                    z += Math.Round(mainPTVs[i].CenterPoint.z / 10.0f) * 10.0f / mainPTVs.Count;
                }
                isocentre = new VVector(x, y, z);
            }
            else
            {
                isocentre = new VVector(0, 0, 0);
            }
            //Create two VMAT beams

            //First get the right jaw dimensions:
            VRect <double> jaws1 = FitJawsToTarget(isocentre, plan, ptvs, 30, 0);
            VRect <double> jaws2 = FitJawsToTarget(isocentre, plan, ptvs, 330, 0);
            Beam           vmat1 = plan.AddArcBeam(ebmp, jaws1, 30, 180.1, 179.9, GantryDirection.Clockwise, 0, isocentre);
            Beam           vmat2 = plan.AddArcBeam(ebmp, jaws2, 330, 179.9, 180.1, GantryDirection.CounterClockwise, 0, isocentre);

            vmat1.Id = "PC_vmat1";
            vmat2.Id = "PC_vmat2";
        }
 // Add beam to the plan
 public Beam AddBeamToVerifPlan(Beam currBm)
 {
     if (verifPln == null)
     {
         return(null);
     }
     else
     {
         bmTech = getMLCBmTechnique(currBm);  // find beam technique
         // Create machine parameters
         String energy  = currBm.EnergyModeDisplayName;
         String fluence = null;
         Match  EMode   = Regex.Match(currBm.EnergyModeDisplayName, @"^([0-9]+[A-Z]+)-?([A-Z]+)?", RegexOptions.IgnoreCase); //format is... e.g. 6X(-FFF)
         if (EMode.Success)
         {
             if (EMode.Groups[2].Length > 0)  // fluence mode
             {
                 energy  = EMode.Groups[1].Value;
                 fluence = EMode.Groups[2].Value;
             } // else normal modes uses default in decleration
         }
         ExternalBeamMachineParameters machParam = new ExternalBeamMachineParameters(currBm.TreatmentUnit.Id.ToString(),
                                                                                     energy, currBm.DoseRate, currBm.Technique.Id.ToString(), fluence);
         // Define collimator, gantry and couch angles //
         Double gantryAng = currBm.ControlPoints.First().GantryAngle;
         Double collAng   = currBm.ControlPoints.First().CollimatorAngle;
         Double couchAng  = 0.0;
         // MU values for each control point //
         IEnumerable <double> muSet = currBm.ControlPoints.Select(cp => cp.MetersetWeight).ToList();
         // Add beam MU to the list of MU values //
         muValues.Add(new KeyValuePair <string, MetersetValue>(currBm.Id, currBm.Meterset));
         // Start adding beam based on beam technique //
         if (bmTech == "StaticMLC")
         {
             Beam verifBm = verifPln.AddMLCBeam(machParam, new float[2, 60], new VRect <double>(-10.0, -10.0, 10.0, 10.0),
                                                collAng, gantryAng, couchAng, verifPlnIso);
             verifBm.Id = currBm.Id;
             BeamParameters ctrPtParam = copyControlPoints(currBm, verifBm);
             verifBm.ApplyParameters(ctrPtParam);
             return(verifBm);
         }
         else if (bmTech == "StaticSegWin")
         {
             Beam verifBm = verifPln.AddMultipleStaticSegmentBeam(machParam, muSet,
                                                                  collAng, gantryAng, couchAng, verifPlnIso);
             verifBm.Id = currBm.Id;
             BeamParameters ctrPtParam = copyControlPoints(currBm, verifBm);
             verifBm.ApplyParameters(ctrPtParam);
             return(verifBm);
         }
         else if (bmTech == "StaticSlidingWin")
         {
             Beam verifBm = verifPln.AddSlidingWindowBeam(machParam, muSet,
                                                          collAng, gantryAng, couchAng, verifPlnIso);
             verifBm.Id = currBm.Id;
             BeamParameters ctrPtParam = copyControlPoints(currBm, verifBm);
             verifBm.ApplyParameters(ctrPtParam);
             return(verifBm);
         }
         else if (bmTech == "ConformalArc")
         {
             Beam verifBm = verifPln.AddConformalArcBeam(machParam, collAng, currBm.ControlPoints.Count(),
                                                         currBm.ControlPoints.First().GantryAngle, currBm.ControlPoints.Last().GantryAngle,
                                                         currBm.GantryDirection, couchAng, verifPlnIso);
             verifBm.Id = currBm.Id;
             BeamParameters ctrPtParam = copyControlPoints(currBm, verifBm);
             verifBm.ApplyParameters(ctrPtParam);
             return(verifBm);
         }
         else if (bmTech == "VMAT")
         {
             Beam verifBm = verifPln.AddVMATBeam(machParam, muSet, collAng,
                                                 currBm.ControlPoints.First().GantryAngle, currBm.ControlPoints.Last().GantryAngle,
                                                 currBm.GantryDirection, couchAng, verifPlnIso);
             verifBm.Id = currBm.Id;
             BeamParameters ctrPtParam = copyControlPoints(currBm, verifBm);
             verifBm.ApplyParameters(ctrPtParam);
             return(verifBm);
         }
         else // null
         {
             return(null);
         }
     }
 }
        public void SetupFieldsPerformUpdates()
        {
            Log.Initialize(_context);
            _context.Patient.BeginModifications();

            ExternalPlanSetup plan = _context.PlanSetup as ExternalPlanSetup;
            Beam           beam    = plan.Beams.FirstOrDefault();
            VRect <double> jaws    = new VRect <double>(-50, -50, 50, 50);
            ExternalBeamMachineParameters machineParams = new ExternalBeamMachineParameters(beam.TreatmentUnit.Id, beam.EnergyModeDisplayName, beam.DoseRate, "STATIC", "");

            int ap, pa, rtLat, ltLat;

            switch (PatientOrientation)
            {
            case "HeadFirstSupine":
                ap    = 0;
                pa    = 180;
                rtLat = 270;
                ltLat = 90;
                break;

            case "FeetFirstSupine":
                ap    = 0;
                pa    = 180;
                rtLat = 90;
                ltLat = 270;
                break;

            case "HeadFirstProne":
                ap    = 180;
                pa    = 0;
                rtLat = 90;
                ltLat = 270;
                break;

            case "FeetFirstProne":
                ap    = 180;
                pa    = 0;
                rtLat = 270;
                ltLat = 90;
                break;

            default:
                ap    = 0;
                pa    = 180;
                rtLat = 270;
                ltLat = 90;
                break;
            }


            if (!MvKvPairFlag)
            {
                if (CbctFlag)
                {
                    plan.AddSetupBeam(machineParams, jaws, 0, 0, 0, beam.IsocenterPosition).Id = _cbctName;
                }
                if (ApFlag)
                {
                    plan.AddSetupBeam(machineParams, jaws, 0, ap, 0, beam.IsocenterPosition).Id = _apName;
                }
                if (PaFlag)
                {
                    plan.AddSetupBeam(machineParams, jaws, 0, pa, 0, beam.IsocenterPosition).Id = _paName;
                }
                if (RtLatFlag)
                {
                    plan.AddSetupBeam(machineParams, jaws, 0, rtLat, 0, beam.IsocenterPosition).Id = _rtLatName;
                }
                if (LtLatFlag)
                {
                    plan.AddSetupBeam(machineParams, jaws, 0, ltLat, 0, beam.IsocenterPosition).Id = _ltLatName;
                }
            }
            else
            {
                if (CbctFlag)
                {
                    plan.AddSetupBeam(machineParams, jaws, 0, 0, 0, beam.IsocenterPosition).Id = _cbctName;
                }
                if (ApFlag)
                {
                    plan.AddSetupBeam(machineParams, jaws, 0, ap, 0, beam.IsocenterPosition).Id = $"{_apName} {Suffix1}";
                    plan.AddSetupBeam(machineParams, jaws, 0, ap, 0, beam.IsocenterPosition).Id = $"{_apName} {Suffix2}";
                }
                if (PaFlag)
                {
                    plan.AddSetupBeam(machineParams, jaws, 0, pa, 0, beam.IsocenterPosition).Id = $"{_paName} {Suffix1}";
                    plan.AddSetupBeam(machineParams, jaws, 0, pa, 0, beam.IsocenterPosition).Id = $"{_paName} {Suffix2}";
                }
                if (RtLatFlag)
                {
                    plan.AddSetupBeam(machineParams, jaws, 0, rtLat, 0, beam.IsocenterPosition).Id = $"{_rtLatName} {Suffix1}";
                    plan.AddSetupBeam(machineParams, jaws, 0, rtLat, 0, beam.IsocenterPosition).Id = $"{_rtLatName} {Suffix2}";
                }
                if (LtLatFlag)
                {
                    plan.AddSetupBeam(machineParams, jaws, 0, ltLat, 0, beam.IsocenterPosition).Id = $"{_ltLatName} {Suffix1}";
                    plan.AddSetupBeam(machineParams, jaws, 0, ltLat, 0, beam.IsocenterPosition).Id = $"{_ltLatName} {Suffix2}";
                }
            }

            log.Info("Setup Fields");
            LogManager.Shutdown();
        }