/// Calculates the RTOG conformity index as isodose volume irradiated at reference dose (Body contour volume irradiated) /// divided by the target volume. Does not necessarily mean the volumes are coincident! /// </summary> /// <param name="s">the target structure</param> /// <param name="pi">the planning item containing the dose</param> /// <param name="referenceDose">the reference isodose (eg. prescription dose)</param> /// <returns>RTOG conformity index</returns> public static double GetCI_RTOG(ESAPIX.Facade.API.Structure s, ESAPIX.Facade.API.PlanningItem pi, DoseValue referenceDose) { var external = pi.GetStructureSet()?.Structures.FirstOrDefault(st => st.DicomType == DICOMType.EXTERNAL); if (external == null) { return(double.NaN); } var prescription_volIsodose = pi.GetVolumeAtDose(external, referenceDose, VolumePresentation.AbsoluteCm3); var target_vol = s.Volume; return(prescription_volIsodose / target_vol); }
/// <summary> /// Converts the dose to the system units. It cannot convert from % to abs dose. Will return NaN if asked /// </summary> /// <param name="dv">the dose value to be converted</param> /// <param name="unit">the unit desired for the returned dose</param> /// <returns>the dose in the desired units</returns> public static DoseValue ConvertToSystemUnits(this DoseValue dv, ESAPIX.Facade.API.PlanningItem pi) { var newDv = new DoseValue(dv.Dose, dv.Unit); if (dv.GetPresentation() != DoseValuePresentation.Relative) { // Need to convert to system units first (ugh!) var oldPresentation = pi.DoseValuePresentation; pi.DoseValuePresentation = DoseValuePresentation.Absolute; if (pi?.Dose != null) { var systemUnits = pi.Dose.DoseMax3D.Unit; pi.DoseValuePresentation = oldPresentation; //Thanks ESAPIX! newDv = dv.ConvertUnits(systemUnits); } else { throw new Exception("Cannot determine system units for dose. Plan dose is null"); } } return(newDv); }