Beispiel #1
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 (%)")
def angle_dd2dcm(angle):
    diff = np.append(np.diff(angle), 0)
    movement = (np.empty_like(angle)).astype(str)

    movement[diff > 0] = "CW"
    movement[diff < 0] = "CC"
    movement[diff == 0] = "NONE"

    converted_angle = np.array(angle, copy=False)
    converted_angle[
        converted_angle < 0] = converted_angle[converted_angle < 0] + 360

    converted_angle = converted_angle.astype(str).tolist()

    return converted_angle, movement
Beispiel #3
0
def visual_alignment_of_equivalent_ellipse(x, y, width, length, callback):
    """Visually align the equivalent ellipse to the insert."""
    insert = shapely_insert(x, y)
    unit_circle = shapely.geometry.Point(0, 0).buffer(1)
    initial_ellipse = shapely.affinity.scale(unit_circle,
                                             xfact=width / 2,
                                             yfact=length / 2)

    def minimising_function(optimiser_input):
        x_shift, y_shift, rotation_angle = optimiser_input
        rotated = shapely.affinity.rotate(initial_ellipse,
                                          rotation_angle,
                                          use_radians=True)
        translated = shapely.affinity.translate(rotated,
                                                xoff=x_shift,
                                                yoff=y_shift)

        disjoint_area = (translated.difference(insert).area +
                         insert.difference(translated).area)

        return disjoint_area / 400

    x0 = np.append(np.squeeze(insert.centroid.coords), np.pi / 4)
    niter = 10
    T = insert.area / 40000
    stepsize = 3
    niter_success = 2
    output = scipy.optimize.basinhopping(
        minimising_function,
        x0,
        niter=niter,
        T=T,
        stepsize=stepsize,
        niter_success=niter_success,
        callback=callback,
    )

    x_shift, y_shift, rotation_angle = output.x

    return x_shift, y_shift, rotation_angle
Beispiel #4
0
def read_mapcheck_txt(file_name):
    """
    Read native MapCheck data file and return dose array.

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

    Returns
    -------
    MapCheck : named tuple
        | MapCheck.x = np.array, float x-coords
        | MapCheck.y = np.array, float y-coords
        | MapCheck.dose = np.array (x,y), float dose
    """

    Mapcheck = namedtuple("Mapcheck", ["x", "y", "dose"])

    with open(file_name, "r") as mapcheck_file:
        m_chk = "\n".join(mapcheck_file.readlines())
        m_chk = m_chk.split("Dose Interpolated")[-1]
        m_chk = m_chk.split("\n")[2:]

    temp = [r for r in csv.reader(m_chk, delimiter="\t") if "Xcm" in r]
    x_coord = np.array(temp[0][2:]).astype(float)
    y_coord, dose = np.array([]), np.array([])

    for line in csv.reader(m_chk, delimiter="\t"):
        if len(line) > 1:
            try:
                line = [float(r) for r in line]
                y_coord = np.insert(y_coord, 0, float(line[0]))
                dose = np.append(dose, line[2:])
            except ValueError:
                pass
    dose = np.array(dose).flatten().astype(float)
    dose.shape = (len(x_coord), len(y_coord))
    return Mapcheck(x_coord, y_coord, dose)
Beispiel #5
0
    def _from_pandas(cls: Type[DeliveryGeneric], table) -> DeliveryGeneric:
        raw_monitor_units = table["Step Dose/Actual Value (Mu)"]

        diff = np.append([0], np.diff(raw_monitor_units))
        diff[diff < 0] = 0

        monitor_units = np.cumsum(diff)

        gantry = table[GANTRY_NAME]
        collimator = table[COLLIMATOR_NAME]

        y1_bank = [table[name] for name in Y1_LEAF_BANK_NAMES]

        y2_bank = [table[name] for name in Y2_LEAF_BANK_NAMES]

        mlc = [y1_bank, y2_bank]
        mlc = np.swapaxes(mlc, 0, 2)

        jaw = [table[name] for name in JAW_NAMES]
        jaw = np.swapaxes(jaw, 0, 1)

        return cls(monitor_units, gantry, collimator, mlc, jaw)
Beispiel #6
0
def _single_calculate_deformability(x_test, y_test, x_data, y_data, z_data):
    """Return the result of the deformability test for a single test point.

    The deformability test applies a shift to the spline to determine whether
    or not sufficient information for modelling is available. For further
    details on the deformability test see the *Methods: Defining valid
    prediction regions of the spline* section within
    <http://dx.doi.org/10.1016/j.ejmp.2015.11.002>.

    Parameters
    ----------
    x_test : float
        The x coordinate of the point to test
    y_test : float
        The y coordinate of the point to test
    x_data : np.ndarray
        The x coordinates of the model data to test
    y_data : np.ndarray
        The y coordinates of the model data to test
    z_data : np.ndarray
        The z coordinates of the model data to test

    Returns
    -------
    deformability : float
        The resulting deformability between 0 and 1
        representing the ratio of deviation the spline model underwent at
        the point in question by introducing an outlier at the point in
        question.

    """
    deviation = 0.02

    adjusted_x_data = np.append(x_data, x_test)
    adjusted_y_data = np.append(y_data, y_test)

    bbox = [
        min(adjusted_x_data),
        max(adjusted_x_data),
        min(adjusted_y_data),
        max(adjusted_y_data),
    ]

    initial_model = scipy.interpolate.SmoothBivariateSpline(x_data,
                                                            y_data,
                                                            z_data,
                                                            bbox=bbox,
                                                            kx=2,
                                                            ky=1).ev(
                                                                x_test, y_test)

    pos_adjusted_z_data = np.append(z_data, initial_model + deviation)
    neg_adjusted_z_data = np.append(z_data, initial_model - deviation)

    pos_adjusted_model = scipy.interpolate.SmoothBivariateSpline(
        adjusted_x_data, adjusted_y_data, pos_adjusted_z_data, kx=2,
        ky=1).ev(x_test, y_test)
    neg_adjusted_model = scipy.interpolate.SmoothBivariateSpline(
        adjusted_x_data, adjusted_y_data, neg_adjusted_z_data, kx=2,
        ky=1).ev(x_test, y_test)

    deformability_from_pos_adjustment = (pos_adjusted_model -
                                         initial_model) / deviation
    deformability_from_neg_adjustment = (initial_model -
                                         neg_adjusted_model) / deviation

    deformability = np.max(
        [deformability_from_pos_adjustment, deformability_from_neg_adjustment])

    return deformability
