Esempio n. 1
0
        /// <summary>
        /// Converts the units of a DoseValue between cGy and Gy
        /// </summary>
        /// <param name="dose">Dose</param>
        /// <param name="units">Requested units</param>
        /// <returns>Dose converted to the new units</returns>
        private DoseValue ConvertDoseUnits(DoseValue dose, DoseValue.DoseUnit units)
        {
            if (dose.Dose == 0 || dose.Unit == DoseValue.DoseUnit.Unknown)
            {
                return(dose);
            }
            if (dose.Unit != DoseValue.DoseUnit.cGy && dose.Unit != DoseValue.DoseUnit.Gy)
            {
                MessageBox.Show("Only units of cGy and Gy can be converted\nVariable: dose.Unit = " + dose.Unit.ToString(), "Invalid Dose Unit", MessageBoxButton.OK, MessageBoxImage.Error);
                throw new FormatException("Invalid dose unit");
            }
            else if (units != DoseValue.DoseUnit.cGy && units != DoseValue.DoseUnit.Gy)
            {
                MessageBox.Show("Can only convert to units of cGy and Gy\nVariable: units = " + units.ToString(), "Invalid Dose Unit", MessageBoxButton.OK, MessageBoxImage.Error);
                throw new FormatException("Invalid dose unit");
            }

            if (dose.Unit == units)
            {
                return(dose);
            }
            else if (dose.Unit == DoseValue.DoseUnit.cGy)
            {
                return(new DoseValue(dose.Dose / 100.0, DoseValue.DoseUnit.Gy));
            }
            else
            {
                return(new DoseValue(dose.Dose * 100.0, DoseValue.DoseUnit.cGy));
            }
        }
