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 absolute_scans_from_mephysto(mephysto_file, absolute_dose, depth_of_absolute_dose_mm): distance, relative_dose, scan_curvetype, scan_depth = api.load_mephysto( mephysto_file) depth_testing = scan_depth[~np.isnan(scan_depth)] depth_testing = np.unique(depth_testing) if depth_of_absolute_dose_mm == "dmax": choose_mephysto = scan_curvetype == "PDD" mephysto_pdd_depth = distance[choose_mephysto][0] mephysto_dose = relative_dose[choose_mephysto][0] depth_of_absolute_dose_mm = mephysto_pdd_depth[np.argmax( mephysto_dose)] mephysto_pdd_depth, mephysto_pdd_dose = mephysto_absolute_depth_dose( absolute_dose, depth_of_absolute_dose_mm, distance, relative_dose, scan_curvetype, ) scans = { "depth_dose": { "displacement": mephysto_pdd_depth, "dose": mephysto_pdd_dose }, "profiles": {}, } for depth_test in depth_testing: ( mephysto_distance_inplane, mephysto_normalised_dose_inplane, ) = mephysto_absolute_profiles( "INPLANE_PROFILE", depth_test, distance, relative_dose, scan_curvetype, scan_depth, mephysto_pdd_depth, mephysto_pdd_dose, ) ( mephysto_distance_crossplane, mephysto_normalised_dose_crossplane, ) = mephysto_absolute_profiles( "CROSSPLANE_PROFILE", depth_test, distance, relative_dose, scan_curvetype, scan_depth, mephysto_pdd_depth, mephysto_pdd_dose, ) scans["profiles"][depth_test] = { "inplane": { "displacement": mephysto_distance_inplane, "dose": mephysto_normalised_dose_inplane, }, "crossplane": { "displacement": mephysto_distance_crossplane, "dose": mephysto_normalised_dose_crossplane, }, } return scans
def merge_view_filtrot(volume, dx, dy): volume_resort = np.copy( volume ) # this will hold the resorted volume 0 to 3 clockwise junctions_comb = [] peaks_figs_comb = [] # we need to create 4 matches # 0,1,2,3 will be tagged top left, top right, bottom right, bottom left for i in range(0, int(np.shape(volume)[2])): diag_stack = [ 0, 0, 0, 0, ] # we will sum along one direction whichever is biggest will tag the file for j in range(0, int(min([np.shape(volume)[0], np.shape(volume)[1]]) / 2)): # print('j=',j,int(np.shape(volume)[0] / 2)+j, int(np.shape(volume)[1] / 2)+j) diag_stack[0] = ( diag_stack[0] + volume[ int(np.shape(volume)[0] / 2) - j, int(np.shape(volume)[1] / 2) - j, i, ] ) diag_stack[1] = ( diag_stack[1] + volume[ int(np.shape(volume)[0] / 2) - j, int(np.shape(volume)[1] / 2) + j, i, ] ) diag_stack[2] = ( diag_stack[2] + volume[ int(np.shape(volume)[0] / 2) + j, int(np.shape(volume)[1] / 2) + j, i, ] ) diag_stack[3] = ( diag_stack[3] + volume[ int(np.shape(volume)[0] / 2) + j, int(np.shape(volume)[1] / 2) - j, i, ] ) volume_resort[:, :, np.argmax(diag_stack)] = volume[:, :, i] # creating merged volumes merge_vol = np.zeros((volume_resort.shape[0], volume_resort.shape[1])) # creating vector for processing (1 horizontal & 1 vertical) amplitude_horz = np.zeros( (volume_resort.shape[1], volume_resort.shape[2]) ) # 1 if it is vertical 0 if the bars are horizontal amplitude_vert = np.zeros((volume_resort.shape[0], volume_resort.shape[2])) # y = np.linspace(0, 0 + (volume_resort.shape[0] * dy), volume_resort.shape[0], # endpoint=False) # definition of the distance axis # x = np.linspace(0, 0 + (volume_resort.shape[1] * dy), volume_resort.shape[1], # endpoint=False) # definition of the distance axis ampl_resamp_y1 = np.zeros( ((volume_resort.shape[0]) * 10, int(volume_resort.shape[2] / 2)) ) ampl_resamp_y2 = np.zeros( ((volume_resort.shape[0]) * 10, int(volume_resort.shape[2] / 2)) ) ampl_resamp_x1 = np.zeros( ((volume_resort.shape[1]) * 10, int(volume_resort.shape[2] / 2)) ) ampl_resamp_x2 = np.zeros( ((volume_resort.shape[1]) * 10, int(volume_resort.shape[2] / 2)) ) amplitude_horz[:, 0] = volume_resort[ int(volume_resort.shape[0] / 3.25), :, 0 ] # for profile 1 amplitude_horz[:, 1] = volume_resort[ int(volume_resort.shape[0] / 3.25), :, 1 ] # for profile 1 amplitude_horz[:, 3] = volume_resort[ int(volume_resort.shape[0]) - int(volume_resort.shape[0] / 3.25), :, 2 ] # the numbers here are reversed because we are going to slide the second graph (the overlay) to minimize the error #for profile 2 amplitude_horz[:, 2] = volume_resort[ int(volume_resort.shape[0]) - int(volume_resort.shape[0] / 3.25), :, 3 ] amplitude_vert[:, 0] = volume_resort[ :, int(volume_resort.shape[1]) - int(volume_resort.shape[1] / 2.8), 1 ] # the numbers here are reversed because we are going to slide the second graph (the overlay) to minimize the error #for profile 3 amplitude_vert[:, 1] = volume_resort[ :, int(volume_resort.shape[1]) - int(volume_resort.shape[1] / 2.8), 2 ] amplitude_vert[:, 3] = volume_resort[ :, int(volume_resort.shape[1] / 2.8), 3 ] # for profile 4 amplitude_vert[:, 2] = volume_resort[:, int(volume_resort.shape[1] / 2.8), 0] plt.figure() for item in tqdm(range(0, int(volume.shape[2] / 2))): merge_vol = merge_vol + volume[:, :, item] data_samp = amplitude_vert[:, item] ampl_resamp_y1[:, item] = signal.resample( data_samp, int(np.shape(amplitude_vert)[0]) * 10 ) data_samp = amplitude_horz[:, item] ampl_resamp_x1[:, item] = signal.resample( data_samp, int(np.shape(amplitude_horz)[0]) * 10 ) for item in tqdm(range(int(volume.shape[2] / 2), volume.shape[2])): merge_vol = merge_vol + volume[:, :, item] data_samp = amplitude_vert[:, item] ampl_resamp_y2[:, item - int(volume.shape[2] / 2)] = signal.resample( data_samp, int(np.shape(amplitude_vert)[0]) * 10 ) data_samp = amplitude_horz[:, item] ampl_resamp_x2[:, item - int(volume.shape[2] / 2)] = signal.resample( data_samp, int(np.shape(amplitude_horz)[0]) * 10 ) fig, ax = plt.subplots(ncols=1, nrows=1, squeeze=True, figsize=(6, 8)) extent = (0, 0 + (volume.shape[1] * dx), 0, 0 + (volume.shape[0] * dy)) ax.imshow(merge_vol, extent=extent, aspect="auto") ax.set_aspect("equal", "box") ax.set_xlabel("x distance [mm]") ax.set_ylabel("y distance [mm]") fig.suptitle("Merged volume", fontsize=16) ax.hlines(dy * int(volume_resort.shape[0] / 3.25), 0, dx * volume_resort.shape[1]) ax.text( dx * int(volume_resort.shape[1] / 2.25), dy * int(volume_resort.shape[0] / 3), "Profile 2", ) ax.hlines( dy * int(volume_resort.shape[0]) - dy * int(volume_resort.shape[0] / 3.25), 0, dx * volume_resort.shape[1], ) ax.text( dx * int(volume_resort.shape[1] / 2.25), dy * int(volume_resort.shape[0]) - dy * int(volume_resort.shape[0] / 3.5), "Profile 1", ) ax.vlines(dx * int(volume_resort.shape[1] / 2.8), 0, dy * volume_resort.shape[0]) ax.text( dx * int(volume_resort.shape[1] / 3.1), dy * int(volume_resort.shape[0] / 1.8), "Profile 4", rotation=90, ) ax.vlines( dx * int(volume_resort.shape[1]) - dx * int(volume_resort.shape[1] / 2.8), 0, dy * volume_resort.shape[0], ) ax.text( dx * int(volume_resort.shape[1]) - dx * int(volume_resort.shape[1] / 2.9), dy * int(volume_resort.shape[0] / 1.8), "Profile 3", rotation=90, ) # plt.show() peaks, peak_type, peak_figs = pffr.peak_find_fieldrot( ampl_resamp_x1, dx, "Profile 1" ) junction_figs = minFR.minimize_junction_fieldrot( ampl_resamp_x1, peaks, peak_type, dx / 10, "Profile 1" ) peaks_figs_comb.append(peak_figs) junctions_comb.append(junction_figs) peaks, peak_type, peak_figs = pffr.peak_find_fieldrot( ampl_resamp_x2, dx, "Profile 2" ) junction_figs = minFR.minimize_junction_fieldrot( ampl_resamp_x2, peaks, peak_type, dx / 10, "Profile 2" ) peaks_figs_comb.append(peak_figs) junctions_comb.append(junction_figs) peaks, peak_type, peak_figs = pffr.peak_find_fieldrot( ampl_resamp_y1, dy, "Profile 3" ) junction_figs = minFR.minimize_junction_fieldrot( ampl_resamp_y1, peaks, peak_type, dy / 10, "Profile 3" ) peaks_figs_comb.append(peak_figs) junctions_comb.append(junction_figs) peaks, peak_type, peak_figs = pffr.peak_find_fieldrot( ampl_resamp_y2, dy, "Profile 4" ) junction_figs = minFR.minimize_junction_fieldrot( ampl_resamp_y2, peaks, peak_type, dy / 10, "Profile 4" ) peaks_figs_comb.append(peak_figs) junctions_comb.append(junction_figs) return fig, peaks_figs_comb, junctions_comb