def main(): # load in the file and define x and y data sdt = SdtFile('1_1.sdt') d = sdt.data[0] aa = d.sum(axis=0) x= aa + 2 y= np.linspace(11.,244., 244) # define values with greater than 0 counts N = x #print('N', x) N = [i for i in N if i>=10000] #print ('Nlog', N) maxval=N.index(max(N)) #print('max',maxval) N2= N[maxval:len(N)] #print('N2: ',N2) tt=np.linspace(int(maxval),int(len(N)), int(len(N) - maxval)) t=tt # new N value N = N2 #sig = np.zeros(nobs) + stdev #sig = np.zeros(len(N)) + stdev sig= np.sqrt(np.array(N)) print('sig',sig) print('sum',np.sum(sig)) # preset variables stdev = 64000 # x and y y=np.array(N) x=np.array(tt) # Fit the curve, give a guess p0 p0=(8, 1000, 8, 1000) opt, pcov = curve_fit(model_func, x, y, p0) a, k , b, kk= opt # Compute chi square Nexp = model_func(x, *opt) r = N - Nexp chisq = np.sum((r/stdev)**2) #df = nobs - 2 print('chisq =',chisq) # test result x2=np.linspace(50,255,50,255) y2=model_func(x2,a,k,b,kk) fig, ax = plt.subplots() ax.plot(x2, y2, color='r', label ='Fit. func: $f(x) = %.3f e^{%.3f x} %.3f e^{%.3f x}' % (a,k,b,kk)) ax.plot(x,y,'bo', label='data') ax.legend(loc='best') plt.yscale('log') plt.show()
def sdtread(filename): """Return decay curve and time axis from Becker & Hickl SDT file.""" from sdtfile import SdtFile, BlockType with SdtFile(filename) as sdt: for i in range(len(sdt.data)): bh = sdt.block_headers[i] if BlockType(bh.block_type).contents == 'DECAY_BLOCK': return sdt.data[i].squeeze(), sdt.times[i].squeeze() raise TypeError('SDT file does not contain any DECAY_BLOCK')
def read_sdt_file(sdtfile, channel=0, xpix=256, ypix=256, tpix=256): """ Reads a sdtfile and returns the header and a data cube. Parameters ---------- sdtfile : str Path to SdtFile channel : int xpix : int ypix : int tpix : int Returns ------- 3d ndarray Read dataset with shape (xpix, ypix, tpix) dict Header information """ sdt = SdtFile(sdtfile) if np.shape(sdt.data)[0] == 0: print("There is an error with this file: {}".format(sdtfile)) sdt_meta = pd.DataFrame.from_records(sdt.measure_info[0]) sdt_meta = sdt_meta.append( pd.DataFrame.from_records(sdt.measure_info[1]), ignore_index=True ) sdt_meta.append(pd.DataFrame.from_records(sdt.measure_info[2]), ignore_index=True) sdt_meta = sdt_meta.append( pd.DataFrame.from_records(sdt.measure_info[3]), ignore_index=True ) header = {} header["flimview"] = {} header["flimview"]["sdt_info"] = sdt.info header["flimview"]["filename"] = os.path.basename(sdtfile) header["flimview"]["pathname"] = os.path.dirname(sdtfile) header["flimview"]["xpix"] = xpix header["flimview"]["ypix"] = ypix header["flimview"]["tpix"] = tpix header["flimview"]["tresolution"] = sdt.times[0][1] / 1e-12 return np.reshape(sdt.data[channel], (xpix, ypix, tpix)), header
def plot_it(self, controller): if controller.filename=='': messagebox.showerror('Error', 'No sdt file loaded!') else: #Takes main file with all pixels# sdt_file=SdtFile(controller.filename) image_size_x=sdt_file.data[0].shape[0] image_size_y=sdt_file.data[0].shape[1] #Pulls the TAC paramters from the sdt file. For some reason the 'times' array from the sdt file is not the correct times - poss software not updated for new card. adc_re=sdt_file.measure_info[0].adc_re tac_r=sdt_file.measure_info[0].tac_r tac_g=sdt_file.measure_info[0].tac_g dt=tac_r/tac_g/adc_re times=range(0,int(sdt_file.measure_info[0].adc_re))*dt #sets end point to end if gating not required if controller.end_gate.get()=='0': end_point=len(sdt_file.data[0][0][0]) start_point=0 else: start_point=round(int((int(controller.start_gate.get())*1e-12)/dt)) #converts back from ps to bins end_point=round(int((int(controller.end_gate.get())*1e-12)/dt)) #If removing the BR/Noise this takes a seperate sdt file# if controller.SBR_var.get() == 1: if controller.end_gate.get() != '0': messagebox.showerror('Error', 'Cannot use noise removal with gating') controller.SBR_var.set('0') else: controller.noise_file = askopenfilename(title="Choose a noise file") noise_file_sdt = SdtFile(controller.noise_file) noise_data=noise_file_sdt.data[0][0][start_point:end_point] #Processes the max counts - also finds brightest pixel for IRF if desired# #Also notes any pixels with no real counts in it and notes the ID's for post px-ing max_arr = np.zeros((image_size_y, image_size_x)) max_count_all=0 pixel=(0,0) for i in range(image_size_y): for j in range(image_size_x): if controller.SBR_var.get() == 1: sdt_file.data[0][i][j]=sdt_file.data[0][i][j]-noise_data max_count=np.amax(sdt_file.data[0][i][j][start_point:end_point]) max_arr[i][j]=max_count if max_count > max_count_all: max_count_all=max_count pixel=(i,j) empty_pixels=np.transpose(np.nonzero(max_arr < 2)) #plots the brightest and fits it to see where we're at centre, scale = fit_exp_mod_gauss(times[start_point:end_point], sdt_file.data[0][pixel[0]][pixel[1]][start_point:end_point], dt, plotting=True) #Checks if you're happy with gating? MsgBox = tk.messagebox.askquestion ('Proceed?','Are you happy with the gating?',icon = 'warning') if MsgBox == 'yes': #Takes brightest pixel as IRF or takes external sdt file# if controller.IRF_var.get() == 1: IRF_pix = sdt_file.data[0][pixel[0]][pixel[1]][start_point:end_point] elif controller.fit_var.get() == 1: pass else: controller.IRF_file = askopenfilename(title="Choose IRF sdt file") IRF_file_sdt = SdtFile(controller.IRF_file) max_irf = np.argmax(IRF_file_sdt.data[0][0]) half_gate = ((int(controller.end_gate.get())-int(controller.start_gate.get()))/2) start_irf = int(max_irf-half_gate) stop_irf = int(max_irf+half_gate) IRF_pix = IRF_file_sdt.data[0][0][start_irf:stop_irf] plt.plot(IRF_pix) plt.show() #prepare an empty 2d arr img_arr = np.zeros((image_size_y, image_size_x)) #either fit or X-corr if controller.fit_var.get() == 1: for i in range(image_size_y): for j in range(image_size_x): try: centre, scale = fit_exp_mod_gauss(times[start_point:end_point], sdt_file.data[0][i][j][start_point:end_point], dt) img_arr[i,j]=centre except TypeError: img_arr[i,j]=float('nan') except RuntimeError: img_arr[i,j]=float('nan') else: #cross correlates the data# for i in range(image_size_y): for j in range(image_size_x): corr = cross_correlate(sdt_file.data[0][i][j][start_point:end_point] , IRF_pix) max_val = np.argmax(corr) img_arr[i,j]=max_val #Scale and convert to mm img_arr= -img_arr - np.nanmean(-img_arr) img_arr=img_arr*1e-6*3e8*0.5*0.5 #Bit of data manipulation for any pixels that are huge if controller.cut_off_max.get() != '0': super_threshold_indices = img_arr > float(controller.cut_off_max.get()) img_arr[super_threshold_indices] = np.mean(img_arr) #If pixels have no counts (or just noise) then leave them out. if controller.remove_empty_pix.get() == 1: for i in empty_pixels: img_arr[i[0], i[1]] = np.nan ####PLOTS#### #3d# # fig1=plt.figure() # f1_ax=fig1.gca(projection='3d') # x_data=np.arange(image_size_x) # y_data=np.arange(image_size_y) # x_data, y_data=np.meshgrid(x_data, y_data) # surf=f1_ax.plot_surface(x_data, y_data, img_arr, cmap=cm.jet) # fig1.colorbar(surf, shrink=0.5, aspect=5) # fig1.suptitle('3D') #2d# # fig2=plt.figure() # flat_plot=plt.imshow(img_arr, cmap=cm.jet) # fig2.colorbar(flat_plot, shrink=0.5, aspect=5) # fig2.suptitle('2D') #counts# fig3=plt.figure() cnt_map=plt.imshow(max_arr, cmap=cm.jet, origin='lower') fig3.colorbar(cnt_map, shrink=0.5, aspect=5) fig3.suptitle('Counts Map') fig5=go.Figure(data=[go.Heatmap(z=img_arr, colorscale='Jet', colorbar=dict(thickness=80, ticklen=3, tickcolor='black', tickfont=dict(size=36, color='black')))]) fig5.update_layout(width = 1500, height = 1500, font=dict(family="Arial",size=36,color="black")) fig5.show() if controller.aspect_togg.get() == 1: if controller.scene_size.get() == '': messagebox.showerror('Error', 'You have not entered a scene size!') aspect_dict=dict(x=1,y=1,z=1) else: scene_size=int(controller.scene_size.get()) #mm aspect_dict=dict(x=1, y=1, z=np.nanmax(img_arr)/(scene_size*1e3)) else: aspect_dict=dict(x=1,y=1,z=1) fig6=go.Figure(data=[go.Surface(z=img_arr, colorscale='Jet', colorbar=dict(thickness=40, ticklen=3, tickcolor='black', tickfont=dict(size=9, color='black')))]) fig6.update_layout(font=dict(family="Arial",size=9,color="black"), scene=dict(aspectmode='manual', aspectratio=aspect_dict)) fig6.show() #plots one histogram from a bright pixel to check for gating errors etc and check fit #fig4=plt.figure() #plt.plot(times[start_point:end_point], sdt_file.data[0][pixel[0]][pixel[1]][start_point:end_point],'o') #fig4.suptitle('Brightest histogram') plt.show() else: pass
####SETUP#### #If gating required. If no gating required leave end_point at 0: start_point=0 end_point=0 #Select if not automatically getting IRF from brightest pixel external_IRF = False #Select to remove back reflections from data and avoid gating - NOT TESTED remove_BR=False ####MAIN#### root = tk.Tk() filename = askopenfilename(initialdir="Z:\\", title="Choose sdt file") root.withdraw() #Takes main file with all pixels# sdt_file=SdtFile(filename) image_size_x=sdt_file.data[0].shape[0] image_size_y=sdt_file.data[0].shape[1] #sets end point to end if gating not required if end_point==0: end_point=len(sdt_file.data[0][0][0]) #If removing the BR/Noise this takes a seperate sdt file# if remove_BR == True: noise_file = askopenfilename(title="Choose a noise file") noise_file_sdt = SdtFile(noise_file) noise_data=noise_file_sdt.data[0][0][start_point:end_point] #Processes the max counts - also finds brightest pixel for IRF if desired# max_arr = np.zeros((image_size_y, image_size_x)) max_count_all=0
def load_dataset( self, file_name: str, *, index: np.ndarray | None = None, flim: bool = False, dataset_index: int | None = None, swap_axis: bool = False, orig_time_axis_index: int = 2, ) -> xr.Dataset: """ Reads a `*.sdt` file and returns a pd.DataFrame (`return_dataframe==True`), a SpectralTemporalDataset (`type_of_data=='st'`) or a FLIMDataset (`type_of_data=='flim'`). Parameters ---------- file_name: str Path to the sdt file which should be read. index: list, np.ndarray This is only needed if `type_of_data=="st"`, since `*.sdt` files, which only contain spectral temporal data, lack the spectral information. Thus for the spectral axis data need to be given by the user. flim: Set true if reading a result from a FLIM measurement. dataset_index: int: default 0 If the `*.sdt` file contains multiple datasets the index will used to select the wanted one swap_axis: bool, default False Flag to switch a wavelength explicit `input_df` to time explicit `input_df`, before generating the SpectralTemporalDataset. orig_time_axis_index: int Index of the axis which corresponds to the time axis. I.e. for data of shape (64, 64, 256), which are a 64x64 pixel map with 256 time steps, orig_time_axis_index=2. Raises ______ IndexError: If the length of the index array is incompatible with the data. """ sdt_parser = SdtFile(file_name) if not dataset_index: # looking at the source code of SdtFile, times and data # always have the same len, so only one needs to be checked nr_of_datasets = len(sdt_parser.times) if nr_of_datasets > 1: warnings.warn( UserWarning( f"The file '{file_name}' contains {nr_of_datasets} Datasets.\n " f"By default only the first Dataset will be read. " f"If you only need the first Dataset and want get rid of " f"this warning you can set dataset_index=0."), stacklevel=4, ) dataset_index = 0 times: np.ndarray = sdt_parser.times[dataset_index] raw_data: np.ndarray = sdt_parser.data[dataset_index] if index and len(index) is not raw_data.shape[0]: raise IndexError( f"The Dataset contains {raw_data.shape[0]} measurements, but the " f"indices supplied are {len(index)}.") elif not index and not flim: warnings.warn( UserWarning( f"There was no `index` provided." f"That for the indices will be a entry count(integers)." f"To prevent this warning from being shown, provide " f"a list of indices, with len(index)={raw_data.shape[0]}"), stacklevel=4, ) if flim: if orig_time_axis_index != 2: np.swapaxes(raw_data, 2, orig_time_axis_index) full_data = xr.DataArray(raw_data, coords={"time": times}, dims=["x", "y", "time"]) data = full_data.stack(pixel=("x", "y")).to_dataset(name="data") data["full_data"] = full_data.rename({ "x": "pixel_x", "y": "pixel_y" }) data["data_intensity_map"] = ( data.data.groupby("pixel").sum().unstack().rename({ "x": "pixel_x", "y": "pixel_y" })) else: if swap_axis: raw_data = raw_data.T if not index: index = np.arange(raw_data.shape[0]) data = xr.DataArray(raw_data.T, coords=[("time", times), ("spectral", index)]) data = prepare_time_trace_dataset(data) return data
def plot_it(self, controller): if controller.filename == '': messagebox.showerror('Error', 'No sdt file loaded!') else: #Takes main file with all pixels# sdt_file = SdtFile(controller.filename) image_size_x = sdt_file.data[0].shape[0] image_size_y = sdt_file.data[0].shape[1] #Pulls the TAC paramters from the sdt file. For some reason the 'times' array from the sdt file is not the correct times - poss software not updated for new card. adc_re = sdt_file.measure_info[0].adc_re tac_r = sdt_file.measure_info[0].tac_r tac_g = sdt_file.measure_info[0].tac_g dt = tac_r / tac_g / adc_re times = range(0, int(sdt_file.measure_info[0].adc_re)) * dt #sets end point to end if gating not required if controller.end_gate.get() == '0': end_point = len(sdt_file.data[0][0][0]) start_point = 0 else: start_point = round( int((int(controller.start_gate.get()) * 1e-12) / dt)) #converts back from ps to bins end_point = round( int((int(controller.end_gate.get()) * 1e-12) / dt)) #If removing the BR/Noise this takes a seperate sdt file# if controller.SBR_var.get() == 1: if controller.end_gate.get() != '0': messagebox.showerror( 'Error', 'Cannot use noise removal with gating') controller.SBR_var.set('0') else: controller.noise_file = askopenfilename( title="Choose a noise file") noise_file_sdt = SdtFile(controller.noise_file) noise_data = noise_file_sdt.data[0][0][ start_point:end_point] #Processes the max counts - also finds brightest pixel for IRF if desired# max_arr = np.zeros((image_size_y, image_size_x)) max_count_all = 0 pixel = (0, 0) for i in range(image_size_y): for j in range(image_size_x): if controller.SBR_var.get() == 1: sdt_file.data[0][i][ j] = sdt_file.data[0][i][j] - noise_data max_count = np.amax( sdt_file.data[0][i][j][start_point:end_point]) max_arr[i][j] = max_count if max_count > max_count_all: max_count_all = max_count pixel = (i, j) #plots the brightest and fits it to see where we're at centre, scale = fit_exp_mod_gauss( times[start_point:end_point], sdt_file.data[0][pixel[0]][pixel[1]][start_point:end_point], dt, plotting=True) #Takes brightest pixel as IRF or takes external sdt file# if controller.IRF_var.get() == 1: IRF_pix = sdt_file.data[0][pixel[0]][ pixel[1]][start_point:end_point] elif controller.fit_var.get() == 1: pass else: controller.IRF_file = askopenfilename( title="Choose IRF sdt file") IRF_file_sdt = SdtFile(controller.IRF_file) max_irf = np.argmax(IRF_file_sdt[0][0]) start_irf = max_irf - 100 stop_irf = max_irf + 100 IRF_pix = IRF_file_sdt.data[0][0][start_point:end_point] plt.plot(IRF_pix) plt.show() #prepare an empty 2d arr img_arr = np.zeros((image_size_y, image_size_x)) #either fit or X-corr if controller.fit_var.get() == 1: for i in range(image_size_y): for j in range(image_size_x): try: centre, scale = fit_exp_mod_gauss( times[start_point:end_point], sdt_file.data[0][i][j][start_point:end_point], dt) img_arr[i, j] = centre except TypeError: img_arr[i, j] = float('nan') except RuntimeError: img_arr[i, j] = float('nan') else: #cross correlates the data# for i in range(image_size_y): for j in range(image_size_x): corr = cross_correlate( sdt_file.data[0][i][j][start_point:end_point], IRF_pix) max_val = np.argmax(corr) img_arr[i, j] = max_val #Scale and convert to mm img_arr = -img_arr - np.nanmean(-img_arr) img_arr = img_arr * 1e-6 * 3e8 * 0.5 * 0.5 ####PLOTS#### #3d# fig1 = plt.figure() f1_ax = fig1.gca(projection='3d') x_data = np.arange(image_size_x) y_data = np.arange(image_size_y) x_data, y_data = np.meshgrid(x_data, y_data) surf = f1_ax.plot_surface(x_data, y_data, img_arr, cmap=cm.jet) fig1.colorbar(surf, shrink=0.5, aspect=5) fig1.suptitle('3D') #2d# fig2 = plt.figure() flat_plot = plt.imshow(img_arr, cmap=cm.jet) fig2.colorbar(flat_plot, shrink=0.5, aspect=5) fig2.suptitle('2D') #counts# fig3 = plt.figure() cnt_map = plt.imshow(max_arr, cmap=cm.jet) fig3.colorbar(cnt_map, shrink=0.5, aspect=5) fig3.suptitle('Counts Map') #plots one histogram from a bright pixel to check for gating errors etc and check fit #fig4=plt.figure() #plt.plot(times[start_point:end_point], sdt_file.data[0][pixel[0]][pixel[1]][start_point:end_point],'o') #fig4.suptitle('Brightest histogram') plt.show()
#B is a list of m, stddev, max, offset #constants worked out first for clarity a = B[3] + B[2] / (B[1] * np.sqrt(2 * np.pi)) b = B[0] c = B[1] y = a * np.exp(-(x - b)**2 / (2 * c**2)) return y def errorfunc(B, x, y): return y - gauss(B, x) filename = askopenfilename(initialdir="Z:\\", title="Choose an sdt file") sdt = SdtFile(filename) data = sdt.data[0][0][start_gate:] m, max_val = get_max(data) B = [m, 0.55, max_val, 0] x = np.arange(1, len(data) + 1) p0 = [m, 1., max_val, 1.] fit = optimize.leastsq(errorfunc, p0, args=(x, data)) fitted_curve = gauss(fit[0], x) #time_per_bin=abs(sdt.times[0][1]) time_per_bin = 0.203 print(fit)
fwhm=round(popt[2]*2.354820045, 3) print(fwhm+'ps') plt.plot(sliced_times+time_shift, counts[start_p:end_p]*max_val, 'x', markersize=6) plt.plot(sliced_times+time_shift,fitted_func*max_val/max(fitted_func),'r-', linewidth=2) plt.xlabel('Bin (ps)') plt.ylabel('Counts') plt.text(centre+10, scale, 'FWHM = '+str(fwhm)+'ps') plt.title('Datpoints and EMG fit') plt.legend(['Data', 'Fit']) plt.show() return centre, scale def exp_mod_gauss(x, b, m, s, l): y = b*(0.5*l*np.exp(0.5*l*(2*m+l*s*s-2*x))*erfc((m+l*s*s-x)/(np.sqrt(2)*s))) return y #l=Lambda, s=Sigma, m=Mu, #b= filename=askopenfilename(initialdir="C:\\", title="Choose an sdt file") sdt_file=SdtFile(filename) data = sdt_file.data[0][0] adc_re=sdt_file.measure_info[0].adc_re tac_r=sdt_file.measure_info[0].tac_r tac_g=sdt_file.measure_info[0].tac_g dt=tac_r/tac_g/adc_re print(tac_r, tac_g, adc_re) print(dt) times=range(0,int(sdt_file.measure_info[0].adc_re))*dt fit_exp_mod_gauss(times, data, dt, plotting=True)
def readfile(path): sdt = SdtFile(path) reshaped = np.reshape(sdt.data[0], (512, -1, 256))[:, :1250, :] return reshaped
def plot_it(self, controller): if controller.filename == '': messagebox.showerror('Error', 'No sdt file loaded!') else: #Checks if .sdt or .npy if controller.filename[-3:] == 'sdt': #Takes main file with all pixels# sdt_file = SdtFile(controller.filename) #Pulls the TAC paramters from the sdt file. For some reason the 'times' array from the sdt file is not the correct times - poss software not updated for new card. adc_re = sdt_file.measure_info[0].adc_re tac_r = sdt_file.measure_info[0].tac_r tac_g = sdt_file.measure_info[0].tac_g image_data = sdt_file.data[0] image_size_x = image_data.shape[0] image_size_y = image_data.shape[1] elif controller.filename[-3:] == 'npy': temp_data = np.load(controller.filename, allow_pickle=True) image_size_x = temp_data.shape[0] image_size_y = temp_data.shape[1] image_data = np.ndarray((image_size_x, image_size_y), dtype='object') for i in range(image_size_y): for j in range(image_size_x): image_data[i][j] = temp_data[i][j][0] #Need to update to pull TAC parameters from .set file, or bundle them with the numpy data adc_re = 4096 tac_r = 2.5016787e-8 tac_g = 15 else: messagebox.showerror('Error', 'Invalid filetype!') #Gets image size and cimputes dt/times arrays dt = tac_r / tac_g / adc_re times = np.arange(0, int(adc_re)) * dt #Binning if controller.bin_toggle.get() == 1: bin_factor = int(controller.bin_factor.get()) image_data = image_data.reshape(*image_data.shape[:2], -1, bin_factor).sum(axis=-1) dt = dt * bin_factor times = np.arange(0, int(adc_re / bin_factor)) * dt #sets end point to end if gating not required if controller.end_gate.get() == '0': end_point = len(image_data[0][0]) start_point = 0 number_bins = end_point - start_point else: start_point = round( int((int(controller.start_gate.get()) * 1e-12) / dt)) #converts back from ps to bins end_point = round( int((int(controller.end_gate.get()) * 1e-12) / dt)) number_bins = end_point - start_point image_data = image_data[:, :, start_point:end_point] times = times[start_point:end_point] #If removing the BR/Noise this takes a seperate sdt file# if controller.SBR_var.get() == 1: if controller.end_gate.get() != '0': messagebox.showerror( 'Error', 'Cannot use noise removal with gating') controller.SBR_var.set('0') else: controller.noise_file = askopenfilename( title="Choose a noise file") noise_file_sdt = SdtFile(controller.noise_file) noise_data = noise_file_sdt.data[0][0][ start_point:end_point] #add binning here if we use this #Processes the max counts - also finds brightest pixel for IRF if desired# #Also notes any pixels with no real counts in it and notes the ID's for post px-ing max_arr = np.zeros((image_size_y, image_size_x)) max_count_all = 0 pixel = (0, 0) for i in range(image_size_y): for j in range(image_size_x): if controller.SBR_var.get() == 1: image_data[i][j] = image_data[i][j] - noise_data max_count = np.amax(image_data[i][j]) max_arr[i][j] = max_count if max_count > max_count_all: max_count_all = max_count pixel = (i, j) empty_pixels = np.transpose(np.nonzero(max_arr < 2)) #plots the brightest and fits it to see where we're at centre, scale = fit_exp_mod_gauss(times, image_data[pixel[0]][pixel[1]], dt, plotting=True) #Checks if you're happy with gating? MsgBox = tk.messagebox.askquestion( 'Proceed?', 'Are you happy with the gating?', icon='warning') if MsgBox == 'yes': #Takes brightest pixel as IRF or takes external sdt file# if controller.IRF_var.get() == 1: IRF_pix = image_data[pixel[0]][pixel[1]] elif controller.fit_var.get() == 1: pass else: controller.IRF_file = askopenfilename( title="Choose IRF sdt file") IRF_file_sdt = SdtFile(controller.IRF_file) max_irf = np.argmax(IRF_file_sdt.data[0][0]) half_gate = ((int(controller.end_gate.get()) - int(controller.start_gate.get())) / 2) start_irf = int(max_irf - half_gate) stop_irf = int(max_irf + half_gate) if controller.bin_toggle.get() == 1: IRF_pix = IRF_file_sdt.data[0][0] IRF_pix = IRF_pix.reshape(int(adc_re / bin_factor), -1).sum(axis=1) IRF_pix = IRF_pix[start_irf:stop_irf] else: IRF_pix = IRF_file_sdt.data[0][0][start_irf:stop_irf] #Add binning here too plt.plot(IRF_pix) plt.show() #prepare an empty 2d arr img_arr = np.zeros((image_size_y, image_size_x)) #either fit or X-corr if controller.fit_var.get() == 1: for i in range(image_size_y): for j in range(image_size_x): try: centre, scale = fit_exp_mod_gauss( times, image_data[i][j], dt) img_arr[i, j] = centre except TypeError: img_arr[i, j] = float('nan') except RuntimeError: img_arr[i, j] = float('nan') else: t0 = time.time() #set thread up api = ocl_api() device = api.get_platforms()[0].get_devices()[ 2] #Do in setting later #print('Performing on {}'.format(device)) thread = api.Thread(device) thread.device_params.local_mem_size = 32768 #Due to Apple bug - reported 01/21 by Bogdan #Take IRF, FFT and conj it on CPU and then send to GPU (1) IRF_pix = np.conj(np.fft.fft(IRF_pix)) #A complex128 #chop up the data into 64x64 chunks as at a adc_re of 4096 (max) this is the largest the AMD card can handle. image_data = cubify(image_data, (64, 64, number_bins)) IRF_arr = np.full(image_data[0].shape, IRF_pix) out_arr = np.zeros( (image_data.shape[0], image_data.shape[1], image_data.shape[2])) #just for max vals t0 = time.time() image_data = image_data.astype('float64') IRF_dev = thread.to_device(IRF_arr) #send to GPU res_dev = thread.array(image_data[0].shape, np.complex128) planC = XCorr2d(image_data[0], IRF_arr).compile(thread) for i in range(image_data.shape[0]): data_dev = thread.to_device(image_data[i]) planC(res_dev, data_dev, IRF_dev) result = np.roll(res_dev.get(), int(number_bins / 2), axis=2) out_arr[i] = np.argmax(result, axis=2) #put it back into a big image img_arr = unblockshaped(out_arr, image_size_x, image_size_y) #Scale and convert to mm img_arr = -img_arr - np.nanmean(-img_arr) img_arr = img_arr * dt * 1e6 * 3e8 * 0.5 #Bit of data manipulation for any pixels that are huge if controller.cut_off_max.get() != '0': super_threshold_indices = img_arr > float( controller.cut_off_max.get()) img_arr[super_threshold_indices] = np.mean(img_arr) #If pixels have no counts (or just noise) then leave them out. if controller.remove_empty_pix.get() == 1: for i in empty_pixels: img_arr[i[0], i[1]] = np.nan ####PLOTS#### #3d# # fig1=plt.figure() # f1_ax=fig1.gca(projection='3d') # x_data=np.arange(image_size_x) # y_data=np.arange(image_size_y) # x_data, y_data=np.meshgrid(x_data, y_data) # surf=f1_ax.plot_surface(x_data, y_data, img_arr, cmap=cm.jet) # fig1.colorbar(surf, shrink=0.5, aspect=5) # fig1.suptitle('3D') #2d# # fig2=plt.figure() # flat_plot=plt.imshow(img_arr, cmap=cm.jet) # fig2.colorbar(flat_plot, shrink=0.5, aspect=5) # fig2.suptitle('2D') #counts# tfin = time.time() - t0 print('Time to process: {} seconds'.format(tfin)) fig3 = plt.figure() cnt_map = plt.imshow(max_arr, cmap=cm.jet, origin='lower') fig3.colorbar(cnt_map, shrink=0.5, aspect=5) print(np.mean(max_arr)) #fig3.suptitle('Counts Map') fig5 = go.Figure(data=[ go.Heatmap(z=img_arr, colorscale='Jet', colorbar=dict(thickness=80, ticklen=3, tickcolor='black', tickfont=dict(size=36, color='black'))) ]) fig5.update_layout(width=1500, height=1500, font=dict(family="Arial", size=36, color="black")) fig5.show() if controller.aspect_togg.get() == 1: if controller.scene_size.get() == '': messagebox.showerror( 'Error', 'You have not entered a scene size!') aspect_dict = dict(x=1, y=1, z=1) else: scene_size = int(controller.scene_size.get()) #mm aspect_dict = dict(x=1, y=1, z=np.nanmax(img_arr) / (scene_size * 1e3)) else: aspect_dict = dict(x=1, y=1, z=1) fig6 = go.Figure(data=[ go.Surface(z=img_arr, colorscale='Jet', colorbar=dict(thickness=40, ticklen=3, tickcolor='black', tickfont=dict(size=9, color='black'))) ]) fig6.update_layout(font=dict(family="Arial", size=9, color="black"), scene=dict(aspectmode='manual', aspectratio=aspect_dict)) fig6.show() #plots one histogram from a bright pixel to check for gating errors etc and check fit #fig4=plt.figure() #plt.plot(times[start_point:end_point], sdt_file.data[0][pixel[0]][pixel[1]][start_point:end_point],'o') #fig4.suptitle('Brightest histogram') plt.show() else: pass