public static DoseValue GetMaxDose(this PlanningItem pitem, Structure structure, DoseValuePresentation requestedDosePresentation) { //if it's a plan we can get absolute or relative dose if (pitem is PlanSetup || requestedDosePresentation == DoseValuePresentation.Absolute) { return(pitem.GetDVHCumulativeData(structure, requestedDosePresentation, VolumePresentation.Relative, 1).MaxDose); } //otherwise if it's a plan sum we can only get absolute and must convert to relative else { DoseValue planSumTotalDose = new DoseValue(0, pitem.Dose.DoseMax3D.Unit); foreach (PlanSetup psetup in ((PlanSum)pitem).PlanSetups) { planSumTotalDose += psetup.TotalDose; } DoseValue temp = pitem.GetDVHCumulativeData(structure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 1).MaxDose; return(new DoseValue(temp.Dose / planSumTotalDose.Dose * 100, DoseValue.DoseUnit.Percent)); } }
//--------------------------------------------------------------------------------------------- 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; } } }
public static DoseValue GetDoseAtVolume(this PlanningItem pitem, Structure structure, double volume, VolumePresentation volumePresentation, DoseValuePresentation requestedDosePresentation) { if (pitem is PlanSetup) { return(((PlanSetup)pitem).GetDoseAtVolume(structure, volume, volumePresentation, requestedDosePresentation)); } else { if (requestedDosePresentation != DoseValuePresentation.Absolute) { throw new ApplicationException("Only absolute dose supported for Plan Sums"); } DVHData dvh = pitem.GetDVHCumulativeData(structure, DoseValuePresentation.Absolute, volumePresentation, 0.001); return(DvhExtensions.DoseAtVolume(dvh, volume)); } }
/// <summary> /// Enables a shorter method for doing a common task (getting the DVH from a structure). Contains default values. /// </summary> public static DVHData GetDefaultDVHCumulativeData(this PlanningItem plan, Structure s, DoseValuePresentation dvp = DoseValuePresentation.Absolute, VolumePresentation vp = VolumePresentation.Relative, double binWidth = 0.1) { return(plan.GetDVHCumulativeData(s, dvp, vp, binWidth)); }
/// <summary> /// Return the compliment dose (coldspot) for a given volume. This is equivalent to taking the total volume of the /// object and subtracting the input volume /// </summary> /// <param name="i">the current planning item</param> /// <param name="s">the input structure</param> /// <param name="volume">the volume to query</param> /// <param name="vPres">the volume presentation of the input volume</param> /// <param name="dPres">the dose presentation to return</param> /// <returns>Return the coldspot dose for a given volume.</returns> public static DoseValue GetDoseComplimentAtVolume(this PlanningItem i, Structure s, double volume, VolumePresentation vPres, DoseValuePresentation dPres) { return(i.GetDoseComplimentAtVolume(new[] { s }, volume, vPres, dPres)); }
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"; } } } } } } } }
public void LoadDVH(Structure structure, PlanSetup plan, DoseValuePresentation dosePresentation, VolumePresentation volPresentation, bool useRapPlanEstim = false) { BinSize = Convert.ToDouble(Myconfig.GetAppKey("DVHBinSize")); DVHData apiDVH = null; EstimatedDVH upEstDVH = null; EstimatedDVH lowEstDVH = null; if (volPresentation == VolumePresentation.AbsoluteCm3) { VolumeUnit = MyDVHData.VolumeUnits.cc; } else if (volPresentation == VolumePresentation.Relative) { VolumeUnit = MyDVHData.VolumeUnits.Percent; } else { VolumeUnit = MyDVHData.VolumeUnits.Unknown; } if (useRapPlanEstim) { upEstDVH = plan.DVHEstimates.FirstOrDefault(s => s.Structure.Id == structure.Id && s.Type == DVHEstimateType.Upper); lowEstDVH = plan.DVHEstimates.FirstOrDefault(s => s.Structure.Id == structure.Id && s.Type == DVHEstimateType.Lower); if (upEstDVH == null || lowEstDVH == null) { CurveData = null; return; } //TODO calc these from estimated DVH MaxDose = 0; MeanDose = 0; DoseUnit = (MyDVHData.DoseUnits)lowEstDVH.CurveData[0].DoseValue.Unit; CurveData = new DVHPoint[lowEstDVH.CurveData.Count()]; for (int i = 0; i < lowEstDVH.CurveData.Count(); i++) { double dose = lowEstDVH.CurveData[i].DoseValue.Dose; double volume = 0.5 * (lowEstDVH.CurveData[i].Volume + upEstDVH.CurveData[i].Volume); CurveData[i] = new DVHPoint { Dose = dose, Volume = volume }; } } else { apiDVH = plan.GetDVHCumulativeData(structure, dosePresentation, volPresentation, BinSize); if (apiDVH == null) { MessageBox.Show("Plan " + plan.Id + " contains no dose\nCannot calculate metrics", "Invalid data", MessageBoxButton.OK, MessageBoxImage.Information); return; } MaxDose = apiDVH.MaxDose.Dose; MeanDose = apiDVH.MeanDose.Dose; DoseUnit = (MyDVHData.DoseUnits)apiDVH.CurveData[0].DoseValue.Unit; CurveData = new DVHPoint[apiDVH.CurveData.Count()]; for (int i = 0; i < apiDVH.CurveData.Count(); i++) { CurveData[i] = new DVHPoint { Dose = apiDVH.CurveData[i].DoseValue.Dose, Volume = apiDVH.CurveData[i].Volume }; } } }
public static string GetMinMaxMean(StructureSet structureSet, PlanningItemViewModel planningItem, Structure evalStructure, MatchCollection testMatch, Group evalunit, Group type) { if (type.Value.CompareTo("Volume") == 0) { return(string.Format("{0:0.00} {1}", evalStructure.Volume, evalunit.Value)); } else { double planSumRxDose = 0; DVHData dvh; DoseValuePresentation dvp = (evalunit.Value.CompareTo("%") == 0) ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute; if (dvp == DoseValuePresentation.Relative && planningItem.PlanningItemObject is PlanSum) { PlanSum planSum = (PlanSum)planningItem.PlanningItemObject; foreach (PlanSetup planSetup in planSum.PlanSetups) { double planSetupRxDose = planSetup.TotalDose.Dose; planSumRxDose += planSetupRxDose; } dvh = planningItem.PlanningItemObject.GetDVHCumulativeData(evalStructure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.1); } else { dvh = planningItem.PlanningItemObject.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)) { return(new DoseValue(dvh.MaxDose.Dose / 100, DoseValue.DoseUnit.Gy).ToString()); } //Gy to Gy or % to % else { if (dvp == DoseValuePresentation.Relative && planningItem.PlanningItemObject is PlanSum) { double maxDoseDouble = double.Parse(dvh.MaxDose.ValueAsString); //double return((maxDoseDouble / planSumRxDose * 100).ToString("0.0") + " " + evalunit.Value); } else { return(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)) { return(new DoseValue(dvh.MinDose.Dose / 100, DoseValue.DoseUnit.Gy).ToString()); } //Gy to Gy or % to % else { return(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)) { return(new DoseValue(dvh.MeanDose.Dose / 100, DoseValue.DoseUnit.Gy).ToString()); } //Gy to Gy or % to % else { return(dvh.MeanDose.ToString()); } } } }
public Task <double> GetDoseAtVolume(string StructureId, double ConstraintValue, VolumePresentation VP, DoseValuePresentation DVP) { switch (PlanType) { case ComponentTypes.Plan: return(A.ExecuteAsync(new Func <PlanSetup, double>((p) => { return (p.GetDoseAtVolume(_Structures[StructureId], ConstraintValue, VP, DVP)).Dose; }), p)); case ComponentTypes.Sum: return(A.ExecuteAsync(new Func <PlanSum, double>((ps) => { return (ps.GetDoseAtVolume(_Structures[StructureId], ConstraintValue, VP, DVP)).Dose; }), ps)); default: return(null); } }
///////////////////////////////// // Evaluation helper functions // ///////////////////////////////// // Calculate the dose at volume private string EvaluateDoseAtVolume(Structure evalStructure, PlanningItem plan, ref List <string> warnings) { string achieved; // Calculate results VolumePresentation vp = (DVHUnit == "%") ? VolumePresentation.Relative : VolumePresentation.AbsoluteCm3; double volume = double.Parse(DVHEvalPt); DoseValuePresentation dvpFinal = (DVHEvalUnit == "%" && plan.GetType().Name != "PlanSum") ? DoseValuePresentation.Relative : DoseValuePresentation.Absolute; DoseValue dvAchieved = plan.GetDoseAtVolume(evalStructure, volume, vp, dvpFinal); // Check if dose is undefined if (dvAchieved.IsUndefined()) { // 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(""); } // Check dose output unit and adapting to template if (dvAchieved.UnitAsString.CompareTo(DVHEvalUnit.ToString()) != 0) { // Convert the acheived dose value to Gy because it wants Gy units. if ((DVHEvalUnit.CompareTo("Gy") == 0) && (dvAchieved.Unit.CompareTo(DoseValue.DoseUnit.cGy) == 0)) { //this is valid for V15 because we should return Gy if the user wants the value in Gy. dvAchieved = new DoseValue(dvAchieved.Dose / 100, DoseValue.DoseUnit.Gy); } else { if (plan.GetType().Name == "PlanSum" && DVHEvalUnit.CompareTo("%") == 0) { if ((DVHEvalUnit.CompareTo("%") == 0) && (dvAchieved.Unit.CompareTo(DoseValue.DoseUnit.cGy) == 0)) { //this is valid for V15 because we should return Gy if the user wants the value in Gy. dvAchieved = new DoseValue(dvAchieved.Dose / 100, DoseValue.DoseUnit.Gy); } } else { throw new ApplicationException("Internal error: Inside else loop"); } } } // Return result achieved = !dvAchieved.IsUndefined() ? dvAchieved.ToString() : ""; if (plan is PlanSum && DVHEvalUnit.CompareTo("%") == 0) { warnings.Add("Relative dose changed to Gy."); } return(achieved); }