def test_simple_interface(check_list=True):
    if check_list:
        inputs = ['1', '2', '3', '4']
        color_inputs = ['Red', 'Blue', 'Green', 'Yellow']
        quest_inputs = [
            'To buy an argument.', 'To find the Holy Grail.',
            'To beat Confucious in a foot race.'
        ]
        name_inputs = [
            'Arthur',
            'Tarquin Fin-tim-lin-bin-whin-bim-lim-bus-stop-Ftang-Ftang-Ole-Biscuitbarrel'
        ]
        sample_dialog = UserInterface.InputDialog(
            title='Sample Interface',
            inputs={
                inputs[0]: 'What is your favorite color?',
                inputs[1]: 'What is your quest?',
                inputs[2]: 'What is your Name?',
                inputs[3]:
                'What Is the Airspeed Velocity of an Unladen Swallow?'
            },
            datatype={
                inputs[0]: 'check',
                inputs[1]: 'combo',
                inputs[2]: 'combo'
            },
            initial={color_inputs[0]: '40'},
            options={
                inputs[0]: color_inputs,
                inputs[1]: quest_inputs,
                inputs[2]: name_inputs
            },
            required=[inputs[0], inputs[1]])
        options_response = sample_dialog.show()

        if options_response == {}:
            sys.exit('Selection of planning structure options was cancelled')

        message = ''
        for k, v in sample_dialog.values.iteritems():
            message += k + ' : ' + str(v) + '\n'

        UserInterface.MessageBox(message)
Esempio n. 2
0
        options['a'].append('Beam Dose')
        inputs['c'] = 'Select which delivery system to export as:'
        required.append('c')
        types['c'] = 'combo'
        options['c'] = DicomExport.machines(beamset)
        if len(options['c']) == 1:
            initial['c'] = options['c'][0]

        inputs['e'] = 'Export options:'
        types['e'] = 'check'
        options['e'] = filters
        initial['e'] = filters

    dialog = UserInterface.InputDialog(inputs=inputs,
                                       datatype=types,
                                       options=options,
                                       initial=initial,
                                       required=required,
                                       title='Export Options')
    response = dialog.show()
    if response == {}:
        status.finish('DICOM export was cancelled')
        sys.exit('DICOM export was cancelled')

    # Execute DicomExport.send() given user response
    status.next_step(
        text=
        'The DICOM datasets are now being exported to a temporary directory, converted to a '
        +
        'treatment delivery system, and sent to the selected destination. Please be patient, as '
        + 'this can take several minutes...')
def main():
    import UserInterface
    import connect
    import logging
    import sys

    # These are the techniques associated with billing codes in the clinic
    # they will be imported
    availabletechniques = [
        'Static MLC -- 2D', 'Static NoMLC -- 2D', 'Electron -- 2D',
        'Static MLC -- 3D', 'Static NoMLC -- 3D', 'Electron -- 3D',
        'FiF MLC -- 3D', 'Static PRDR MLC -- 3D', 'SnS MLC -- IMRT',
        'SnS PRDR MLC -- IMRT', 'Conformal Arc -- 3D', 'VMAT Arc -- IMRT'
    ]
    supportedRStechniques = ['SMLC', 'DynamicArc']

    dialog = UserInterface.InputDialog(
        inputs={
            'Site': 'Enter a Site name, e.g. BreL',
            'Technique': 'Select Treatment Technique (Billing)'
        },
        datatype={'Technique': 'combo'},
        initial={'Technique': 'Select'},
        options={'Technique': availabletechniques},
        required=['Site', 'Technique'])
    # Show the dialog
    print dialog.show()

    site_name = dialog.values['Site']
    inputtechnique = dialog.values['Technique']

    try:
        patient = connect.get_current('Patient')
        case = connect.get_current('Case')
        exam = connect.get_current('Examination')
        plan = connect.get_current('Plan')
        beamset = connect.get_current("BeamSet")

    except Exception:
        UserInterface.WarningBox(
            'This script requires a Beam Set to be loaded')
        sys.exit('This script requires a Beam Set to be loaded')

    #
    # Electrons, 3D, and VMAT Arcs are all that are supported.  Reject plans that aren't
    technique = beamset.DeliveryTechnique
    #
    # Oddly enough, Electrons are DeliveryTechnique = 'SMLC'
    if technique not in supportedRStechniques:
        raise IOError(
            "Technique unsupported, manually name beams according to clinical convention."
        )

    # While loop variable definitions
    beam_index = 0
    patient_position = beamset.PatientPosition
    logging.debug(
        'Renaming and adding set up fields to Beam Set with name {}, patient position {}, technique {}'
        .format(beamset.DicomPlanLabel, beamset.PatientPosition,
                beamset.DeliveryTechnique))
    #
    # HFS Beam Naming
    if patient_position == 'HeadFirstSupine':
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        inputtechnique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + inputtechnique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif gantry_angle > 180 and gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif gantry_angle > 270 and gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif gantry_angle > 0 and gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif gantry_angle > 90 and gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'

                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                UserInterface.WarningBox(
                    'Error occured in setting names of beams')
                sys.exit('Error occurred in setting names of beams')
        connect.await_user_input(
            'Please go to Plan Design>Plan Setup and use Copy Setup to ensure there are 4 Setup beams'
        )
        #
        # Set-Up Fields
        try:
            #
            # AP set-up field
            beamset.PatientSetup.SetupBeams[0].Name = "SetUp AP"
            beamset.PatientSetup.SetupBeams[0].Description = "SetUp AP"
            beamset.PatientSetup.SetupBeams[0].GantryAngle = "0.0"
            beamset.PatientSetup.SetupBeams[0].Segments[0].DoseRate = "5"

            #
            # Rt Lateral set-up field
            beamset.PatientSetup.SetupBeams[1].Name = "SetUp RtLat"
            beamset.PatientSetup.SetupBeams[1].Description = "SetUp RtLat"
            beamset.PatientSetup.SetupBeams[1].GantryAngle = "270.0"
            beamset.PatientSetup.SetupBeams[1].Segments[0].DoseRate = "5"

            #
            # Lt Lateral set-up field
            beamset.PatientSetup.SetupBeams[2].Name = "SetUp LtLat"
            beamset.PatientSetup.SetupBeams[2].Description = "SetUp LtLat"
            beamset.PatientSetup.SetupBeams[2].GantryAngle = "90.0"
            beamset.PatientSetup.SetupBeams[2].Segments[0].DoseRate = "5"
            #
            # Cone-Beam CT set-up field
            try:
                beamset.PatientSetup.SetupBeams[3].Name = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].Description = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].GantryAngle = "0.0"
                beamset.PatientSetup.SetupBeams[3].Segments[0].DoseRate = "5"
            except:
                connect.await_user_input(
                    'Pretty Please go to Plan Design>Plan Setup and copy any Setup Beam then continue script'
                )
                beamset.PatientSetup.SetupBeams[3].Name = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].Description = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].GantryAngle = "0.0"
                beamset.PatientSetup.SetupBeams[3].Segments[0].DoseRate = "5"
        except:
            raise IOError(
                'Please select Create Set Up Beams in Edit Plan and Rerun script'
            )

            # Address the Head-first prone position
    elif patient_position == 'HeadFirstProne':
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        inputtechnique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + inputtechnique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif gantry_angle > 180 and gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif gantry_angle > 270 and gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif gantry_angle > 0 and gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif gantry_angle > 90 and gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                UserInterface.WarningBox(
                    'Error occured in setting names of beams')
                sys.exit('Error occurred in setting names of beams')
        connect.await_user_input(
            'Please go to Plan Design>Plan Setup and use Copy Setup to ensure there are 4 Setup beams'
        )
        #
        # Set-Up fields
        try:
            #
            # PA set-up field
            beamset.PatientSetup.SetupBeams[0].Name = "SetUp PA"
            beamset.PatientSetup.SetupBeams[0].Description = "SetUp PA"
            beamset.PatientSetup.SetupBeams[0].GantryAngle = "0.0"
            beamset.PatientSetup.SetupBeams[0].Segments[0].DoseRate = "5"

            #
            # Rt Lateral set-up field
            beamset.PatientSetup.SetupBeams[1].Name = "SetUp RtLat"
            beamset.PatientSetup.SetupBeams[1].Description = "SetUp RtLat"
            beamset.PatientSetup.SetupBeams[1].GantryAngle = "90.0"
            beamset.PatientSetup.SetupBeams[1].Segments[0].DoseRate = "5"

            #
            # Lt Lateral set-up field
            beamset.PatientSetup.SetupBeams[2].Name = "SetUp LtLat"
            beamset.PatientSetup.SetupBeams[2].Description = "SetUp LtLat"
            beamset.PatientSetup.SetupBeams[2].GantryAngle = "270.0"
            beamset.PatientSetup.SetupBeams[2].Segments[0].DoseRate = "5"

            #
            # Cone-Beam CT set-up field
            try:
                beamset.PatientSetup.SetupBeams[3].Name = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].Description = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].GantryAngle = "0.0"
                beamset.PatientSetup.SetupBeams[3].Segments[0].DoseRate = "5"
            except:
                connect.await_user_input(
                    'Pretty Please go to Plan Design>Plan Setup and copy any Setup Beam then continue script'
                )
                beamset.PatientSetup.SetupBeams[3].Name = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].Description = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].GantryAngle = "0.0"
                beamset.PatientSetup.SetupBeams[3].Segments[0].DoseRate = "5"
        except:
            raise IOError(
                'Please select Create Set Up Beams in Edit Plan and Rerun script'
            )
            # Address the Feet-first supine position
    elif patient_position == 'FeetFirstSupine':
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        inputtechnique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + inputtechnique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif gantry_angle > 180 and gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif gantry_angle > 270 and gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif gantry_angle > 0 and gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif gantry_angle > 90 and gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                UserInterface.WarningBox(
                    'Error occured in setting names of beams')
                sys.exit('Error occurred in setting names of beams')
        connect.await_user_input(
            'Please go to Plan Design>Plan Setup and use Copy Setup to ensure there are 4 Setup beams'
        )
        #
        # Set-Up Fields
        try:
            # AP set-up field
            beamset.PatientSetup.SetupBeams[0].Name = "SetUp AP"
            beamset.PatientSetup.SetupBeams[0].Description = "SetUp AP"
            beamset.PatientSetup.SetupBeams[0].GantryAngle = "0.0"
            beamset.PatientSetup.SetupBeams[0].Segments[0].DoseRate = "5"

            # Rt Lateral set-up field
            beamset.PatientSetup.SetupBeams[1].Name = "SetUp RtLat"
            beamset.PatientSetup.SetupBeams[1].Description = "SetUp RtLat"
            beamset.PatientSetup.SetupBeams[1].GantryAngle = "90.0"
            beamset.PatientSetup.SetupBeams[1].Segments[0].DoseRate = "5"

            # Lt Lateral set-up field
            beamset.PatientSetup.SetupBeams[2].Name = "SetUp LtLat"
            beamset.PatientSetup.SetupBeams[2].Description = "SetUp LtLat"
            beamset.PatientSetup.SetupBeams[2].GantryAngle = "270.0"
            beamset.PatientSetup.SetupBeams[2].Segments[0].DoseRate = "5"

            #
            # Cone-Beam CT set-up field
            try:
                beamset.PatientSetup.SetupBeams[3].Name = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].Description = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].GantryAngle = "0.0"
                beamset.PatientSetup.SetupBeams[3].Segments[0].DoseRate = "5"
            except:
                connect.await_user_input(
                    'Pretty Please go to Plan Design>Plan Setup and copy any Setup Beam then continue script'
                )
                beamset.PatientSetup.SetupBeams[3].Name = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].Description = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].GantryAngle = "0.0"
                beamset.PatientSetup.SetupBeams[3].Segments[0].DoseRate = "5"
        except:
            raise IOError(
                'Please select Create Set Up Beams in Edit Plan and Rerun script'
            )

            # Address the Feet-first prone position
    elif patient_position == 'FeetFirstProne':
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        inputtechnique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + inputtechnique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif gantry_angle > 180 and gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif gantry_angle > 270 and gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif gantry_angle > 0 and gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif gantry_angle > 90 and gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                UserInterface.WarningBox(
                    'Error occured in setting names of beams')
                sys.exit('Error occurred in setting names of beams')
        connect.await_user_input(
            'Please go to Plan Design>Plan Setup and use Copy Setup to ensure there are 4 Setup beams'
        )
        try:
            # PA set-up field
            beamset.PatientSetup.SetupBeams[0].Name = "SetUp PA"
            beamset.PatientSetup.SetupBeams[0].Description = "SetUp PA"
            beamset.PatientSetup.SetupBeams[0].GantryAngle = "0.0"
            beamset.PatientSetup.SetupBeams[0].Segments[0].DoseRate = "5"

            # Rt Lateral set-up field
            beamset.PatientSetup.SetupBeams[1].Name = "SetUp RtLat"
            beamset.PatientSetup.SetupBeams[1].Description = "SetUp RtLat"
            beamset.PatientSetup.SetupBeams[1].GantryAngle = "270.0"
            beamset.PatientSetup.SetupBeams[1].Segments[0].DoseRate = "5"

            # Lt Lateral set-up field
            beamset.PatientSetup.SetupBeams[2].Name = "SetUp LtLat"
            beamset.PatientSetup.SetupBeams[2].Description = "SetUp LtLat"
            beamset.PatientSetup.SetupBeams[2].GantryAngle = "90.0"
            beamset.PatientSetup.SetupBeams[2].Segments[0].DoseRate = "5"
            #
            # Cone-Beam CT set-up field
            try:
                beamset.PatientSetup.SetupBeams[3].Name = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].Description = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].GantryAngle = "0.0"
                beamset.PatientSetup.SetupBeams[3].Segments[0].DoseRate = "5"
            except:
                connect.await_user_input(
                    'Pretty Please go to Plan Design>Plan Setup and copy any Setup Beam then continue script'
                )
                beamset.PatientSetup.SetupBeams[3].Name = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].Description = "SetUp CBCT"
                beamset.PatientSetup.SetupBeams[3].GantryAngle = "0.0"
                beamset.PatientSetup.SetupBeams[3].Segments[0].DoseRate = "5"
        except:
            raise IOError(
                'Please select Create Set Up Beams in Edit Plan and Rerun script'
            )
    else:
        raise IOError(
            "Patient Orientation Unsupported.. Manual Beam Naming Required")
