Example #1
0
 def energy_of_arc_test(self):
   t = TEST.Test("Skal normalt ikke bruke 15 MV ved VMAT", '6 eller 10', self.energy)
   if self.is_vmat():
     if self.beam.BeamQualityId == '15':
       return t.fail(self.beam.BeamQualityId)
     else:
       return t.succeed()
Example #2
0
 def mu_beam_vmat_test(self):
   t = TEST.Test("Skal være høyere enn nedre praktiserte grense", '>2', self.mu)
   if self.is_vmat():
     if self.beam.BeamMU < 2:
       return t.fail(self.beam.BeamMU)
     else:
       return t.succeed()
Example #3
0
 def collimator_angle_of_arc_test(self):
   t = TEST.Test("Skal normalt unngå rette vinkler for VMAT buer", 'Ulik [0, 90, 180, 270]', self.collimator)
   if self.beam.ArcRotationDirection != 'None':
     if self.beam.InitialCollimatorAngle in [0, 90, 180, 270]:
       return t.fail(self.beam.InitialCollimatorAngle)
     else:
       return t.succeed()
 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()
Example #5
0
 def prosthesis_titanium_test(self):
     t = TEST.Test(
         "Hvis proteser er til stedet, skal disse hete " +
         ROIS.prosthesis.name + ", " + ROIS.prosthesis_r.name + " eller " +
         ROIS.prosthesis_l.name + " og skal være satt til 'Titanium'", True,
         self.geometry)
     # Run test if this structure set corresponds to the examination used for the treatment plan:
     match = False
     for rg in self.structure_set.RoiGeometries:
         if rg.OfRoi.Name in [
                 ROIS.prosthesis.name, ROIS.prosthesis_r.name,
                 ROIS.prosthesis_l.name
         ]:
             if rg.OfRoi.Name in [
                     ROIS.prosthesis.name, ROIS.prosthesis_r.name,
                     ROIS.prosthesis_l.name
             ] and rg.OfRoi.RoiMaterial.OfMaterial.Name == 'Titanium' and rg.OfRoi.RoiMaterial.OfMaterial.MassDensity == 4.54:
                 match = True
             else:
                 match = False
         else:
             match = True
     for rg in self.structure_set.RoiGeometries:
         if rg.OfRoi.RoiMaterial:
             if rg.OfRoi.RoiMaterial.OfMaterial.Name == 'Titanium' and rg.OfRoi.Name not in [
                     ROIS.prosthesis.name, ROIS.prosthesis_r.name,
                     ROIS.prosthesis_l.name
             ]:
                 match = False
         else:
             match = True
     if match:
         return t.succeed()
     else:
         return t.fail()
Example #6
0
 def external_bounding_test(self):
     t = TEST.Test(
         "External ligger helt på yttergrensen av bildeopptaket. Dette kan tyde på at CT-bildene er beskjært uheldig, og at deler av pasienten mangler. Dersom denne beskjæringen forekommer i nærheten av målvolumet, vil det resultere i feil doseberegning.",
         True, self.external_bounding)
     # Run test if this structure set corresponds to the examination used for the treatment plan:
     has_external_at_bounding_box = False
     for rg in self.structure_set.RoiGeometries:
         if rg.OfRoi.Type == ROIS.external.type:
             # Check if the external bounding box equals that of its image series
             # (which indicates that the patient was cropped with the chosen FOV,
             # and that dose computation will not be accurate).
             ext_box = rg.GetBoundingBox()
             for series in self.structure_set.OnExamination.Series:
                 img_box = series.ImageStack.GetBoundingBox()
                 # We check in lateral (x) and vertical (y) directions:
                 if abs(ext_box[0].x - img_box[0].x) < 0.1:
                     has_external_at_bounding_box = True
                 if abs(ext_box[1].x - img_box[1].x) < 0.1:
                     has_external_at_bounding_box = True
                 if abs(ext_box[0].y - img_box[0].y) < 0.1:
                     has_external_at_bounding_box = True
                 if abs(ext_box[1].y - img_box[1].y) < 0.1:
                     has_external_at_bounding_box = True
             if has_external_at_bounding_box:
                 return t.fail()
             else:
                 return t.succeed()
