Ejemplo n.º 1
0
def create_transformed_mesh(width_data, length_data, factor_data):
    """Return factor data meshgrid."""
    x = np.arange(
        np.floor(np.min(width_data)) - 1,
        np.ceil(np.max(width_data)) + 1, 0.1)
    y = np.arange(
        np.floor(np.min(length_data)) - 1,
        np.ceil(np.max(length_data)) + 1, 0.1)

    xx, yy = np.meshgrid(x, y)

    zz = spline_model_with_deformability(
        xx,
        convert2_ratio_perim_area(xx, yy),
        width_data,
        convert2_ratio_perim_area(width_data, length_data),
        factor_data,
    )

    zz[xx > yy] = np.nan

    no_data_x = np.all(np.isnan(zz), axis=0)
    no_data_y = np.all(np.isnan(zz), axis=1)

    x = x[np.invert(no_data_x)]
    y = y[np.invert(no_data_y)]

    zz = zz[np.invert(no_data_y), :]
    zz = zz[:, np.invert(no_data_x)]

    return x, y, zz
Ejemplo n.º 2
0
def get_grid(
    max_leaf_gap=__DEFAULT_MAX_LEAF_GAP,
    grid_resolution=__DEFAULT_GRID_RESOLUTION,
    leaf_pair_widths=__DEFAULT_LEAF_PAIR_WIDTHS,
):
    """Get the MU Density grid for plotting purposes.

    Examples
    --------
    See `pymedphys.mudensity.calculate`_.
    """

    leaf_pair_widths = np.array(leaf_pair_widths)

    grid = dict()

    grid["mlc"] = np.arange(
        -max_leaf_gap / 2, max_leaf_gap / 2 + grid_resolution, grid_resolution
    ).astype("float")

    _, top_of_reference_leaf = _determine_leaf_centres(leaf_pair_widths)
    grid_reference_position = _determine_reference_grid_position(
        top_of_reference_leaf, grid_resolution
    )

    # It might be better to use round instead of ceil here.
    total_leaf_widths = np.sum(leaf_pair_widths)
    top_grid_pos = (
        np.ceil((total_leaf_widths / 2 - grid_reference_position) / grid_resolution)
        * grid_resolution
        + grid_reference_position
    )

    bot_grid_pos = (
        grid_reference_position
        - np.ceil((total_leaf_widths / 2 + grid_reference_position) / grid_resolution)
        * grid_resolution
    )

    grid["jaw"] = np.arange(
        bot_grid_pos, top_grid_pos + grid_resolution, grid_resolution
    )

    return grid
Ejemplo n.º 3
0
def calculate_coordinates_shell_2d(distance, distance_step_size):
    """Create points along the circumference of a circle. The spacing
    between points is not larger than the defined distance_step_size
    """
    amount_to_check = np.ceil(2 * np.pi * distance / distance_step_size).astype(int) + 1
    theta = np.linspace(0, 2 * np.pi, amount_to_check + 1)[:-1:]
    x_coords = distance * np.cos(theta)
    y_coords = distance * np.sin(theta)

    return (x_coords, y_coords)
Ejemplo n.º 4
0
def calculate_coordinates_shell_3d(distance, distance_step_size):
    """Create points along the surface of a sphere (a shell) where no gap
    between points is larger than the defined distance_step_size"""

    number_of_rows = np.ceil(np.pi * distance / distance_step_size).astype(int) + 1

    elevation = np.linspace(0, np.pi, number_of_rows)
    row_radii = distance * np.sin(elevation)
    row_circumference = 2 * np.pi * row_radii
    amount_in_row = np.ceil(row_circumference / distance_step_size).astype(int) + 1

    x_coords = []
    y_coords = []
    z_coords = []
    for i, phi in enumerate(elevation):
        azimuth = np.linspace(0, 2 * np.pi, amount_in_row[i] + 1)[:-1:]
        x_coords.append(distance * np.sin(phi) * np.cos(azimuth))
        y_coords.append(distance * np.sin(phi) * np.sin(azimuth))
        z_coords.append(distance * np.cos(phi) * np.ones_like(azimuth))

    return (np.hstack(x_coords), np.hstack(y_coords), np.hstack(z_coords))
