예제 #1
0
        public ObservableCollection <PQMSummaryViewModel> AddPQMSummary(ObservableCollection <PQMSummaryViewModel> PqmSummaries, ConstraintViewModel constraintPath, PlanningItemViewModel planningItem, Patient patient)
        {
            StructureSet structureSet = planningItem.PlanningItemStructureSet;
            Structure    evalStructure;
            //ObservableCollection<PQMSummaryViewModel> pqmSummaries = new ObservableCollection<PQMSummaryViewModel>();
            //ObservableCollection<StructureViewModel> foundStructureList = new ObservableCollection<StructureViewModel>();
            var calculator = new PQMSummaryCalculator();

            //var numCol = PqmSummaries[0]
            //Objectives = calculator.GetObjectives(constraintPath);
            if (planningItem.PlanningItemObject is PlanSum)
            {
                var     waitWindowPQM = new WaitWindowPQM();
                PlanSum plansum       = (PlanSum)planningItem.PlanningItemObject;
                if (plansum.IsDoseValid() == true)
                {
                    waitWindowPQM.Show();
                    foreach (PQMSummaryViewModel pqm in PqmSummaries)
                    {
                        evalStructure = calculator.FindStructureFromAlias(structureSet, pqm.TemplateId, pqm.TemplateAliases, pqm.TemplateCodes);
                        if (evalStructure != null)
                        {
                            var pqmSummary = calculator.GetObjectiveProperties(pqm, planningItem, structureSet, new StructureViewModel(evalStructure));
                            //pqm.Achieved_Comparison = pqmSummary.Achieved;
                            //pqm.AchievedColor_Comparison = pqmSummary.AchievedColor;
                            //pqm.AchievedPercentageOfGoal_Comparison = pqmSummary.AchievedPercentageOfGoal;
                            //pqm.Met_Comparison = pqmSummary.Met;
                            //pqmSummaries.Add(pqmSummary);
                            //foundStructureList.Add(new StructureViewModel(evalStructure));
                        }
                    }
                    //FoundStructureList = foundStructureList;
                    waitWindowPQM.Close();
                }
                //PqmSummaries = pqmSummaries;
            }
            else //is plansetup
            {
                var waitWindowPQM = new WaitWindowPQM();

                PlanSetup planSetup = (PlanSetup)planningItem.PlanningItemObject;
                if (planSetup.IsDoseValid() == true)
                {
                    waitWindowPQM.Show();
                    foreach (PQMSummaryViewModel pqm in PqmSummaries)
                    {
                        evalStructure = calculator.FindStructureFromAlias(structureSet, pqm.TemplateId, pqm.TemplateAliases, pqm.TemplateCodes);
                        if (evalStructure != null)
                        {
                            if (evalStructure.Id.Contains("PTV") == true)
                            {
                                foreach (Structure s in structureSet.Structures)
                                {
                                    if (s.Id == planSetup.TargetVolumeID)
                                    {
                                        evalStructure = s;
                                    }
                                }
                            }
                            var pqmSummary = calculator.GetObjectiveProperties(pqm, planningItem, structureSet, new StructureViewModel(evalStructure));
                            //pqm.Achieved_Comparison = pqmSummary.Achieved;
                            //foundStructureList.Add(new StructureViewModel(evalStructure));
                        }
                    }
                    //FoundStructureList = foundStructureList;
                    waitWindowPQM.Close();
                }
                //PqmSummaries = pqmSummaries;
            }
            return(PqmSummaries);
        }
