// Use regular expressions to determine the type of the metric public void DetermineMetricType() { // Parse the objective if (!String.IsNullOrEmpty(DVHObjective)) { var testMatch = objectiveDictionary.Where(x => x.Key.IsMatch(DVHObjective)); if (testMatch.Count() == 1) { // Found a match for a known objective type. var match = testMatch.First().Key.Matches(DVHObjective)[0]; DVHType = testMatch.First().Value; DVHEvalUnit = match.Groups["evalunit"].Value; DVHEvalPt = match.Groups["evalpt"].Value; DVHUnit = match.Groups["unit"].Value; Console.WriteLine("expression {0} => type = {1}, evalPoint = {2}, unit = {3}, evalUnit = {4}", DVHObjective, DVHType, DVHEvalPt, DVHUnit, DVHEvalUnit); // Fix case if needed. List <string> fixcase = new List <string> { "cGy", "Gy", "cc", "%" }; DVHEvalUnit = fixcase.Where(x => x.ToUpper().CompareTo(DVHEvalUnit.ToUpper()) == 0).FirstOrDefault(); DVHUnit = fixcase.Where(x => x.ToUpper().CompareTo(DVHUnit.ToUpper()) == 0).FirstOrDefault(); } } // Parse the Evaluator string eval_pattern = @"^(?<type><|<=|=|>=|>)(?<goal>\d+\p{P}\d+|\d+)$"; if (!String.IsNullOrEmpty(Evaluator)) //Variables remain null if empty { var matches = Regex.Matches(Evaluator, eval_pattern); if (matches.Count == 1) { DVHEvalValue = matches[0].Groups["goal"].ToString(); DVHEvalType = matches[0].Groups["type"].ToString(); } else //If no match, set to not recognized { DVHEvalValue = "Not recognized"; DVHEvalType = "Not recognized"; } } // Parse the Variation string variation_pattern = @"^(\d+\p{P}\d+|\d+)$"; if (!String.IsNullOrEmpty(Variation)) //Variables remain null if empty or no match { var matches = Regex.Matches(Variation, variation_pattern); if (matches.Count == 1) { DVHVariation = matches[0].Value; } else { DVHVariation = "Not recognized"; } } }
// Evaluate covered dose at Volume. private string EvaluateCoveredDoseAtVolume(Structure evalStructure, PlanningItem plan, ref List <string> warnings) { // Covered Dose at Volume DCxcc is equivalent to D(V_tot - x)cc double Vtot = evalStructure.Volume; double doseEvalPt = (DVHUnit.CompareTo("cc") == 0) ? Vtot - double.Parse(DVHEvalPt) : 100 - double.Parse(DVHEvalPt); StructureObjective tmp = new StructureObjective() { DVHUnit = DVHUnit, DVHEvalPt = string.Format("{0:0.00}", doseEvalPt), DVHEvalUnit = DVHEvalUnit }; return(tmp.EvaluateDoseAtVolume(evalStructure, plan, ref warnings)); }
// 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); }