Esempio n. 2
0
        public static string GetVolumeAtDose(StructureSet structureSet, PlanningItem planningItem, Structure evalStructure, MatchCollection testMatch, Group evalunit)
        {
            //check for sufficient sampling and dose coverage
            DVHData dvh = planningItem.GetDVHCumulativeData(evalStructure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.1);

            //MessageBox.Show(evalStructure.Id + "- Eval unit: " + evalunit.Value.ToString() + "Achieved unit: " + dvAchieved.UnitAsString + " - Sampling coverage: " + dvh.SamplingCoverage.ToString() + " Coverage: " + dvh.Coverage.ToString());
            if ((dvh.SamplingCoverage < 0.9) || (dvh.Coverage < 0.9))
            {
                return("Unable to calculate - insufficient dose or sampling coverage");
            }
            Group eval = testMatch[0].Groups["evalpt"];
            Group unit = testMatch[0].Groups["unit"];

            DoseValue.DoseUnit du = (unit.Value.CompareTo("%") == 0) ? DoseValue.DoseUnit.Percent :
                                    (unit.Value.CompareTo("cGy") == 0) ? DoseValue.DoseUnit.cGy : DoseValue.DoseUnit.Unknown;
            VolumePresentation    vp             = (unit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
            DoseValue             dv             = new DoseValue(double.Parse(eval.Value), du);
            double                volume         = double.Parse(eval.Value);
            VolumePresentation    vpFinal        = (evalunit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
            DoseValuePresentation dvpFinal       = (evalunit.Value.CompareTo("%") == 0) ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
            double                volumeAchieved = planningItem.GetVolumeAtDose(evalStructure, dv, vpFinal);

            return(string.Format("{0:0.00} {1}", volumeAchieved, evalunit.Value));   // todo: better formatting based on VolumePresentation
//#if false
//            string message = string.Format("{0} - Dose unit = {1}, Volume Presentation = {2}, vpFinal = {3}, dvpFinal ={4}",
//               objective.DVHObjective, du.ToString(), vp.ToString(), vpFinal.ToString(), dvpFinal.ToString());
//           MessageBox.Show(message);
//#endif
        }
 public static string GetCoveredVolumeAtDose(StructureSet structureSet, PlanningItemViewModel planningItem, StructureViewModel evalStructure, MatchCollection testMatch, Group evalunit)
 {
     try
     {
         var structure = structureSet.Structures.FirstOrDefault(x => x.Id == evalStructure.StructureName);
         //check for sufficient sampling and dose coverage
         DVHData dvh = planningItem.PlanningItemObject.GetDVHCumulativeData(structure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.1);
         if ((dvh.SamplingCoverage < 0.9) || (dvh.Coverage < 0.9))
         {
             return("Unable to calculate - insufficient dose or sampling coverage");
         }
         Group eval            = testMatch[0].Groups["evalpt"];
         Group unit            = testMatch[0].Groups["unit"];
         DoseValue.DoseUnit du = (unit.Value.CompareTo("%") == 0) ? DoseValue.DoseUnit.Percent :
                                 (unit.Value.CompareTo("cGy") == 0) ? DoseValue.DoseUnit.cGy : DoseValue.DoseUnit.Unknown;
         VolumePresentation    vp             = (unit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
         DoseValue             dv             = new DoseValue(double.Parse(eval.Value), du);
         double                volume         = double.Parse(eval.Value);
         VolumePresentation    vpFinal        = (evalunit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
         DoseValuePresentation dvpFinal       = (evalunit.Value.CompareTo("%") == 0) ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
         double                volumeAchieved = planningItem.PlanningItemObject.GetVolumeAtDose(structure, dv, vpFinal);
         double                organVolume    = Convert.ToDouble(evalStructure.VolumeValue);
         double                coveredVolume  = organVolume - volumeAchieved;
         return(string.Format("{0:0.00} {1}", coveredVolume, evalunit.Value));   // todo: better formatting based on VolumePresentation
     }
     catch (NullReferenceException)
     {
         return("Unable to calculate - DVH is not valid");
     }
 }
Esempio n. 4
0
        public static DoseValue CalculateMeanDose(PlanSetup plan, Structure structure)
        {
            Dose dose = plan.Dose;

            if (dose == null)
            {
                return(new DoseValue(Double.NaN, DoseValue.DoseUnit.Unknown));
            }

            plan.DoseValuePresentation = DoseValuePresentation.Absolute;

            double sum   = 0.0;
            int    count = 0;

            double xres = 2.5;
            double yres = 2.5;
            double zres = 2.5;

            int xcount = (int)((dose.XRes * dose.XSize) / xres);

            System.Collections.BitArray segmentStride = new System.Collections.BitArray(xcount);
            double[]           doseArray = new double[xcount];
            DoseValue.DoseUnit doseUnit  = dose.DoseMax3D.Unit;

            for (double z = 0; z < dose.ZSize * dose.ZRes; z += zres)
            {
                for (double y = 0; y < dose.YSize * dose.YRes; y += yres)
                {
                    VVector start = dose.Origin +
                                    dose.YDirection * y +
                                    dose.ZDirection * z;
                    VVector end = start + dose.XDirection * dose.XRes * dose.XSize;

                    SegmentProfile segmentProfile = structure.GetSegmentProfile(start, end, segmentStride);
                    DoseProfile    doseProfile    = null;

                    for (int i = 0; i < segmentProfile.Count; i++)
                    {
                        if (segmentStride[i])
                        {
                            if (doseProfile == null)
                            {
                                doseProfile = dose.GetDoseProfile(start, end, doseArray);
                            }

                            double doseValue = doseProfile[i].Value;
                            if (!Double.IsNaN(doseValue))
                            {
                                sum += doseProfile[i].Value;
                                count++;
                            }
                        }
                    }
                    doseProfile = null;
                }
            }
            double mean = sum / ((double)count);

            return(new DoseValue(mean, doseUnit));
        }
Esempio n. 5
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                        JsonSerializer serializer)
        {
            // Load the JSON for the Result into a JObject
            var jo = JObject.Load(reader);

            // Read the properties which will be used as constructor parameters
            var value   = (double)jo["Dose"];
            var unitVal = jo["Unit"].Value <string>();

            DoseValue.DoseUnit unit = DoseValue.DoseUnit.Unknown;
            switch (unitVal)
            {
            case "%": unit = DoseValue.DoseUnit.Percent; break;

            case "cGy": unit = DoseValue.DoseUnit.cGy; break;

            case "Gy": unit = DoseValue.DoseUnit.Gy; break;
            }

            // Construct the Result object using the non-default constructor
            var dv = new DoseValue(value, unit);

            // Return the result
            return(dv);
        }
Esempio n. 6
0
 internal static dynamic ConstructDoseValue(double value, DoseValue.DoseUnit unit)
 {
     if (ConstructDoseValueFunc1 == null)
     {
         throw new NullReferenceException(
                   "The function ConstructDoseValueFunc1 has not been initialized. Try calling FacadeInitializer.Initialize() in ESAPIX.VMS before calling this method.");
     }
     return(XContext.Instance.CurrentContext.GetValue(sc => { return ConstructDoseValueFunc1(value, unit); }));
 }
Esempio n. 7
0
        public static double GetVolumeAtDose(this PlanningItem pitem, Structure structure, DoseValue dose, VolumePresentation requestedVolumePresentation, DoseValue?planSumRx = null)
        {
            //Get units that the dose is represented in within Eclipse but can't call that function if it's requesting % for a plan sum, so if that's the case it must be set manually
            DoseValue.DoseUnit systemUnits = DoseValue.DoseUnit.Percent;
            if (dose.Unit != DoseValue.DoseUnit.Percent)
            {
                systemUnits = pitem.GetDVHCumulativeData(structure, dose.Unit == DoseValue.DoseUnit.Percent ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute, VolumePresentation.Relative, 1).MeanDose.Unit;
            }

            //When calling GetVolumeAtDose, the dose must be in the same units as the system is set to

            //If "dose" is in %, they should be equal, but we will convert them if they are not equal to each other
            if (dose.Unit != systemUnits)
            {
                if (dose.Unit == DoseValue.DoseUnit.cGy && systemUnits == DoseValue.DoseUnit.Gy)
                {
                    dose = new DoseValue(dose.Dose / 100.0, DoseValue.DoseUnit.Gy);
                }
                else if (dose.Unit == DoseValue.DoseUnit.Gy && systemUnits == DoseValue.DoseUnit.cGy)
                {
                    dose = new DoseValue(dose.Dose * 100.0, DoseValue.DoseUnit.cGy);
                }
                else
                {
                    MessageBox.Show(String.Format("There was an error converting {0}, with units of {1} into the units used by Eclipse, {2}\n\nExpected values were cGy and Gy", dose.ToString(), dose.Unit.ToString(), systemUnits.ToString()), String.Format("Error during calculation of V{0}", dose.ToString()), MessageBoxButton.OK, MessageBoxImage.Warning);
                }
            }

            //Now functions can be called as normal
            if (pitem is PlanSetup)
            {
                return(((PlanSetup)pitem).GetVolumeAtDose(structure, dose, requestedVolumePresentation));
            }
            else
            {
                DVHData dvh = pitem.GetDVHCumulativeData(structure, DoseValuePresentation.Absolute, requestedVolumePresentation, 0.001);

                if (dose.Unit == DoseValue.DoseUnit.Percent)
                {
                    //MessageBox.Show(String.Format("Only absolute dose is supported for Plan Sums.  A prescription dose of {1} will be assumed to convert the V{0} for {2} into a percentage.", dosecGy.ToString(), planSumRx.ToString(), structure.Id), String.Format("Error during calculation of V{0}", dosecGy.ToString()), MessageBoxButton.OK, MessageBoxImage.Warning);
                    return(DvhExtensions.VolumeAtDose(dvh, dose.Dose, planSumRx));
                }
                else
                {
                    return(DvhExtensions.VolumeAtDose(dvh, dose.Dose));
                }
            }
        }
Esempio n. 8
0
 /// <summary>
 ///     Converts the dose to the unit requested. It cannot convert from % to abs dose. Will return NaN if asked
 /// </summary>
 /// <param name="dv">the dose value to be converted</param>
 /// <param name="unit">the unit desired for the returned dose</param>
 /// <returns>the dose in the desired units</returns>
 public static double GetDose(this DoseValue dv, DoseValue.DoseUnit unit)
 {
     if (dv.Unit == unit)
     {
         return(dv.Dose);
     }
     if (dv.Unit == DoseValue.DoseUnit.cGy && unit == DoseValue.DoseUnit.Gy)
     {
         return(dv.Dose / 100);
     }
     if (dv.Unit == DoseValue.DoseUnit.Gy && unit == DoseValue.DoseUnit.cGy)
     {
         return(dv.Dose * 100);
     }
     return(double.NaN);
 }
Esempio n. 9
0
 public static string GetConformationNumber(StructureSet structureSet, PlanningItemViewModel planningItem, StructureViewModel evalStructure, MatchCollection testMatch, Group evalunit)
 {
     try
     {
         var       structure = structureSet.Structures.FirstOrDefault(x => x.Id == evalStructure.StructureName);
         DVHData   dvh       = planningItem.PlanningItemObject.GetDVHCumulativeData(structure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.1);
         DoseValue prescribedDose;
         double    planDoseDouble = 0;
         if ((dvh.SamplingCoverage < 0.9) || (dvh.Coverage < 0.9))
         {
             return("Unable to calculate - insufficient dose or sampling coverage");
         }
         if (planningItem.PlanningItemObject is PlanSum)
         {
             PlanSum planSum = (PlanSum)planningItem.PlanningItemObject;
             foreach (PlanSetup planSetup in planSum.PlanSetups)
             {
                 planDoseDouble += planSetup.TotalDose.Dose;
             }
         }
         if (planningItem.PlanningItemObject is PlanSetup)
         {
             PlanSetup planSetup = (PlanSetup)planningItem.PlanningItemObject;
             planDoseDouble = planSetup.TotalDose.Dose;
         }
         prescribedDose = new DoseValue(planDoseDouble, DoseValue.DoseUnit.cGy);
         Group eval            = testMatch[0].Groups["evalpt"];
         Group unit            = testMatch[0].Groups["unit"];
         DoseValue.DoseUnit du = (unit.Value.CompareTo("%") == 0) ? DoseValue.DoseUnit.Percent :
                                 (unit.Value.CompareTo("cGy") == 0) ? DoseValue.DoseUnit.cGy : DoseValue.DoseUnit.Unknown;
         var body = structureSet.Structures.Where(x => x.Id.Contains("BODY")).First();
         //VolumePresentation vpFinal = (evalunit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
         VolumePresentation    vpFinal         = VolumePresentation.AbsoluteCm3;
         DoseValuePresentation dvpFinal        = (evalunit.Value.CompareTo("%") == 0) ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
         DoseValue             dv              = new DoseValue(double.Parse(eval.Value) / 100 * prescribedDose.Dose, DoseValue.DoseUnit.cGy);
         double bodyWithPrescribedDoseVolume   = planningItem.PlanningItemObject.GetVolumeAtDose(body, prescribedDose, vpFinal);
         double targetWithPrescribedDoseVolume = planningItem.PlanningItemObject.GetVolumeAtDose(structure, dv, vpFinal);
         double targetVolume = Convert.ToDouble(evalStructure.VolumeValue);
         var    cn           = (targetWithPrescribedDoseVolume / targetVolume) * (targetWithPrescribedDoseVolume / bodyWithPrescribedDoseVolume);
         return(string.Format("{0:0.0}", cn));
     }
     catch (NullReferenceException)
     {
         return("Unable to calculate - DVH is not valid");
     }
 }
Esempio n. 10
0
        public static string GetDoseAtVolume(StructureSet structureSet, PlanningItemViewModel planningItem, StructureViewModel evalStructure, MatchCollection testMatch, Group evalunit)
        {
            //check for sufficient dose and sampling coverage
            DVHData dvh = planningItem.PlanningItemObject.GetDVHCumulativeData(evalStructure.Structure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.1);

            if (dvh != null)
            {
                if ((dvh.SamplingCoverage < 0.9) || (dvh.Coverage < 0.9))
                {
                    return("Unable to calculate - insufficient dose or sampling coverage");
                }
                Group eval            = testMatch[0].Groups["evalpt"];
                Group unit            = testMatch[0].Groups["unit"];
                DoseValue.DoseUnit du = (unit.Value.CompareTo("%") == 0) ? DoseValue.DoseUnit.Percent :
                                        (unit.Value.CompareTo("cGy") == 0) ? DoseValue.DoseUnit.cGy : DoseValue.DoseUnit.Unknown;
                VolumePresentation    vp         = (unit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
                DoseValue             dv         = new DoseValue(double.Parse(eval.Value), du);
                double                volume     = double.Parse(eval.Value);
                VolumePresentation    vpFinal    = (evalunit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
                DoseValuePresentation dvpFinal   = (evalunit.Value.CompareTo("%") == 0) ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
                DoseValue             dvAchieved = planningItem.PlanningItemObject.GetDoseAtVolume(evalStructure.Structure, volume, vp, dvpFinal);
                //checking dose output unit and adapting to template
                if (dvAchieved.UnitAsString.CompareTo(evalunit.Value.ToString()) != 0)
                {
                    if ((evalunit.Value.CompareTo("cGy") == 0) && (dvAchieved.Unit.CompareTo(DoseValue.DoseUnit.cGy) == 0))
                    {
                        dvAchieved = new DoseValue(dvAchieved.Dose / 100, DoseValue.DoseUnit.cGy);
                    }
                    else
                    {
                        return("Unable to calculate");
                    }
                }

                return(dvAchieved.ToString());
            }
            else
            {
                return("Unable to calculate - structure is empty");
            }
        }
Esempio n. 11
0
        public static string GetGradientIndex(StructureSet structureSet, PlanningItemViewModel planningItem, Structure evalStructure, MatchCollection testMatch, Group evalunit)
        {
            // we have Gradient Index pattern
            DVHData dvh = planningItem.PlanningItemObject.GetDVHCumulativeData(evalStructure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.1);

            if ((dvh.SamplingCoverage < 0.9) || (dvh.Coverage < 0.9))
            {
                return("Unable to calculate - insufficient dose or sampling coverage");
            }
            Group     eval = testMatch[0].Groups["evalpt"];
            Group     unit = testMatch[0].Groups["unit"];
            DoseValue prescribedDose;
            double    planDoseDouble = 0;

            DoseValue.DoseUnit du = (unit.Value.CompareTo("%") == 0) ? DoseValue.DoseUnit.Percent :
                                    (unit.Value.CompareTo("cGy") == 0) ? DoseValue.DoseUnit.cGy : DoseValue.DoseUnit.Unknown;
            if (planningItem.PlanningItemObject is PlanSum)
            {
                PlanSum planSum = (PlanSum)planningItem.PlanningItemObject;
                foreach (PlanSetup planSetup in planSum.PlanSetups)
                {
                    planDoseDouble += planSetup.TotalDose.Dose;
                }
            }
            if (planningItem.PlanningItemObject is PlanSetup)
            {
                PlanSetup planSetup = (PlanSetup)planningItem.PlanningItemObject;
                planDoseDouble = planSetup.TotalDose.Dose;
            }
            prescribedDose = new DoseValue(planDoseDouble, DoseValue.DoseUnit.cGy);
            //var body = structureSet.Structures.Where(x => x.Id.Contains("BODY")).First();
            VolumePresentation    vpFinal       = VolumePresentation.AbsoluteCm3;
            DoseValuePresentation dvpFinal      = (evalunit.Value.CompareTo("%") == 0) ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
            DoseValue             dv            = new DoseValue(double.Parse(eval.Value) / 100 * prescribedDose.Dose, DoseValue.DoseUnit.cGy);
            double bodyWithPrescribedDoseVolume = planningItem.PlanningItemObject.GetVolumeAtDose(evalStructure, prescribedDose, vpFinal);
            double bodyWithEvalDoseVolume       = planningItem.PlanningItemObject.GetVolumeAtDose(evalStructure, dv, vpFinal);
            var    gi = bodyWithEvalDoseVolume / bodyWithPrescribedDoseVolume;

            return(string.Format("{0:0.0}", gi));
        }
Esempio n. 12
0
        public static string GetVolumeAtDose(StructureSet structureSet, PlanningItemViewModel planningItem, StructureViewModel evalStructure, MatchCollection testMatch, Group evalunit)
        {
            try
            {
                var structure = structureSet.Structures.FirstOrDefault(x => x.Id == evalStructure.StructureName);
                //check for sufficient sampling and dose coverage
                DVHData dvh = planningItem.PlanningItemObject.GetDVHCumulativeData(structure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.1);
                //MessageBox.Show(evalStructure.Id + "- Eval unit: " + evalunit.Value.ToString() + "Achieved unit: " + dvAchieved.UnitAsString + " - Sampling coverage: " + dvh.SamplingCoverage.ToString() + " Coverage: " + dvh.Coverage.ToString());
                if ((dvh.SamplingCoverage < 0.9) || (dvh.Coverage < 0.9))
                {
                    return("Unable to calculate - insufficient dose or sampling coverage");
                }
                Group eval            = testMatch[0].Groups["evalpt"];
                Group unit            = testMatch[0].Groups["unit"];
                DoseValue.DoseUnit du = (unit.Value.CompareTo("%") == 0) ? DoseValue.DoseUnit.Percent :
                                        (unit.Value.CompareTo("cGy") == 0) ? DoseValue.DoseUnit.cGy : DoseValue.DoseUnit.Unknown;
                VolumePresentation    vp       = (unit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
                DoseValue             dv       = new DoseValue(double.Parse(eval.Value), du);
                double                volume   = double.Parse(eval.Value);
                VolumePresentation    vpFinal  = (evalunit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
                DoseValuePresentation dvpFinal = (evalunit.Value.CompareTo("%") == 0) ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
                if (planningItem.PlanningItemObject is PlanSum)
                {
                    double  planDoseDouble = 0;
                    PlanSum planSum        = (PlanSum)planningItem.PlanningItemObject;
                    foreach (PlanSetup planSetup in planSum.PlanSetups)
                    {
                        planDoseDouble += planSetup.TotalDose.Dose;
                    }
                    dv = new DoseValue(planDoseDouble, DoseValue.DoseUnit.cGy);
                }

                double volumeAchieved = planningItem.PlanningItemObject.GetVolumeAtDose(structure, dv, vpFinal);
                return(string.Format("{0:0.00} {1}", volumeAchieved, evalunit.Value));   // todo: better formatting based on VolumePresentation
            }
            catch (NullReferenceException)
            {
                return("Unable to calculate - DVH is not valid");
            }
        }
Esempio n. 13
0
        /// <summary>
        ///     Return the 3D dose matrix
        /// </summary>
        /// <param name="pi">the current planning item</param>
        /// <param name="unit">the units for the returned dose matrix</param>
        /// <returns>Return the 3D dose matrix associated with the planning item</returns>
        public static double[,,] GetDoseMatrix(this PlanningItem pi, DoseValue.DoseUnit unit)
        {
            var oldPresentation = pi.DoseValuePresentation;

            pi.DoseValuePresentation = DoseValuePresentation.Absolute;
            double factor = 1.0;

            if (unit == DoseValue.DoseUnit.Percent)
            {
                factor  = 100 * pi.Dose.VoxelToDoseValue(int.MaxValue).GetDose(DoseValue.DoseUnit.Gy) / pi.TotalPrescribedDoseGy();
                factor /= (double)int.MaxValue;
            }
            else if (unit != DoseValue.DoseUnit.Unknown)
            {
                factor = pi.Dose.VoxelToDoseValue(int.MaxValue).GetDose(unit) / (double)int.MaxValue;
            }
            pi.DoseValuePresentation = oldPresentation;

            int nx = pi.Dose.XSize;
            int ny = pi.Dose.YSize;
            int nz = pi.Dose.ZSize;

            double [,,] dose = new double[nx, ny, nz];
            int [,] slice    = new int[nx, ny];

            for (int kz = 0; kz < nz; kz++)
            {
                pi.Dose.GetVoxels(kz, slice);
                for (int ix = 0; ix < nx; ix++)
                {
                    for (int jy = 0; jy < ny; jy++)
                    {
                        dose[ix, jy, kz] = factor * slice[ix, jy];
                    }
                }
            }

            return(dose);
        }
Esempio n. 14
0
        // Calculate Volume at Dose
        private string EvaluateVolumeAtDose(Structure evalStructure, PlanningItem plan, ref List <string> warnings)
        {
            string achieved;

            // Plan sums don't support relative dose.
            if (plan is PlanSum && DVHUnit.CompareTo("%") == 0)
            {
                warnings.Add("Relative dose not supported for plan sums.");
                return("");
            }

            // Determine Units
            DoseValue.DoseUnit du = (DVHUnit.CompareTo("%") == 0) ? DoseValue.DoseUnit.Percent :
                                    (DVHUnit.CompareTo("Gy") == 0) ? DoseValue.DoseUnit.Gy :
                                    (DVHUnit.CompareTo("cGy") == 0) ? DoseValue.DoseUnit.cGy : DoseValue.DoseUnit.Unknown;
            string doseunit = (plan is PlanSum) ? (plan as PlanSum).PlanSetups.First().DosePerFraction.UnitAsString :
                              (plan as PlanSetup).DosePerFraction.UnitAsString;

            // If plan sum and relative dose then convert to Gy
            if (plan is PlanSum && DVHUnit.CompareTo("%") == 0)
            {
                du = DoseValue.DoseUnit.Gy;
            }

            // For version 15, we must handle all doses in the unit they are supposed to be presented in.
            double dose_value = double.Parse(DVHEvalPt);

            if (du.ToString() == "Gy" && doseunit == "cGy")
            {
                dose_value = dose_value * 100;
                du         = DoseValue.DoseUnit.cGy;
            }
            else if (du.ToString() == "cGy" && doseunit == "Gy")
            {
                dose_value = dose_value / 100;
                du         = DoseValue.DoseUnit.Gy;
            }

            // Calculate results
            DoseValue          dv             = new DoseValue(dose_value, du);
            VolumePresentation vpFinal        = (DVHEvalUnit.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
            double             volumeAchieved = plan.GetVolumeAtDose(evalStructure, dv, vpFinal);

            // Check if dose is undefined
            if (double.IsNaN(volumeAchieved))
            {
                // Check for sufficient sampling and dose coverage
                DVHData dvh = plan.GetDVHCumulativeData(evalStructure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.1);
                if (dvh.SamplingCoverage < 0.9)
                {
                    warnings.Add("Insufficient sampling coverage.");
                }

                if (dvh.Coverage < 1.0)
                {
                    warnings.Add("Insufficient dose coverage.");
                }

                if (warnings.Count == 0)
                {
                    warnings.Add("Dose value undefined.");
                }

                return("");
            }

            achieved = string.Format("{0:0.00} {1}", volumeAchieved, DVHEvalUnit);
            return(achieved);
        }
Esempio n. 15
0
        //---------------------------------------------------------------------------------------------
        void UpdateDvhLookup()
        {
            if (m_closing || SelectedStructure == null)
            {
                return;
            }

            bool doseAbsolute = m_absDoseCheckbox.IsChecked.Value;
            bool volAbsolute  = m_absVolCheckbox.IsChecked.Value;

            m_volumeAtDoseResultLabel.Content = "";
            m_doseAtVolumeResultLabel.Content = "";

            m_resultVolumeAtDose.Content = "";
            m_resultDoseAtVolume.Content = "";
            m_structureVolume.Text       = "";

            double inputVolume = Double.NaN;

            if (m_volumeTextBox.Text != null)
            {
                Double.TryParse(m_volumeTextBox.Text, out inputVolume);
            }

            double inputDose = Double.NaN;

            if (m_doseTextBox.Text != null)
            {
                Double.TryParse(m_doseTextBox.Text, out inputDose);
            }

            DoseValuePresentation dosePres = doseAbsolute ? DoseValuePresentation.Absolute : DoseValuePresentation.Relative;
            VolumePresentation    volPres  = volAbsolute ? VolumePresentation.AbsoluteCm3 : VolumePresentation.Relative;

            DVHData dvhData = SelectedPlanningItem.GetDVHCumulativeData(SelectedStructure, dosePres, volPres, s_binWidth);

            m_structureVolume.Text = dvhData.Volume.ToString("F5");

            if (SelectedPlanningItem != null && SelectedPlanningItem.Dose != null && SelectedStructure != null)
            {
                if (!Double.IsNaN(inputVolume))
                {
                    DoseValue val        = SelectedPlanningItem.GetDoseAtVolume(SelectedStructure, inputVolume, volPres, dosePres);
                    DoseValue controlVal = DvhExtensions.DoseAtVolume(dvhData, inputVolume);
                    double    err        = Math.Abs((val.Dose - controlVal.Dose) / val.Dose);
                    if (err > 0.001)
                    {
                        MessageBox.Show("Value : " + val.ToString() + " Control Val : " + controlVal.ToString());
                    }
                    m_resultDoseAtVolume.Content = val.ToString();

                    string doseAtVolumeResultType = volAbsolute ? "cm3 D(" : "% D(";
                    doseAtVolumeResultType           += inputVolume.ToString("F1") + (volAbsolute ? "cm3" : "%") + ") =";
                    m_doseAtVolumeResultLabel.Content = doseAtVolumeResultType;
                }
                if (!Double.IsNaN(inputDose))
                {
                    DoseValue.DoseUnit doseUnit = dvhData.MaxDose.Unit;
                    double             vol      = SelectedPlanningItem.GetVolumeAtDose(SelectedStructure, new DoseValue(inputDose, doseUnit), volPres);

                    double controlVal = DvhExtensions.VolumeAtDose(dvhData, inputDose);
                    double err        = Math.Abs((vol - controlVal) / vol);
                    if (err > 0.001)
                    {
                        MessageBox.Show("Value : " + vol.ToString("F3") + " Control Val : " + controlVal.ToString("F3"));
                    }

                    m_resultVolumeAtDose.Content = vol.ToString("F5") + (volAbsolute ? "cm3" : "%");

                    string volumeAtDoseResultType = doseUnit.ToString() + " V(";
                    volumeAtDoseResultType           += inputDose.ToString("F1") + doseUnit.ToString() + " ) =";
                    m_volumeAtDoseResultLabel.Content = volumeAtDoseResultType;
                }
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Converts the dose to the unit requested. It cannot convert from % to abs dose. Will return NaN if asked
        /// </summary>
        /// <param name="dv">the dose value to be converted</param>
        /// <param name="unit">the unit desired for the returned dose</param>
        /// <returns>the dose in the desired units</returns>
        public static DoseValue ConvertUnits(this DoseValue dv, DoseValue.DoseUnit unit)
        {
            var dose = dv.GetDose(unit);

            return(new DoseValue(dose, unit));
        }
Esempio n. 17
0
        public string VaDa(string strnum, double doseindex, double criteria, int updown, StructureSet list, PlanSetup plan)//updown(1up,0down)
        {
            Structure retstructure = null;
            int       bit          = 0;
            double    binwidth     = 0.1;
            string    doostr       = "";
            string    judge        = "";

            foreach (Structure scan in list.Structures)
            {
                if (scan.Id == strnum)
                {
                    retstructure = scan;
                    if (retstructure.IsEmpty)
                    {
                        bit = 2; break;
                    }
                    bit = 1;
                    DVHData            dvhData  = plan.GetDVHCumulativeData(retstructure, DoseValuePresentation.Absolute, VolumePresentation.AbsoluteCm3, binwidth);
                    DoseValue.DoseUnit doseUnit = dvhData.MaxDose.Unit;
                    Double             Doo      = plan.GetVolumeAtDose(retstructure, new DoseValue(doseindex, doseUnit), VolumePresentation.AbsoluteCm3);
                    doostr = Doo.ToString("F2");
                    if (updown == 1)//upper dose
                    {
                        if (Doo <= criteria)
                        {
                            judge = "o";
                        }
                        else
                        {
                            judge = "x";
                        }
                    }
                    else
                    {
                        if (Doo > criteria)
                        {
                            judge = "o";
                        }
                        else
                        {
                            judge = "x";
                        }
                    }
                    break;
                }
            }
            string doseindexreturn = "";
            string judgement       = "";
            string retstring       = "";

            if (bit == 1)
            {
                retstring = retstructure.Id; doseindexreturn = doostr; judgement = judge; retstring = string.Format("{0}\t\tV{1}Gy\t\t{2}cc\t\t{3}cc\t{4}\n", retstructure.Id, (doseindex / 100).ToString("F0"), criteria.ToString("F0"), doseindexreturn, judgement);
            }
            else if (bit == 2)
            {
                retstring = strnum + "\tis Empty structure" + "\n";
            }
            else
            {
                retstring = "No Structure named " + strnum + "\n";
            }
            return(retstring);
        }
Esempio n. 18
0
        void EvaluateMetrics(StructureSet ss, PlanningItem plan)
        {
            //start with a general regex that pulls out the metric type and the @ (evalunit) part.
            string pattern            = @"^(?<type>[^\[\]]+)(\[(?<evalunit>[^\[\]]+)\])$";
            string minmaxmean_Pattern = @"^(M(in|ax|ean)|Volume)$";                          //check for Max or Min or Mean or Volume
            string d_at_v_pattern     = @"^D(?<evalpt>\d+\p{P}\d+|\d+)(?<unit>(%|cc))$";     // matches D95%, D2cc
            string dc_at_v_pattern    = @"^DC(?<evalpt>\d+)(?<unit>(%|cc))$";                // matches DC95%, DC700cc
            string v_at_d_pattern     = @"^V(?<evalpt>\d+\p{P}\d+|\d+)(?<unit>(%|Gy|cGy))$"; // matches V98%, V40Gy
            string cv_at_d_pattern    = @"^CV(?<evalpt>\d+)(?<unit>(%|Gy|cGy))$";            // matches CV98%, CV40Gy

            // Max[Gy] D95%[%] V98%[%] CV98%[%] D2cc[Gy] V40Gy[%]

            foreach (var objective in m_objectives)
            {
                // first find the structure for this objective
                Structure evalStructure = FindStructureFromAlias(ss, objective.ID, objective.Aliases);
                if (evalStructure == null)
                {
                    objective.Achieved         = "Structure not found.";
                    objective.FoundStructureID = "";
                    continue;
                }
                objective.FoundStructureID = evalStructure.Id;

                //start with a general regex that pulls out the metric type and the [evalunit] part.
                var matches = Regex.Matches(objective.DVHObjective, pattern);

                if (matches.Count != 1)
                {
                    objective.Achieved =
                        string.Format("DVH Objective expression \"{0}\" is not a recognized expression type.",
                                      objective.DVHObjective);
                    break;
                }
                Match m        = matches[0];
                Group type     = m.Groups["type"];
                Group evalunit = m.Groups["evalunit"];
                Console.WriteLine("expression {0} => type = {1}, unit = {2}", objective.DVHObjective, type.Value, evalunit.Value);

                //MessageBox.Show(type.Value+" " + minmaxmean_Pattern);


                // further decompose <type>
                var testMatch = Regex.Matches(type.Value, minmaxmean_Pattern);
                if (testMatch.Count != 1)
                {
                    testMatch = Regex.Matches(type.Value, v_at_d_pattern);
                    if (testMatch.Count != 1)
                    {
                        testMatch = Regex.Matches(type.Value, d_at_v_pattern);
                        if (testMatch.Count != 1)
                        {
                            testMatch = Regex.Matches(type.Value, cv_at_d_pattern);
                            if (testMatch.Count != 1)
                            {
                                testMatch = Regex.Matches(type.Value, dc_at_v_pattern);
                                if (testMatch.Count != 1)
                                {
                                    objective.Achieved =
                                        string.Format("DVH Objective expression \"{0}\" is not a recognized expression type.",
                                                      objective.DVHObjective);
                                    //                                MessageBox.Show(objective.Achieved);
                                }
                                else
                                {
                                    // we have Covered Dose at Volume pattern
                                    System.Console.WriteLine("Covered Dose at Volume");
                                    objective.Achieved = "Not supported";
                                }
                            }
                            else
                            {
                                // we have Covered Volume at Dose pattern
                                System.Console.WriteLine("Covered Volume at Dose");
                                objective.Achieved = "Not supported";
                            }
                        }
                        else
                        {
                            // we have Dose at Volume pattern
                            //                        MessageBox.Show("Dose at Volume");

                            /*
                             * string d_at_v_pattern = @"^D(?<evalpt>\d+)(?<unit>(%|cc))$"; // matches D95%, D2cc
                             */
                            Group eval            = testMatch[0].Groups["evalpt"];
                            Group unit            = testMatch[0].Groups["unit"];
                            DoseValue.DoseUnit du = (unit.Value.CompareTo("%") == 0) ? DoseValue.DoseUnit.Percent :
                                                    (unit.Value.CompareTo("Gy") == 0) ? DoseValue.DoseUnit.Gy : DoseValue.DoseUnit.Unknown;
                            VolumePresentation    vp       = (unit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
                            DoseValue             dv       = new DoseValue(double.Parse(eval.Value), du);
                            double                volume   = double.Parse(eval.Value);
                            VolumePresentation    vpFinal  = (evalunit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
                            DoseValuePresentation dvpFinal = (evalunit.Value.CompareTo("%") == 0) ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;

                            DoseValue dvAchieved = plan.GetDoseAtVolume(evalStructure, volume, vp, dvpFinal);
                            //checking dose output unit and adapting to template
                            if (dvAchieved.UnitAsString.CompareTo(evalunit.Value.ToString()) != 0)
                            {
                                if ((evalunit.Value.CompareTo("Gy") == 0) && (dvAchieved.Unit.CompareTo(DoseValue.DoseUnit.cGy) == 0))
                                {
                                    dvAchieved = new DoseValue(dvAchieved.Dose / 100, DoseValue.DoseUnit.Gy);
                                }
                                else
                                {
                                    throw new ApplicationException("internal error");
                                }
                            }

                            objective.Achieved = dvAchieved.ToString();
                        }
                    }
                    else
                    {
                        // we have Volume at Dose pattern
                        //                    MessageBox.Show("Volume at Dose");

                        /*
                         * string v_at_d_pattern = @"^V(?<evalpt>\d+)(?<unit>(%|Gy|cGy))$"; // matches V98%, V40Gy, V4000cGy
                         */
                        Group eval            = testMatch[0].Groups["evalpt"];
                        Group unit            = testMatch[0].Groups["unit"];
                        DoseValue.DoseUnit du = (unit.Value.CompareTo("%") == 0) ? DoseValue.DoseUnit.Percent :
                                                (unit.Value.CompareTo("Gy") == 0) ? DoseValue.DoseUnit.Gy : DoseValue.DoseUnit.Unknown;
                        VolumePresentation    vp             = (unit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
                        DoseValue             dv             = new DoseValue(double.Parse(eval.Value), du);
                        double                volume         = double.Parse(eval.Value);
                        VolumePresentation    vpFinal        = (evalunit.Value.CompareTo("%") == 0) ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
                        DoseValuePresentation dvpFinal       = (evalunit.Value.CompareTo("%") == 0) ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
                        double                volumeAchieved = plan.GetVolumeAtDose(evalStructure, dv, vpFinal);
                        objective.Achieved = string.Format("{0:0.00} {1}", volumeAchieved, evalunit.Value);   // todo: better formatting based on VolumePresentation
#if false
                        string message = string.Format("{0} - Dose unit = {1}, Volume Presentation = {2}, vpFinal = {3}, dvpFinal ={4}",
                                                       objective.DVHObjective, du.ToString(), vp.ToString(), vpFinal.ToString(), dvpFinal.ToString());
                        MessageBox.Show(message);
#endif
                    }
                }
                else
                {
                    // we have Min, Max, Mean, or Volume
                    if (type.Value.CompareTo("Volume") == 0)
                    {
                        objective.Achieved = string.Format("{0:0.00} {1}", evalStructure.Volume, evalunit.Value);
                    }
                    else
                    {
                        DoseValuePresentation dvp = (evalunit.Value.CompareTo("%") == 0) ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
                        DVHData dvh = plan.GetDVHCumulativeData(evalStructure, dvp, VolumePresentation.Relative, 0.1);
                        if (type.Value.CompareTo("Max") == 0)
                        {
                            //checking dose output unit and adapting to template
                            //Gy to cGy
                            if ((evalunit.Value.CompareTo("Gy") == 0) && (dvh.MaxDose.Unit.CompareTo(DoseValue.DoseUnit.cGy) == 0))
                            {
                                objective.Achieved = new DoseValue(dvh.MaxDose.Dose / 100, DoseValue.DoseUnit.Gy).ToString();
                            }
                            //Gy to Gy or % to %
                            else
                            {
                                objective.Achieved = dvh.MaxDose.ToString();
                            }
                        }
                        else if (type.Value.CompareTo("Min") == 0)
                        {
                            //checking dose output unit and adapting to template
                            //Gy to cGy
                            if ((evalunit.Value.CompareTo("Gy") == 0) && (dvh.MinDose.Unit.CompareTo(DoseValue.DoseUnit.cGy) == 0))
                            {
                                objective.Achieved = new DoseValue(dvh.MinDose.Dose / 100, DoseValue.DoseUnit.Gy).ToString();
                            }
                            //Gy to Gy or % to %
                            else
                            {
                                objective.Achieved = dvh.MinDose.ToString();
                            }
                        }
                        else
                        {
                            //checking dose output unit and adapting to template
                            //Gy to cGy
                            if ((evalunit.Value.CompareTo("Gy") == 0) && (dvh.MeanDose.Unit.CompareTo(DoseValue.DoseUnit.cGy) == 0))
                            {
                                objective.Achieved = new DoseValue(dvh.MeanDose.Dose / 100, DoseValue.DoseUnit.Gy).ToString();
                            }
                            //Gy to Gy or % to %
                            else
                            {
                                objective.Achieved = dvh.MeanDose.ToString();
                            }
                        }
                    }
                }
            }
            // further decompose <ateval>
            //look at the evaluator and compare to goal or variation
            foreach (var objective in m_objectives)
            {
                string evalpattern = @"^(?<type><|<=|=|>=|>)(?<goal>\d+\p{P}\d+|\d+)$";
                if (!String.IsNullOrEmpty(objective.Evaluator))
                {
                    var matches = Regex.Matches(objective.Evaluator, evalpattern);
                    if (matches.Count != 1)
                    {
                        MessageBox.Show("Eval pattern not recognized");
                        objective.Met =
                            string.Format("Evaluator expression \"{0}\" is not a recognized expression type.",
                                          objective.Evaluator);
                    }
                    Match m        = matches[0];
                    Group goal     = m.Groups["goal"];
                    Group evaltype = m.Groups["type"];


                    if (String.IsNullOrEmpty(Regex.Match(objective.Achieved, @"\d+\p{P}\d+|\d+").Value))
                    {
                        objective.Met = "Not evaluated";
                    }
                    else
                    {
                        double evalvalue = Double.Parse(Regex.Match(objective.Achieved, @"\d+\p{P}\d+|\d+").Value);
                        if (evaltype.Value.CompareTo("<") == 0)
                        {
                            if ((evalvalue - Double.Parse(goal.ToString())) < 0)
                            {
                                objective.Met = "Goal";
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(objective.Variation))
                                {
                                    objective.Met = "Not met";
                                }
                                else
                                {
                                    if ((evalvalue - Double.Parse(objective.Variation)) < 0)
                                    {
                                        objective.Met = "Variation";
                                    }
                                    else
                                    {
                                        objective.Met = "Not met";
                                    }
                                }
                            }
                        }
                        else if (evaltype.Value.CompareTo("<=") == 0)
                        {
                            //MessageBox.Show("evaluating <= " + evaltype.ToString());
                            if ((evalvalue - Double.Parse(goal.ToString())) <= 0)
                            {
                                objective.Met = "Goal";
                            }
                            else
                            {
                                //MessageBox.Show("Evaluating variation");
                                if (String.IsNullOrEmpty(objective.Variation))
                                {
                                    //MessageBox.Show(String.Format("Empty variation condition Achieved: {0} Variation: {1}", objective.Achieved.ToString(), objective.Variation.ToString()));
                                    objective.Met = "Not met";
                                }
                                else
                                {
                                    //MessageBox.Show(String.Format("Non Empty variation condition Achieved: {0} Variation: {1}", objective.Achieved.ToString(), objective.Variation.ToString()));
                                    if ((evalvalue - Double.Parse(objective.Variation)) <= 0)
                                    {
                                        objective.Met = "Variation";
                                    }
                                    else
                                    {
                                        objective.Met = "Not met";
                                    }
                                }
                            }
                        }
                        else if (evaltype.Value.CompareTo("=") == 0)
                        {
                            if ((evalvalue - Double.Parse(goal.ToString())) == 0)
                            {
                                objective.Met = "Goal";
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(objective.Variation))
                                {
                                    objective.Met = "Not met";
                                }
                                else
                                {
                                    if ((evalvalue - Double.Parse(objective.Variation)) == 0)
                                    {
                                        objective.Met = "Variation";
                                    }
                                    else
                                    {
                                        objective.Met = "Not met";
                                    }
                                }
                            }
                        }
                        else if (evaltype.Value.CompareTo(">=") == 0)
                        {
                            if ((evalvalue - Double.Parse(goal.ToString())) >= 0)
                            {
                                objective.Met = "Goal";
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(objective.Variation))
                                {
                                    objective.Met = "Not met";
                                }
                                else
                                {
                                    if ((evalvalue - Double.Parse(objective.Variation)) >= 0)
                                    {
                                        objective.Met = "Variation";
                                    }
                                    else
                                    {
                                        objective.Met = "Not met";
                                    }
                                }
                            }
                        }
                        else if (evaltype.Value.CompareTo(">") == 0)
                        {
                            if ((evalvalue - Double.Parse(goal.ToString())) > 0)
                            {
                                objective.Met = "Goal";
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(objective.Variation))
                                {
                                    objective.Met = "Not met";
                                }
                                else
                                {
                                    if ((evalvalue - Double.Parse(objective.Variation)) > 0)
                                    {
                                        objective.Met = "Variation";
                                    }
                                    else
                                    {
                                        objective.Met = "Not met";
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 19
0
        /// <summary>
        /// Computes the planned value of each constraint in the selected protocol
        /// </summary>
        private void ComputePlanValues()
        {
            //make sure structures are valid
            PlanResult = "";
            if (SelectedStructure.Name.Contains("Couch"))
            {
                PlanResult = "Couch structure cannot be used";
            }
            else if (SelectedStructure.IsEmpty)
            {
                PlanResult = "Structure is empty";
            }
            else if (SelectedStructure.DicomType == "MARKER")
            {
                PlanResult = "Structure is a Patient Marker";
            }
            else
            {
                DoseValue.DoseUnit systemUnits = _viewModel.SelectedPlanningItem.GetDVHCumulativeData(SelectedStructure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 1).MeanDose.Unit;

                if (ConstraintType == ConstraintType.Dose)
                {
                    VolumePresentation    volPres  = ConstraintUnits == "%" ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;
                    DoseValuePresentation dosePres = LimitUnits == "%" ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;

                    DoseValue val    = _viewModel.SelectedPlanningItem.GetDoseAtVolume(SelectedStructure, Constraint, volPres, dosePres, _viewModel.PlanSumTotalDose);
                    DoseValue varVal = VariationConstraint != -1 ? _viewModel.SelectedPlanningItem.GetDoseAtVolume(SelectedStructure, VariationConstraint, volPres, dosePres, _viewModel.PlanSumTotalDose) : val;

                    //convert to correct units for display
                    if (!LimitUnits.Contains("%"))
                    {
                        val    = ConvertDoseUnits(val, LimitUnits);
                        varVal = ConvertDoseUnits(varVal, LimitUnits);
                    }

                    PlanValue              = val.Dose;
                    PlanValueText          = val.ToString();
                    PlanVariationValue     = varVal.Dose;
                    PlanVariationValueText = varVal.ToString();
                }
                else if (ConstraintType == ConstraintType.Volume)
                {
                    DoseValuePresentation dosePres = ConstraintUnits == "%" ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
                    VolumePresentation    volPres  = LimitUnits == "%" ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;

                    DoseValue.DoseUnit doseUnit       = ConstraintUnits.ToLower().Contains("cgy") ? DoseValue.DoseUnit.cGy : DoseValue.DoseUnit.Gy;
                    double             tempConstraint = 0;
                    if (doseUnit == systemUnits || doseUnit == DoseValue.DoseUnit.Percent)
                    {
                        tempConstraint = Constraint;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.cGy)
                    {
                        tempConstraint = Constraint / 100;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.Gy)
                    {
                        tempConstraint = Constraint * 100;
                    }

                    double tempVariationConstraint = 0;
                    if (doseUnit == systemUnits || doseUnit == DoseValue.DoseUnit.Percent)
                    {
                        tempVariationConstraint = Constraint;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.cGy)
                    {
                        tempVariationConstraint = Constraint / 100;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.Gy)
                    {
                        tempVariationConstraint = Constraint * 100;
                    }

                    double vol    = dosePres == DoseValuePresentation.Absolute ? _viewModel.SelectedPlanningItem.GetVolumeAtDose(SelectedStructure, new DoseValue(tempConstraint, systemUnits), volPres) : _viewModel.SelectedPlanningItem.GetVolumeAtDose(SelectedStructure, new DoseValue(Constraint, DoseValue.DoseUnit.Percent), volPres, _viewModel.PlanSumTotalDose);
                    double varVol = VariationConstraint != -1 ? _viewModel.SelectedPlanningItem.GetVolumeAtDose(SelectedStructure, new DoseValue(tempVariationConstraint, systemUnits), volPres, _viewModel.PlanSumTotalDose) : vol;

                    PlanValue              = Math.Round(vol, 1);
                    PlanValueText          = PlanValue.ToString() + (volPres == VolumePresentation.Relative ? " %" : " cc");
                    PlanVariationValue     = Math.Round(varVol, 1);
                    PlanVariationValueText = PlanVariationValue.ToString() + (volPres == VolumePresentation.Relative ? " %" : " cc");
                }
                else if (ConstraintType == ConstraintType.Mean)
                {
                    DoseValuePresentation dosePres = dosePres = LimitUnits == "%" ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;

                    DoseValue val    = _viewModel.SelectedPlanningItem.GetMeanDose(SelectedStructure, dosePres);
                    DoseValue varVal = VariationConstraint != -1 ? _viewModel.SelectedPlanningItem.GetMeanDose(SelectedStructure, dosePres) : val;

                    //convert to correct units for display
                    if (!LimitUnits.Contains("%"))
                    {
                        val    = ConvertDoseUnits(val, LimitUnits);
                        varVal = ConvertDoseUnits(varVal, LimitUnits);
                    }

                    PlanValue              = val.Dose;
                    PlanValueText          = val.ToString();
                    PlanVariationValue     = varVal.Dose;
                    PlanVariationValueText = varVal.ToString();
                }
                else if (ConstraintType == ConstraintType.Max)
                {
                    DoseValuePresentation dosePres = dosePres = LimitUnits == "%" ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;

                    DoseValue val    = _viewModel.SelectedPlanningItem.GetMaxDose(SelectedStructure, dosePres);
                    DoseValue varVal = VariationConstraint != -1 ? _viewModel.SelectedPlanningItem.GetMaxDose(SelectedStructure, dosePres) : val;

                    //convert to correct units for display
                    if (!LimitUnits.Contains("%"))
                    {
                        val    = ConvertDoseUnits(val, LimitUnits);
                        varVal = ConvertDoseUnits(varVal, LimitUnits);
                    }

                    PlanValue              = val.Dose;
                    PlanValueText          = val.ToString();
                    PlanVariationValue     = varVal.Dose;
                    PlanVariationValueText = varVal.ToString();
                }
                else if (ConstraintType == ConstraintType.Min)
                {
                    DoseValuePresentation dosePres = dosePres = LimitUnits == "%" ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;

                    DoseValue val    = _viewModel.SelectedPlanningItem.GetMinDose(SelectedStructure, dosePres);
                    DoseValue varVal = VariationConstraint != -1 ? _viewModel.SelectedPlanningItem.GetMinDose(SelectedStructure, dosePres) : val;

                    //convert to correct units for display
                    if (!LimitUnits.Contains("%"))
                    {
                        val    = ConvertDoseUnits(val, LimitUnits);
                        varVal = ConvertDoseUnits(varVal, LimitUnits);
                    }

                    PlanValue              = val.Dose;
                    PlanValueText          = val.ToString();
                    PlanVariationValue     = varVal.Dose;
                    PlanVariationValueText = varVal.ToString();
                }
                else if (ConstraintType == ConstraintType.ColdVolume)
                {
                    DoseValuePresentation dosePres = ConstraintUnits == "%" ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
                    VolumePresentation    volPres  = LimitUnits == "%" ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3;

                    DoseValue.DoseUnit doseUnit       = ConstraintUnits.ToLower().Contains("cgy") ? DoseValue.DoseUnit.cGy : DoseValue.DoseUnit.Gy;
                    double             tempConstraint = 0;
                    if (doseUnit == systemUnits || doseUnit == DoseValue.DoseUnit.Percent)
                    {
                        tempConstraint = Constraint;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.cGy)
                    {
                        tempConstraint = Constraint / 100;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.Gy)
                    {
                        tempConstraint = Constraint * 100;
                    }

                    double tempVariationConstraint = 0;
                    if (doseUnit == systemUnits || doseUnit == DoseValue.DoseUnit.Percent)
                    {
                        tempVariationConstraint = Constraint;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.cGy)
                    {
                        tempVariationConstraint = Constraint / 100;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.Gy)
                    {
                        tempVariationConstraint = Constraint * 100;
                    }

                    double vol    = dosePres == DoseValuePresentation.Absolute ? _viewModel.SelectedPlanningItem.GetVolumeAtDose(SelectedStructure, new DoseValue(tempConstraint, systemUnits), volPres) : _viewModel.SelectedPlanningItem.GetVolumeAtDose(SelectedStructure, new DoseValue(Constraint, DoseValue.DoseUnit.Percent), volPres, _viewModel.PlanSumTotalDose);
                    double varVol = VariationConstraint != -1 ? _viewModel.SelectedPlanningItem.GetVolumeAtDose(SelectedStructure, new DoseValue(tempVariationConstraint, systemUnits), volPres, _viewModel.PlanSumTotalDose) : vol;

                    //this is the normal volume getting the requested dose, to get cold volume we want the remaining volume in the structure getting less than the requested dose, so subtract it from the total structure volume
                    vol    = volPres == VolumePresentation.AbsoluteCm3 ? SelectedStructure.Volume - vol : 100 - vol;
                    varVol = volPres == VolumePresentation.AbsoluteCm3 ? SelectedStructure.Volume - varVol : 100 - varVol;

                    PlanValue              = Math.Round(vol, 1);
                    PlanValueText          = PlanValue.ToString() + (volPres == VolumePresentation.Relative ? " %" : " cc");
                    PlanVariationValue     = Math.Round(varVol, 1);
                    PlanVariationValueText = PlanVariationValue.ToString() + (volPres == VolumePresentation.Relative ? " %" : " cc");
                }
                else if (ConstraintType == ConstraintType.CI)
                {
                    Structure External;

                    if (_viewModel.SelectedStructureSet.Structures.Where(struc => struc.Id == "External" || struc.Id == "BODY" || struc.Id == "Body").Count() > 0)
                    {
                        External = _viewModel.SelectedStructureSet.Structures.Where(struc => struc.Id == "External" || struc.Id == "BODY" || struc.Id == "Body").FirstOrDefault();
                    }
                    else
                    {
                        MessageBox.Show("No body contour found for isodose volumes for CI calculation", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        throw new FormatException("No body contour found for isodose volumes for CI calculation");
                    }

                    DoseValuePresentation dosePres = ConstraintUnits == "%" ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute;
                    VolumePresentation    volPres  = VolumePresentation.AbsoluteCm3;

                    DoseValue.DoseUnit doseUnit       = ConstraintUnits.ToLower().Contains("cgy") ? DoseValue.DoseUnit.cGy : DoseValue.DoseUnit.Gy;
                    double             tempConstraint = 0;
                    if (doseUnit == systemUnits || doseUnit == DoseValue.DoseUnit.Percent)
                    {
                        tempConstraint = Constraint;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.cGy)
                    {
                        tempConstraint = Constraint / 100;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.Gy)
                    {
                        tempConstraint = Constraint * 100;
                    }

                    double tempVariationConstraint = 0;
                    if (doseUnit == systemUnits || doseUnit == DoseValue.DoseUnit.Percent)
                    {
                        tempVariationConstraint = Constraint;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.cGy)
                    {
                        tempVariationConstraint = Constraint / 100;
                    }
                    else if (doseUnit == DoseValue.DoseUnit.Gy)
                    {
                        tempVariationConstraint = Constraint * 100;
                    }

                    double vol    = dosePres == DoseValuePresentation.Absolute ? _viewModel.SelectedPlanningItem.GetVolumeAtDose(External, new DoseValue(tempConstraint, systemUnits), volPres) : _viewModel.SelectedPlanningItem.GetVolumeAtDose(External, new DoseValue(Constraint, DoseValue.DoseUnit.Percent), volPres, _viewModel.PlanSumTotalDose);
                    double varVol = VariationConstraint != -1 ? _viewModel.SelectedPlanningItem.GetVolumeAtDose(External, new DoseValue(tempVariationConstraint, systemUnits), volPres, _viewModel.PlanSumTotalDose) : vol;

                    PlanValue     = Math.Round(vol / SelectedStructure.Volume, 1);
                    PlanValueText = PlanValue.ToString();
                }
                else
                {
                    MessageBox.Show("Invalid constraint type: " + ConstraintType + " for structure " + Structure, "Invalid Constraint Type", MessageBoxButton.OK, MessageBoxImage.Error);
                    throw new FormatException("Invalid constraint type: " + ConstraintType + " for structure " + Structure);
                }
            }

            //make it show up on the DVH
            //if it is contoured
            if (_viewModel.DVHStructures.Where(s => s.structure == SelectedStructure).Count() > 0)
            {
                _viewModel.DVHStructures.Where(s => s.structure == SelectedStructure).First().OnDVH = true;
            }
        }