// Fill in patient & plan information to the MainWindow private void fillPtInfo() { // Fill in patient info lblPtName.Content = currPt.Name; lblPtMRN.Content = currPt.Id; // Fill in current course currCrs = EclipseContext.Course; lblCrs.Content = currCrs.Id; // Create list of all plans with course foreach (ExternalPlanSetup pln in currCrs.PlanSetups) { cmbPln.Items.Add(pln.Id); } // Select the current plan as default plan in the plan list currPln = EclipseContext.ExternalPlanSetup; if (currPln != null) { cmbPln.SelectedValue = currPln.Id; } // Create the default course name for the QA plan course Match m = Regex.Match(currCrs.Id, @"C\s*[0-9]+", RegexOptions.IgnoreCase); if (m.Success && m.Length < 10) { txtbQACrs.Text = m.Value + ": QA"; } }
public void Execute(ScriptContext context /*, System.Windows.Window window, ScriptEnvironment environment*/) { // TODO : Add here the code that is called when the script is launched from Eclipse. Patient p = context.Patient; p.BeginModifications();//this line for scripting automation. //find the ctv in the structures. Structure ctv = context.StructureSet.Structures.First(o => o.DicomType == "CTV"); //create on the structureset a PTV from the ctv. Structure ptv = context.StructureSet.AddStructure("PTV", "PTVAuto"); ptv.SegmentVolume = ctv.Margin(8); //create a new plan. Course c_auto = p.AddCourse(); c_auto.Id = "Course_Auto"; ExternalPlanSetup plan = c_auto.AddExternalPlanSetup(context.StructureSet); plan.Id = "Plan_Auto"; //create the fields. //define the externalBeam Parameters ExternalBeamMachineParameters ebmp = new ExternalBeamMachineParameters( "TrueBeam", "6X", 600, "STATIC", null); //set gantry angles double[] g_angles = new double[] { 270, 0, 90, 180 }; foreach (double ga in g_angles) { //add a new beam with intial parametres Beam b = plan.AddMLCBeam( ebmp, new float[2, 60], new VRect <double>(-10, -10, 10, 10), 0, ga, 0, ptv.CenterPoint); //fit the MLC to the structure outline of the PTV. b.FitMLCToStructure(new FitToStructureMargins(10), ptv, false, JawFitting.FitToRecommended, OpenLeavesMeetingPoint.OpenLeavesMeetingPoint_Middle, ClosedLeavesMeetingPoint.ClosedLeavesMeetingPoint_Center); } //Calculate Dose plan.CalculateDose(); //Set Normalization plan.PlanNormalizationValue = plan.Beams.Count() * 100; //Set Prescription. plan.SetPrescription(30, new DoseValue(180, DoseValue.DoseUnit.cGy), 1); }
/// <summary> /// Get the currently active plan from the script context. /// </summary> private ExternalPlanSetup GetPlan(ScriptContext ctx) { Patient pt = ctx.Patient; if (pt == null) { string info = "No patient is currently open. Open a patient before executing this script."; string caption = "No patient available"; MessageBox.Show(info, caption, MessageBoxButton.OK, MessageBoxImage.Error); return(null); } Course cs = ctx.Course; if (cs == null) { string info = "No course is currently open. Open a course before executing this script."; string caption = "No course available"; MessageBox.Show(info, caption, MessageBoxButton.OK, MessageBoxImage.Error); return(null); } ExternalPlanSetup plan = ctx.ExternalPlanSetup; if (plan.Dose == null) { string info = string.Format("Plan '{0}' does not have a valid dose. Perform dose calculation before executing this script.", plan.Id); string caption = "No dose available"; MessageBox.Show(info, caption, MessageBoxButton.OK, MessageBoxImage.Error); return(null); } return(plan); }
private void OnCalculatePlan() { patient.BeginModifications(); Course course_temp = patient.AddCourse(); ExternalPlanSetup plan_temp = course_temp. AddExternalPlanSetup(patient.StructureSets.FirstOrDefault()); ExternalBeamMachineParameters exBeamParams = new ExternalBeamMachineParameters( "HESN10", "6X", 600, "STATIC", null); foreach (string fs in FieldSizes.Split(';')) { double fsd = Convert.ToDouble(fs); plan_temp.AddStaticBeam(exBeamParams, new VRect <double>(-fsd / 2 * 10, -fsd / 2 * 10, fsd / 2 * 10, fsd / 2 * 10), 0, 0, 0, new VVector(0, -200, 0)); } plan_temp.SetPrescription(1, new DoseValue(100, DoseValue.DoseUnit.cGy), 1); plan_temp.CalculateDose(); _app.SaveModifications(); AddCourses(patient); SelectedCourse = course_temp.Id; SelectedPlan = plan_temp.Id; }
private void populateOptimizationTab(ExternalPlanSetup plan) { //grab the optimization constraints in the existing VMAT TBI plan and display them to the user List <Tuple <string, string, double, double, int> > defaultList = new List <Tuple <string, string, double, double, int> > { }; IEnumerable <OptimizationObjective> obj = plan.OptimizationSetup.Objectives; OptimizationPointObjective pt; OptimizationMeanDoseObjective mean; foreach (OptimizationObjective o in obj) { //do NOT include any cooler or heater tuning structures in the list if (!o.StructureId.ToLower().Contains("ts_cooler") && !o.StructureId.ToLower().Contains("ts_heater")) { if (o.GetType() == typeof(OptimizationPointObjective)) { pt = (o as OptimizationPointObjective); defaultList.Add(Tuple.Create(pt.StructureId, pt.Operator.ToString(), pt.Dose.Dose, pt.Volume, (int)pt.Priority)); } else if (o.GetType() == typeof(OptimizationMeanDoseObjective)) { mean = (o as OptimizationMeanDoseObjective); defaultList.Add(Tuple.Create(mean.StructureId, "Mean", mean.Dose.Dose, 0.0, (int)mean.Priority)); } } } //clear the current list of optimization constraints and ones obtained from the plan to the user clearAllOptimizationStructs(); if (obj.Count() > 0) { add_opt_volumes(plan.StructureSet, defaultList); } }
public static void CopyDynamicMlcPlan(string planId, Course course, ExternalPlanSetup originalPlan) { var structureSet = originalPlan.StructureSet; var plan = course.AddExternalPlanSetup(structureSet); if (course.PlanSetups.Where(p => p.Id == planId).Count() > 0) { throw new ArgumentException($"{planId} already exists"); } plan.Id = planId; var dosePerFraction = originalPlan.UniqueFractionation.PrescribedDosePerFraction; var numberOfFractions = originalPlan.UniqueFractionation.NumberOfFractions != null ? originalPlan.UniqueFractionation.NumberOfFractions.Value : 0; const double prescribedPercentage = 1.0; // Note: 100% corresponds to 1.0 plan.UniqueFractionation.SetPrescription(numberOfFractions, dosePerFraction, prescribedPercentage); foreach (var beam in originalPlan.Beams) { CopyFluenceBeam(beam, plan); } if (originalPlan.Beams.First().NormalizationMethod == "NO_ISQLAW_NORM") { plan.SetCalculationOption("AAA_13623", "FieldNormalizationType", "No field normalization"); } plan.PlanNormalizationValue = originalPlan.PlanNormalizationValue; plan.SetCalculationModel(CalculationType.PhotonLeafMotions, "Varian Leaf Motion Calculator [13.6.23]"); plan.CalculateLeafMotions(new LMCVOptions(true)); plan.CalculateDose(); }
/// <summary> /// Subtract a given set of OARS from the PTV. /// </summary> private static Dictionary <string, ModelStructure> SubtractOARsFromPTV(ExternalPlanSetup plan, Dictionary <string, ModelStructure> structureMatches, List <string> sparedOrgans) { // Remove the old PTV - OARs structure if the script was already run before. if (plan.StructureSet.Structures.Any(x => x.Id == PTVSubOARSId)) { var oldPtv = plan.StructureSet.Structures.Single(x => x.Id == PTVSubOARSId); plan.StructureSet.RemoveStructure(oldPtv); } var ptvId = structureMatches.Single(x => x.Value.StructureType == ModelStructureType.Target).Key; var ptv = plan.StructureSet.Structures.Single(st => st.Id == ptvId); var ptvSegmentVolume = ptv.SegmentVolume; // Remove all parts of PTV that overlap with OARs var oars = plan.StructureSet.Structures.Where(x => structureMatches.ContainsKey(x.Id) && structureMatches[x.Id].StructureType == ModelStructureType.OAR); foreach (var oar in oars) { if (sparedOrgans.Contains(structureMatches[oar.Id].ModelId)) { ptvSegmentVolume = ptvSegmentVolume.Sub(oar.SegmentVolume); } } const string dicomType = "PTV"; var newPtv = plan.StructureSet.AddStructure(dicomType, PTVSubOARSId); newPtv.SegmentVolume = ptvSegmentVolume; // Replace the old PTV with new PTV in the structure matches. structureMatches.Remove(ptvId); structureMatches.Add(PTVSubOARSId, new ModelStructure("PTV", ModelStructureType.Target)); return(structureMatches); }
/// <summary> /// Create a copy of an existing beam (beams are unique to plans). /// </summary> public static void CopyStaticMlcBeam(Beam originalBeam, ExternalPlanSetup plan) { var MachineParameters = new ExternalBeamMachineParameters(originalBeam.TreatmentUnit.Id, originalBeam.EnergyModeDisplayName, originalBeam.DoseRate, originalBeam.Technique.Id, string.Empty); // Create a new beam. var collimatorAngle = originalBeam.ControlPoints.First().CollimatorAngle; var gantryAngle = originalBeam.ControlPoints.First().GantryAngle; var PatientSupportAngle = originalBeam.ControlPoints.First().PatientSupportAngle; var jawPositions = originalBeam.ControlPoints.First().JawPositions; var leafPositions = originalBeam.ControlPoints.First().LeafPositions; var isocenter = originalBeam.IsocenterPosition; var beam = plan.AddMLCBeam(MachineParameters, leafPositions, jawPositions, collimatorAngle, gantryAngle, PatientSupportAngle, isocenter); if (plan.Beams.Where(b => b.Id == originalBeam.Id).Count() > 0) { throw new InvalidOperationException($"{originalBeam.Id} already exists"); } beam.Id = originalBeam.Id; // Copy control points from the original beam. var editableParams = beam.GetEditableParameters(); editableParams.WeightFactor = originalBeam.WeightFactor; beam.ApplyParameters(editableParams); }
/// <summary> /// Fit jaw positions to a given target. /// </summary> public static VRect <double> FitJawsToTarget(ExternalPlanSetup plan, Structure ptv, double gantryAngleInDeg, double collimatorRotationInDeg, double margin) { var isocenter = ptv.CenterPoint; var gantryAngleInRad = DegToRad(gantryAngleInDeg); var collimatorRotationInRad = DegToRad(collimatorRotationInDeg); double xMin = 0; double yMin = 0; double xMax = 0; double yMax = 0; var nPlanes = plan.StructureSet.Image.ZSize; for (int z = 0; z < nPlanes; z++) { var contoursOnImagePlane = ptv.GetContoursOnImagePlane(z); if (contoursOnImagePlane != null && contoursOnImagePlane.Length > 0) { foreach (var contour in contoursOnImagePlane) { AdjustJawSizeForContour(ref xMin, ref xMax, ref yMin, ref yMax, isocenter, contour, gantryAngleInRad, collimatorRotationInRad); } } } return(new VRect <double>(xMin - margin, yMin - margin, xMax + margin, yMax + margin)); }
/// <summary> /// Run IMRT optimization for a given plan. /// </summary> public static void Optimize(ExternalPlanSetup plan) { plan.SetCalculationModel(CalculationType.PhotonIMRTOptimization, OptimizationAlgorithm); var opt = new OptimizationOptionsIMRT(NumberOfIterationsForIMRTOptimization, OptimizationOption.RestartOptimization, OptimizationConvergenceOption.TerminateIfConverged, MlcId); Trace.WriteLine("\nOptimizing...\n"); var res = plan.Optimize(opt); if (!res.Success) { var message = string.Format("Optimization failed for plan '{0}'", plan.Id); throw new Exception(message); } plan.SetCalculationModel(CalculationType.PhotonVolumeDose, DoseCalculationAlgorithm); plan.SetCalculationModel(CalculationType.PhotonLeafMotions, LeafMotionCalculator); Trace.WriteLine("\nCalculating leaf motions...\n"); var calcRes = plan.CalculateLeafMotions(); if (!res.Success) { var message = string.Format("Leaf motion calculation failed for plan '{0}'. Output:\n{1}", plan.Id, calcRes); throw new Exception(message); } }
/// <summary> /// Create a copy of an existing beam (beams are unique to plans). /// </summary> public static void CopyFluenceBeam(Beam originalBeam, ExternalPlanSetup plan) { var MachineParameters = new ExternalBeamMachineParameters(originalBeam.TreatmentUnit.Id, originalBeam.EnergyModeDisplayName, originalBeam.DoseRate, originalBeam.Technique.Id, string.Empty); // Create a new beam. var collimatorAngle = originalBeam.ControlPoints.First().CollimatorAngle; var gantryAngle = originalBeam.ControlPoints.First().GantryAngle; var PatientSupportAngle = originalBeam.ControlPoints.First().PatientSupportAngle; var isocenter = originalBeam.IsocenterPosition; var metersetWeights = originalBeam.ControlPoints.Select(cp => cp.MetersetWeight); var beam = plan.AddSlidingWindowBeam(MachineParameters, metersetWeights, collimatorAngle, gantryAngle, PatientSupportAngle, isocenter); beam.Id = originalBeam.Id; // Copy control points from the original beam. var editableParams = beam.GetEditableParameters(); for (var i = 0; i < editableParams.ControlPoints.Count(); i++) { editableParams.ControlPoints.ElementAt(i).LeafPositions = originalBeam.ControlPoints.ElementAt(i).LeafPositions; editableParams.ControlPoints.ElementAt(i).JawPositions = originalBeam.ControlPoints.ElementAt(i).JawPositions; } editableParams.WeightFactor = originalBeam.WeightFactor; beam.ApplyParameters(editableParams); var fluence = originalBeam.GetOptimalFluence(); beam.SetOptimalFluence(fluence); }
public static ExternalPlanSetup AddNewPlan(Course course, StructureSet structureSet, string planId) { try { var oldPlans = course.PlanSetups.Where(x => x.Id == planId); if (oldPlans.Any()) { var plansToBeRemoved = oldPlans.ToArray(); foreach (var p in plansToBeRemoved) { course.RemovePlanSetup(p); } } } catch { var message = string.Format("Could not cleanup old plans."); throw new Exception(message); } ExternalPlanSetup plan = course.AddExternalPlanSetup(structureSet); plan.Id = planId; return(plan); }
static void Execute(Application app) { Patient pat = app.OpenPatientById("exercise5-0"); try { pat.BeginModifications(); const string courseId = "AutoPlanned"; Course course = pat.Courses.Where(o => o.Id == courseId).SingleOrDefault(); if (course == null) { if (course == null) { course = pat.AddCourse(); course.Id = courseId; } } StructureSet ss = pat.StructureSets.First(x => x.Id == "CT_1"); if (course.CanAddPlanSetup(ss)) { // find the PTV Structure ptv = ss.Structures.First(x => x.Id == "PTV"); // Put isocenter to the center of the ptv. var isocenter = ptv.CenterPoint; //add plan and beams ExternalPlanSetup plan = course.AddExternalPlanSetup(ss); plan.SetPrescription(5, new DoseValue(2, DoseValue.DoseUnit.Gy), 1.0); Beam g0 = plan.AddMLCBeam(MachineParameters, null, new VRect <double>(-10, -10, 10, 10), 0, 0, 0, isocenter); Beam g180 = plan.AddMLCBeam(MachineParameters, null, new VRect <double>(-10, -10, 10, 10), 0, 180.0, 0, isocenter); // fit beam jaws and MLC bool useAsymmetricXJaw = true, useAsymmetricYJaws = true, optimizeCollimatorRotation = true; g0.FitCollimatorToStructure(new FitToStructureMargins(0), ptv, useAsymmetricXJaw, useAsymmetricYJaws, optimizeCollimatorRotation); FitToStructureMargins margins = new FitToStructureMargins(1); JawFitting jawFit = JawFitting.FitToRecommended; OpenLeavesMeetingPoint olmp = OpenLeavesMeetingPoint.OpenLeavesMeetingPoint_Middle; ClosedLeavesMeetingPoint clmp = ClosedLeavesMeetingPoint.ClosedLeavesMeetingPoint_BankOne; g0.FitMLCToStructure(margins, ptv, optimizeCollimatorRotation, jawFit, olmp, clmp); g180.FitMLCToStructure(margins, ptv, optimizeCollimatorRotation, jawFit, olmp, clmp); // format the field ids g0.Id = string.Format("g{0}c{1}", g0.GantryAngleToUser(g0.ControlPoints[0].GantryAngle), g0.CollimatorAngleToUser(g0.ControlPoints[0].CollimatorAngle) ); g180.Id = string.Format("g{0}c{1}", g180.GantryAngleToUser(g180.ControlPoints[0].GantryAngle), g180.CollimatorAngleToUser(g180.ControlPoints[0].CollimatorAngle) ); app.SaveModifications(); } } finally { app.ClosePatient(); } }
static void Execute(Application app) { // TODO: add here your code Patient curpat = app.OpenPatientById("002441"); Course curcourse = curpat.Courses.Where(x => x.Id == "advanced.3").Single(); ExternalPlanSetup cureps = curcourse.ExternalPlanSetups.Where(x => x.Id == "NCPTestScript").Single(); PlanInfoFromControlPoints(cureps); }
public bool SetExternalPlanSetup(ExternalPlanSetup ex) { PlanSetup = ex; ExternalPlanSetup = ex; //Notify OnExternalPlanSetupChanged(ex); OnPlanSetupChanged(ex); return(ExternalPlanSetup != null); }
/// <summary> /// Add normal tissue objectives. The NTO values are taken from the WUSTL Prostate Model datasheet. /// </summary> public static void AddNTO(ExternalPlanSetup plan) { const double priority = 100.0; const double distanceFromTargetBorderInMM = 3.0; const double startDosePersentage = 100.0; const double endDosePercentage = 40.0; const double fallOff = 0.05; plan.OptimizationSetup.AddNormalTissueObjective(priority, distanceFromTargetBorderInMM, startDosePersentage, endDosePercentage, fallOff); }
// 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); }
public planPrep(ExternalPlanSetup vmat, IEnumerable <ExternalPlanSetup> appa) { //copy arguments into local variables vmatPlan = vmat; appaPlan = appa; //if there is more than one AP/PA legs plan in the list, this indicates that the user already separated these plans. Don't separate them in this script if (appa.Count() > 1) { legsSeparated = true; } }
/// <summary> /// Calculate dose for a given plan. /// </summary> public static void CalculateDose(ExternalPlanSetup plan) { plan.SetCalculationModel(CalculationType.PhotonVolumeDose, DoseCalculationAlgorithm); Trace.WriteLine("\nCalculating dose...\n"); var res = plan.CalculateDose(); if (!res.Success) { var message = string.Format("Dose calculation failed for plan '{0}'. Output:\n{1}", plan.Id, res); Trace.WriteLine(message); } }
public void Execute(ScriptContext context, Window MainWin) { // Open current patient Patient currPt = context.Patient; // If there's no selected patient, throw an exception if (currPt == null) { throw new ApplicationException("Please open a patient before using this script."); } currPt.BeginModifications(); // Open current course Course currCrs = context.Course; // If there's no selected course, throw an exception if (currCrs == null) { throw new ApplicationException("Please select at least one course before using this script."); } // Open current plan ExternalPlanSetup currPln = context.ExternalPlanSetup; // If there's no selected plan, throw an exception if (currPln == null) { throw new ApplicationException("Please creat a plan with one beam with the preferred machine and energy."); } // Check if plan is approved if (currPln.ApprovalStatus != PlanSetupApprovalStatus.UnApproved) { throw new ApplicationException("Please unapprove plan before using this script."); } // Open beam Beam currBm = currPln.Beams.FirstOrDefault(); if (currBm == null) { throw new ApplicationException("Please insert one beam with the preferred machine and energy."); } // Call WPF Win var MainWinCtr = new createMLCPicture.MainWindow(context); MainWin.Content = MainWinCtr; MainWin.Title = "Create MLC Picture"; MainWin.Width = 440; MainWin.Height = 240; MainWin.ResizeMode = ResizeMode.NoResize; }
private void populateRx(ExternalPlanSetup plan) { //populate the prescription text boxes dosePerFx.Text = plan.DosePerFraction.Dose.ToString(); numFx.Text = plan.NumberOfFractions.ToString(); Rx.Text = plan.TotalDose.Dose.ToString(); //if the dose per fraction and number of fractions equal 200 cGy and 4, respectively, then this is a scleroderma trial patient. This information will be passed to the optimization loop if (plan.DosePerFraction.Dose == 200.0 && plan.NumberOfFractions == 4) { scleroTrial = true; } }
/// <summary> /// Create PTV from CTV by adding a margin. /// </summary> private static void CreatePTVFromCTV(ExternalPlanSetup plan, double ptvMargin, string ctvId) { var ctvs = plan.StructureSet.Structures.Where(structure => structure.Id == ctvId).ToList(); if (ctvs.Count() == 1) { const string dicomType = "ORGAN"; var ctv = ctvs.Single(); var ptv = plan.StructureSet.AddStructure(dicomType, ExpandedCTVId); ptv.SegmentVolume = ctv.Margin(ptvMargin); } }
public void Execute(ScriptContext context /*, System.Windows.Window window, ScriptEnvironment environment*/) { Patient p = context.Patient; if (p == null) { throw new ApplicationException("Please load a patient"); } ExternalPlanSetup plan = context.ExternalPlanSetup; if (plan == null) { throw new ApplicationException("Please load an external beam plan that will be verified."); } p.BeginModifications(); // TODO: look whether the phantom scan exists in this patient before copying it StructureSet ssQA = p.CopyImageFromOtherPatient(QAPatientID, QAStudyID, QAImageID); // Get or create course with Id 'IMRTQA' const string courseId = "IMRTQA"; Course course = p.Courses.Where(o => o.Id == courseId).SingleOrDefault(); if (course == null) { course = p.AddCourse(); course.Id = courseId; } #if false // Create an individual verification plan for each field. foreach (var beam in plan.Beams) { CreateVerificationPlan(course, new List <Beam> { beam }, plan, ssQA, beam.Id, calculateDose: false); } #endif // Create a verification plan that contains all fields (Composite). ExternalPlanSetup verificationPlan = CreateVerificationPlan(course, plan.Beams, plan, ssQA, "Composite", calculateDose: true); //ExternalPlanSetup verificationPlan = course.AddExternalPlanSetupAsVerificationPlan(ssQA, plan); // nagivate back from verificationPlan to verified plan PlanSetup verifiedPlan = verificationPlan.VerifiedPlan; if (plan != verifiedPlan) { MessageBox.Show(string.Format("ERROR! verified plan {0} != loaded plan {1}", verifiedPlan.Id , plan.Id)); } MessageBox.Show(string.Format("Success - verification plan {0} created in course {1}.", verificationPlan.Id, course.Id)); }
private void add_constraint_Click(object sender, RoutedEventArgs e) { //add a blank contraint to the list ExternalPlanSetup plan = getPlan(); if (plan != null) { add_opt_volumes(plan.StructureSet, new List <Tuple <string, string, double, double, int> > { Tuple.Create("--select--", "--select--", 0.0, 0.0, 0) }); optParamScroller.ScrollToBottom(); } }
private void getOptFromPlan_Click(object sender, RoutedEventArgs e) { ExternalPlanSetup plan = getPlan(); if (plan == null) { return; } else { populateOptimizationTab(plan); } }
public static VRect <double> FitJawsToTarget(VVector isocentre, ExternalPlanSetup plan, List <Structure> ptvs, double collimatorAngleInDeg, double margin) { var collimatorAngleInRad = DegToRad(collimatorAngleInDeg); double xMin = isocentre.x; double yMin = isocentre.y; double xMax = isocentre.x; double yMax = isocentre.y; for (int gantryRotationInDeg = 0; gantryRotationInDeg < 360; gantryRotationInDeg += 30) { double gantryRotationInRad = DegToRad(gantryRotationInDeg); var nPlanes = plan.StructureSet.Image.ZSize; //Need to approximate the rotating gantry as finite number of static fields. approximate it as 6 static fields for (int i = 0; i < ptvs.Count; i++) { for (int z = 0; z < nPlanes; z++) { var contoursOnImagePlane = ptvs[i].GetContoursOnImagePlane(z); if (contoursOnImagePlane != null && contoursOnImagePlane.Length > 0) { foreach (var contour in contoursOnImagePlane) { AdjustJawSizeForContour(ref xMin, ref xMax, ref yMin, ref yMax, isocentre, contour, gantryRotationInRad, collimatorAngleInRad); } } } } } xMin = Math.Max(-149, xMin); yMin = Math.Max(-149, yMin); xMax = Math.Min(149, xMax); yMax = Math.Min(149, yMax); //Issues if exceed a field size of 22cm, so need to trim if necessary: if (xMax - xMin > 220) { double extraLength = (xMax - xMin) - 220; xMin += (extraLength / 2); xMax -= (extraLength / 2); } if (yMax - yMin > 220) { double extraLength = (yMax - yMin) - 220; yMin += (extraLength / 2); yMax -= (extraLength / 2); } return(new VRect <double>(xMin, yMin, xMax, yMax)); }
public static void CopyBeamToPlan(Beam beam, ExternalPlanSetup plansetup, VVector isocenter) { string energyModeDisp = beam.EnergyModeDisplayName; Char[] sep = { '-' }; string energyMode = energyModeDisp.Split(sep).First(); string pfm = energyModeDisp.Split(sep).Count() > 1 ? energyModeDisp.Split(sep).Last() : null; ExternalBeamMachineParameters extParams = new ExternalBeamMachineParameters(beam.TreatmentUnit.Id, energyMode, beam.DoseRate, beam.Technique.Id, pfm); List <double> metersetWeights = GetControlPointWeights(beam); Beam copyBeam = null; if (beam.MLCPlanType == MLCPlanType.VMAT) { copyBeam = plansetup.AddVMATBeam(extParams, metersetWeights, beam.ControlPoints[0].CollimatorAngle, beam.ControlPoints[0].GantryAngle, beam.ControlPoints[beam.ControlPoints.Count - 1].GantryAngle, beam.GantryDirection, beam.ControlPoints[0].PatientSupportAngle, isocenter); } else if (beam.MLCPlanType == MLCPlanType.ArcDynamic) { copyBeam = plansetup.AddConformalArcBeam(extParams, beam.ControlPoints[0].CollimatorAngle, beam.ControlPoints.Count, beam.ControlPoints[0].GantryAngle, beam.ControlPoints[beam.ControlPoints.Count - 1].GantryAngle, beam.GantryDirection, beam.ControlPoints[0].PatientSupportAngle, isocenter); } else if (beam.MLCPlanType == MLCPlanType.DoseDynamic) { var cppPairs = metersetWeights.Zip(metersetWeights.Skip(1), (a, b) => new Tuple <double, double>(a, b)).ToList(); var oddCppPairs = cppPairs.Where((p, i) => i % 2 == 1); if (metersetWeights.Count >= 4 && metersetWeights.Count % 2 == 0 && oddCppPairs.All(p => p.Item1 == p.Item2)) { copyBeam = plansetup.AddMultipleStaticSegmentBeam(extParams, metersetWeights, beam.ControlPoints[0].CollimatorAngle, beam.ControlPoints[0].GantryAngle, beam.ControlPoints[0].PatientSupportAngle, isocenter); } else { copyBeam = plansetup.AddSlidingWindowBeam(extParams, metersetWeights, beam.ControlPoints[0].CollimatorAngle, beam.ControlPoints[0].GantryAngle, beam.ControlPoints[0].PatientSupportAngle, isocenter); } } else { throw new NotImplementedException("Copying this type of beam not implemented"); } var beamParams = copyBeam.GetEditableParameters(); CopyJawAndLeafPositions(beam, beamParams); beamParams.WeightFactor = beam.WeightFactor; copyBeam.ApplyParameters(beamParams); copyBeam.Id = beam.Id; }
/// <summary> /// Rectum metrics. /// </summary> private static void CreateRectumMetrics(XmlTextWriter writer, ExternalPlanSetup plan, Dictionary <string, ModelStructure> structureMatches) { var structure = plan.StructureSet.Structures.Single(st => st.Id == structureMatches.Single(x => x.Value.ModelId == "Rectum").Key); writer.WriteStartElement("Structure"); writer.WriteAttributeString("Id", structure.Id); writer.WriteAttributeString("Model_Id", structureMatches[structure.Id].ModelId); var metrics = new List <VolumeAtDoseMetric> { new VolumeAtDoseMetric(new DoseValue(40.0, DoseValue.DoseUnit.Gy), 50.0, MetricType.Upper), new VolumeAtDoseMetric(new DoseValue(50.0, DoseValue.DoseUnit.Gy), 40.0, MetricType.Upper), new VolumeAtDoseMetric(new DoseValue(65.0, DoseValue.DoseUnit.Gy), 25.0, MetricType.Upper) }; CreateVolumeAtDoseMetrics(writer, plan, structure, metrics); writer.WriteEndElement(); }
public static Tuple <List <List <Structure> >, List <List <Structure> >, List <List <string> >, bool> StartOptimizer(ScriptContext context, HNPlan hnPlan, List <List <Structure> > matchingStructures, int numIterations, List <Tuple <bool, double[], string> > features, Tuple <string, string, bool> beamParams) //Returns list of matching structures { // Check for patient plan loaded ExternalPlanSetup plan = context.ExternalPlanSetup; Patient patient = context.Patient; StructureSet ss = context.StructureSet; Course course = context.Course; Image image3d = context.Image; //Create two VMAT beams BeamMaker(ref plan, ss, plan.TotalDose.Dose, beamParams); //set prescriptions dose int numFractions = hnPlan.Fractions; int dosePerFraction = (int)hnPlan.PrescriptionDose / numFractions; plan.SetPrescription(numFractions, new DoseValue(dosePerFraction, "cGy"), 1); //matchingStructures is the same length as hnPlan.ROIs.count //Now set optimization constraints List <List <Structure> > optimizedStructures = OptObjectivesEditing.SetConstraints(ref plan, hnPlan, matchingStructures, true); //true to check for opti structures, returns new matching list of structures List <List <double[, ]> > choppedContours; List <double[]> planes; string contraParName; if (features[0].Item1 == true) //parotid segmentation feature { Tuple <List <List <double[, ]> >, string, List <double[]> > choppedAndName = ParotidChop(ref plan, hnPlan, matchingStructures, ss, context); choppedContours = choppedAndName.Item1; contraParName = choppedAndName.Item2; planes = choppedAndName.Item3; } else { choppedContours = new List <List <double[, ]> >(); contraParName = ""; planes = new List <double[]>(); } Tuple <bool, List <List <string> > > optimData = Optimize(choppedContours, planes, ref plan, ref ss, hnPlan, context, optimizedStructures, matchingStructures, contraParName, numIterations, features, beamParams); bool isPassed = optimData.Item1; List <List <string> > updatesLog = optimData.Item2; return(Tuple.Create(optimizedStructures, matchingStructures, updatesLog, isPassed)); }
private void BT_AbrirPaciente_Click(object sender, EventArgs e) { try { paciente = abrirPaciente(TB_ID.Text); TB_Output.Text += "Se abrió el paciente: " + paciente.Name + "\n"; curso = abrirCurso(paciente, TB_Curso.Text); TB_Output.Text += "Se abrió el curso: " + curso.Name + "\n"; plan = abrirPlan(curso, TB_Plan.Text); TB_Output.Text += "Se abrió el plan: " + plan.Name + "\n"; } catch (Exception f) { MessageBox.Show(f.ToString()); TB_Output.Text += "No se pudo abrir \n"; } }