def create_cornea(pm, examination, ss, source_roi, box_roi, roi,
                  subtraction_roi):
    if SSF.has_named_roi_with_contours(ss, source_roi.name):
        center_x = SSF.roi_center_x(ss, source_roi.name)
        center_z = SSF.roi_center_z(ss, source_roi.name)
        source_roi_box = ss.RoiGeometries[source_roi.name].GetBoundingBox()
        y_min = source_roi_box[1].y
        if y_min > 0:
            y_min = -source_roi_box[1].y
        delete_roi(pm, box_roi.name)
        box = pm.CreateRoi(Name=box_roi.name,
                           Color=box_roi.color,
                           Type=box_roi.type)
        pm.RegionsOfInterest[box_roi.name].CreateBoxGeometry(
            Size={
                'x': 5,
                'y': 5,
                'z': 4
            },
            Examination=examination,
            Center={
                'x': center_x,
                'y': y_min + 2.5,
                'z': center_z
            })
        exclude_roi_from_export(pm, box_roi.name)
        if source_roi.name == ROIS.lens_l.name:
            wall_roi = ROIS.z_eye_l
        elif source_roi.name == ROIS.lens_r.name:
            wall_roi = ROIS.z_eye_r
        delete_roi(pm, wall_roi.name)
        create_wall_roi(pm, examination, ss, wall_roi)
        exclude_roi_from_export(pm, wall_roi.name)
        if not SSF.is_approved_roi_structure(ss, roi.name):
            if is_approved_roi_structure_in_one_of_all_structure_sets(
                    pm, roi.name):
                intersection = ROI.ROIAlgebra(roi.name + "1",
                                              roi.type,
                                              roi.color,
                                              sourcesA=[source_roi],
                                              sourcesB=[box_roi],
                                              operator='Intersection')
                # In the rare case that this ROI already exists, delete it (to avoid a crash):
                delete_roi(pm, intersection.name)
                create_algebra_roi(pm, examination, ss, intersection)
                GUIF.handle_creation_of_new_roi_because_of_approved_structure_set(
                    intersection.name)
            else:
                subtraction = ROI.ROIAlgebra(subtraction_roi.name,
                                             subtraction_roi.type,
                                             subtraction_roi.color,
                                             sourcesA=[wall_roi],
                                             sourcesB=[box_roi],
                                             operator='Subtraction')
                # In the rare case that this ROI already exists, delete it (to avoid a crash):
                delete_roi(pm, subtraction.name)
                create_algebra_roi(pm, examination, ss, subtraction)
    else:
        GUIF.handle_missing_roi_for_derived_rois(subtraction_roi.name,
                                                 source_roi.name)
Exemplo n.º 2
0
 def __init__(self, pm, examination, ss, choices, site):
   site.add_oars(DEF.bladder_oars)
   ctv =  ROI.ROIAlgebra(ROIS.ctv.name, ROIS.ctv.type, COLORS.ctv_low, sourcesA=[ROIS.gtv], sourcesB=[ROIS.bladder])
   ptv = ROI.ROIAlgebra(ROIS.ptv.name, ROIS.ptv.type, ROIS.ptv.color, sourcesA = [ctv], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.bladder_expansion, marginsB = MARGINS.uniform_5mm_contraction)
   site.add_targets([ROIS.gtv, ctv, ptv])
   # Create all targets and OARs in RayStation:
   site.create_rois()
Exemplo n.º 3
0
def create_bottom_part_x_cm(pm, examination, ss, source_roi, roi, distance):
    if SSF.has_named_roi_with_contours(ss, source_roi.name):
        center_x = SSF.roi_center_x(ss, source_roi.name)
        center_y = SSF.roi_center_y(ss, source_roi.name)
        center_z = SSF.roi_center_z(ss, source_roi.name)
        source_roi_box = ss.RoiGeometries[source_roi.name].GetBoundingBox()
        x_min = source_roi_box[0].x
        x_max = source_roi_box[1].x
        x = source_roi_box[1].x - source_roi_box[0].x
        y_min = source_roi_box[0].y
        y_max = source_roi_box[1].y
        y = source_roi_box[1].y - source_roi_box[0].y
        z_min = source_roi_box[0].z

        z = source_roi_box[1].z - source_roi_box[0].z
        z_cutoff = z_min + distance / 2
        delete_roi(pm, ROIS.box.name)
        box = pm.CreateRoi(Name=ROIS.box.name,
                           Color=ROIS.box.color,
                           Type=ROIS.box.type)
        pm.RegionsOfInterest[ROIS.box.name].CreateBoxGeometry(
            Size={
                'x': x,
                'y': y,
                'z': distance
            },
            Examination=examination,
            Center={
                'x': center_x,
                'y': center_y,
                'z': z_cutoff
            })
        if not SSF.is_approved_roi_structure(ss, roi.name):
            if is_approved_roi_structure_in_one_of_all_structure_sets(
                    pm, roi.name):
                intersection = ROI.ROIAlgebra(roi.name + "1",
                                              roi.type,
                                              roi.color,
                                              sourcesA=[source_roi],
                                              sourcesB=[ROIS.box],
                                              operator='Intersection')
                # In the rare case that this ROI already exists, delete it (to avoid a crash):
                delete_roi(pm, intersection.name)
                create_algebra_roi(pm, examination, ss, intersection)
                GUIF.handle_creation_of_new_roi_because_of_approved_structure_set(
                    intersection.name)
            else:
                intersection = ROI.ROIAlgebra(roi.name,
                                              roi.type,
                                              roi.color,
                                              sourcesA=[source_roi],
                                              sourcesB=[ROIS.box],
                                              operator='Intersection')
                # In the rare case that this ROI already exists, delete it (to avoid a crash):
                delete_roi(pm, intersection.name)
                create_algebra_roi(pm, examination, ss, intersection)
        delete_roi(pm, ROIS.box.name)
    else:
        GUIF.handle_missing_roi_for_derived_rois(roi.name, source_roi.name)
Exemplo n.º 4
0
def create_posterior_half_fast(pm, examination, ss, source_roi, roi):
    center_x = SSF.roi_center_x(ss, source_roi.name)
    center_y = SSF.roi_center_y(ss, source_roi.name)
    center_z = SSF.roi_center_z(ss, source_roi.name)
    source_roi_box = ss.RoiGeometries[source_roi.name].GetBoundingBox()
    x_min = source_roi_box[0].x
    x_max = source_roi_box[1].x
    x = source_roi_box[1].x - source_roi_box[0].x
    boxes = []
    boxes2 = []
    for [contour_index, contour] in enumerate(
            ss.RoiGeometries[source_roi.name].PrimaryShape.Contours):
        y_min = 9999
        y_max = -9999
        for coordinate in contour:
            if coordinate.y > y_max:
                y_max = coordinate.y
            elif coordinate.y < y_min:
                y_min = coordinate.y
        length = round((abs(y_max - y_min)), 1)
        center_y = y_max
        delete_roi(pm, ROIS.box.name + str(contour_index))
        box = pm.CreateRoi(Name=ROIS.box.name + str(contour_index),
                           Color=ROIS.box.color,
                           Type=ROIS.box.type)
        i = 0
        for i in range(0, contour_index):
            if i % 3 == 0:
                pm.RegionsOfInterest[ROIS.box.name +
                                     str(contour_index)].CreateBoxGeometry(
                                         Size={
                                             'x': x,
                                             'y': length,
                                             'z': 0.3
                                         },
                                         Examination=examination,
                                         Center={
                                             'x': center_x,
                                             'y': center_y,
                                             'z': coordinate.z
                                         })

        boxes.append(box)
        boxes2.append(
            ROI.ROI(ROIS.box.name + str(contour_index), ROIS.box.type,
                    ROIS.box.color))

    subtraction = ROI.ROIAlgebra(roi.name,
                                 roi.type,
                                 roi.color,
                                 sourcesA=[source_roi],
                                 sourcesB=boxes2,
                                 operator='Intersection')
    # In the rare case that this ROI already exists, delete it (to avoid a crash):
    delete_roi(pm, subtraction.name)
    create_algebra_roi(pm, examination, ss, subtraction)
    for i in range(0, len(boxes)):
        delete_roi(pm, boxes[i].Name)
Exemplo n.º 5
0
def create_grey_value_intersection_roi(pm, examination, ss, grey_level_roi,
                                       source_roi, intersection_roi,
                                       low_threshold, high_threshold):
    # If the grey level threshold ROI already exists, delete it and re-create an empty ROI:
    delete_roi(pm, grey_level_roi.name)
    pm.CreateRoi(Name=grey_level_roi.name,
                 Type=grey_level_roi.type,
                 Color=grey_level_roi.color)
    ss.RoiGeometries[grey_level_roi.name].OfRoi.GrayLevelThreshold(
        Examination=examination,
        LowThreshold=low_threshold,
        HighThreshold=high_threshold)
    # Create the intersection ROI:
    if not SSF.is_approved_roi_structure(ss, intersection_roi.name):
        if is_approved_roi_structure_in_one_of_all_structure_sets(
                pm, intersection_roi.name):
            intersection = ROI.ROIAlgebra(intersection_roi.name + "1",
                                          intersection_roi.type,
                                          intersection_roi.color,
                                          sourcesA=[source_roi],
                                          sourcesB=[grey_level_roi],
                                          operator='Intersection')
            create_algebra_roi(pm, examination, ss, intersection)
        else:
            delete_roi(pm, intersection_roi.name)
            intersection = ROI.ROIAlgebra(intersection_roi.name,
                                          intersection_roi.type,
                                          intersection_roi.color,
                                          sourcesA=[source_roi],
                                          sourcesB=[grey_level_roi],
                                          operator='Intersection')
            create_algebra_roi(pm, examination, ss, intersection)
    # Clean up: Delete the threshold ROI which was created:
    if ss.RoiGeometries[grey_level_roi.name]:
        delete_roi(pm, grey_level_roi.name)
    # In case of failure (no volume or volume < 0.1 cm^3), delete the intersection ROI:
    if ss.RoiGeometries[intersection_roi.name].HasContours():
        if ss.RoiGeometries[intersection_roi.name].GetRoiVolume() < 0.1:
            delete_roi(pm, intersection_roi.name)
    else:
        delete_roi(pm, intersection_roi.name)
Exemplo n.º 6
0
def roi_overlap(pm, examination, ss, roi1, roi2, threshold):
    subtraction = ROI.ROIAlgebra(roi1.name + '-' + roi2.name,
                                 'Undefined',
                                 'Black',
                                 sourcesA=[roi1],
                                 sourcesB=[roi2],
                                 operator='Subtraction')
    # In the rare case that this ROI already exists, delete it (to avoid a crash):
    PMF.delete_roi(pm, subtraction.name)
    PMF.create_algebra_roi(pm, examination, ss, subtraction)
    # Is overlapping volume less than threshold?
    overlap = False
    if ss.RoiGeometries[roi1.name].GetRoiVolume() - ss.RoiGeometries[
            subtraction.name].GetRoiVolume() > threshold:
        overlap = True
    PMF.delete_roi(pm, subtraction.name)
    return overlap
def create_roi_subtraction(pm, examination, ss, roi1, roi2, subtraction_name,
                           threshold):
    overlap = False
    if has_named_roi_with_contours(
            ss, roi1.name) and has_named_roi_with_contours(ss, roi2.name):
        subtraction = ROI.ROIAlgebra(subtraction_name,
                                     'Undefined',
                                     'Black',
                                     sourcesA=[roi1],
                                     sourcesB=[roi2],
                                     operator='Subtraction')
        # In the rare case that this ROI already exists, delete it (to avoid a crash):
        PMF.delete_roi(pm, subtraction.name)
        PMF.create_algebra_roi(pm, examination, ss, subtraction)
        # Is overlapping volume less than threshold?
        if has_named_roi_with_contours(ss, subtraction.name):
            if ss.RoiGeometries[roi1.name].GetRoiVolume() - ss.RoiGeometries[
                    subtraction.name].GetRoiVolume() > threshold:
                overlap = True
    else:
        GUIF.handle_missing_roi_for_derived_rois(subtraction_name, roi2.name)
    return overlap
def create_expanded_and_intersected_volume(pm, examination, ss, source_roi,
                                           intersect_roi, expanded_roi_name,
                                           threshold_volume):
    # Volume of source roi
    volume1 = ss.RoiGeometries[source_roi.name].GetRoiVolume()
    # Estimated radius of source roi calculated from volume (assuming perfect sphere)
    radius1 = math.pow((volume1 * 3) / (4 * math.pi), 1.0 / 3.0)
    # Estimated radius of expanded roi calculated from thresgold volume (assuming perfect sphere)
    radius2 = math.pow((threshold_volume * 3) / (4 * math.pi), 1.0 / 3.0)
    # Expansion radius
    r = round(radius2 - radius1, 1)
    # Expanded roi object
    expanded_roi = ROI.ROIAlgebra(expanded_roi_name,
                                  'Undefined',
                                  'Black',
                                  sourcesA=[source_roi],
                                  sourcesB=[intersect_roi],
                                  operator='Intersection',
                                  marginsA=MARGIN.Expansion(r, r, r, r, r, r),
                                  marginsB=MARGINS.zero)
    # Deletes roi if it already exists in RayStation
    PMF.delete_roi(pm, expanded_roi.name)
    # Create ROI in RayStation
    PMF.create_algebra_roi(pm, examination, ss, expanded_roi)
