public double GetDoseAtVolumeForUncertainties(curve DVH, double Volume, VolumePresentation VolPres, DoseValuePresentation RequestedDosePresentation) { double dose; if (DVH.VolumePresentation == VolumePresentation.AbsoluteCm3 && VolPres == VolumePresentation.Relative) { Volume = Volume * DVH.AbsoluteStructureVolume / 100.0; } if (DVH.VolumePresentation == VolumePresentation.Relative && VolPres == VolumePresentation.AbsoluteCm3) { Volume = Volume / DVH.AbsoluteStructureVolume * 100.0; } int ind1 = DVH.CurveData.Select(x => x.Volume).Count() - DVH.CurveData.Where(x => x.Volume < Volume).Select(x => x.Volume).Count() - 1; int ind2 = DVH.CurveData.Select(x => x.Volume).Count() - DVH.CurveData.Where(x => x.Volume < Volume).Select(x => x.Volume).Count(); DVHPoint DVP1 = DVH.CurveData.ElementAt(ind1); DVHPoint DVP2 = DVH.CurveData.ElementAt(ind2); dose = Interpolate(DVP1.Volume, DVP2.Volume, DVP1.DoseValue.Dose, DVP2.DoseValue.Dose, Volume); if (DVH.DoseValuePresentation == DoseValuePresentation.Absolute && RequestedDosePresentation == DoseValuePresentation.Relative) { dose = dose / DVH.PrescribedDose * 100.0; } if (DVH.DoseValuePresentation == DoseValuePresentation.Relative && RequestedDosePresentation == DoseValuePresentation.Absolute) { dose = dose * DVH.PrescribedDose / 100.0; } return(dose); }
/// <summary> /// Converts cumulative to differntial /// </summary> /// <param name="dvh">the dvh curve</param> /// <returns>the differential dvh</returns> public static DVHPoint[] Differential(this DVHPoint[] dvh) { var maxDose = dvh.MaxDose(); var volumeUnit = dvh.First().VolumeUnit; var minDose = dvh.MinDose(); List <DVHPoint> differential = new List <DVHPoint>(); for (int i = 0; i < dvh.Length - 1; i++) { var pt1 = dvh[i]; var pt2 = dvh[i + 1]; var vol = pt1.Volume - pt2.Volume; var dose = pt2.DoseValue.Dose - pt1.DoseValue.Dose; var ddvh = vol / dose; differential.Add(new DVHPoint(pt1.DoseValue, ddvh, volumeUnit)); } //Normalize var max = differential.Max(d => d.Volume); for (int i = 0; i < differential.Count; i++) { var dv = differential[i]; differential[i] = new DVHPoint(dv.DoseValue, dv.Volume / max, dv.VolumeUnit); } return(differential.ToArray()); }
private void exportDVH(PlanSetup plan, Structure target, string fileName) { // extract DVH data DVHData dvhData = plan.GetDVHCumulativeData(target, DoseValuePresentation.Relative, VolumePresentation.AbsoluteCm3, 0.1); if (dvhData == null) { throw new ApplicationException("No DVH data for target '" + target.Id + "'."); } // export DVH data as a CSV file using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fileName, false, Encoding.ASCII)) { // write the header, assume the first dvh point represents the others DVHPoint rep = dvhData.CurveData[0]; sw.WriteLine( string.Format("Relative dose [{0}],Structure volume [{1}],", rep.DoseValue.UnitAsString, rep.VolumeUnit) ); // write each row of dose / volume data foreach (DVHPoint pt in dvhData.CurveData) { sw.WriteLine(string.Format("{0:0.0},{1:0.00000}", pt.DoseValue.Dose, pt.Volume)); } } }
/// <summary> /// If appropriate, converts the DVH curve into relative dose points instead of absolute dose /// </summary> /// <param name="dvh">the input DVH</param> /// <param name="scalingPoint">the dose value which represents 100%, all doses will be scaled in reference to this</param> /// <returns>the dvh with relative dose points</returns> public static DVHPoint[] ConvertToRelativeDose(this DVHPoint[] dvh, DoseValue scalingPoint) { if (dvh.Any() && dvh.First().DoseValue.Unit == DoseValue.DoseUnit.Percent) { return(dvh); //Already in relative format } for (var i = 0; i < dvh.Length; i++) { var dv = new DoseValue(dvh[i].DoseValue.Divide(scalingPoint).Dose * 100, DoseValue.DoseUnit.Percent); dvh[i] = new DVHPoint(dv, dvh[i].Volume, dvh[i].VolumeUnit); } return(dvh); }
public void SerializeDeserializeDVHPoint() { var doseValue = new DoseValue(25, DoseValue.DoseUnit.Gy); var dp = new DVHPoint(doseValue, 30, "cc"); var serialized = FacadeSerializer.Serialize(dp); var deserialized = FacadeSerializer.Deserialize <DVHPoint>(serialized); Assert.AreEqual(deserialized.DoseValue, doseValue); Assert.AreEqual(deserialized.Volume, dp.Volume); Assert.AreEqual(deserialized.VolumeUnit, dp.VolumeUnit); }
/// <summary> /// If appropriate, converts the DVH curve into relative volume points instead of absolute volume /// </summary> /// <param name="dvh">the input DVH</param> /// <returns>the dvh with relative volume points</returns> public static DVHPoint[] ConvertToRelativeVolume(this DVHPoint[] dvh) { var maxVol = dvh.Max(d => d.Volume); if (dvh.Any() && dvh.First().VolumeUnit != "%") { for (int i = 0; i < dvh.Length; i++) { dvh[i] = new DVHPoint(dvh[i].DoseValue, 100 * dvh[i].Volume / maxVol, "%"); } } return(dvh); }
public void MeanDoseTest() { var dvh = new DVHPoint[] { new DVHPoint(new DoseValue(0, cGy), 0, "cc"), new DVHPoint(new DoseValue(50, cGy), 0, "cc"), new DVHPoint(new DoseValue(100, cGy), 0, "cc") }; var actual = dvh.MeanDose(); var expected = new DoseValue(50, cGy); Assert.AreEqual(expected.Dose, actual.Dose, 0.0001); }
public void ConvertToRelativeVolumeTest() { var dvh = new DVHPoint[] { new DVHPoint(new DoseValue(0, cGy), 0, "cc"), new DVHPoint(new DoseValue(100, cGy), 100, "cc"), new DVHPoint(new DoseValue(200, cGy), 200, "cc") }; var relative = dvh.ConvertToRelativeVolume(); Assert.AreEqual(relative[0].Volume, 0, 0.0001); Assert.AreEqual(relative[1].Volume, 50, 0.0001); Assert.AreEqual(relative[2].Volume, 100, 0.0001); }
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 jValue = (JObject)jo[nameof(DVHPoint.DoseValue)]; var value = serializer.Deserialize <DoseValue>(jValue.CreateReader()); var vol = (double)jo[nameof(DVHPoint.Volume)]; var unit = (string)jo[nameof(DVHPoint.VolumeUnit)]; // Construct the Result object using the non-default constructor var dp = new DVHPoint(value, vol, unit); // Return the result return(dp); }
/// <summary> /// Merges DVHData from multiple structures into one DVH by summing the volumes at each dose value /// </summary> /// <param name="dvhs"></param> /// <returns></returns> public static DVHPoint[] MergeDVHs(this IEnumerable <DVHData> dvhs) { var maxLength = dvhs.Max(d => d.CurveData.Length); var maxDVH = dvhs.First(d => d.CurveData.Length == maxLength); var mergedDVH = maxDVH.CurveData.Select(d => new DVHPoint(d.DoseValue, 0, d.VolumeUnit)).ToArray(); var volUnit = dvhs.First().CurveData.First().VolumeUnit; if (volUnit == "%") { throw new ArgumentException("Cannot merge relative DVHs. Must be in absolute volume format"); } foreach (var dvh in dvhs) { for (int i = 0; i < dvh.CurveData.Length; i++) { var current = dvh.CurveData[i]; mergedDVH[i] = new DVHPoint(current.DoseValue, current.Volume + mergedDVH[i].Volume, current.VolumeUnit); } } return(mergedDVH); }
/// <summary> /// Merges DVHData from multiple structures into one DVH by summing the volumes at each dose value /// </summary> /// <param name="dvhs">the multiple dvh curves to merge</param> /// <returns>the combined dvh from multiple structures</returns> public static DVHPoint[] MergeDVHs(this IEnumerable <DVHPoint[]> dvhs) { //The merged DVH must be the same length as the maximum length DVH input var maxLength = dvhs.Max(d => d.Length); var maxDVH = dvhs.First(d => d.Length == maxLength); var mergedDVH = maxDVH.Select(d => new DVHPoint(d.DoseValue, 0, d.VolumeUnit)).ToArray(); //Lets check units before we continue var volUnit = dvhs.First().First().VolumeUnit; var doseUnit = dvhs.First().First().DoseValue.Unit; if (dvhs.Any(d => d.First().DoseValue.Unit != doseUnit)) { throw new ArgumentException("Cannot merge relative DVHs. All DVHs must have the same dose units"); } if (dvhs.Any(d => d.First().VolumeUnit != volUnit)) { throw new ArgumentException("Cannot merge relative DVHs. All DVHs must have the same volume units"); } if (volUnit == MagicStrings.VolumeUnits.PERCENT) { throw new ArgumentException("Cannot merge relative DVHs. Must be in absolute volume format"); } //Everything looks good, let's do it foreach (var dvh in dvhs) { for (var i = 0; i < dvh.Length; i++) { var current = dvh[i]; mergedDVH[i] = new DVHPoint(current.DoseValue, current.Volume + mergedDVH[i].Volume, current.VolumeUnit); } } return(mergedDVH); }
public static DataPoint CreateDataPoint(DVHPoint dvhPoint) { return(new DataPoint(dvhPoint.DoseValue.Dose, dvhPoint.Volume)); }
private DataPoint CreateDataPoint(DVHPoint p) { return(new DataPoint(p.DoseValue.Dose, p.Volume)); }
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 }; } } }