def isocenter_centered_test(self): t = TEST.Test( "Skal i utgangspunktet være mest mulig sentrert i pasientens aksial-snitt", '<= 12 cm', self.isocenter) photon_iso = None if self.beam_set.Modality == 'Photons': ss = self.ts_structure_set().structure_set for beam in self.beam_set.Beams: if not photon_iso: photon_iso = beam.Isocenter.Position # For photon plans, isosenter should be somewhat centered in the patient to avoid gantry collisions. # Compare isocenter x and y coordinates to the center coordinates of the external ROI: if SSF.has_named_roi_with_contours(ss, ROIS.external.name): # Determine x and y coordinate: patient_center_x = SSF.roi_center_x( ss, ROIS.external.name) patient_center_y = SSF.roi_center_y( ss, ROIS.external.name) # Reset large patient center x values (Why do we do this?!) if abs(patient_center_x) > 3: patient_center_x = 0 # Determine the distance between patient center and isocenter: diff = round( ((photon_iso.x - patient_center_x)**2 + (photon_iso.y - patient_center_y)**2)**0.5, 1) if diff > 12: return t.fail(diff) else: return t.succeed()
def create_bottom_part_x_cm(pm, examination, ss, source_roi, roi, distance): if SSF.has_named_roi_with_contours(ss, source_roi.name): center_x = SSF.roi_center_x(ss, source_roi.name) center_y = SSF.roi_center_y(ss, source_roi.name) center_z = SSF.roi_center_z(ss, source_roi.name) source_roi_box = ss.RoiGeometries[source_roi.name].GetBoundingBox() x_min = source_roi_box[0].x x_max = source_roi_box[1].x x = source_roi_box[1].x - source_roi_box[0].x y_min = source_roi_box[0].y y_max = source_roi_box[1].y y = source_roi_box[1].y - source_roi_box[0].y z_min = source_roi_box[0].z z = source_roi_box[1].z - source_roi_box[0].z z_cutoff = z_min + distance / 2 delete_roi(pm, ROIS.box.name) box = pm.CreateRoi(Name=ROIS.box.name, Color=ROIS.box.color, Type=ROIS.box.type) pm.RegionsOfInterest[ROIS.box.name].CreateBoxGeometry( Size={ 'x': x, 'y': y, 'z': distance }, Examination=examination, Center={ 'x': center_x, 'y': center_y, 'z': z_cutoff }) if not SSF.is_approved_roi_structure(ss, roi.name): if is_approved_roi_structure_in_one_of_all_structure_sets( pm, roi.name): intersection = ROI.ROIAlgebra(roi.name + "1", roi.type, roi.color, sourcesA=[source_roi], sourcesB=[ROIS.box], operator='Intersection') # In the rare case that this ROI already exists, delete it (to avoid a crash): delete_roi(pm, intersection.name) create_algebra_roi(pm, examination, ss, intersection) GUIF.handle_creation_of_new_roi_because_of_approved_structure_set( intersection.name) else: intersection = ROI.ROIAlgebra(roi.name, roi.type, roi.color, sourcesA=[source_roi], sourcesB=[ROIS.box], operator='Intersection') # In the rare case that this ROI already exists, delete it (to avoid a crash): delete_roi(pm, intersection.name) create_algebra_roi(pm, examination, ss, intersection) delete_roi(pm, ROIS.box.name) else: GUIF.handle_missing_roi_for_derived_rois(roi.name, source_roi.name)
def create_posterior_half_fast(pm, examination, ss, source_roi, roi): center_x = SSF.roi_center_x(ss, source_roi.name) center_y = SSF.roi_center_y(ss, source_roi.name) center_z = SSF.roi_center_z(ss, source_roi.name) source_roi_box = ss.RoiGeometries[source_roi.name].GetBoundingBox() x_min = source_roi_box[0].x x_max = source_roi_box[1].x x = source_roi_box[1].x - source_roi_box[0].x boxes = [] boxes2 = [] for [contour_index, contour] in enumerate( ss.RoiGeometries[source_roi.name].PrimaryShape.Contours): y_min = 9999 y_max = -9999 for coordinate in contour: if coordinate.y > y_max: y_max = coordinate.y elif coordinate.y < y_min: y_min = coordinate.y length = round((abs(y_max - y_min)), 1) center_y = y_max delete_roi(pm, ROIS.box.name + str(contour_index)) box = pm.CreateRoi(Name=ROIS.box.name + str(contour_index), Color=ROIS.box.color, Type=ROIS.box.type) i = 0 for i in range(0, contour_index): if i % 3 == 0: pm.RegionsOfInterest[ROIS.box.name + str(contour_index)].CreateBoxGeometry( Size={ 'x': x, 'y': length, 'z': 0.3 }, Examination=examination, Center={ 'x': center_x, 'y': center_y, 'z': coordinate.z }) boxes.append(box) boxes2.append( ROI.ROI(ROIS.box.name + str(contour_index), ROIS.box.type, ROIS.box.color)) subtraction = ROI.ROIAlgebra(roi.name, roi.type, roi.color, sourcesA=[source_roi], sourcesB=boxes2, operator='Intersection') # In the rare case that this ROI already exists, delete it (to avoid a crash): delete_roi(pm, subtraction.name) create_algebra_roi(pm, examination, ss, subtraction) for i in range(0, len(boxes)): delete_roi(pm, boxes[i].Name)
def setup_beams(ss, examination, beam_set, isocenter, region_code, fraction_dose, technique_name, energy_name, iso_index = 1, beam_index=1): if technique_name == '3D-CRT': # 3D-CRT: if region_code in RC.breast_partial_l_codes: # Partial breast, left sided: BSF.create_three_beams(beam_set, isocenter, energy = energy_name, name1 = 'LPO', name2 = 'LAO', name3 = 'RAO', gantry_angle1 = '110', gantry_angle2 = '35', gantry_angle3 = '350', collimator_angle1 = '343', collimator_angle2 = '17', collimator_angle3 = '17', iso_index=iso_index, beam_index=beam_index) BSF.set_MU(beam_set,['LPO','LAO','RAO'], [90, 15, 90] ) elif region_code in RC.breast_tang_l_codes: # Whole breast, left sided: BSF.create_two_beams(beam_set, isocenter, energy = energy_name, name1 = 'LPO', name2 = 'RAO', gantry_angle1 = '130', gantry_angle2 = '310', collimator_angle1 = '343', collimator_angle2 = '17', iso_index=iso_index, beam_index=beam_index) BSF.set_MU(beam_set,['LPO','RAO'], [110, 110] ) elif region_code in RC.breast_partial_r_codes: # Partial breast, right sided: BSF.create_three_beams(beam_set, isocenter, energy = energy_name, name1 = 'RPO', name2 = 'RAO', name3 = 'LAO', gantry_angle1 = '250', gantry_angle2 = '325', gantry_angle3 = '10', collimator_angle1 = '9', collimator_angle2 = '352', collimator_angle3 = '352', iso_index=iso_index, beam_index=beam_index) BSF.set_MU(beam_set,['RPO','RAO','LAO'], [90, 15, 90] ) elif region_code in RC.breast_tang_r_codes: # Whole breast, right sided: BSF.create_two_beams(beam_set, isocenter, energy = energy_name, name1 = 'RPO', name2 = 'LAO', gantry_angle1 = '230', gantry_angle2 = '50', collimator_angle1 = '9', collimator_angle2 = '352', iso_index=iso_index, beam_index=beam_index) BSF.set_MU(beam_set,['RPO','LAO'], [110, 110] ) elif region_code in RC.breast_reg_l_codes: # Breast with regional lymph nodes, left sided: BSF.create_four_beams(beam_set, isocenter, energy = energy_name, name1 = 'LPO', name2 = 'Venstre', name3 = 'Forfra', name4 = 'RAO', gantry_angle1 = '130', gantry_angle2 = '90', gantry_angle3 = '0', gantry_angle4 = '309', iso_index=iso_index, beam_index=beam_index) if fraction_dose == 2: BSF.set_MU(beam_set,['LPO','Venstre','Forfra','RAO'], [25, 15, 100, 90] ) elif fraction_dose == 2.67: BSF.set_MU(beam_set,['LPO','Venstre','Forfra','RAO'], [40, 25, 115, 105] ) elif region_code in RC.breast_reg_r_codes: # Breast with regional lymph nodes, right sided: BSF.create_four_beams(beam_set, isocenter, energy = energy_name, name1 = 'RPO', name2 = 'Høyre', name3 = 'Forfra', name4 = 'LAO', gantry_angle1 = '235', gantry_angle2 = '270', gantry_angle3 = '0', gantry_angle4 = '55', iso_index=iso_index, beam_index=beam_index) if fraction_dose == 2: BSF.set_MU(beam_set,['RPO','Høyre','Forfra','LAO'], [25, 15, 100, 90] ) elif fraction_dose == 2.67: BSF.set_MU(beam_set,['RPO','Høyre','Forfra','LAO'], [40, 25, 115, 105] ) elif region_code in RC.brain_whole_codes: # Whole brain: BSF.create_two_beams(beam_set, isocenter, energy = '10', name1 = 'Høyre', name2 = 'Venstre', gantry_angle1 = '270', gantry_angle2 = '90', collimator_angle1 = '295', collimator_angle2 = '63', iso_index=iso_index, beam_index=beam_index) BSF.set_MU(beam_set,['Høyre','Venstre'], [130, 130] ) elif technique_name == 'VMAT': # VMAT: # Brain: if region_code in RC.brain_whole_codes: # Whole brain: BSF.create_single_arc(beam_set, isocenter) elif region_code in RC.brain_partial_codes: # Partial brain: if fraction_dose > 15: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) elif fraction_dose > 6: # Stereotactic brain BSF.create_single_arc(beam_set, isocenter, energy = energy_name, collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) else: # Partial brain (ordinary fractionation): if SSF.partial_brain_conflict_oars(ss): BSF.create_single_arc(beam_set, isocenter, energy = energy_name, collimator_angle = '45', iso_index=iso_index, beam_index=beam_index) else: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) # Breast with regional lymph nodes: elif region_code in RC.breast_reg_l_codes: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, gantry_stop_angle = '300', gantry_start_angle = '179', collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) elif region_code in RC.breast_reg_r_codes: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, gantry_stop_angle = '60', gantry_start_angle = '181', collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) # Lung: elif region_code in RC.lung_and_mediastinum_codes: if region_code in RC.lung_r_codes: # Right: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, gantry_stop_angle = '30', gantry_start_angle = '181', collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) elif region_code in RC.lung_l_codes: # Left: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, gantry_stop_angle = '330', gantry_start_angle = '179', collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) else: # Mediastinum or both lungs: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) elif region_code in RC.bladder_codes: # Bladder: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, iso_index=iso_index, beam_index=beam_index) elif region_code in RC.prostate_codes: # Prostate: if SSF.has_roi_with_shape(ss, ROIS.ptv_56.name): # With lymph nodes: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) else: # Without lymph nodes: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, iso_index=iso_index, beam_index=beam_index) elif region_code in RC.rectum_codes: # Rectum: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) elif region_code in RC.palliative_codes: # Palliative treatment: if fraction_dose > 8: # Stereotactic fractionation: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) else: # 'Normal' fractionation: if region_code in RC.whole_pelvis_codes: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) else: if abs(isocenter.x) > 5: # Lateral treatment volume: if isocenter.x > 5 and CF.is_head_first_supine(examination) or not CF.is_head_first_supine(examination) and isocenter.x < -5: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, gantry_stop_angle = '330', gantry_start_angle = '179', collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) else: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, gantry_stop_angle = '30', gantry_start_angle = '181', collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) elif abs(isocenter.y) + 5 < abs(SSF.roi_center_y(ss, "External")): # Anterior treatment volume: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, gantry_stop_angle = '250', gantry_start_angle = '110', collimator_angle = '5', iso_index=iso_index, beam_index=beam_index) else: BSF.create_single_arc(beam_set, isocenter, energy = energy_name, iso_index=iso_index, beam_index=beam_index) # Return the number of beams created: return len(list(beam_set.Beams))