Esempio n. 1
0
def run_test(
    field_centre,
    field_side_lengths,
    field_penumbra,
    field_rotation,
    bb_centre,
    bb_diameter,
    bb_max_attenuation,
):

    x, y, img = create_test_image(
        field_centre,
        field_side_lengths,
        field_penumbra,
        field_rotation,
        bb_centre,
        bb_diameter,
        bb_max_attenuation,
    )

    (
        determined_bb_centre,
        determined_field_centre,
        determined_field_rotation,
    ) = pymedphys.wlutz.find_field_and_bb(
        x,
        y,
        img,
        field_side_lengths,
        bb_diameter,
        penumbra=field_penumbra,
        pylinac_tol=None,
    )

    try:
        assert np.allclose(bb_centre, determined_bb_centre, atol=0.001)
        assert np.allclose(field_centre, determined_field_centre, atol=0.001)
        assert np.allclose(field_rotation,
                           determined_field_rotation,
                           atol=0.01)

    except:
        reporting.image_analysis_figure(
            x,
            y,
            img,
            determined_bb_centre,
            determined_field_centre,
            determined_field_rotation,
            bb_diameter,
            field_side_lengths,
            field_penumbra,
        )
        raise
Esempio n. 2
0
def optimise_rotation(field, centre, edge_lengths, penumbra):
    to_minimise = create_rotation_only_minimiser(field, centre, edge_lengths,
                                                 penumbra)
    result = scipy.optimize.basinhopping(
        to_minimise,
        INITIAL_ROTATION,
        T=1,
        niter=BASINHOPPING_NITER,
        niter_success=5,
        stepsize=90,
        minimizer_kwargs={"method": "L-BFGS-B"},
    )

    predicted_rotation = result.x[0]

    if np.allclose(*edge_lengths, rtol=0.001, atol=0.001):
        modulo_rotation = predicted_rotation % 90
        if modulo_rotation >= 45:
            modulo_rotation = modulo_rotation - 90
        return modulo_rotation

    modulo_rotation = predicted_rotation % 180
    if modulo_rotation >= 90:
        modulo_rotation = modulo_rotation - 180
    return modulo_rotation
Esempio n. 3
0
def check_centre_close(verification_centre, predicted_centre):
    if not np.allclose(
            verification_centre, predicted_centre, rtol=0.01, atol=0.01):
        raise ValueError(
            "Field centre not able to be reproducibly determined.\n"
            f"    Verification Centre: {verification_centre}\n"
            f"    Predicted Centre: {predicted_centre}\n")
Esempio n. 4
0
def check_aspect_ratio(edge_lengths):
    if not np.allclose(*edge_lengths):
        if np.min(edge_lengths) > 0.95 * np.max(edge_lengths):
            raise ValueError(
                "For non-square rectangular fields, "
                "to accurately determine the rotation, "
                "need to have the small edge be less than 95% of the long edge."
            )
Esempio n. 5
0
def advanced_debugging():
    config = get_config()

    st.sidebar.markdown("# Advanced Debugging")
    if st.sidebar.button("Compare Baseline to Output Directory"):
        """
        ## Comparing Results to Baseline
        """

        baseline_directory = pathlib.Path(
            config["debug"]["baseline_directory"]).resolve()

        png_baseline_directory = baseline_directory.joinpath("png")

        baseline_png_paths = [
            path for path in (png_baseline_directory.rglob("*"))
            if path.is_file()
        ]

        relative_png_paths = [
            path.relative_to(png_baseline_directory)
            for path in baseline_png_paths
        ]

        output_dir = pathlib.Path(config["output"]["png_directory"]).resolve()

        evaluation_png_paths = [
            output_dir.joinpath(path) for path in relative_png_paths
        ]

        for baseline, evaluation in zip(baseline_png_paths,
                                        evaluation_png_paths):

            f"### {baseline.parent.name}/{baseline.name}"

            f"`{baseline}`\n\n**vs**\n\n`{evaluation}`"

            baseline_image = imageio.imread(baseline)

            try:
                evaluation_image = imageio.imread(evaluation)
            except FileNotFoundError as e:
                """
                #### File was not found
                """
                st.write(e)
                f"""
                For debugging purposes, here are all the files that
                were found within {str(output_dir)}
                """

                [str(path) for path in output_dir.rglob("*") if path.is_file()]

                return

            agree = np.allclose(baseline_image, evaluation_image)
            f"Images Agree: `{agree}`"
Esempio n. 6
0
def check_rotation_close(edge_lengths, verification_rotation,
                         predicted_rotation):
    if np.allclose(*edge_lengths):
        diff = (verification_rotation - predicted_rotation) % 90
        if not (diff < 0.3 or diff > 89.7):
            raise ValueError(
                _rotation_error_string(verification_rotation,
                                       predicted_rotation, diff))
    else:
        diff = (verification_rotation - predicted_rotation) % 180
        if not (diff < 0.3 or diff > 179.7):
            raise ValueError(
                _rotation_error_string(verification_rotation,
                                       predicted_rotation, diff))
Esempio n. 7
0
def read_prs(file_name):
    """
    Read native Profiler data file and return dose profiles.

    Parameters
    ----------
    file_name : string
        | file name of Profiler file including path

    Returns
    -------
    Profiler : named tuple
        | Profiler.cax = float dose at central axis
        | Profiler.x = list of (x, dose) tuples
        | Profiler.y = list of (y, dose) tuples
    """

    Profiler = namedtuple("Profiler", ["cax", "x", "y"])

    with open(file_name) as profiler_file:
        for row in profiler_file.readlines():
            contents = row
            if contents[:11] == "Calibration" and "File" not in contents:
                calibs = np.array(contents.split())[1:].astype(float)
            elif contents[:5] == "Data:":
                counts = np.array(contents.split()[5:145]).astype(float)
            elif contents[:15] == "Dose Per Count:":
                dose_per_count = float(contents.split()[-1])
        assert (len(calibs)) == (len(counts)) == 140
        assert dose_per_count > 0.0
    dose = counts * dose_per_count * calibs

    y_vals = [-16.4 + 0.4 * i for i in range(83)]
    x_vals = [-11.2 + 0.4 * i for i in range(57)]

    x_prof = list(zip(y_vals, dose[:57]))
    y_prof = list(zip(x_vals, dose[57:]))

    assert np.allclose(y_prof[41][1], x_prof[28][1])
    cax_dose = y_prof[41][1]

    return Profiler(cax_dose, x_prof, y_prof)