Example #7
0
    def update_tests(self, tests):
        new_tests = []
        for testname in tests:
            file_md5 = testf.md5(testname)

            if testname not in self.tests:
                test = testf.Test(name=testname,
                                  id=self.get_count_tests(),
                                  file_md5=file_md5)
                self.tests[testname] = test
                self.is_changed = True
                new_tests.append(test)
            else:
                test = self.tests[testname]
                if test.md5 != file_md5:
                    new_tests.append(test)
                    self.is_changed = True
                    test.md5 = file_md5
                    for solution_name in self.all_solutions.keys():
                        solution = self.all_solutions[solution_name]
                        solution.times[test.id] = None
                        if test.id in solution.rt:
                            solution.rt.remove(test.id)
                        if test.id in solution.tl:
                            solution.tl.remove(test.id)

        return new_tests
Example #8
0
 def dose_grid_test(self):
     # Default voxel size:
     max_voxel_size = 0.3
     # Expected dose grid resolution depends on whether the beam set is stereotactic or not and which region is treated:
     if self.is_stereotactic():
         if self.ts_beam_set.ts_label.label.region in RC.brain_codes:
             max_voxel_size = 0.1
         elif self.ts_beam_set.ts_label.label.region in RC.lung_and_mediastinum_codes:
             max_voxel_size = 0.2
         else:
             # Bone mets SBRT:
             max_voxel_size = 0.1
     else:
         # Conventional treatment:
         if self.ts_beam_set.ts_label.label.region in RC.brain_codes:
             max_voxel_size = 0.2
         elif self.ts_beam_set.ts_label.label.region in RC.prostate_codes:
             max_voxel_size = 0.2
     # Create the test:
     t = TEST.Test(
         "Skal i utgangspunktet bruke dose grid med maks voksel størrelse: "
         + str(max_voxel_size) + " cm", "<=" + str(max_voxel_size),
         self.grid)
     # Determine actual value:
     grid = self.optimization.OptimizationParameters.TreatmentSetupSettings[
         0].ForTreatmentSetup.FractionDose.InDoseGrid.VoxelSize
     grid_max = max([grid.x, grid.y, grid.z])
     # Test:
     if grid_max <= max_voxel_size:
         return t.succeed()
     else:
         return t.fail(grid_max)
    def mlc_corner_validity_test(self):
        t = TEST.Test("Skal ha hjørne-posisjoner som er leverbare på Elekta",
                      True, self.mlc)
        violated = False
        # Agility/Versa HD:
        limits = [20.0 for i in range(80)]
        limits[0] = limits[79] = 16.1
        limits[1] = limits[78] = 16.7
        limits[2] = limits[77] = 17.3
        limits[3] = limits[76] = 17.8
        limits[4] = limits[75] = 18.3
        limits[5] = limits[74] = 18.8
        limits[6] = limits[73] = 19.2
        limits[7] = limits[72] = 19.7

        # Iterate leaf positions and check against limits:
        #for i in range(len(limits)):
        for i in it.chain(range(0, 7), range(72, 79)):
            if self.segment.LeafPositions[0][i] < -limits[i]:
                violated = True
            if self.segment.LeafPositions[1][i] > limits[i]:
                violated = True

        if violated:
            return t.fail(False)
        else:
            return t.succeed()
Example #10
0
 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))
Example #11
0
 def breast_oar_defined_test(self):
     failed_geometries = []
     t = TEST.Test("Regionen må ha definert volum:", True, self.defined_roi)
     t.expected = None
     ss = self.ts_beam_sets[0].ts_structure_set().structure_set
     roi_not_contours_dict = SSF.create_roi_dict_not_contours(ss)
     roi_and_region_dict = {
         ROIS.a_lad.name: RC.breast_r_codes,
         ROIS.breast_r_draft.name: RC.breast_l_codes,
         ROIS.breast_r.name: RC.breast_l_codes,
         ROIS.breast_l.name: RC.breast_r_codes
     }
     if self.ts_case.ts_plan.ts_beam_sets[0].ts_label.label.region:
         for key, value in roi_and_region_dict.items():
             if roi_not_contours_dict.get(key) and self.ts_beam_sets[
                     0].ts_label.label.region in value:
                 del roi_not_contours_dict[key]
     structure_sets = self.ts_case.case.PatientModel.StructureSets
     for i in range(len(structure_sets)):
         if structure_sets[i].OnExamination.Name != self.ts_beam_sets[
                 0].ts_structure_set().structure_set.OnExamination.Name:
             roi = structure_sets[i].RoiGeometries
             for j in range(len(roi)):
                 if roi[j].HasContours() and roi_not_contours_dict.get(
                         roi[j].OfRoi.Name):
                     del roi_not_contours_dict[roi[j].OfRoi.Name]
     if len(roi_not_contours_dict.keys()) >= 1:
         return t.fail(list(roi_not_contours_dict.keys()))
     else:
         return t.succeed()
 def setup_beams_test(self):
     t = TEST.Test("'Create setup beams' skal ikke være aktivert", False,
                   self.param)
     if self.beam_set.PatientSetup.UseSetupBeams:
         return t.fail(True)
     else:
         return t.succeed()