Ejemplo n.º 5
0
def define_rotation_field_points_at_origin(edge_lengths, penumbra):
    x_half_range = edge_lengths[0] / 2 + penumbra / 2
    y_half_range = edge_lengths[1] / 2 + penumbra / 2

    num_x = np.ceil(x_half_range * 2 * 8) + 1
    num_y = np.ceil(y_half_range * 2 * 8) + 1

    x = np.linspace(-x_half_range, x_half_range, int(num_x))
    y = np.linspace(-y_half_range, y_half_range, int(num_y))

    xx, yy = np.meshgrid(x, y)
    xx_flat = np.ravel(xx)
    yy_flat = np.ravel(yy)

    inside = np.logical_and((np.abs(xx_flat) < x_half_range),
                            (np.abs(yy_flat) < y_half_range))

    xx_flat = xx_flat[np.invert(inside)]
    yy_flat = yy_flat[np.invert(inside)]

    return xx_flat, yy_flat
Ejemplo n.º 6
0
def _calc_time_steps(positions, grid_resolution, min_step_per_pixel):
    maximum_travel = []
    for _, value in positions.items():
        for _, (start, end) in value.items():
            maximum_travel.append(np.max(np.abs(end - start)))

    maximum_travel = np.max(maximum_travel)
    number_of_pixels = np.ceil(maximum_travel / grid_resolution)
    time_steps = number_of_pixels * min_step_per_pixel

    if time_steps < 10:
        time_steps = 10

    return time_steps
Ejemplo n.º 7
0
def minimize_junction_X(amplitude, peaks, peak_type, dx):
    print("Analyzing X jaws...")

    amp_prev = 0
    amp_filt_prev = 0

    fig = plt.figure(figsize=(10, 6))  # create the plot

    kk = 0  # counter for figure generation
    for j in range(0, amplitude.shape[1] - 1):
        for k in range(j + 1,
                       amplitude.shape[1]):  # looping through remaining images
            amp_base_res = signal.convolve(amplitude[:, j],
                                           amplitude[:, j],
                                           mode="full")
            amp_base_res = signal.resample(
                amp_base_res / np.amax(amp_base_res),
                int(np.ceil(len(amp_base_res) / 2)),
            )

            amp_overlay_res = signal.convolve(amplitude[:, k],
                                              amplitude[:, k],
                                              mode="full")
            amp_overlay_res = signal.resample(
                amp_overlay_res / np.amax(amp_overlay_res),
                int(np.ceil(len(amp_overlay_res) / 2)),
            )
            peak1, _ = find_peaks(amp_base_res, prominence=0.5)
            peak2, _ = find_peaks(amp_overlay_res, prominence=0.5)

            if (abs(peak2 - peak1) < 2500
                ):  # if the two peaks are close together proceeed to analysis
                kk = kk + 1  # incrementing the figure generator
                cumsum_prev = 1e7
                if peak2 < peak1:  # this guarantee that we always slide the overlay
                    amp_base_res = amplitude[:, k]
                    amp_overlay_res = amplitude[:, j]
                else:
                    amp_base_res = amplitude[:, j]
                    amp_overlay_res = amplitude[:, k]

                if peak_type[j] == 0:
                    inc = -1
                else:
                    inc = 1
                for i in range(0, inc * 80, inc * 1):
                    # x = np.linspace(0, 0 + (len(amp_base_res) * dx), len(amplitude),
                    #                 endpoint=False)  # definition of the distance axis
                    amp_overlay_res_roll = np.roll(amp_overlay_res, i)

                    # amplitude is the vector to analyze +-500 samples from the center
                    amp_tot = (
                        amp_base_res[peaks[j] - 1000:peaks[j] + 1000] +
                        amp_overlay_res_roll[peaks[j] - 1000:peaks[j] + 1000]
                    )  # divided by 2 to normalize
                    # xsel = x[peaks[j] - 1000:peaks[j] + 1000]

                    amp_filt = rm.running_mean(amp_tot, 281)
                    cumsum = np.sum(np.abs(amp_tot - amp_filt))

                    if (  # pylint: disable = no-else-break
                            cumsum > cumsum_prev):  # then we went too far
                        break
                    else:
                        amp_prev = amp_tot
                        amp_filt_prev = amp_filt
                        cumsum_prev = cumsum

                ax = fig.add_subplot(amplitude.shape[1] - 1, 1, kk)
                ax.plot(amp_prev)
                ax.plot(amp_filt_prev)
                if kk == 1:
                    ax.set_title("Minimization result", fontsize=16)
                if (kk == amplitude.shape[1] - 1
                    ):  # if we reach the final plot the add the x axis label
                    ax.set_xlabel("distance [mm]")

                ax.set_ylabel("amplitude")
                # ax.annotate('delta=' + str(abs(i - inc * 1) * dx) + ' mm', xy=(2, 1), xycoords='axes fraction',
                #             xytext=(.35, .10))
                if peaks[kk - 1] != 0:
                    ax.annotate(
                        "delta=" + str(abs(i - inc * 1) * dx) + " mm",
                        xy=(2, 1),
                        xycoords="axes fraction",
                        xytext=(0.35, 0.10),
                    )
                else:
                    ax.annotate(
                        "delta= 0 mm (NO PEAK FOUND)",
                        xy=(2, 1),
                        xycoords="axes fraction",
                        xytext=(0.35, 0.10),
                    )

    return fig
