/// <summary> /// Create verifications plans for a given treatment plan. /// </summary> public static ExternalPlanSetup CreateVerificationPlan(Course course, IEnumerable <Beam> beams, ExternalPlanSetup verifiedPlan, StructureSet verificationStructures, string planId, bool calculateDose) { var verificationPlan = course.AddExternalPlanSetupAsVerificationPlan(verificationStructures, verifiedPlan); verificationPlan.Id = planId; // Put isocenter to the center of the body. var isocenter = verificationStructures.Structures.Single(st => st.Id.ToLower().StartsWith("body")).CenterPoint; // Copy the given beams to the verification plan and the meterset values. var getCollimatorAndGantryAngleFromBeam = beams.Count() > 1; var presetValues = (from beam in beams let newBeamId = CopyBeam(beam, verificationPlan, isocenter, getCollimatorAndGantryAngleFromBeam) select new KeyValuePair <string, MetersetValue>(newBeamId, beam.Meterset)).ToList(); // Set presciption const int numberOfFractions = 1; verificationPlan.SetPrescription(numberOfFractions, verifiedPlan.DosePerFraction, treatmentPercentage: 1.0); if (calculateDose) { verificationPlan.SetCalculationModel(CalculationType.PhotonVolumeDose, verifiedPlan.GetCalculationModel(CalculationType.PhotonVolumeDose)); // Trace.WriteLine("\nCalculating dose for verification plan...\n"); var res = verificationPlan.CalculateDoseWithPresetValues(presetValues); if (!res.Success) { var message = string.Format("Dose calculation failed for verification plan. Output:\n{0}", res); // Trace.WriteLine(message); throw new Exception(message); } } return(verificationPlan); }
// Create verification plan public ExternalPlanSetup CreateVerificationPlan(StructureSet pStructSt, Course verifCrs, String verifPlnID) { verifPln = verifCrs.AddExternalPlanSetupAsVerificationPlan(pStructSt, currPln); verifPln.Id = verifPlnID; // Copy and set prescription info// verifPln.SetPrescription(1, currPln.DosePerFraction, currPln.TreatmentPercentage); // Remove target structure if available (needed for v 16) verifPln.SetTargetStructureIfNoDose(null, null); return(verifPln); }
/// <summary> /// Copies a already created verification plan to: /// 1. The same structure set if one is not inpput /// 2. A new phantom structure set if one is input /// </summary> /// <param name="planToCopy"></param> /// <param name="course"></param> /// <param name="phantomStructureSetId"></param> /// <param name="phantomPatientId"></param> /// <param name="phantomStudyId"></param> /// <returns></returns> public static ExternalPlanSetup CopyVerificationPlan(ExternalPlanSetup planToCopy, Course course, string phantomStructureSetId, string phantomPatientId, string phantomStudyId) { if (course.PlanSetups.Any(p => p.Id == planToCopy.Id)) { GlobalLogger.Instance.Trace($"A plan with ID {planToCopy.Id} already exists in course {course.Id}."); throw new Exception("A plan with the same ID as the source plan already exists in the destination course."); } if (String.IsNullOrWhiteSpace(phantomStructureSetId)) { return((ExternalPlanSetup)course.CopyPlanSetup(planToCopy)); } else { StructureSet structureSet; if (String.IsNullOrWhiteSpace(phantomPatientId)) { structureSet = planToCopy.Course.Patient.StructureSets.Where(s => s.Id == phantomStructureSetId).Single(); } else { structureSet = planToCopy.Course.Patient.CopyImageFromOtherPatient(phantomPatientId, phantomStudyId, phantomStructureSetId); GlobalLogger.Instance.Trace($"New phantom structure set {structureSet.Id} created from structure set {phantomStructureSetId} in patient ID {phantomPatientId}"); } ExternalPlanSetup verifiedPlan = (ExternalPlanSetup)planToCopy.VerifiedPlan; ExternalPlanSetup copyPlan = course.AddExternalPlanSetupAsVerificationPlan(structureSet, verifiedPlan); copyPlan.Id = planToCopy.Id; copyPlan.SetPrescription((int)planToCopy.NumberOfFractions, planToCopy.DosePerFraction, planToCopy.TreatmentPercentage); GlobalLogger.Instance.Trace($"Added verification plan created from {verifiedPlan.Id} (Course {verifiedPlan.Course.Id}) using phantom structure set {structureSet.Id}"); foreach (Beam b in planToCopy.Beams) { VVector iso = b.IsocenterPosition - planToCopy.StructureSet.Image.UserOrigin; iso += structureSet.Image.UserOrigin; BeamCopier.CopyBeamToPlan(b, copyPlan, iso);// setup beam isocenters to user origin of the QA device GlobalLogger.Instance.Trace($"Copied {b.Id} to verification plan"); } return(copyPlan); } }
/// <summary> /// Create verifications plans for a given treatment plan. /// </summary> public static ExternalPlanSetup CreateVerificationPlan(Course course, IEnumerable <Beam> beams, ExternalPlanSetup verifiedPlan, StructureSet verificationStructures, bool calculateDose) { var verificationPlan = course.AddExternalPlanSetupAsVerificationPlan(verificationStructures, verifiedPlan); try { verificationPlan.Id = verifiedPlan.Id; } catch (System.ArgumentException) { var message = "Plan already exists in QA course."; throw new Exception(message); } // Put isocenter to the center of the QAdevice VVector isocenter = verificationPlan.StructureSet.Image.UserOrigin; var beamList = verifiedPlan.Beams.ToList(); //used for looping later foreach (Beam beam in beams) { if (beam.IsSetupField) { continue; } ExternalBeamMachineParameters MachineParameters = new ExternalBeamMachineParameters(beam.TreatmentUnit.Id, beam.EnergyModeDisplayName, beam.DoseRate, beam.Technique.Id, string.Empty); if (beam.MLCPlanType.ToString() == "VMAT") { // Create a new VMAT beam. var collimatorAngle = beam.ControlPoints.First().CollimatorAngle; var gantryAngleStart = beam.ControlPoints.First().GantryAngle; var gantryAngleEnd = beam.ControlPoints.Last().GantryAngle; var gantryDirection = beam.GantryDirection; var metersetWeights = beam.ControlPoints.Select(cp => cp.MetersetWeight); verificationPlan.AddVMATBeam(MachineParameters, metersetWeights, collimatorAngle, gantryAngleStart, gantryAngleEnd, gantryDirection, 0.0, isocenter); continue; } else { if (beam.MLCPlanType.ToString() == "DoseDynamic") { // Create a new IMRT beam. double gantryAngle; double collimatorAngle; if (beam.TreatmentUnit.Name == "Trilogy") //arccheck { gantryAngle = beam.ControlPoints.First().GantryAngle; collimatorAngle = beam.ControlPoints.First().CollimatorAngle; } else //ix with only mapcheck { gantryAngle = 0.0; collimatorAngle = 0.0; } var metersetWeights = beam.ControlPoints.Select(cp => cp.MetersetWeight); verificationPlan.AddSlidingWindowBeam(MachineParameters, metersetWeights, collimatorAngle, gantryAngle, 0.0, isocenter); continue; } else { var message = string.Format("Treatment field {0} is not VMAT or IMRT.", beam); throw new Exception(message); } } } int i = 0; foreach (Beam verificationBeam in verificationPlan.Beams) { verificationBeam.Id = beamList[i].Id; i++; } foreach (Beam verificationBeam in verificationPlan.Beams) { foreach (Beam beam in verifiedPlan.Beams) { if (verificationBeam.Id == beam.Id) { var editableParams = beam.GetEditableParameters(); editableParams.Isocenter = verificationPlan.StructureSet.Image.UserOrigin; verificationBeam.ApplyParameters(editableParams); continue; } } } // Set presciption const int numberOfFractions = 1; verificationPlan.SetPrescription(numberOfFractions, verifiedPlan.DosePerFraction, verifiedPlan.TreatmentPercentage); verificationPlan.SetCalculationModel(CalculationType.PhotonVolumeDose, verifiedPlan.GetCalculationModel(CalculationType.PhotonVolumeDose)); CalculationResult res; if (verificationPlan.Beams.FirstOrDefault().MLCPlanType.ToString() == "DoseDynamic") { var getCollimatorAndGantryAngleFromBeam = beams.Count() > 1; var presetValues = (from beam in beams select new KeyValuePair <string, MetersetValue>(beam.Id, beam.Meterset)).ToList(); res = verificationPlan.CalculateDoseWithPresetValues(presetValues); } else //vmat { res = verificationPlan.CalculateDose(); } if (!res.Success) { var message = string.Format("Dose calculation failed for verification plan. Output:\n{0}", res); throw new Exception(message); } return(verificationPlan); }