Esempio n. 4
0
def main():
    import UserInterface
    import connect
    import logging
    import sys

    # These are the techniques associated with billing codes in the clinic
    # they will be imported
    available_techniques = [
        'Static MLC -- 2D', 'Static NoMLC -- 2D', 'Electron -- 2D',
        'Static MLC -- 3D', 'Static NoMLC -- 3D', 'Electron -- 3D',
        'FiF MLC -- 3D', 'Static PRDR MLC -- 3D', 'SnS MLC -- IMRT',
        'SnS PRDR MLC -- IMRT', 'Conformal Arc -- 2D', 'Conformal Arc -- 3D',
        'VMAT Arc -- IMRT'
    ]
    supported_rs_techniques = ['SMLC', 'DynamicArc']

    try:
        patient = connect.get_current('Patient')
        case = connect.get_current('Case')
        exam = connect.get_current('Examination')
        plan = connect.get_current('Plan')
        beamset = connect.get_current("BeamSet")

    except Exception:
        UserInterface.WarningBox(
            'This script requires a Beam Set to be loaded')
        sys.exit('This script requires a Beam Set to be loaded')

    initial_sitename = beamset.DicomPlanLabel[:4]
    # Prompt the user for Site Name and Billing technique
    dialog = UserInterface.InputDialog(
        inputs={
            'Site': 'Enter a Site name, e.g. BreL',
            'Technique': 'Select Treatment Technique (Billing)'
        },
        datatype={'Technique': 'combo'},
        initial={
            'Technique': 'Select',
            'Site': initial_sitename
        },
        options={'Technique': available_techniques},
        required=['Site', 'Technique'])
    # Show the dialog
    print dialog.show()

    site_name = dialog.values['Site']
    input_technique = dialog.values['Technique']
    #
    # Electrons, 3D, and VMAT Arcs are all that are supported.  Reject plans that aren't
    technique = beamset.DeliveryTechnique
    #
    # Oddly enough, Electrons are DeliveryTechnique = 'SMLC'
    if technique not in supported_rs_techniques:
        logging.warning(
            'Technique: {} unsupported in renaming script'.format(technique))
        raise IOError(
            "Technique unsupported, manually name beams according to clinical convention."
        )

    # While loop variable definitions
    beam_index = 0
    patient_position = beamset.PatientPosition
    # Turn on set-up fields
    beamset.PatientSetup.UseSetupBeams = True
    logging.debug(
        'Renaming and adding set up fields to Beam Set with name {}, patient position {}, technique {}'
        .format(beamset.DicomPlanLabel, beamset.PatientPosition,
                beamset.DeliveryTechnique))
    # Rename isocenters
    for b in beamset.Beams:
        iso_n = int(b.Isocenter.IsocenterNumber)
        b.Isocenter.Annotation.Name = 'Iso_' + beamset.DicomPlanLabel + '_' + str(
            iso_n + 1)
    #
    # HFS
    if patient_position == 'HeadFirstSupine':
        standard_beam_name = 'Naming Error'
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        input_technique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + input_technique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif 180 < gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif 270 < gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif 0 < gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif 90 < gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'

                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                logging.warning('Error occurred in setting names of beams')
                UserInterface.WarningBox(
                    'Error occurred in setting names of beams')
                sys.exit('Error occurred in setting names of beams')

    # Set-Up Fields
    # HFS Setup
    # set_up: [ Set-Up Field Name, Set-Up Field Description, Gantry Angle, Dose Rate]
        set_up = {
            0: ['SetUp AP', 'SetUp AP', 0.0, '5'],
            1: ['SetUp RtLat', 'SetUp RtLat', 270.0, '5'],
            2: ['SetUp LtLat', 'SetUp LtLat', 90.0, '5'],
            3: ['SetUp CBCT', 'SetUp CBCT', 0.0, '5']
        }
        # Extract the angles
        angles = []
        for k, v in set_up.iteritems():
            angles.append(v[2])
            print "v2={}".format(v[2])

        beamset.UpdateSetupBeams(ResetSetupBeams=True,
                                 SetupBeamsGantryAngles=angles)

        # Set the set-up parameter specifics
        for i, b in enumerate(beamset.PatientSetup.SetupBeams):
            b.Name = set_up[i][0]
            b.Description = set_up[i][1]
            b.GantryAngle = str(set_up[i][2])
            b.Segments[0].DoseRate = set_up[i][3]
    # HFLDR
    elif patient_position == 'HeadFirstDecubitusRight':
        standard_beam_name = 'Naming Error'
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        input_technique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + input_technique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif 180 < gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif 270 < gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif 0 < gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif 90 < gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'

                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                logging.warning('Error occurred in setting names of beams')
                UserInterface.WarningBox(
                    'Error occurred in setting names of beams')
                sys.exit('Error occurred in setting names of beams')

    # Set-Up Fields
    # HFLDR Setup
    # set_up: [ Set-Up Field Name, Set-Up Field Description, Gantry Angle, Dose Rate]
        set_up = {
            0: ['SetUp LtLat', 'SetUp LtLat', 0.0, '5'],
            1: ['SetUp AP', 'SetUp AP', 270.0, '5'],
            2: ['SetUp PA', 'SetUp PA', 90.0, '5'],
            3: ['SetUp CBCT', 'SetUp CBCT', 0.0, '5']
        }
        # Extract the angles
        angles = []
        for k, v in set_up.iteritems():
            angles.append(v[2])
            print "v2={}".format(v[2])

        beamset.UpdateSetupBeams(ResetSetupBeams=True,
                                 SetupBeamsGantryAngles=angles)

        # Set the set-up parameter specifics
        for i, b in enumerate(beamset.PatientSetup.SetupBeams):
            b.Name = set_up[i][0]
            b.Description = set_up[i][1]
            b.GantryAngle = str(set_up[i][2])
            b.Segments[0].DoseRate = set_up[i][3]
    # HFLDL
    elif patient_position == 'HeadFirstDecubitusLeft':
        standard_beam_name = 'Naming Error'
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        input_technique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + input_technique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif 180 < gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif 270 < gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif 0 < gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif 90 < gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'

                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                logging.warning('Error occurred in setting names of beams')
                UserInterface.WarningBox(
                    'Error occurred in setting names of beams')
                sys.exit('Error occurred in setting names of beams')

        # Set-Up Fields
        # HFLDL Setup
        # set_up: [ Set-Up Field Name, Set-Up Field Description, Gantry Angle, Dose Rate]
        set_up = {
            0: ['SetUp RtLat', 'SetUp RtLat', 0.0, '5'],
            1: ['SetUp PA', 'SetUp PA', 270.0, '5'],
            2: ['SetUp AP', 'SetUp AP', 90.0, '5'],
            3: ['SetUp CBCT', 'SetUp CBCT', 0.0, '5']
        }
        # Extract the angles
        angles = []
        for k, v in set_up.iteritems():
            angles.append(v[2])
            print "v2={}".format(v[2])

        beamset.UpdateSetupBeams(ResetSetupBeams=True,
                                 SetupBeamsGantryAngles=angles)

        # Set the set-up parameter specifics
        for i, b in enumerate(beamset.PatientSetup.SetupBeams):
            b.Name = set_up[i][0]
            b.Description = set_up[i][1]
            b.GantryAngle = str(set_up[i][2])
            b.Segments[0].DoseRate = set_up[i][3]
    # HFP
    elif patient_position == 'HeadFirstProne':
        standard_beam_name = 'Naming Error'
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        input_technique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + input_technique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif 180 < gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif 270 < gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif 0 < gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif 90 < gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                UserInterface.WarningBox(
                    'Error occurred in setting names of beams')
                sys.exit('Error occurred in setting names of beams')
        #
        # Set-Up fields
        # set_up: [ Set-Up Field Name, Set-Up Field Description, Gantry Angle, Dose Rate]
        set_up = {
            0: ['SetUp PA', 'SetUp PA', 0, '5'],
            1: ['SetUp RtLat', 'SetUp RtLat', 90.0, '5'],
            2: ['SetUp LtLat', 'SetUp LtLat', 270.0, '5'],
            3: ['SetUp CBCT', 'SetUp CBCT', 0.0, '5']
        }
        # Extract the angles
        angles = []
        for k, v in set_up.iteritems():
            angles.append(v[2])
        beamset.UpdateSetupBeams(ResetSetupBeams=True,
                                 SetupBeamsGantryAngles=angles)

        for i, b in enumerate(beamset.PatientSetup.SetupBeams):
            b.Name = set_up[i][0]
            b.Description = set_up[i][1]
            b.GantryAngle = str(set_up[i][2])
            b.Segments[0].DoseRate = set_up[i][3]
    # FFS
    elif patient_position == 'FeetFirstSupine':
        standard_beam_name = 'Naming Error'
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        input_technique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + input_technique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif 180 < gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif 270 < gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif 0 < gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif 90 < gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                UserInterface.WarningBox(
                    'Error occured in setting names of beams')
                sys.exit('Error occurred in setting names of beams')

        # Set-Up fields
        # set_up: [ Set-Up Field Name, Set-Up Field Description, Gantry Angle, Dose Rate]
        set_up = {
            0: ['SetUp AP', 'SetUp AP', 0, '5'],
            1: ['SetUp RtLat', 'SetUp RtLat', 90.0, '5'],
            2: ['SetUp LtLat', 'SetUp LtLat', 270.0, '5'],
            3: ['SetUp CBCT', 'SetUp CBCT', 0.0, '5']
        }
        # Extract the angles
        angles = []
        for k, v in set_up.iteritems():
            angles.append(v[2])
        beamset.UpdateSetupBeams(ResetSetupBeams=True,
                                 SetupBeamsGantryAngles=angles)

        for i, b in enumerate(beamset.PatientSetup.SetupBeams):
            b.Name = set_up[i][0]
            b.Description = set_up[i][1]
            b.GantryAngle = str(set_up[i][2])
            b.Segments[0].DoseRate = set_up[i][3]

            # Address the Feet-first prone position
    # FFLDR
    elif patient_position == 'FeetFirstDecubitusRight':
        standard_beam_name = 'Naming Error'
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        input_technique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + input_technique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif 180 < gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif 270 < gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif 0 < gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif 90 < gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'

                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                logging.warning('Error occurred in setting names of beams')
                UserInterface.WarningBox(
                    'Error occurred in setting names of beams')
                sys.exit('Error occurred in setting names of beams')

        # Set-Up Fields
        # FFLDR Setup
        # set_up: [ Set-Up Field Name, Set-Up Field Description, Gantry Angle, Dose Rate]
        set_up = {
            0: ['SetUp RtLat', 'SetUp RtLat', 0.0, '5'],
            1: ['SetUp PA', 'SetUp PA', 270.0, '5'],
            2: ['SetUp AP', 'SetUp AP', 90.0, '5'],
            3: ['SetUp CBCT', 'SetUp CBCT', 0.0, '5']
        }
        # Extract the angles
        angles = []
        for k, v in set_up.iteritems():
            angles.append(v[2])
            print "v2={}".format(v[2])

        beamset.UpdateSetupBeams(ResetSetupBeams=True,
                                 SetupBeamsGantryAngles=angles)

        # Set the set-up parameter specifics
        for i, b in enumerate(beamset.PatientSetup.SetupBeams):
            b.Name = set_up[i][0]
            b.Description = set_up[i][1]
            b.GantryAngle = str(set_up[i][2])
            b.Segments[0].DoseRate = set_up[i][3]
    # FFLDL
    elif patient_position == 'FeetFirstDecubitusLeft':
        standard_beam_name = 'Naming Error'
        for b in beamset.Beams:
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        input_technique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + input_technique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif 180 < gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif 270 < gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif 0 < gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif 90 < gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'

                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                logging.warning('Error occurred in setting names of beams')
                UserInterface.WarningBox(
                    'Error occurred in setting names of beams')
                sys.exit('Error occurred in setting names of beams')

        # Set-Up Fields
        # FFLDL Setup
        # set_up: [ Set-Up Field Name, Set-Up Field Description, Gantry Angle, Dose Rate]
        set_up = {
            0: ['SetUp RtLat', 'SetUp RtLat', 0.0, '5'],
            1: ['SetUp AP', 'SetUp AP', 270.0, '5'],
            2: ['SetUp PA', 'SetUp PA', 90.0, '5'],
            3: ['SetUp CBCT', 'SetUp CBCT', 0.0, '5']
        }
        # Extract the angles
        angles = []
        for k, v in set_up.iteritems():
            angles.append(v[2])
            print "v2={}".format(v[2])

        beamset.UpdateSetupBeams(ResetSetupBeams=True,
                                 SetupBeamsGantryAngles=angles)

        # Set the set-up parameter specifics
        for i, b in enumerate(beamset.PatientSetup.SetupBeams):
            b.Name = set_up[i][0]
            b.Description = set_up[i][1]
            b.GantryAngle = str(set_up[i][2])
            b.Segments[0].DoseRate = set_up[i][3]
    # FFP
    elif patient_position == 'FeetFirstProne':
        for b in beamset.Beams:
            standard_beam_name = 'Naming Error'
            try:
                gantry_angle = int(b.GantryAngle)
                couch_angle = int(b.CouchAngle)
                gantry_angle_string = str(int(gantry_angle))
                couch_angle_string = str(int(couch_angle))
                #
                # Determine if the type is an Arc or SMLC
                # Name arcs as #_Arc_<Site>_<Direction>_<Couch>
                if technique == 'DynamicArc':
                    arc_direction = b.ArcRotationDirection
                    if arc_direction == 'Clockwise':
                        arc_direction_string = 'CW'
                    else:
                        arc_direction_string = 'CCW'

                    # Based on convention for billing, e.g. "1 CCW VMAT -- IMRT"
                    # set the beam_description
                    beam_description = (str(beam_index + 1) + ' ' +
                                        arc_direction_string + ' ' +
                                        input_technique)
                    if couch_angle == 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc')
                    else:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_Arc' + '_c' +
                                              couch_angle_string.zfill(3))
                else:
                    # Based on convention for billing, e.g. "1 SnS PRDR MLC -- IMRT"
                    # set the beam_description
                    beam_description = str(beam_index +
                                           1) + ' ' + input_technique
                    if couch_angle != 0:
                        standard_beam_name = (str(beam_index + 1) + '_' +
                                              site_name + '_g' +
                                              gantry_angle_string.zfill(3) +
                                              'c' +
                                              couch_angle_string.zfill(3))
                    elif gantry_angle == 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_AP'
                    elif 180 < gantry_angle < 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RAO'
                    elif gantry_angle == 270:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RLAT'
                    elif 270 < gantry_angle < 360:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_RPO'
                    elif gantry_angle == 0:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_PA'
                    elif 0 < gantry_angle < 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LPO'
                    elif gantry_angle == 90:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LLAT'
                    elif 90 < gantry_angle < 180:
                        standard_beam_name = str(beam_index +
                                                 1) + '_' + site_name + '_LAO'
                # Set the beamset names and description according to the convention above
                b.Name = standard_beam_name
                b.Description = beam_description
                beam_index += 1
            except Exception:
                UserInterface.WarningBox(
                    'Error occurred in setting names of beams')
                sys.exit('Error occurred in setting names of beams')
        # FFP: Set-Up fields
        # set_up: [ Set-Up Field Name, Set-Up Field Description, Gantry Angle, Dose Rate]
        set_up = {
            0: ['SetUp PA', 'SetUp PA', 0, '5'],
            1: ['SetUp RtLat', 'SetUp RtLat', 270.0, '5'],
            2: ['SetUp LtLat', 'SetUp LtLat', 90.0, '5'],
            3: ['SetUp CBCT', 'SetUp CBCT', 0.0, '5']
        }
        # Extract the angles
        angles = []
        for k, v in set_up.iteritems():
            angles.append(v[2])
        beamset.UpdateSetupBeams(ResetSetupBeams=True,
                                 SetupBeamsGantryAngles=angles)

        for i, b in enumerate(beamset.PatientSetup.SetupBeams):
            b.Name = set_up[i][0]
            b.Description = set_up[i][1]
            b.GantryAngle = str(set_up[i][2])
            b.Segments[0].DoseRate = set_up[i][3]
    else:
        raise IOError(
            "Patient Orientation Unsupported.. Manual Beam Naming Required")
    # Get some user data
    status.next_step(text="Complete plan information - check the TPO for doses " +
                          "and ARIA for the treatment machine")
    # This dialog grabs the relevant parameters to generate the whole brain plan
    input_dialog = UserInterface.InputDialog(
        inputs={
            'input0_make_plan': 'Create the RayStation Plan',
            'input1_plan_name': 'Enter the Plan Name, typically Brai_3DC_R0A0',
            'input2_number_fractions': 'Enter the number of fractions',
            'input3_dose': 'Enter total dose in cGy',
            'input4_choose_machine': 'Choose Treatment Machine'
        },
        title='Whole Brain Plan Input',
        datatype={'input0_make_plan': 'check',
                  'input4_choose_machine': 'combo'
                  },
        initial={
            'input0_make_plan': ['Make Plan'],
            'input1_plan_name': 'Brai_3DC_R0A0',
        },
        options={'input0_make_plan': ['Make Plan'],
                 'input4_choose_machine': institution_inputs_machine_name,
                 },
        required=['input2_number_fractions',
                  'input3_dose',
                  'input4_choose_machine'])

    # Launch the dialog
    print input_dialog.show()

    # Parse the outputs