Ejemplo n.º 8
0
def peak_find(ampl_resamp, dx):
    peak_figs = []
    peaks = []
    peak_type = []
    for j in range(0, ampl_resamp.shape[1] - 1):
        amp_base_res = signal.convolve(ampl_resamp[:, j],
                                       ampl_resamp[:, j],
                                       mode="full")
        amp_base_res = signal.resample(amp_base_res / np.amax(amp_base_res),
                                       int(np.ceil(len(amp_base_res) / 2)))
        for k in range(j + 1, ampl_resamp.shape[1]):
            amp_overlay_res = signal.convolve(ampl_resamp[:, k],
                                              ampl_resamp[:, k],
                                              mode="full")
            amp_overlay_res = signal.resample(
                amp_overlay_res / np.amax(amp_overlay_res),
                int(np.ceil(len(amp_overlay_res) / 2)),
            )
            # amp_overlay_res = signal.savgol_filter(ampl_resamp[:, k], 1501, 1)

            peak1, _ = find_peaks(amp_base_res, prominence=0.5)
            peak2, _ = find_peaks(amp_overlay_res, prominence=0.5)

            if (
                    abs(peak2 - peak1) < 2500
            ):  # if the two peaks are separated the two fields are not adjacent.
                amp_peak = ampl_resamp[:, j] + ampl_resamp[:, k]
                x = np.linspace(
                    0,
                    0 + (len(amp_peak) * dx / 10),
                    len(amp_peak),
                    endpoint=False)  # definition of the distance axis

                peak_pos, _ = find_peaks(
                    signal.savgol_filter(
                        amp_peak[min(peak1[0], peak2[0]
                                     ):max(peak1[0], peak2[0])],
                        201,
                        3,
                    ),
                    prominence=0.010,
                )
                pos_prominence = signal.peak_prominences(
                    signal.savgol_filter(
                        amp_peak[min(peak1[0], peak2[0]
                                     ):max(peak1[0], peak2[0])],
                        201,
                        3,
                    ),
                    peak_pos,
                )
                # print('#peaks pos det=', len(peak_pos), peak_pos)
                # print('#pos peaks prominence=', pos_prominence[0])
                peak_neg, _ = find_peaks(
                    signal.savgol_filter(
                        -amp_peak[min(peak1[0], peak2[0]
                                      ):max(peak1[0], peak2[0])],
                        201,
                        3,
                    ),
                    prominence=0.010,
                )
                neg_prominence = signal.peak_prominences(
                    signal.savgol_filter(
                        -amp_peak[min(peak1[0], peak2[0]
                                      ):max(peak1[0], peak2[0])],
                        201,
                        3,
                    ),
                    peak_neg,
                )
                # print('#peaks neg det=',len(peak_neg),peak_neg)
                # print('#neg peaks prominence=', neg_prominence[0])
                # we now need to select the peak with the largest prominence positve or negative
                # we add all the peaks and prominences toghether
                peaks_all = np.concatenate((peak_pos, peak_neg), axis=None)
                prom_all = np.concatenate(
                    (pos_prominence[0], neg_prominence[0]), axis=None)
                # print('all peaks',peaks_all,prom_all)

                if peaks_all.size != 0:
                    peak = peaks_all[np.argmax(prom_all)]
                    if peak in peak_pos:
                        peak_type.append(1)
                        peaks.append(min(peak1[0], peak2[0]) + peak)
                        # print('pos peak')
                    elif peak in peak_neg:
                        peak_type.append(0)
                        peaks.append(min(peak1[0], peak2[0]) + peak)
                        # print('neg peak')

                    fig = plt.figure(figsize=(10, 6))
                    plt.plot(x, amp_peak, label="Total amplitude profile")
                    plt.plot(
                        x[min(peak1[0], peak2[0]) + peak],
                        amp_peak[min(peak1[0], peak2[0]) + peak],
                        "x",
                        label="Peaks detected",
                    )
                    plt.ylabel("amplitude [a.u.]")
                    plt.xlabel("distance [mm]")
                    plt.legend()
                    fig.suptitle("Junctions", fontsize=16)
                    peak_figs.append(fig)

                elif peaks_all.size == 0:
                    peaks.append(0)
                    peak_type.append(0)
                    print("no peak has been found")
                    fig = plt.figure(figsize=(10, 6))
                    plt.plot(x, amp_peak, label="Total amplitude profile")
                    # plt.plot(x[min(peak1[0], peak2[0]) + peak], amp_peak[min(peak1[0], peak2[0]) + peak], "x",
                    #          label='Peaks detected')
                    plt.ylabel("amplitude [a.u.]")
                    plt.xlabel("distance [mm]")
                    plt.legend()
                    fig.suptitle("Junctions", fontsize=16)
                    peak_figs.append(fig)

            # else:
            # print(j, k, 'the data is not contiguous finding another curve in dataset')

    # print('peaks_here=',peaks)
    return peaks, peak_type, peak_figs