Exemplo n.º 9
0
    def __init__(self, pm, examination, ss, choices, site):
        # Choice 1: Local/Regional/Regional with IMN
        region = choices[1]
        # Choice 2: Side - Left or right?
        side = choices[2]

        if region == 'part':
            site.add_oars(DEF.breast_part_oars)
            if side == 'right':
                site.add_oars([ROIS.breast_r_draft])
                breast_r = ROI.ROIAlgebra(
                    ROIS.breast_r.name,
                    ROIS.breast_r.type,
                    ROIS.breast_r.color,
                    sourcesA=[ROIS.breast_r_draft],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.zero,
                    marginsB=MARGINS.uniform_5mm_contraction)
                ctv_sb = ROI.ROIAlgebra(
                    ROIS.ctv_sb.name,
                    ROIS.ctv.type,
                    ROIS.ctv.color,
                    sourcesA=[ROIS.surgical_bed],
                    sourcesB=[breast_r],
                    operator='Intersection',
                    marginsA=MARGINS.uniform_15mm_expansion,
                    marginsB=MARGINS.zero)
                ptv_sbc = ROI.ROIAlgebra(
                    ROIS.ptv_sbc.name,
                    ROIS.ptv.type,
                    ROIS.ptv.color,
                    sourcesA=[ctv_sb],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.uniform_5mm_expansion,
                    marginsB=MARGINS.uniform_5mm_contraction)
                site.add_oars([breast_r, ctv_sb, ptv_sbc])
            else:
                site.add_oars([ROIS.breast_l_draft])
                breast_l = ROI.ROIAlgebra(
                    ROIS.breast_l.name,
                    ROIS.breast_l.type,
                    ROIS.breast_l.color,
                    sourcesA=[ROIS.breast_l_draft],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.zero,
                    marginsB=MARGINS.uniform_5mm_contraction)
                ctv_sb = ROI.ROIAlgebra(
                    ROIS.ctv_sb.name,
                    ROIS.ctv.type,
                    ROIS.ctv.color,
                    sourcesA=[ROIS.surgical_bed],
                    sourcesB=[breast_l],
                    operator='Intersection',
                    marginsA=MARGINS.uniform_15mm_expansion,
                    marginsB=MARGINS.zero)
                ptv_sbc = ROI.ROIAlgebra(
                    ROIS.ptv_sbc.name,
                    ROIS.ptv.type,
                    ROIS.ptv.color,
                    sourcesA=[ctv_sb],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.uniform_5mm_expansion,
                    marginsB=MARGINS.uniform_5mm_contraction)
                site.add_oars([breast_l, ctv_sb, ptv_sbc])
        elif region == 'tang':
            # Breast with tangential fields
            site.add_oars(DEF.breast_tang_oars)
            if side == 'right':
                site.add_oars([ROIS.breast_r_draft])
                ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                                     ROIS.ctv.type,
                                     ROIS.ctv.color,
                                     sourcesA=[ROIS.breast_r_draft],
                                     sourcesB=[ROIS.external],
                                     operator='Intersection',
                                     marginsA=MARGINS.zero,
                                     marginsB=MARGINS.uniform_5mm_contraction)
            else:
                site.add_oars([ROIS.breast_l_draft])
                ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                                     ROIS.ctv.type,
                                     ROIS.ctv.color,
                                     sourcesA=[ROIS.breast_l_draft],
                                     sourcesB=[ROIS.external],
                                     operator='Intersection',
                                     marginsA=MARGINS.zero,
                                     marginsB=MARGINS.uniform_5mm_contraction)
            ptv = ROI.ROIAlgebra(ROIS.ptv_c.name,
                                 ROIS.ptv.type,
                                 ROIS.ptv.color,
                                 sourcesA=[ctv],
                                 sourcesB=[ROIS.external],
                                 operator='Intersection',
                                 marginsA=MARGINS.uniform_5mm_expansion,
                                 marginsB=MARGINS.uniform_5mm_contraction)
            site.add_targets([ctv, ptv])
            # Choice 2: With our without boost?
            boost = choices[3]
        elif region in ['reg', 'imn']:
            # Breast where regional lymph nodes or IMN is included
            # Choice 3: Hypofractionation or not
            frac = choices[3]
            # Choice 4: With our without boost?
            boost = choices[4]
            site.add_oars(DEF.breast_reg_oars)
            # Hypofractionated
            if frac == 'hypo':
                if side == 'right':
                    ctv_p = ROI.ROIAlgebra(
                        ROIS.ctv_p.name,
                        ROIS.ctv_p.type,
                        ROIS.ctv.color,
                        sourcesA=[ROIS.breast_r_draft],
                        sourcesB=[ROIS.external],
                        operator='Intersection',
                        marginsA=MARGINS.zero,
                        marginsB=MARGINS.uniform_5mm_contraction)
                    ctv_n = ROI.ROIAlgebra(ROIS.ctv_n.name,
                                           ROIS.ctv_n.type,
                                           ROIS.ctv.color,
                                           sourcesA=[
                                               ROIS.level_r, ROIS.level1_r,
                                               ROIS.level2_r, ROIS.level3_r,
                                               ROIS.level4_r
                                           ],
                                           sourcesB=[ctv_p],
                                           operator='Subtraction',
                                           marginsA=MARGINS.zero,
                                           marginsB=MARGINS.zero)
                    site.add_oars([
                        ROIS.breast_r_draft, ROIS.humeral_r, ROIS.breast_l,
                        ROIS.level_r, ROIS.level1_r, ROIS.level2_r,
                        ROIS.level3_r, ROIS.level4_r, ROIS.artery1_r,
                        ROIS.artery2_r, ROIS.vein1_r, ROIS.vein2_r
                    ])
                else:  # (left)
                    ctv_p = ROI.ROIAlgebra(
                        ROIS.ctv_p.name,
                        ROIS.ctv_p.type,
                        ROIS.ctv.color,
                        sourcesA=[ROIS.breast_l_draft],
                        sourcesB=[ROIS.external],
                        operator='Intersection',
                        marginsA=MARGINS.zero,
                        marginsB=MARGINS.uniform_5mm_contraction)
                    ctv_n = ROI.ROIAlgebra(ROIS.ctv_n.name,
                                           ROIS.ctv_n.type,
                                           ROIS.ctv.color,
                                           sourcesA=[
                                               ROIS.level_l, ROIS.level1_l,
                                               ROIS.level2_l, ROIS.level3_l,
                                               ROIS.level4_l
                                           ],
                                           sourcesB=[ctv_p],
                                           operator='Subtraction',
                                           marginsA=MARGINS.zero,
                                           marginsB=MARGINS.zero)
                    site.add_oars([
                        ROIS.breast_l_draft, ROIS.humeral_l, ROIS.breast_r,
                        ROIS.level_l, ROIS.level1_l, ROIS.level2_l,
                        ROIS.level3_l, ROIS.level4_l, ROIS.artery1_l,
                        ROIS.artery2_l, ROIS.vein1_l, ROIS.vein2_l
                    ])
                # Common for left and right:
                ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                                     ROIS.ctv.type,
                                     ROIS.ctv.color,
                                     sourcesA=[ctv_n],
                                     sourcesB=[ctv_p],
                                     operator='Union',
                                     marginsA=MARGINS.zero,
                                     marginsB=MARGINS.zero)
                ptv_p = ROI.ROIAlgebra(
                    ROIS.ptv_pc.name,
                    ROIS.ptv_pc.type,
                    ROIS.ptv.color,
                    sourcesA=[ctv_p],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.uniform_5mm_expansion,
                    marginsB=MARGINS.uniform_5mm_contraction)
                ptv_n = ROI.ROIAlgebra(
                    ROIS.ptv_nc.name,
                    ROIS.ptv_nc.type,
                    ROIS.ptv.color,
                    sourcesA=[ctv_n],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.uniform_5mm_expansion,
                    marginsB=MARGINS.uniform_5mm_contraction)
                ptv = ROI.ROIAlgebra(ROIS.ptv_c.name,
                                     ROIS.ptv.type,
                                     ROIS.ptv.color,
                                     sourcesA=[ptv_n],
                                     sourcesB=[ptv_p],
                                     operator='Union',
                                     marginsA=MARGINS.zero,
                                     marginsB=MARGINS.zero)
            else:
                if side == 'right':
                    ctv = ROI.ROIAlgebra(
                        ROIS.ctv_50.name,
                        ROIS.ctv_50.type,
                        ROIS.ctv.color,
                        sourcesA=[ROIS.breast_r_draft],
                        sourcesB=[ROIS.external],
                        operator='Intersection',
                        marginsA=MARGINS.zero,
                        marginsB=MARGINS.uniform_5mm_contraction)
                    ctv_47 = ROI.ROIAlgebra(
                        ROIS.ctv_47.name,
                        ROIS.ctv_50.type,
                        ROIS.ctv.color,
                        sourcesA=[
                            ROIS.level_r, ROIS.level1_r, ROIS.level2_r,
                            ROIS.level3_r, ROIS.level4_r
                        ],
                        sourcesB=[ctv],
                        operator='Subtraction',
                        marginsA=MARGINS.zero,
                        marginsB=MARGINS.uniform_5mm_expansion)
                    site.add_oars([
                        ROIS.breast_r_draft, ROIS.humeral_r, ROIS.breast_l,
                        ROIS.level_r, ROIS.level1_r, ROIS.level2_r,
                        ROIS.level3_r, ROIS.level4_r, ROIS.artery1_r,
                        ROIS.artery2_r, ROIS.vein1_r, ROIS.vein2_r
                    ])
                else:  # (left)
                    ctv = ROI.ROIAlgebra(
                        ROIS.ctv_50.name,
                        ROIS.ctv_50.type,
                        ROIS.ctv.color,
                        sourcesA=[ROIS.breast_l_draft],
                        sourcesB=[ROIS.external],
                        operator='Intersection',
                        marginsA=MARGINS.zero,
                        marginsB=MARGINS.uniform_5mm_contraction)
                    ctv_47 = ROI.ROIAlgebra(
                        ROIS.ctv_47.name,
                        ROIS.ctv_47.type,
                        ROIS.ctv.color,
                        sourcesA=[
                            ROIS.level_l, ROIS.level1_l, ROIS.level2_l,
                            ROIS.level3_l, ROIS.level4_l
                        ],
                        sourcesB=[ctv],
                        operator='Subtraction',
                        marginsA=MARGINS.zero,
                        marginsB=MARGINS.uniform_5mm_expansion)
                    site.add_oars([
                        ROIS.breast_l_draft, ROIS.humeral_l, ROIS.breast_r,
                        ROIS.level_l, ROIS.level1_l, ROIS.level2_l,
                        ROIS.level3_l, ROIS.level4_l, ROIS.artery1_l,
                        ROIS.artery2_l, ROIS.vein1_l, ROIS.vein2_l
                    ])
                # Common for left and right:
                ctv_47_50 = ROI.ROIAlgebra(ROIS.ctv_47_50.name,
                                           ROIS.ctv_47_50.type,
                                           ROIS.ctv.color,
                                           sourcesA=[ctv_47],
                                           sourcesB=[ctv],
                                           operator='Union',
                                           marginsA=MARGINS.zero,
                                           marginsB=MARGINS.zero)
                ptv_50c = ROI.ROIAlgebra(
                    ROIS.ptv_50c.name,
                    ROIS.ptv_50.type,
                    ROIS.ptv.color,
                    sourcesA=[ctv],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.uniform_5mm_expansion,
                    marginsB=MARGINS.uniform_5mm_contraction)
                ptv_47 = ROI.ROIAlgebra(ROIS.ptv_47.name,
                                        ROIS.ptv_47.type,
                                        ROIS.ptv.color,
                                        sourcesA=[ctv_47],
                                        sourcesB=[ptv_50c],
                                        operator='Subtraction',
                                        marginsA=MARGINS.uniform_5mm_expansion,
                                        marginsB=MARGINS.zero)
                ptv_47c = ROI.ROIAlgebra(
                    ROIS.ptv_47c.name,
                    ROIS.ptv_47.type,
                    ROIS.ptv.color,
                    sourcesA=[ptv_47],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.zero,
                    marginsB=MARGINS.uniform_5mm_contraction)
                ptv = ROI.ROIAlgebra(ROIS.ptv_c.name,
                                     ROIS.ptv.type,
                                     ROIS.ptv.color,
                                     sourcesA=[ptv_47c],
                                     sourcesB=[ptv_50c],
                                     operator='Union',
                                     marginsA=MARGINS.zero,
                                     marginsB=MARGINS.zero)
                # Only if IMN is included in target volume:
            if region == 'imn':
                site.add_oars([ROIS.imn])
                if frac == 'hypo':
                    ctv_n.sourcesA.extend([ROIS.imn])
                else:
                    ctv_47.sourcesA.extend([ROIS.imn])
            # Common for all regional:
            if frac == 'hypo':
                site.add_targets([ctv_p, ctv_n, ctv, ptv_p, ptv_n, ptv])
            else:
                site.add_targets(
                    [ctv, ctv_47, ctv_47_50, ptv_50c, ptv_47, ptv_47c, ptv])
        # Add volumes for boost (2Gy x 8) if selected:
        if not region == 'part':
            if boost == 'with':
                if side == 'right':
                    ctv_sb = ROI.ROIAlgebra(
                        ROIS.ctv_sb.name,
                        ROIS.ctv.type,
                        ROIS.ctv.color,
                        sourcesA=[ROIS.surgical_bed],
                        sourcesB=[ctv],
                        operator='Intersection',
                        marginsA=MARGINS.uniform_5mm_expansion,
                        marginsB=MARGINS.zero)
                else:
                    ctv_sb = ROI.ROIAlgebra(
                        ROIS.ctv_sb.name,
                        ROIS.ctv.type,
                        ROIS.ctv.color,
                        sourcesA=[ROIS.surgical_bed],
                        sourcesB=[ctv],
                        operator='Intersection',
                        marginsA=MARGINS.uniform_5mm_expansion,
                        marginsB=MARGINS.zero)
                ptv_sbc = ROI.ROIAlgebra(
                    ROIS.ptv_sbc.name,
                    ROIS.ptv_sb.type,
                    ROIS.ptv.color,
                    sourcesA=[ctv_sb],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.uniform_5mm_expansion,
                    marginsB=MARGINS.uniform_5mm_contraction)
                site.add_targets([ROIS.surgical_bed, ctv_sb, ptv_sbc])
        # Create all targets and OARs in RayStation:
        site.create_rois()
