public string CalculateMetricDose(Patient patient, string courseId, string planId, string structureId, PQMViewModel objective) { var plan = Extensions.GetPlanningItem(patient, courseId, planId); var planVM = new PlanningItemViewModel(plan); var structure = Extensions.GetStructure(plan, structureId); DirectoryInfo constraintDir = new DirectoryInfo(Path.Combine(AssemblyHelper.GetAssemblyDirectory(), "ConstraintTemplates")); string firstFileName = constraintDir.GetFiles().FirstOrDefault().ToString(); string firstConstraintFilePath = Path.Combine(constraintDir.ToString(), firstFileName); // make sure the workbook template exists if (!System.IO.File.Exists(firstConstraintFilePath)) { System.Windows.MessageBox.Show(string.Format("The template file '{0}' chosen does not exist.", firstConstraintFilePath)); } var structureVM = new StructureViewModel(structure); string metric = ""; var goal = ""; string result = ""; string variation = ""; if (objective.TemplateId == structureId) { metric = objective.DVHObjective; goal = objective.Goal; variation = objective.Variation; result = _metricCalc.CalculateMetric(planVM.PlanningItemStructureSet, structureVM, planVM, metric); } else { result = ""; } return(result); }
public StructureSetViewModel(StructureSet structureSet) { var StructureList = new ObservableCollection <StructureViewModel>(); foreach (Structure structure in structureSet.Structures) { if (!structure.IsEmpty && structure.DicomType != "SUPPORT") { var structureViewModel = new StructureViewModel(structure); StructureList.Add(structureViewModel); } } StructureList = new ObservableCollection <StructureViewModel>(StructureList.OrderBy(x => x.StructureId)); }
public static string GetCoveredDoseAtVolume(StructureSet structureSet, PlanningItemViewModel planningItem, StructureViewModel evalStructure, MatchCollection testMatch, Group evalunit) { System.Console.WriteLine("Covered Dose at Volume"); return("Not supported"); }
public static string GetMinMaxMean(StructureSet structureSet, PlanningItemViewModel planningItem, StructureViewModel evalStructure, MatchCollection testMatch, Group evalunit, Group type) { if (type.Value.CompareTo("Volume") == 0) { return(string.Format("{0:0.00} {1}", evalStructure.Structure.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.Structure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.1); } else { dvh = planningItem.PlanningItemObject.GetDVHCumulativeData(evalStructure.Structure, 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 static string GetCoveredVolumeAtDose(StructureSet structureSet, PlanningItemViewModel planningItem, StructureViewModel evalStructure, MatchCollection testMatch, Group evalunit) { //check for sufficient sampling and dose coverage DVHData dvh = planningItem.PlanningItemObject.GetDVHCumulativeData(evalStructure.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(evalStructure.Structure, dv, vpFinal); double organVolume = evalStructure.Structure.Volume; double coveredVolume = organVolume - volumeAchieved; return(string.Format("{0:0.00} {1}", coveredVolume, evalunit.Value)); // todo: better formatting based on VolumePresentation }
public static string GetVolumeAtDose(StructureSet structureSet, PlanningItemViewModel planningItem, StructureViewModel evalStructure, MatchCollection testMatch, Group evalunit) { //check for sufficient sampling and dose coverage DVHData dvh = planningItem.PlanningItemObject.GetDVHCumulativeData(evalStructure.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(evalStructure.Structure, 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 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"); } }
public static string GetConformationNumber(StructureSet structureSet, PlanningItemViewModel planningItem, StructureViewModel evalStructure, MatchCollection testMatch, Group evalunit) { DVHData dvh = planningItem.PlanningItemObject.GetDVHCumulativeData(evalStructure.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(evalStructure.Structure, dv, vpFinal); double targetVolume = evalStructure.Structure.Volume; var cn = (targetWithPrescribedDoseVolume / targetVolume) * (targetWithPrescribedDoseVolume / bodyWithPrescribedDoseVolume); return(string.Format("{0:0.0}", cn)); }
public string CalculateMetric(StructureSet structureSet, StructureViewModel evalStructure, PlanningItemViewModel planningItem, string DVHObjective) { //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[%] string cn_pattern = @"^CN(?<evalpt>\d+\p{P}\d+|\d+)(?<unit>(%|Gy|cGy))$"; //matches CN50% string gi_pattern = @"^GI(?<evalpt>\d+\p{P}\d+|\d+)(?<unit>(%|Gy|cGy))$"; //matches GI50% //Structure evalStructure = ; if (evalStructure == null) { return("Structure not found"); } //start with a general regex that pulls out the metric type and the [evalunit] part. var matches = Regex.Matches(DVHObjective, pattern); if (matches.Count != 1) { return(string.Format("DVH Objective expression \"{0}\" is not a recognized expression type.", DVHObjective)); } Match m = matches[0]; Group type = m.Groups["type"]; Group evalunit = m.Groups["evalunit"]; Console.WriteLine("expression {0} => type = {1}, unit = {2}", DVHObjective, type.Value, evalunit.Value); // 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) { testMatch = Regex.Matches(type.Value, cn_pattern); if (testMatch.Count != 1) { testMatch = Regex.Matches(type.Value, gi_pattern); if (testMatch.Count != 1) { return(string.Format("DVH Objective expression \"{0}\" is not a recognized expression type.", DVHObjective)); } else { // we have Gradient Index pattern return(PQMGradientIndex.GetGradientIndex(structureSet, planningItem, evalStructure, testMatch, evalunit)); } } else { // we have Conformation Number pattern return(PQMConformationNumber.GetConformationNumber(structureSet, planningItem, evalStructure, testMatch, evalunit)); } } else { // we have Covered Dose at Volume pattern return(PQMCoveredDoseAtVolume.GetCoveredDoseAtVolume(structureSet, planningItem, evalStructure, testMatch, evalunit)); } } else { // we have Covered Volume at Dose pattern return(PQMCoveredVolumeAtDose.GetCoveredVolumeAtDose(structureSet, planningItem, evalStructure, testMatch, evalunit)); } } else { // we have Dose at Volume pattern return(PQMDoseAtVolume.GetDoseAtVolume(structureSet, planningItem, evalStructure, testMatch, evalunit)); } } else { // we have Volume at Dose pattern return(PQMVolumeAtDose.GetVolumeAtDose(structureSet, planningItem, evalStructure, testMatch, evalunit)); } } else { // we have Min, Max, Mean, or Volume return(PQMMinMaxMean.GetMinMaxMean(structureSet, planningItem, evalStructure, testMatch, evalunit, type)); } }