Esempio n. 6
0
def main():

    # Get current date, time and initialize variables
    now = datetime.datetime.now()
    name = ''
    mrn = ''
    size = []
    res = []
    path = ''
    pad = True
    status = None
    patient_db = None
    machine_db = None

    # If running from within RayStation, write to temp folder and import
    try:

        # Import RayStation packages
        import connect
        import UserInterface

        # Connect to RayStation DB
        logging.debug('Attempting to connect to RsyStation DB')
        machine_db = connect.get_current('MachineDB')
        patient_db = connect.get_current('PatientDB')

        # If an existing patient is loaded, warn the user before saving
        try:
            patient = connect.get_current('Patient')
            case = connect.get_current('Case')
            box = UserInterface.WarningeBox(
                'An existing patient is loaded, and will be saved and closed')
            patient.Save()

        except Exception:
            logging.info('No patient is loaded')

        # Start script status window
        status = UserInterface.ScriptStatus(steps=[
            'Enter Phantom Dimensions', 'Generate Temporary CT Files',
            'Import Files into RayStation', 'Set Imaging Equipment',
            'Create External Contour', 'Export CT (optional)'
        ],
                                            docstring=__doc__,
                                            help=__help__)
        status.next_step(
            text=
            'For this step, enter the desired phantom details in the displayed input box.'
        )

        # Display input dialog and retrieve phantom size
        inputs = UserInterface.InputDialog(inputs={
            'a':
            'Enter phantom name:',
            'b':
            'Enter phantom ID:',
            'c':
            'Enter number of voxels in IEC X,Z,Y:',
            'd':
            'Enter resolution in IEC X,Z,Y (mm):'
        },
                                           required=['a', 'b', 'c', 'd'],
                                           initial={
                                               'a':
                                               'Water Phantom',
                                               'b':
                                               '{0}{1:0>2}{2:0>2}'.format(
                                                   now.year, now.month,
                                                   now.day),
                                               'c':
                                               '600, 400, 600',
                                               'd':
                                               '1, 1, 1'
                                           })

        # Wait a second to make sure the script selector is displayed before the input dialog
        time.sleep(1)
        logging.debug('Displaying input dialog')
        response = inputs.show()

        # Check if dialog was closed
        if response == {}:
            logging.warning('Input dialog closed')
            status.finish(text='The input dialog was closed, script cancelled')

        else:
            logging.debug('Parsing inputs and generating temp folder')
            name = response['a'].strip()
            mrn = response['b'].strip()
            size = map(int, response['c'].split(','))
            res = map(int, response['d'].split(','))

            status.next_step(
                text=
                'Generating temporary CT files based on provided dimensions...'
            )
            path = tempfile.mkdtemp()
            logging.debug('Temporary folder generated at {}'.format(path))

    # Prompt for name, ID, image size and resolution (in mm), IEC [X,Z,Y]
    except (ImportError, OSError, SystemError):
        logging.info(
            'Likely running outside RayStation, prompting user to enter info via raw_input()'
        )
        name = raw_input('Enter phantom name: ').strip()
        mrn = raw_input('Enter phantom ID: ').strip()
        size = map(
            int,
            raw_input('Enter number of voxels in IEC X,Z,Y (600, 400, 600): ').
            split(','))
        res = map(
            int,
            raw_input('Enter mm resolution in IEC X,Z,Y (1, 1, 1): ').split(
                ','))
        path = raw_input('Enter path to write CT to: ').strip()
        if not os.path.exists(path):
            logging.debug(
                'Provided path does not exist, creating {}'.format(path))
            os.mkdir(path)

    # Only continue if inputs were provided
    if name != '' and mrn != '' and len(size) == 3 and len(res) == 3:

        # Start timer
        tic = time.time()

        # Pad X/Z dimensions by a voxel (will be air)
        if pad:
            logging.debug('Padding image in X/Z dimensions')
            size[0] += 2
            size[1] += 2

        # Create new dict, and add basic image attributes
        logging.debug('Initializing DICOM header')
        ds = pydicom.dataset.Dataset()
        ds.file_meta = pydicom.dataset.Dataset()
        ds.file_meta.TransferSyntaxUID = '1.2.840.10008.1.2'
        ds.file_meta.ImplementationClassUID = '1.2.40.0.13.1.1'
        ds.file_meta.ImplementationVersionName = 'dcm4che-2.0'
        ds.SpecificCharacterSet = 'ISO_IR 100'
        ds.file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.2'
        ds.Modality = 'CT'
        ds.SOPClassUID = ds.file_meta.MediaStorageSOPClassUID
        ds.is_little_endian = True
        ds.is_implicit_VR = True
        ds.RescaleIntercept = -1024
        ds.RescaleSlope = 1
        ds.InstanceCreationDate = '{0}{1:0>2}{2:0>2}'.format(
            now.year, now.month, now.day)
        ds.InstanceCreationTime = '{0:0>2}{1:0>2}{2:0>2}'.format(
            now.hour, now.minute, now.second)
        ds.StudyDate = '{0}{1:0>2}{2:0>2}'.format(now.year, now.month, now.day)
        ds.StudyTime = '{0:0>2}{1:0>2}{2:0>2}'.format(now.hour, now.minute,
                                                      now.second)
        ds.AcquisitionDate = '{0}{1:0>2}{2:0>2}'.format(
            now.year, now.month, now.day)
        ds.AcquisitionTime = '{0:0>2}{1:0>2}{2:0>2}'.format(
            now.hour, now.minute, now.second)
        ds.ImageType = 'ORIGINAL\PRIMARY\AXIAL'
        ds.Manufacturer = 'pydicom'
        ds.ManufacturerModelName = 'CreateReferenceCT'
        ds.SoftwareVersion = '1.0'
        ds.SeriesDescription = 'Uniform Phantom'
        ds.PatientName = name
        ds.PatientID = mrn
        ds.SliceThickness = res[2]
        ds.StudyInstanceUID = pydicom.uid.generate_uid()
        ds.SeriesInstanceUID = pydicom.uid.generate_uid()
        ds.FrameOfReferenceUID = pydicom.uid.generate_uid()
        ds.PatientPosition = 'HFS'
        ds.ImageOrientationPatient = [1, 0, 0, 0, 1, 0]
        ds.ImagePositionPatient = [
            -((size[0] - 0.5) * res[0]) / 2, -res[1] / 2,
            ((size[2] - 0.5) * res[2]) / 2
        ]
        ds.ImagesInAcquisition = size[2]
        ds.SamplesPerPixel = 1
        ds.PhotometricInterpretation = 'MONOCHROME2'
        ds.Rows = size[1]
        ds.Columns = size[0]
        ds.PixelSpacing = [res[0], res[1]]
        ds.BitsAllocated = 16
        ds.BitsStored = 16
        ds.HighBit = 15
        ds.PixelRepresentation = 0

        # Create image
        logging.debug('Initializing rectangular phantom image')
        if pad:
            img = numpy.zeros(shape=(size[1], size[0]), dtype=numpy.uint16)
            for i in range(1, size[1] - 1):
                for j in range(1, size[0] - 1):
                    img[i, j] = 1024

        else:
            img = numpy.ones(shape=(size[1], size[0]),
                             dtype=numpy.uint16) * 1024

        ds.PixelData = img.tostring()

        # Only display progress bar
        if isinstance(status, UserInterface.ScriptStatus):
            bar = UserInterface.ProgressBar(text='Writing CT files',
                                            steps=size[2])

        else:
            bar = None

        # Loop through CT Images
        for i in range(size[2]):

            # Generate unique IDs
            ds.file_meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid(
            )
            ds.SOPInstanceUID = ds.file_meta.MediaStorageSOPInstanceUID

            # Set position info for this image
            ds.SliceLocation = -((size[2] - 1) * res[2]) / 2 + i * res[2]
            ds.ImagePositionPatient[2] = -ds.SliceLocation
            ds.InstanceNumber = i + 1

            # Write CT image
            if isinstance(bar, UserInterface.ProgressBar):
                bar.update('Writing image ct_{0:0>3}.dcm'.format(i + 1))

            if path != '':
                logging.debug('Writing image {0}/ct_{1:0>3}.dcm'.format(
                    path, i + 1))
                ds.save_as(
                    os.path.normpath('{0}/ct_{1:0>3}.dcm'.format(path, i + 1)))

        if isinstance(bar, UserInterface.ProgressBar):
            bar.close()

        # If in RayStation, import DICOM files
        if isinstance(status,
                      UserInterface.ScriptStatus) and patient_db is not None:

            status.next_step(
                text='Importing the temporary CT into RayStation...')
            logging.debug(
                'Executing ImportPatientFromPath against {}'.format(path))
            patient_db.ImportPatientFromPath(Path=path,
                                             Patient={'Name': name},
                                             SeriesFilter={},
                                             ImportFilters=[])

            patient = connect.get_current('Patient')
            case = connect.get_current('Case')
            examination = connect.get_current('Examination')
            logging.info('Import successful, patient name: {}, MRN: {}'.format(
                patient.Name, patient.PatientID))

            # Set imaging equipment
            if machine_db is not None:
                try:
                    import clr
                    clr.AddReference('System.Collections')
                    import System.Collections.Generic
                    ct_dict = machine_db.GetCtImagingSystemsNameAndCommissionTime(
                    )
                    e = ct_dict.GetEnumerator()
                    e.MoveNext()
                    status.next_step(
                        'Setting imaging equipment to {}...'.format(
                            e.Current.Key))
                    logging.debug('Setting imaging equipment to {}'.format(
                        e.Current.Key))
                    examination.EquipmentInfo.SetImagingSystemReference(
                        ImagingSystemName=e.Current.Key)

                except Exception as error:
                    logging.warning(str(error))

            # Create external ROI
            status.next_step(text='Generating External Contour...')
            logging.debug('Executing PatientModel.CreateRoi for External')
            external = case.PatientModel.CreateRoi(Name='External',
                                                   Color='Blue',
                                                   Type='External',
                                                   TissueName='',
                                                   RbeCellTypeName=None,
                                                   RoiMaterial=None)

            logging.debug('Executing CreateExternalGeometry for External')
            external.CreateExternalGeometry(Examination=examination,
                                            ThresholdLevel=None)
            logging.debug('Saving patient')
            patient.Save()

            # Prompt user to export
            logging.debug('Displaying export question box')
            status.next_step(
                text=
                'At this step, you can choose to export the phantom CT and structure set. '
                + 'Answer Yes or No in the displayed message box.')
            answer = UserInterface.QuestionBox(
                'Do you wish to export the phantom to a folder?')
            if answer.yes:
                logging.debug(
                    'User chose Yes to export CT and structure set, now displaying folder browser'
                )
                common = UserInterface.CommonDialog()
                export = common.folder_browser('Select a folder to export to:')

                try:
                    status.update_text('Exporting CT and structure set...')
                    logging.debug(
                        'Executing ScriptableDicomExport to export to {}'.
                        format(export))
                    case.ScriptableDicomExport(
                        ExportFolderPath=export,
                        Examinations=[examination.Name],
                        RtStructureSetsForExaminations=[examination.Name],
                        DicomFilter='',
                        IgnorePreConditionWarnings=True)

                except Exception as error:
                    logging.warning(str(error))

            # Finish up
            logging.debug(
                'Cleanup started, deleting temporary folder {}'.format(path))
            shutil.rmtree(path, ignore_errors=True)
            status.finish(
                text=
                'Script execution successful. Note, the phantom material was not set to water.'
                +
                ' If you plan on running other QA scripts, you may want to do so.'
            )

        logging.debug(
            'CreateReferenceCT finished successfully in {:.3f} seconds'.format(
                time.time() - tic))

    else:
        logging.warning('Patient name, MRN, size, or resolution invalid')
