Esempio n. 1
0
def batch_process(image_paths,
                  edge_lengths,
                  bb_diameter=8,
                  penumbra=2,
                  display_figure=True):
    bb_centres = []
    field_centres = []
    field_rotations = []

    for image_path in image_paths:
        bb_centre, field_centre, field_rotation = iview_find_bb_and_field(
            image_path,
            edge_lengths,
            bb_diameter=bb_diameter,
            penumbra=penumbra,
            display_figure=display_figure,
        )

        bb_centres.append(bb_centre)
        field_centres.append(field_centre)
        field_rotations.append(field_rotation)

        if display_figure:
            plt.show()

    data = np.concatenate(
        [bb_centres, field_centres,
         np.array(field_rotations)[:, None]],
        axis=1)
    return pd.DataFrame(
        data=data, columns=["BB x", "BB y", "Field x", "Field y", "Rotation"])
Esempio n. 2
0
def calc_calibration_points(prescans,
                            postscans,
                            alignments=None,
                            figures=False,
                            pixel_trim=0):
    """Returns calibration points based on dictionaries of prescans and postscans.

    The key of the dictionaries of images is to represent the dose calibration
    point. If the key cannot be converted into a float that image will be
    ignored.
    """
    keys = prescans.keys()
    assert keys == postscans.keys()

    calibration_points = {}

    if alignments is None:
        alignments = {key: None for key in keys}

    for key in keys:
        try:
            dose_value = float(key)
        except ValueError:
            warnings.warn(
                "{} does not appear to be a calibration image key. This will "
                "be skipped.")
            continue

        net_od, alignment = calc_net_od(prescans[key],
                                        postscans[key],
                                        alignment=alignments[key])

        if pixel_trim != 0:
            trim_ref = (slice(pixel_trim,
                              -pixel_trim), slice(pixel_trim, -pixel_trim))
            net_od = net_od[trim_ref]

        if figures:
            plt.figure()
            plt.imshow(net_od)
            plt.show()

        calibration_points[dose_value] = np.median(net_od)
        alignments[key] = alignment

    return calibration_points, alignments
Esempio n. 3
0
def plot_results(
    grid_xx, grid_yy, logfile_mu_density, mosaiq_mu_density, diff_colour_scale=0.1
):
    min_val = np.min([logfile_mu_density, mosaiq_mu_density])
    max_val = np.max([logfile_mu_density, mosaiq_mu_density])

    plt.figure()
    plt.pcolormesh(grid_xx, grid_yy, logfile_mu_density, vmin=min_val, vmax=max_val)
    plt.colorbar()
    plt.title("Logfile MU density")
    plt.xlabel("MLC direction (mm)")
    plt.ylabel("Jaw direction (mm)")
    plt.gca().invert_yaxis()

    plt.figure()
    plt.pcolormesh(grid_xx, grid_yy, mosaiq_mu_density, vmin=min_val, vmax=max_val)
    plt.colorbar()
    plt.title("Mosaiq MU density")
    plt.xlabel("MLC direction (mm)")
    plt.ylabel("Jaw direction (mm)")
    plt.gca().invert_yaxis()

    scaled_diff = (logfile_mu_density - mosaiq_mu_density) / max_val

    plt.figure()
    plt.pcolormesh(
        grid_xx,
        grid_yy,
        scaled_diff,
        vmin=-diff_colour_scale / 2,
        vmax=diff_colour_scale / 2,
    )
    plt.colorbar(label="Limited colour range = {}".format(diff_colour_scale / 2))
    plt.title("(Logfile - Mosaiq MU density) / Maximum MU Density")
    plt.xlabel("MLC direction (mm)")
    plt.ylabel("Jaw direction (mm)")
    plt.gca().invert_yaxis()

    plt.show()

    plt.figure()
    plt.pcolormesh(
        grid_xx, grid_yy, scaled_diff, vmin=-diff_colour_scale, vmax=diff_colour_scale
    )
    plt.colorbar(label="Limited colour range = {}".format(diff_colour_scale))
    plt.title("(Logfile - Mosaiq MU density) / Maximum MU Density")
    plt.xlabel("MLC direction (mm)")
    plt.ylabel("Jaw direction (mm)")
    plt.gca().invert_yaxis()

    plt.show()

    absolute_range = np.max([-np.min(scaled_diff), np.max(scaled_diff)])

    plt.figure()
    plt.pcolormesh(
        grid_xx, grid_yy, scaled_diff, vmin=-absolute_range, vmax=absolute_range
    )
    plt.colorbar(label="No limited colour range")
    plt.title("(Logfile - Mosaiq MU density) / Maximum MU Density")
    plt.xlabel("MLC direction (mm)")
    plt.ylabel("Jaw direction (mm)")
    plt.gca().invert_yaxis()

    plt.show()