Exemplo n.º 10
0
 def __init__(self, pm, examination, ss, choices, site):
   # Choice 1: Stereotactic or not?
   stereotactic = choices[1]
   # Choice 2: Region
   region = choices[2]
   # Stereotactic:
   if stereotactic == 'yes':
     if region in ['col thorax', 'col pelvis']:
       if region == 'col thorax':
         site.add_oars(DEF.palliative_stereotactic_thorax_oars)
       elif region == 'col pelvis':
         site.add_oars(DEF.palliative_stereotactic_spine_pelvis_oars)
       ctv = ROI.ROIExpanded(ROIS.ctv.name, ROIS.ctv.type, COLORS.ctv_med, ROIS.gtv, margins = MARGINS.uniform_3mm_expansion)
       ptv = ROI.ROIAlgebra(ROIS.ptv.name, ROIS.ptv.type, ROIS.ptv.color, sourcesA=[ctv], sourcesB=[ROIS.vb])
       ptv_gtv = ROI.ROIAlgebra(ROIS.ptv_gtv.name, ROIS.ptv_gtv.type, COLORS.ptv_med, sourcesA = [ptv], sourcesB = [ROIS.gtv], operator='Subtraction')
       ptv_spinal = ROI.ROIAlgebra(ROIS.ptv_spinal.name, ROIS.ptv_spinal.type, COLORS.ptv_med, sourcesA = [ptv], sourcesB = [ROIS.spinal_cord_prv], operator='Subtraction', marginsA = MARGINS.zero, marginsB = MARGINS.uniform_1mm_expansion)
       wall_ptv = ROI.ROIWall(ROIS.wall_ptv.name, ROIS.wall_ptv.type, COLORS.wall, ptv, 1, 0)
       site.add_oars([ROIS.spinal_cord_prv, wall_ptv])
       site.add_targets([ROIS.gtv, ROIS.vb, ptv_gtv, ptv_spinal, ctv, ptv])
     else:
       site.add_oars(DEF.palliative_stereotactic_pelvis_oars)
       ptv = ROI.ROIExpanded(ROIS.ptv.name, ROIS.ptv.type, ROIS.ptv.color, ROIS.gtv, margins = MARGINS.uniform_3mm_expansion)
       wall_ptv = ROI.ROIWall(ROIS.wall_ptv.name, ROIS.wall_ptv.type, COLORS.wall, ptv, 1, 0)
       site.add_oars([wall_ptv])
       site.add_targets([ROIS.gtv, ptv])
   # Not stereotactic:
   else:
     # Region:
     if region == 'head':
       site.add_oars(DEF.palliative_head_oars)
     elif region == 'neck':
       site.add_oars(DEF.palliative_neck_oars)
     elif region == 'thorax':
       site.add_oars(DEF.palliative_thorax_oars)
     elif region == 'thorax_abdomen':
       site.add_oars(DEF.palliative_thorax_abdomen_oars)
     elif region == 'abdomen':
       site.add_oars(DEF.palliative_abdomen_oars)
     elif region == 'abdomen_pelvis':
       site.add_oars(DEF.palliative_abdomen_pelvis_oars)
     elif region == 'pelvis':
       site.add_oars(DEF.palliative_pelvis_oars)
     # Choice 3: Number of targets:
     nr_targets = choices[3]
     # Choice 4: GTV included?
     with_gtv = choices[4]
     # Nr of target volumes:
     if nr_targets == '1':
       if with_gtv == 'with':
         site.add_targets([ROIS.gtv, ROIS.ctv_ext])
       else:
         site.add_targets([ROIS.ctv_underived])
         if region == 'other':
           ROIS.ptv_ext.sourcesA = [ROIS.ctv_underived]
           site.add_targets([ROIS.ptv_ext_7])
         else:
           ROIS.ptv_ext.sourcesA = [ROIS.ctv_underived]
           site.add_targets([ROIS.ptv_ext])
     # 2 or 3 targets:
     else:
       # With GTV:
       if with_gtv=='with':
         ctv1 = ROI.ROIAlgebra(ROIS.ctv1.name, ROIS.ctv1.type, ROIS.ctv.color, sourcesA = [ROIS.gtv1], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
         ctv2 = ROI.ROIAlgebra(ROIS.ctv2.name, ROIS.ctv2.type, ROIS.ctv.color, sourcesA = [ROIS.gtv2], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
         ptv1 = ROI.ROIAlgebra(ROIS.ptv1.name, ROIS.ptv1.type, ROIS.ptv.color, sourcesA = [ROIS.ctv1], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
         ptv2 = ROI.ROIAlgebra(ROIS.ptv2.name, ROIS.ptv2.type, ROIS.ptv.color, sourcesA = [ROIS.ctv2], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
         gtv =  ROI.ROIAlgebra(ROIS.gtv.name, ROIS.gtv.type, ROIS.gtv.color, sourcesA=[ROIS.gtv1], sourcesB=[ROIS.gtv2])
         ctv =  ROI.ROIAlgebra(ROIS.ctv.name, ROIS.ctv.type, ROIS.ctv.color, sourcesA=[ctv1], sourcesB=[ctv2])
         ptv =  ROI.ROIAlgebra(ROIS.ptv.name, ROIS.ptv.type, ROIS.ptv.color, sourcesA=[ptv1], sourcesB=[ptv2])
         site.add_targets([ROIS.gtv1, ROIS.gtv2, gtv, ctv1, ctv2, ctv, ptv1, ptv2, ptv])
         if nr_targets == '3':
           ctv3 = ROI.ROIAlgebra(ROIS.ctv3.name, ROIS.ctv3.type, ROIS.ctv.color, sourcesA = [ROIS.gtv3], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
           ptv3 = ROI.ROIAlgebra(ROIS.ptv3.name, ROIS.ptv3.type, ROIS.ptv.color, sourcesA = [ROIS.ctv3], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
           gtv.sourcesB.extend([ROIS.gtv3])
           ctv.sourcesB.extend([ctv3])
           ptv.sourcesB.extend([ptv3])
           site.add_targets([ROIS.gtv3, ctv3, ptv3])
       # Without GTV:
       else:
         if region == 'other':
           ptv1 = ROI.ROIAlgebra(ROIS.ptv1.name, ROIS.ptv1.type, ROIS.ptv.color, sourcesA = [ROIS.ctv1], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_7mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
           ptv2 = ROI.ROIAlgebra(ROIS.ptv2.name, ROIS.ptv2.type, ROIS.ptv.color, sourcesA = [ROIS.ctv2], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_7mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
         else:
           ptv1 = ROI.ROIAlgebra(ROIS.ptv1.name, ROIS.ptv1.type, ROIS.ptv.color, sourcesA = [ROIS.ctv1], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
           ptv2 = ROI.ROIAlgebra(ROIS.ptv2.name, ROIS.ptv2.type, ROIS.ptv.color, sourcesA = [ROIS.ctv2], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
         ctv =  ROI.ROIAlgebra(ROIS.ctv.name, ROIS.ctv.type, ROIS.ctv.color, sourcesA=[ROIS.ctv1], sourcesB=[ROIS.ctv2])
         ptv =  ROI.ROIAlgebra(ROIS.ptv.name, ROIS.ptv.type, ROIS.ptv.color, sourcesA=[ptv1], sourcesB=[ptv2])
         site.add_targets([ROIS.ctv1, ROIS.ctv2, ctv, ptv1, ptv2, ptv])
         if nr_targets == '3':
           if region == 'other':
             ptv3 = ROI.ROIAlgebra(ROIS.ptv3.name, ROIS.ptv3.type, ROIS.ptv.color, sourcesA = [ROIS.ctv3], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.uniform_7mm_contraction)
           else:
             ptv3 = ROI.ROIAlgebra(ROIS.ptv3.name, ROIS.ptv3.type, ROIS.ptv.color, sourcesA = [ROIS.ctv3], sourcesB = [ROIS.external], operator = 'Intersection', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.uniform_5mm_contraction)
           ctv.sourcesB.extend([ROIS.ctv3])
           ptv.sourcesB.extend([ptv3])
           site.add_targets([ROIS.ctv3, ptv3])
   # Create all targets and OARs in RayStation:
   site.create_rois()
Exemplo n.º 11
0
 def __init__(self, pm, examination, ss, choices, site):
     # Choice 1: Stereotactic or not?
     stereotactic = choices[1]
     # Choice 2: Region
     region = choices[2]
     if stereotactic == 'yes':
         # Stereotactic:
         if region in ['col thorax', 'col pelvis']:
             # Targets:
             ctv = ROI.ROIExpanded(ROIS.ctv.name,
                                   ROIS.ctv.type,
                                   COLORS.ctv_med,
                                   ROIS.gtv,
                                   margins=MARGINS.uniform_3mm_expansion)
             ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ctv],
                                  sourcesB=[ROIS.vb])
             ptv_gtv = ROI.ROIAlgebra(ROIS.ptv_gtv.name,
                                      ROIS.ptv_gtv.type,
                                      COLORS.ptv_med,
                                      sourcesA=[ptv],
                                      sourcesB=[ROIS.gtv],
                                      operator='Subtraction')
             ptv_spinal = ROI.ROIAlgebra(
                 ROIS.ptv_spinal.name,
                 ROIS.ptv_spinal.type,
                 COLORS.ptv_med,
                 sourcesA=[ptv],
                 sourcesB=[ROIS.spinal_cord_prv],
                 operator='Subtraction',
                 marginsA=MARGINS.zero,
                 marginsB=MARGINS.uniform_1mm_expansion)
             site.add_targets(
                 [ROIS.gtv, ROIS.vb, ptv_gtv, ptv_spinal, ctv, ptv])
             # OARs:
             if region == 'col thorax':
                 site.add_oars(DEF.palliative_stereotactic_thorax_oars)
             elif region == 'col pelvis':
                 site.add_oars(
                     DEF.palliative_stereotactic_spine_pelvis_oars)
             wall_ptv = ROI.ROIWall(ROIS.wall_ptv.name, ROIS.wall_ptv.type,
                                    COLORS.wall, ptv, 1, 0)
             site.add_oars([ROIS.spinal_cord_prv, wall_ptv])
         else:
             # Non-columna SBRT (assumed pelvis):
             # Targets:
             ptv = ROI.ROIExpanded(ROIS.ptv.name,
                                   ROIS.ptv.type,
                                   ROIS.ptv.color,
                                   ROIS.gtv,
                                   margins=MARGINS.uniform_3mm_expansion)
             site.add_targets([ROIS.gtv, ptv])
             # OARs:
             wall_ptv = ROI.ROIWall(ROIS.wall_ptv.name, ROIS.wall_ptv.type,
                                    COLORS.wall, ptv, 1, 0)
             site.add_oars(DEF.palliative_stereotactic_pelvis_oars +
                           [wall_ptv])
     else:
         # Non-stereotactic:
         # Region:
         if region == 'head':
             site.add_oars(DEF.palliative_head_oars)
         elif region == 'neck':
             site.add_oars(DEF.palliative_neck_oars)
         elif region == 'thorax':
             site.add_oars(DEF.palliative_thorax_oars)
         elif region == 'costa':
             site.add_oars(DEF.palliative_thorax_abdomen_oars)
         elif region == 'thorax_abdomen':
             site.add_oars(DEF.palliative_thorax_abdomen_oars)
         elif region == 'abdomen':
             site.add_oars(DEF.palliative_abdomen_oars)
         elif region == 'abdomen_pelvis':
             site.add_oars(DEF.palliative_abdomen_pelvis_oars)
         elif region == 'pelvis':
             site.add_oars(DEF.palliative_pelvis_oars)
         # Choice 3: Number of targets:
         nr_targets = int(choices[3])
         # Choice 4: GTV included?
         with_gtv = choices[4]
         # Determine PTV margins:
         if with_gtv == 'with':
             # Soft tissue target:
             if region in ['head']:
                 # Head: 3 mm
                 ptv_margin = MARGINS.uniform_3mm_expansion
             elif region in ['neck']:
                 # Neck: 3 mm (mask) or 5 mm (no mask)
                 # Choice 5: Mask?
                 mask = choices[5]
                 if mask == 'mask':
                     ptv_margin = MARGINS.uniform_3mm_expansion
                 else:
                     ptv_margin = MARGINS.uniform_5mm_expansion
             elif region in ['thorax_abdomen']:
                 # Near lung (affected by breathing motion):
                 ptv_margin = MARGINS.abdomen_near_lung_soft_tissue_expansion
             else:
                 # All others: 7 mm
                 ptv_margin = MARGINS.uniform_7mm_expansion
         else:
             # Bone target:
             if region in ['head']:
                 # Head: 3 mm
                 ptv_margin = MARGINS.uniform_3mm_expansion
             elif region in ['neck']:
                 # Neck: 3 mm (mask) or 5 mm (no mask)
                 # Choice 5: Mask?
                 mask = choices[5]
                 if mask == 'mask':
                     ptv_margin = MARGINS.uniform_3mm_expansion
                 else:
                     ptv_margin = MARGINS.uniform_5mm_expansion
             elif region in ['costa', 'other']:
                 # Costa/Extremities: 7 mm
                 ptv_margin = MARGINS.uniform_7mm_expansion
             else:
                 # Other torso: 5 mm
                 ptv_margin = MARGINS.uniform_5mm_expansion
         # Set up target volumes:
         if nr_targets == 1:
             # A single target:
             if with_gtv == 'with':
                 site.add_targets([ROIS.gtv, ROIS.ctv_ext])
             else:
                 site.add_targets([ROIS.ctv_underived])
             site.add_targets([
                 ROI.ROIAlgebra(ROIS.ptv.name,
                                ROIS.ptv.type,
                                ROIS.ptv.color,
                                sourcesA=[ROIS.ctv],
                                sourcesB=[ROIS.external],
                                operator='Intersection',
                                marginsA=ptv_margin,
                                marginsB=MARGINS.uniform_5mm_contraction)
             ])
         else:
             # Multiple targets (2 or 3):
             gtvs = []
             ctvs = []
             ptvs = []
             if with_gtv == 'with':
                 # With GTV:
                 for i in range(0, nr_targets):
                     gtvs.append(
                         ROI.ROI('GTV' + str(i + 1), 'Gtv', COLORS.gtv))
                     ctvs.append(
                         ROI.ROIAlgebra(
                             ROIS.ctv.name + str(i + 1),
                             ROIS.ctv1.type,
                             ROIS.ctv.color,
                             sourcesA=[gtvs[-1]],
                             sourcesB=[ROIS.external],
                             operator='Intersection',
                             marginsA=ptv_margin,
                             marginsB=MARGINS.uniform_5mm_contraction))
                     ptvs.append(
                         ROI.ROIAlgebra(
                             ROIS.ptv.name + str(i + 1),
                             ROIS.ptv1.type,
                             ROIS.ptv.color,
                             sourcesA=[ctvs[-1]],
                             sourcesB=[ROIS.external],
                             operator='Intersection',
                             marginsA=ptv_margin,
                             marginsB=MARGINS.uniform_5mm_contraction))
                 # GTV union target volume:
                 gtvs.append(
                     ROI.ROIAlgebra(ROIS.gtv.name,
                                    ROIS.gtv.type,
                                    ROIS.gtv.color,
                                    sourcesA=[gtvs[0]],
                                    sourcesB=gtvs[1:]))
                 site.add_targets(gtvs)
             else:
                 # Without GTV:
                 for i in range(0, nr_targets):
                     ctvs.append(
                         ROI.ROI('CTV' + str(i + 1), 'Ctv', COLORS.ctv))
                     ptvs.append(
                         ROI.ROIAlgebra(
                             ROIS.ptv.name + str(i + 1),
                             ROIS.ptv.type,
                             ROIS.ptv.color,
                             sourcesA=[ctvs[-1]],
                             sourcesB=[ROIS.external],
                             operator='Intersection',
                             marginsA=ptv_margin,
                             marginsB=MARGINS.uniform_5mm_contraction))
             # Union target volumes:
             ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                                  ROIS.ctv.type,
                                  ROIS.ctv.color,
                                  sourcesA=[ctvs[0]],
                                  sourcesB=ctvs[1:])
             ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ptvs[0]],
                                  sourcesB=ptvs[1:])
             ctvs.append(ctv)
             ptvs.append(ptv)
             site.add_targets(ctvs + ptvs)
     # Create all targets and OARs in RayStation:
     site.create_rois()
Exemplo n.º 12
0
def create_brain_objectives(pm, examination, ss, plan, total_dose,
                            nr_fractions):
    if nr_fractions in [1, 3]:  # Stereotactic brain
        nr_targets = SSF.determine_nr_of_indexed_ptvs(ss)
        for i in range(0, nr_targets):
            OF.max_eud(ss,
                       plan,
                       ROIS.brain_ptv.name,
                       0.08 * total_dose * 100,
                       1.3,
                       1,
                       beam_set_index=i)
            OF.max_eud(ss,
                       plan,
                       ROIS.brain_ptv.name,
                       0.06 * total_dose * 100,
                       1,
                       1,
                       beam_set_index=i)
            OF.fall_off(ss,
                        plan,
                        ROIS.body.name,
                        total_dose * 100,
                        total_dose * 100 / 2,
                        0.8,
                        25,
                        beam_set_index=i)
        if nr_targets == 1:  # one target
            OF.min_dose(ss,
                        plan,
                        ROIS.ptv.name,
                        total_dose * 100,
                        200,
                        beam_set_index=0)
            OF.fall_off(ss,
                        plan,
                        ROIS.z_ptv_wall.name,
                        total_dose * 100,
                        0.7 * total_dose * 100,
                        0.6,
                        25,
                        beam_set_index=0)
        else:
            for i in range(0, nr_targets):
                OF.min_dose(ss,
                            plan,
                            ROIS.ptv.name + str(i + 1),
                            total_dose * 100,
                            200,
                            beam_set_index=i)
                OF.fall_off(ss,
                            plan,
                            "zPTV" + str(i + 1) + "_Wall",
                            total_dose * 100,
                            0.7 * total_dose * 100,
                            0.6,
                            25,
                            beam_set_index=i)
    else:  # Partial brain
        OF.max_dose(ss, plan, ROIS.ptv.name, total_dose * 100 * 1.05, 80)
        OF.fall_off(ss, plan, ROIS.external.name, total_dose * 100,
                    total_dose * 100 / 2, 1.5, 30)
        OF.max_dose(ss, plan, ROIS.external.name, total_dose * 100 * 1.05, 30)
        # Objectives for prioritized OARs:
        OF.max_dose(
            ss, plan, ROIS.brainstem_surface.name,
            (TOL.brainstem_surface_v003_adx.equivalent(nr_fractions) * 100) -
            50, 60)
        OF.max_dose(
            ss, plan, ROIS.brainstem_core.name,
            (TOL.brainstem_core_v003_adx.equivalent(nr_fractions) * 100) - 50,
            80)
        OF.max_dose(
            ss, plan, ROIS.optic_chiasm.name,
            (TOL.optic_chiasm_v003_adx.equivalent(nr_fractions) * 100) - 50,
            40)
        OF.max_dose(ss, plan, ROIS.optic_nrv_l.name,
                    (TOL.optic_nrv_v003_adx.equivalent(nr_fractions) * 100) -
                    50, 20)
        OF.max_dose(ss, plan, ROIS.optic_nrv_r.name,
                    (TOL.optic_nrv_v003_adx.equivalent(nr_fractions) * 100) -
                    50, 20)

        prioritized_oars = [
            ROIS.brainstem_core, ROIS.brainstem_surface, ROIS.optic_chiasm,
            ROIS.optic_nrv_l, ROIS.optic_nrv_r
        ]
        tolerances = [
            TOL.brainstem_core_v003_adx, TOL.brainstem_surface_v003_adx,
            TOL.optic_chiasm_v003_adx, TOL.optic_nrv_v003_adx,
            TOL.optic_nrv_v003_adx
        ]
        conflict_oars = []
        for i in range(len(prioritized_oars)):
            if tolerances[i].equivalent(nr_fractions) < total_dose * 0.95:
                conflict_oars.append(prioritized_oars[i])
        # Setup of min and uniform doses depends on presence of critical overlaps or not:
        if len(conflict_oars) > 0:
            # Create subtraction and intersect ROIs for planning of conflicting sites:
            ctv_oars = ROI.ROIAlgebra(ROIS.ctv_oars.name,
                                      ROIS.ctv_oars.type,
                                      ROIS.ctv.color,
                                      sourcesA=[ROIS.ctv],
                                      sourcesB=conflict_oars,
                                      operator='Subtraction',
                                      marginsA=MARGINS.zero,
                                      marginsB=MARGINS.uniform_2mm_expansion)
            ptv_oars = ROI.ROIAlgebra(ROIS.ptv_oars.name,
                                      ROIS.ptv_oars.type,
                                      ROIS.ptv.color,
                                      sourcesA=[ROIS.ptv],
                                      sourcesB=conflict_oars,
                                      operator='Subtraction',
                                      marginsA=MARGINS.zero,
                                      marginsB=MARGINS.uniform_2mm_expansion)
            ptv_and_oars = ROI.ROIAlgebra(ROIS.ptv_and_oars.name,
                                          ROIS.ptv_and_oars.type,
                                          ROIS.other_ptv.color,
                                          sourcesA=[ROIS.ptv],
                                          sourcesB=conflict_oars,
                                          operator='Intersection')
            rois = [ctv_oars, ptv_oars, ptv_and_oars]
            PMF.delete_matching_rois(pm, rois)
            for i in range(len(rois)):
                PMF.create_algebra_roi(pm, examination, ss, rois[i])
                PMF.exclude_roi_from_export(pm, rois[i].name)
            # Create objectives for the subtraction/intersect ROIs:
            OF.uniform_dose(
                ss, plan, ROIS.ptv_and_oars.name,
                (tolerances[0].equivalent(nr_fractions) * 100 - 50), 5
            )  # (Note that this assumes our OARs have the same tolerance dose...)
            OF.uniform_dose(ss, plan, ROIS.ctv_oars.name, total_dose * 100, 30)
            OF.min_dose(ss, plan, ROIS.ptv_oars.name, total_dose * 100 * 0.95,
                        150)
        else:
            OF.uniform_dose(ss, plan, ROIS.ctv.name, total_dose * 100, 30)
            OF.min_dose(ss, plan, ROIS.ptv.name, total_dose * 100 * 0.95, 150)
        # Setup of objectives for less prioritized OARs:
        other_oars = [
            ROIS.cochlea_l, ROIS.cochlea_r, ROIS.hippocampus_l,
            ROIS.hippocampus_r, ROIS.lens_l, ROIS.lens_r, ROIS.lacrimal_l,
            ROIS.lacrimal_r, ROIS.retina_l, ROIS.retina_r, ROIS.cornea_r,
            ROIS.cornea_l, ROIS.pituitary
        ]
        tolerances = [
            TOL.cochlea_mean_tinnitus, TOL.cochlea_mean_tinnitus,
            TOL.hippocampus_v40, TOL.hippocampus_v40, TOL.lens_v003_adx,
            TOL.lens_v003_adx, TOL.lacrimal_mean, TOL.lacrimal_mean,
            TOL.retina_v003_adx, TOL.retina_v003_adx, TOL.cornea_v003_adx,
            TOL.cornea_v003_adx, TOL.pituitary_mean
        ]
        for i in range(len(other_oars)):
            if SSF.has_named_roi_with_contours(ss, other_oars[i].name):
                weight = None
                # Conflict with dose?
                if tolerances[i].equivalent(nr_fractions) < total_dose * 0.95:
                    # Conflict with dose:
                    if not SSF.roi_overlap(pm, examination, ss, ROIS.ptv,
                                           other_oars[i], 2):
                        if ROIF.roi_vicinity_approximate(
                                SSF.rg(ss, ROIS.ptv.name),
                                SSF.rg(ss, other_oars[i].name), 2):
                            # OAR is close, but not overlapping:
                            weight = 2
                        else:
                            weight = 20
                else:
                    # No conflict with dose:
                    weight = 20
                # Create objective if indicated:
                if weight:
                    if other_oars[i].name in [
                            ROIS.cochlea_r.name, ROIS.cochlea_l.name,
                            ROIS.lacrimal_l.name, ROIS.lacrimal_r.name,
                            ROIS.hippocampus_l.name, ROIS.hippocampus_r.name
                    ]:
                        OF.max_eud(
                            ss, plan, other_oars[i].name,
                            tolerances[i].equivalent(nr_fractions) * 100 - 50,
                            1, weight)
                    else:
                        OF.max_dose(
                            ss, plan, other_oars[i].name,
                            (tolerances[i].equivalent(nr_fractions) * 100) -
                            50, weight)
            else:
                GUIF.handle_missing_roi_for_objective(other_oars[i].name)
Exemplo n.º 13
0
    def __init__(self, pm, examination, ss, choices, site):
        site.add_oars(DEF.lung_oars)
        # Choice 1: Intent (curative or palliative)
        intent = choices[1]
        # Curative:
        if intent == 'curative':
            # Choice 2: Diagnosis
            diagnosis = choices[2]
            # Non small cell lung cancer (with 4DCT) or small cell lung cancer (with 4DCT):
            if diagnosis == '4dct':
                igtv = ROI.ROIAlgebra(ROIS.igtv.name,
                                      ROIS.igtv.type,
                                      ROIS.gtv.color,
                                      sourcesA=[ROIS.igtv_p],
                                      sourcesB=[ROIS.igtv_n])
                ictv_p = ROI.ROIExpanded(
                    ROIS.ictv_p.name,
                    ROIS.ictv_p.type,
                    COLORS.ctv_high,
                    source=ROIS.igtv_p,
                    margins=MARGINS.uniform_10mm_expansion)
                ictv_n = ROI.ROIExpanded(ROIS.ictv_n.name,
                                         ROIS.ictv_n.type,
                                         COLORS.ctv_high,
                                         source=ROIS.igtv_n,
                                         margins=MARGINS.uniform_5mm_expansion)
                ictv = ROI.ROIAlgebra(ROIS.ictv.name,
                                      ROIS.ictv.type,
                                      ROIS.ctv.color,
                                      sourcesA=[ictv_p, ictv_n],
                                      sourcesB=[ROIS.external],
                                      operator='Intersection',
                                      marginsA=MARGINS.zero,
                                      marginsB=MARGINS.uniform_5mm_contraction)
                ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                     ROIS.ptv.type,
                                     COLORS.ptv_high,
                                     sourcesA=[ictv],
                                     sourcesB=[ROIS.external],
                                     operator='Intersection',
                                     marginsA=MARGINS.uniform_5mm_expansion,
                                     marginsB=MARGINS.uniform_5mm_contraction)
                lungs_igtv = ROI.ROIAlgebra(ROIS.lungs_igtv.name,
                                            ROIS.lungs_igtv.type,
                                            COLORS.lungs,
                                            sourcesA=[ROIS.lungs],
                                            sourcesB=[igtv],
                                            operator='Subtraction')
                water = ROI.ROIAlgebra(ROIS.z_water.name,
                                       ROIS.z_water.type,
                                       COLORS.other_ptv,
                                       sourcesA=[ROIS.lungs, ptv],
                                       sourcesB=[igtv],
                                       operator='Subtraction',
                                       operatorA='Intersection')
                site.add_targets([
                    ROIS.igtv_p, ROIS.igtv_n, igtv, ictv_p, ictv_n, ictv, ptv
                ])
                site.add_oars([lungs_igtv, water])
            # Small cell lung cancer (without 4DCT):
            elif diagnosis == 'sclc':
                ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                                     ROIS.ctv.type,
                                     ROIS.ctv.color,
                                     sourcesA=[ROIS.ctv_p, ROIS.ctv_n],
                                     sourcesB=[ROIS.external],
                                     operator='Intersection',
                                     marginsA=MARGINS.zero,
                                     marginsB=MARGINS.uniform_5mm_contraction)
                ptv_p = ROI.ROIAlgebra(
                    ROIS.ptv_p.name,
                    ROIS.ptv.type,
                    ROIS.ptv.color,
                    sourcesA=[ROIS.ctv_p],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.lung_sclc_without_4dct,
                    marginsB=MARGINS.uniform_5mm_contraction)
                ptv_n = ROI.ROIAlgebra(
                    ROIS.ptv_n.name,
                    ROIS.ptv.type,
                    ROIS.ptv.color,
                    sourcesA=[ROIS.ctv_n],
                    sourcesB=[ROIS.external],
                    operator='Intersection',
                    marginsA=MARGINS.uniform_10mm_expansion,
                    marginsB=MARGINS.uniform_5mm_contraction)
                ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                     ROIS.ptv.type,
                                     ROIS.ptv.color,
                                     sourcesA=[ptv_p],
                                     sourcesB=[ptv_n])
                water = ROI.ROIAlgebra(ROIS.z_water.name,
                                       ROIS.z_water.type,
                                       COLORS.other_ptv,
                                       sourcesA=[ROIS.lungs, ptv],
                                       sourcesB=[ctv],
                                       operator='Subtraction',
                                       operatorA='Intersection')
                site.add_oars([water])
                site.add_targets(
                    [ROIS.ctv_p, ROIS.ctv_n, ctv, ptv_p, ptv_n, ptv])
            # Pancoast tumor (with 4DCT):
            elif diagnosis == 'pancoast':
                igtv = ROI.ROI(ROIS.igtv.name, ROIS.igtv.type, COLORS.gtv)
                ictv = ROI.ROIAlgebra(ROIS.ictv.name,
                                      ROIS.ictv.type,
                                      ROIS.ctv.color,
                                      sourcesA=[igtv],
                                      sourcesB=[ROIS.external],
                                      operator='Intersection',
                                      marginsA=MARGINS.uniform_10mm_expansion,
                                      marginsB=MARGINS.uniform_5mm_contraction)
                ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                     ROIS.ptv.type,
                                     ROIS.ptv.color,
                                     sourcesA=[ictv],
                                     sourcesB=[ROIS.external],
                                     operator='Intersection',
                                     marginsA=MARGINS.uniform_5mm_expansion,
                                     marginsB=MARGINS.uniform_5mm_contraction)
                lungs_igtv = ROI.ROIAlgebra(ROIS.lungs_igtv.name,
                                            ROIS.lungs_igtv.type,
                                            COLORS.lungs,
                                            sourcesA=[ROIS.lungs],
                                            sourcesB=[igtv],
                                            operator='Subtraction')
                water = ROI.ROIAlgebra(ROIS.z_water.name,
                                       ROIS.z_water.type,
                                       COLORS.other_ptv,
                                       sourcesA=[ROIS.lungs, ptv],
                                       sourcesB=[igtv],
                                       operator='Subtraction',
                                       operatorA='Intersection')
                site.add_oars([lungs_igtv, water])
                site.add_targets([igtv, ictv, ptv])
            # Post operative treatment:
            elif diagnosis == 'postop':
                ctv = ROI.ROI(ROIS.ctv.name, ROIS.ctv.type, COLORS.ctv)
                ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                     ROIS.ptv.type,
                                     ROIS.ptv.color,
                                     sourcesA=[ctv],
                                     sourcesB=[ROIS.external],
                                     operator='Intersection',
                                     marginsA=MARGINS.uniform_10mm_expansion,
                                     marginsB=MARGINS.uniform_5mm_contraction)
                water = ROI.ROIAlgebra(ROIS.z_water.name,
                                       ROIS.z_water.type,
                                       COLORS.other_ptv,
                                       sourcesA=[ROIS.lungs, ptv],
                                       sourcesB=[ctv],
                                       operator='Subtraction',
                                       operatorA='Intersection')
                site.add_oars([water])
                site.add_targets([ctv, ptv])
            # Common for all curative cases:
            heart_ptv = ROI.ROIAlgebra(ROIS.z_heart.name,
                                       ROIS.z_heart.type,
                                       COLORS.heart,
                                       sourcesA=[ROIS.heart],
                                       sourcesB=[ptv],
                                       operator='Subtraction',
                                       marginsB=MARGINS.uniform_3mm_expansion)
            esophagus_ptv = ROI.ROIAlgebra(
                ROIS.z_esophagus.name,
                ROIS.z_esophagus.type,
                COLORS.esophagus,
                sourcesA=[ROIS.esophagus],
                sourcesB=[ptv],
                operator='Subtraction',
                marginsB=MARGINS.uniform_3mm_expansion)
            site.add_oars([heart_ptv, esophagus_ptv])
        # Palliative:
        elif intent == 'palliative':
            # Choice 2: 4DCT - with or without?
            # With 4DCT:
            if choices[2]:
                ictv = ROI.ROIAlgebra(ROIS.ictv.name,
                                      ROIS.ictv.type,
                                      ROIS.ctv.color,
                                      sourcesA=[ROIS.igtv],
                                      sourcesB=[ROIS.external],
                                      operator='Intersection',
                                      marginsA=MARGINS.uniform_5mm_expansion,
                                      marginsB=MARGINS.uniform_5mm_contraction)
                ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                     ROIS.ptv.type,
                                     ROIS.ptv.color,
                                     sourcesA=[ictv],
                                     sourcesB=[ROIS.external],
                                     operator='Intersection',
                                     marginsA=MARGINS.uniform_5mm_expansion,
                                     marginsB=MARGINS.uniform_5mm_contraction)
                lungs_gtv = ROI.ROIAlgebra(ROIS.lungs_igtv.name,
                                           ROIS.lungs_igtv.type,
                                           COLORS.lungs,
                                           sourcesA=[ROIS.lungs],
                                           sourcesB=[ROIS.igtv],
                                           operator='Subtraction')
                water = ROI.ROIAlgebra(ROIS.z_water.name,
                                       ROIS.z_water.type,
                                       COLORS.other_ptv,
                                       sourcesA=[ROIS.lungs, ptv],
                                       sourcesB=[ROIS.igtv],
                                       operator='Subtraction',
                                       operatorA='Intersection')
                site.add_oars([lungs_gtv, water])
                site.add_targets([ROIS.igtv, ictv, ptv])
            # Without 4DCT:
            else:
                ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                                     ROIS.ctv.type,
                                     ROIS.ctv.color,
                                     sourcesA=[ROIS.gtv],
                                     sourcesB=[ROIS.external],
                                     operator='Intersection',
                                     marginsA=MARGINS.uniform_5mm_expansion,
                                     marginsB=MARGINS.uniform_5mm_contraction)
                ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                     ROIS.ptv.type,
                                     ROIS.ptv.color,
                                     sourcesA=[ctv],
                                     sourcesB=[ROIS.external],
                                     operator='Intersection',
                                     marginsA=MARGINS.uniform_10mm_expansion,
                                     marginsB=MARGINS.uniform_5mm_contraction)
                lungs_gtv = ROI.ROIAlgebra(ROIS.lungs_gtv.name,
                                           ROIS.lungs_gtv.type,
                                           COLORS.lungs,
                                           sourcesA=[ROIS.lungs],
                                           sourcesB=[ROIS.gtv],
                                           operator='Subtraction')
                water = ROI.ROIAlgebra(ROIS.z_water.name,
                                       ROIS.z_water.type,
                                       COLORS.other_ptv,
                                       sourcesA=[ROIS.lungs, ptv],
                                       sourcesB=[ROIS.gtv],
                                       operator='Subtraction',
                                       operatorA='Intersection')
                site.add_oars([lungs_gtv, water])
                site.add_targets([ROIS.gtv, ctv, ptv])
            # Common for all palliative cases:
            heart_ptv = ROI.ROIAlgebra(ROIS.z_heart.name,
                                       ROIS.z_heart.type,
                                       COLORS.heart,
                                       sourcesA=[ROIS.heart],
                                       sourcesB=[ptv],
                                       operator='Subtraction',
                                       marginsB=MARGINS.uniform_3mm_expansion)
            esophagus_ptv = ROI.ROIAlgebra(
                ROIS.z_esophagus.name,
                ROIS.z_esophagus.type,
                COLORS.esophagus,
                sourcesA=[ROIS.esophagus],
                sourcesB=[ptv],
                operator='Subtraction',
                marginsB=MARGINS.uniform_3mm_expansion)
            site.add_oars([heart_ptv, esophagus_ptv])
        # Stereotactic treatment:
        elif intent == 'stereotactic':
            # Choice 2: Side - left or right?
            side = choices[2]
            if side == 'right':
                site.add_oars([ROIS.rib_x_r, ROIS.rib_y_r, ROIS.ribs_r])
            elif side == 'left':
                site.add_oars([ROIS.rib_x_l, ROIS.rib_y_l, ROIS.ribs_l])
            nr_targets = choices[3]
            # Choice 3: Number of target volumes?
            if nr_targets == 'one':
                site.add_targets(
                    [ROIS.igtv, ROIS.ictv, ROIS.iptv, ROIS.wall_ptv])
                site.add_oars([ROIS.lungs_igtv])
            elif nr_targets in ['two', 'three']:
                igtv = ROI.ROIAlgebra(ROIS.igtv.name,
                                      ROIS.igtv.type,
                                      ROIS.gtv.color,
                                      sourcesA=[ROIS.igtv1],
                                      sourcesB=[ROIS.igtv2])
                site.add_targets([
                    ROIS.igtv1, ROIS.igtv2, igtv, ROIS.ictv1, ROIS.ictv2,
                    ROIS.iptv1, ROIS.iptv2, ROIS.wall_ptv1, ROIS.wall_ptv2
                ])
                if nr_targets == 'three':
                    igtv.sourcesB.extend([ROIS.igtv3])
                    site.add_targets(
                        [ROIS.igtv3, ROIS.ictv3, ROIS.iptv3, ROIS.wall_ptv3])
                lungs_igtv = ROI.ROIAlgebra(ROIS.lungs_igtv.name,
                                            'Organ',
                                            COLORS.lungs,
                                            sourcesA=[ROIS.lungs],
                                            sourcesB=[igtv],
                                            operator='Subtraction')
                site.add_oars([lungs_igtv])
            site.add_oars(DEF.lung_stereotactic_oars)

        # Create all targets and OARs in RayStation:
        site.create_rois()
