Esempio n. 1
0
File: uPL.py Progetto: FM-Zhang/uPL
def mplot_ANU(ax,
              fnames,
              path='',
              labels='',
              colors='',
              corr=False,
              shiftup=0,
              plot=True,
              xvar='eV',
              norm=False,
              logy=True,
              eps=False,
              cutoffs=(0, -1)):
    # prepare the ground
    if path != 'current':
        path_full = genSZ.device() + path
    elif path == 'current':
        path = Path().absolute()
    path_ori = Path().absolute()
    os.chdir(path_full)

    num_files = len(fnames)

    if labels == '':  # make labels the filenames, if no labels
        labels = []
        for f in fnames:
            labels.append(os.path.splitext(f)[0])

    if colors == '' or colors == 1:  # the colours feature
        colorRev = False
        colors = [
            None
        ] * num_files  # so that the plotting section doesn't throw an error
    elif colors == -1:
        colorRev = True
        colors = [None] * num_files
    elif type(colors) == list:
        colorRev = False
    else:
        raise TypeError(
            'The colors have to be in list format. The number of colors specificed have to equal the number of PL spectra'
        )

    # if colors are specified, they will override this
    if colorRev == True:
        mpl.rcParams['axes.prop_cycle'] = plt.cycler(
            color=plt.cm.rainbow(np.linspace(1, 0.1, num_files)))
    else:
        mpl.rcParams['axes.prop_cycle'] = plt.cycler(
            color=plt.cm.rainbow(np.linspace(0.1, 1, num_files)))

    # Adjust for correction

    if corr == True or corr == False:
        corr = [corr] * num_files
    elif type(corr) != list or len(corr) != num_files:
        raise NameError(
            'Please ensure variable corr is of type bool or list, and has the same number of elements as files to be processed. Lists use sq brackets []'
        )

    # Adjust for shiftup
    if type(shiftup) == int or type(shiftup) == float:
        shiftup = np.full(num_files, shiftup)
    elif shiftup != list or len(shiftup) != num_files:
        raise NameError(
            'Please ensure variable corr is of type int, float, or list, and has the same number of elements as files to be processed. Lists use sq brackets []'
        )

    # load data
#    data = np.empty((0,0))
#    for f in fnames:
#        i = fnames.index(f)
#        data = np.concatenate((data,load_corr_ANU(f,path=path,corr=corr[i],shiftup=shiftup[i])))
#        print(data)
    data = []
    for f in fnames:
        i = fnames.index(f)
        data.append(
            load_corr_ANU(f,
                          path=path,
                          corr=corr[i],
                          shiftup=shiftup[i],
                          cutoffs=cutoffs))
    data = list(
        zip(*data)
    )  # transpose the list of lists, and make it a list of lists instead of a list of tuples so I can call elements

    eV = data[0]
    PL = data[1]
    PLn = data[2]
    wvl = data[3]
    PL_wvl = data[4]
    PLn_wvl = data[5]

    # return to original directory
    os.chdir(path_ori)

    #x-axis wvl or eV?
    if xvar == 'wvl':
        xax = wvl
        xlabel = r'$ \rm Wavelength~[nm] $'
        PL_plot = PL_wvl
        if norm == True:
            PL_plot = PLn_wvl
    elif xvar == 'eV':
        xax = eV
        xlabel = r'$ \rm Emission~Energy~[eV] $'
        PL_plot = PL
        if norm == True:
            PL_plot = PLn
    else:
        raise Exception('The x-axis must be in wvl or eV')
    # Do we plot?
    if plot == False:
        return (eV, PL, PLn, wvl, PL_wvl, PLn_wvl)
    elif plot != True:
        raise NameError('The variable plot must be a boolean')

    # Why, I shall plot, of course
    if logy == False:
        for i in range(num_files):
            ax.plot(xax[i], PL_plot[i], label=labels[i], color=colors[i], lw=1)
    elif logy == True:
        for i in range(num_files):
            #            print(np.shape(PL_plot[1]))
            if type(eps) == float or type(eps) == int:  # apply epsilon cutting
                y = np.where(
                    PL_plot[i] > eps, PL_plot[i], eps
                )  # account for possible length differences between lines in PL_plot
                ax.semilogy(xax[i], y, label=labels[i], color=colors[i], lw=1)
            else:
                ax.semilogy(xax[i],
                            PL_plot[i],
                            label=labels[i],
                            color=colors[i],
                            lw=1)
    else:
        raise Exception('The plot must be linear or semilogy')
    ax.set_xlabel(xlabel)
    ax.legend()
    ax.set_ylabel(r'$ \rm PL~Intensity~[AU] $')
    plt.tight_layout()

    return (eV, PL, PLn, wvl, PL_wvl, PLn_wvl)
