private static void CreateVerificationPlan(Common.Model.API.Application app, ExternalPlanSetup verifiedPlan, StructureSet verificationStructures) { var course = Helpers.GetCourse(verifiedPlan.Course.Patient, VerificationCourseId); Trace.WriteLine("\nCreating verification plans...\n"); // Create an individual verification plan for each field. foreach (var beam in verifiedPlan.Beams) { PlanGeneration.CreateVerificationPlan(course, new List <Beam> { beam }, verifiedPlan, verificationStructures, beam.Id, calculateDose: false); } // Create a verification plan that contains all fields. PlanGeneration.CreateVerificationPlan(course, verifiedPlan.Beams, verifiedPlan, verificationStructures, "All fields", calculateDose: true); }
private static void Execute(Common.Model.API.Application app, string patientId, string planId) { var patient = app.OpenPatientById(patientId); patient.BeginModifications(); if (!Helpers.CheckStructures(patient)) { return; } // The demo patient has structures in a set structure called "Prostate". var structures = patient.StructureSets.Single(st => st.Id == "Prostate"); var course = Helpers.GetCourse(patient, CourseId); // If old courses exists, remove them. Remove also the structures generated by the script (in the previous run). Helpers.RemoveOldPlan(course, planId); Helpers.RemoveStructures(structures, new List <string> { "PTV", PlanGeneration.ExpandedCTVId, PlanGeneration.PTVSubOARSId }); // Launch the prescription dialog. var prescriptionDialog = new PrescriptionDialog(patientId, DefaultDosePerFraction, DefaultNumberOfFractions, DefaultMarginForPTVInMM, structures.Structures) { Width = 300, Height = 350 }; double?dosePerFraction = null; int? numberOfFractions = null; double?marginForPTV = null; string ctvId = string.Empty; prescriptionDialog.Closed += (s, e) => { dosePerFraction = prescriptionDialog.DosePerFraction; numberOfFractions = prescriptionDialog.NumberOfFractions; marginForPTV = prescriptionDialog.PTVMargin; ctvId = prescriptionDialog.SelectedStructure; }; prescriptionDialog.ShowDialog(); // If the user inputs are valid, proceed to plan creation. if (dosePerFraction.HasValue && numberOfFractions.HasValue && marginForPTV.HasValue && ctvId != string.Empty) { // Create new plan. var plan = course.AddExternalPlanSetup(structures); plan.Id = planId; // Re-direct output from trace to console. Trace.Listeners.Add(new ConsoleTraceListener()); // Beam geometry generation. PlanGeneration.GenerateBeamGeometry(plan, dosePerFraction != null ? dosePerFraction.Value : 0, numberOfFractions != null ? numberOfFractions.Value : 0, marginForPTV != null ? marginForPTV.Value : 0, ctvId); // DVH estimation. var structureMatches = PlanGeneration.GetStructureMatches(plan); structureMatches.Remove(PlanGeneration.ExpandedCTVId); structureMatches.Add(PlanGeneration.PTVSubOARSId, new ModelStructure("PTV", ModelStructureType.Target)); PlanGeneration.CalculateDVHEstimates(plan, structureMatches); // Add normal tissue objectives. PlanGeneration.AddNTO(plan); // Save beam geometry and DVH estimation results. var message = "Beam geometry generation and DVH estimation completed."; SaveAndShowMessage(app, message); // Optimization. PlanGeneration.Optimize(plan); // Save optimization results. message = "Optimization completed."; SaveAndShowMessage(app, message); // Caluclate dose. PlanGeneration.CalculateDose(plan); Trace.WriteLine("\nPlan successfully generated.\n"); // Normalize plan. PlanGeneration.Normalize(plan, structureMatches); app.SaveModifications(); // Report DVHs. var outputPath = @"C:\Temp\dvh.svg"; const string browser = @"C:\Program Files (x86)\Mozilla Firefox\firefox.exe"; var structuresForReporting = plan.StructureSet.Structures.Where(st => structureMatches.ContainsKey(st.Id)); const int dvhWidth = 512; const int dvhHeight = 256; SVGFromDVH.SaveSVGFromStructures(outputPath, plan, structuresForReporting, dvhWidth, dvhHeight); outputPath = @"C:\Temp"; var reportLocation = PlanQualityReporter.CreateReport(plan, structureMatches, outputPath); Trace.WriteLine("\nReport successfully generated.\n"); // Display the generated report in web browser. Process.Start(browser, reportLocation); Thread.Sleep(1000); // Ask user if we want to proceed to plan verification. const string title = "Quality assurance"; message = "Proceed to creation of verification plan?"; var res = MessageBox.Show(new Window { Topmost = true }, message, title, MessageBoxButton.YesNo, MessageBoxImage.Question); if (res == MessageBoxResult.Yes) { // Create verification plan. Trace.Write("\nRetrieving CT image of the QA device...\n"); var qaStructures = patient.StructureSets.Where(set => set.Id == VerificationPatientImageId).ToList(); // If we have already loaded the structures for verification, do not load them again. Currently, ESAPI doesn't offer methods to remove them... (has to be done by hand in Eclipse). var verificationStructures = qaStructures.Any() ? qaStructures.First() : plan.Course.Patient.CopyImageFromOtherPatient(VerificationPatientId, VerificationPatientStudyId, VerificationPatientImageId); CreateVerificationPlan(app, plan, verificationStructures); app.SaveModifications(); Trace.WriteLine("\nVerification plans succesfully created.\n"); } Trace.WriteLine("\nScript successfully executed.\n"); } else { const string message = "Please provide a valid prescription."; const string title = "Invalid prescription"; MessageBox.Show(message, title, MessageBoxButton.OK, MessageBoxImage.Error); } }