Exemplo n.º 14
0
 def __init__(self, pm, examination, ss, choices, site):
     # Choice 1: Local/Regional/Regional with IMN
     region = choices[1]
     # Choice 2: Side - Left or right?
     side = choices[2]
     # Region:
     if region == 'partial':
         # Partial breast only:
         if side == 'right':
             # Right:
             breast_draft = ROIS.breast_r_draft
             breast = ROI.ROIAlgebra(
                 ROIS.breast_r.name,
                 ROIS.breast_r.type,
                 ROIS.breast_r.color,
                 sourcesA=[breast_draft],
                 sourcesB=[ROIS.external],
                 operator='Intersection',
                 marginsA=MARGINS.zero,
                 marginsB=MARGINS.uniform_5mm_contraction)
         else:
             # Left:
             breast_draft = ROIS.breast_l_draft
             breast = ROI.ROIAlgebra(
                 ROIS.breast_l.name,
                 ROIS.breast_l.type,
                 ROIS.breast_l.color,
                 sourcesA=[breast_draft],
                 sourcesB=[ROIS.external],
                 operator='Intersection',
                 marginsA=MARGINS.zero,
                 marginsB=MARGINS.uniform_5mm_contraction)
         # Targets:
         ctv_sb = ROI.ROIAlgebra(ROIS.ctv_sb.name,
                                 ROIS.ctv.type,
                                 ROIS.ctv.color,
                                 sourcesA=[ROIS.surgical_bed],
                                 sourcesB=[breast],
                                 operator='Intersection',
                                 marginsA=MARGINS.uniform_15mm_expansion,
                                 marginsB=MARGINS.zero)
         ptv_sbc = ROI.ROIAlgebra(ROIS.ptv_sbc.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ctv_sb],
                                  sourcesB=[ROIS.external],
                                  operator='Intersection',
                                  marginsA=MARGINS.uniform_5mm_expansion,
                                  marginsB=MARGINS.uniform_5mm_contraction)
         site.add_targets([ctv_sb, ptv_sbc])
         # OARs:
         site.add_oars(DEF.breast_part_oars + [breast_draft, breast])
     else:
         # Whole breast (with or without regional nodes):
         # Choice 3: With our without boost?
         boost = choices[3]
         if region == 'whole':
             # Whole breast:
             if side == 'right':
                 breast_draft = ROIS.breast_r_draft
                 # OARs:
                 site.add_oars(DEF.breast_whole_oars +
                               [ROIS.breast_r_draft])
             else:
                 breast_draft = ROIS.breast_l_draft
                 # Left side: Use DL model:
                 examination.RunOarSegmentation(
                     ModelName="St. Olavs-Ålesund Breast CT",
                     ExaminationsAndRegistrations={examination.Name: None},
                     RoisToInclude=[
                         "A_LAD", "BreastString_L", "Breast_L_Draft",
                         "Clips_L", "Breast_R_Draft", "Esophagus", "Heart",
                         "Lung_L", "Lung_R", "SpinalCanalFull", "Sternum",
                         "SurgicalBed_L", "Trachea"
                     ])
                 # Rename DL ROI(s):
                 pm.RegionsOfInterest[
                     'SpinalCanalFull'].Name = 'SpinalCanal'
                 # Change type to 'Other' for selected ROIs:
                 for roi_name in [
                         'Clips_L', 'BreastString_L', 'Breast_L_Draft',
                         'Breast_R_Draft', 'SurgicalBed_L'
                 ]:
                     pm.RegionsOfInterest[
                         roi_name].OrganData.OrganType = "Other"
                 # OARs:
                 site.add_oars([ROIS.breast_r, ROIS.lungs])
             # Targets:
             ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                                  ROIS.ctv.type,
                                  ROIS.ctv.color,
                                  sourcesA=[breast_draft],
                                  sourcesB=[ROIS.external],
                                  operator='Intersection',
                                  marginsA=MARGINS.zero,
                                  marginsB=MARGINS.uniform_5mm_contraction)
             ptv = ROI.ROIAlgebra(ROIS.ptv_c.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ctv],
                                  sourcesB=[ROIS.external],
                                  operator='Intersection',
                                  marginsA=MARGINS.uniform_5mm_expansion,
                                  marginsB=MARGINS.uniform_5mm_contraction)
             # Robustness evaluation volume:
             if side == 'right':
                 ptv_robustness = ROI.ROIExpanded(
                     'PTV_robustness',
                     ROIS.ptv.type,
                     COLORS.ptv_high,
                     ptv,
                     margins=MARGINS.breast_right_robustness)
             else:
                 ptv_robustness = ROI.ROIExpanded(
                     'PTV_robustness',
                     ROIS.ptv.type,
                     COLORS.ptv_high,
                     ptv,
                     margins=MARGINS.breast_left_robustness)
             # Targets for whole breast:
             site.add_targets([ctv, ptv, ptv_robustness])
         elif region in ['regional', 'regional_imn']:
             # Regional breast (with or without IMN):
             # Side dependent OARs and support structures for regional treatment:
             if side == 'right':
                 # Targets:
                 ctv_p = ROI.ROIAlgebra(
                     ROIS.ctv_p.name,
                     ROIS.ctv_p.type,
                     ROIS.ctv.color,
                     sourcesA=[ROIS.breast_r_draft],
                     sourcesB=[ROIS.external],
                     operator='Intersection',
                     marginsA=MARGINS.zero,
                     marginsB=MARGINS.uniform_5mm_contraction)
                 ctv_n = ROI.ROIAlgebra(ROIS.ctv_n.name,
                                        ROIS.ctv_n.type,
                                        ROIS.ctv.color,
                                        sourcesA=[
                                            ROIS.level_r, ROIS.level1_r,
                                            ROIS.level2_r, ROIS.level3_r,
                                            ROIS.level4_r
                                        ],
                                        sourcesB=[ctv_p],
                                        operator='Subtraction',
                                        marginsA=MARGINS.zero,
                                        marginsB=MARGINS.zero)
                 if region == 'regional_imn':
                     imn = ROIS.imn_r
                     site.add_targets([imn])
                 # Others:
                 site.add_oars([
                     ROIS.breast_r_draft, ROIS.breast_l, ROIS.level_r,
                     ROIS.level1_r, ROIS.level2_r, ROIS.level3_r,
                     ROIS.level4_r
                 ])
                 # OARs:
                 site.add_oars(DEF.breast_reg_oars + [
                     ROIS.humeral_r, ROIS.scalene_muscle_r, ROIS.artery1_r,
                     ROIS.artery2_r, ROIS.artery3_r, ROIS.vein1_r,
                     ROIS.vein2_r, ROIS.vein3_r, ROIS.liver
                 ])
             else:
                 # Left side: Use DL model:
                 examination.RunOarSegmentation(
                     ModelName="St. Olavs-Ålesund Breast CT",
                     ExaminationsAndRegistrations={examination.Name: None},
                     RoisToInclude=[
                         "A_Carotid_L", "A_LAD",
                         "A_Subclavian_L+A_Axillary_L", "BreastString_L",
                         "Breast_L_Draft", "Clips_L", "Breast_R_Draft",
                         "Esophagus", "Heart", "HumeralHead_L",
                         "LN_Ax_L1_L", "LN_Ax_L2_L", "LN_Ax_L3_L",
                         "LN_Ax_L4_L", "LN_Ax_Pectoral_L", "LN_IMN_L",
                         "Lung_L", "Lung_R", "ScaleneMusc_Ant_L",
                         "SpinalCanalFull", "Sternum", "SurgicalBed_L",
                         "ThyroidGland", "Trachea", "V_Brachioceph_L",
                         "V_Jugular_L", "V_Subclavian_L+V_Axillary_L"
                     ])
                 # Rename DL ROI(s):
                 pm.RegionsOfInterest[
                     'SpinalCanalFull'].Name = 'SpinalCanal'
                 # Change type to 'Other' for selected ROIs:
                 for roi_name in [
                         'Clips_L', 'BreastString_L', 'Breast_L_Draft',
                         'LN_Ax_Pectoral_L', 'LN_Ax_L1_L', 'LN_Ax_L2_L',
                         'LN_Ax_L3_L', 'LN_Ax_L4_L', 'Breast_R_Draft',
                         'ScaleneMusc_Ant_L', 'A_Subclavian_L+A_Axillary_L',
                         'A_Carotid_L', 'V_Brachioceph_L',
                         'V_Subclavian_L+V_Axillary_L', 'V_Jugular_L',
                         'LN_IMN_L', 'SurgicalBed_L'
                 ]:
                     pm.RegionsOfInterest[
                         roi_name].OrganData.OrganType = "Other"
                 # Targets:
                 ctv_p = ROI.ROIAlgebra(
                     ROIS.ctv_p.name,
                     ROIS.ctv_p.type,
                     ROIS.ctv.color,
                     sourcesA=[ROIS.breast_l_draft],
                     sourcesB=[ROIS.external],
                     operator='Intersection',
                     marginsA=MARGINS.zero,
                     marginsB=MARGINS.uniform_5mm_contraction)
                 ctv_n = ROI.ROIAlgebra(ROIS.ctv_n.name,
                                        ROIS.ctv_n.type,
                                        ROIS.ctv.color,
                                        sourcesA=[
                                            ROIS.level_l, ROIS.level1_l,
                                            ROIS.level2_l, ROIS.level3_l,
                                            ROIS.level4_l
                                        ],
                                        sourcesB=[ctv_p],
                                        operator='Subtraction',
                                        marginsA=MARGINS.zero,
                                        marginsB=MARGINS.zero)
                 if region == 'regional_imn':
                     imn = ROIS.imn_l
                 # OARs:
                 site.add_oars([ROIS.breast_r, ROIS.lungs])
             # Common targets for left and right:
             ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                                  ROIS.ctv.type,
                                  ROIS.ctv.color,
                                  sourcesA=[ctv_n],
                                  sourcesB=[ctv_p],
                                  operator='Union',
                                  marginsA=MARGINS.zero,
                                  marginsB=MARGINS.zero)
             ptv_p = ROI.ROIAlgebra(
                 ROIS.ptv_pc.name,
                 ROIS.ptv_pc.type,
                 ROIS.ptv.color,
                 sourcesA=[ctv_p],
                 sourcesB=[ROIS.external],
                 operator='Intersection',
                 marginsA=MARGINS.uniform_5mm_expansion,
                 marginsB=MARGINS.uniform_5mm_contraction)
             ptv_n = ROI.ROIAlgebra(
                 ROIS.ptv_nc.name,
                 ROIS.ptv_nc.type,
                 ROIS.ptv.color,
                 sourcesA=[ctv_n],
                 sourcesB=[ROIS.external],
                 operator='Intersection',
                 marginsA=MARGINS.uniform_5mm_expansion,
                 marginsB=MARGINS.uniform_5mm_contraction)
             ptv = ROI.ROIAlgebra(ROIS.ptv_c.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ptv_n],
                                  sourcesB=[ptv_p],
                                  operator='Union',
                                  marginsA=MARGINS.zero,
                                  marginsB=MARGINS.zero)
             # IMN:
             if region == 'regional_imn':
                 ctv_n.sourcesA.extend([imn])
             # Robustness evaluation volume:
             if side == 'right':
                 ptv_robustness = ROI.ROIExpanded(
                     'PTV_robustness',
                     ROIS.ptv.type,
                     COLORS.ptv_high,
                     ptv_p,
                     margins=MARGINS.breast_right_robustness)
             else:
                 ptv_robustness = ROI.ROIExpanded(
                     'PTV_robustness',
                     ROIS.ptv.type,
                     COLORS.ptv_high,
                     ptv_p,
                     margins=MARGINS.breast_left_robustness)
             # Common targets for all regional:
             site.add_targets(
                 [ctv_p, ctv_n, ctv, ptv_p, ptv_n, ptv, ptv_robustness])
         # Add targets for boost (2 Gy x 8) if selected:
         if boost == 'with':
             if side == 'right':
                 sb = ROIS.surgical_bed_r
                 site.add_targets([sb])
             else:
                 sb = ROIS.surgical_bed_l
             ctv_sb = ROI.ROIAlgebra(ROIS.ctv_sb.name,
                                     ROIS.ctv.type,
                                     ROIS.ctv.color,
                                     sourcesA=[sb],
                                     sourcesB=[ctv],
                                     operator='Intersection',
                                     marginsA=MARGINS.uniform_5mm_expansion,
                                     marginsB=MARGINS.zero)
             ptv_sbc = ROI.ROIAlgebra(
                 ROIS.ptv_sbc.name,
                 ROIS.ptv_sb.type,
                 ROIS.ptv.color,
                 sourcesA=[ctv_sb],
                 sourcesB=[ROIS.external],
                 operator='Intersection',
                 marginsA=MARGINS.uniform_5mm_expansion,
                 marginsB=MARGINS.uniform_5mm_contraction)
             site.add_targets([ctv_sb, ptv_sbc])
     # Create all targets and OARs in RayStation:
     site.create_rois()
     if 'ptv_robustness' in locals():
         # Change type of robustness volume to avoid problems with dose grid and dose calculation:
         pm.RegionsOfInterest['PTV_robustness'].Type = "Control"
         pm.RegionsOfInterest[
             'PTV_robustness'].OrganData.OrganType = "Other"