Ejemplo n.º 9
0
def minimize_junction_fieldrot(
    amplitude, peaks, peak_type, dx, profilename
):  # minimize junction for field rotations is done differently given the shape of the fields
    print("Field rotation jaw analysis...")
    # print('number of peaks=', peaks)
    amp_prev = 0
    amp_filt_prev = 0

    fig = plt.figure(figsize=(10, 6))  # create the plot

    kk = 1  # counter for figure generation
    for j in range(0, amplitude.shape[1] - 1):
        for k in range(j + 1,
                       amplitude.shape[1]):  # looping through remaining images
            amp_base_res = signal.convolve(amplitude[:, j],
                                           amplitude[:, j],
                                           mode="full")
            amp_base_res = signal.resample(
                amp_base_res / np.amax(amp_base_res),
                int(np.ceil(len(amp_base_res) / 2)),
            )

            amp_overlay_res = signal.convolve(amplitude[:, k],
                                              amplitude[:, k],
                                              mode="full")
            amp_overlay_res = signal.resample(
                amp_overlay_res / np.amax(amp_overlay_res),
                int(np.ceil(len(amp_overlay_res) / 2)),
            )
            # amp_base_res = signal.savgol_filter(amplitude[:, j], 1001, 3)
            # amp_overlay_res = signal.savgol_filter(amplitude[:, k], 1001, 3)
            # peak1, _ = find_peaks(amp_base_res, prominence=0.5)
            # peak2, _ = find_peaks(amp_overlay_res, prominence=0.5)

            cumsum_prev = 1e7
            amp_base_res = amplitude[:, j]
            amp_overlay_res = amplitude[:, k]

            if peak_type[j] == 0:
                inc = -1
            else:
                inc = 1
            for i in range(0, inc * 80, inc * 1):
                # x = np.linspace(0, 0 + (len(amp_base_res) * dx), len(amplitude),
                #                 endpoint=False)  # definition of the distance axis
                amp_overlay_res_roll = np.roll(amp_overlay_res, i)

                # amplitude is the vector to analyze +-500 samples from the center
                amp_tot = (
                    amp_base_res[peaks[j] - 1000:peaks[j] + 1000] +
                    amp_overlay_res_roll[peaks[j] - 1000:peaks[j] + 1000]
                )  # divided by 2 to normalize
                # xsel = x[peaks[j] - 1000:peaks[j] + 1000]
                amp_filt = rm.running_mean(amp_tot, 281)

                cumsum = np.sum(np.abs(amp_tot - amp_filt))

                if (  # pylint: disable = no-else-break
                        cumsum > cumsum_prev):  # then we went too far
                    ax = fig.add_subplot(amplitude.shape[1] - 1, 1, kk)

                    ax.plot(amp_prev)
                    ax.plot(amp_filt_prev)
                    if kk == 1:
                        ax.set_title("Minimization result - " + profilename,
                                     fontsize=16)
                    if (
                            kk == amplitude.shape[1] - 1
                    ):  # if we reach the final plot the add the x axis label
                        ax.set_xlabel("distance [mm]")

                    ax.set_ylabel("amplitude")
                    ax.annotate(
                        "delta=" + str(abs(i - inc * 1) * dx) + " mm",
                        xy=(2, 1),
                        xycoords="axes fraction",
                        xytext=(0.35, 0.10),
                    )

                    # plt.show()

                    kk = kk + 1
                    break
                else:
                    amp_prev = amp_tot
                    amp_filt_prev = amp_filt
                    cumsum_prev = cumsum

    return fig