public static DoseValue DoseAtVolume(DVHData dvhData, double volume, DoseValue?psumTotalDose = null) { if (dvhData == null || dvhData.CurveData.Count() == 0) { return(DoseValue.UndefinedDose()); } double absVolume = dvhData.CurveData[0].VolumeUnit == "%" ? volume * dvhData.Volume * 0.01 : volume; if (volume < 0.0 || absVolume > dvhData.Volume) { return(DoseValue.UndefinedDose()); } DVHPoint[] hist = dvhData.CurveData; for (int i = 0; i < hist.Length; i++) { if (hist[i].Volume < volume) { if (psumTotalDose == null) { return(hist[i].DoseValue); } else { return(new DoseValue(hist[i].DoseValue.Dose / ((DoseValue)psumTotalDose).Dose * 100, DoseValue.DoseUnit.Percent)); } } } return(DoseValue.UndefinedDose()); }
/// <summary> /// Returns the min dose from the dvh curve /// </summary> /// <param name="dvh">the dvh curve</param> /// <returns>the minimum dose in the same units as the curve</returns> public static DoseValue MinDose(this DVHPoint[] dvh) { if (dvh.Any()) { var unit = dvh.First().DoseValue.Unit; var minVal = dvh.Min(d => d.DoseValue.Dose); return(new DoseValue(minVal, unit)); } return(DoseValue.UndefinedDose()); }
/// <summary> /// Gets the dose value at the specified volume for the curve /// </summary> /// <param name="dvh">the dvhPoint array that is queried</param> /// <param name="volume">the volume in the same units as the DVH curve</param> /// <returns></returns> public static DoseValue GetDoseAtVolume(this DVHPoint[] dvh, double volume) { var minVol = dvh.Min(d => d.Volume); var maxVol = dvh.Max(d => d.Volume); //Check for max point dose scenario if (volume <= minVol) { return(dvh.MaxDose()); } //Check dose to total volume scenario (min dose) if (volume == maxVol) { return(dvh.MinDose()); } //Overvolume scenario, undefined if (volume > maxVol) { return(DoseValue.UndefinedDose()); } //Convert to list so we can grab indices var dvhList = dvh.ToList(); //Find the closest point to the requested volume, //If its really close, let's use it instead of interpolating var minVolumeDiff = dvhList.Min(d => Math.Abs(d.Volume - volume)); var closestPoint = dvhList.First(d => Math.Abs(d.Volume - volume) == minVolumeDiff); if (minVolumeDiff < 0.001) { return(closestPoint.DoseValue); } //Interpolate var index1 = dvhList.IndexOf(closestPoint); var index2 = closestPoint.Volume < volume ? index1 - 1 : index1 + 1; if (index1 >= 0 && index2 < dvh.Count()) { var point1 = dvhList[index1]; var point2 = dvhList[index2]; var doseAtPoint = Interpolate(point1.Volume, point2.Volume, point1.DoseValue.Dose, point2.DoseValue.Dose, volume); return(new DoseValue(doseAtPoint, point1.DoseValue.Unit)); } return(new DoseValue(double.NaN, closestPoint.DoseValue.Unit)); throw new Exception(string.Format( "Interpolation failed. Index was : {0}, DVH Point Count : {1}, Volume was {2}, ClosestVol was {3}", index1, dvh.Count(), volume, minVolumeDiff)); }
/// <summary> /// Returns the mean dose from the dvh curve /// </summary> /// <param name="dvh">the dvh curve</param> /// <returns>the mean dose in the same units as the curve</returns> public static DoseValue MeanDose(this DVHPoint[] dvh) { if (dvh.Any()) { var unit = dvh.First().DoseValue.Unit; dvh = dvh.Differential(); var sum = dvh.Sum(d => d.Volume * d.DoseValue.Dose); var totalVolume = dvh.Sum(d => d.Volume); var meanVal = sum / totalVolume; return(new DoseValue(meanVal, unit)); } return(DoseValue.UndefinedDose()); }
public static DoseValue DoseAtVolume(DVHData dvhData, double volume) { if (dvhData == null || dvhData.CurveData.Count() == 0) { return(DoseValue.UndefinedDose()); } double absVolume = dvhData.CurveData[0].VolumeUnit == "%" ? volume * dvhData.Volume * 0.01 : volume; if (volume < 0.0 || absVolume > dvhData.Volume) { return(DoseValue.UndefinedDose()); } DVHPoint[] hist = dvhData.CurveData; for (int i = 0; i < hist.Length; i++) { if (hist[i].Volume < volume) { return(hist[i].DoseValue); } } return(DoseValue.UndefinedDose()); }