Esempio n. 7
0
                if not found:
                    if m not in m_c:
                        m_c.append(m)
            if not m_c:
                logging.debug('All structures in protocol accounted for')
            else:
                mc_list = ',\n'.join(m_c)
                missing_message = 'Missing structures remain: ' + mc_list
                logging.warning(
                    'Missing contours from this order: {}'.format(m_c))

        status.next_step(text="Getting target doses from user.", num=2)
        target_dialog = UserInterface.InputDialog(
            inputs=target_inputs,
            title='Input Target Dose Levels',
            datatype=target_datatype,
            initial=target_initial,
            options=target_options,
            required=[])
        print
        target_dialog.show()

        # Process inputs
        # Make a dict with key = name from elementTree : [ Name from ROIs, Dose in Gy]
        nominal_dose = 0
        translation_map = {}
        # TODO Add a dict element that is just key and dose
        #  seems like the next two loops could be combined, but
        #  since dict cycling isn't ordered I don't know how to create
        #  a blank element space
        for k, v in target_dialog.values.iteritems():
 inputs = UserInterface.InputDialog(inputs={
     'a':
     'Select machines to create plans for:',
     'b':
     'Enter MU for each beam:',
     'c':
     'Enter leaf gaps (cm):',
     'd':
     'Enter leaf offsets (cm):',
     'e':
     'Enter DLG offset iterations (cm):',
     'j':
     'Dose grid resolution (mm):',
     'k':
     'Runtime options:',
     'l':
     'Mobius3D host name/IP address:',
     'm':
     'Mobius3D DICOM port:',
     'n':
     'Mobius3D DICOM AE title:',
     'o':
     'Time delay between DICOM exports (sec):'
 },
                                    datatype={
                                        'a': 'check',
                                        'k': 'check'
                                    },
                                    initial={
                                        'a': machine_list,
                                        'b': '100',
                                        'c': '0.5, 1.0, 1.5, 2.0',
                                        'd': '0, 0.25, 0.5',
                                        'e': '0.0, 0.1, 0.2, 0.3',
                                        'j': '1.0',
                                        'k':
                                        ['Calculate plan', 'Export plan'],
                                        'l': 'mobius.uwhealth.wisc.edu',
                                        'm': '104',
                                        'n': 'MOBIUS3D',
                                        'o': '60'
                                    },
                                    options={
                                        'a': machine_list,
                                        'k':
                                        ['Calculate plan', 'Export plan']
                                    },
                                    required=['a', 'b', 'c', 'd', 'e', 'j'])
    status.next_step(
        text='Fill in the runtime options and click OK to continue')
    inputs = UserInterface.InputDialog(
        inputs={
            'a': 'Select machines to create plans for:',
            'b': 'Enter MU for each beam:',
            'c': 'Enter SDDs to compute at (cm):',
            'd': 'Enter open field jaw sizes (cm):',
            'e': 'Enter EDW field jaw sizes (cm):',
            'f': 'Enter open field MLC sizes (cm):',
            'g': 'Runtime options:'
        },
        datatype={
            'a': 'check',
            'g': 'check'
        },
        initial={
            'a': machine_list,
            'b': '100',
            'c': '80, 90, 100, 110, 120',
            'd': '2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 35, 40',
            'e': '5, 10, 15, 20',
            'f': '2, 3, 4, 5, 6, 7, 8, 9, 10',
            'g': ['Calculate dose', 'Export dose']
        },
        options={
            'a': machine_list,
            'g': ['Calculate dose', 'Export dose']
        },
        required=['a', 'b', 'c'])

    # Parse responses
    status.next_step(text='Next, select a machine model to compute on. If left blank, the existing machine in the ' +
                          'DICOM RT Plan will be used. You can also choose whether or not to re-center each plan to ' +
                          'the CT origin (0,0,0). Note, if the selected machine is not compatible with a plan (due ' +
                          'to energy or MLC differences), the import will occur but calculation and export will be ' +
                          'skipped.')
    machines = machine_db.QueryCommissionedMachineInfo(Filter={})
    machine_list = []
    for i, m in enumerate(machines):
        if m['IsCommissioned']:
            machine_list.append(m['Name'])

    dialog = UserInterface.InputDialog(title='Select Import Overrides',
                                       inputs={'a': 'Select a machine model to re-calculate plans (leave blank to ' +
                                                    'use existing machine):',
                                               'b': 'Choose whether to re-center isocenter to (0,0,0):',
                                               'c': 'Enter the calculation resolution (mm):'},
                                       datatype={'a': 'combo', 'b': 'combo', 'c': 'text'},
                                       options={'a': machine_list, 'b': ['Yes', 'No']},
                                       initial={'b': 'No', 'c': '2'},
                                       required=['b', 'c'])
    inputs = dialog.show()
    if 'a' in inputs:
        machine = inputs['a']

    else:
        machine = ''

    res = float(inputs['c'])/10
    if inputs['b'] == 'Yes':
        center = True