Exemplo n.º 15
0
 def __init__(self, pm, examination, ss, choices, site):
     # Choice 1: Scope (whole brain, part or stereotactic).
     region = choices[1]
     # Region:
     if region == 'whole':
         # Whole brain:
         # Choice 2: Involvement of menignes.
         meninges = choices[2]
         if meninges == 'yes':
             brain_margin = MARGINS.uniform_1mm_expansion
         else:
             brain_margin = MARGINS.zero
         # Targets:
         ctv = ROI.ROIExpanded(ROIS.ctv.name,
                               ROIS.ctv.type,
                               COLORS.ctv,
                               ROIS.brain,
                               margins=brain_margin)
         ptv = ROI.ROIExpanded(ROIS.ptv.name,
                               ROIS.ptv.type,
                               COLORS.ptv,
                               ctv,
                               margins=MARGINS.uniform_3mm_expansion)
         site.add_targets([ctv, ptv])
         # OARs:
         site.add_oars(DEF.brain_whole_oars)
     elif region == 'part':
         # Partial Brain:
         # Targets:
         ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                              ROIS.ctv.type,
                              COLORS.ctv,
                              sourcesA=[ROIS.gtv],
                              sourcesB=[ROIS.brain],
                              operator='Intersection',
                              marginsA=MARGINS.uniform_20mm_expansion,
                              marginsB=MARGINS.uniform_1mm_expansion)
         ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                              ROIS.ptv.type,
                              COLORS.ptv,
                              sourcesA=[ctv],
                              sourcesB=[ROIS.body],
                              operator='Intersection',
                              marginsA=MARGINS.uniform_3mm_expansion,
                              marginsB=MARGINS.uniform_5mm_contraction)
         site.add_targets([ROIS.gtv, ctv, ptv])
         # OARs:
         brain_gtv = ROI.ROIAlgebra(ROIS.brain_gtv.name,
                                    ROIS.brain_gtv.type,
                                    ROIS.brain.color,
                                    sourcesA=[ROIS.brain],
                                    sourcesB=[ROIS.gtv],
                                    operator='Subtraction')
         brain_ptv = ROI.ROIAlgebra(ROIS.brain_ptv.name,
                                    ROIS.brain_ptv.type,
                                    ROIS.other_ptv.color,
                                    sourcesA=[ROIS.brain],
                                    sourcesB=[ptv],
                                    operator='Subtraction')
         site.add_oars(DEF.brain_partial_oars + [brain_gtv, brain_ptv])
     elif region == 'stereotactic':
         # Stereotactic brain:
         # Choice 2: Nr of targets.
         nr_targets = int(choices[2])
         gtvs = []
         ptvs = []
         walls = []
         # How many targets?
         if nr_targets == 1:
             # Single target:
             gtv = ROI.ROI('GTV', 'Gtv', ROIS.gtv.color)
             ptv = ROI.ROIExpanded(ROIS.ptv.name,
                                   ROIS.ptv.type,
                                   COLORS.ptv,
                                   gtv,
                                   margins=MARGINS.uniform_2mm_expansion)
             gtvs.append(gtv)
             ptvs.append(ptv)
             walls.append(
                 ROI.ROIWall(ROIS.z_ptv_wall.name, ROIS.z_ptv_wall.type,
                             COLORS.wall, ptvs[-1], 1, 0))
         else:
             # Multiple targets (2, 3 or 4):
             for i in range(0, nr_targets):
                 # Targets:
                 gtvs.append(
                     ROI.ROI('GTV' + str(i + 1), 'Gtv', ROIS.gtv.color))
                 ptvs.append(
                     ROI.ROIExpanded(ROIS.ptv.name + str(i + 1),
                                     ROIS.ptv.type,
                                     COLORS.ptv,
                                     gtvs[-1],
                                     margins=MARGINS.uniform_2mm_expansion))
                 # OARs:
                 walls.append(
                     ROI.ROIWall("zPTV" + str(i + 1) + "_Wall",
                                 ROIS.z_ptv_wall.type, COLORS.wall,
                                 ptvs[-1], 1, 0))
             # Union target volumes:
             gtv = ROI.ROIAlgebra(ROIS.gtv.name,
                                  ROIS.gtv.type,
                                  ROIS.gtv.color,
                                  sourcesA=[gtvs[0]],
                                  sourcesB=gtvs[1:])
             ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ptvs[0]],
                                  sourcesB=ptvs[1:])
             gtvs.append(gtv)
             ptvs.append(ptv)
         # Common for single or multiple SRT targets:
         # Brain with targets excluded:
         brain_gtv = ROI.ROIAlgebra(ROIS.brain_gtv.name,
                                    ROIS.brain_gtv.type,
                                    ROIS.brain.color,
                                    sourcesA=[ROIS.brain],
                                    sourcesB=[gtv],
                                    operator='Subtraction')
         brain_ptv = ROI.ROIAlgebra(ROIS.brain_ptv.name,
                                    ROIS.brain_ptv.type,
                                    ROIS.other_ptv.color,
                                    sourcesA=[ROIS.brain],
                                    sourcesB=[ptv],
                                    operator='Subtraction')
         # Add to site:
         site.add_targets(gtvs + ptvs)
         site.add_oars(DEF.brain_stereotactic_oars +
                       [brain_gtv, brain_ptv] + walls)
     # Create all targets and OARs in RayStation:
     site.create_rois()
Exemplo n.º 16
0
    def __init__(self, pm, examination, ss, choices, site):
        # Choice 1: Scope (whole brain, part or stereotactic).
        region = choices[1]
        # Region:
        # Whole brain:
        if region == 'whole':
            site.add_oars(DEF.brain_whole_oars)
            ctv = ROI.ROIExpanded(ROIS.ctv.name, ROIS.ctv.type, COLORS.ctv,
                                  ROIS.brain)
            ptv = ROI.ROIExpanded(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  COLORS.ptv,
                                  ctv,
                                  margins=MARGINS.uniform_3mm_expansion)
            site.add_targets([ctv, ptv])
        # Partial Brain:
        elif region == 'part':
            ctv = ROI.ROIExpanded(ROIS.ctv.name,
                                  ROIS.ctv.type,
                                  COLORS.ctv,
                                  ROIS.gtv,
                                  margins=MARGINS.uniform_20mm_expansion)
            brain_gtv = ROI.ROIAlgebra(ROIS.brain_gtv.name,
                                       ROIS.brain_gtv.type,
                                       ROIS.brain.color,
                                       sourcesA=[ROIS.brain],
                                       sourcesB=[ROIS.gtv],
                                       operator='Subtraction')
            site.add_oars([brain_gtv])
            site.add_targets([ROIS.gtv, ctv])
            # Common for all diagnoses of partial brain:
            site.add_oars(DEF.brain_partial_oars)
            ptv = ROI.ROIExpanded(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  COLORS.ptv,
                                  ctv,
                                  margins=MARGINS.uniform_3mm_expansion)
            brain_ptv = ROI.ROIAlgebra(ROIS.brain_ptv.name,
                                       ROIS.brain_ptv.type,
                                       ROIS.other_ptv.color,
                                       sourcesA=[ROIS.brain],
                                       sourcesB=[ptv],
                                       operator='Subtraction')
            site.add_oars([brain_ptv])
            site.add_targets([ptv])

        # Stereotactic brain:
        elif region == 'stereotactic':
            site.add_oars(DEF.brain_stereotactic_oars)
            # Choice 2: Nr of targets.
            nr_targets = choices[2]
            # One target:
            if nr_targets == 'one':
                gtv = ROI.ROI('GTV', 'Gtv', ROIS.gtv.color)
                ptv = ROI.ROIExpanded(ROIS.ptv.name,
                                      ROIS.ptv.type,
                                      COLORS.ptv,
                                      gtv,
                                      margins=MARGINS.uniform_2mm_expansion)
                wall_ptv = ROI.ROIWall(ROIS.z_ptv_wall.name,
                                       ROIS.z_ptv_wall.type, COLORS.wall, ptv,
                                       1, 0)
                site.add_targets([wall_ptv])
            # Multiple targets (2, 3 or 4):
            elif nr_targets in ['two', 'three', 'four']:
                gtv = ROI.ROIAlgebra(ROIS.gtv.name,
                                     ROIS.gtv.type,
                                     ROIS.gtv.color,
                                     sourcesA=[ROIS.gtv1],
                                     sourcesB=[ROIS.gtv2])
                ptv1 = ROI.ROIExpanded(ROIS.ptv1.name,
                                       ROIS.ptv1.type,
                                       COLORS.ptv,
                                       ROIS.gtv1,
                                       margins=MARGINS.uniform_2mm_expansion)
                ptv2 = ROI.ROIExpanded(ROIS.ptv2.name,
                                       ROIS.ptv2.type,
                                       COLORS.ptv,
                                       ROIS.gtv2,
                                       margins=MARGINS.uniform_2mm_expansion)
                ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                     ROIS.ptv.type,
                                     ROIS.ptv.color,
                                     sourcesA=[ptv1],
                                     sourcesB=[ptv2])
                wall_ptv1 = ROI.ROIWall(ROIS.z_ptv1_wall.name,
                                        ROIS.z_ptv1_wall.type, COLORS.wall,
                                        ptv1, 1, 0)
                wall_ptv2 = ROI.ROIWall(ROIS.z_ptv2_wall.name,
                                        ROIS.z_ptv2_wall.type, COLORS.wall,
                                        ptv2, 1, 0)
                site.add_targets([wall_ptv1, wall_ptv2])
                site.add_targets([ROIS.gtv1, ROIS.gtv2, ptv1, ptv2])
                # 3 or 4 targets:
                if nr_targets in ['three', 'four']:
                    ptv3 = ROI.ROIExpanded(
                        ROIS.ptv3.name,
                        ROIS.ptv3.type,
                        COLORS.ptv,
                        ROIS.gtv3,
                        margins=MARGINS.uniform_2mm_expansion)
                    wall_ptv3 = ROI.ROIWall(ROIS.z_ptv3_wall.name,
                                            ROIS.z_ptv3_wall.type, COLORS.wall,
                                            ptv3, 1, 0)
                    ptv.sourcesB.extend([ptv3])
                    gtv.sourcesB.extend([ROIS.gtv3])
                    site.add_targets([ROIS.gtv3, ptv3])
                    site.add_targets([wall_ptv3])
                    # 4 targets:
                    if nr_targets in ['four']:
                        ptv4 = ROI.ROIExpanded(
                            ROIS.ptv4.name,
                            ROIS.ptv4.type,
                            COLORS.ptv,
                            ROIS.gtv4,
                            margins=MARGINS.uniform_2mm_expansion)
                        wall_ptv4 = ROI.ROIWall(ROIS.z_ptv4_wall.name,
                                                ROIS.z_ptv4_wall.type,
                                                COLORS.wall, ptv4, 1, 0)
                        ptv.sourcesB.extend([ptv4])
                        gtv.sourcesB.extend([ROIS.gtv4])
                        site.add_targets([ROIS.gtv4, ptv4])
                        site.add_targets([wall_ptv4])
            # Common for stereotactic:
            brain_ptv = ROI.ROIAlgebra(ROIS.brain_ptv.name,
                                       ROIS.brain_ptv.type,
                                       ROIS.other_ptv.color,
                                       sourcesA=[ROIS.brain],
                                       sourcesB=[ptv],
                                       operator='Subtraction')
            brain_gtv = ROI.ROIAlgebra(ROIS.brain_gtv.name,
                                       ROIS.brain_gtv.type,
                                       ROIS.brain.color,
                                       sourcesA=[ROIS.brain],
                                       sourcesB=[gtv],
                                       operator='Subtraction')
            site.add_targets([gtv, ptv])
            site.add_oars([brain_ptv, brain_gtv])

        # Create all targets and OARs in RayStation:
        site.create_rois()
Exemplo n.º 17
0
 def __init__(self, pm, examination, ss, choices, site):
     # Default OARs:
     site.add_oars(DEF.lung_oars)
     # Choice 1: Intent (curative or palliative)
     intent = choices[1]
     if intent == 'curative':
         # Curative:
         # Choice 2: Diagnosis
         diagnosis = choices[2]
         if diagnosis == '4dct':
             # Non small cell lung cancer (with 4DCT) or small cell lung cancer (with 4DCT):
             # Targets:
             igtv = ROI.ROIAlgebra(ROIS.igtv.name,
                                   ROIS.igtv.type,
                                   ROIS.gtv.color,
                                   sourcesA=[ROIS.igtv_p],
                                   sourcesB=[ROIS.igtv_n])
             ictv_p = ROI.ROIExpanded(
                 ROIS.ictv_p.name,
                 ROIS.ictv_p.type,
                 COLORS.ctv_high,
                 source=ROIS.igtv_p,
                 margins=MARGINS.uniform_10mm_expansion)
             ictv_n = ROI.ROIExpanded(ROIS.ictv_n.name,
                                      ROIS.ictv_n.type,
                                      COLORS.ctv_high,
                                      source=ROIS.igtv_n,
                                      margins=MARGINS.uniform_5mm_expansion)
             ictv = ROI.ROIAlgebra(ROIS.ictv.name,
                                   ROIS.ictv.type,
                                   ROIS.ctv.color,
                                   sourcesA=[ictv_p, ictv_n],
                                   sourcesB=[ROIS.external],
                                   operator='Intersection',
                                   marginsA=MARGINS.zero,
                                   marginsB=MARGINS.uniform_5mm_contraction)
             ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  COLORS.ptv_high,
                                  sourcesA=[ictv],
                                  sourcesB=[ROIS.external],
                                  operator='Intersection',
                                  marginsA=MARGINS.uniform_5mm_expansion,
                                  marginsB=MARGINS.uniform_5mm_contraction)
             site.add_targets([
                 ROIS.igtv_p, ROIS.igtv_n, igtv, ictv_p, ictv_n, ictv, ptv
             ])
             # OARs / others:
             lungs_igtv = ROI.ROIAlgebra(ROIS.lungs_igtv.name,
                                         ROIS.lungs_igtv.type,
                                         COLORS.lungs,
                                         sourcesA=[ROIS.lungs],
                                         sourcesB=[igtv],
                                         operator='Subtraction')
             water = ROI.ROIAlgebra(ROIS.z_water.name,
                                    ROIS.z_water.type,
                                    COLORS.other_ptv,
                                    sourcesA=[ROIS.lungs, ptv],
                                    sourcesB=[igtv],
                                    operator='Subtraction',
                                    operatorA='Intersection')
             site.add_oars([lungs_igtv, water])
         elif diagnosis == 'sclc':
             # Small cell lung cancer (without 4DCT):
             # Targets:
             ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                                  ROIS.ctv.type,
                                  ROIS.ctv.color,
                                  sourcesA=[ROIS.ctv_p, ROIS.ctv_n],
                                  sourcesB=[ROIS.external],
                                  operator='Intersection',
                                  marginsA=MARGINS.zero,
                                  marginsB=MARGINS.uniform_5mm_contraction)
             ptv_p = ROI.ROIAlgebra(
                 ROIS.ptv_p.name,
                 ROIS.ptv.type,
                 ROIS.ptv.color,
                 sourcesA=[ROIS.ctv_p],
                 sourcesB=[ROIS.external],
                 operator='Intersection',
                 marginsA=MARGINS.lung_sclc_without_4dct,
                 marginsB=MARGINS.uniform_5mm_contraction)
             ptv_n = ROI.ROIAlgebra(
                 ROIS.ptv_n.name,
                 ROIS.ptv.type,
                 ROIS.ptv.color,
                 sourcesA=[ROIS.ctv_n],
                 sourcesB=[ROIS.external],
                 operator='Intersection',
                 marginsA=MARGINS.uniform_10mm_expansion,
                 marginsB=MARGINS.uniform_5mm_contraction)
             ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ptv_p],
                                  sourcesB=[ptv_n])
             site.add_targets(
                 [ROIS.ctv_p, ROIS.ctv_n, ctv, ptv_p, ptv_n, ptv])
             # OARs / others:
             water = ROI.ROIAlgebra(ROIS.z_water.name,
                                    ROIS.z_water.type,
                                    COLORS.other_ptv,
                                    sourcesA=[ROIS.lungs, ptv],
                                    sourcesB=[ctv],
                                    operator='Subtraction',
                                    operatorA='Intersection')
             site.add_oars([water])
         elif diagnosis == 'pancoast':
             # Pancoast tumor (with 4DCT):
             # Targets:
             igtv = ROI.ROI(ROIS.igtv.name, ROIS.igtv.type, COLORS.gtv)
             ictv = ROI.ROIAlgebra(ROIS.ictv.name,
                                   ROIS.ictv.type,
                                   ROIS.ctv.color,
                                   sourcesA=[igtv],
                                   sourcesB=[ROIS.external],
                                   operator='Intersection',
                                   marginsA=MARGINS.uniform_10mm_expansion,
                                   marginsB=MARGINS.uniform_5mm_contraction)
             ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ictv],
                                  sourcesB=[ROIS.external],
                                  operator='Intersection',
                                  marginsA=MARGINS.uniform_5mm_expansion,
                                  marginsB=MARGINS.uniform_5mm_contraction)
             site.add_targets([igtv, ictv, ptv])
             # OARs / others:
             lungs_igtv = ROI.ROIAlgebra(ROIS.lungs_igtv.name,
                                         ROIS.lungs_igtv.type,
                                         COLORS.lungs,
                                         sourcesA=[ROIS.lungs],
                                         sourcesB=[igtv],
                                         operator='Subtraction')
             water = ROI.ROIAlgebra(ROIS.z_water.name,
                                    ROIS.z_water.type,
                                    COLORS.other_ptv,
                                    sourcesA=[ROIS.lungs, ptv],
                                    sourcesB=[igtv],
                                    operator='Subtraction',
                                    operatorA='Intersection')
             site.add_oars([lungs_igtv, water])
         elif diagnosis == 'postop':
             # Post operative treatment:
             # Targets:
             ctv = ROI.ROI(ROIS.ctv.name, ROIS.ctv.type, COLORS.ctv)
             ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ctv],
                                  sourcesB=[ROIS.external],
                                  operator='Intersection',
                                  marginsA=MARGINS.uniform_10mm_expansion,
                                  marginsB=MARGINS.uniform_5mm_contraction)
             site.add_targets([ctv, ptv])
             # OARs / others:
             water = ROI.ROIAlgebra(ROIS.z_water.name,
                                    ROIS.z_water.type,
                                    COLORS.other_ptv,
                                    sourcesA=[ROIS.lungs, ptv],
                                    sourcesB=[ctv],
                                    operator='Subtraction',
                                    operatorA='Intersection')
             site.add_oars([water])
         # Common structures for all curative cases:
         heart_ptv = ROI.ROIAlgebra(ROIS.z_heart.name,
                                    ROIS.z_heart.type,
                                    COLORS.heart,
                                    sourcesA=[ROIS.heart],
                                    sourcesB=[ptv],
                                    operator='Subtraction',
                                    marginsB=MARGINS.uniform_3mm_expansion)
         esophagus_ptv = ROI.ROIAlgebra(
             ROIS.z_esophagus.name,
             ROIS.z_esophagus.type,
             COLORS.esophagus,
             sourcesA=[ROIS.esophagus],
             sourcesB=[ptv],
             operator='Subtraction',
             marginsB=MARGINS.uniform_3mm_expansion)
         site.add_oars([heart_ptv, esophagus_ptv])
     elif intent == 'palliative':
         # Palliative:
         # Choice 2: 4DCT - with or without?
         with_4dct = choices[2]
         if with_4dct == 'with':
             # 4DCT:
             # Targets:
             ictv = ROI.ROIAlgebra(ROIS.ictv.name,
                                   ROIS.ictv.type,
                                   ROIS.ctv.color,
                                   sourcesA=[ROIS.igtv],
                                   sourcesB=[ROIS.external],
                                   operator='Intersection',
                                   marginsA=MARGINS.uniform_5mm_expansion,
                                   marginsB=MARGINS.uniform_5mm_contraction)
             ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ictv],
                                  sourcesB=[ROIS.external],
                                  operator='Intersection',
                                  marginsA=MARGINS.uniform_5mm_expansion,
                                  marginsB=MARGINS.uniform_5mm_contraction)
             site.add_targets([ROIS.igtv, ictv, ptv])
             # OARs / others:
             lungs_gtv = ROI.ROIAlgebra(ROIS.lungs_igtv.name,
                                        ROIS.lungs_igtv.type,
                                        COLORS.lungs,
                                        sourcesA=[ROIS.lungs],
                                        sourcesB=[ROIS.igtv],
                                        operator='Subtraction')
             water = ROI.ROIAlgebra(ROIS.z_water.name,
                                    ROIS.z_water.type,
                                    COLORS.other_ptv,
                                    sourcesA=[ROIS.lungs, ptv],
                                    sourcesB=[ROIS.igtv],
                                    operator='Subtraction',
                                    operatorA='Intersection')
             site.add_oars([lungs_gtv, water])
         else:
             # Non-4DCT:
             # Targets:
             ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                                  ROIS.ctv.type,
                                  ROIS.ctv.color,
                                  sourcesA=[ROIS.gtv],
                                  sourcesB=[ROIS.external],
                                  operator='Intersection',
                                  marginsA=MARGINS.uniform_5mm_expansion,
                                  marginsB=MARGINS.uniform_5mm_contraction)
             ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ctv],
                                  sourcesB=[ROIS.external],
                                  operator='Intersection',
                                  marginsA=MARGINS.uniform_10mm_expansion,
                                  marginsB=MARGINS.uniform_5mm_contraction)
             site.add_targets([ROIS.gtv, ctv, ptv])
             # OARs / others:
             lungs_gtv = ROI.ROIAlgebra(ROIS.lungs_gtv.name,
                                        ROIS.lungs_gtv.type,
                                        COLORS.lungs,
                                        sourcesA=[ROIS.lungs],
                                        sourcesB=[ROIS.gtv],
                                        operator='Subtraction')
             water = ROI.ROIAlgebra(ROIS.z_water.name,
                                    ROIS.z_water.type,
                                    COLORS.other_ptv,
                                    sourcesA=[ROIS.lungs, ptv],
                                    sourcesB=[ROIS.gtv],
                                    operator='Subtraction',
                                    operatorA='Intersection')
             site.add_oars([lungs_gtv, water])
         # Common for all palliative cases:
         heart_ptv = ROI.ROIAlgebra(ROIS.z_heart.name,
                                    ROIS.z_heart.type,
                                    COLORS.heart,
                                    sourcesA=[ROIS.heart],
                                    sourcesB=[ptv],
                                    operator='Subtraction',
                                    marginsB=MARGINS.uniform_3mm_expansion)
         esophagus_ptv = ROI.ROIAlgebra(
             ROIS.z_esophagus.name,
             ROIS.z_esophagus.type,
             COLORS.esophagus,
             sourcesA=[ROIS.esophagus],
             sourcesB=[ptv],
             operator='Subtraction',
             marginsB=MARGINS.uniform_3mm_expansion)
         site.add_oars([heart_ptv, esophagus_ptv])
     elif intent == 'stereotactic':
         # Stereotactic treatment:
         # Slice thickness quality control:
         DEFQC.test_slice_thickness(examination, 0.2, "Lunge SBRT")
         # Add a POI for breath hold measurement:
         PMF.create_poi(pm, examination, 'Pust', 'Marker', 'Magenta')
         # Choice 2: Side - left or right?
         side = choices[2]
         if side == 'right':
             site.add_oars([ROIS.rib_x_r, ROIS.rib_y_r, ROIS.ribs_r])
         elif side == 'left':
             site.add_oars([ROIS.rib_x_l, ROIS.rib_y_l, ROIS.ribs_l])
         # Choice 3: Number of target volumes?
         nr_targets = int(choices[3])
         if nr_targets == 1:
             # Single target:
             site.add_targets(
                 [ROIS.igtv, ROIS.ictv, ROIS.iptv, ROIS.wall_ptv])
             site.add_oars([ROIS.lungs_igtv])
         else:
             # Multiple targets:
             igtvs = []
             ictvs = []
             ptvs = []
             walls = []
             for i in range(0, nr_targets):
                 # Targets:
                 igtvs.append(
                     ROI.ROI('IGTV' + str(i + 1), 'Gtv', ROIS.igtv.color))
                 ictvs.append(
                     ROI.ROIExpanded(ROIS.ictv.name + str(i + 1),
                                     ROIS.ictv.type,
                                     COLORS.ctv,
                                     igtvs[-1],
                                     margins=MARGINS.uniform_5mm_expansion))
                 ptvs.append(
                     ROI.ROIExpanded(ROIS.ptv.name + str(i + 1),
                                     ROIS.ptv.type,
                                     COLORS.ptv,
                                     ictvs[-1],
                                     margins=MARGINS.uniform_5mm_expansion))
                 # OARs / others:
                 walls.append(
                     ROI.ROIWall("zPTV" + str(i + 1) + "_Wall",
                                 ROIS.z_ptv_wall.type, COLORS.wall,
                                 ptvs[-1], 1, 0))
             # Union target volumes:
             igtv = ROI.ROIAlgebra(ROIS.igtv.name,
                                   ROIS.igtv.type,
                                   ROIS.igtv.color,
                                   sourcesA=[igtvs[0]],
                                   sourcesB=igtvs[1:])
             ictv = ROI.ROIAlgebra(ROIS.ictv.name,
                                   ROIS.ictv.type,
                                   ROIS.ictv.color,
                                   sourcesA=[ictvs[0]],
                                   sourcesB=ictvs[1:])
             ptv = ROI.ROIAlgebra(ROIS.ptv.name,
                                  ROIS.ptv.type,
                                  ROIS.ptv.color,
                                  sourcesA=[ptvs[0]],
                                  sourcesB=ptvs[1:])
             igtvs.append(igtv)
             ictvs.append(ictv)
             ptvs.append(ptv)
             # Targets:
             site.add_targets(igtvs + ictvs + ptvs)
             # OARs / others:
             lungs_igtv = ROI.ROIAlgebra(ROIS.lungs_igtv.name,
                                         'Organ',
                                         COLORS.lungs,
                                         sourcesA=[ROIS.lungs],
                                         sourcesB=[igtv],
                                         operator='Subtraction')
             site.add_oars([lungs_igtv] + walls)
         # Common for single or multiple targets:
         site.add_oars(DEF.lung_stereotactic_oars)
     # Create all targets and OARs in RayStation:
     site.create_rois()