예제 #2
0
        protected override void RunTest(PlanSetup plan)
        {
            bool IMRT = false;

            DisplayName     = "Jaw Tracking";
            Result          = "";
            TestExplanation = "Checks to see if jaw tracking is enabled for IMRT/VMAT plans";

            #region Macomb Group
            // use jaw tracking
            if (Department == Department.MAC ||
                Department == Department.MPH)
            {
                //VMAT plan
                if ((from s in plan.Beams where s.MLCPlanType == MLCPlanType.VMAT select s).Count() > 0)
                {
                    IMRT = true;

                    foreach (Beam field in plan.Beams)
                    {
                        //ignore setup fields
                        if (!field.IsSetupField)
                        {
                            //for VMAT fields, check that there are different jaw positions in the control points
                            if (field.MLCPlanType == MLCPlanType.VMAT)
                            {
                                //get initial jaw positions
                                double x1 = field.ControlPoints.First().JawPositions.X1;
                                double x2 = field.ControlPoints.First().JawPositions.X2;
                                double y1 = field.ControlPoints.First().JawPositions.Y1;
                                double y2 = field.ControlPoints.First().JawPositions.Y2;

                                //if they change at any of the control points, then jaw tracking must be on
                                foreach (ControlPoint point in field.ControlPoints)
                                {
                                    if (x1 != point.JawPositions.X1 || x2 != point.JawPositions.X2 || y1 != point.JawPositions.Y1 || y2 != point.JawPositions.Y2)
                                    {
                                        Result       = "Pass";
                                        DisplayColor = ResultColorChoices.Pass;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                //IMRT plan
                else if ((from s in plan.Beams where s.MLCPlanType == MLCPlanType.DoseDynamic select s).Count() > 0)
                {
                    foreach (Beam field in plan.Beams)
                    {
                        //ignore setup fields
                        if (!field.IsSetupField)
                        {
                            //for IMRT fields that have more control points than step and shoot, check that there are different jaw positions in the control points
                            if (field.MLCPlanType == MLCPlanType.DoseDynamic && field.ControlPoints.Count > 18)
                            {
                                IMRT = true;

                                //get initial jaw positions
                                double x1 = field.ControlPoints.First().JawPositions.X1;
                                double x2 = field.ControlPoints.First().JawPositions.X2;
                                double y1 = field.ControlPoints.First().JawPositions.Y1;
                                double y2 = field.ControlPoints.First().JawPositions.Y2;

                                //if they change at any of the control points, then jaw tracking must be on
                                foreach (ControlPoint point in field.ControlPoints)
                                {
                                    if (x1 != point.JawPositions.X1 || x2 != point.JawPositions.X2 || y1 != point.JawPositions.Y1 || y2 != point.JawPositions.Y2)
                                    {
                                        Result       = "Pass";
                                        DisplayColor = ResultColorChoices.Pass;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                //Static fields
                if (!IMRT)
                {
                    Result       = "Pass";
                    DisplayColor = ResultColorChoices.Pass;
                }

                //No jaw tracking detected
                else if (Result == "")
                {
                    Result        = "Warning";
                    ResultDetails = "Please check that jaw tracking is enabled in the optimization window or leaf motion calculator";
                    DisplayColor  = ResultColorChoices.Warn;
                }
            }
            #endregion

            #region Flint Group and Northern TrueBeam (for now)
            // do not use jaw tracking
            else if (Department == Department.FLT || Department == Department.NOR)
            {
                //VMAT plan
                if ((from s in plan.Beams where s.MLCPlanType == MLCPlanType.VMAT select s).Count() > 0)
                {
                    IMRT = true;

                    foreach (Beam field in plan.Beams)
                    {
                        //ignore setup fields
                        if (!field.IsSetupField)
                        {
                            //for VMAT fields, check that there are different jaw positions in the control points
                            if (field.MLCPlanType == MLCPlanType.VMAT)
                            {
                                //get initial jaw positions
                                double x1 = field.ControlPoints.First().JawPositions.X1;
                                double x2 = field.ControlPoints.First().JawPositions.X2;
                                double y1 = field.ControlPoints.First().JawPositions.Y1;
                                double y2 = field.ControlPoints.First().JawPositions.Y2;

                                //if they change at any of the control points, then jaw tracking must be on
                                foreach (ControlPoint point in field.ControlPoints)
                                {
                                    if (x1 != point.JawPositions.X1 || x2 != point.JawPositions.X2 || y1 != point.JawPositions.Y1 || y2 != point.JawPositions.Y2)
                                    {
                                        Result        = "Warning";
                                        ResultDetails = "Please check that jaw tracking is disabled in the optimization window";
                                        DisplayColor  = ResultColorChoices.Warn;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                //IMRT plan
                else if ((from s in plan.Beams where s.MLCPlanType == MLCPlanType.DoseDynamic select s).Count() > 0)
                {
                    foreach (Beam field in plan.Beams)
                    {
                        //ignore setup fields
                        if (!field.IsSetupField)
                        {
                            //for IMRT fields that have more control points than step and shoot, check that there are different jaw positions in the control points
                            if (field.MLCPlanType == MLCPlanType.DoseDynamic && field.ControlPoints.Count > 18)
                            {
                                IMRT = true;

                                //get initial jaw positions
                                double x1 = field.ControlPoints.First().JawPositions.X1;
                                double x2 = field.ControlPoints.First().JawPositions.X2;
                                double y1 = field.ControlPoints.First().JawPositions.Y1;
                                double y2 = field.ControlPoints.First().JawPositions.Y2;

                                //if they change at any of the control points, then jaw tracking must be on
                                foreach (ControlPoint point in field.ControlPoints)
                                {
                                    if (x1 != point.JawPositions.X1 || x2 != point.JawPositions.X2 || y1 != point.JawPositions.Y1 || y2 != point.JawPositions.Y2)
                                    {
                                        Result        = "Warning";
                                        ResultDetails = "Please check that jaw tracking is disabled in the leaf motion calculator";
                                        DisplayColor  = ResultColorChoices.Warn;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                //Static fields
                if (!IMRT)
                {
                    Result       = "Pass";
                    DisplayColor = ResultColorChoices.Pass;
                }

                //No jaw tracking detected
                else if (Result == "")
                {
                    Result       = "Pass";
                    DisplayColor = ResultColorChoices.Pass;
                }
            }
            #endregion

            else
            {
                TestNotImplemented();
            }
        }
예제 #3
0
 public PrecriptionChecks(PlanSetup plan) : base(plan)
 {
 }
        /// <summary>
        /// calcDQP
        /// </summary>
        /// <param name="ps"></param>
        /// <param name="DQPList"></param>
        /// <returns></returns>
        static string calcDQP(PlanSetup ps, Collection <DQP> DQPList)
        {
            // Initialize variables.
            DVHData   dvhStat         = null;
            Structure targetStructure = null;
            string    oText           = "";

            // Iterate over all DQP in list.
            foreach (var row in DQPList)
            {
                targetStructure = ps.StructureSet.Structures.Where(s => s.Id == row.structureName).FirstOrDefault();

                // Execute if the structure name match.
                if (targetStructure != null)
                {
                    //get string of dose unit [Gy] or [cGy].
                    dvhStat = ps.GetDVHCumulativeData(targetStructure, DoseValuePresentation.Absolute, VolumePresentation.AbsoluteCm3, 0.1);
                    string doseUnitString = dvhStat.MaxDose.UnitAsString;

                    // define prefix DQP name.
                    if (row.DQPtype == DQPtype.Dose)
                    {
                        oText += row.structureName + "-D" + row.DQPvalue.ToString();
                    }
                    else if (row.DQPtype == DQPtype.Volume)
                    {
                        oText += row.structureName + "-V" + row.DQPvalue.ToString();
                    }
                    else if (row.DQPtype == DQPtype.DoseComplement)
                    {
                        oText += row.structureName + "-DC" + row.DQPvalue.ToString();
                    }
                    else if (row.DQPtype == DQPtype.ComplementVolume)
                    {
                        oText += row.structureName + "-CV" + row.DQPvalue.ToString();
                    }

                    // define input unit [Gy/cGy] or [cc] or [%]
                    if (row.InputUnit == IOUnit.Absolute)
                    {
                        if (row.DQPtype == DQPtype.Dose)
                        {
                            oText += "cc";
                        }
                        else if (row.DQPtype == DQPtype.Volume)
                        {
                            oText += doseUnitString;
                        }
                        else if (row.DQPtype == DQPtype.DoseComplement)
                        {
                            oText += "cc";
                        }
                        else if (row.DQPtype == DQPtype.ComplementVolume)
                        {
                            oText += doseUnitString;
                        }
                    }
                    else
                    {
                        oText += "%";
                    }

                    // define output unit [Gy/cGy] or [cc] or [%]
                    if (row.OutputUnit == IOUnit.Absolute)
                    {
                        if (row.DQPtype == DQPtype.Dose)
                        {
                            oText += "[" + doseUnitString + "]";
                        }
                        else if (row.DQPtype == DQPtype.Volume)
                        {
                            oText += "[cc]";
                        }
                        else if (row.DQPtype == DQPtype.DoseComplement)
                        {
                            oText += "[" + doseUnitString + "]";
                        }
                        else if (row.DQPtype == DQPtype.ComplementVolume)
                        {
                            oText += "[cc]";
                        }
                    }
                    else
                    {
                        oText += "[%]";
                    }
                    oText += ":";

                    // calculate dose quality parameters (VolumeAtDose,DoseAtVolume,DoseComplement,ComplementVolume).
                    if (row.DQPtype == DQPtype.Dose) // calculate DoseAtVolume.
                    {
                        DoseValue doseValue = ps.GetDoseAtVolume(targetStructure, row.DQPvalue,
                                                                 row.InputUnit == IOUnit.Relative ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3,
                                                                 row.OutputUnit == IOUnit.Relative ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute);
                        oText += doseValue.Dose.ToString();
                    }
                    else if (row.DQPtype == DQPtype.Volume) // calculate VolumeAtDose.
                    {
                        double volumeValue = ps.GetVolumeAtDose(targetStructure,
                                                                row.InputUnit == IOUnit.Relative ?
                                                                new DoseValue(ps.TotalDose.Dose * (row.DQPvalue * 0.01), dvhStat.MaxDose.Unit) :
                                                                new DoseValue(row.DQPvalue, dvhStat.MaxDose.Unit),
                                                                row.OutputUnit == IOUnit.Relative ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3);
                        oText += volumeValue.ToString();
                    }
                    else if (row.DQPtype == DQPtype.DoseComplement) // calculate DoseComplement.
                    {
                        double subVolume = 0.0;
                        if (row.InputUnit == IOUnit.Relative)
                        {
                            subVolume = targetStructure.Volume - targetStructure.Volume * (row.DQPvalue * 0.01);
                            subVolume = (subVolume / targetStructure.Volume * 100);
                        }
                        else
                        {
                            subVolume = targetStructure.Volume - row.DQPvalue;
                        }
                        DoseValue doseValue = ps.GetDoseAtVolume(targetStructure, subVolume,
                                                                 row.InputUnit == IOUnit.Relative ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3,
                                                                 row.OutputUnit == IOUnit.Relative ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute);
                        oText += doseValue.Dose.ToString();
                    }
                    else if (row.DQPtype == DQPtype.ComplementVolume) // calculate ComplementVolume.
                    {
                        double volumeValue = ps.GetVolumeAtDose(targetStructure,
                                                                row.InputUnit == IOUnit.Relative ?
                                                                new DoseValue(ps.TotalDose.Dose * (row.DQPvalue * 0.01), dvhStat.MaxDose.Unit) :
                                                                new DoseValue(row.DQPvalue, dvhStat.MaxDose.Unit),
                                                                VolumePresentation.AbsoluteCm3);
                        double CV = targetStructure.Volume - volumeValue;
                        if (row.OutputUnit == IOUnit.Relative)
                        {
                            CV = (CV / targetStructure.Volume * 100);
                        }
                        oText += CV.ToString();
                    }
                    else
                    {
                        oText += "DQP type not found";
                    }
                    oText += "\t";
                }
            }
            return(oText);
        }
예제 #5
0
 public OrientationChecks(PlanSetup plan) : base(plan)
 {
 }
예제 #6
0
 // Returns the unweighted metrics of a beam's apertures
 private double[] CalculateForBeamPerAperture(Patient patient, PlanSetup plan, Beam beam)
 {
     return(CalculatePerAperture(CreateApertures(patient, plan, beam)));
 }
예제 #7
0
 public void Nothing(PlanSetup plan)
 {
 }
예제 #8
0
 public BolusChecks(PlanSetup plan) : base(plan)
 {
 }
예제 #9
0
        protected override void RunTest(PlanSetup plan)
        {
            DisplayName     = "Bolus";
            Result          = "";
            ResultDetails   = "";
            TestExplanation = "Checks that each field has a linked bolus if a bolus exists";

            string bolus            = "";
            bool   containsBolus    = false;
            bool   containsMultiple = false;
            string resultDetailsMultiPerFieldLine = "";
            string resultDetailsMultiPerPlanLine  = "";

            //Check to see if plan contains a bolus
            foreach (Structure struc in plan.StructureSet.Structures)
            {
                if (struc.DicomType == "BOLUS")
                {
                    //if it's already found one bolus, then there are multiple
                    if (containsBolus)
                    {
                        containsMultiple = true;
                    }

                    containsBolus = true;
                }
            }

            //Check each field to make sure it has a bolus attached
            foreach (Beam field in plan.Beams)
            {
                if (!containsBolus)
                {
                    break;
                }
                if (!field.IsSetupField)
                {
                    //no bolus
                    if (field.Boluses.Count() == 0)
                    {
                        //Set up "no bolus linked" string
                        if (ResultDetails == "")
                        {
                            Result        = "Warning";
                            ResultDetails = "Some fields do not have a linked bolus: ";
                            DisplayColor  = ResultColorChoices.Warn;
                        }
                        ResultDetails += field.Id + ", ";
                    }
                    //more than 1 bolus
                    else if (field.Boluses.Count() > 1)
                    {
                        //set up "multiple boluses" string
                        if (resultDetailsMultiPerFieldLine == "")
                        {
                            Result = "Warning";
                            resultDetailsMultiPerFieldLine = "Some fields have more than one bolus linked: ";
                            DisplayColor = ResultColorChoices.Warn;
                        }
                        resultDetailsMultiPerFieldLine += field.Id + ", ";
                    }
                    //just one bolus
                    else
                    {
                        //if this is the first bolus found, save it
                        if (bolus == "")
                        {
                            bolus = field.Boluses.First().Id;
                        }
                        //if not make sure it's the same bolus used on other fields
                        else if (field.Boluses.First().Id != bolus)
                        {
                            //set up "multiple boluses" string
                            if (resultDetailsMultiPerPlanLine == "")
                            {
                                Result = "Warning";
                                resultDetailsMultiPerPlanLine = $"Multiple bolus structures linked in plan: {bolus}, ";
                                DisplayColor = ResultColorChoices.Warn;
                            }
                            resultDetailsMultiPerPlanLine += field.Boluses.First().Id + ", ";
                        }
                    }
                }
            }

            //no bolus in plan so it's good
            if (!containsBolus)
            {
                Result        = "";
                ResultDetails = "No bolus in structure set";
                DisplayColor  = ResultColorChoices.Pass;
            }
            //no issues found
            else if (Result == "")
            {
                Result        = "";
                ResultDetails = $"{bolus} attached to all fields";
                DisplayColor  = ResultColorChoices.Pass;
            }

            //clean up strings
            ResultDetails = ResultDetails.TrimEnd(' ');
            ResultDetails = ResultDetails.TrimEnd(',');
            resultDetailsMultiPerFieldLine = resultDetailsMultiPerFieldLine.TrimEnd(' ');
            resultDetailsMultiPerFieldLine = resultDetailsMultiPerFieldLine.TrimEnd(',');
            resultDetailsMultiPerPlanLine  = resultDetailsMultiPerPlanLine.TrimEnd(' ');
            resultDetailsMultiPerPlanLine  = resultDetailsMultiPerPlanLine.TrimEnd(',');
            if (resultDetailsMultiPerFieldLine != "")
            {
                ResultDetails += '\n' + resultDetailsMultiPerFieldLine;
            }
            if (resultDetailsMultiPerPlanLine != "")
            {
                ResultDetails += '\n' + resultDetailsMultiPerPlanLine;
            }
            ResultDetails = ResultDetails.TrimStart('\n');
            ResultDetails = ResultDetails.TrimStart('\n');

            //multiple boluses in structure set, so put a warning at the end
            if (containsMultiple)
            {
                Result         = "Warning";
                ResultDetails += "\nMultiple bolus structures in the structure set, please ensure that the correct one is used";
                DisplayColor   = ResultColorChoices.Warn;
            }
        }
 private static int GetFractions(PlanSetup planSetup)
 {
     return(planSetup.NumberOfFractions.Value);
 }
예제 #11
0
        /// <summary>
        /// Return image profiles through plan isocenter in primary axis direction
        /// </summary>
        /// <param name="plan">TPS.NET.Plan</param>
        /// <param name="profileLengthInmm"> length of the profiles in mm</param>
        /// <returns></returns>
        public static (ImageProfile, ImageProfile, ImageProfile) getImageProfilesThroughIsocenter(PlanSetup plan)
        {
            var image   = plan.StructureSet.Image;
            var dirVecs = new VVector[] {
                plan.StructureSet.Image.XDirection,
                plan.StructureSet.Image.YDirection,
                plan.StructureSet.Image.ZDirection
            };

            var steps = new double[] {
                plan.StructureSet.Image.XRes,
                plan.StructureSet.Image.YRes,
                plan.StructureSet.Image.ZRes
            };


            var planIso = plan.Beams.First().IsocenterPosition;
            var tmpRes  = new ImageProfile[3];

            //
            // Throws if plan does not have 'BODY'
            //
            var body = plan.StructureSet.Structures.Single(st => st.Id == "BODY");

            for (int ind = 0; ind < 3; ind++)
            {
                (var startPoint, var endPoint) = Helpers.GetStructureEntryAndExit(body, dirVecs[ind], planIso, steps[ind]);
                var samples = (int)Math.Ceiling((endPoint - startPoint).Length / steps[ind]);
                tmpRes[ind] = image.GetImageProfile(startPoint, endPoint, new double[samples]);
            }
            return(tmpRes[0], tmpRes[1], tmpRes[2]);
        }
 private static Structure GetStructure(PlanSetup planSetup, string structureId)
 {
     return(planSetup.StructureSet.Structures.First(s => s.Id == structureId));
 }
예제 #13
0
 public void OnPlanSetupChanged(PlanSetup ps)
 {
     PlanSetupChanged?.Invoke(ps);
 }
예제 #14
0
        public Tuple <List <CollisionCheckViewModel>, Model3DGroup> GetCollisionSummary(PlanningItemViewModel planningItem)
        {
            var waitWindowCollision = new WaitWindowCollision();

            waitWindowCollision.Show();

            var calculator           = new CollisionSummariesCalculator();
            var collimatorModelGroup = new Model3DGroup();
            var isoModelGroup        = new Model3DGroup();
            var modelGroup           = new Model3DGroup();

            upDir          = new Vector3D(0, -1, 0);
            lookDir        = new Vector3D(0, 0, 1);
            isoctr         = new Point3D(0, 0, 0); //just to initalize
            cameraPosition = new Point3D(0, 0, -3500);
            var CollisionSummaries = new List <CollisionCheckViewModel>();

            // Create some materials
            var redMaterial        = new DiffuseMaterial(new SolidColorBrush(Colors.Red));
            var darkblueMaterial   = new DiffuseMaterial(new SolidColorBrush(Colors.DarkBlue));
            var collimatorMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.Green));

            Structure      bodyStruct;
            var            iso3DMesh = calculator.CalculateIsoMesh(isoctr);
            MeshGeometry3D bodyMesh  = null;
            MeshGeometry3D couchMesh = null;

            if (planningItem.PlanningItemObject is PlanSetup)
            {
                PlanSetup planSetup = (PlanSetup)planningItem.PlanningItemObject;
                bodyStruct = planSetup.StructureSet.Structures.Where(x => x.Id.Contains("BODY")).First();
                bodyMesh   = bodyStruct.MeshGeometry;
                foreach (Structure structure in planSetup.StructureSet.Structures)
                {
                    if (structure.StructureCodeInfos.FirstOrDefault().Code != null)
                    {
                        if (structure.StructureCodeInfos.FirstOrDefault().Code == "Support")
                        {
                            Structure couchStruct = structure;
                            couchMesh = couchStruct.MeshGeometry;
                        }
                    }
                }
                foreach (Beam beam in planSetup.Beams)
                {
                    isoctr    = calculator.GetIsocenter(beam);
                    iso3DMesh = calculator.CalculateIsoMesh(calculator.GetIsocenter(beam));
                    bool view = true;
                    if (planSetup.TreatmentOrientation.ToString() == "HeadFirstProne")
                    {
                        upDir = new Vector3D(0, 1, 0);
                    }
                    bool isVMAT     = false;
                    bool isStatic   = false;
                    bool isElectron = false;
                    bool isSRSArc   = false;
                    collimatorMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.Green));
                    if (beam.IsSetupField == true)
                    {
                        continue;
                    }
                    if (beam.Name.Contains("Subfield 2") || beam.Name.Contains("Subfield 3"))
                    {
                        continue;
                    }
                    if (beam.EnergyModeDisplayName.Contains("E"))
                    {
                        isElectron = true;
                    }
                    if (beam.EnergyModeDisplayName.Contains("SRS"))
                    {
                        isSRSArc = true;
                    }
                    if (beam.MLCPlanType.ToString() == "VMAT")
                    {
                        isVMAT             = true;
                        collimatorMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.GreenYellow));
                    }
                    if (beam.Technique.ToString().Contains("STATIC"))
                    {
                        isStatic           = true;
                        collimatorMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.DarkGreen));
                    }

                    foreach (Structure structure in planSetup.StructureSet.Structures)
                    {
                        if (structure.Id.Contains("CouchSurface") == true)
                        {
                            Structure couchStruct = planSetup.StructureSet.Structures.Where(x => x.Id.Contains("CouchSurface")).First();
                            couchMesh = couchStruct.MeshGeometry;
                        }
                    }
                    MeshGeometry3D collimatorMesh        = calculator.CalculateCollimatorMesh(planSetup, beam, isoctr, isVMAT, isStatic, isElectron, isSRSArc);
                    string         shortestDistanceBody  = "2000000";
                    string         shortestDistanceTable = "2000000";
                    string         status = "Clear";
                    shortestDistanceBody = calculator.ShortestDistance(collimatorMesh, bodyMesh);
                    if (couchMesh != null)
                    {
                        shortestDistanceTable = calculator.ShortestDistance(collimatorMesh, couchMesh);
                    }
                    else
                    {
                        shortestDistanceTable = " - ";
                        status = " - ";
                    }
                    Console.WriteLine(beam.Id + " - gantry to body is " + shortestDistanceBody + " cm");
                    Console.WriteLine(beam.Id + " - gantry to table is " + shortestDistanceTable + " cm");
                    if (shortestDistanceTable != " - ")
                    {
                        if ((Convert.ToDouble(shortestDistanceBody) < 3.0) || (Convert.ToDouble(shortestDistanceTable) < 3.0))
                        {
                            collimatorMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.Red));
                            status             = "Collision";
                        }
                    }
                    collimatorModelGroup.Children.Add(new GeometryModel3D {
                        Geometry = collimatorMesh, Material = collimatorMaterial, BackMaterial = darkblueMaterial
                    });
                    isoModelGroup.Children.Add(new GeometryModel3D {
                        Geometry = iso3DMesh, Material = redMaterial, BackMaterial = redMaterial
                    });
                    var collisionSummary = calculator.GetFieldCollisionSummary(beam, view, shortestDistanceBody, shortestDistanceTable, status);
                    CollisionSummaries.Add(collisionSummary);
                }
            }
            modelGroup = CreateModel(bodyMesh, couchMesh, isoModelGroup, collimatorModelGroup, collimatorMaterial);
            waitWindowCollision.Close();
            return(Tuple.Create(CollisionSummaries, modelGroup));
        }
예제 #15
0
 // Returns the complexity metric of a beam, calculated as
 // the weighted sum of the individual metrics for each control point
 public double CalculateForBeam(Patient patient, PlanSetup plan, Beam beam)
 {
     return(WeightedSum(GetWeights(beam), GetMetrics(patient, plan, beam)));
 }
예제 #16
0
 // Returns the weighted metrics of a beam's control points
 public double[] CalculatePerControlPointWeighted(
     Patient patient, PlanSetup plan, Beam beam)
 {
     return(WeightedValues(GetWeights(beam), GetMetrics(patient, plan, beam)));
 }
예제 #17
0
 // Returns the unweighted metrics of a beam's control points
 protected virtual double[] GetMetrics(Patient patient, PlanSetup plan, Beam beam)
 {
     return(CalculateForBeamPerAperture(patient, plan, beam));
 }
예제 #18
0
 // Returns the unweighted metrics of a beam's control points
 public double[] CalculatePerControlPointUnweighted(
     Patient patient, PlanSetup plan, Beam beam)
 {
     return(GetMetrics(patient, plan, beam));
 }
예제 #19
0
 // Returns the apertures created from a beam
 private IEnumerable <Aperture> CreateApertures(Patient patient, PlanSetup plan, Beam beam)
 {
     return(new AperturesFromBeamCreator().Create(patient, plan, beam));
 }
예제 #20
0
 // Returns the complexity metric of a plan, calculated as
 // the weighted sum of the individual metrics for each beam
 public double CalculateForPlan(Patient patient, PlanSetup plan)
 {
     return(WeightedSum(GetWeights(plan), GetMetrics(patient, plan)));
 }
        /// <summary>
        /// ReportOnePlan
        /// </summary>
        /// <param name="patient"></param>
        /// <param name="ps"></param>
        /// <param name="reportFile"></param>
        static void ReportOnePlan(Patient patient, PlanSetup ps, StreamWriter reportFile)
        {
            // Change type of presentation for dose value to absolute.
            ps.DoseValuePresentation = DoseValuePresentation.Absolute;

            // Initialize output text
            string msg = "";

            msg += patient.Id + "\t";   // Add patient ID to output text.
            msg += ps.Course.Id + "\t"; // Add course ID to output text.
            msg += ps.Id + "\t";        // Add plan ID to output text.


            // TODO : Add here the code /////////////////////////////////////////////////////////////

            // Get plan information. ////////////////////////////////////////////////////////////////
            // Get plan normalization method.
            msg += ps.PlanNormalizationMethod + "\t";

            // Get calculation model & options.
            int countFieldX = 0;
            int countFieldE = 0;

            foreach (var b in ps.Beams)
            {
                if (!b.IsSetupField)
                {
                    if (b.EnergyModeDisplayName.IndexOf("X") >= 0)
                    {
                        countFieldX++;
                    }
                    if (b.EnergyModeDisplayName.IndexOf("E") >= 0)
                    {
                        countFieldE++;
                    }
                }
            }

            string CalculationModel = "";

            if (countFieldX > 0)
            {
                CalculationModel += "(" + ps.PhotonCalculationModel.ToString();
                foreach (KeyValuePair <string, string> kvp in ps.PhotonCalculationOptions)
                {
                    CalculationModel += "/" + kvp.Key + ":" + kvp.Value;
                }
                CalculationModel += ")";
            }
            if (countFieldE > 0)
            {
                CalculationModel += "(" + ps.ElectronCalculationModel.ToString();
                foreach (KeyValuePair <string, string> kvp in ps.ElectronCalculationOptions)
                {
                    CalculationModel += "/" + kvp.Key + ":" + kvp.Value;
                }
                CalculationModel += ")";
            }
            msg += CalculationModel + "\t";


            // Get field information. ////////////////////////////////////////////////////////////////
            var energy_List = new List <string>();
            var mu_List     = new List <string>();
            int nBeam       = 0;

            // Iterate over all beams
            foreach (var b in ps.Beams)
            {
                if (!b.IsSetupField)                                        //exclude SetupField.
                {
                    energy_List.Add(b.EnergyModeDisplayName);               // beam energy.
                    mu_List.Add(string.Format("{0:f1}", b.Meterset.Value)); // Get MU at 1st decimal place .
                    nBeam++;                                                //count number of beams.
                }
            }
            msg += "#beam:" + nBeam.ToString() + "\t";               //add number of beams to output text.
            msg += "Energy:" + string.Join("/", energy_List) + "\t"; // Combine all values with "/".
            msg += "MU:" + string.Join("/", mu_List) + "\t";         // Combine all values with "/".
            ///////////////////////////////////////////////////////////////////////////////////////////

            // Get DVH statistic information. ///////////////////////////////////////////////////////////////////

            // calculate Max/Mean/Min dose.
            // Initialize variables.
            DVHData   dvhStat         = null;
            Structure targetStructure = null;

            string[] s_targetIds =
            {
                "ITV",     "PTV",  "PTV-PROST", "PTV-SV", "GTV",   "CTV",
                "BLADDER", "CORD", "BRAINSTEM", "LUNG",   "LIVER", "KIDNEY","BREAST","OPTIC", "PAROTID", "SPINE", "RECTUM", "BOWEL", "BRAIN"
            };

            // Iterate over all structures.
            foreach (var structure in ps.StructureSet.Structures)
            {
                if (ps.Dose != null && ps.StructureSet != null)
                {
                    targetStructure = FindStructure(structure, s_targetIds);
                    if (targetStructure != null)
                    {
                        dvhStat = ps.GetDVHCumulativeData(targetStructure, DoseValuePresentation.Absolute, VolumePresentation.AbsoluteCm3, 0.1);
                        if (dvhStat != null)
                        {
                            string doseUnitString = dvhStat.MaxDose.UnitAsString;
                            msg += targetStructure.Id + "[Max/Mean/Min," + doseUnitString + "]:" +
                                   dvhStat.MaxDose.Dose.ToString() + "/" +
                                   dvhStat.MeanDose.Dose.ToString() + "/" +
                                   dvhStat.MinDose.Dose.ToString() + "\t";
                        }
                    }
                }
            }


            // Calculate Dose Quality Parameters (VolumeAtDose,DoseAtVolume,DoseComplement,ComplementVolume).
            var DQPList = new Collection <DQP>();

            // define parameters
            DQPList.Add(new DQP
            {
                structureName = "Prostate",
                DQPtype       = DQPtype.Dose,
                DQPvalue      = 95.0,
                InputUnit     = IOUnit.Relative,
                OutputUnit    = IOUnit.Absolute
            });
            DQPList.Add(new DQP
            {
                structureName = "Rectum",
                DQPtype       = DQPtype.Volume,
                DQPvalue      = 70,
                InputUnit     = IOUnit.Relative,
                OutputUnit    = IOUnit.Relative
            });
            // calculate DQP.
            msg += calcDQP(ps, DQPList);
            ///////////////////////////////////////////////////////////////////////////////////////////

            reportFile.WriteLine(msg);
        }
예제 #22
0
 // Returns the weights of a plan's beams;
 // by default, the weights are the meterset values per beam
 protected virtual double[] GetWeights(PlanSetup plan)
 {
     return(GetMetersets(plan));
 }
예제 #23
0
        public void Execute(ScriptContext context /*, System.Windows.Window window*/)
        {
            PlanSetup    planSetup = context.PlanSetup;
            PlanSum      psum      = context.PlanSumsInScope.FirstOrDefault();
            StructureSet structureSet;
            bool         isPlanSum = false;
            string       psumName  = null;

            // If there's no selected plan with calculated dose throw an exception
            if (planSetup == null && psum == null)
            {
                throw new ApplicationException("Please open a calculated plan/planSum before using this script.");
            }
            else if (planSetup != null)
            {
                if (planSetup.Dose == null)
                {
                    throw new ApplicationException("Please open a calculated plan before using this script.");
                }

                structureSet = planSetup.StructureSet;
            }
            else
            {
                if (psum.Dose == null)
                {
                    throw new ApplicationException("Please open a calculated plansum before using this script.");
                }

                isPlanSum = true;

                if (context.PlanSumsInScope.Count() > 1)
                {
                    List <String> psumList = new List <String>();
                    foreach (var sum in context.PlanSumsInScope)
                    {
                        foreach (var course in context.Patient.Courses)
                        {
                            if (course.PlanSums.FirstOrDefault(ps => ps.Id == sum.Id) != null)
                            {
                                if (sum.Equals(course.PlanSums.First(ps => ps.Id == sum.Id)))
                                {
                                    psumList.Add(String.Format("{0}/{1}", course.Id, sum.Id));
                                }
                            }
                        }
                        // v13以降はforeach (var course ~)の代わりにこれだけでいける
                        // psumList.Add(String.Format("{0}/{1}", sum.Course.Id, sum.Id));
                    }
                    psumName     = Form5.ShowMiniForm(psumList);
                    structureSet = context.Patient.Courses.First(c => c.Id == psumName.Split('/')[0]).PlanSums.First(ps => ps.Id == psumName.Split('/')[1]).StructureSet;
                }
                else
                {
                    structureSet = psum.StructureSet;
                    foreach (var course in context.Patient.Courses)
                    {
                        if (course.PlanSums.FirstOrDefault(ps => ps.Id == psum.Id) != null)
                        {
                            if (psum.Equals(course.PlanSums.First(ps => ps.Id == psum.Id)))
                            {
                                psumName = course.Id + '/' + psum.Id;
                            }
                        }
                    }
                    // v13以降は foreach(var course ~)の代わりにこれでいける
                    // psumName = psum.Course.Id + '/' + psum.Id;
                }
            }

            // Retrieve StructureSet
            if (structureSet == null)
            {
                throw new ApplicationException("The selected plan does not reference a StructureSet.");
            }

            Form1 window;

            if (!isPlanSum)
            {
                window = new Form1(context);
            }
            else
            {
                window = new Form1(context, true, psumName);
            }
            window.ShowDialog();
        }
예제 #24
0
 // Returns the total metersets of a plan's beams
 protected double[] GetMetersets(PlanSetup plan)
 {
     return((from beam in plan.Beams
             where !beam.IsSetupField
             select beam.Meterset.Value).ToArray());
 }
예제 #25
0
 public JawTrackingChecks(PlanSetup plan) : base(plan)
 {
 }
예제 #26
0
 // Returns the unweighted metrics of a plan's beams
 private double[] GetMetrics(Patient patient, PlanSetup plan)
 {
     return(CalculateForPlanPerBeam(patient, plan));
 }
        /// <summary>
        /// The PlanQualityMetrics script generates a report of plan quality, using evaluation metrics defined in UserDefinedMetrics.cs.
        /// The script first computes metrics for all found structures, evaluates whether the metrics are in or out of tolerance and
        /// generates an xml report of that information and saves it to %temp\<patientid>\PQMReport-<planid>.xml.  The XML report is
        /// then transformed into an HTML report with an XSLT stylesheet, using either the gen_report.xsl stylesheet for Plans, or
        /// the gen_report_plansum.xsl stylesheet for PlanSums.  The HTML report is then shown to the user.
        ///
        /// Metric evaluation and XML & HTML report generation is driven by PQMReporter.
        ///
        // Many of these metrics used in this script come from QUANTEC data. See
        // http://en.wikibooks.org/wiki/Radiation_Oncology/Toxicity/QUANTEC
        //
        /// Add your own evaluators and change structure ids to match those used in your clinic in UserDefinedMetrics.cs.
        /// If new evaluators are added, you need to also add a call to use those evaluators in
        /// PQMReporter.WriteDoseStatisticsXML_Prostate2GyOrLess, or WriteDoseStatisticsXML_HeadAndNeck2GyOrLess.
        ///
        /// This script currently supports metric reporting for normally fractionated Prostate and Head and Neck.
        /// </summary>
        /// <param name="context"></param>
        public void Execute(ScriptContext context /*, System.Windows.Window window*/)
        {
            string temp           = System.Environment.GetEnvironmentVariable("TEMP");
            string eclipseVersion = System.Reflection.Assembly.GetAssembly
                                        (typeof(VMS.TPS.Common.Model.API.Application)).GetName().Version.ToString();
            string scriptVersion = "1.0.10";

            if (context.PlanSumsInScope.Count() > 0)
            {
                foreach (PlanSum plansum in context.PlanSumsInScope)
                {
                    if (plansum.StructureSet == null)
                    {
                        MessageBox.Show("Plansum has no structure set.",
                                        "Varian Developer", MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }
                    if (plansum.Dose == null)
                    {
                        MessageBox.Show("Loaded plansum has no dose: Please select an external beam plan or plansum with dose calculated that you would like evaluate.",
                                        "Varian Developer", MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }
                    // Load the plansum stylesheet into memory, transform report XML into HTML, show that to the user.
                    // gen_report_plansum.xsl is automatically compiled in when the build action for the VS project is set to
                    // "Embedded Resource".  See online help for Build Action.  Read the embedded stylesheet file from the DLL.
                    Stream    stylesheet             = Assembly.GetExecutingAssembly().GetManifestResourceStream("PlanQualityMetrics.gen_report_plansum.xsl");
                    XmlReader stylesheetReader       = XmlReader.Create(new StreamReader(stylesheet));
                    VMS.TPS.PlanSumReporter reporter = new PlanSumReporter(temp, context.CurrentUser.Id, eclipseVersion, scriptVersion, stylesheetReader);
                    Patient patient = context.Patient;

                    string xmlReportPath;
                    string htmlReportPath = reporter.generateReport(patient, plansum.StructureSet, plansum, out xmlReportPath);

                    // 'Start' generated HTML file to launch browser window
                    System.Diagnostics.Process.Start(htmlReportPath);
                    // Sleep for a few seconds to let internet browser window to start
                    System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
                }
            }
            else
            {
                if (context.Patient == null || context.PlanSetup == null)
                {
                    MessageBox.Show("Please select the external beam plan that you would like evaluate.",
                                    "Varian Developer", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                if (context.PlanSetup.StructureSet == null)
                {
                    MessageBox.Show("Loaded plan does not have a structure set.",
                                    "Varian Developer", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                if (context.PlanSetup.Dose == null)
                {
                    MessageBox.Show("Loaded plan has no dose: Please select an external beam plan with dose calculated that you would like evaluate.",
                                    "Varian Developer", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                // gen_report.xsl is automatically compiled in when the build action for the VS project is set to
                // "Embedded Resource".  See online help for Build Action.  Read the embedded stylesheet file from the DLL.
                Stream    stylesheet               = Assembly.GetExecutingAssembly().GetManifestResourceStream("PlanQualityMetrics.gen_report.xsl");
                XmlReader stylesheetReader         = XmlReader.Create(new StreamReader(stylesheet));
                VMS.TPS.PlanSetupReporter reporter = new PlanSetupReporter(temp, context.CurrentUser.Id, eclipseVersion, scriptVersion, stylesheetReader);
                Patient      patient               = context.Patient;
                PlanSetup    plan = context.PlanSetup;
                StructureSet ss   = context.StructureSet;

                string xmlReportPath;
                string htmlReportPath = reporter.generateReport(patient, plan.StructureSet, plan, out xmlReportPath);

                // 'Start' generated HTML file to launch browser window
                System.Diagnostics.Process.Start(htmlReportPath);
                // Sleep for a few seconds to let internet browser window to start
                System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
            }
        }
예제 #28
0
 // Returns the unweighted metrics of a plan's non-setup beams
 private double[] CalculateForPlanPerBeam(Patient patient, PlanSetup plan)
 {
     return((from beam in plan.Beams
             where !beam.IsSetupField
             select CalculateForBeam(patient, plan, beam)).ToArray());
 }
예제 #29
0
 private Structure GetStructure(PlanSetup plan, string structureId) =>
 plan?.StructureSet?.Structures?.FirstOrDefault(x => x.Id == structureId);
예제 #30
0
        public void GetPQMSummaries(ConstraintViewModel constraintPath, PlanningItemViewModel planningItem, Patient patient)
        {
            PqmSummaries = new ObservableCollection <PQMSummaryViewModel>();
            StructureSet structureSet = planningItem.PlanningItemStructureSet;
            Structure    evalStructure;
            ObservableCollection <PQMSummaryViewModel> pqmSummaries       = new ObservableCollection <PQMSummaryViewModel>();
            ObservableCollection <StructureViewModel>  foundStructureList = new ObservableCollection <StructureViewModel>();
            var calculator = new PQMSummaryCalculator();

            Objectives = calculator.GetObjectives(constraintPath);
            if (planningItem.PlanningItemObject is PlanSum)
            {
                var     waitWindowPQM = new WaitWindowPQM();
                PlanSum plansum       = (PlanSum)planningItem.PlanningItemObject;
                if (plansum.IsDoseValid() == true)
                {
                    waitWindowPQM.Show();
                    foreach (PQMSummaryViewModel objective in Objectives)
                    {
                        evalStructure = calculator.FindStructureFromAlias(structureSet, objective.TemplateId, objective.TemplateAliases, objective.TemplateCodes);
                        if (evalStructure != null)
                        {
                            var evalStructureVM = new StructureViewModel(evalStructure);
                            var obj             = calculator.GetObjectiveProperties(objective, planningItem, structureSet, evalStructureVM);
                            PqmSummaries.Add(obj);
                            NotifyPropertyChanged("Structure");
                        }
                    }
                    waitWindowPQM.Close();
                }
            }
            if (planningItem.PlanningItemObject is PlanSetup) //is plansetup
            {
                var waitWindowPQM = new WaitWindowPQM();

                PlanSetup planSetup = (PlanSetup)planningItem.PlanningItemObject;
                if (planSetup.IsDoseValid() == true)
                {
                    waitWindowPQM.Show();
                    foreach (PQMSummaryViewModel objective in Objectives)
                    {
                        evalStructure = calculator.FindStructureFromAlias(structureSet, objective.TemplateId, objective.TemplateAliases, objective.TemplateCodes);
                        if (evalStructure != null)
                        {
                            if (evalStructure.StructureCodeInfos.FirstOrDefault().Code != null)
                            {
                                if (evalStructure.StructureCodeInfos.FirstOrDefault().Code.Contains("PTV") == true)
                                {
                                    foreach (Structure s in structureSet.Structures)
                                    {
                                        if (s.Id == planSetup.TargetVolumeID)
                                        {
                                            evalStructure = s;
                                        }
                                    }
                                }
                            }
                            var evalStructureVM = new StructureViewModel(evalStructure);
                            var obj             = calculator.GetObjectiveProperties(objective, planningItem, structureSet, evalStructureVM);
                            PqmSummaries.Add(obj);
                            NotifyPropertyChanged("Structure");
                        }
                    }
                    waitWindowPQM.Close();
                }
            }
        }