Esempio n. 11
0
def main():
    """
    Function will take the optional input of the protocol file name
    :return:
    """
    filename = None
    status = UserInterface.ScriptStatus(steps=[
        'Finding correct protocol', 'Matching Structure List',
        'Getting target Doses', 'Adding Goals'
    ],
                                        docstring=__doc__,
                                        help=__help__)

    protocol_folder = r'../protocols'
    institution_folder = r'UW'
    path_protocols = os.path.join(os.path.dirname(__file__), protocol_folder,
                                  institution_folder)

    # Get current patient, case, exam, and plan
    try:
        patient = connect.get_current('Patient')
        case = connect.get_current('Case')
        exam = connect.get_current('Examination')
        plan = connect.get_current('Plan')
        patient.Save()

    except Exception:
        UserInterface.WarningBox(
            'This script requires a patient and plan to be loaded')
        sys.exit('This script requires a patient and plan to be loaded')

    tpo = UserInterface.TpoDialog()
    tpo.load_protocols(path_protocols)

    status.next_step(text="Determining correct treatment protocol" +
                     "based on treatment planning order.",
                     num=0)

    # Eventually we may want to conver
    if filename:
        logging.info("create_goals.py: protocol selected: {}".format(filename))
        root = tpo.protocols[tpo.protocols[filename]]
    else:
        # Find the protocol the user wants to use.
        input_dialog = UserInterface.InputDialog(
            inputs={'input1': 'Select Protocol'},
            title='Protocol Selection',
            datatype={'input1': 'combo'},
            initial={},
            options={'input1': list(tpo.protocols.keys())},
            required=['input1'])
        # Launch the dialog
        print input_dialog.show()
        # Link root to selected protocol ElementTree
        logging.info("create_goals.py: protocol selected: {}".format(
            input_dialog.values['input1']))
        order_list = []
        protocol = tpo.protocols[input_dialog.values['input1']]
        for o in protocol.findall('order/name'):
            order_list.append(o.text)

        if len(order_list) > 1:
            use_orders = True
            # Find the protocol the user wants to use.
            input_dialog = UserInterface.InputDialog(
                inputs={'input1': 'Select Order'},
                title='Order Selection',
                datatype={'input1': 'combo'},
                initial={},
                options={'input1': order_list},
                required=['input1'])
            # Launch the dialog
            print input_dialog.show()
            # Link root to selected protocol ElementTree
            logging.info("create_goals.py: order selected: {}".format(
                input_dialog.values['input1']))
            for o in protocol.findall('order'):
                if o.find('name').text == input_dialog.values['input1']:
                    order = o
                    logging.debug(
                        'Matching protocol ElementTag found for {}'.format(
                            input_dialog.values['input1']))
                    break
        else:
            order = None

    # Find RS targets
    plan_targets = []
    for r in case.PatientModel.RegionsOfInterest:
        if r.OrganData.OrganType == 'Target':
            plan_targets.append(r.Name)
