def range_invert(arrayin): max_val = np.amax(arrayin) arrayout = arrayin / max_val min_val = np.amin(arrayout) arrayout = arrayout - min_val arrayout = 1 - arrayout # inverting the range arrayout = arrayout * max_val return arrayout
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
def norm01(arrayin): min_val = np.amin(arrayin) # normalizing arrayout = arrayin - min_val arrayout = arrayout / (np.amax(arrayout)) # normalizing the data return arrayout
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
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
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." )
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