Exemplo n.º 18
0
 def __init__(self, pm, examination, ss, choices, site):
     # Choice 1: Fractionation - normo or hypofractionated?
     frac = choices[1]
     site.add_oars(DEF.rectum_oars)
     # Conventionally fractionated (2 Gy x 25):
     if frac == 'normo':
         # Choice 2: Groin target volume - included or not?
         groin = choices[2]
         # Groin targets included:
         if groin == 'with':
             gtv = ROI.ROIAlgebra(
                 ROIS.gtv.name,
                 ROIS.gtv.type,
                 ROIS.gtv.color,
                 sourcesA=[ROIS.gtv_p],
                 sourcesB=[ROIS.gtv_n1, ROIS.gtv_groin_l, ROIS.gtv_groin_r])
             site.add_targets([
                 ROIS.gtv_p, ROIS.gtv_n1, ROIS.gtv_groin_l,
                 ROIS.gtv_groin_r, gtv
             ])
         # Without groin targets:
         else:
             gtv = ROI.ROIAlgebra(ROIS.gtv.name,
                                  ROIS.gtv.type,
                                  ROIS.gtv.color,
                                  sourcesA=[ROIS.gtv_p],
                                  sourcesB=[ROIS.gtv_n1])
             site.add_targets([ROIS.gtv_p, ROIS.gtv_n1, gtv])
         # Common for groin included or not:
         ctv_50 = ROI.ROIExpanded(ROIS.ctv_50.name,
                                  ROIS.ctv_50.type,
                                  COLORS.ctv_high,
                                  source=gtv,
                                  margins=MARGINS.uniform_10mm_expansion)
         ptv_50 = ROI.ROIExpanded(ROIS.ptv_50.name,
                                  ROIS.ptv_50.type,
                                  COLORS.ptv_high,
                                  source=ctv_50,
                                  margins=MARGINS.rectum_ptv_50_expansion)
         if groin == 'with':
             ctv_47 = ROI.ROIAlgebra(
                 ROIS.ctv_47.name,
                 ROIS.ctv_47.type,
                 COLORS.ctv_low,
                 sourcesA=[ROIS.ctv_e, ROIS.ctv_groin_l, ROIS.ctv_groin_r],
                 sourcesB=[ptv_50],
                 operator='Subtraction',
                 marginsA=MARGINS.zero,
                 marginsB=MARGINS.zero)
             ptv_47_tot = ROI.ROIAlgebra(
                 ROIS.ptv_47_tot.name,
                 ROIS.ptv_47.type,
                 COLORS.ptv_med,
                 sourcesA=[ROIS.ctv_e],
                 sourcesB=[ROIS.ctv_groin_l, ROIS.ctv_groin_r],
                 operator='Union',
                 marginsA=MARGINS.rectum_ctv_primary_risk_expansion,
                 marginsB=MARGINS.uniform_5mm_expansion)
             ptv_47 = ROI.ROIAlgebra(ROIS.ptv_47.name,
                                     ROIS.ptv_47.type,
                                     COLORS.ptv_med,
                                     sourcesA=[ptv_47_tot],
                                     sourcesB=[ptv_50],
                                     operator='Subtraction',
                                     marginsA=MARGINS.zero,
                                     marginsB=MARGINS.zero)
             site.add_targets([
                 ctv_47, ptv_47_tot, ptv_47, ROIS.ctv_groin_l,
                 ROIS.ctv_groin_r, ctv_47, ptv_47_tot, ptv_47
             ])
         else:
             ctv_47 = ROI.ROIAlgebra(ROIS.ctv_47.name,
                                     ROIS.ctv_47.type,
                                     COLORS.ctv_low,
                                     sourcesA=[ROIS.ctv_e],
                                     sourcesB=[ptv_50],
                                     operator='Subtraction',
                                     marginsA=MARGINS.zero,
                                     marginsB=MARGINS.zero)
             ptv_47 = ROI.ROIAlgebra(
                 ROIS.ptv_47.name,
                 ROIS.ptv_47.type,
                 COLORS.ptv_med,
                 sourcesA=[ctv_47],
                 sourcesB=[ptv_50],
                 operator='Subtraction',
                 marginsA=MARGINS.rectum_ctv_primary_risk_expansion,
                 marginsB=MARGINS.zero)
             site.add_targets([ctv_47, ptv_47])
         ctv_47_50 = ROI.ROIAlgebra(ROIS.ctv_47_50.name,
                                    ROIS.ctv_47_50.type,
                                    COLORS.ctv_alt,
                                    sourcesA=[ctv_47],
                                    sourcesB=[ctv_50],
                                    operator='Union',
                                    marginsA=MARGINS.zero,
                                    marginsB=MARGINS.zero)
         ptv_47_50 = ROI.ROIAlgebra(ROIS.ptv_47_50.name,
                                    ROIS.ptv_47_50.type,
                                    COLORS.ptv_low,
                                    sourcesA=[ptv_47],
                                    sourcesB=[ptv_50],
                                    operator='Union',
                                    marginsA=MARGINS.zero,
                                    marginsB=MARGINS.zero)
         bladder_ptv = ROI.ROIAlgebra(
             ROIS.z_bladder.name,
             ROIS.z_bladder.type,
             COLORS.bladder,
             sourcesA=[ROIS.bladder],
             sourcesB=[ptv_47_50],
             operator='Subtraction',
             marginsB=MARGINS.uniform_3mm_expansion)
         bowel_ptv = ROI.ROIAlgebra(ROIS.z_spc_bowel.name,
                                    ROIS.z_spc_bowel.type,
                                    COLORS.bowel_space,
                                    sourcesA=[ROIS.bowel_space],
                                    sourcesB=[ptv_47_50],
                                    operator='Subtraction',
                                    marginsB=MARGINS.uniform_3mm_expansion)
         wall_ptv_50 = ROI.ROIWall(ROIS.z_ptv_50_wall.name,
                                   ROIS.z_ptv_50_wall.type, COLORS.wall,
                                   ptv_50, 0.5, 0)
         site.add_oars([bladder_ptv, bowel_ptv, wall_ptv_50])
         site.add_targets(
             [ROIS.ctv_e, ctv_50, ptv_50, ctv_47_50, ptv_47_50])
     # Hypofractionated treatment (5 Gy x 5):
     else:
         ctv_p = ROI.ROIExpanded(ROIS.ctv_p.name,
                                 ROIS.ctv_p.type,
                                 COLORS.ctv_high,
                                 source=ROIS.gtv_p,
                                 margins=MARGINS.uniform_10mm_expansion)
         ctv = ROI.ROIAlgebra(ROIS.ctv.name,
                              ROIS.ctv.type,
                              COLORS.ctv_low,
                              sourcesA=[ROIS.ctv_e],
                              sourcesB=[ctv_p])
         ptv = ROI.ROIAlgebra(
             ROIS.ptv.name,
             ROIS.ptv.type,
             COLORS.ptv_med,
             sourcesA=[ctv_p],
             sourcesB=[ROIS.ctv_e],
             marginsA=MARGINS.rectum_ptv_50_expansion,
             marginsB=MARGINS.rectum_ctv_primary_risk_expansion)
         bladder_ptv = ROI.ROIAlgebra(
             ROIS.z_bladder.name,
             ROIS.z_bladder.type,
             COLORS.bladder,
             sourcesA=[ROIS.bladder],
             sourcesB=[ptv],
             operator='Subtraction',
             marginsB=MARGINS.uniform_3mm_expansion)
         bowel_ptv = ROI.ROIAlgebra(ROIS.z_spc_bowel.name,
                                    ROIS.z_spc_bowel.type,
                                    COLORS.bowel_space,
                                    sourcesA=[ROIS.bowel_space],
                                    sourcesB=[ptv],
                                    operator='Subtraction',
                                    marginsB=MARGINS.uniform_3mm_expansion)
         site.add_oars([bladder_ptv, bowel_ptv])
         site.add_targets([ROIS.gtv_p, ctv_p, ROIS.ctv_e, ctv, ptv])
     # Create all targets and OARs in RayStation:
     site.create_rois()
