def stereotactic_mu_constraints_for_single_beam(self): t = TEST.Test( "Skal i utgangspunktet bruke begrensninger på antall MU per bue <= 1.4*fraksjonsdose (cGy).", True, self.mu) beam_start = 0 beam_stop = 0 beam_length = 0 total_beam_length = 0 if self.ts_beam_set.has_prescription(): if len(list(self.ts_beam_set.beam_set.Beams)) == 1: if self.ts_beam_set.ts_label.label.technique: if self.ts_beam_set.ts_label.label.technique.upper( ) == 'S': for po in self.ts_beam_set.ts_plan.plan.PlanOptimizations: for beam_settings in po.OptimizationParameters.TreatmentSetupSettings[ 0].BeamSettings: if self.beam.Number == beam_settings.ForBeam.Number and beam_settings.ArcConversionPropertiesPerBeam.MaxArcMU: t.expected = "<" + str( RSU.fraction_dose( self.ts_beam_set.beam_set) * 140) if beam_settings.ArcConversionPropertiesPerBeam.MaxArcMU <= ( RSU.fraction_dose( self.ts_beam_set.beam_set) * 140 * 1.15): return t.succeed() else: return t.fail( round( beam_settings. ArcConversionPropertiesPerBeam. MaxArcMU, 1))
def stereotactic_mu_constraints_for_multiple_beams(self): t = TEST.Test( "Skal i utgangspunktet bruke begrensninger på antall MU per bue <= 1.4*fraksjonsdose (cGy), disse bør også ta hensyn til buelengden. Begrensningen på MU for denne buen er > 1.15 * forventningsverdien.", True, self.mu) beam_start = 0 beam_stop = 0 beam_length = 0 total_beam_length = 0 if self.ts_beam_set.has_prescription(): if len(list(self.ts_beam_set.beam_set.Beams)) > 1: if self.ts_beam_set.ts_label.label.technique: if self.ts_beam_set.ts_label.label.technique.upper( ) == 'S': for po in self.ts_beam_set.ts_plan.plan.PlanOptimizations: for beam_settings in po.OptimizationParameters.TreatmentSetupSettings[ 0].BeamSettings: if self.beam.Number == beam_settings.ForBeam.Number and beam_settings.ArcConversionPropertiesPerBeam.MaxArcMU: for beam in self.ts_beam_set.beam_set.Beams: beam_start = beam.GantryAngle beam_stop = beam.ArcStopGantryAngle if beam_start > 180: total_beam_length += 360 - beam_start else: total_beam_length += beam_start if beam_stop > 180: total_beam_length += 360 - beam_stop else: total_beam_length += beam_stop beam_start = beam_settings.ForBeam.GantryAngle beam_stop = beam_settings.ForBeam.ArcStopGantryAngle if beam_start > 180: beam_length += 360 - beam_start else: beam_length += beam_start if beam_stop > 180: beam_length += 360 - beam_stop else: beam_length += beam_stop t.expected = "<" + str( round( (beam_length / total_beam_length) * RSU.fraction_dose( self.ts_beam_set.beam_set) * 140)) if beam_settings.ArcConversionPropertiesPerBeam.MaxArcMU <= ( (beam_length / total_beam_length) * RSU.fraction_dose( self.ts_beam_set.beam_set) * 140 * 1.15): return t.succeed() else: return t.fail( round( beam_settings. ArcConversionPropertiesPerBeam. MaxArcMU, 1))
def prescription_mu_breast_regional_cranial_test(self): t = TEST.Test( "Skal stå i forhold til fraksjonsdosen for beam-settet, det ser ut som MU kranielt for isosenter avviker med mer enn 20% av fraksjonsdosen (cGy).", True, self.mu) mu_total_over = 0 text = "" t.expected = RSU.fraction_dose(self.beam_set) * 100 if not self.is_vmat(): if self.ts_label.label.region in RC.breast_reg_codes: for beam in self.beam_set.Beams: segment_partial_area = [] for index, segment in enumerate(beam.Segments): jaw = segment.JawPositions y1 = jaw[2] if y1 < 0: y1 = 0 y2 = jaw[3] if y1 >= 0 and y2 > 0 or y2 > 0: leaf_positions = segment.LeafPositions mlc_y1 = int(math.floor((y1 + 20) * 2)) mlc_y2 = int(math.ceil((y2 + 20) * 2)) - 1 segment_partial_area.extend([0]) segment_partial_area[index] += ( leaf_positions[1][mlc_y1] - leaf_positions[0][mlc_y1]) * (( (mlc_y1 + 1) - (y1 + 20) * 2) / 2) for mlc in range(mlc_y1 + 1, mlc_y2): segment_partial_area[index] += ( leaf_positions[1][mlc] - leaf_positions[0][mlc]) * 0.5 segment_partial_area[index] += ( leaf_positions[1][mlc_y2] - leaf_positions[0][mlc_y2]) * (((y2 + 20) * 2 - (mlc_y2)) / 2) else: segment_partial_area.extend([0]) max_area = max(segment_partial_area) for index, segment in enumerate(beam.Segments): jaw = segment.JawPositions if segment_partial_area[ index] > 1.5 and segment_partial_area[ index] / max_area > 0.4 or round( jaw[2], 1) >= 0: mu_total_over += beam.BeamMU * segment.RelativeWeight if abs( (mu_total_over - RSU.fraction_dose(self.beam_set) * 100) / (RSU.fraction_dose(self.beam_set) * 100) * 100) > 20: return t.fail(round(mu_total_over, 1)) else: return t.succeed()
def vmat_mu_test(self): t = TEST.Test( "Bør som hovedregel være innenfor 2.5*fraksjonsdose (cGy)", True, self.mu) mu_total = 0 if self.has_prescription(): t.expected = "<" + str( round(RSU.fraction_dose(self.beam_set) * 250, 1)) if self.is_vmat(): for beam in self.beam_set.Beams: mu_total += beam.BeamMU if mu_total > RSU.fraction_dose(self.beam_set) * 250: return t.fail(round(mu_total, 1)) else: return t.succeed()
def stereotactic_mu_test(self): t = TEST.Test( "Bør som hovedregel være innenfor 1.4*fraksjonsdose (cGy)", True, self.mu) mu_total = 0 if self.has_prescription(): t.expected = "<" + str(RSU.fraction_dose(self.beam_set) * 140) if self.ts_label.label.technique: if self.ts_label.label.technique.upper() == 'S': for beam in self.beam_set.Beams: mu_total += beam.BeamMU if mu_total > RSU.fraction_dose(self.beam_set) * 140: return t.fail(round(mu_total, 1)) else: return t.succeed()
def stereotactic_beam_distribution_mu_test(self): t = TEST.Test( "Antall MU bør være jevnt fordelt per bue (buelengde tatt i betraktning). MU på denne buen er > 1.15 * forventningsverdien.", True, self.mu) beam_start = 0 beam_stop = 0 beam_length = 0 total_beam_length = 0 if self.ts_beam_set.has_prescription(): if len(list(self.ts_beam_set.beam_set.Beams)) > 1: if self.ts_beam_set.ts_label.label.technique: if self.ts_beam_set.ts_label.label.technique.upper( ) == 'S': for beam in self.ts_beam_set.beam_set.Beams: beam_start = beam.GantryAngle beam_stop = beam.ArcStopGantryAngle if beam_start > 180: total_beam_length += 360 - beam_start else: total_beam_length += beam_start if beam_stop > 180: total_beam_length += 360 - beam_stop else: total_beam_length += beam_stop beam_start = self.beam.GantryAngle beam_stop = self.beam.ArcStopGantryAngle if beam_start > 180: beam_length += 360 - beam_start else: beam_length += beam_start if beam_stop > 180: beam_length += 360 - beam_stop else: beam_length += beam_stop t.expected = "<" + str( round( (beam_length / total_beam_length) * RSU.fraction_dose(self.ts_beam_set.beam_set) * 140)) if self.beam.BeamMU > ( beam_length / total_beam_length) * RSU.fraction_dose( self.ts_beam_set.beam_set) * 140 * 1.15: return t.fail(round(self.beam.BeamMU, 1)) else: return t.succeed()
def vmat_mu_test(self): t = TEST.Test( "Bør som hovedregel være innenfor 2.5*fraksjonsdose (cGy) (+/- 5 MU)", True, self.mu) mu_total = 0 if self.has_prescription(): # Do not run MU test on SBRT plans: if self.ts_label.label.technique.upper() != 'S': t.expected = "<" + str( round(RSU.fraction_dose(self.beam_set) * 250 + 5, 1)) if self.is_vmat(): for beam in self.beam_set.Beams: mu_total += beam.BeamMU if mu_total > RSU.fraction_dose(self.beam_set) * 250 + 5: return t.fail(round(mu_total, 1)) else: return t.succeed()
def prescription_mu_test(self): t = TEST.Test( "Skal stå i forhold til fraksjonsdosen for beam-settet, bør som hovedregel være innenfor +/- 15% av fraksjonsdosen (cGy)", True, self.mu) mu_total = 0 for beam in self.beam_set.Beams: mu_total += beam.BeamMU if not self.is_vmat(): if not self.ts_label.label.region in RC.breast_reg_codes: # Naive approximation only relevant for conventional plans (not VMAT): # Sum of monitor units compared to fraction dose (+/- 15% of 100Mu/Gy): percent_dev = (mu_total - RSU.fraction_dose(self.beam_set) * 100) / (RSU.fraction_dose(self.beam_set) * 100) * 100 t.expected = RSU.fraction_dose(self.beam_set) * 100 if abs(percent_dev) > 15: return t.fail(round(mu_total, 1)) else: return t.succeed()