Esempio n. 2
0
File: uPL.py Progetto: FM-Zhang/uPL
def load_corr_ANU(fname, path='', corr=False, shiftup=0, cutoffs=(0, -1)):
    # Go to the target directory
    if path != 'current':
        path = genSZ.device() + path
    else:
        path = Path().absolute()

    path_ori = Path().absolute()
    os.chdir(path)

    # load the correction coefficients
    #    np.seterr(invalid='ignore') # invalid (probably NaN) values exist in the below operation. use this to override the warning. Corresponding expression below sets it back
    corr_InGaAs = np.loadtxt(
        genSZ.device() +
        'Modules/Correction base files/ANU QE/no laser corrected.txt'
    )[:,
      1] / np.loadtxt(genSZ.device() +
                      'Modules/Correction base files/ANU QE/no laser.txt')[:,
                                                                           1]
    corr_Si = np.loadtxt(
        genSZ.device() +
        'Modules/Correction base files/ANU QE/Si corrected.txt'
    )[:, 1] / np.loadtxt(
        genSZ.device() +
        'Modules/Correction base files/ANU QE/Si uncorrected.txt')[:, 1]
    #    np.seterr(invalid='warn')

    # load and return to the original path
    wvl, PL = np.loadtxt(fname, unpack=True)
    os.chdir(path_ori)

    if np.any(wvl) > 1200:
        detector = 'InGaAs'
    else:
        detector = 'Si'

    PL = PL + shiftup
    if corr == True:
        if detector == 'InGaAs':
            PL = PL * corr_InGaAs
        elif detector == 'Si':
            PL = PL * corr_Si
    elif corr != False:
        raise NameError('The correction variable must be True or False')

    PL_wvl = PL

    dw = np.gradient(wvl)
    dw = dw / dw.max()
    eV = conSZ.nm2eV / wvl

    PL = PL_wvl / (eV**2 * dw)

    PL = PL[cutoffs[0]:cutoffs[1]]
    PL_wvl = PL_wvl[cutoffs[0]:cutoffs[1]]
    eV = eV[cutoffs[0]:cutoffs[1]]
    wvl = wvl[cutoffs[0]:cutoffs[1]]

    PLn = PL / PL.max()
    PLn_wvl = PL_wvl / PL_wvl.max()

    return (eV, PL, PLn, wvl, PL_wvl, PLn_wvl)
Esempio n. 3
0
File: uPL.py Progetto: FM-Zhang/uPL
def imap(filename,
         path,
         times,
         Nx,
         Ny,
         dx,
         dy,
         dark='PL0.csv',
         detector='InGaAs',
         cutoff=0):

    # go to required directory
    if path != 'current':
        path = genSZ.device() + path
    else:
        path = Path().absolute()

    path_ori = Path().absolute()
    os.chdir(path)

    # set up map
    x = np.linspace(0, Nx * dx, Nx)
    y = np.linspace(0, Ny * dy, Ny)
    extent = (x.min(), x.max(), y.min(), y.max())

    # Import map and PL0
    PL0, noise = np.loadtxt(dark,
                            skiprows=80,
                            usecols=(6, 7),
                            delimiter=',',
                            unpack=True)
    PL = np.loadtxt(filename)
    PL = PL[:, 2:]

    # Spectrum corrections setup: QE, wvl to eV, averaging wvl
    path = genSZ.device(
    ) + 'Modules/'  # make sure that it's using the QE files in the Modules folder
    if detector == "InGaAs":
        wvl, QE = np.loadtxt(path + 'QE_InGaAs.csv',
                             unpack=True,
                             delimiter=',',
                             skiprows=1,
                             usecols=(0, 1))
    elif detector == "Si":
        #            wvl, QE = np.loadtxt(path+'QE_Si.csv', unpack=True,
        #                             delimiter = ',', skiprows=1, usecols = (0, 1))
        wvl, QE = np.loadtxt(
            path + 'QE_Si_Avantes.csv',
            unpack=True,  # the calibration using the lamp
            delimiter=',',
            skiprows=1,
            usecols=(0, 3))
        PL = PL[:, 138:2041]
        PL0 = PL0[138:2041]
        noise = noise[138:2041]  # end of Avantes calibration
    else:
        raise NameError('Detector must be string named InGaAs or Si')

    Nw = len(wvl)
    dw = np.gradient(
        wvl
    )  # for elements in a 1D array it will output half the difference between the elements proceeding and following that element
    dw = dw / dw.max()
    eV = conSZ.nm2eV / wvl

    # spectral corrections
    PL_eV = (PL - times * PL0) / (QE * eV**2 * dw)
    PL_wvl = (PL - times * PL0) / (QE * dw)

    # reshape the data: 2D -> 3D
    PL_eV = np.reshape(PL_eV, (Nx, Ny, Nw))
    PL_eV[1::2, :, :] = PL_eV[1::2, ::-1, :]
    PL_eV = np.flipud(PL_eV)
    PL_eV = np.rot90(PL_eV, 3)
    PL_wvl = np.reshape(PL_wvl, (Nx, Ny, Nw))
    PL_wvl[1::2, :, :] = PL_wvl[1::2, ::-1, :]
    PL_wvl = np.flipud(PL_wvl)
    PL_wvl = np.rot90(PL_wvl, 3)

    # Cut-off data where needed
    if cutoff < 0:
        PL_eV = PL_eV[:, :, :cutoff]
        PL_wvl = PL_wvl[:, :, :cutoff]
        PL0 = PL0[:cutoff]
        eV = eV[:cutoff]
        wvl = wvl[:cutoff]
    elif cutoff >= 0:
        PL_eV = PL_eV[:, :, cutoff:]
        PL_wvl = PL_wvl[:, :, cutoff:]
        PL0 = PL0[cutoff:]
        eV = eV[cutoff:]
        wvl = wvl[cutoff:]
    # go back to previous directory
    os.chdir(path_ori)
    return PL_wvl, PL_eV, wvl, eV, PL0, noise, extent