Example #13
0
    def dose_grid_test(self):
        correct_grid = 0.3
        match = True
        grid = self.optimization.OptimizationParameters.TreatmentSetupSettings[
            0].ForTreatmentSetup.FractionDose.InDoseGrid.VoxelSize
        if self.ts_beam_set.ts_label.label.technique:
            if self.ts_beam_set.ts_label.label.technique.upper(
            ) == 'S' and self.ts_beam_set.ts_label.label.region in RC.brain_partial_codes:
                if grid.x != 0.1 or grid.y != 0.1 or grid.z != 0.1:
                    correct_grid = 0.1
                    match = False
            elif self.ts_beam_set.ts_label.label.region in RC.brain_partial_codes or self.ts_beam_set.ts_label.label.region in RC.prostate_codes or self.ts_beam_set.ts_label.label.technique.upper(
            ) == 'S' and self.ts_beam_set.ts_label.label.region in RC.lung_codes:
                if grid.x != 0.2 or grid.y != 0.2 or grid.z != 0.2:
                    correct_grid = 0.2
                    match = False
            elif grid.x != 0.3 or grid.y != 0.3 or grid.z != 0.3:
                correct_grid = 0.3
                match = False

        t = TEST.Test(
            "Skal i utgangspunktet bruke dosegrid: " + str(correct_grid) +
            "x" + str(correct_grid) + "x" + str(correct_grid) + " cm^3", True,
            self.grid)
        if match:
            return t.succeed()
        else:
            return t.fail(grid.x)
Example #14
0
 def name_capitalization_test(self):
   t = TEST.Test("Skal være navngitt med stor forbokstav", None, self.name)
   if self.beam.Name[0].isupper() or not self.beam.Name[0].isalpha():
     return t.succeed()
   else:
     t.expected = self.beam.Name[0].upper()
     return t.fail(self.beam.Name[0])
Example #15
0
 def bolus_set_test(self):
   t = TEST.Test("Bolus forventes å være aktivert for feltet når en bolus ROI eksisterer i struktursettet", None, self.param)
   if PMF.bolus(self.ts_beam_set.ts_plan.ts_case.case.PatientModel):
     t.expected = str(PMF.bolus_names(self.ts_beam_set.ts_plan.ts_case.case.PatientModel))
     if len(self.beam.Boli) > 0:
       return t.succeed()
     else:
       return t.fail(None)
Example #16
0
 def gantry_angle_test(self):
     t = TEST.Test(
         "Gantryvinkel lik 180 grader bør unngås, da denne vinkelen er tvetydig. Bruk < eller > enn 180.0, og velg den siden som best passer overens med øvrige feltvinkler samt planlagt XVI-protokoll.",
         '!= 180.0', self.gantry)
     if self.beam.GantryAngle == 180:
         return t.fail(self.beam.GantryAngle)
     else:
         return t.succeed()
 def technique_test(self):
     t = TEST.Test("Plan-teknikk skal være en av disse",
                   ['3D-CRT', 'SMLC', 'VMAT'], self.technique)
     if not self.beam_set.DeliveryTechnique in ('Arc', 'SMLC', '3DCRT',
                                                'DynamicArc'):
         return t.fail(self.beam_set.DeliveryTechnique)
     else:
         return t.succeed()
 def dose_is_clinical_test(self):
     t = TEST.Test("Beregning skal være markert som 'klinisk'", True,
                   self.dose)
     if self.has_dose():
         if self.beam_set.FractionDose.DoseValues.IsClinical:
             return t.succeed()
         else:
             return t.fail()
