Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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')
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
    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
Ejemplo n.º 6
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()
Ejemplo n.º 8
0
    #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)
Ejemplo n.º 9
0
        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)
Ejemplo n.º 10
0
def readfile(path):
    sdt = SdtFile(path)
    reshaped = np.reshape(sdt.data[0], (512, -1, 256))[:, :1250, :]
    return reshaped
Ejemplo n.º 11
0
    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