Esempio n. 12
0
            if int(g.find('priority').text) % 2:
                if not any(r.Name == g_name
                           for r in case.PatientModel.RegionsOfInterest
                           ) and g_name not in missing_contours:
                    missing_contours.append(g_name)
    # Warn the user they are missing stuff
    if missing_contours:
        mc_list = ',\n'.join(missing_contours)
        missing_message = 'Missing structures, continue script or cancel \n' + mc_list
        status.next_step(text=missing_message, num=1)
        connect.await_user_input(missing_message)

    status.next_step(text="Getting target doses from user.", num=2)
    final_dialog = UserInterface.InputDialog(inputs=final_inputs,
                                             title='Input Clinical Goals',
                                             datatype=final_datatype,
                                             initial=final_initial,
                                             options=final_options,
                                             required=[])
    print final_dialog.show()

    # Process inputs
    # Make a dict with key = name from elementTree : [ Name from ROIs, Dose in Gy]
    protocol_match = {}
    nominal_name = ''
    nominal_dose = 0
    for k, v in final_dialog.values.iteritems():
        if len(v) > 0:
            i, p = k.split("_", 1)
            if 'name' in i:
                # Key name will be the protocol target name
                protocol_match[p] = v
Esempio n. 13
0
def select_objective_protocol(folder=None,
                              filename=None,
                              order_name=None,
                              protocol=None):
    """
    Function to select the location of the objectives to be loaded within the plan.

    This function can be used to load a raw objectiveset list from an xml file or
    can be used to search a protocol level xml file and load desired objectives.

    The locations of all the orders containing of objectives is identified and the
    element containing this order is returned. All the
    objectiveset elements are returned as well.

    :param filename: os joined protocol name, used to directly open a file
    :param folder: folder from os to search within and prompt user to select appropriate protocol
    :param order_name: the name of order level element from xml file
    :param protocol: ElementTree-Element of the objectiveset you want

    :return: et_list: elementtree list of elements with objectives and/or objectivesets

    Usage:
    USE CASE 1:
    ## User knows the file the order is housed in but wants to select the order
    # Prompt user to select an order out of a specific file (UWBrainCNS.xml) located in
    # ../protocols/UW
    protocol_folder = r'../protocols'
    institution_folder = r'UW'
    file = 'UWBrainCNS.xml'
    path_protocols = os.path.join(os.path.dirname(__file__), protocol_folder, institution_folder)
    objective_elements = Objectives.select_objective_protocol(filename=file, folder=path_protocols)

    USE CASE 2:
    ## User knows the exact order that needs to be loaded. Return only the selected order and
    ## any objectivesets in the protocol
    protocol_folder = r'../protocols'
    institution_folder = r'UW'
    file = 'UWBrainCNS.xml'
    order_name = 'GBM Brain 6000cGy in 30Fx [Single-Phase Stupp]'
    path_protocols = os.path.join(os.path.dirname(__file__),
                                  protocol_folder,
                                  institution_folder)
    objective_elements = Objectives.select_objective_protocol(filename=file,
                                                              folder=path_protocols,
                                                              order_name=order_name)
    USE CASE 3:
    ## User will select a default objectiveset from the standard objectives directory
    objective_elements = Objectives.select_objective_protocol()

    USE CASE 4:
    ## User supplies ordername and protocol element:
    objective_elements = Objectives.select_objective_protocol(order_name=order_name,
                                                              protocol=protocol)

    """
    protocol_folder = r'../protocols'
    institution_folder = r'UW'
    objectives_folder = r'objectives'

    # First search the file list to be searched depending on the supplied information
    # output a list of files that are to be scanned
    if filename:
        # User directly supplied the filename of the protocol or objectiveset
        path_objectives = folder
        file_list = [filename]
    elif folder and not filename:
        # User wants to select the protocol or objectiveset from a list of xml files
        path_objectives = os.path.join(os.path.dirname(__file__),
                                       protocol_folder, institution_folder)
        file_list = os.listdir(path_objectives)
    else:
        # If no information was supplied look in the objectives folder
        path_objectives = os.path.join(os.path.dirname(__file__),
                                       protocol_folder, institution_folder,
                                       objectives_folder)
        file_list = os.listdir(path_objectives)

    objective_sets = {}
    # Return variable. A list of ET Elements
    et_list = []
    if protocol is not None:
        # Search first for a top level objectiveset
        # Find the objectivesets:
        # These get loaded for protocols regardless of orders
        protocol_obj_set = protocol.findall('./objectiveset')
        for p in protocol_obj_set:
            et_list.append(p)
        orders = protocol.findall('./order')
        # Search the orders to find those with objectives and return the candidates
        # for the selectable objectives
        for o in orders:
            objectives = o.findall('./objectives')
            if objectives:
                n = o.find('name').text
                objective_sets[n] = o
            else:
                logging.debug('No objectives found in {}'.format(
                    o.find('name').text))
    else:
        for f in file_list:
            if f.endswith('.xml'):
                # Parse the xml file
                tree = xml.etree.ElementTree.parse(
                    os.path.join(path_objectives, f))
                # Search first for a top level objectiveset
                if tree.getroot().tag == 'objectiveset':
                    n = tree.find('name').text
                    if n in objective_sets:
                        # objective_sets[n].extend(tree.getroot())
                        logging.debug(
                            "Objective set {} already in list".format(n))
                    else:
                        objective_sets[n] = tree
                        et_list.append(tree)
                elif tree.getroot().tag == 'protocol':
                    # Find the objectivesets:
                    # These get loaded for protocols regardless of orders
                    protocol_obj_set = tree.findall('./objectiveset')
                    for p in protocol_obj_set:
                        et_list.append(p)
                    orders = tree.findall('./order')
                    # Search the orders to find those with objectives and return the candidates
                    # for the selectable objectives
                    for o in orders:
                        objectives = o.findall('./objectives')
                        if objectives:
                            n = o.find('name').text
                            objective_sets[n] = o
                        else:
                            logging.debug('No objectives found in {}'.format(
                                o.find('name').text))

    # Augment the list to include all xml files found with an "objectiveset" tag in name
    if order_name is not None:
        try:
            selected_order = objective_sets[order_name]
        except KeyError:
            # This order doesn't appear to match one that has objectives in it
            # Pass an empty entry
            logging.debug(
                'Order: {} has no objectives. Protocol objectives being used'.
                format(order_name))
            selected_order = None
    else:
        input_dialog = UserInterface.InputDialog(
            inputs={'i': 'Select Objective Set'},
            title='Objective Selection',
            datatype={'i': 'combo'},
            initial={},
            options={'i': list(objective_sets.keys())},
            required=['i'])
        response = input_dialog.show()
        # Close on cancel
        if response == {}:
            logging.info('create_objective cancelled by user')
            sys.exit('create_objective cancelled by user')
        else:
            logging.debug('User selected order: {} for objectives'.format(
                input_dialog.values['i']))
            selected_order = objective_sets[input_dialog.values['i']]
    # Add the order to the returned list
    if selected_order is not None:
        et_list.append(selected_order)

    if et_list is not None:
        for e in et_list:
            logging.info('Objective list to be loaded {}'.format(
                e.find('name').text))
    else:
        logging.warning('objective files were not found')

    return et_list