Esempio n. 4
0
def optimise_bb_centre(
    field: imginterp.Field,
    bb_diameter,
    edge_lengths,
    penumbra,
    field_centre,
    field_rotation,
    pylinac_tol=0.2,
    debug=True,
):
    centralised_field = utilities.create_centralised_field(
        field, field_centre, field_rotation)
    to_minimise_edge_agreement = create_bb_to_minimise(centralised_field,
                                                       bb_diameter)
    bb_bounds = define_bb_bounds(bb_diameter, edge_lengths, penumbra)

    bb_centre_in_centralised_field = bb_basinhopping(
        to_minimise_edge_agreement, bb_bounds)

    if check_if_at_bounds(bb_centre_in_centralised_field, bb_bounds):
        raise ValueError("BB found at bounds, likely incorrect")

    bb_centre = utilities.transform_point(bb_centre_in_centralised_field,
                                          field_centre, field_rotation)

    verification_repeat = bb_basinhopping(to_minimise_edge_agreement,
                                          bb_bounds)
    repeat_agreement = np.abs(verification_repeat -
                              bb_centre_in_centralised_field)

    if np.any(repeat_agreement > BB_REPEAT_TOL):
        bb_repeated = utilities.transform_point(verification_repeat,
                                                field_centre, field_rotation)
        if debug:
            reporting.image_analysis_figure(
                field.x,
                field.y,
                field.img,
                bb_centre,
                field_centre,
                field_rotation,
                bb_diameter,
                edge_lengths,
                penumbra,
            )
            plt.title("First iteration")

            reporting.image_analysis_figure(
                field.x,
                field.y,
                field.img,
                bb_repeated,
                field_centre,
                field_rotation,
                bb_diameter,
                edge_lengths,
                penumbra,
            )
            plt.title("Second iteration")
            plt.show()
        raise ValueError("BB centre not able to be consistently determined\n"
                         f"  First iteration:  {bb_centre}\n"
                         f"  Second iteration: {bb_repeated}")

    if not pylinac_tol is None:
        try:
            pylinac_result = pylinac.run_wlutz(
                field,
                edge_lengths,
                penumbra,
                field_centre,
                field_rotation,
                find_bb=True,
                pylinac_versions=("v2.2.6", ),
            )
        except ValueError:
            raise ValueError(
                "While comparing result to PyLinac an error was raised")
            # warnings.simplefilter("always", UserWarning)
            # warnings.warn(
            #     "This iteration has not been checked against pylinac. "
            #     "When attempting to run pylinac instead an error was "
            #     f"raised. Pylinac raised the following error:\n\n{e}\n"
            # )
            # pylinac = {}

        try:
            pylinac_2_2_6_out_of_tol = np.any(
                np.abs(
                    np.array(pylinac_result["v2.2.6"]["bb_centre"]) -
                    bb_centre) > pylinac_tol)
            if pylinac_2_2_6_out_of_tol:
                raise pylinac.PylinacComparisonDeviation(
                    "The determined bb centre deviates from pylinac more "
                    "than the defined tolerance")
        except KeyError:
            pass

    return bb_centre
Esempio n. 5
0
 def plot(self):
     """Plot the profile."""
     plt.plot(self.values)
     plt.show()