Example #19
0
 def number_of_segments_of_static_beam_test(self):
   t = TEST.Test("Skal i utgangspunktet være tilbakeholden med å bruke mange segmenter (ved IMRT)", '<8', self.segments)
   if self.beam.ArcRotationDirection == 'None':
     nr_segments = RSU.soc_length(self.beam.Segments)
     if nr_segments >= 8:
       return t.fail(nr_segments)
     else:
       return t.succeed()
Example #20
0
 def mu_segment_3dcrt_test(self):
   t = TEST.Test("Skal være høyere enn nedre praktiserte grense", '>2', self.mu)
   if self.beam.ArcRotationDirection == 'None':
     for segment in self.beam.Segments:
       if self.beam.BeamMU*segment.RelativeWeight < 2:
         return t.fail(round(self.beam.BeamMU*segment.RelativeWeight, 2))
       else:
         return t.succeed()
 def id_space_test(self):
     t = TEST.Test(
         'Skal være mellomrom mellom fødselsdato og personnr (ddmmåå xxxxx)',
         ' ', self.id)
     if len(self.patient.PatientID) != 12:
         return t.fail(len(self.patient.PatientID))
     else:
         return t.succeed()
Example #22
0
 def prescription_type_test(self):
     t = TEST.Test("Skal være en av disse",
                   ['MedianDose', 'DoseAtPoint', 'DoseAtVolume'], self.type)
     if self.prescription.PrimaryDosePrescription.PrescriptionType in (
             'MedianDose', 'DoseAtPoint', 'DoseAtVolume'):
         return t.succeed()
     else:
         return t.fail()
Example #23
0
 def nr_parts_test(self):
     t = TEST.Test(
         "Skal være 3 deler adskilt av kolon (eks '342V:70-78:4')", 3,
         self.param)
     if len(self.label.parts) == 3:
         return t.succeed()
     else:
         return t.fail(len(self.label.parts))
Example #24
0
 def planned_by_test(self):
     t = TEST.Test(
         'Doseplanleggerens initialer bør være fylt inn her (Planned by)',
         True, self.planned_by)
     if self.plan.PlannedBy:
         return t.succeed()
     else:
         return t.fail()
Example #25
0
 def prescription_poi_target_volume_test(self):
     t = TEST.Test(
         "Punktnormering skal kun benyttes for planer som ikke har målvolum definert",
         False, self.type)
     if self.prescription.PrimaryDosePrescription.PrescriptionType == 'DoseAtPoint':
         if self.ts_beam_set.ts_plan.ts_case.has_target_volume:
             return t.fail(True)
         else:
             return t.succeed()
Example #26
0
 def middle_part_separator_test(self):
     t = TEST.Test(
         "Midterste del skal inneholde to deler adskilt av bindestrek (eks '342V:70-78:4')",
         True, self.param)
     if len(self.label.parts) == 3:
         if len(self.label.middle_parts) == 2:
             return t.succeed()
         else:
             return t.fail(len(self.label.middle_parts))
Example #27
0
 def region_test(self):
     t = TEST.Test(
         "Første del (av første del) skal være et heltall for regionkode (eks '342V:70-78:4')",
         True, self.param)
     if len(self.label.parts) == 3:
         if self.label.region:
             return t.succeed()
         else:
             return t.fail(self.label.region)
Example #28
0
 def technique_test(self):
     t = TEST.Test(
         "Siste tegn av første del skal være en bokstav for plan-teknikk (eks '342V:70-78:4')",
         True, self.param)
     if len(self.label.parts) == 3:
         if self.label.technique:
             return t.succeed()
         else:
             return t.fail(self.label.technique)
Example #29
0
 def nr_fractions_test(self):
     t = TEST.Test(
         "Siste del skal være heltall for antall fraksjoner (eks '342V:70-78:4')",
         True, self.param)
     if len(self.label.parts) == 3:
         if self.label.nr_fractions:
             return t.succeed()
         else:
             return t.fail(self.label.nr_fractions)
Example #30
0
 def is_not_zero_test(self):
     t = TEST.Test("Skal ikke ha koordinater i punktet: 0,0,0", True,
                   self.coordinates)
     if self.poi_geometry.Point:
         # When the poi geometry is undefined, RayStation seems to represent this with the min float value:
         if self.poi_geometry.Point.x == 0 and self.poi_geometry.Point.y == 0 and self.poi_geometry.Point.z == 0:
             return t.fail()
         else:
             return t.succeed()