def full_imageProcess(ArrayDicom_o, dx, dy, title):  # process a full image
    ArrayDicom = u.norm01(ArrayDicom_o)
    height = np.shape(ArrayDicom)[0]
    width = np.shape(ArrayDicom)[1]

    blobs_log = blob_log(
        ArrayDicom, min_sigma=1, max_sigma=5, num_sigma=20, threshold=0.15
    )  # run on windows, for some stupid reason exclude_border is not recognized in my distro at home

    center = []
    point_det = []
    for blob in blobs_log:
        y, x, r = blob
        point_det.append((x, y, r))

    point_det = sorted(
        point_det, key=itemgetter(2), reverse=True
    )  # here we sort by the radius of the dot bigger dots are around the center and edges

    # we need to find the centre dot as well as the larger dots on the sides of the image

    # for j in range(0, len(point_det)):
    #     x, y, r = point_det[j]
    #     center.append((int(round(x)), int(round(y))))

    # now that we have detected the centre we are going to increase the precision of the detected point
    im_centre = Image.fromarray(
        255
        * ArrayDicom[
            height // 2 - 20 : height // 2 + 20, width // 2 - 20 : width // 2 + 20
        ]
    )
    im_centre = im_centre.resize(
        (im_centre.width * 10, im_centre.height * 10), Image.LANCZOS
    )

    xdet_int, ydet_int = point_detect_singleImage(im_centre)
    xdet = int(width // 2 - 20) + xdet_int / 10
    ydet = int(height // 2 - 20) + ydet_int / 10

    center.append((xdet, ydet))

    textstr = ""

    print("center=", center)
    fig, ax = viewer(u.range_invert(ArrayDicom_o), dx, dy, center, title, textstr)

    return fig, ax, center
Exemple #2
0
def read_dicom(directory):
    for subdir, dirs, files in os.walk(
            directory):  # pylint: disable = unused-variable
        list_title = []
        list_gantry_angle = []
        list_collimator_angle = []
        list_figs = []
        # center_g0c90 = [(0, 0)]
        center_g0 = [(0, 0)]
        dx = 0
        dy = 0
        distance = 0  # pylint: disable = unused-variable

        k = 0  # we callect all the images in ArrayDicom
        for file in tqdm(sorted(files)):
            print(file)

            if os.path.splitext(directory + file)[1] == ".dcm":
                dataset = pydicom.dcmread(directory + file)
                gantry_angle = dataset[0x300A, 0x011E].value
                collimator_angle = dataset[0x300A, 0x0120].value

                list_gantry_angle.append(gantry_angle)
                list_collimator_angle.append(collimator_angle)

                # title = ('Gantry= ' + str(gantry_angle), 'Collimator= ' + str(collimator_angle))
                title = (
                    "g" + str(round(gantry_angle)),
                    "c" + str(round(collimator_angle)),
                )
                print(title)

                if k == 0:
                    # title = ('Gantry= ' + str(gantry_angle), 'Collimator= ' + str(collimator_angle))
                    title = (
                        "g" + str(round(gantry_angle)),
                        "c" + str(round(collimator_angle)),
                    )
                    list_title.append(title)
                    ArrayDicom = dataset.pixel_array
                    # height = np.shape(ArrayDicom)[0]
                    # width = np.shape(ArrayDicom)[1]
                    SID = dataset.RTImageSID
                    dx = 1 / (SID *
                              (1 / dataset.ImagePlanePixelSpacing[0]) / 1000)
                    dy = 1 / (SID *
                              (1 / dataset.ImagePlanePixelSpacing[1]) / 1000)
                    print("pixel spacing row [mm]=", dx)
                    print("pixel spacing col [mm]=", dy)
                    distance, fig_scaling = scalingAnalysis(ArrayDicom, dx, dy)

                else:
                    list_title.append(title)
                    tmp_array = dataset.pixel_array
                    tmp_array = u.norm01(tmp_array)
                    # tmp_array = norm01(tmp_array)
                    ArrayDicom = np.dstack((ArrayDicom, tmp_array))

            k = k + 1

    # After we colect all the images we only select g0c90 and g0c270 to calculate the center at g0
    print(list_title)
    for i, _ in enumerate(list_title):
        if list_title[i][0] == "g0" and list_title[i][1] == "c90":
            # height = np.shape(ArrayDicom[:, :, i])[0]
            # width = np.shape(ArrayDicom[:, :, i])[1]
            fig_g0c90, ax_g0c90, center_g0c90 = full_imageProcess(
                ArrayDicom[:, :, i], dx, dy, list_title[i])
            center_g0[0] = (
                center_g0[0][0] + center_g0c90[0][0] * 0.5,
                center_g0[0][1] + center_g0c90[0][1] * 0.5,
            )

            list_figs.append(fig_g0c90)  # we plot always the image at g0c90

        if list_title[i][0] == "g0" and list_title[i][1] == "c270":
            center_g0c270 = full_imageProcess_noGraph(ArrayDicom[:, :, i])
            center_g0[0] = (
                center_g0[0][0] + center_g0c270[0][0] * 0.5,
                center_g0[0][1] + center_g0c270[0][1] * 0.5,
            )

    # for i in range(0, len(list_title)):
    for i, _ in enumerate(list_title):
        if list_title[i][1] != "c90":
            center = full_imageProcess_noGraph(ArrayDicom[:, :, i])

            x_g0, y_g0 = center_g0[0]
            x, y = center[0]

            dist = sqrt((x_g0 - x) * (x_g0 - x) * dx * dx + (y_g0 - y) *
                        (y_g0 - y) * dy * dy)
            # dist = sqrt((width//2 - x) * (width//2 - x) * dx * dx + (height//2 - y) * (height//2 - y) * dy * dy)

            textstr = "offset" + str(list_title[i]) + "=" + str(round(
                dist, 4)) + " mm"

            ax_g0c90.scatter(x * dx, (ArrayDicom[:, :, i].shape[0] - y) * dy,
                             label=textstr)  # perfect!

            print(list_title[i], "center_g0c90=", center_g0c90, "center=",
                  center, dist)
            ax_g0c90.legend(bbox_to_anchor=(1.25, 1), loc=2, borderaxespad=0.0)

    with PdfPages(directory + "/" + "Graticule_report.pdf") as pdf:
        # Page = plt.figure(figsize=(4, 5))
        # Page.text(0, 0.9, 'Report', size=18)
        # Page.text(0, 0.9, "Distance=" + str(distance)+ " cm", size=14)
        pdf.savefig(fig_g0c90)
        pdf.savefig(fig_scaling)

    # exit(0)
    sys.exit(0)
Exemple #3
0
def scalingAnalysis(ArrayDicom_o, dx, dy):  # determine scaling
    ArrayDicom = u.norm01(ArrayDicom_o)
    # ArrayDicom = norm01(ArrayDicom_o)
    blobs_log = blob_log(
        ArrayDicom, min_sigma=1, max_sigma=5, num_sigma=20, threshold=0.15
    )  # run on windows, for some stupid reason exclude_border is not recognized in my distro at home

    point_det = []
    for blob in blobs_log:
        y, x, r = blob
        point_det.append((x, y, r))

    point_det = sorted(
        point_det, key=itemgetter(2), reverse=True
    )  # here we sort by the radius of the dot bigger dots are around the center and edges

    point_det = np.asarray(point_det)

    # now we need to select the most extreme left and right point
    print(np.shape(ArrayDicom)[0] // 2)
    print(abs(point_det[:6, 1] - np.shape(ArrayDicom)[0] // 2) < 10)
    point_sel = []
    for i in range(0, 6):
        if abs(point_det[i, 1] - np.shape(ArrayDicom)[0] // 2) < 10:
            point_sel.append(abs(point_det[i, :]))

    point_sel = np.asarray(point_sel)

    imax = np.argmax(point_sel[:, 0])
    imin = np.argmin(point_sel[:, 0])

    print(point_sel[imax, :], point_sel[imin, :])
    distance = (np.sqrt((point_sel[imax, 0] - point_sel[imin, 0]) *
                        (point_sel[imax, 0] - point_sel[imin, 0]) * dx * dx +
                        (point_sel[imax, 1] - point_sel[imin, 1]) *
                        (point_sel[imax, 1] - point_sel[imin, 1]) * dy * dy) /
                10.0)

    print("distance=", distance, "cm")  # distance is reported in cm

    # plotting the figure of scaling results

    fig = plt.figure(figsize=(12, 7))
    ax = fig.subplots()
    ax.volume = ArrayDicom_o
    width = ArrayDicom_o.shape[1]
    height = ArrayDicom_o.shape[0]
    extent = (0, 0 + (width * dx), 0, 0 + (height * dy))
    img = ax.imshow(  # pylint: disable = unused-variable
        ArrayDicom_o,
        extent=extent,
        origin="lower")
    # fig.colorbar(img, ax=ax, orientation="vertical")
    # img = ax.imshow(ArrayDicom_o)
    ax.set_xlabel("x distance [mm]")
    ax.set_ylabel("y distance [mm]")

    ax.scatter(point_sel[imax, 0] * dx, point_sel[imax, 1] * dy)
    ax.scatter(point_sel[imin, 0] * dx, point_sel[imin, 1] * dy)

    # adding a horizontal arrow
    ax.annotate(
        s="",
        xy=(point_sel[imax, 0] * dx, point_sel[imax, 1] * dy),
        xytext=(point_sel[imin, 0] * dx, point_sel[imin, 1] * dy),
        arrowprops=dict(arrowstyle="<->", color="r"),
    )  # example on how to plot a double headed arrow
    ax.text(
        (width // 2.8) * dx,
        (height // 2 + 10) * dy,
        "Distance=" + str(round(distance, 4)) + " cm",
        rotation=0,
        fontsize=14,
        color="r",
    )

    return distance, fig
Exemple #4
0
def read_dicom3D(direc, i_option):
    # item = 0
    for subdir, dirs, files in os.walk(
            direc):  # pylint: disable = unused-variable
        k = 0
        for file in tqdm(sorted(files)):
            # print('filename=', file)
            if os.path.splitext(file)[1] == ".dcm":
                dataset = pydicom.dcmread(direc + file)
                if k == 0:
                    ArrayDicom = np.zeros(
                        (dataset.Rows, dataset.Columns, 0),
                        dtype=dataset.pixel_array.dtype,
                    )
                    tmp_array = dataset.pixel_array
                    if i_option.startswith(("y", "yeah", "yes")):
                        max_val = np.amax(tmp_array)
                        tmp_array = tmp_array / max_val
                        min_val = np.amin(tmp_array)
                        tmp_array = tmp_array - min_val
                        tmp_array = 1 - tmp_array  # inverting the range

                        # min_val = np.amin(tmp_array)  # normalizing
                        # tmp_array = tmp_array - min_val
                        # tmp_array = tmp_array / (np.amax(tmp_array))
                        tmp_array = u.norm01(tmp_array)
                    else:
                        # min_val = np.amin(tmp_array)
                        # tmp_array = tmp_array - min_val
                        # tmp_array = tmp_array / (np.amax(tmp_array))
                        tmp_array = u.norm01(tmp_array)  # just normalize
                    ArrayDicom = np.dstack((ArrayDicom, tmp_array))
                    # print("item thickness [mm]=", dataset.SliceThickness)
                    SID = dataset.RTImageSID
                    dx = 1 / (SID *
                              (1 / dataset.ImagePlanePixelSpacing[0]) / 1000)
                    dy = 1 / (SID *
                              (1 / dataset.ImagePlanePixelSpacing[1]) / 1000)
                    print("pixel spacing row [mm]=", dx)
                    print("pixel spacing col [mm]=", dy)
                else:
                    tmp_array = dataset.pixel_array
                    if i_option.startswith(("y", "yeah", "yes")):
                        max_val = np.amax(tmp_array)
                        tmp_array = tmp_array / max_val
                        min_val = np.amin(tmp_array)
                        tmp_array = tmp_array - min_val
                        tmp_array = 1 - tmp_array  # inverting the range

                        # min_val = np.amin(tmp_array)  # normalizing
                        # tmp_array = tmp_array - min_val
                        # tmp_array = tmp_array / (np.amax(tmp_array))
                        tmp_array = u.norm01(tmp_array)
                    else:
                        # min_val = np.amin(tmp_array)
                        # tmp_array = tmp_array - min_val
                        # tmp_array = tmp_array / (np.amax(tmp_array))  # just normalize
                        tmp_array = u.norm01(tmp_array)
                    ArrayDicom = np.dstack((ArrayDicom, tmp_array))
            k = k + 1

    xfield, yfield, rotfield = image_analyze(ArrayDicom, i_option)

    multi_slice_viewer(ArrayDicom, dx, dy)

    if np.shape(xfield)[2] == 2:
        fig, peak_figs, junctions_figs = merge_view_vert(xfield, dx, dy)
        with PdfPages(direc + "jaws_X_report.pdf") as pdf:
            pdf.savefig(fig)
            # for i in range(0, len(peak_figs)):
            for _, f in enumerate(peak_figs):
                pdf.savefig(f)

            # for i in range(0, len(junctions_figs)):
            for _, f in enumerate(junctions_figs):
                pdf.savefig(f)

            plt.close()

    else:
        print(
            "X jaws data analysis not completed please verify that you have two X jaws images. For more information see manual."
        )

    if np.shape(yfield)[2] == 4:
        fig, peak_figs, junctions_figs = merge_view_horz(yfield, dx, dy)
        # print('peak_figs********************************************************=', len(peak_figs),peak_figs)
        with PdfPages(direc + "jaws_Y_report.pdf") as pdf:
            pdf.savefig(fig)
            # for i in range(0, len(peak_figs)):
            for _, f in enumerate(peak_figs):
                pdf.savefig(f)

            for _, f in enumerate(junctions_figs):
                pdf.savefig(f)

            plt.close()

    else:
        print(
            "Y jaws data analysis not completed please verify that you have four Y jaws images. For more information see manual."
        )

    if np.shape(rotfield)[2] == 4:
        fig, peak_figs, junctions_figs = merge_view_filtrot(rotfield, dx, dy)

        with PdfPages(direc + "jaws_FR_report.pdf") as pdf:
            pdf.savefig(fig)
            for _, f in enumerate(peak_figs):
                pdf.savefig(f)

            for _, f in enumerate(junctions_figs):
                pdf.savefig(f)

            plt.close()

    else:
        print(
            "Field rotation data analysis not completed please verify that you have four field rotation images. For more information see manual."
        )
Exemple #5
0
def read_dicom(filenm, ioptn):
    dataset = pydicom.dcmread(filenm)
    now = datetime.now()

    ArrayDicom = np.zeros((dataset.Rows, dataset.Columns),
                          dtype=dataset.pixel_array.dtype)
    ArrayDicom = dataset.pixel_array
    SID = dataset.RTImageSID
    print("array_shape=", np.shape(ArrayDicom))
    height = np.shape(ArrayDicom)[0]
    width = np.shape(ArrayDicom)[1]
    dx = 1 / (SID * (1 / dataset.ImagePlanePixelSpacing[0]) / 1000)
    dy = 1 / (SID * (1 / dataset.ImagePlanePixelSpacing[1]) / 1000)
    print("pixel spacing row [mm]=", dx)
    print("pixel spacing col [mm]=", dy)

    # creating the figure extent based on the image dimensions, we divide by 10 to get the units in cm
    extent = (
        0,
        0 + (ArrayDicom.shape[1] * dx / 10),
        0 + (ArrayDicom.shape[0] * dy / 10),
        0,
    )

    # creating the figure extent list for the bib images
    list_extent = []

    # plt.figure()
    # plt.imshow(ArrayDicom, extent=extent, origin='upper')
    # plt.imshow(ArrayDicom)
    # plt.xlabel('x distance [cm]')
    # plt.ylabel('y distance [cm]')
    # plt.show()

    if ioptn.startswith(("y", "yeah", "yes")):
        height, width = ArrayDicom.shape
        ArrayDicom_mod = ArrayDicom[:, width // 2 - height // 2:width // 2 +
                                    height // 2]
    else:
        ArrayDicom_mod = ArrayDicom

    # we take a diagonal profile to avoid phantom artifacts
    # im_profile = ArrayDicom_mod.diagonal()

    # test to make sure image is displayed correctly bibs are high amplitude against dark background
    ctr_pixel = ArrayDicom_mod[height // 2, width // 2]
    corner_pixel = ArrayDicom_mod[0, 0]

    if ctr_pixel > corner_pixel:
        ArrayDicom = u.range_invert(ArrayDicom)

    ArrayDicom = u.norm01(ArrayDicom)

    # working on transforming the full image and invert it first and go from there.
    if ioptn.startswith(("y", "yeah", "yes")):
        ROI1 = {
            "edge_top": 70,
            "edge_bottom": 130,
            "edge_left": 270,
            "edge_right": 350
        }
        ROI2 = {
            "edge_top": 70,
            "edge_bottom": 130,
            "edge_left": 680,
            "edge_right": 760
        }
        ROI3 = {
            "edge_top": 150,
            "edge_bottom": 210,
            "edge_left": 760,
            "edge_right": 830,
        }
        ROI4 = {
            "edge_top": 560,
            "edge_bottom": 620,
            "edge_left": 760,
            "edge_right": 830,
        }
        ROI5 = {
            "edge_top": 640,
            "edge_bottom": 700,
            "edge_left": 680,
            "edge_right": 760,
        }
        ROI6 = {
            "edge_top": 640,
            "edge_bottom": 700,
            "edge_left": 270,
            "edge_right": 350,
        }
        ROI7 = {
            "edge_top": 560,
            "edge_bottom": 620,
            "edge_left": 200,
            "edge_right": 270,
        }
        ROI8 = {
            "edge_top": 150,
            "edge_bottom": 210,
            "edge_left": 200,
            "edge_right": 270,
        }
    else:
        ROI1 = {
            "edge_top": 280,
            "edge_bottom": 360,
            "edge_left": 360,
            "edge_right": 440,
        }
        ROI2 = {
            "edge_top": 280,
            "edge_bottom": 360,
            "edge_left": 830,
            "edge_right": 910,
        }
        ROI3 = {
            "edge_top": 360,
            "edge_bottom": 440,
            "edge_left": 940,
            "edge_right": 1020,
        }
        ROI4 = {
            "edge_top": 840,
            "edge_bottom": 920,
            "edge_left": 940,
            "edge_right": 1020,
        }
        ROI5 = {
            "edge_top": 930,
            "edge_bottom": 1000,
            "edge_left": 830,
            "edge_right": 910,
        }
        ROI6 = {
            "edge_top": 930,
            "edge_bottom": 1000,
            "edge_left": 360,
            "edge_right": 440,
        }
        ROI7 = {
            "edge_top": 840,
            "edge_bottom": 920,
            "edge_left": 280,
            "edge_right": 360,
        }
        ROI8 = {
            "edge_top": 360,
            "edge_bottom": 440,
            "edge_left": 280,
            "edge_right": 360,
        }

    # images for object detection
    imcirclist = []
    imcirc1 = Image.fromarray(
        255 * ArrayDicom[ROI1["edge_top"]:ROI1["edge_bottom"],
                         ROI1["edge_left"]:ROI1["edge_right"], ])
    imcirc1 = imcirc1.resize((imcirc1.width * 10, imcirc1.height * 10),
                             Image.LANCZOS)

    list_extent.append((
        (ROI1["edge_left"] * dx / 10),
        (ROI1["edge_right"] * dx / 10),
        (ROI1["edge_bottom"] * dy / 10),
        (ROI1["edge_top"] * dy / 10),
    ))

    imcirc2 = Image.fromarray(
        255 * ArrayDicom[ROI2["edge_top"]:ROI2["edge_bottom"],
                         ROI2["edge_left"]:ROI2["edge_right"], ])
    imcirc2 = imcirc2.resize((imcirc2.width * 10, imcirc2.height * 10),
                             Image.LANCZOS)

    list_extent.append((
        (ROI2["edge_left"] * dx / 10),
        (ROI2["edge_right"] * dx / 10),
        (ROI2["edge_bottom"] * dy / 10),
        (ROI2["edge_top"] * dy / 10),
    ))

    imcirc3 = Image.fromarray(
        255 * ArrayDicom[ROI3["edge_top"]:ROI3["edge_bottom"],
                         ROI3["edge_left"]:ROI3["edge_right"], ])
    imcirc3 = imcirc3.resize((imcirc3.width * 10, imcirc3.height * 10),
                             Image.LANCZOS)
    list_extent.append((
        (ROI3["edge_left"] * dx / 10),
        (ROI3["edge_right"] * dx / 10),
        (ROI3["edge_bottom"] * dy / 10),
        (ROI3["edge_top"] * dy / 10),
    ))

    imcirc4 = Image.fromarray(
        255 * ArrayDicom[ROI4["edge_top"]:ROI4["edge_bottom"],
                         ROI4["edge_left"]:ROI4["edge_right"], ])
    imcirc4 = imcirc4.resize((imcirc4.width * 10, imcirc4.height * 10),
                             Image.LANCZOS)

    list_extent.append((
        (ROI4["edge_left"] * dx / 10),
        (ROI4["edge_right"] * dx / 10),
        (ROI4["edge_bottom"] * dy / 10),
        (ROI4["edge_top"] * dy / 10),
    ))

    imcirc5 = Image.fromarray(
        255 * ArrayDicom[ROI5["edge_top"]:ROI5["edge_bottom"],
                         ROI5["edge_left"]:ROI5["edge_right"], ])
    imcirc5 = imcirc5.resize((imcirc5.width * 10, imcirc5.height * 10),
                             Image.LANCZOS)

    list_extent.append((
        (ROI5["edge_left"] * dx / 10),
        (ROI5["edge_right"] * dx / 10),
        (ROI5["edge_bottom"] * dy / 10),
        (ROI5["edge_top"] * dy / 10),
    ))

    imcirc6 = Image.fromarray(
        255 * ArrayDicom[ROI6["edge_top"]:ROI6["edge_bottom"],
                         ROI6["edge_left"]:ROI6["edge_right"], ])
    imcirc6 = imcirc6.resize((imcirc6.width * 10, imcirc6.height * 10),
                             Image.LANCZOS)

    list_extent.append((
        (ROI6["edge_left"] * dx / 10),
        (ROI6["edge_right"] * dx / 10),
        (ROI6["edge_bottom"] * dy / 10),
        (ROI6["edge_top"] * dy / 10),
    ))

    imcirc7 = Image.fromarray(
        255 * ArrayDicom[ROI7["edge_top"]:ROI7["edge_bottom"],
                         ROI7["edge_left"]:ROI7["edge_right"], ])
    imcirc7 = imcirc7.resize((imcirc7.width * 10, imcirc7.height * 10),
                             Image.LANCZOS)

    list_extent.append((
        (ROI7["edge_left"] * dx / 10),
        (ROI7["edge_right"] * dx / 10),
        (ROI7["edge_bottom"] * dy / 10),
        (ROI7["edge_top"] * dy / 10),
    ))

    imcirc8 = Image.fromarray(
        255 * ArrayDicom[ROI8["edge_top"]:ROI8["edge_bottom"],
                         ROI8["edge_left"]:ROI8["edge_right"], ])
    imcirc8 = imcirc8.resize((imcirc8.width * 10, imcirc8.height * 10),
                             Image.LANCZOS)

    list_extent.append((
        (ROI8["edge_left"] * dx / 10),
        (ROI8["edge_right"] * dx / 10),
        (ROI8["edge_bottom"] * dy / 10),
        (ROI8["edge_top"] * dy / 10),
    ))

    imcirclist.append(imcirc1)
    imcirclist.append(imcirc2)
    imcirclist.append(imcirc3)
    imcirclist.append(imcirc4)
    imcirclist.append(imcirc5)
    imcirclist.append(imcirc6)
    imcirclist.append(imcirc7)
    imcirclist.append(imcirc8)

    xdet, ydet = point_detect(imcirclist)

    profiles = []
    profile1 = np.array(imcirc1, dtype=np.uint8)[:, xdet[0]] / 255
    profile2 = np.array(imcirc2, dtype=np.uint8)[:, xdet[1]] / 255
    profile3 = np.array(imcirc3, dtype=np.uint8)[ydet[2], :] / 255
    profile4 = np.array(imcirc4, dtype=np.uint8)[ydet[3], :] / 255
    profile5 = np.array(imcirc5, dtype=np.uint8)[:, xdet[4]] / 255
    profile6 = np.array(imcirc6, dtype=np.uint8)[:, xdet[5]] / 255
    profile7 = np.array(imcirc7, dtype=np.uint8)[ydet[6], :] / 255
    profile8 = np.array(imcirc8, dtype=np.uint8)[ydet[7], :] / 255

    profiles.append(profile1)
    profiles.append(profile2)
    profiles.append(profile3)
    profiles.append(profile4)
    profiles.append(profile5)
    profiles.append(profile6)
    profiles.append(profile7)
    profiles.append(profile8)

    k = 0
    fig = plt.figure(figsize=(8, 12))  # this figure will hold the bibs
    plt.subplots_adjust(hspace=0.35)

    # creating the page to write the results
    dirname = os.path.dirname(filenm)

    # tolerance levels to change at will
    tol = 1.0  # tolearance level
    act = 2.0  # action level
    phantom_distance = 3.0  # distance from the bib to the edge of the phantom

    with PdfPages(dirname + "/" + now.strftime("%d-%m-%Y_%H:%M_") +
                  dataset[0x0008, 0x1010].value +
                  "_Lightrad_report.pdf") as pdf:
        Page = plt.figure(figsize=(4, 5))
        Page.text(0.45, 0.9, "Report", size=18)
        kk = 0  # counter for data points
        for profile in profiles:
            _, index = u.find_nearest(profile,
                                      0.5)  # find the 50% amplitude point
            # value_near, index = find_nearest(profile, 0.5) # find the 50% amplitude point

            if (  # pylint: disable = consider-using-in
                    k == 0 or k == 1 or k == 4
                    or k == 5):  # there are the bibs in the horizontal
                offset_value_y = round(
                    abs((ydet[k] - index) * (dy / 10)) - phantom_distance, 2)

                txt = str(offset_value_y)
                # print('offset_value_y=', offset_value_y)
                if abs(offset_value_y) <= tol:
                    Page.text(
                        0.1,
                        0.8 - kk / 10,
                        "Point" + str(kk + 1) + " offset=" + txt + " mm",
                        color="g",
                    )
                elif abs(offset_value_y) > tol and abs(offset_value_y) <= act:
                    Page.text(
                        0.1,
                        0.8 - kk / 10,
                        "Point" + str(kk + 1) + " offset=" + txt + " mm",
                        color="y",
                    )
                else:
                    Page.text(
                        0.1,
                        0.8 - kk / 10,
                        "Point" + str(kk + 1) + " offset=" + txt + " mm",
                        color="r",
                    )
                kk = kk + 1

                ax = fig.add_subplot(
                    4, 2, k + 1)  # plotting all the figures in a single plot

                ax.imshow(
                    np.array(imcirclist[k], dtype=np.uint8) / 255,
                    extent=list_extent[k],
                    origin="upper",
                )
                ax.scatter(
                    list_extent[k][0] + xdet[k] * dx / 100,
                    list_extent[k][3] + ydet[k] * dy / 100,
                    s=30,
                    marker="P",
                    color="y",
                )
                ax.set_title("Bib=" + str(k + 1))
                ax.axhline(list_extent[k][3] + index * dy / 100,
                           color="r",
                           linestyle="--")
                ax.set_xlabel("x distance [cm]")
                ax.set_ylabel("y distance [cm]")
            else:
                offset_value_x = round(
                    abs((xdet[k] - index) * (dx / 10)) - phantom_distance, 2)

                txt = str(offset_value_x)
                if abs(offset_value_x) <= tol:
                    # print('1')
                    Page.text(
                        0.1,
                        0.8 - kk / 10,
                        "Point" + str(kk + 1) + " offset=" + txt + " mm",
                        color="g",
                    )
                elif abs(offset_value_x) > tol and abs(offset_value_x) <= act:
                    # print('2')
                    Page.text(
                        0.1,
                        0.8 - kk / 10,
                        "Point" + str(kk + 1) + " offset=" + txt + " mm",
                        color="y",
                    )
                else:
                    # print('3')
                    Page.text(
                        0.1,
                        0.8 - kk / 10,
                        "Point" + str(kk + 1) + " offset=" + txt + " mm",
                        color="r",
                    )
                kk = kk + 1

                ax = fig.add_subplot(
                    4, 2, k + 1)  # plotting all the figures in a single plot

                ax.imshow(
                    np.array(imcirclist[k], dtype=np.uint8) / 255,
                    extent=list_extent[k],
                    origin="upper",
                )
                ax.scatter(
                    list_extent[k][0] + xdet[k] * dx / 100,
                    list_extent[k][3] + ydet[k] * dy / 100,
                    s=30,
                    marker="P",
                    color="y",
                )
                ax.set_title("Bib=" + str(k + 1))
                ax.axvline(list_extent[k][0] + index * dx / 100,
                           color="r",
                           linestyle="--")
                ax.set_xlabel("x distance [cm]")
                ax.set_ylabel("y distance [cm]")

            k = k + 1

        pdf.savefig()
        pdf.savefig(fig)

        # we now need to select a horizontal and a vertical profile to find the edge of the field from an image
        # for the field size calculation
        im = Image.fromarray(255 * ArrayDicom)

        if ioptn.startswith(("y", "yeah", "yes")):
            PROFILE = {
                "horizontal": 270,
                "vertical": 430,
            }  # location to extract the horizontal and vertical profiles if this is a linac
        else:
            PROFILE = {
                "horizontal": 470,
                "vertical": 510,
            }  # location to extract the horizontal and vertical profiles if this is a true beam

        profilehorz = (
            np.array(im, dtype=np.uint8)[PROFILE["horizontal"], :] / 255
        )  # we need to change these limits on a less specific criteria
        profilevert = np.array(im, dtype=np.uint8)[:,
                                                   PROFILE["vertical"]] / 255

        # top_edge, index_top = find_nearest(profilevert[0:height//2], 0.5) # finding the edge of the field on the top
        # bot_edge, index_bot = find_nearest(profilevert[height//2:height], 0.5) # finding the edge of the field on the bottom
        _, index_top = u.find_nearest(
            profilevert[0:height // 2],
            0.5)  # finding the edge of the field on the top
        _, index_bot = u.find_nearest(
            profilevert[height // 2:height],
            0.5)  # finding the edge of the field on the bottom

        # l_edge, index_l = find_nearest(profilehorz[0:width//2], 0.5) #finding the edge of the field on the bottom
        # r_edge, index_r = find_nearest(profilehorz[width//2:width], 0.5) #finding the edge of the field on the right
        _, index_l = u.find_nearest(
            profilehorz[0:width // 2],
            0.5)  # finding the edge of the field on the bottom
        _, index_r = u.find_nearest(
            profilehorz[width // 2:width],
            0.5)  # finding the edge of the field on the right

        fig2 = plt.figure(
            figsize=(7, 5)
        )  # this figure will show the vertical and horizontal calculated field size
        ax = fig2.subplots()
        ax.imshow(ArrayDicom, extent=extent, origin="upper")
        ax.set_xlabel("x distance [cm]")
        ax.set_ylabel("y distance [cm]")

        # adding a vertical arrow
        ax.annotate(
            s="",
            xy=(PROFILE["vertical"] * dx / 10, index_top * dy / 10),
            xytext=(PROFILE["vertical"] * dx / 10,
                    (height // 2 + index_bot) * dy / 10),
            arrowprops=dict(arrowstyle="<->", color="r"),
        )  # example on how to plot a double headed arrow
        ax.text(
            (PROFILE["vertical"] + 10) * dx / 10,
            (height // 1.25) * dy / 10,
            "Vfs=" +
            str(round(
                (height // 2 + index_bot - index_top) * dy / 10, 2)) + "cm",
            rotation=90,
            fontsize=14,
            color="r",
        )

        # adding a horizontal arrow
        # print(index_l*dx, index_l, PROFILE['horizontal']*dy, PROFILE['horizontal'])
        ax.annotate(
            s="",
            xy=(index_l * dx / 10, PROFILE["horizontal"] * dy / 10),
            xytext=((width // 2 + index_r) * dx / 10,
                    PROFILE["horizontal"] * dy / 10),
            arrowprops=dict(arrowstyle="<->", color="r"),
        )  # example on how to plot a double headed arrow
        ax.text(
            (width // 2) * dx / 10,
            (PROFILE["horizontal"] - 10) * dy / 10,
            "Hfs=" + str(round(
                (width // 2 + index_r - index_l) * dx / 10, 2)) + "cm",
            rotation=0,
            fontsize=14,
            color="r",
        )

        pdf.savefig(fig2)
def read_dicom(directory):
    now = datetime.now()
    for subdir, dirs, files in os.walk(directory):  # pylint: disable = unused-variable
        dirs.clear()
        list_title = []
        list_gantry_angle = []
        list_collimator_angle = []
        list_figs = []
        center = []
        center_g0 = [(0, 0)]
        center_g90 = [(0, 0)]
        center_g180 = [(0, 0)]
        center_g270 = [(0, 0)]
        dx = 0
        dy = 0

        k = 0  # we callect all the images in ArrayDicom
        for file in tqdm(sorted(files)):
            print("Reading file=>", file)

            if os.path.splitext(directory + file)[1] == ".dcm":
                dataset = pydicom.dcmread(directory + file)
                gantry_angle = dataset[0x300A, 0x011E].value
                collimator_angle = dataset[0x300A, 0x0120].value

                list_gantry_angle.append(gantry_angle)
                list_collimator_angle.append(collimator_angle)

                if round(gantry_angle) == 360:
                    gantry_angle = 0
                if round(collimator_angle) == 360:
                    collimator_angle = 0

                title = (
                    "g" + str(round(gantry_angle)),
                    "c" + str(round(collimator_angle)),
                )
                print(title)

                if k == 0:
                    # title = ('Gantry= ' + str(gantry_angle), 'Collimator= ' + str(collimator_angle))
                    title = (
                        "g" + str(round(gantry_angle)),
                        "c" + str(round(collimator_angle)),
                    )
                    list_title.append(title)
                    ArrayDicom = dataset.pixel_array
                    height = np.shape(ArrayDicom)[0]
                    width = np.shape(ArrayDicom)[1]
                    SID = dataset.RTImageSID
                    dx = 1 / (SID * (1 / dataset.ImagePlanePixelSpacing[0]) / 1000)
                    dy = 1 / (SID * (1 / dataset.ImagePlanePixelSpacing[1]) / 1000)
                    print("pixel spacing row [mm]=", dx)
                    print("pixel spacing col [mm]=", dy)
                    distance, fig_scaling = scalingAnalysis(ArrayDicom, dx, dy)
                    print("distance", distance)

                else:
                    list_title.append(title)
                    tmp_array = dataset.pixel_array
                    tmp_array = u.norm01(tmp_array)
                    ArrayDicom = np.dstack((ArrayDicom, tmp_array))

                k = k + 1

    # After we colect all the images we only select g0c90 and g0c270 to calculate the center at g0

    k = 0
    l = 0
    m = 0
    n = 0

    for i, _ in enumerate(list_title):
        if list_title[i][0] == "g0" and k == 0:
            k = k + 1
            # height = np.shape(ArrayDicom[:, :, i])[0]
            # width = np.shape(ArrayDicom[:, :, i])[1]
            fig_g0c90, ax_g0c90, center_g0c90 = full_imageProcess(
                ArrayDicom[:, :, i], dx, dy, list_title[i]
            )
            center_g0[0] = (
                center_g0[0][0] + center_g0c90[0][0],
                center_g0[0][1] + center_g0c90[0][1],
            )

            list_figs.append(fig_g0c90)  # we plot always the image at g0c90

        if list_title[i][0] == "g0" and k != 0:
            k = k + 1
            center_g0c270 = full_imageProcess_noGraph(ArrayDicom[:, :, i])
            center_g0[0] = (
                center_g0[0][0] + center_g0c270[0][0],
                center_g0[0][1] + center_g0c270[0][1],
            )

    for i, _ in enumerate(list_title):
        if list_title[i][0] == "g90":
            l = l + 1
            center_g90c = full_imageProcess_noGraph(ArrayDicom[:, :, i])
            center_g90[0] = (
                center_g90[0][0] + center_g90c[0][0],
                center_g90[0][1] + center_g90c[0][1],
            )

        if list_title[i][0] == "g180":
            m = m + 1
            center_g180c = full_imageProcess_noGraph(ArrayDicom[:, :, i])
            center_g180[0] = (
                center_g180[0][0] + center_g180c[0][0],
                center_g180[0][1] + center_g180c[0][1],
            )

        if list_title[i][0] == "g270":
            n = n + 1
            center_g270c = full_imageProcess_noGraph(ArrayDicom[:, :, i])
            center_g270[0] = (
                center_g270[0][0] + center_g270c[0][0],
                center_g270[0][1] + center_g270c[0][1],
            )

    print(k, "images used for g0")
    print(l, "images used for g90")
    print(m, "images used for g180")
    print(n, "images used for g270")

    center_g0[0] = (center_g0[0][0] / k, center_g0[0][1] / k)
    center_g90[0] = (center_g90[0][0] / l, center_g90[0][1] / l)
    center_g180[0] = (center_g180[0][0] / m, center_g180[0][1] / m)
    center_g270[0] = (center_g270[0][0] / n, center_g270[0][1] / n)

    center.append(center_g0[0])
    center.append(center_g90[0])
    center.append(center_g180[0])
    center.append(center_g270[0])

    x_g0, y_g0 = center_g0[0]
    x_g90, y_g90 = center_g90[0]
    x_g180, y_g180 = center_g180[0]
    x_g270, y_g270 = center_g270[0]

    max_deltax = 0
    max_deltay = 0
    for i in range(0, len(center)):  # pylint: disable = consider-using-enumerate
        for j in range(i + 1, len(center)):
            deltax = abs(center[i][0] - center[j][0])
            deltay = abs(center[i][1] - center[j][1])
            if deltax > max_deltax:
                max_deltax = deltax
            if deltay > max_deltay:
                max_deltay = deltay

    print("Maximum delta x =", max_deltax * dx, "mm")
    print("Maximum delta y =", max_deltay * dy, "mm")

    ax_g0c90.scatter(
        x_g0 * dx, (ArrayDicom[:, :, i].shape[0] - y_g0) * dy, label="g=0"
    )  # perfect!

    ax_g0c90.scatter(
        x_g90 * dx, (ArrayDicom[:, :, i].shape[0] - y_g90) * dy, label="g=90"
    )  # perfect!
    ax_g0c90.scatter(
        x_g180 * dx, (ArrayDicom[:, :, i].shape[0] - y_g180) * dy, label="g=180"
    )  # perfect!
    ax_g0c90.scatter(
        x_g270 * dx, (ArrayDicom[:, :, i].shape[0] - y_g270) * dy, label="g=270"
    )  # perfect!

    # print(list_title[i], "center_g0c90=", center_g0c90, "center=", center, dist)
    ax_g0c90.legend(bbox_to_anchor=(1.25, 1), loc=2, borderaxespad=0.0)

    # adding a horizontal arrow
    # ax.annotate(
    #     s="",
    #     xy=(point_sel[imax, 0] * dx, point_sel[imax, 1] * dy),
    #     xytext=(point_sel[imin, 0] * dx, point_sel[imin, 1] * dy),
    #     arrowprops=dict(arrowstyle="<->", color="r"),
    # )  # example on how to plot a double headed arrow
    ax_g0c90.text(
        (width // 2.15) * dx,
        (height // 2.15) * dy,
        "Maximum delta x =" + str(round(max_deltax * dx, 4)) + " mm",
        rotation=0,
        fontsize=14,
        color="r",
    )
    ax_g0c90.text(
        (width // 2.15) * dx,
        (height // 2.18) * dy,
        "Maximum delta y =" + str(round(max_deltay * dy, 4)) + " mm",
        rotation=0,
        fontsize=14,
        color="r",
    )

    if platform == "linux":
        output_flnm = (
            dirname
            + "/"
            + now.strftime("%d-%m-%Y_%H:%M_")
            + dataset[0x0008, 0x1010].value
            + "_Graticule_report.pdf"
        )
    elif platform == "win32":
        output_flnm = dataset[0x0008, 0x1010].value + "_Graticule_report.pdf"

    # with PdfPages(directory + "/" + output_flnm) as pdf:
    with PdfPages(output_flnm) as pdf:
        # Page = plt.figure(figsize=(4, 5))
        # Page.text(0, 0.9, 'Report', size=18)
        # Page.text(0, 0.9, "Distance=" + str(distance)+ " cm", size=14)
        pdf.savefig(fig_g0c90)
        pdf.savefig(fig_scaling)

    # exit(0)
    sys.exit(0)