public void Execute(ScriptContext context /*, System.Windows.Window window, ScriptEnvironment environment*/) { var ss = context.StructureSet; var body = ss.Structures.Single(st => st.DicomType == "EXTERNAL"); var s = SelectStructureWindow.SelectStructure(ss); // A user interface for selecting structure if (s == null) { return; } context.Patient.BeginModifications(); var newStr = EnlargeStructure(s, ss, 30, 20); if (newStr != null) { MessageBox.Show("New structure was created: " + newStr.Id); } else { MessageBox.Show("New structure could not be created"); } }
public void Execute(ScriptContext context /*, System.Windows.Window window, ScriptEnvironment environment*/) { // TODO : Add here your code that is called when the script is launched from Eclipse // check if the plan has dose if (!context.PlanSetup.IsDoseValid) { MessageBox.Show("The plan selected has no valid dose."); return; } // get list of structures for loaded plan StructureSet ss = context.StructureSet; var listStructures = ss.Structures; // define PTV (selected) //Structure ptv = listStructures.Where(x => !x.IsEmpty && x.Id.ToUpper().Contains("PTV1 REKTM")).FirstOrDefault(); //Structure ptv = listStructures.Where(x => x.Id == context.PlanSetup.TargetVolumeID).FirstOrDefault(); var ptv = SelectStructureWindow.SelectStructure(ss); // make sure the volume is non-zero if (ptv.IsEmpty == true) { MessageBox.Show("Target Volume has no contours."); return; } // search for body Structure body = listStructures.Where(x => !x.IsEmpty && (x.DicomType.ToUpper().Equals("EXTERNAL") || x.Id.ToUpper().Equals("KÖRPER") || x.Id.ToUpper().Equals("BODY") || x.Id.ToUpper().Equals("OUTER CONTOUR"))).FirstOrDefault(); if (body == null) { MessageBox.Show("Unbekannte Körper-Struktur-Bezeichnung. Körper, Body oder Outer Contour."); return; } // --- calc Conformity index (CI) DoseValue dose100 = new DoseValue(context.PlanSetup.TreatmentPercentage * 100, DoseValue.DoseUnit.Percent); //DoseValue dose100 = new DoseValue(100, DoseValue.DoseUnit.Percent); DoseValue dose95 = new DoseValue(95, DoseValue.DoseUnit.Percent); double ptv100 = context.PlanSetup.GetVolumeAtDose(ptv, dose100, VolumePresentation.AbsoluteCm3); double v100 = context.PlanSetup.GetVolumeAtDose(body, dose100, VolumePresentation.AbsoluteCm3); double CI = Math.Round(v100 * ptv.Volume / ptv100 / ptv100, 2); double ptv95 = context.PlanSetup.GetVolumeAtDose(ptv, dose95, VolumePresentation.AbsoluteCm3); double v95 = context.PlanSetup.GetVolumeAtDose(body, dose95, VolumePresentation.AbsoluteCm3); double CI95 = Math.Round(v95 * ptv.Volume / ptv95 / ptv95, 2); // --- calc Gradient index (GI) DoseValue dose50 = new DoseValue(context.PlanSetup.TreatmentPercentage * 100 / 2, DoseValue.DoseUnit.Percent); double v50 = context.PlanSetup.GetVolumeAtDose(body, dose50, VolumePresentation.AbsoluteCm3); double GI = Math.Round(v50 / v100, 2); // C# can handle divide-by-zero (double.infinity) so not need to check the situation double GI95 = Math.Round(v50 / v95, 2); // C# can handle divide-by-zero (double.infinity) so not need to check the situation // --- calc Heterogeneity index (HI) // get prescription dose double Dp = context.PlanSetup.DosePerFraction.Dose * context.PlanSetup.NumberOfFractions.Value; double D2 = context.PlanSetup.GetDoseAtVolume(ptv, 2, VolumePresentation.Relative, DoseValuePresentation.Absolute).Dose; double D98 = context.PlanSetup.GetDoseAtVolume(ptv, 98, VolumePresentation.Relative, DoseValuePresentation.Absolute).Dose; double HI = Math.Round((D2 - D98) / Dp, 2); // C# can handle divide-by-zero (double.infinity) so not need to check the situation MessageBox.Show(string.Format("Zielvolumen: {0}\rCI\t= {1}\rCI95\t= {2}\rGI\t= {3}\rGI95\t= {4}\rHI\t= {5}\r\rBemerkung: Es sollte nur ein Zielvolumen geben.\r\rFormeln:\rCI\t= TV*PIV/(TV_PIV)^2)\rCI95\t= TV*V95/(TV_V95)^2)\rGI\t= V50/PIV\rGI95\t= V50/V95\rHI\t= (D_2-D_98)/D_p", ptv.Id, CI, CI95, GI, GI95, HI)); }
public void Execute(ScriptContext context /*, System.Windows.Window window, ScriptEnvironment environment*/) { // Choose structure for DVH-export in all plans or one course of a patient var ss = context.StructureSet; var roi2 = SelectStructureWindow.SelectStructure(ss); if (roi2 == null) { return; } string structureOfInterest = roi2.Id; // Choose Destination-Folder string startPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); var fileDialog = new Microsoft.Win32.OpenFileDialog(); fileDialog.InitialDirectory = startPath; fileDialog.Multiselect = false; fileDialog.Title = "Choose Destination-Folder and press OK"; fileDialog.ShowReadOnly = true; fileDialog.FilterIndex = 0; fileDialog.ValidateNames = false; fileDialog.CheckFileExists = false; fileDialog.CheckPathExists = true; fileDialog.FileName = "Folder Selection."; if (fileDialog.ShowDialog() == false) { return; // user canceled } var filePath = fileDialog.FileName; string outputDestinationDirectory = Path.GetDirectoryName(filePath); //string outputDestinationDirectory = @"C:\Users\mg\Desktop\Skript-Output"; string scriptname = "DVH-Export (all plans)"; // Retrieve patient information Patient patient = context.Patient; // Iterate through all created courses and plans with dosis // Use all courses of a patient. Uncomment this: var courses = patient.Courses.Where(c => c.HistoryDateTime != null).ToList(); // Use specific Course. Uncomment this: // var courses = patient.Courses.Where(c => c.Id.Equals("ProstataOnly")).ToList(); foreach (var course in courses) { // Iterate through alls plans with dose var planSetups = course.PlanSetups.Where(p => (p.Dose != null)).ToList(); foreach (var planSetup in planSetups) { var listStructures = planSetup.StructureSet.Structures; // search for error structure Structure error = listStructures.Where(x => !x.IsEmpty && x.Id.Equals(structureOfInterest)).FirstOrDefault(); if (error == null) { string message2 = string.Format("Can not find {0} in {1}", structureOfInterest, planSetup.Id); MessageBox.Show(message2, scriptname, MessageBoxButton.OK, MessageBoxImage.Exclamation); //return; } // Check for structure of interest var roi = planSetup.StructureSet.Structures.FirstOrDefault(o => o.Id.Equals(structureOfInterest)); if (roi != null) { // extract DVH data for ptv using bin width of 0.1. DVHData dvh = planSetup.GetDVHCumulativeData(roi, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.1); string filename = string.Format(@"{0}\DVH_{1}_{2}_{3}.txt", outputDestinationDirectory, context.Patient.Id, roi.Id, planSetup.Id); // write a header string[] msg = { string.Format("Pat.Id:,{0}", context.Patient.Id), string.Format("Plan.Id:,{0}", planSetup.Id), string.Format("Structure:,{0}", roi.Id), "----,----", "Dose,Volume", "Gy,%" }; System.IO.File.WriteAllLines(filename, msg); // write all dvh points foreach (DVHPoint pt in dvh.CurveData) { string line = string.Format("{0},{1}", pt.DoseValue.Dose, pt.Volume); File.AppendAllText(filename, line + Environment.NewLine); } } } } string message = string.Format("DVH-Export for {0} is finished. \nData saved in: {1}", context.Patient.Id, outputDestinationDirectory); MessageBox.Show(message, scriptname, MessageBoxButton.OK, MessageBoxImage.Information); }
public void Execute(ScriptContext context /*, System.Windows.Window window, ScriptEnvironment environment*/) { if (context.Patient == null || context.StructureSet == null) { MessageBox.Show("Please load a patient, 3D image, and structure set before running this script.", SCRIPT_NAME, MessageBoxButton.OK, MessageBoxImage.Exclamation); return; } string msg1 = ""; string msg2 = ""; StructureSet ss = context.StructureSet; // get list of structures for loaded plan var listStructures = context.StructureSet.Structures; // define PTV (selected) //Structure ptv = listStructures.Where(x => !x.IsEmpty && x.Id.ToUpper().Contains("PTV1 REKTM")).FirstOrDefault(); //Structure ptv = listStructures.Where(x => x.Id == context.PlanSetup.TargetVolumeID).FirstOrDefault(); var ptv = SelectStructureWindow.SelectStructure(ss); if (ptv == null) { return; } else { msg2 += string.Format("'{0}' found \n", ptv.Id); } context.Patient.BeginModifications(); // enable writing with this script. //============================ // FIND OAR //============================ // find Rectum Structure rectum = listStructures.Where(x => !x.IsEmpty && (x.Id.ToUpper().Contains("REKTUM") || x.Id.ToUpper().Contains("RECTUM")) && x.DicomType.Equals("ORGAN") & !x.Id.ToUpper().Contains("HK")).FirstOrDefault(); if (rectum == null) { msg1 += string.Format("Not found: '{0}' \n", "Rektum (OAR)"); } else { msg2 += string.Format("'{0}' found \n", rectum.Id); } // find Blase Structure blase = listStructures.Where(x => !x.IsEmpty && x.Id.ToUpper().Contains("BLASE") && x.DicomType.Equals("ORGAN") & !x.Id.ToUpper().Contains("HK")).FirstOrDefault(); if (blase == null) { msg1 += string.Format("Not found: '{0}' \n", "Blase (OAR)"); } else { msg2 += string.Format("'{0}' found \n", blase.Id); } MessageBox.Show(msg2 + "\n" + msg1, SCRIPT_NAME, MessageBoxButton.OK, MessageBoxImage.Information); //============================ // GENERATE HelpStructures //============================ int RectumHkCount = 1; int BlaseHkCount = 1; foreach (Structure scan in listStructures) { if (scan.Id.ToUpper().Contains("ZHK REKTUM")) { RectumHkCount++; } if (scan.Id.ToUpper().Contains("ZHK BLASE")) { BlaseHkCount++; } } // HK Rektum if (rectum != null) { Structure hk_rectum = ss.AddStructure("CONTROL", "zHK Rektum_" + RectumHkCount); hk_rectum.SegmentVolume = rectum.Margin(8.0); hk_rectum.SegmentVolume = hk_rectum.Sub(ptv); } // HK Blase (german for bladder) if (blase != null) { double x1 = 5; double y1 = 10; double z1 = 15; double x2 = 5; double y2 = 20; double z2 = 8; AxisAlignedMargins margins = new AxisAlignedMargins(StructureMarginGeometry.Outer, x1, y1, z1, x2, y2, z2); Structure hk_blase = ss.AddStructure("CONTROL", "zHK Blase_" + BlaseHkCount); hk_blase.SegmentVolume = blase.AsymmetricMargin(margins); hk_blase.SegmentVolume = hk_blase.Sub(ptv); } //============================ // remove structures unneccesary for optimization //============================ //ss.RemoveStructure(ptv_3mm); //ss.RemoveStructure(ptv_minus); //ss.RemoveStructure(Iso95); }