Esempio n. 4
0
File: uPL.py Progetto: FM-Zhang/uPL
def load_correct_0d(filename,
                    detector,
                    times,
                    xvar='eV',
                    delimiter=',',
                    cutoff=0):

    #load data. unpack transposes the ndarray output
    PL0, PL = np.loadtxt(filename,
                         skiprows=80,
                         usecols=(4, 6),
                         delimiter=delimiter,
                         unpack=True)
    info = pd.read_csv(filename,
                       delimiter=delimiter,
                       usecols=(0, 1),
                       index_col='Name',
                       header=0,
                       names=['Name', 'Value'])
    t_int = np.float(info.loc['intigration times(ms)'])
    n_avg = np.float(info.loc['average number'])
    # Spectrum corrections setup
    path = genSZ.device(
    ) + 'Modules/'  # make sure that it's using the QE files in the Modules folder
    if detector == "InGaAs":
        wvl, QE = np.loadtxt(path + 'QE_InGaAs.csv',
                             unpack=True,
                             delimiter=',',
                             skiprows=1,
                             usecols=(0, 1))
    elif detector == "Si":
        #            wvl, QE = np.loadtxt(path+'QE_Si.csv', unpack=True,
        #                             delimiter = ',', skiprows=1, usecols = (0, 1))
        wvl, QE = np.loadtxt(
            path + 'QE_Si_Avantes.csv',
            unpack=True,  # the calibration using the lamp
            delimiter=',',
            skiprows=1,
            usecols=(0, 3))
        PL = PL[138:2041]
        PL0 = PL0[138:2041]
    else:
        raise NameError('Detector must be string named InGaAs or Si')

    dw = np.gradient(
        wvl
    )  # for elements in a 1D array it will output half the difference between the elements proceeding and following that element
    dw = dw / dw.max()
    eV = conSZ.nm2eV / wvl

    if xvar == 'eV':
        PL = (PL - times * PL0) / (QE * eV**2 * dw)
    elif xvar == 'wvl':
        PL = (PL - times * PL0) / (QE * dw)
    else:
        raise Exception('The x-axis must be in wvl or eV')

    # Cut-off data where needed
    if cutoff < 0:
        PL = PL[:cutoff]
        PL0 = PL0[:cutoff]
        eV = eV[:cutoff]
        wvl = wvl[:cutoff]
    elif cutoff >= 0:
        PL = PL[cutoff:]
        PL0 = PL0[cutoff:]
        eV = eV[cutoff:]
        wvl = wvl[cutoff:]
    return PL, wvl, eV, PL0, t_int, n_avg