Esempio n. 14
0
def main():
    """
    Function will take the optional input of the protocol file name
    :return:
    """
    filename = None
    status = UserInterface.ScriptStatus(steps=[
        'Finding correct protocol', 'Matching Structure List',
        'Getting target Doses', 'Adding Goals', 'Adding Standard Objectives'
    ],
                                        docstring=__doc__,
                                        help=__help__)

    protocol_folder = r'../protocols'
    institution_folder = r'UW'
    path_protocols = os.path.join(os.path.dirname(__file__), protocol_folder,
                                  institution_folder)

    # Get current patient, case, exam, and plan
    patient = find_scope(level='Patient')
    case = find_scope(level='Case')
    exam = find_scope(level='Examination')
    plan = find_scope(level='Plan')
    beamset = find_scope(level='BeamSet')

    tpo = UserInterface.TpoDialog()
    tpo.load_protocols(path_protocols)

    status.next_step(text="Determining correct treatment protocol" +
                     "based on treatment planning order.",
                     num=0)

    # TODO: Set up a means of bypassing the dialogs
    #  Eventually we may want to convert to accepting a call from a filename
    #  Alternatively, this could all be set up as a function call
    if filename:
        logcrit("Protocol selected: {}".format(filename))
        root = tpo.protocols[tpo.protocols[filename]]
    else:
        # Find the protocol the user wants to use.
        input_dialog = UserInterface.InputDialog(
            inputs={'i': 'Select Protocol'},
            title='Protocol Selection',
            datatype={'i': 'combo'},
            initial={},
            options={'i': list(tpo.protocols.keys())},
            required=['i'])
        # Launch the dialog
        response = input_dialog.show()
        # Link root to selected protocol ElementTree
        logging.info("Protocol selected: {}".format(input_dialog.values['i']))
        # Store the protocol name and optional order name
        protocol_name = input_dialog.values['i']
        order_name = None
        order_list = []
        protocol = tpo.protocols[input_dialog.values['i']]
        for o in protocol.findall('order/name'):
            order_list.append(o.text)

        if len(order_list) >= 1:
            use_orders = True
            # Find the protocol the user wants to use.
            input_dialog = UserInterface.InputDialog(
                inputs={'i': 'Select Order'},
                title='Order Selection',
                datatype={'i': 'combo'},
                initial={'i': order_list[0]},
                options={'i': order_list},
                required=['i'])
            # Launch the dialog
            response = input_dialog.show()
            # Link root to selected protocol ElementTree
            logging.critical("Order selected: {}".format(
                input_dialog.values['i']))
            # Update the order name

            # I believe this loop can be eliminated with we can use a different function
            # to match protocol.find('order') with input_dialog.values['i']
            for o in protocol.findall('order'):
                if o.find('name').text == input_dialog.values['i']:
                    order = o
                    logging.debug(
                        'Matching protocol ElementTag found for {}'.format(
                            input_dialog.values['i']))
                    break
            order_name = input_dialog.values['i']

        else:
            logging.debug('No orders in protocol')
            use_orders = False

        # Match the list of structures found in the objective protocols and protocols

        # Find RS targets
        plan_targets = StructureOperations.find_targets(case=case)
        status.next_step(text="Matching all structures to the current list.",
                         num=1)

        protocol_targets = []
        missing_contours = []

        # Build second dialog
        target_inputs = {}
        target_initial = {}
        target_options = {}
        target_datatype = {}
        target_required = []
        i = 1
        # Lovely code, but had to break this loop up
        # for g, t in ((a, b) for a in root.findall('./goals/roi') for b in plan_targets):

        if use_orders:
            goal_locations = (protocol.findall('./goals/roi'),
                              order.findall('./goals/roi'))
        else:
            goal_locations = (protocol.findall('./goals/roi'))
        # Use the following loop to find the targets in protocol matching the names above
        for s in goal_locations:
            for g in s:
                g_name = g.find('name').text
                # Priorities should be even for targets and append unique elements only
                # into the protocol_targets list
                if int(g.find('priority').text
                       ) % 2 == 0 and g_name not in protocol_targets:
                    protocol_targets.append(g_name)
                    k = str(i)
                    # Python doesn't sort lists....
                    k_name = k.zfill(2) + 'Aname_' + g_name
                    k_dose = k.zfill(2) + 'Bdose_' + g_name
                    target_inputs[k_name] = 'Match a plan target to ' + g_name
                    target_options[k_name] = plan_targets
                    target_datatype[k_name] = 'combo'
                    target_required.append(k_name)
                    target_inputs[
                        k_dose] = 'Provide dose for protocol target: ' + g_name + ' Dose in cGy'
                    target_required.append(k_dose)
                    i += 1
                    # Exact matches get an initial guess in the dropdown
                    for t in plan_targets:
                        if g_name == t:
                            target_initial[k_name] = t

        # Warn the user they are missing organs at risk specified in the order
        rois = []  # List of contours in plan
        protocol_rois = [
        ]  # List of all the regions of interest specified in the protocol

        for r in case.PatientModel.RegionsOfInterest:
            # Maybe extend, can't remember
            rois.append(r.Name)
        for s in goal_locations:
            for g in s:
                g_name = g.find('name').text
                if g_name not in protocol_rois: protocol_rois.append(g_name)
                # Add a quick check if the contour exists in RS
                # This step is slow, we may want to gather all rois into a list and look for it
                if int(g.find('priority').text) % 2:
                    if not any(
                            r == g_name
                            for r in rois) and g_name not in missing_contours:
                        #       case.PatientModel.RegionsOfInterest) and g_name not in missing_contours:
                        missing_contours.append(g_name)

        # Launch the matching script here. Then check for any missing that remain. Supply function with rois and
        # protocol_rois

        if missing_contours:
            mc_list = ',\n'.join(missing_contours)
            missing_message = 'Missing structures, continue script or cancel \n' + mc_list
            status.next_step(text=missing_message, num=1)
            connect.await_user_input(missing_message)
            # Add a line here to check again for missing contours and write out the list
            for r in case.PatientModel.RegionsOfInterest:
                # Maybe extend, can't remember
                rois.append(r.Name)

            m_c = []
            found = False
            for m in missing_contours:
                # We don't want in, we need an exact match - for length too
                for r in rois:
                    found = False
                    if r == m:
                        found = True
                        break
                if not found:
                    if m not in m_c:
                        m_c.append(m)
            if not m_c:
                logging.debug('All structures in protocol accounted for')
            else:
                mc_list = ',\n'.join(m_c)
                missing_message = 'Missing structures remain: ' + mc_list
                logging.warning(
                    'Missing contours from this order: {}'.format(m_c))