Beispiel #7
0
def image_analyze(volume, i_opt):
    xfield = []
    yfield = []
    rotfield = []

    if i_opt.startswith(("y", "yeah", "yes")):
        kx = 0
        ky = 0
        krot = 0
        for item in range(0, volume.shape[2]):
            stack1 = np.sum(
                volume[
                    int(
                        np.shape(volume)[0] / 2
                        - np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ) : int(
                        np.shape(volume)[0] / 2
                        + np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ),
                    int(
                        np.shape(volume)[1] / 2
                        - np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ) : int(
                        np.shape(volume)[1] / 2
                        + np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ),
                    item,
                ],
                axis=0,
            )
            maxstack1 = np.amax(stack1)

            # stack2 = np.sum(volume[:, :, item], axis=1)
            stack2 = np.sum(
                volume[
                    int(
                        np.shape(volume)[0] / 2
                        - np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ) : int(
                        np.shape(volume)[0] / 2
                        + np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ),
                    int(
                        np.shape(volume)[1] / 2
                        - np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ) : int(
                        np.shape(volume)[1] / 2
                        + np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ),
                    item,
                ],
                axis=1,
            )
            maxstack2 = np.amax(stack2)

            if maxstack2 / maxstack1 > 1.1:  # It is a Y field folder
                if ky == 0:
                    yfield = volume[:, :, item]
                    yfield = yfield[:, :, np.newaxis]
                else:
                    volappend = volume[:, :, item]
                    yfield = np.append(yfield, volappend[:, :, np.newaxis], axis=2)
                ky = ky + 1
            elif maxstack2 / maxstack1 < 0.9:  # It is a X field folder
                if kx == 0:
                    xfield = volume[:, :, item]
                    xfield = xfield[:, :, np.newaxis]
                else:
                    # xfield=xfield[:,:,np.newaxis]
                    volappend = volume[:, :, item]
                    xfield = np.append(xfield, volappend[:, :, np.newaxis], axis=2)
                kx = kx + 1
            else:  # It is a field rotation folder
                if krot == 0:
                    rotfield = volume[:, :, item]
                    rotfield = rotfield[:, :, np.newaxis]
                else:
                    # rotfield = rotfield[:, :, np.newaxis]
                    volappend = volume[:, :, item]
                    rotfield = np.append(rotfield, volappend[:, :, np.newaxis], axis=2)
                krot = krot + 1

    else:
        kx = 0
        ky = 0
        krot = 0
        for item in range(0, volume.shape[2]):
            stack1 = np.sum(
                volume[
                    int(
                        np.shape(volume)[0] / 2
                        - np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ) : int(
                        np.shape(volume)[0] / 2
                        + np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ),
                    int(
                        np.shape(volume)[1] / 2
                        - np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ) : int(
                        np.shape(volume)[1] / 2
                        + np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ),
                    item,
                ],
                axis=0,
            )
            maxstack1 = np.amax(stack1)

            # stack2 = np.sum(volume[:, :, item], axis=1)
            stack2 = np.sum(
                volume[
                    int(
                        np.shape(volume)[0] / 2
                        - np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ) : int(
                        np.shape(volume)[0] / 2
                        + np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ),
                    int(
                        np.shape(volume)[1] / 2
                        - np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ) : int(
                        np.shape(volume)[1] / 2
                        + np.amin([np.shape(volume)[0], np.shape(volume)[1]]) / 2
                    ),
                    item,
                ],
                axis=1,
            )
            maxstack2 = np.amax(stack2)

            if maxstack2 / maxstack1 > 1.5:  # It is a Y field folder
                if ky == 0:
                    yfield = volume[:, :, item]
                    yfield = yfield[:, :, np.newaxis]
                else:
                    volappend = volume[:, :, item]
                    yfield = np.append(yfield, volappend[:, :, np.newaxis], axis=2)
                ky = ky + 1
            elif maxstack2 / maxstack1 < 0.5:  # It is a X field folder
                if kx == 0:
                    xfield = volume[:, :, item]
                    xfield = xfield[:, :, np.newaxis]
                else:
                    # xfield=xfield[:,:,np.newaxis]
                    volappend = volume[:, :, item]
                    xfield = np.append(xfield, volappend[:, :, np.newaxis], axis=2)
                kx = kx + 1
            else:  # It is a field rotation folder
                if krot == 0:
                    rotfield = volume[:, :, item]
                    rotfield = rotfield[:, :, np.newaxis]
                else:
                    # rotfield = rotfield[:, :, np.newaxis]
                    volappend = volume[:, :, item]
                    rotfield = np.append(rotfield, volappend[:, :, np.newaxis], axis=2)
                krot = krot + 1

    return xfield, yfield, rotfield