Esempio n. 5
0
File: uPL.py Progetto: FM-Zhang/uPL
def mplot(filenames,
          times,
          path='',
          labels='',
          detector='Si',
          plot=True,
          xvar='eV',
          norm=False,
          logy=True,
          colors='',
          delimiter=',',
          cutoff=0,
          ratio=0,
          offset=False):
    # prepare the ground
    if path != 'current':
        path = genSZ.device() + path
    elif path == 'current':
        path = Path().absolute()
    path_ori = Path().absolute()
    os.chdir(path)

    if detector == 'Si':  # which detector
        #        length=2048-np.abs(cutoff) # this is for the default Si calibration with blackbody at 400C, which uRob rarely uses and is therefore not optimal
        length = 1903 - np.abs(
            cutoff
        )  # this is measured with a lamp, the bottom turrent position #6 which I think is probably empty
    elif detector == "InGaAs":
        length = 512 - np.abs(cutoff)
    else:
        raise NameError('The detector must be Si or InGaAs')

    num_files = len(
        filenames)  #the number of files this function will need to process

    if labels == '':  # make labels the filenames, if no labels
        labels = []
        for f in filenames:
            labels.append(os.path.splitext(f)[0])

    if colors == '' or colors == 1:  # the colours feature
        colorRev = False
        colors = [None] * num_files
    elif colors == -1:
        colorRev = True
        colors = [None] * num_files
    elif type(colors) == list:
        colorRev = False
    else:
        raise TypeError(
            'The colors have to be in list format. The number of colors specificed have to equal the number of PL spectra'
        )
#    try:
    if colorRev == True:
        mpl.rcParams['axes.prop_cycle'] = plt.cycler(
            color=plt.cm.rainbow(np.linspace(1, 0.1, num_files)))
    else:
        mpl.rcParams['axes.prop_cycle'] = plt.cycler(
            color=plt.cm.rainbow(np.linspace(0.1, 1, num_files)))
#    except:
#        pass

    if type(times) == float or type(
            times) == int:  # allowing customisation of the times variable
        mul = np.empty((num_files, length))
        for i in range(len(mul)):
            mul[i] = times
    elif len(times) != num_files:
        raise Exception(
            'The times variable must be a float, or an array with the same length as the filenames array'
        )

    #load the data
    PL = np.empty((num_files, length))
    wvl = np.empty((num_files, length))
    eV = np.empty((num_files, length))
    PL0 = np.empty((num_files, length))
    t_int = np.empty((num_files, 1))
    n_avg = np.empty((num_files, 1))

    for f in filenames:
        i = filenames.index(f)
        PL[i], wvl[i], eV[i], PL0[i], t_int[i], n_avg[i] = load_correct_0d(
            filename=f,
            times=times,
            detector=detector,
            xvar=xvar,
            delimiter=delimiter,
            cutoff=cutoff)

    # return to original directory
    os.chdir(path_ori)

    # account for possible different integration times or multipliers
    if ratio == 0:
        pass
    elif type(ratio) == int or type(ratio) == float:
        for i in range(num_files):
            PL[i] = PL[i] / ratio
    elif len(ratio) == num_files:
        for i in range(num_files):
            PL[i] = PL[i] / ratio[i]
    else:
        raise Exception(
            'The ratio variable must be zero, or have length 1, or an array with the same length as the filenames array'
        )

    # Do we plot?
    if plot == False:
        return PL, wvl, eV, PL0, t_int, n_avg
    elif plot != True:
        raise NameError('The variable plot must be a boolean')
    # prep the data for plotting
    PL_plot = np.empty((num_files, length))
    xax = np.empty((num_files, length))

    if norm == True:  #possible normalisation
        for i in range(num_files):
            PL_plot[i] = PL[i] / PL[i].max()
    elif norm == False:
        PL_plot = PL
    else:
        raise NameError(
            'You must specify whether the graph should be normalised')

    if xvar == 'wvl':  #x-axis wavelength or energy?
        xax = wvl
        xlabel = r'$ \rm Wavelength~[nm] $'
    elif xvar == 'eV':
        xax = eV
        xlabel = r'$ \rm Emission~Energy~[eV] $'
    else:
        raise Exception('The x-axis must be in wvl or eV')

    # plot, both the semilogy and the linear plot
    if logy == True:
        eps = 0.3
        PL_plot = np.flip(PL_plot, axis=0)
        PL_plot = np.where(PL_plot > eps, PL_plot, eps)
        if type(offset) == int or type(offset) == float:
            for i in range(num_files):
                PL_plot[i] = PL_plot[i] * offset**i
        for i in range(num_files):
            plt.semilogy(xax[i],
                         PL_plot[i],
                         label=labels[i],
                         color=colors[i],
                         lw=1)
    elif logy == False:
        if type(offset) == int or type(offset) == float:
            for i in range(num_files):
                PL_plot[i] = PL_plot[i] + offset * i
        for i in range(num_files):
            plt.plot(xax[i],
                     PL_plot[i],
                     label=labels[i],
                     color=colors[i],
                     lw=1)
    else:
        raise Exception(
            'The plot must be linear or semilogy, the variable must be a Boolean'
        )

    plt.xlabel(xlabel)
    plt.legend()
    plt.ylabel(r'$ \rm PL~Intensity~[AU] $')
    plt.tight_layout()

    return PL, wvl, eV, PL0, t_int, n_avg