Esempio n. 15
0
def main():
    # Get current patient, case, exam, plan, and beamset
    try:
        patient = connect.get_current('Patient')
        case = connect.get_current('Case')
        exam = connect.get_current('Examination')

    except Exception:
        UserInterface.WarningBox('This script requires a patient to be loaded')
        sys.exit('This script requires a patient to be loaded')

    try:
        plan = connect.get_current('Plan')
        beamset = connect.get_current('BeamSet')

    except Exception:
        logging.debug(
            'A plan and/or beamset is not loaded; plan export options will be disabled'
        )
        UserInterface.WarningBox(
            'This script requires a plan and beamset to be loaded')
        sys.exit('This script requires a plan and beamset to be loaded')

    # Find the correct verification plan for this beamset
    logging.debug(
        'Looking through verifications plans for plan {} and beamset {}'.
        format(plan.Name, beamset.DicomPlanLabel))

    verification_plans = plan.VerificationPlans
    qa_plan = None
    # TODO: Extend for multiple verification plans
    for vp in verification_plans:
        logging.debug('vp is {}'.format(vp.BeamSet.DicomPlanLabel))
        if vp.OfRadiationSet.DicomPlanLabel == beamset.DicomPlanLabel:
            qa_plan = vp
            break

    # indx = 0
    # index_not_found = True
    # try:
    #     for vbs in plan.VerificationPlans[str(indx)].ForTreatmentPlan.BeamSets:
    #         while index_not_found:
    #             vp_plan_name = plan.VerificationPlans[str(indx)].ForTreatmentPlan.Name
    #             vp_beamset_name = vbs.DicomPlanLabel
    #             logging.debug('Current verif plan is {} and beamset {}'.format(vp_plan_name,vp_beamset_name))
    #             if vp_beamset_name == beamset.DicomPlanLabel and vp_plan_name == plan.Name:
    #                 index_not_found = False
    #                 logging.debug('Verification index found {}'.format(indx))
    #                 break
    #             else:
    #                 indx += 1

    # except KeyError:
    #     logging.debug('All plans searched through indx = {}'.format(indx))
    #     index_not_found = True

    if qa_plan is None:
        logging.warning("verification plan for {} could not be found.".format(
            beamset.DicomPlanLabel))
        sys.exit("Could not find beamset optimization")

    # else:
    #     qa_plan = plan.VerificationPlans[indx]
    #     logging.info('verification plan found, exporting {} for beamset {}'.format(
    #         plan.VerificationPlans[indx].BeamSet.DicomPlanLabel, beamset.DicomPlanLabel))

    # Initialize options to include DICOM destination and data selection. Add more if a plan is also selected
    inputs = {
        'a': 'Enter the Gantry period as [ss.ff]:',
        'b': 'Check one or more DICOM destinations to export to:'
    }
    required = ['a', 'b']
    types = {'b': 'check'}
    options = {'b': DicomExport.destinations()}
    initial = {}

    dialog = UserInterface.InputDialog(inputs=inputs,
                                       datatype=types,
                                       options=options,
                                       initial=initial,
                                       required=required,
                                       title='Export Options')
    response = dialog.show()
    if response == {}:
        sys.exit('DICOM export was cancelled')
    # Link root to selected protocol ElementTree
    logging.info(
        "Gantry period filter to be used. Gantry Period (ss.ff) = {} ".format(
            response['a']))

    daughter_beamset = qa_plan.BeamSet
    # daughter_beamset.SetCurrent()
    # connect.get_current('BeamSet')
    success = DicomExport.send(case=case,
                               destination=response['b'],
                               qa_plan=qa_plan,
                               exam=False,
                               beamset=False,
                               ct=False,
                               structures=False,
                               plan=False,
                               plan_dose=False,
                               beam_dose=False,
                               ignore_warnings=False,
                               ignore_errors=False,
                               gantry_period=response['a'],
                               filters=['tomo_dqa'],
                               bar=False)

    # Finish up
    if success:
        logging.info('Export script completed successfully')

    else:
        logging.warning('Export script completed with errors')
Esempio n. 16
0
    status.next_step(text="Determining correct treatment protocol" +
                     "based on treatment planning order.",
                     num=0)

    # Eventually we may want to convert to accepting a call from a filename
    # Alternatively, this could all be set up as a function call
    # TODO: Set up a means of bypassing the dialogs
    if filename:
        logging.info("Protocol selected: {}".format(filename))
        root = tpo.protocols[tpo.protocols[filename]]
    else:
        # Find the protocol the user wants to use.
        input_dialog = UserInterface.InputDialog(
            inputs={'i': 'Select Protocol'},
            title='Protocol Selection',
            datatype={'i': 'combo'},
            initial={},
            options={'i': list(tpo.protocols.keys())},
            required=['i'])
        # Launch the dialog
        print input_dialog.show()
        # Link root to selected protocol ElementTree
        logging.info("Protocol selected: {}".format(input_dialog.values['i']))
        order_list = []
        protocol = tpo.protocols[input_dialog.values['i']]
        for o in protocol.findall('order/name'):
            order_list.append(o.text)

        if len(order_list) >= 1:
            use_orders = True
            # Find the protocol the user wants to use.
Esempio n. 17
0
 input_dialog = UserInterface.InputDialog(
     inputs={
         # 'input1_plan_name': 'Enter the Plan Name, typically DryRun',
         # 'input2_site': 'Select the Site',
         # 'input3_MMT': 'Motion Management Technique',
         'input4_choose_machine': 'Choose Treatment Machine',
         'input5_target': 'Select target for isocenter localization'
     },
     title='Dry Run Input',
     datatype={
         # 'input2_site': 'combo',
         # 'input3_MMT': 'combo',
         'input4_choose_machine': 'combo',
         'input5_target': 'combo'
     },
     initial={
         # 'input1_plan_name': 'DryRun',
     },
     options={
         # 'input2_site': institution_inputs_sites,
         # 'input3_MMT': institution_inputs_motion,
         'input4_choose_machine': institution_inputs_machine_name,
         'input5_target': plan_targets
     },
     required=[
         # 'input1_plan_name',
         # 'input2_site',
         # 'input3_MMT',
         'input4_choose_machine',
         'input5_target'
     ])
 optimization_dialog = UserInterface.InputDialog(
     title='Optimization Inputs',
     inputs={
         'input01_fluence_only': 'Fluence calculation only, for dialing in parameters ' +
                                 'all other values in this window will be ignored',
         'input02_cold_start': 'Reset beams (cold start)',
         'input03_cold_max_iteration': 'Maximum number of iterations for initial optimization',
         'input04_cold_interm_iteration': 'Intermediate iteration for svd to aperture conversion',
         'input05_ws_max_iteration': 'Maximum iteration used in warm starts ',
         'input06_ws_interm_iteration': 'Intermediate iteration used in warm starts',
         'input07_vary_dose_grid': 'Start with large grid, and decrease gradually',
         'input08_n_iterations': 'Number of Iterations',
         'input09_segment_weight': 'Segment weight calculation',
         'input10_reduce_oar': 'Reduce OAR Dose',
         # Small Target
         # 'input11_small_target': 'Target size < 3 cm'
     },
     datatype={
         'input07_vary_dose_grid': 'check',
         'input01_fluence_only': 'check',
         'input02_cold_start': 'check',
         'input09_segment_weight': 'check',
         'input10_reduce_oar': 'check',
         # 'input11_small_target': 'check'
     },
     initial={'input03_cold_max_iteration': '50',
              'input04_cold_interm_iteration': '10',
              'input05_ws_max_iteration': '35',
              'input06_ws_interm_iteration': '5',
              'input08_n_iterations': '4',
              'input09_segment_weight': ['Perform Segment Weighted optimization'],
              'input10_reduce_oar': ['Perform reduce OAR dose before completion'],
              # Small Target
              # 'input11_small_target': ['Target size < 3 cm - limit jaws']
              },
     options={
         'input01_fluence_only': ['Fluence calc'],
         'input02_cold_start': ['Reset Beams'],
         'input07_vary_dose_grid': ['Variable Dose Grid'],
         'input09_segment_weight': ['Perform Segment Weighted optimization'],
         'input10_reduce_oar': ['Perform reduce OAR dose before completion'],
         # Small Target
         # 'input11_small_target': ['Target size < 3 cm - limit jaws']
     },
     required=[])
Esempio n. 19
0
    datatype = {}
    options = {}
    initial = {}
    for k, v in matches.iteritems():
        inputs[k] = k
        datatype[k] = 'combo'
        options[k] = v
        for item in v:
            if item == k:
                initial[k] = item
                break

    matchy_dialog = UserInterface.InputDialog(
        inputs=inputs,
        title='Matchy Matchy',
        datatype=datatype,
        initial=initial,
        options=matches,
        required={})
    # Launch the dialog
    response = matchy_dialog.show()
    if response is not None:
        # Link root to selected protocol ElementTree
        for k, v in response.iteritems():
            logging.debug('Match key {k} and response {v}'.format(k=k, v=v))
        logging.info("Matches selected: {}".format(
            matchy_dialog))

        correct = 0

        m_logs = r'Q:\\RadOnc\RayStation\RayScripts\dev_logs'