Exemplo n.º 19
0
  def __init__(self, pm, examination, ss, choices, site):
    # Choice 1: Region - prostate or bed?
    region = choices[1]
    # Prostate:
    if region == 'prostate':
      # Choice 2: Fractionation - normo or hypo?
      frac = choices[2]
      if frac == 'palliative':
        site.add_oars(DEF.prostate_palliative_oars)
      else:
        site.add_oars(DEF.prostate_oars)
      # Conventionally fractionated prostate with vesicles (2.2Gy x 35):
      if frac == 'normo':
        # Choice 3: Nodes - included or not?
        nodes = choices[3]
        ptv_77 = ROI.ROIExpanded(ROIS.ptv_77.name, ROIS.ptv_77.type, COLORS.ptv_high, source = ROIS.prostate, margins = MARGINS.prostate_seed_expansion)
        ctv_77 = ROI.ROIExpanded(ROIS.ctv_77.name, ROIS.ctv_77.type, COLORS.ctv_high, source = ROIS.prostate)
        bladder_ptv = ROI.ROIAlgebra(ROIS.z_bladder.name, ROIS.z_bladder.type, COLORS.bladder, sourcesA = [ROIS.bladder], sourcesB = [ptv_77], operator='Subtraction', marginsB = MARGINS.uniform_3mm_expansion)
        rectum_ptv = ROI.ROIAlgebra(ROIS.z_rectum.name, ROIS.z_rectum.type, COLORS.rectum, sourcesA = [ROIS.rectum], sourcesB = [ptv_77], operator='Subtraction', marginsB = MARGINS.uniform_2mm_expansion)
        wall_ptv_77 = ROI.ROIWall(ROIS.z_ptv_77_wall.name, ROIS.z_ptv_77_wall.type, COLORS.wall, ptv_77, 0.5, 0)
        # With nodes:
        if nodes == 'without':
          ctv_70 = ROI.ROIAlgebra(ROIS.ctv_70_sib.name, ROIS.ctv_70.type, COLORS.ctv_med, sourcesA = [ROIS.vesicles], sourcesB = [ptv_77], operator = 'Subtraction', marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          ptv_70 = ROI.ROIAlgebra(ROIS.ptv_70_sib.name, ROIS.ptv_70.type, COLORS.ptv_med, sourcesA = [ROIS.vesicles], sourcesB = [ptv_77], operator = 'Subtraction', marginsA = MARGINS.uniform_10mm_expansion, marginsB = MARGINS.zero)
          ptv_70_77 =  ROI.ROIAlgebra(ROIS.ptv_70_77.name, ROIS.ptv_70_77.type, COLORS.ptv_low, sourcesA = [ROIS.prostate], sourcesB = [ROIS.vesicles], marginsA = MARGINS.prostate_seed_expansion, marginsB = MARGINS.uniform_10mm_expansion)
          bladder_ptv.sourcesB.extend([ptv_70])
          rectum_ptv.sourcesB.extend([ptv_70])
          site.add_targets([ptv_70_77])
        elif nodes == 'with_node':
          ctv_n = ROI.ROIExpanded(ROIS.ctv_n.name, ROIS.ctv_n.type, COLORS.pelvic_nodes, source = ROIS.gtv_n, margins = MARGINS.uniform_5mm_expansion)
          ptv_n = ROI.ROIExpanded(ROIS.ptv_n.name, ROIS.ptv_n.type, ROIS.ptv_n.color, source = ctv_n, margins = MARGINS.prostate_lymph_nodes_seed_expansion)
          ctv_70 = ROI.ROIAlgebra(ROIS.ctv_70_sib.name, ROIS.ctv_70.type, COLORS.ctv_med, sourcesA = [ROIS.vesicles, ctv_n], sourcesB = [ptv_77], operator = 'Subtraction', marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          ptv_semves = ROI.ROIAlgebra(ROIS.ptv_semves.name, ROIS.ptv_semves.type, COLORS.ptv_med, sourcesA = [ROIS.vesicles], sourcesB = [ptv_77], operator = 'Subtraction', marginsA = MARGINS.uniform_10mm_expansion, marginsB = MARGINS.zero)
          ptv_70 =  ROI.ROIAlgebra(ROIS.ptv_70_sib.name, ROIS.ptv_70_sib.type, ROIS.ptv_70_sib.color, sourcesA = [ptv_semves, ptv_n], sourcesB = [ptv_77], operator = 'Subtraction', marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          ptv_70_77 =  ROI.ROIAlgebra(ROIS.ptv_70_77.name, ROIS.ptv_70_77.type, COLORS.ptv_low, sourcesA = [ptv_70], sourcesB = [ptv_77], marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          ptv_56 = ROI.ROIAlgebra(ROIS.ptv_56.name, ROIS.ptv_56.type, COLORS.ptv_low, sourcesA = [ROIS.pelvic_nodes], sourcesB = [ptv_77, ptv_70], operator = 'Subtraction', marginsA = MARGINS.prostate_lymph_nodes_seed_expansion, marginsB = MARGINS.zero)
          ctv_56 = ROI.ROIAlgebra(ROIS.ctv_56.name, ROIS.ctv_56.type, COLORS.ctv_low, sourcesA = [ROIS.pelvic_nodes], sourcesB = [ptv_77, ptv_70], operator = 'Subtraction', marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          ptv_56_70_77 = ROI.ROIAlgebra(ROIS.ptv_56_70_77.name, ROIS.ptv_56_70_77.type, COLORS.ptv_low, sourcesA = [ptv_56, ptv_70], sourcesB = [ptv_77], marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          bladder_ptv.sourcesB.extend([ptv_70, ptv_56])
          rectum_ptv.sourcesB.extend([ptv_70, ptv_56])
          bowel_ptv = ROI.ROIAlgebra(ROIS.z_spc_bowel.name, ROIS.z_spc_bowel.type, COLORS.bowel_space, sourcesA = [ROIS.bowel_space], sourcesB = [ptv_77, ptv_70, ptv_56], operator='Subtraction', marginsB = MARGINS.uniform_3mm_expansion)
          wall_ptv_70_77 = ROI.ROIWall(ROIS.z_ptv_70_77_wall.name, ROIS.z_ptv_70_77_wall.type, COLORS.wall, ptv_70_77, 1, 0)
          site.add_oars([bowel_ptv, wall_ptv_70_77])
          site.add_targets([ROIS.gtv_n, ctv_n, ptv_n, ptv_semves, ptv_56, ctv_56, ROIS.pelvic_nodes, ptv_70_77, ptv_56_70_77])
        elif nodes == 'with':
          ctv_70 = ROI.ROIAlgebra(ROIS.ctv_70_sib.name, ROIS.ctv_70.type, COLORS.ctv_med, sourcesA = [ROIS.vesicles], sourcesB = [ptv_77], operator = 'Subtraction', marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          ptv_70 = ROI.ROIAlgebra(ROIS.ptv_70_sib.name, ROIS.ptv_70.type, COLORS.ptv_med, sourcesA = [ROIS.vesicles], sourcesB = [ptv_77], operator = 'Subtraction', marginsA = MARGINS.uniform_10mm_expansion, marginsB = MARGINS.zero)
          ptv_70_77 =  ROI.ROIAlgebra(ROIS.ptv_70_77.name, ROIS.ptv_70_77.type, COLORS.ptv_low, sourcesA = [ROIS.prostate], sourcesB = [ROIS.vesicles], marginsA = MARGINS.prostate_seed_expansion, marginsB = MARGINS.uniform_10mm_expansion)
          ptv_56 = ROI.ROIAlgebra(ROIS.ptv_56.name, ROIS.ptv_56.type, COLORS.ptv_low, sourcesA = [ROIS.pelvic_nodes], sourcesB = [ptv_77, ptv_70], operator = 'Subtraction', marginsA = MARGINS.prostate_lymph_nodes_seed_expansion, marginsB = MARGINS.zero)
          ctv_56 = ROI.ROIAlgebra(ROIS.ctv_56.name, ROIS.ctv_56.type, COLORS.ctv_low, sourcesA = [ROIS.pelvic_nodes], sourcesB = [ptv_77, ptv_70], operator = 'Subtraction', marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          ptv_56_70_77 = ROI.ROIAlgebra(ROIS.ptv_56_70_77.name, ROIS.ptv_56_70_77.type, COLORS.ptv_low, sourcesA = [ptv_56, ptv_70], sourcesB = [ptv_77], marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          bladder_ptv.sourcesB.extend([ptv_70, ptv_56])
          rectum_ptv.sourcesB.extend([ptv_70, ptv_56])
          bowel_ptv = ROI.ROIAlgebra(ROIS.z_spc_bowel.name, ROIS.z_spc_bowel.type, COLORS.bowel_space, sourcesA = [ROIS.bowel_space], sourcesB = [ptv_77, ptv_70, ptv_56], operator='Subtraction', marginsB = MARGINS.uniform_3mm_expansion)
          wall_ptv_70_77 = ROI.ROIWall(ROIS.z_ptv_70_77_wall.name, ROIS.z_ptv_70_77_wall.type, COLORS.wall, ptv_70_77, 1, 0)
          site.add_oars([bowel_ptv, wall_ptv_70_77])
          site.add_targets([ptv_56, ctv_56, ROIS.pelvic_nodes, ptv_70_77, ptv_56_70_77])
        # Common for conventional fractionation:
        site.add_oars([bladder_ptv, rectum_ptv, wall_ptv_77])
        site.add_targets([ctv_77, ctv_70, ptv_77, ptv_70, ROIS.prostate, ROIS.vesicles])
      # Hypofractionated prostate with vesicles (3 Gy x 20):
      elif frac == 'hypo_60':
        ptv_57_60 =  ROI.ROIAlgebra(ROIS.ptv_57_60.name, ROIS.ptv_57_60.type, COLORS.ptv_low, sourcesA = [ROIS.prostate], sourcesB = [ROIS.vesicles], marginsA = MARGINS.prostate_seed_expansion, marginsB = MARGINS.uniform_10mm_expansion)
        ptv_60 = ROI.ROIExpanded(ROIS.ptv_60.name, ROIS.ptv_60.type, COLORS.ptv_high, source = ROIS.prostate, margins = MARGINS.prostate_seed_expansion)
        ptv_57 = ROI.ROIAlgebra(ROIS.ptv_57.name, ROIS.ptv_57.type, COLORS.ptv_med, sourcesA = [ptv_57_60], sourcesB = [ptv_60], operator = 'Subtraction', marginsA = MARGINS.zero, marginsB = MARGINS.zero)
        ctv_57_60 =  ROI.ROIAlgebra(ROIS.ctv_57_60.name, ROIS.ctv_57_60.type, COLORS.ctv_low, sourcesA = [ROIS.prostate], sourcesB = [ROIS.vesicles], marginsA = MARGINS.zero, marginsB = MARGINS.zero)
        ctv_60 = ROI.ROIExpanded(ROIS.ctv_60.name, ROIS.ctv_60.type, COLORS.ctv_high, source = ROIS.prostate)
        ctv_57 = ROI.ROIAlgebra(ROIS.ctv_57.name, ROIS.ctv_57.type, COLORS.ctv_med, sourcesA = [ctv_57_60], sourcesB = [ptv_60], operator = 'Subtraction', marginsA = MARGINS.zero, marginsB = MARGINS.zero)
        bladder_ptv = ROI.ROIAlgebra(ROIS.z_bladder.name, ROIS.z_bladder.type, COLORS.bladder, sourcesA = [ROIS.bladder], sourcesB = [ptv_60, ptv_57], operator='Subtraction', marginsB = MARGINS.uniform_3mm_expansion)
        rectum_ptv = ROI.ROIAlgebra(ROIS.z_rectum.name, ROIS.z_rectum.type, COLORS.rectum, sourcesA = [ROIS.rectum], sourcesB = [ptv_60, ptv_57], operator='Subtraction', marginsB = MARGINS.uniform_2mm_expansion)
        wall_ptv_60 = ROI.ROIWall(ROIS.z_ptv_60_wall.name, ROIS.z_ptv_60_wall.type, COLORS.wall, ptv_60, 0.5, 0)
        wall_ptv_57_60 = ROI.ROIWall(ROIS.z_ptv_57_60_wall.name, ROIS.z_ptv_57_60_wall.type, COLORS.wall, ptv_57_60, 1, 0)
        site.add_oars([bladder_ptv, rectum_ptv, wall_ptv_60, wall_ptv_57_60])
        site.add_targets([ptv_57_60, ptv_60, ptv_57, ctv_60, ctv_57, ctv_57_60, ROIS.prostate, ROIS.vesicles])
      elif frac in ['hypo_55','palliative']:
        ctv =  ROI.ROIAlgebra(ROIS.ctv.name, ROIS.ctv.type, COLORS.ctv_low, sourcesA = [ROIS.prostate], sourcesB = [ROIS.vesicles], marginsA = MARGINS.zero, marginsB = MARGINS.zero)
        if frac == 'hypo_55':
          ptv = ROI.ROIExpanded(ROIS.ptv.name, ROIS.ptv.type, COLORS.ptv_high, source = ctv, margins = MARGINS.prostate_seed_expansion)
        elif frac == 'palliative':
          ptv = ROI.ROIExpanded(ROIS.ptv.name, ROIS.ptv.type, COLORS.ptv_high, source = ctv, margins = MARGINS.prostate_bone_match_expansion)

        bladder_ptv = ROI.ROIAlgebra(ROIS.z_bladder.name, ROIS.z_bladder.type, COLORS.bladder, sourcesA = [ROIS.bladder], sourcesB = [ptv], operator='Subtraction', marginsB = MARGINS.uniform_3mm_expansion)
        rectum_ptv = ROI.ROIAlgebra(ROIS.z_rectum.name, ROIS.z_rectum.type, COLORS.rectum, sourcesA = [ROIS.rectum], sourcesB = [ptv], operator='Subtraction', marginsB = MARGINS.uniform_2mm_expansion)
        wall_ptv_55 = ROI.ROIWall(ROIS.z_ptv_wall.name, ROIS.z_ptv_wall.type, COLORS.wall, ptv, 1, 0)
        site.add_oars([bladder_ptv, rectum_ptv, wall_ptv_55])
        site.add_targets([ptv, ctv, ROIS.prostate, ROIS.vesicles])
    # Prostate bed:
    else:
      # Choice 2: Nodes - included or not?
      frac = choices[2]
      site.add_oars(DEF.prostate_bed_oars)
      # With nodes:
      if frac == 'normo':
        nodes = choices[3]
        if nodes == 'without':
          ctv_70 = ROI.ROIExpanded(ROIS.ctv_70.name, ROIS.ctv_70.type, COLORS.ctv_high, source = ROIS.ctv_sb)
          ptv_70 = ROI.ROIExpanded(ROIS.ptv_70.name, ROIS.ptv_70.type, COLORS.ptv, source = ctv_70, margins = MARGINS.prostate_bone_match_expansion)
          bladder_ptv = ROI.ROIAlgebra(ROIS.z_bladder.name, ROIS.z_bladder.type, COLORS.bladder, sourcesA = [ROIS.bladder], sourcesB = [ptv_70], operator='Subtraction', marginsB = MARGINS.uniform_3mm_expansion)
          rectum_ptv = ROI.ROIAlgebra(ROIS.z_rectum.name, ROIS.z_rectum.type, COLORS.rectum, sourcesA = [ROIS.rectum], sourcesB = [ptv_70], operator='Subtraction', marginsB = MARGINS.uniform_2mm_expansion)
        else:
          if nodes == 'with':
            ctv_70 = ROI.ROIExpanded(ROIS.ctv_70.name, ROIS.ctv_70.type, COLORS.ctv_high, source = ROIS.ctv_sb)
            ptv_70 = ROI.ROIExpanded(ROIS.ptv_70.name, ROIS.ptv_70.type, COLORS.ptv, source = ctv_70, margins = MARGINS.prostate_bone_match_expansion)
          else:
            ctv_n = ROI.ROIExpanded(ROIS.ctv_n.name, ROIS.ctv_n.type, COLORS.pelvic_nodes, source = ROIS.gtv_n, margins = MARGINS.uniform_5mm_expansion)
            ptv_n = ROI.ROIExpanded(ROIS.ptv_n.name, ROIS.ptv_n.type, ROIS.ptv_n.color, source = ctv_n, margins = MARGINS.uniform_5mm_expansion)
            ptv_sb = ROI.ROIExpanded(ROIS.ptv_sb.name, ROIS.ptv_sb.type, ROIS.ptv_sb.color, source = ROIS.ctv_sb, margins = MARGINS.prostate_bone_match_expansion)
            ctv_70 = ROI.ROIAlgebra(ROIS.ctv_70.name, ROIS.ctv_70.type, COLORS.ctv_med, sourcesA = [ROIS.ctv_sb], sourcesB = [ctv_n], operator = 'Union')
            ptv_70 = ROI.ROIAlgebra(ROIS.ptv_70.name, ROIS.ptv_70.type, COLORS.ptv, sourcesA = [ptv_sb], sourcesB = [ptv_n], operator = 'Union', marginsA = MARGINS.zero , marginsB = MARGINS.zero)
            site.add_targets([ROIS.gtv_n, ctv_n, ptv_n, ptv_sb])
          ctv_56 = ROI.ROIAlgebra(ROIS.ctv_56.name, ROIS.ctv_56.type, COLORS.ctv_low, sourcesA = [ROIS.pelvic_nodes], sourcesB = [ptv_70], operator = 'Subtraction', marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          ptv_56 = ROI.ROIAlgebra(ROIS.ptv_56.name, ROIS.ptv_56.type, COLORS.ptv_low, sourcesA = [ROIS.pelvic_nodes], sourcesB = [ptv_70], operator = 'Subtraction', marginsA = MARGINS.uniform_5mm_expansion, marginsB = MARGINS.zero)
          ptv_56_70 = ROI.ROIAlgebra(ROIS.ptv_56_70.name, ROIS.ptv_56_70.type, COLORS.ptv_low, sourcesA = [ptv_56], sourcesB = [ptv_70], marginsA = MARGINS.zero, marginsB = MARGINS.zero)
          bladder_ptv = ROI.ROIAlgebra(ROIS.z_bladder.name, ROIS.z_bladder.type, COLORS.bladder, sourcesA = [ROIS.bladder], sourcesB = [ptv_70, ptv_56], operator='Subtraction', marginsB = MARGINS.uniform_3mm_expansion)
          rectum_ptv = ROI.ROIAlgebra(ROIS.z_rectum.name, ROIS.z_rectum.type, COLORS.rectum, sourcesA = [ROIS.rectum], sourcesB = [ptv_70, ptv_56], operator='Subtraction', marginsB = MARGINS.uniform_2mm_expansion)
          bowel_ptv = ROI.ROIAlgebra(ROIS.z_spc_bowel.name, ROIS.z_spc_bowel.type, COLORS.bowel_space, sourcesA = [ROIS.bowel_space], sourcesB = [ptv_70, ptv_56], operator='Subtraction', marginsB = MARGINS.uniform_3mm_expansion)
          wall_ptv_70 = ROI.ROIWall(ROIS.z_ptv_70_wall.name, ROIS.z_ptv_70_wall.type, COLORS.wall, ptv_70, 1, 0)
          wall_ptv_56_temp = ROI.ROIWall(ROIS.z_ptv_56_temp.name, ROIS.z_ptv_56_temp.type, COLORS.wall, ptv_56, 1, 0)
          wall_ptv_56 = ROI.ROIAlgebra(ROIS.z_ptv_56_wall.name, ROIS.z_ptv_56_wall.type, COLORS.wall, sourcesA = [wall_ptv_56_temp], sourcesB = [ptv_70, wall_ptv_70], operator='Subtraction', marginsB = MARGINS.zero)
          site.add_oars([bowel_ptv, ROIS.bowel_space, wall_ptv_70, wall_ptv_56_temp, wall_ptv_56])
          site.add_targets([ctv_56, ptv_56, ROIS.pelvic_nodes, ptv_56_70])
        # Common for bed (with or without nodes):
        site.add_oars([bladder_ptv, rectum_ptv])
        site.add_targets([ctv_70, ptv_70, ROIS.ctv_sb])
      else:
        ptv = ROI.ROIExpanded(ROIS.ptv_sb.name, ROIS.ptv_sb.type, COLORS.ptv_high, source = ROIS.ctv_sb, margins = MARGINS.prostate_bone_match_expansion)
        bladder_ptv = ROI.ROIAlgebra(ROIS.z_bladder.name, ROIS.z_bladder.type, COLORS.bladder, sourcesA = [ROIS.bladder], sourcesB = [ptv], operator='Subtraction', marginsB = MARGINS.uniform_3mm_expansion)
        rectum_ptv = ROI.ROIAlgebra(ROIS.z_rectum.name, ROIS.z_rectum.type, COLORS.rectum, sourcesA = [ROIS.rectum], sourcesB = [ptv], operator='Subtraction', marginsB = MARGINS.uniform_2mm_expansion)
        wall_ptv = ROI.ROIWall(ROIS.z_ptv_wall.name, ROIS.z_ptv_wall.type, COLORS.wall, ptv, 1, 0)
        site.add_oars([bladder_ptv, rectum_ptv, wall_ptv])
        site.add_targets([ptv, ROIS.ctv_sb])

    # Create all targets and OARs in RayStation:
    site.create_rois()
Exemplo n.º 20
0
# Target volumes:
gtv = ROI.ROI('GTV', 'Gtv', COLORS.gtv)
ctv = ROI.ROIExpanded('CTV',
                      'Ctv',
                      COLORS.ctv,
                      gtv,
                      margins=MARGINS.uniform_5mm_expansion)
ptv = ROI.ROIExpanded('PTV',
                      'Ptv',
                      COLORS.ptv,
                      ctv,
                      margins=MARGINS.uniform_5mm_expansion)
ctv_ext = ROI.ROIAlgebra('CTV',
                         'Ctv',
                         COLORS.ctv,
                         sourcesA=[gtv],
                         sourcesB=[external],
                         operator='Intersection',
                         marginsA=MARGINS.uniform_5mm_expansion,
                         marginsB=MARGINS.uniform_5mm_contraction)
ctv_underived = ROI.ROI('CTV', 'Ctv', COLORS.ctv)
igtv = ROI.ROI('IGTV', 'Gtv', COLORS.gtv)
igtv1 = ROI.ROI('IGTV1', 'Gtv', COLORS.gtv)
igtv2 = ROI.ROI('IGTV2', 'Gtv', COLORS.gtv)
igtv3 = ROI.ROI('IGTV3', 'Gtv', COLORS.gtv)
ictv = ROI.ROIExpanded('ICTV',
                       'Ctv',
                       COLORS.ctv,
                       igtv,
                       margins=MARGINS.uniform_5mm_expansion)
ictv1 = ROI.ROIExpanded('ICTV1',
                        'Ctv',
Exemplo n.º 21
0
 def __init__(self, pm, examination, ss, choices, site):
     # Choice 1: Region - prostate or bed?
     region = choices[1]
     if region == 'prostate':
         # Prostate:
         # Choice 2: Fractionation - normo or hypo?
         frac = choices[2]
         if frac == 'normo':
             # Conventionally fractionated prostate with vesicles (2.2Gy x 35):
             # Choice 3: Nodes - included or not?
             nodes = choices[3]
             # Targets:
             ctv_77 = ROI.ROIExpanded(ROIS.ctv_77.name,
                                      ROIS.ctv_77.type,
                                      COLORS.ctv_high,
                                      source=ROIS.prostate)
             ptv_77 = ROI.ROIExpanded(
                 ROIS.ptv_77.name,
                 ROIS.ptv_77.type,
                 COLORS.ptv_high,
                 source=ROIS.prostate,
                 margins=MARGINS.prostate_seed_expansion)
             # OARs:
             bladder_ptv = ROI.ROIAlgebra(
                 ROIS.z_bladder.name,
                 ROIS.z_bladder.type,
                 COLORS.bladder,
                 sourcesA=[ROIS.bladder],
                 sourcesB=[ptv_77],
                 operator='Subtraction',
                 marginsB=MARGINS.uniform_3mm_expansion)
             rectum_ptv = ROI.ROIAlgebra(
                 ROIS.z_rectum.name,
                 ROIS.z_rectum.type,
                 COLORS.rectum,
                 sourcesA=[ROIS.rectum],
                 sourcesB=[ptv_77],
                 operator='Subtraction',
                 marginsB=MARGINS.uniform_2mm_expansion)
             wall_ptv_77 = ROI.ROIWall(ROIS.z_ptv_77_wall.name,
                                       ROIS.z_ptv_77_wall.type, COLORS.wall,
                                       ptv_77, 0.5, 0)
             if nodes == 'no':
                 # Prostate only:
                 # Targets:
                 ctv_70 = ROI.ROIAlgebra(ROIS.ctv_70_sib.name,
                                         ROIS.ctv_70.type,
                                         COLORS.ctv_med,
                                         sourcesA=[ROIS.vesicles],
                                         sourcesB=[ptv_77],
                                         operator='Subtraction',
                                         marginsA=MARGINS.zero,
                                         marginsB=MARGINS.zero)
                 ptv_70 = ROI.ROIAlgebra(
                     ROIS.ptv_70_sib.name,
                     ROIS.ptv_70.type,
                     COLORS.ptv_med,
                     sourcesA=[ROIS.vesicles],
                     sourcesB=[ptv_77],
                     operator='Subtraction',
                     marginsA=MARGINS.uniform_8mm_expansion,
                     marginsB=MARGINS.zero)
                 ptv_70_77 = ROI.ROIAlgebra(
                     ROIS.ptv_70_77.name,
                     ROIS.ptv_70_77.type,
                     COLORS.ptv_low,
                     sourcesA=[ROIS.prostate],
                     sourcesB=[ROIS.vesicles],
                     marginsA=MARGINS.prostate_seed_expansion,
                     marginsB=MARGINS.uniform_8mm_expansion)
                 site.add_targets([ptv_70_77])
                 # OARs:
                 bladder_ptv.sourcesB.extend([ptv_70])
                 rectum_ptv.sourcesB.extend([ptv_70])
                 site.add_oars(DEF.prostate_oars +
                               [bladder_ptv, rectum_ptv, wall_ptv_77])
             elif nodes == 'with_node':
                 # Elective nodes (with positive node):
                 # Targets:
                 ctv_n = ROI.ROIExpanded(
                     ROIS.ctv_n.name,
                     ROIS.ctv_n.type,
                     COLORS.pelvic_nodes,
                     source=ROIS.gtv_n,
                     margins=MARGINS.uniform_5mm_expansion)
                 ptv_n = ROI.ROIExpanded(
                     ROIS.ptv_n.name,
                     ROIS.ptv_n.type,
                     ROIS.ptv_n.color,
                     source=ctv_n,
                     margins=MARGINS.prostate_lymph_nodes_seed_expansion)
                 ctv_70 = ROI.ROIAlgebra(ROIS.ctv_70_sib.name,
                                         ROIS.ctv_70.type,
                                         COLORS.ctv_med,
                                         sourcesA=[ROIS.vesicles, ctv_n],
                                         sourcesB=[ptv_77],
                                         operator='Subtraction',
                                         marginsA=MARGINS.zero,
                                         marginsB=MARGINS.zero)
                 ptv_semves = ROI.ROIAlgebra(
                     ROIS.ptv_semves.name,
                     ROIS.ptv_semves.type,
                     COLORS.ptv_med,
                     sourcesA=[ROIS.vesicles],
                     sourcesB=[ptv_77],
                     operator='Subtraction',
                     marginsA=MARGINS.uniform_8mm_expansion,
                     marginsB=MARGINS.zero)
                 ptv_70 = ROI.ROIAlgebra(ROIS.ptv_70_sib.name,
                                         ROIS.ptv_70_sib.type,
                                         ROIS.ptv_70_sib.color,
                                         sourcesA=[ptv_semves, ptv_n],
                                         sourcesB=[ptv_77],
                                         operator='Subtraction',
                                         marginsA=MARGINS.zero,
                                         marginsB=MARGINS.zero)
                 ptv_70_77 = ROI.ROIAlgebra(ROIS.ptv_70_77.name,
                                            ROIS.ptv_70_77.type,
                                            COLORS.ptv_low,
                                            sourcesA=[ptv_70],
                                            sourcesB=[ptv_77],
                                            marginsA=MARGINS.zero,
                                            marginsB=MARGINS.zero)
                 ptv_56 = ROI.ROIAlgebra(
                     ROIS.ptv_56.name,
                     ROIS.ptv_56.type,
                     COLORS.ptv_low,
                     sourcesA=[ROIS.pelvic_nodes],
                     sourcesB=[ptv_77, ptv_70],
                     operator='Subtraction',
                     marginsA=MARGINS.prostate_lymph_nodes_seed_expansion,
                     marginsB=MARGINS.zero)
                 ctv_56 = ROI.ROIAlgebra(ROIS.ctv_56.name,
                                         ROIS.ctv_56.type,
                                         COLORS.ctv_low,
                                         sourcesA=[ROIS.pelvic_nodes],
                                         sourcesB=[ptv_77, ptv_70],
                                         operator='Subtraction',
                                         marginsA=MARGINS.zero,
                                         marginsB=MARGINS.zero)
                 ptv_56_70_77 = ROI.ROIAlgebra(ROIS.ptv_56_70_77.name,
                                               ROIS.ptv_56_70_77.type,
                                               COLORS.ptv_low,
                                               sourcesA=[ptv_56, ptv_70],
                                               sourcesB=[ptv_77],
                                               marginsA=MARGINS.zero,
                                               marginsB=MARGINS.zero)
                 site.add_targets([
                     ROIS.gtv_n, ROIS.pelvic_nodes, ctv_n, ctv_56, ptv_n,
                     ptv_semves, ptv_56, ptv_70_77, ptv_56_70_77
                 ])
                 # OARs:
                 bladder_ptv.sourcesB.extend([ptv_70, ptv_56])
                 rectum_ptv.sourcesB.extend([ptv_70, ptv_56])
                 bowel_ptv = ROI.ROIAlgebra(
                     ROIS.z_spc_bowel.name,
                     ROIS.z_spc_bowel.type,
                     COLORS.bowel_space,
                     sourcesA=[ROIS.bowel_space],
                     sourcesB=[ptv_77, ptv_70, ptv_56],
                     operator='Subtraction',
                     marginsB=MARGINS.uniform_3mm_expansion)
                 wall_ptv_70_77 = ROI.ROIWall(ROIS.z_ptv_70_77_wall.name,
                                              ROIS.z_ptv_70_77_wall.type,
                                              COLORS.wall, ptv_70_77, 1, 0)
                 site.add_oars(DEF.prostate_nodes_oars +
                               [bladder_ptv, rectum_ptv, wall_ptv_77] +
                               [bowel_ptv, wall_ptv_70_77])
             elif nodes == 'with':
                 # Elective nodes:
                 # Targets:
                 ctv_70 = ROI.ROIAlgebra(ROIS.ctv_70_sib.name,
                                         ROIS.ctv_70.type,
                                         COLORS.ctv_med,
                                         sourcesA=[ROIS.vesicles],
                                         sourcesB=[ptv_77],
                                         operator='Subtraction',
                                         marginsA=MARGINS.zero,
                                         marginsB=MARGINS.zero)
                 ptv_70 = ROI.ROIAlgebra(
                     ROIS.ptv_70_sib.name,
                     ROIS.ptv_70.type,
                     COLORS.ptv_med,
                     sourcesA=[ROIS.vesicles],
                     sourcesB=[ptv_77],
                     operator='Subtraction',
                     marginsA=MARGINS.uniform_8mm_expansion,
                     marginsB=MARGINS.zero)
                 ptv_70_77 = ROI.ROIAlgebra(
                     ROIS.ptv_70_77.name,
                     ROIS.ptv_70_77.type,
                     COLORS.ptv_low,
                     sourcesA=[ROIS.prostate],
                     sourcesB=[ROIS.vesicles],
                     marginsA=MARGINS.prostate_seed_expansion,
                     marginsB=MARGINS.uniform_8mm_expansion)
                 ptv_56 = ROI.ROIAlgebra(
                     ROIS.ptv_56.name,
                     ROIS.ptv_56.type,
                     COLORS.ptv_low,
                     sourcesA=[ROIS.pelvic_nodes],
                     sourcesB=[ptv_77, ptv_70],
                     operator='Subtraction',
                     marginsA=MARGINS.prostate_lymph_nodes_seed_expansion,
                     marginsB=MARGINS.zero)
                 ctv_56 = ROI.ROIAlgebra(ROIS.ctv_56.name,
                                         ROIS.ctv_56.type,
                                         COLORS.ctv_low,
                                         sourcesA=[ROIS.pelvic_nodes],
                                         sourcesB=[ptv_77, ptv_70],
                                         operator='Subtraction',
                                         marginsA=MARGINS.zero,
                                         marginsB=MARGINS.zero)
                 ptv_56_70_77 = ROI.ROIAlgebra(ROIS.ptv_56_70_77.name,
                                               ROIS.ptv_56_70_77.type,
                                               COLORS.ptv_low,
                                               sourcesA=[ptv_56, ptv_70],
                                               sourcesB=[ptv_77],
                                               marginsA=MARGINS.zero,
                                               marginsB=MARGINS.zero)
                 site.add_targets([
                     ROIS.pelvic_nodes, ctv_56, ptv_56, ptv_70_77,
                     ptv_56_70_77
                 ])
                 # OARs:
                 bladder_ptv.sourcesB.extend([ptv_70, ptv_56])
                 rectum_ptv.sourcesB.extend([ptv_70, ptv_56])
                 bowel_ptv = ROI.ROIAlgebra(
                     ROIS.z_spc_bowel.name,
                     ROIS.z_spc_bowel.type,
                     COLORS.bowel_space,
                     sourcesA=[ROIS.bowel_space],
                     sourcesB=[ptv_77, ptv_70, ptv_56],
                     operator='Subtraction',
                     marginsB=MARGINS.uniform_3mm_expansion)
                 wall_ptv_70_77 = ROI.ROIWall(ROIS.z_ptv_70_77_wall.name,
                                              ROIS.z_ptv_70_77_wall.type,
                                              COLORS.wall, ptv_70_77, 1, 0)
                 site.add_oars(DEF.prostate_nodes_oars +
                               [bladder_ptv, rectum_ptv, wall_ptv_77] +
                               [bowel_ptv, wall_ptv_70_77])
             # Common ROIs for all conventional fractionation:
             site.add_targets([
                 ROIS.prostate, ROIS.vesicles, ctv_77, ctv_70, ptv_77,
                 ptv_70
             ])
         elif frac == 'hypo_60':
             # Hypofractionated prostate with vesicles (3 Gy x 20):
             # Targets:
             ptv_57_60 = ROI.ROIAlgebra(
                 ROIS.ptv_57_60.name,
                 ROIS.ptv_57_60.type,
                 COLORS.ptv_low,
                 sourcesA=[ROIS.prostate],
                 sourcesB=[ROIS.vesicles],
                 marginsA=MARGINS.prostate_seed_expansion,
                 marginsB=MARGINS.uniform_8mm_expansion)
             ptv_60 = ROI.ROIExpanded(
                 ROIS.ptv_60.name,
                 ROIS.ptv_60.type,
                 COLORS.ptv_high,
                 source=ROIS.prostate,
                 margins=MARGINS.prostate_seed_expansion)
             ptv_57 = ROI.ROIAlgebra(ROIS.ptv_57.name,
                                     ROIS.ptv_57.type,
                                     COLORS.ptv_med,
                                     sourcesA=[ptv_57_60],
                                     sourcesB=[ptv_60],
                                     operator='Subtraction',
                                     marginsA=MARGINS.zero,
                                     marginsB=MARGINS.zero)
             ctv_57_60 = ROI.ROIAlgebra(ROIS.ctv_57_60.name,
                                        ROIS.ctv_57_60.type,
                                        COLORS.ctv_low,
                                        sourcesA=[ROIS.prostate],
                                        sourcesB=[ROIS.vesicles],
                                        marginsA=MARGINS.zero,
                                        marginsB=MARGINS.zero)
             ctv_60 = ROI.ROIExpanded(ROIS.ctv_60.name,
                                      ROIS.ctv_60.type,
                                      COLORS.ctv_high,
                                      source=ROIS.prostate)
             ctv_57 = ROI.ROIAlgebra(ROIS.ctv_57.name,
                                     ROIS.ctv_57.type,
                                     COLORS.ctv_med,
                                     sourcesA=[ctv_57_60],
                                     sourcesB=[ptv_60],
                                     operator='Subtraction',
                                     marginsA=MARGINS.zero,
                                     marginsB=MARGINS.zero)
             site.add_targets([
                 ROIS.prostate, ROIS.vesicles, ctv_60, ctv_57, ctv_57_60,
                 ptv_57_60, ptv_60, ptv_57
             ])
             # OARs:
             bladder_ptv = ROI.ROIAlgebra(
                 ROIS.z_bladder.name,
                 ROIS.z_bladder.type,
                 COLORS.bladder,
                 sourcesA=[ROIS.bladder],
                 sourcesB=[ptv_60, ptv_57],
                 operator='Subtraction',
                 marginsB=MARGINS.uniform_3mm_expansion)
             rectum_ptv = ROI.ROIAlgebra(
                 ROIS.z_rectum.name,
                 ROIS.z_rectum.type,
                 COLORS.rectum,
                 sourcesA=[ROIS.rectum],
                 sourcesB=[ptv_60, ptv_57],
                 operator='Subtraction',
                 marginsB=MARGINS.uniform_2mm_expansion)
             wall_ptv_60 = ROI.ROIWall(ROIS.z_ptv_60_wall.name,
                                       ROIS.z_ptv_60_wall.type, COLORS.wall,
                                       ptv_60, 0.5, 0)
             wall_ptv_57_60 = ROI.ROIWall(ROIS.z_ptv_57_60_wall.name,
                                          ROIS.z_ptv_57_60_wall.type,
                                          COLORS.wall, ptv_57_60, 1, 0)
             site.add_oars(
                 DEF.prostate_oars +
                 [bladder_ptv, rectum_ptv, wall_ptv_60, wall_ptv_57_60])
         elif frac in ['hypo_55', 'palliative']:
             # STAMPEDE (2.75 Gy x 20) or palliative prostate (e.q. 3 Gy x 13):
             # Targets:
             ctv = ROI.ROIExpanded(ROIS.ctv.name,
                                   ROIS.ctv.type,
                                   COLORS.ctv_low,
                                   source=ROIS.prostate,
                                   margins=MARGINS.zero)
             if frac == 'hypo_55':
                 # Choice 3: Seed match or bone match?
                 match = choices[3]
                 if match == 'seeds':
                     # Seed match:
                     ptv = ROI.ROIExpanded(
                         ROIS.ptv.name,
                         ROIS.ptv.type,
                         COLORS.ptv_high,
                         source=ctv,
                         margins=MARGINS.prostate_seed_expansion)
                 else:
                     # Bone match:
                     ptv = ROI.ROIExpanded(
                         ROIS.ptv.name,
                         ROIS.ptv.type,
                         COLORS.ptv_high,
                         source=ctv,
                         margins=MARGINS.prostate_bone_match_expansion)
             elif frac == 'palliative':
                 # Assuming no markers:
                 ptv = ROI.ROIExpanded(
                     ROIS.ptv.name,
                     ROIS.ptv.type,
                     COLORS.ptv_high,
                     source=ctv,
                     margins=MARGINS.prostate_bone_match_expansion)
             site.add_targets([ROIS.prostate, ctv, ptv])
             # OARs:
             bladder_ptv = ROI.ROIAlgebra(
                 ROIS.z_bladder.name,
                 ROIS.z_bladder.type,
                 COLORS.bladder,
                 sourcesA=[ROIS.bladder],
                 sourcesB=[ptv],
                 operator='Subtraction',
                 marginsB=MARGINS.uniform_3mm_expansion)
             rectum_ptv = ROI.ROIAlgebra(
                 ROIS.z_rectum.name,
                 ROIS.z_rectum.type,
                 COLORS.rectum,
                 sourcesA=[ROIS.rectum],
                 sourcesB=[ptv],
                 operator='Subtraction',
                 marginsB=MARGINS.uniform_2mm_expansion)
             wall_ptv_55 = ROI.ROIWall(ROIS.z_ptv_wall.name,
                                       ROIS.z_ptv_wall.type, COLORS.wall,
                                       ptv, 1, 0)
             site.add_oars(DEF.prostate_palliative_oars +
                           [bladder_ptv, rectum_ptv, wall_ptv_55])
     else:
         # Prostate bed:
         # Choice 2: Fractionation - normo or hypo?
         frac = choices[2]
         # Fractionation:
         if frac == 'normo':
             # Conventional fractionation (2 Gy):
             # Choice 3: Nodes - included or not?
             nodes = choices[3]
             if nodes == 'no':
                 # Prostate bed only:
                 # Targets:
                 ctv_70 = ROI.ROIExpanded(ROIS.ctv_70.name,
                                          ROIS.ctv_70.type,
                                          COLORS.ctv_high,
                                          source=ROIS.ctv_sb)
                 ptv_70 = ROI.ROIExpanded(
                     ROIS.ptv_70.name,
                     ROIS.ptv_70.type,
                     COLORS.ptv,
                     source=ctv_70,
                     margins=MARGINS.prostate_bone_match_expansion)
                 # OARs:
                 bladder_ptv = ROI.ROIAlgebra(
                     ROIS.z_bladder.name,
                     ROIS.z_bladder.type,
                     COLORS.bladder,
                     sourcesA=[ROIS.bladder],
                     sourcesB=[ptv_70],
                     operator='Subtraction',
                     marginsB=MARGINS.uniform_3mm_expansion)
                 rectum_ptv = ROI.ROIAlgebra(
                     ROIS.z_rectum.name,
                     ROIS.z_rectum.type,
                     COLORS.rectum,
                     sourcesA=[ROIS.rectum],
                     sourcesB=[ptv_70],
                     operator='Subtraction',
                     marginsB=MARGINS.uniform_2mm_expansion)
                 site.add_oars(DEF.prostate_bed_oars +
                               [bladder_ptv, rectum_ptv])
             else:
                 # Elective nodes:
                 if nodes == 'with':
                     # Targets:
                     ctv_70 = ROI.ROIExpanded(ROIS.ctv_70.name,
                                              ROIS.ctv_70.type,
                                              COLORS.ctv_high,
                                              source=ROIS.ctv_sb)
                     ptv_70 = ROI.ROIExpanded(
                         ROIS.ptv_70.name,
                         ROIS.ptv_70.type,
                         COLORS.ptv,
                         source=ctv_70,
                         margins=MARGINS.prostate_bone_match_expansion)
                 else:
                     # Elective nodes (with positive node):
                     # Targets:
                     ctv_n = ROI.ROIExpanded(
                         ROIS.ctv_n.name,
                         ROIS.ctv_n.type,
                         COLORS.pelvic_nodes,
                         source=ROIS.gtv_n,
                         margins=MARGINS.uniform_5mm_expansion)
                     ptv_n = ROI.ROIExpanded(
                         ROIS.ptv_n.name,
                         ROIS.ptv_n.type,
                         ROIS.ptv_n.color,
                         source=ctv_n,
                         margins=MARGINS.uniform_5mm_expansion)
                     ptv_sb = ROI.ROIExpanded(
                         ROIS.ptv_sb.name,
                         ROIS.ptv_sb.type,
                         ROIS.ptv_sb.color,
                         source=ROIS.ctv_sb,
                         margins=MARGINS.prostate_bone_match_expansion)
                     ctv_70 = ROI.ROIAlgebra(ROIS.ctv_70.name,
                                             ROIS.ctv_70.type,
                                             COLORS.ctv_med,
                                             sourcesA=[ROIS.ctv_sb],
                                             sourcesB=[ctv_n],
                                             operator='Union')
                     ptv_70 = ROI.ROIAlgebra(ROIS.ptv_70.name,
                                             ROIS.ptv_70.type,
                                             COLORS.ptv,
                                             sourcesA=[ptv_sb],
                                             sourcesB=[ptv_n],
                                             operator='Union',
                                             marginsA=MARGINS.zero,
                                             marginsB=MARGINS.zero)
                     site.add_targets([ROIS.gtv_n, ctv_n, ptv_n, ptv_sb])
                 # Common for elective nodes (with or without positive node):
                 # Targets:
                 ctv_56 = ROI.ROIAlgebra(ROIS.ctv_56.name,
                                         ROIS.ctv_56.type,
                                         COLORS.ctv_low,
                                         sourcesA=[ROIS.pelvic_nodes],
                                         sourcesB=[ptv_70],
                                         operator='Subtraction',
                                         marginsA=MARGINS.zero,
                                         marginsB=MARGINS.zero)
                 ptv_56 = ROI.ROIAlgebra(
                     ROIS.ptv_56.name,
                     ROIS.ptv_56.type,
                     COLORS.ptv_low,
                     sourcesA=[ROIS.pelvic_nodes],
                     sourcesB=[ptv_70],
                     operator='Subtraction',
                     marginsA=MARGINS.uniform_5mm_expansion,
                     marginsB=MARGINS.zero)
                 ptv_56_70 = ROI.ROIAlgebra(ROIS.ptv_56_70.name,
                                            ROIS.ptv_56_70.type,
                                            COLORS.ptv_low,
                                            sourcesA=[ptv_56],
                                            sourcesB=[ptv_70],
                                            marginsA=MARGINS.zero,
                                            marginsB=MARGINS.zero)
                 site.add_targets(
                     [ROIS.pelvic_nodes, ctv_56, ptv_56, ptv_56_70])
                 # OARs:
                 bladder_ptv = ROI.ROIAlgebra(
                     ROIS.z_bladder.name,
                     ROIS.z_bladder.type,
                     COLORS.bladder,
                     sourcesA=[ROIS.bladder],
                     sourcesB=[ptv_70, ptv_56],
                     operator='Subtraction',
                     marginsB=MARGINS.uniform_3mm_expansion)
                 rectum_ptv = ROI.ROIAlgebra(
                     ROIS.z_rectum.name,
                     ROIS.z_rectum.type,
                     COLORS.rectum,
                     sourcesA=[ROIS.rectum],
                     sourcesB=[ptv_70, ptv_56],
                     operator='Subtraction',
                     marginsB=MARGINS.uniform_2mm_expansion)
                 bowel_ptv = ROI.ROIAlgebra(
                     ROIS.z_spc_bowel.name,
                     ROIS.z_spc_bowel.type,
                     COLORS.bowel_space,
                     sourcesA=[ROIS.bowel_space],
                     sourcesB=[ptv_70, ptv_56],
                     operator='Subtraction',
                     marginsB=MARGINS.uniform_3mm_expansion)
                 wall_ptv_70 = ROI.ROIWall(ROIS.z_ptv_70_wall.name,
                                           ROIS.z_ptv_70_wall.type,
                                           COLORS.wall, ptv_70, 1, 0)
                 wall_ptv_56_temp = ROI.ROIWall(ROIS.z_ptv_56_temp.name,
                                                ROIS.z_ptv_56_temp.type,
                                                COLORS.wall, ptv_56, 1, 0)
                 wall_ptv_56 = ROI.ROIAlgebra(
                     ROIS.z_ptv_56_wall.name,
                     ROIS.z_ptv_56_wall.type,
                     COLORS.wall,
                     sourcesA=[wall_ptv_56_temp],
                     sourcesB=[ptv_70, wall_ptv_70],
                     operator='Subtraction',
                     marginsB=MARGINS.zero)
                 site.add_oars(DEF.prostate_bed_nodes_oars +
                               [bladder_ptv, rectum_ptv] + [
                                   bowel_ptv, ROIS.bowel_space, wall_ptv_70,
                                   wall_ptv_56_temp, wall_ptv_56
                               ])
             # Common for all prostate bed (with or without nodes):
             site.add_targets([ROIS.ctv_sb, ctv_70, ptv_70])
         else:
             # Hypofractionated (palliative):
             # Targets:
             ptv = ROI.ROIExpanded(
                 ROIS.ptv_sb.name,
                 ROIS.ptv_sb.type,
                 COLORS.ptv_high,
                 source=ROIS.ctv_sb,
                 margins=MARGINS.prostate_bone_match_expansion)
             site.add_targets([ROIS.ctv_sb, ptv])
             # OARs:
             bladder_ptv = ROI.ROIAlgebra(
                 ROIS.z_bladder.name,
                 ROIS.z_bladder.type,
                 COLORS.bladder,
                 sourcesA=[ROIS.bladder],
                 sourcesB=[ptv],
                 operator='Subtraction',
                 marginsB=MARGINS.uniform_3mm_expansion)
             rectum_ptv = ROI.ROIAlgebra(
                 ROIS.z_rectum.name,
                 ROIS.z_rectum.type,
                 COLORS.rectum,
                 sourcesA=[ROIS.rectum],
                 sourcesB=[ptv],
                 operator='Subtraction',
                 marginsB=MARGINS.uniform_2mm_expansion)
             wall_ptv = ROI.ROIWall(ROIS.z_ptv_wall.name,
                                    ROIS.z_ptv_wall.type, COLORS.wall, ptv,
                                    1, 0)
             site.add_oars([bladder_ptv, rectum_ptv, wall_ptv])
     # Create all targets and OARs in RayStation:
     site.create_rois()