Ejemplo n.º 1
0
def plot_gamma_hist(gamma, percent, dist):
    valid_gamma = gamma[~np.isnan(gamma)]

    plt.hist(valid_gamma, 50, density=True)
    pass_ratio = np.sum(valid_gamma <= 1) / len(valid_gamma)

    plt.title(
        "Local Gamma ({0}%/{1}mm) | Percent Pass: {2:.2f} % | Mean Gamma: {3:.2f} | Max Gamma: {4:.2f}"
        .format(percent, dist, pass_ratio * 100, np.mean(valid_gamma),
                np.max(valid_gamma)))
Ejemplo n.º 2
0
def plot_insert(insert_x, insert_y, width, length, circle_centre):
    circle, ellipse = visual_circle_and_ellipse(insert_x, insert_y, width,
                                                length, circle_centre)

    plt.figure()
    plt.plot(insert_x, insert_y)
    plt.axis("equal")

    plt.plot(circle["x"], circle["y"])
    plt.title("Insert shape parameterisation")
    plt.xlabel("x (cm)")
    plt.ylabel("y (cm)")
    plt.grid(True)

    plt.plot(ellipse["x"], ellipse["y"])
Ejemplo n.º 3
0
def create_dvh(structure, dcm_struct, dcm_dose):
    structure_dose_values = find_dose_within_structure(structure, dcm_struct,
                                                       dcm_dose)
    hist = np.histogram(structure_dose_values, 100)
    freq = hist[0]
    bin_edge = hist[1]
    bin_mid = (bin_edge[1::] + bin_edge[:-1:]) / 2

    cumulative = np.cumsum(freq[::-1])
    cumulative = cumulative[::-1]
    bin_mid = np.append([0], bin_mid)

    cumulative = np.append(cumulative[0], cumulative)
    percent_cumulative = cumulative / cumulative[0] * 100

    plt.plot(bin_mid, percent_cumulative, label=structure)
    plt.title("DVH")
    plt.xlabel("Dose (Gy)")
    plt.ylabel("Relative Volume (%)")
Ejemplo n.º 4
0
def display_mu_density(
    grid, mu_density, grid_resolution=None, cmap=None, vmin=None, vmax=None
):
    """Prints a colour plot of the MU Density.

    Examples
    --------
    See `pymedphys.mudensity.calculate`_.
    """
    if grid_resolution is None:
        grid_resolution = grid["mlc"][1] - grid["mlc"][0]

    x, y = pcolormesh_grid(grid["mlc"], grid["jaw"], grid_resolution)
    plt.pcolormesh(x, y, mu_density, cmap=cmap, vmin=vmin, vmax=vmax)
    plt.colorbar()
    plt.title("MU density")
    plt.xlabel("MLC direction (mm)")
    plt.ylabel("Jaw direction (mm)")
    plt.axis("equal")
    plt.gca().invert_yaxis()
Ejemplo n.º 5
0
def plot_model(width_data, length_data, factor_data):

    i, j, k = create_transformed_mesh(width_data, length_data, factor_data)
    model_width, model_length, model_factor = i, j, k

    # model_width_mesh, model_length_mesh = np.meshgrid(
    #     model_width, model_length)

    vmin = np.nanmin(
        np.concatenate([model_factor.ravel(),
                        factor_data.ravel()]))
    vmax = np.nanmax(
        np.concatenate([model_factor.ravel(),
                        factor_data.ravel()]))
    # vrange = vmax - vmin

    plt.scatter(
        width_data,
        length_data,
        s=100,
        c=factor_data,
        cmap="viridis",
        vmin=vmin,
        vmax=vmax,
        zorder=2,
    )

    plt.colorbar()

    cs = plt.contour(model_width,
                     model_length,
                     model_factor,
                     20,
                     vmin=vmin,
                     vmax=vmax)

    plt.clabel(cs, cs.levels[::2], inline=True)

    plt.title("Insert model")
    plt.xlabel("width (cm)")
    plt.ylabel("length (cm)")
Ejemplo n.º 6
0
def plot_and_save_results(
    reference_mudensity,
    evaluation_mudensity,
    gamma,
    gamma_options,
    png_record_directory,
    header_text="",
    footer_text="",
):
    reference_filepath = png_record_directory.joinpath("reference.png")
    evaluation_filepath = png_record_directory.joinpath("evaluation.png")
    diff_filepath = png_record_directory.joinpath("diff.png")
    gamma_filepath = png_record_directory.joinpath("gamma.png")

    diff = evaluation_mudensity - reference_mudensity

    imageio.imwrite(reference_filepath, reference_mudensity)
    imageio.imwrite(evaluation_filepath, evaluation_mudensity)
    imageio.imwrite(diff_filepath, diff)
    imageio.imwrite(gamma_filepath, gamma)

    largest_mu_density = np.max(
        [np.max(evaluation_mudensity),
         np.max(reference_mudensity)])
    largest_diff = np.max(np.abs(diff))

    widths = [1, 1]
    heights = [0.5, 1, 1, 1, 0.4]
    gs_kw = dict(width_ratios=widths, height_ratios=heights)

    fig, axs = plt.subplots(5, 2, figsize=(10, 16), gridspec_kw=gs_kw)
    gs = axs[0, 0].get_gridspec()

    for ax in axs[0, 0:]:
        ax.remove()

    for ax in axs[1, 0:]:
        ax.remove()

    for ax in axs[4, 0:]:
        ax.remove()

    ax_header = fig.add_subplot(gs[0, :])
    ax_hist = fig.add_subplot(gs[1, :])
    ax_footer = fig.add_subplot(gs[4, :])

    ax_header.axis("off")
    ax_footer.axis("off")

    ax_header.text(0, 0, header_text, ha="left", wrap=True, fontsize=21)
    ax_footer.text(0,
                   1,
                   footer_text,
                   ha="left",
                   va="top",
                   wrap=True,
                   fontsize=6)

    plt.sca(axs[2, 0])
    pymedphys.mudensity.display(GRID,
                                reference_mudensity,
                                vmin=0,
                                vmax=largest_mu_density)
    axs[2, 0].set_title("Reference MU Density")

    plt.sca(axs[2, 1])
    pymedphys.mudensity.display(GRID,
                                evaluation_mudensity,
                                vmin=0,
                                vmax=largest_mu_density)
    axs[2, 1].set_title("Evaluation MU Density")

    plt.sca(axs[3, 0])
    pymedphys.mudensity.display(GRID,
                                diff,
                                cmap="seismic",
                                vmin=-largest_diff,
                                vmax=largest_diff)
    plt.title("Evaluation - Reference")

    plt.sca(axs[3, 1])
    pymedphys.mudensity.display(GRID, gamma, cmap="coolwarm", vmin=0, vmax=2)
    plt.title("Local Gamma | "
              f"{gamma_options['dose_percent_threshold']}%/"
              f"{gamma_options['distance_mm_threshold']}mm")

    plt.sca(ax_hist)
    plot_gamma_hist(
        gamma,
        gamma_options["dose_percent_threshold"],
        gamma_options["distance_mm_threshold"],
    )

    return fig
Ejemplo n.º 7
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()
Ejemplo n.º 8
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