diff --git a/181K_GN_Package.zip b/181K_GN_Package.zip deleted file mode 100644 index 80bd41a..0000000 Binary files a/181K_GN_Package.zip and /dev/null differ diff --git a/191K_GN_Package.zip b/191K_GN_Package.zip deleted file mode 100644 index f257935..0000000 Binary files a/191K_GN_Package.zip and /dev/null differ diff --git a/2023May_100ns_alpha.csv b/2023May_100ns_alpha.csv deleted file mode 100644 index 3d22b5e..0000000 --- a/2023May_100ns_alpha.csv +++ /dev/null @@ -1,17 +0,0 @@ -,Bias voltage [V],Bias voltage [V] error,Alpha Pulse Amplitude [V],Alpha Pulse Amplitude [V] error -0,28.5,0.08625000000000001,0.028009033970152898,3.249707741529069e-05 -1,29.0,0.0875,0.08727488009828935,7.764165446026013e-05 -2,29.5,0.08875,0.15568700458584298,6.473247139000486e-05 -3,30.0,0.09,0.23198482967127615,8.48870606426965e-05 -4,30.5,0.09125,0.31267505382916255,0.00015149064513088686 -5,31.0,0.0925,0.40818662643256276,0.00018905592378484664 -6,31.5,0.09375,0.5160954304598626,0.0002795306551075519 -7,32.0,0.095,0.6410273882344782,0.00028145685731121765 -8,32.5,0.09625,0.7827084721934965,0.0005078297668612443 -9,33.0,0.0975,0.9554176824886271,0.0004881016336482213 -10,33.5,0.09875,1.1629936034079476,0.0007274367637879921 -11,34.0,0.1,1.4041173969096357,0.0010871221927317449 -12,34.5,0.10125,1.7229636600884872,0.0012238012413472955 -13,35.0,0.10250000000000001,2.1301697146593717,0.0011186026142756948 -14,35.5,0.10375,2.629829172763848,0.0011383565502673797 -15,36.0,0.105,3.2306190926509135,0.0015761990190051199 diff --git a/217K_GN_Package.zip b/217K_GN_Package.zip deleted file mode 100644 index 5b0891d..0000000 Binary files a/217K_GN_Package.zip and /dev/null differ diff --git a/221K_GN_Package.zip b/221K_GN_Package.zip deleted file mode 100644 index fdcbd4b..0000000 Binary files a/221K_GN_Package.zip and /dev/null differ diff --git a/234K_GN_Package.zip b/234K_GN_Package.zip deleted file mode 100644 index fb33088..0000000 Binary files a/234K_GN_Package.zip and /dev/null differ diff --git a/AnalyzePDE.py b/AnalyzePDE.py index 3cba92f..1562bba 100644 --- a/AnalyzePDE.py +++ b/AnalyzePDE.py @@ -323,6 +323,7 @@ def plot_spe( } df = pd.DataFrame(data) df.to_csv(out_file) + plt.show() def plot_CA(self, color: str = "blue", out_file: str = None) -> None: """ @@ -343,6 +344,7 @@ def plot_CA(self, color: str = "blue", out_file: str = None) -> None: fig = plt.figure() data_x = self.ov + # data_x = self.bias_vals data_x_err = self.bias_err data_y = self.CA_vals data_y_err = self.CA_err @@ -403,6 +405,8 @@ def plot_CA(self, color: str = "blue", out_file: str = None) -> None: } df = pd.DataFrame(data) df.to_csv(out_file) + else: + plt.show() def plot_CA_rms(self, color: str = "blue", out_file: str = None) -> None: """ @@ -424,6 +428,8 @@ def plot_CA_rms(self, color: str = "blue", out_file: str = None) -> None: data_x = self.bias_vals data_x_err = self.bias_err + # data_x = self.ov + # data_x_err = self.ov_err data_y = self.CA_rms_vals data_y_err = self.CA_rms_err @@ -463,6 +469,8 @@ def plot_CA_rms(self, color: str = "blue", out_file: str = None) -> None: } df = pd.DataFrame(data) df.to_csv(out_file) + else: + plt.show() # I HAVE A SECRET TO TELL YOU! (it was reed who wrote that message and thwy are pinning it on me) @@ -760,7 +768,7 @@ def plot_num_det_photons(self, color: str = "purple", out_file: str = None) -> N fig = plt.figure() data_x = self.ov - data_x_err = self.bias_err + data_x_err = self.bias_err # use error from voltage source, not over correlated error from OV data_y = self.num_det_photons data_y_err = self.num_det_photons_err @@ -790,6 +798,7 @@ def plot_num_det_photons(self, color: str = "purple", out_file: str = None) -> N ylow, yhigh = plt.ylim() plt.ylim(-1, yhigh * 1.1) plt.tight_layout() + plt.show() if out_file: x_label = "Overvoltage [V]" @@ -872,13 +881,10 @@ def plot_PDE( plt.legend(loc="lower left") plt.tight_layout() if out_file: - x_label = "Overvoltage [V]" - y_label = "Photon Detection Efficiency" data = { - x_label: data_x, - x_label + " error": data_x_err, - y_label: data_y, - y_label + " error": data_y_err, + 'ov': data_x, 'ov error': data_x_err, + 'amps': self.alpha_vals, 'amps error': self.alpha_err, + 'bias': self.bias_vals, 'bias err': self.bias_err } df = pd.DataFrame(data) df.to_csv(out_file) diff --git a/AnalyzePhotons.py b/AnalyzePhotons.py new file mode 100644 index 0000000..164fa60 --- /dev/null +++ b/AnalyzePhotons.py @@ -0,0 +1,871 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Mar 1 16:35:32 2024 + +@author: Hannah +""" + +import lmfit as lm +import numpy as np +import matplotlib.pyplot as plt +from scipy import signal +from scipy import stats +from scipy import optimize +from scipy import interpolate +from scipy.stats import sem +import statistics +import matplotlib as mpl +import pprint +import pandas as pd +from typing import Any, Dict, List, Tuple, Optional +from MeasurementInfo import MeasurementInfo +#%% +def errorprop(tupled_err1, tupled_err2, combo = "multiplication"): + val1, error1 = tupled_err1 + val2, error2 = tupled_err2 + if combo == "multiplication": + percent1 = error1/val1 + percent2 = error2/val2 + prop = np.sqrt(percent1**2 + percent2**2) + else: + prop = np.sqrt(error1**2+error2**2) + return prop +#%% +def get_v_bd(spe, spe_err, bias, bias_err): # gets v_bd of CA data + model = lm.models.LinearModel() + params = model.make_params() + spe_wgts = spe_wgts = [1.0 / curr_std for curr_std in spe_err] + spe_res = model.fit(spe, params=params, x=bias, weights=spe_wgts) + + # linear fit + b_spe = spe_res.params["intercept"].value + m_spe = spe_res.params["slope"].value + v_bd = -b_spe / m_spe + return v_bd +#%% +def plot_CA(ov, ov_err, CA_vals, CA_err, alpha_ov_vals, color = 'blue'): + color = 'tab:' + color + + data_x = ov + data_x_err = ov_err + data_y = CA_vals + data_y_err = CA_err + + CA_model = lm.Model(CA_func) + CA_params = CA_model.make_params(A = 1, B = .1) + CA_wgts = [1.0 / curr_std for curr_std in CA_err] + CA_res = CA_model.fit(CA_vals, params=CA_params, x=ov, weights=CA_wgts) + + fit_x = np.linspace(0.0, 10.0, num = 100) + fit_y = CA_res.eval(params=CA_res.params, x = fit_x) + fit_y_err = CA_res.eval_uncertainty(x = fit_x, params = CA_res.params, sigma = 1) + + plt.fill_between(fit_x, fit_y + fit_y_err, fit_y - fit_y_err, color = color, alpha = .5) + plt.plot(fit_x, fit_y, color = color) #, label = r'$\frac{Ae^{B*V_{OV}}+1}{A + 1} - 1$ fit' + plt.errorbar(data_x, data_y, xerr = data_x_err, yerr = data_y_err, markersize = 7, fmt = '.', label = r'$\frac{1}{N}\sum_{i=1}^{N}{\frac{A_i}{\bar{A}_{1 PE}}-1}$') + + x_label = 'Overvoltage [V]' + y_label = 'Number of CA [PE]' + plt.xlabel(x_label) + plt.ylabel(y_label) + plt.tight_layout() + + out_vals = CA_res.eval(params=CA_res.params, x=alpha_ov_vals) + out_err = CA_res.eval_uncertainty(x=alpha_ov_vals, sigma=1) + return out_vals, out_err + +def load_CA(path, + v_bd, + return_bias = False, + ov_key = ('Overvoltage [V]', 'Overvoltage [V] error'), + CA_key = ('Number of CA [PE]', 'Number of CA [PE] error') + ): + print('reading in CAs...') + df = pd.read_csv(path) + print('reading columns ' + ov_key[0] + ' , ' + ov_key[1]) + ov_vals = np.array(df[ov_key[0]]) + ov_err = np.array(df[ov_key[1]]) + print('reading columns ' + CA_key[0] + ' , ' + CA_key[1]) + CA_vals = np.array(df[CA_key[0]]) + CA_vals_err = np.array(df[CA_key[1]]) + + bias_vals = np.array([V + v_bd for V in ov_vals]) + if not return_bias: + return (ov_vals,ov_err), (CA_vals,CA_vals_err) + else: + return (bias_vals,ov_err), (CA_vals,CA_vals_err) + + +def load_data(path, + v_bd = 0.0, + return_ov = False, + data_type = 'Alpha', + bias_key = ('Bias Voltage [V]', 'Bias Voltage [V] error'), + data_key = ('Alpha Pulse Amplitude [V]', 'Alpha Pulse Amplitude [V] error') + ): + + print('reading in data of type '+ data_type) + df = pd.read_csv(path) + print('reading column ' + bias_key[0]) + bias_vals = df[bias_key[0]] + print('reading column ' + bias_key[1]) + bias_err = df[bias_key[1]] + print('reading column ' + data_key[0]) + vals = np.array(df[data_key[0]]) + print('reading column ' + data_key[1]) + vals_err = np.array(df[data_key[1]]) + + if data_type == 'SPE' and data_key == 'Alpha Pulse Amplitude [V]' or None: + print('Warning: data_type ' + data_type + ' does not match provided key name ' + data_key + '. Changing key name...') + data_key = ('SPE Amplitude [V]','SPE Amplitude [V] error') + # bias_key = bias_key = ('Bias voltage [V]', 'Bias voltage [V] error') + + if v_bd == 0.0 and return_ov: + print('Breakdown voltage not provided. Returning bias values.') + if return_ov and v_bd != 0.0: + ov_vals = np.array([V - v_bd for V in bias_vals]) + ov_err = np.array(bias_err) + return (ov_vals,ov_err), (vals,vals_err) + else: + return (bias_vals,bias_err), (vals,vals_err) + +#%% +def CA_func(x, A, B): + return (A * np.exp(B * x) + 1.0) / (1.0 + A) - 1.0 +class CorrelatedAvalancheProbability: + def __init__( + self, + path: str, + v_bd: float = 0.0, + return_bias: bool = False, + ov_key = ('Overvoltage [V]', 'Overvoltage [V] error'), + CA_key = ('Number of CA [PE]', 'Number of CA [PE] error') + ): + self.path = path + self.v_bd = v_bd + self.return_bias = return_bias + self.ov_key = ov_key + self.CA_key = CA_key + + if self.v_bd == 0.0 and self.return_bias == True: + print('Breakdown voltage not provided. Setting return_bias to False.') + self.return_bias == False + + self.x, self.y = load_CA(self.path, self.v_bd, ov_key = self.ov_key, CA_key = self.CA_key, return_bias = self.return_bias) # x = voltage, y = CA + + def fit_CA(self, plot = True, with_fit = True, color = 'blue', evaluate = True, eval_x = [], max_OV = 10, show_label = True): + if self.return_bias: + print('Warning: data was loaded with bias values, not OV. CA fit will not function') + color = color + + data = np.array(list(zip(self.x[0],self.x[1],self.y[0],self.y[1]))) + data = data[data[:,0] < max_OV] # get only the data with OV < max_OV + + data_x, data_x_err = data[:,0], data[:,1] + data_y, data_y_err = data[:,2], data[:,3] + + CA_model = lm.Model(CA_func) + CA_params = CA_model.make_params(A = 1, B = .1) + CA_wgts = [1.0 / curr_std for curr_std in data_y_err] + CA_res = CA_model.fit(data_y, params=CA_params, x=data_x, weights=CA_wgts) + fit_x = np.linspace(0.0, float(max_OV)+1.0, num = 100) + fit_y = CA_res.eval(params=CA_res.params, x = fit_x) + fit_y_err = CA_res.eval_uncertainty(x = fit_x, params = CA_res.params, sigma = 1) + + if plot: + if with_fit: + plt.fill_between(fit_x, fit_y + fit_y_err, fit_y - fit_y_err, color = color, alpha = .5) + plt.plot(fit_x, fit_y, color = color, label = r'$\frac{Ae^{B*V_{OV}}+1}{A + 1} - 1$ fit') + plt.errorbar(data_x, data_y, xerr = data_x_err, yerr = data_y_err, color = color, markersize = 7, fmt = '.', label = r'$\frac{1}{N}\sum_{i=1}^{N}{\frac{A_i}{\bar{A}_{1 PE}}-1}$') + x_label = 'Overvoltage [V]' + y_label = 'Number of CA [PE]' + textstr = f"""A: {CA_res.params['A'].value:0.3} $\pm$ {CA_res.params['A'].stderr:0.3}\n""" + textstr += f"""B: {CA_res.params['B'].value:0.2} $\pm$ {CA_res.params['B'].stderr:0.2}\n""" + textstr += rf"""Reduced $\chi^2$: {CA_res.redchi:0.4}""" + props = dict(boxstyle="round", facecolor=color, alpha=0.4) + if show_label == True: + plt.text(0.17, 1, textstr, fontsize=10, verticalalignment="top", bbox=props) + plt.xlabel(x_label, fontsize=14) + plt.ylabel(y_label, fontsize=14) + plt.tight_layout() + plt.legend() + plt.grid(True) + + if evaluate and len(eval_x) > 0: + eval_x = eval_x[eval_x < max_OV] + out_vals = CA_res.eval(params=CA_res.params, x=eval_x) + out_err = CA_res.eval_uncertainty(x=eval_x, sigma=1) + return out_vals, out_err + + def return_CA_vals(self, printout = True): + if printout: + print('(CA, CA_err):') + return self.y[0], self.y[1] + + def get_V(self, tupled = True): + if tupled: + return list(zip(self.x[0],self.x[1])) + else: + return self.x[0], self.x[1] + + def get_CA_eval(self, tupled = True, values = [], max_OV = 10.0): #gets CA evaluated at a chosen value + out_vals, out_err = self.fit_CA(plot = False, with_fit = False, evaluate = True, eval_x = values, max_OV = max_OV) + if tupled: + return list(zip(out_vals, out_err)) + return out_vals, out_err + +#%% +class SPEData: + def __init__( + self, + path: str, # path to file + invC_spe: tuple = (None, None), + return_ov: bool = True, # work in terms of OV or not + #set these if for some reason CSV file has differently named columns + bias_key: tuple = (None,None), + spe_key: tuple = ('SPE Amplitude [V]','SPE Amplitude [V] error'), + shaper: str = '1 $\mu$s', + filtering: str = '400 kHz', + color: str = "red", + ): + self.path = path + self.invC_spe, self.invC_spe_err = invC_spe + self.return_ov = return_ov + self.bias_key = bias_key + self.spe_key = spe_key + self.shaper = shaper + self.filtering = filtering + self.color = color + + print('Using conversion invC = ' + str(self.invC_spe) + ' +/- ' + str(self.invC_spe_err) + ' for spe data') + + print('loading SPE data from file: ' + str(self.path)) + self.bias_spe, self.amp_spe = load_data(self.path, + data_type = 'SPE', + bias_key = self.bias_key, + data_key = self.spe_key, + return_ov = False # do not put in terms of OV right now + ) + + spe = self.amp_spe[0] + spe_err = self.amp_spe[1] + bias = self.bias_spe[0] + bias_err = self.bias_spe[1] + model = lm.models.LinearModel() + params = model.make_params() + spe_wgts = spe_wgts = [1.0 / curr_std for curr_std in spe_err] + self.spe_res = model.fit(spe, params=params, x=bias, weights=spe_wgts) + + def get_v_bd(self, plot = False): # method to get the breakdown voltage from provided SPE values + spe = self.amp_spe[0] + spe_err = self.amp_spe[1] + bias = self.bias_spe[0] + bias_err = self.bias_spe[1] + spe_res = self.spe_res + + # linear fit + b_spe = spe_res.params["intercept"].value + m_spe = spe_res.params["slope"].value + v_bd = -b_spe / m_spe + vec_spe = np.array([b_spe / (m_spe * m_spe), -1.0 / m_spe]) + v_bd_err = np.sqrt( + np.matmul( + np.reshape(vec_spe, (1, 2)), + np.matmul(spe_res.covar, np.reshape(vec_spe, (2, 1))), + )[0, 0] + ) + if plot: + start_bias = v_bd + end_bias = np.amax(bias) + 1.0 + fit_bias = np.linspace(start_bias, end_bias, 20) + fit_y = spe_res.eval(params=spe_res.params, x=fit_bias) + fit_y_err = spe_res.eval_uncertainty( + x=fit_bias, params=spe_res.params, sigma=1 + ) + fit_label = "SPE Amplitude Best Fit" + data_label = "SPE Amplitude values" + y_label = "SPE Amplitude [V]" + data_y = spe + data_y_err = spe_err + chi_sqr = spe_res.redchi + slope_text = rf"""Slope: {self.spe_res.params['slope'].value:0.4} $\pm$ {self.spe_res.params['slope'].stderr:0.2} [V/V]""" + intercept_text = rf"""Intercept: {self.spe_res.params['intercept'].value:0.4} $\pm$ {self.spe_res.params['intercept'].stderr:0.2} [V]""" + parameter_text = slope_text + fit_x = fit_bias + data_x = bias + data_x_err = bias_err + x_label = "Bias Voltage [V]" + parameter_text += f"""\n""" + parameter_text += intercept_text + parameter_text += f"""\n""" + parameter_text += rf"""Reduced $\chi^2$: {chi_sqr:0.4}""" + parameter_text += f"""\n""" + plt.fill_between( + fit_x, fit_y + fit_y_err, fit_y - fit_y_err, color="red", alpha=0.5 + ) + plt.plot(fit_x, fit_y, color="red", label=fit_label) + plt.errorbar( + data_x, + data_y, + xerr=data_x_err, + yerr=data_y_err, + markersize=6, + fmt=".", + label=data_label, + ) + plt.xlabel(x_label) + plt.ylabel(y_label) + plt.legend() + textstr = self.filtering + textstr += f"--\n" + textstr += parameter_text + textstr += f"--\n" + textstr += rf"Breakdown Voltage: {v_bd:0.4} $\pm$ {v_bd_err:0.3} [V]" + + props = dict(boxstyle="round", facecolor='blue', alpha=0.4) + plt.text(0.6, 0.45, textstr, fontsize=8, verticalalignment="top", bbox=props) + plt.tight_layout() + plt.grid(True) + + print('Breakdown voltage: ' + str(v_bd) + ' +/- ' + str(v_bd_err)) + return v_bd, v_bd_err + + def get_SPEs(self, input_vals, in_ov = False, tupled = True): # method to get SPE value at a list of given OV or bias + spe_res = self.spe_res + b_spe = spe_res.params["intercept"].value + m_spe = spe_res.params["slope"].value + v_bd = -b_spe / m_spe + if in_ov or min(input_vals) < 10: + input_vals = input_vals + v_bd + if min(input_vals < 10): + print('Warning: SPE requested for bias voltage of less than 10V. Did you mean to set in_ov = True?') + + out_vals = spe_res.eval(params=spe_res.params, x=input_vals) + out_err = spe_res.eval_uncertainty(x=input_vals, sigma=1) + if tupled: + return list(zip(out_vals, out_err)) + else: + return out_vals, out_err +#%% +class AlphaData: #class for alpha data loaded from CSV. assumes columns of alpha amplitudes and bias voltages. SPE values must be loaded concurrently for complete functionality + def __init__( + self, + path: str, # path to file containing alpha amplitudes + spe: SPEData, + invC_alpha: tuple, # conversion factor from electronics calibration and error + path_spe: str = None, # path to file containing SPE amplitudes + v_bd: float = 0.0, # breakdown voltage, optional + return_ov: bool = True, # work in terms of OV or not + reflector: str = "None", + #set these if for some reason CSV file has differently named columns + bias_key: tuple = ('Bias voltage [V]', 'Bias voltage [V] error'), #name of column in CSV file + alpha_key: tuple = ('Alpha Pulse Amplitude [V]', 'Alpha Pulse Amplitude [V] error'), + shaper: str = '1 $\mu$s', + color: str = "red", + mean_subtract: str = None, #optional path to file containing mean of subtracted histograms (if calculating CA from mean, slope. requires SPE data to be loaded) + use_fit_result_only: bool = False #set if you want to use fit evals only or the actual data points + ): + self.path = path + self.spe = spe + self.path_spe = path_spe + self.invC, self.invC_err = invC_alpha + self.invC_spe, self.invC_spe_err = spe.invC_spe, spe.invC_spe_err + self.v_bd = v_bd + self.return_ov = return_ov + self.bias_key = bias_key + self.alpha_key = alpha_key + self.shaper = shaper + self.reflector = reflector + self.filtering = self.spe.filtering + self.mean_subtract = mean_subtract + self.use_fit_result_only = use_fit_result_only + self.color = color + + print('Using conversion invC = ' + str(self.invC) + ' +/- ' + str(self.invC_err) + ' for alpha data') + + self.x_spe, self.y_spe = self.spe.bias_spe, self.spe.amp_spe + + if self.v_bd == 0.0: + print('Breakdown voltage not provided. Calculating breakdown voltage from user-provided SPE data...') + self.v_bd, self.v_bd_err = self.get_v_bd() + + print('loading alpha data from file: ' + str(self.path)) + self.x, self.y = load_data(self.path, + self.v_bd, + data_type = 'Alpha', + bias_key = self.bias_key, + data_key = self.alpha_key, + return_ov = self.return_ov + ) + + self.spe_for_alpha, self.spe_for_alpha_err = self.get_SPEs(self.x[0], in_ov = self.return_ov, tupled = False) #get the SPE values at specifically the OVs indicated for alpha + + self.alpha_in_spe_units = self.y[0]/self.spe_for_alpha * self.invC_spe/self.invC + self.alpha_in_spe_units_err = self.alpha_in_spe_units * np.sqrt((self.y[1] * self.y[1])/(self.y[0] * self.y[0]) + + (self.spe_for_alpha_err*self.spe_for_alpha_err)/(self.spe_for_alpha*self.spe_for_alpha) + + (self.invC_err*self.invC_err)/(self.invC*self.invC) + + (self.invC_spe_err*self.invC_spe_err)/(self.invC_spe*self.invC_spe) + ) + # list of tuples with : V, V err, amp, amp err, spe, spe err + self.data = list(zip(self.x[0],self.x[1],self.y[0],self.y[1], self.spe_for_alpha, self.spe_for_alpha_err)) + self.data_array = np.array(self.data) + + if not self.use_fit_result_only: + self.alpha_bias = self.x[0] + if self.x_spe[0][0] > 10 : #this is misleadingly named but bias => OV + self.spe_bias = self.x_spe[0] - self.v_bd + else: + self.spe_bias = self.x_spe[0] + self.spe_vals_raw = self.y_spe[0] + self.spe_vals_raw_err = self.y_spe[1] + self.color_tracker = np.array([False for i in range(len(self.alpha_bias))]) + for v in self.alpha_bias: #look in list alpha_bias (OV) + if (min(self.spe_bias) - 0.05) < v < (max(self.spe_bias) + 0.05): #for value v that has a measurement of SPE associated with it (OV) + i, = np.where(np.isclose(self.alpha_bias, v)) #get the index of the bias (OV) we are replacing in alpha bias list + j, = np.where(np.isclose(self.spe_bias, v)) #get the index of the bias (OV) we are replacing in spe bias list + if len(self.spe_vals_raw[j]) > 0 and len(self.spe_for_alpha[i])>0: # accounts for situations where SPEs, Alphas are not spaced equally (30.5, 30, 30.5, 31 v.s. 30,31) + print('replacing SPE = '+str(self.spe_for_alpha[i])+' with ' + 'SPE = '+str(self.spe_vals_raw[j]) + ' at OV ' + str(self.alpha_bias[i]) + ' == ' + str(self.spe_bias[j])) + self.spe_for_alpha[i] = self.spe_vals_raw[j] #replace value obtained from doing a fit with actual CA value calculated from mean of amplitudes + self.spe_for_alpha_err[i] = self.spe_vals_raw_err[j] #do the same for the error (we do not want to use the fit error!) + self.color_tracker[i] = True + else: + print('Alpha pulse measurement at ' + str(v) + '[V] does not have an associated SPE gain measurement. Using extrapolated value from linear fit.') + continue + else: + print('Alpha pulse measurement at ' + str(v) + '[V] does not have an associated SPE gain measurement. Using extrapolated value from linear fit.') + + self.alpha_in_spe_units_raw = self.y[0]/self.spe_for_alpha * self.invC_spe/self.invC + self.alpha_in_spe_units_err_raw = self.alpha_in_spe_units * np.sqrt((self.y[1] * self.y[1])/(self.y[0] * self.y[0]) + + (self.spe_for_alpha_err*self.spe_for_alpha_err)/(self.spe_for_alpha*self.spe_for_alpha) + + (self.invC_err*self.invC_err)/(self.invC*self.invC) + + (self.invC_spe_err*self.invC_spe_err)/(self.invC_spe*self.invC_spe) + ) + + def get_SPEs(self, input_vals, in_ov = False, tupled = True): # method to get SPE value at a list of given OV or bias + spe = self.y_spe[0] + spe_err = self.y_spe[1] + bias = self.x_spe[0] + model = lm.models.LinearModel() + params = model.make_params() + spe_wgts = spe_wgts = [1.0 / curr_std for curr_std in spe_err] + spe_res = model.fit(spe, params=params, x=bias, weights=spe_wgts) + spe_res = self.spe.spe_res + # linear fit: + b_spe = spe_res.params["intercept"].value + m_spe = spe_res.params["slope"].value + v_bd = -b_spe / m_spe + + if in_ov or min(input_vals) < 10: + input_vals = input_vals + v_bd + if min(input_vals < 10): + print('Warning: SPE requested for bias voltage of less than 10V. Did you mean to set in_ov = True?') + + out_vals = spe_res.eval(params=spe_res.params, x=input_vals) + out_err = spe_res.eval_uncertainty(x=input_vals, sigma=1) + if tupled: + return list(zip(out_vals, out_err)) + else: + return out_vals, out_err + + def get_v_bd(self): # method to get the breakdown voltage from provided SPE values + return self.spe.get_v_bd(plot = False) + + def plot_alpha(self, color = None, unit = 'V'): + if color == None: + color = self.color + if unit == 'V': + y = self.y[0] + y_err = self.y[1] + y_label = self.alpha_key[0] + if unit == 'PE': + y = self.alpha_in_spe_units + y_err = self.alpha_in_spe_units_err + y_label = "Alpha Amplitude [p.e.] (from SPE gain fit)" + if not self.use_fit_result_only: + y_raw = [b for a, b in zip(self.color_tracker, self.alpha_in_spe_units_raw) if a] + y_raw_err = [b for a, b in zip(self.color_tracker,self.alpha_in_spe_units_err_raw) if a] + y_raw_label = "Alpha Amplitude [p.e.] (from data)" + + plt.errorbar( + self.x[0], + y, + xerr=self.x[1], + yerr=y_err, + markersize=7, + fmt=".", + capsize = 0, + color=color, + label = str(self.reflector) + ' / ' + str(y_label) + ) + plt.legend() + + if not self.use_fit_result_only and unit == 'PE': + plt.errorbar( + [b for a, b in zip(self.color_tracker, self.x[0]) if a], + y_raw, + xerr=[b for a, b in zip(self.color_tracker, self.x[1]) if a], + yerr=y_raw_err, + markersize=7, + capsize = 0, + fmt=".", + color='green', + label = str(self.reflector) + ' / ' + y_raw_label + ) + plt.legend() + + if self.return_ov == True: + x_label = "Overvoltage [V]" + else: + x_label = self.bias_key[0] + plt.xlabel(x_label) + plt.ylabel(y_label) + plt.grid(True) + + def get_alpha(self, tupled = True, out_bias = False): + if out_bias: + V = self.x[0] + self.v_bd + return V, self.y[0],self.y[1] + if tupled: + zipped = zip(self.y[0],self.y[1]) + return list(zipped) + else: + return self.y[0],self.y[1] + + def get_V(self, ov = True): + v, amp = load_data(self.path, + self.v_bd, + data_type = 'Alpha', + bias_key = self.bias_key, + data_key = self.alpha_key, + return_ov = ov + ) + zipped = zip(v[0],v[1]) + return list(zipped) + # return (v[0], v[1]) + + + def get_CA_from_means(self, #get the CA from user-provided CSV of mean subtracted histogram values + return_bias = True, + key = ("mean", "mean error"), + out_file: str = None + ): + print('reading in mean of subtracted histogram...') + df = pd.read_csv(self.mean_subtract) + print('reading columns ' + key[0] + ' , ' + key[1]) + vals = np.array(df[key[0]]) + err = np.array(df[key[1]]) + print('reading columns ' + self.spe_bias_key[0] + ' , ' + self.spe_bias_key[1]) + bias_vals = np.array(df[self.spe_bias_key[0]]) + bias_err = np.array(df[self.spe_bias_key[1]]) + + ov_vals = np.array([V - self.v_bd for V in bias_vals]) + print('calculating SPE at bias voltages ' + str(bias_vals)) + spe, spe_err = self.get_SPEs(bias_vals, in_ov=False, tupled = False) + print('SPE values: ' + str(spe)) + print('mean values: ' + str(vals)) + CA_vals = vals / spe - 1 + CA_err = CA_vals * np.sqrt((err/vals)**2 + (spe_err/spe)**2) + + if out_file != None: #easiest way to deal with this is to save it to its own CSV file and treat it like any other CA data set + data = { + "Number of CA [PE]": CA_vals, + "Number of CA [PE] error": CA_err, + "Overvoltage [V]": ov_vals, + "Overvoltage [V] error": bias_err # just use error on keysight + } + df = pd.DataFrame(data) + df.to_csv(out_file) + + if not return_bias: + return (ov_vals,bias_err), (CA_vals,CA_err) + else: + return (bias_vals,bias_err), (CA_vals,CA_err) + + +#%% +class AlphaRatio: + def __init__( + self, + alpha_1: AlphaData, + alpha_2: AlphaData, + ): + self.alpha_1 = alpha_1 + self.alpha_2 = alpha_2 + self.color1, self.color2 = alpha_1.color, alpha_2.color + + self.list_of_volt_tuples_1, self.list_of_volt_tuples_2 = sorted(alpha_1.get_V(ov = True)), sorted(alpha_2.get_V(ov = True)) + self.list_of_amp_tuples_1, self.list_of_amp_tuples_2 = sorted(alpha_1.get_alpha()), sorted(alpha_2.get_alpha()) + # all the sorted tuples help ensure OVs don't get out of order + self.v_1, self.v_2 = np.array(self.list_of_volt_tuples_1)[:,0], np.array(self.list_of_volt_tuples_2)[:,0] + self.v_1_err, self.v_2_err = np.array(self.list_of_volt_tuples_1)[:,1], np.array(self.list_of_volt_tuples_2)[:,1] + self.alpha_vals_1, self.alpha_vals_2 = np.array(self.list_of_amp_tuples_1)[:,0], np.array(self.list_of_amp_tuples_2)[:,0] + self.alpha_err_1, self.alpha_err_2 = np.array(self.list_of_amp_tuples_1)[:,1], np.array(self.list_of_amp_tuples_2)[:,1] + + #inherit breakdown voltage and bias values + self.v_bd_1, self.v_bd_2 = alpha_1.v_bd, alpha_2.v_bd + self.v_bd_1_err, self.v_bd_2_err = alpha_1.v_bd_err, alpha_2.v_bd_err + self.alpha_1_bias, self.alpha_2_bias = self.v_1 + alpha_1.v_bd, self.v_2 + alpha_2.v_bd + + self.average_v_bd = (self.v_bd_2+self.v_bd_1)/2 + + self.average_v_bd_err = np.sqrt((self.v_bd_1_err)**2 + (self.v_bd_2_err)**2) + print('AVERAGE BREAKDOWN VOLTAGE = ' +str(self.average_v_bd)+'+/-'+str(self.average_v_bd_err)) + + + #all this allows for the alpha data sets to be of different lengths: + self.longer_data = max([self.alpha_1_bias,self.alpha_2_bias] , key = len) + self.longer_data_err = max([self.v_1_err,self.v_2_err] , key = len) + + self.ov_from_avg = self.longer_data - self.average_v_bd + + self.shorter_data = min([self.alpha_1_bias,self.alpha_2_bias] , key = len) + self.shorter_data_err = min([self.v_1_err,self.v_2_err] , key = len) + self.longer_alpha_vals = max([self.alpha_vals_1,self.alpha_vals_2] , key = len) + self.longer_alpha_vals_err = max([self.alpha_err_1,self.alpha_err_2] , key = len) + self.shorter_alpha_vals = min([self.alpha_vals_1,self.alpha_vals_2] , key = len) + self.shorter_alpha_vals_err = min([self.alpha_err_1,self.alpha_err_2] , key = len) + self.alpha_ratio = [] + self.alpha_ratio_err = [] + self.bias_for_ratio = [] + self.bias_for_ratio_err = [] + for i in range(len(self.longer_data)): + if self.longer_data[i] in self.shorter_data: + print(str(self.longer_data[i]) + ' is common to both data sets; computing ratio') + j, = np.where(np.isclose(self.shorter_data, self.longer_data[i])) + print(str(self.longer_data[i]) +'=='+str(self.shorter_data[j[0]])) + # alpha_ratio = self.alpha_vals_1[i]/self.alpha_vals_2[j] + # amp_long, amp_short = self.longer_data[i], self.shorter_data[j] + if len(self.longer_data) != len(self.shorter_data): + alpha_ratio = max(self.longer_alpha_vals[i], self.shorter_alpha_vals[j])/min(self.longer_alpha_vals[i], self.shorter_alpha_vals[j]) + else: + alpha_ratio = self.alpha_vals_1[i]/self.alpha_vals_2[j] + print(alpha_ratio) + self.alpha_ratio.append(alpha_ratio[0]) # alpha_ratio is a single-element np array by default + err = np.sqrt((self.longer_alpha_vals_err[i]/self.longer_alpha_vals[i])**2+(self.shorter_alpha_vals_err[j]/self.shorter_alpha_vals[j])**2) + self.alpha_ratio_err.append(err[0]) # err is a single element np array by default + print('alpha ratios: ' + str(self.alpha_ratio)) + self.bias_for_ratio.append(self.longer_data[i]) + self.bias_for_ratio_err.append(self.longer_data_err[i]) + else: + continue + + #average ratio + self.average_alpha_ratio = np.mean(self.alpha_ratio) + self.average_alpha_ratio_SEM = stats.sem(self.alpha_ratio) + self.average_alpha_ratio_std = statistics.stdev(self.alpha_ratio) + + #save ratio of SPE values. if the ratio is systematically > or < 1 num det photons could be misleading + self.spes_1, self.spes_1_err = self.alpha_1.get_SPEs(np.array(self.bias_for_ratio), in_ov = False, tupled = False) + self.spes_2, self.spes_2_err= self.alpha_2.get_SPEs(np.array(self.bias_for_ratio), in_ov = False, tupled = False) + self.spe_ratio = self.spes_1/self.spes_2 + self.spe_ratio_err = errorprop((self.spes_1, self.spes_1_err),(self.spes_2, self.spes_2_err)) + + def plot_spe_ratio(self, color = 'red'): + plt.errorbar(self.bias_for_ratio, self.spe_ratio, xerr = self.bias_for_ratio_err, yerr = self.spe_ratio_err, + markersize = 3, fmt = 's', color = color, capsize=0 + ) + + def get_average(self, return_std = False): + if return_std: + a = self.average_alpha_ratio_std + else: + a = self.average_alpha_ratio_SEM + return self.average_alpha_ratio, a + + def plot_alpha(self, unit = 'V'): + color1 = self.color1 + color2 = self.color2 + self.alpha_1.plot_alpha(color = color1, unit = unit) + self.alpha_2.plot_alpha(color = color2, unit = unit) + + def plot_alpha_ratio(self, color = 'purple', ov_from_avg = False): #ov_from_avg: display in OV with respect to the average of the two breakdown voltages + config1, config2 = self.alpha_1.reflector, self.alpha_2.reflector + data_y = self.alpha_ratio + data_y_err = self.alpha_ratio_err + + if ov_from_avg: + data_x = np.array(self.bias_for_ratio) - self.average_v_bd + data_x_err = np.sqrt(np.array(self.average_v_bd_err)**2 +np.array(self.bias_for_ratio_err)**2) + else: + data_x = np.array(self.bias_for_ratio) + data_x_err = np.array(self.bias_for_ratio_err) + plt.errorbar(data_x, data_y, xerr = data_x_err, yerr = data_y_err, markersize = 3, fmt = 's', color = color, capsize=0, + # label = 'Ratio = '+str(self.average_alpha_ratio)+ r' $\pm$ ' + str(self.average_alpha_ratio_SEM)) + label = 'Ratio = '+f'{self.get_average()[0]:0.3}'+ r' $\pm$ ' + f'{self.get_average()[1]:0.2}' + + '\n' + 'Standard Deviation: ' + f'{self.average_alpha_ratio_std:0.3}' + ) + plt.legend() + if ov_from_avg: + x_label = 'Overvoltage [V] w.r.t. average breakdown voltage' + else: + x_label = 'Bias Voltage [V]' + y_label = 'Ratio ' + config1 + '/' +config2 + plt.axhline(y = self.average_alpha_ratio, color = color) + plt.fill_between( + data_x, self.average_alpha_ratio + self.average_alpha_ratio_std, self.average_alpha_ratio - self.average_alpha_ratio_std, + color=color, alpha=0.25 + ) + plt.xlabel(x_label,fontsize = 14) + plt.ylabel(y_label, fontsize=16) + plt.tight_layout() + +#%% +class AnalyzePhotons: + def __init__( + self, + info: MeasurementInfo, + reflector: str, + alpha: AlphaData, + CA: CorrelatedAvalancheProbability, + ratio: AlphaRatio = None, + use_fit_results_only: bool = False, + max_OV: float = 10.0, + use_average_v_bd: bool = False + ): + self.alpha = alpha + self.alpha_data_list = alpha.data + self.CA = CA + self.info = info + self.reflector = reflector + self.max_OV = max_OV + self.use_average_v_bd = use_average_v_bd + + self.ratio = ratio + self.ov_from_avg = ratio.ov_from_avg + + self.alpha_data_all = np.array(sorted(self.alpha_data_list)) + self.alpha_data = self.alpha_data_all[self.alpha_data_all[:,0] < self.max_OV] + + self.use_fit_results_only = use_fit_results_only + self.v = np.array(sorted(alpha.get_V(ov = True)))[:,0] + self.v_err = np.array(sorted(alpha.get_V(ov = True)))[:,1] + self.alpha_vals = self.alpha_data[:,2] + self.alpha_err = self.alpha_data[:,3] + + self.spe_vals, self.spe_err = self.alpha_data[:,4], self.alpha_data[:,5] + self.invC_spe, self.invC_spe_err = alpha.invC_spe, alpha.invC_spe_err + self.invC_alpha, self.invC_alpha_err = alpha.invC, alpha.invC_err + + self.alpha_bias, self.alpha_bias_err = np.array(sorted(self.alpha_data[:,0])), np.array(sorted(self.alpha_data[:,1])) + + self.CA_vals, self.CA_err = np.array(sorted(CA.get_CA_eval(values = self.alpha_bias, max_OV = self.max_OV)))[:,0], np.array(sorted(CA.get_CA_eval(values = self.alpha_bias, max_OV = self.max_OV)))[:,1] + + self.CA_measured = np.array(sorted(zip(self.CA.x[0],self.CA.x[0],self.CA.y[0],self.CA.y[1]))) #sort by voltage + self.CA_measured = self.CA_measured[self.CA_measured[:,0] < self.max_OV] + self.CA_raw, self.CA_raw_err = self.CA_measured[:,2], self.CA_measured[:,3] + self.CA_raw_bias, self.CA_raw_bias_err = self.CA_measured[:,0], self.CA_measured[:,1] + + if not use_fit_results_only: + self.color_tracker = np.array([False for i in range(len(self.CA_vals))]) + for v in self.alpha_bias: #look in list alpha_bias (OV) + if min(self.CA_raw_bias)-0.05 < v < max(self.CA_raw_bias)+0.05: #for value v that has a measurement of CA (OV) + i, = np.where(np.isclose(self.alpha_bias, v)) #get the index of the bias (OV) we are replacing + j, = np.where(np.isclose(self.CA_raw_bias, v)) #get the index of the bias (OV) we are replacing + if len(self.CA_raw[j]) > 0: + print('replacing CA = '+str(self.CA_vals[i])+' with ' + str(self.CA_raw[j]) + ' at OV ' + str(self.v[i]) + ' == ' + str(self.CA_raw_bias[j])) + self.CA_vals[i] = self.CA_raw[j] #replace value obtained from doing a fit with actual CA value calculated from mean of amplitudes + self.CA_err[i] = self.CA_raw_err[j] #do the same for the error (we do not want to use the fit error!) + self.color_tracker[i] = True + else: + print('OV value ' + str(v) + ' does not have an associated CA measurement. Using value from fit.') + + if use_average_v_bd and ratio != None and use_fit_results_only == False: + self.CA_vals_from_avg, self.CA_err_from_avg = np.array(sorted(CA.get_CA_eval(values = self.ov_from_avg, max_OV = self.max_OV)))[:,0], np.array(sorted(CA.get_CA_eval(values = self.ov_from_avg, max_OV = self.max_OV)))[:,1] + self.spe_from_avg, self.spe_from_avg = alpha.get_SPEs(self.ov_from_avg, in_ov = True, tupled = False) + self.spe_vals, self.spe_err = self.spe_from_avg, self.spe_from_avg + self.CA_vals, self.CA_err = self.CA_vals_from_avg, self.CA_err_from_avg + + #calculate number of detected photons + self.num_det_photons = ( + self.alpha_vals * self.invC_spe + / (self.spe_vals * self.invC_alpha * (1.0 + self.CA_vals)) + ) + self.num_det_photons_err = self.num_det_photons * np.sqrt( + (self.alpha_err * self.alpha_err) / (self.alpha_vals * self.alpha_vals) + + (self.invC_spe_err * self.invC_spe_err) / (self.invC_spe * self.invC_spe) + + (self.spe_err * self.spe_err) / (self.spe_vals * self.spe_vals) + + (self.invC_alpha_err * self.invC_alpha_err) / (self.invC_alpha * self.invC_alpha) + + (self.CA_err * self.CA_err) / (self.CA_vals * self.CA_vals) + ) + + def plot_num_det_photons(self, color = None, label = True, out_file = None): + """ + Plot the number of detected photons as a function of overvoltage. + """ + if color == None: + color = self.alpha.color + color = "tab:" + color + if label: + fig = plt.figure() + + data_y = self.num_det_photons + data_y_err = self.num_det_photons_err + if self.use_average_v_bd: + data_x = self.ov_from_avg[:len(data_y)] + else: + data_x = self.alpha_bias + data_x_err = self.alpha_bias_err + + plt.errorbar( + data_x, + data_y, + xerr=data_x_err, + yerr=data_y_err, + markersize=7, + fmt=".", + color=color, + label = f"{self.reflector}" + ) + + plt.xlabel("Overvoltage [V]",fontsize=17) + plt.ylabel("Number of Detected Photons",fontsize = 17) + textstr = f"Date: {self.info.date}\n" + textstr = f"Shaper: {self.alpha.shaper}\n" + textstr += f"RTD4: {self.info.temperature} [K]\n" + textstr += f'Filtering: {self.alpha.filtering}' + + props = dict(boxstyle="round", facecolor=color, alpha=0.4) + if label: + fig.text(0.3, 0.4, textstr, fontsize=14, verticalalignment="top", bbox=props) + plt.xlim(0, np.amax(self.v) + 1.0) + ylow, yhigh = plt.ylim() + plt.ylim(-1, yhigh * 1.1) + plt.grid(True) + plt.legend() + plt.tight_layout() + + x_label = "Overvoltage [V]" + y_label = "Number of Detected Photons" + if out_file: + data = { + x_label: data_x, + x_label + " error": data_x_err, + y_label: data_y, + y_label + " error": data_y_err, + } + df = pd.DataFrame(data) + df.to_csv(out_file) + + def plot_CA(self, plot = True, color = 'blue'): #plots the CA values *specifically used to find num det photons* + color = color + data_x = self.alpha_bias + if not self.use_fit_results_only: + data_x_with_raw_CA = [b for a, b in zip(self.color_tracker, self.alpha_bias) if a] + data_x_err_raw_CA = [b for a, b in zip(self.color_tracker, self.alpha_bias_err) if a] + data_y_with_raw_CA = [b for a, b in zip(self.color_tracker, self.CA_vals) if a] + data_y_err_raw_CA = [b for a, b in zip(self.color_tracker, self.CA_err) if a] + data_x_err = self.alpha_bias_err + data_y = self.CA_vals + data_y_err = self.CA_err + + + plt.errorbar(data_x, data_y, xerr = data_x_err, yerr = data_y_err, markersize = 7, color ='xkcd:'+color, fmt = '.', label = r'$\frac{Ae^{B*V_{OV}}+1}{A + 1} - 1$ fit') + if not self.use_fit_results_only: + plt.errorbar(data_x_with_raw_CA, data_y_with_raw_CA, xerr = data_x_err_raw_CA, color = color, yerr = data_y_err_raw_CA, markersize = 7, fmt = '.', label = r'$\frac{1}{N}\sum_{i=1}^{N}{\frac{A_i}{\bar{A}_{1 PE}}-1}$'+ ' from LED data') + x_label = 'Overvoltage [V]' + y_label = 'Number of CA [PE]' + plt.xlabel(x_label) + plt.ylabel(y_label) + plt.tight_layout() + plt.legend() + plt.grid(True) \ No newline at end of file diff --git a/CA_190K_new_code.py b/CA_190K_new_code.py deleted file mode 100644 index e1fb5f6..0000000 --- a/CA_190K_new_code.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Tue Sep 20 15:06:03 2022 - -@author: lab-341 -""" - -# -*- coding: utf-8 -*- -""" -Created on Tue Aug 23 11:34:31 2022 - -@author: lab-341 -""" - -#%% -import sys -import numpy as np -# append necessary file paths, and change E -> D or vice versa -sys.path.append('D:/Xe/AnalysisScripts/LXe May 2023/') -from MeasurementInfo import MeasurementInfo -from RunInfo import RunInfo -import heapq -from scipy import signal -from scipy.optimize import curve_fit -import AnalyzePDE -from AnalyzePDE import SPE_data -from AnalyzePDE import Alpha_data -import matplotlib.pyplot as plt -import matplotlib as mpl -import ProcessWaveforms_MultiGaussian -from ProcessWaveforms_MultiGaussian import WaveformProcessor as WaveformProcessor -import h5py -plt.style.use('D:/Xe/AnalysisScripts/LXe May 2023/nexo_new.mplstyle') -#%% -run_spe_solicited = RunInfo(['D:/Xe/DAQ/Run_1648191265.hdf5'], do_filter = True, is_solicit = True, upper_limit = 1, baseline_correct = True) -files = ['Run_1648176286','Run_1648179496', 'Run_1648181807', 'Run_1648184235', 'Run_1648186910'] #, 'Run_1648186910', 'Run_1648171846' -# upperlim = [1, 1.76, 4.4, 4.4, 4.4] -upperlim = [5, 5, 5, 5, 5, 5] -runs = [] -for file in range(len(files)): - run_spe = RunInfo(['D:/Xe/DAQ/' + files[file] + '.hdf5'], do_filter = True, upper_limit = upperlim[file], baseline_correct = True, prominence = 0.05) - runs.append(run_spe) -biases = [run.bias for run in runs] # get all the bias voltages from RunInfo (enter manually if metadata is wrong) -#%% -#%% -cutoffs = [] -centers_list=[] -centers_guesses = [] - -for run in runs: - bins = int(round(np.sqrt(len(run.all_peak_data)))*1.5) - print(bins) - count, edges = np.histogram(run.all_peak_data, bins=bins) - if run.bias == 36.8: - peak_data = run.all_peak_data[run.all_peak_data > 0.08] - bins = int(round(np.sqrt(len(peak_data)))*1.5) - count, edges = np.histogram(peak_data, bins=bins) - centers = (edges[:-1] + edges[1:])/2 - peaks, props = signal.find_peaks(count, prominence=10, distance=2) - print(peaks) - fitrange = ((centers[peaks[3]] - centers[peaks[0]])/2) - range_low = centers[peaks[0]]- 0.31*fitrange - range_high = centers[peaks[3]]+ 0.35*fitrange - - cutoffs.append((range_low, range_high)) - centers_list.append(centers[peaks[0]]) - peaks = peaks[0:] - centers_guesses.append([centers[peak] for peak in peaks]) - - plt.figure() - plt.hist(run.all_peak_data, bins=bins) - for peak in peaks: - plt.scatter(centers[peak],count[peak]) - plt.axvline(range_low, c='red') - plt.axvline(range_high, c='black') - plt.xlim([0,1]) - plt.yscale('log') -#%% - -#%% make a list of ProcessWaveforms objects -campaign_spe = [] -for i in range(len(runs)): - info_spe = MeasurementInfo() - info_spe.condition = 'LXe' - info_spe.date = runs[i].date - info_spe.temperature = 170 - info_spe.bias = runs[i].bias - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 150 - info_spe.data_type = 'h5' - # if i < 3: - # num = 3 - # else: - num = 4 - wp_spe = WaveformProcessor(info_spe, run_info_self = runs[i], run_info_solicit = run_spe_solicited, baseline_correct = True, cutoff = cutoffs[i], centers = centers_guesses[i], no_solicit = False, numpeaks = num) - wp_spe.process(do_spe = True, do_alpha = False) - wp_spe.plot_peak_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/CA_190K_gauss_'+str(info_spe.bias)+'.png') - wp_spe.plot_spe(savefig=True, path = 'D:/Xe/AnalysisScripts/May_170K_spe_'+str(info_spe.bias)+'.png') - wp_spe.plot_both_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/CA_190K_baseline_'+str(info_spe.bias)+'.png') - wp_spe.plot_peak_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/CA_190K_gauss_'+str(info_spe.bias)+'.svg') - wp_spe.plot_spe(savefig=True, path = 'D:/Xe/AnalysisScripts/May_170K_spe_'+str(info_spe.bias)+'.svg') - wp_spe.plot_both_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/CA_190K_baseline_'+str(info_spe.bias)+'.svg') - plt.close() - campaign_spe.append(wp_spe) - -#%% plots -for i in range(len(campaign_spe)): - campaign_spe[i].plot_peak_histograms() -#%% -n = 0 -for i in campaign_spe: - n+=1 - i.plot_peak_histograms(log_scale=False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe May 2023/100ns_gauss_'+str(n)+'.png') - i.plot_peak_histograms(log_scale=False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe May 2023/100ns_gauss_'+str(n)+'.svg') - plt.grid(True) - # plt.close() -#%% -invC_spe_filter = 0.19261918346201742 -invC_spe_err_filter = 0.0021831140214106596 -spe = SPE_data(campaign_spe, invC_spe_filter, invC_spe_err_filter, filtered = True) -spe.plot_spe(in_ov = False, absolute = False, out_file = None) -#%% -path = 'D:/Xe/AnalysisScripts/March 2022 HD3 Vacuum/CA_updated.csv' -spe.plot_CA() diff --git a/Dec13_158K_Package.zip b/Dec13_158K_Package.zip deleted file mode 100644 index 0c41eb1..0000000 Binary files a/Dec13_158K_Package.zip and /dev/null differ diff --git a/Dec20_153K_Package.zip b/Dec20_153K_Package.zip deleted file mode 100644 index 94d634d..0000000 Binary files a/Dec20_153K_Package.zip and /dev/null differ diff --git a/GN_Oct_2022_Analysis.py b/GN_Oct_2022_Analysis.py deleted file mode 100644 index 15dee3e..0000000 --- a/GN_Oct_2022_Analysis.py +++ /dev/null @@ -1,112 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Tue Jan 31 19:13:35 2023 - -@author: heps1 -""" -import sys -import numpy as np -# append necessary file paths, and change E -> D or vice versa -sys.path.append('E:/Xe/AnalysisScripts') -sys.path.append('E:/Xe/AnalysisScripts/August 2022 Low Illumination Campaign') -from MeasurementInfo import MeasurementInfo -from RunInfo import RunInfo -import heapq -from scipy import signal -from scipy.optimize import curve_fit -import AnalyzePDE -from AnalyzePDE import SPE_data -import matplotlib.pyplot as plt -import matplotlib as mpl -import ProcessWaveforms_MultiGaussian -from ProcessWaveforms_MultiGaussian import WaveformProcessor as WaveformProcessor - -#%% 167K -# loop quickly loads in files -run_spe_solicited = RunInfo(['E:/Xe/DAQ/Run_1666778594.hdf5'], specifyAcquisition = True, acquisition ='Acquisition_1666781843', do_filter = True, is_solicit = True, upper_limit = .5, baseline_correct = True) -files = ['Acquisition_1666778815','Acquisition_1666779156','Acquisition_1666782030','Acquisition_1666780808','Acquisition_1666779491'] -proms = [0.033,0.038,0.04,0.054,0.068] -upperlim = [1.9, 1.9, 4.9, 4.9, 4.9] -runs = [] -for file in range(len(files)): - run_spe = RunInfo(['E:/Xe/DAQ/Run_1666778594.hdf5'], specifyAcquisition = True, acquisition = files[file], do_filter = True, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file]) - runs.append(run_spe) -biases = [run.bias for run in runs] -#%% gain calibration conversion factor (change as needed; make sure it is the correct factor for the data set) -#100ns, old shaper, 100x gain -invC_spe_filter = 0.19261918346201742 -invC_spe_err_filter = 0.0021831140214106596 - -#%% take a look at waveforms (solicited) -RunInfo(['E:/Xe/DAQ/Run_1666778594.hdf5'], specifyAcquisition = True, acquisition ='Acquisition_1666781843', do_filter = False, is_solicit = True, upper_limit = .5, baseline_correct = True, plot_waveforms = True, fourier = False) -#%% take a look at finger plots -for run in runs: - run.plot_hists('167', '.') -#%% set the initial guesses and fitting range -a_guess = 0.01674 -b_guess = -0.4598 -range_lows = [0.035, 0.05, 0.06, 0.07, 0.086] -centers = [biases[i]*a_guess+b_guess for i in range(len(runs))] #guess position of 1 p.e. for each bias -range_highs = [range_lows[i] + centers[i]*4 for i in range(len(runs))] -#%% plot with peak fit - test -n= 4 -T = 167 -con = 'GN' -info_spe = MeasurementInfo() -info_spe.condition = con -info_spe.date = runs[n].date.decode('utf-8') -info_spe.temperature = T -info_spe.bias = biases[n] -info_spe.baseline_numbins = 50 -info_spe.peaks_numbins = 150 -info_spe.data_type = 'h5' -wp = WaveformProcessor(info_spe, run_info_self = runs[n], run_info_solicit = run_spe_solicited, baseline_correct = True, range_low = range_lows[n], range_high = range_highs[n], center = centers[n]) -wp.process(do_spe = True, do_alpha = False) -wp.plot_both_histograms() -wp.plot_peak_histograms() -wp.plot_spe() - -#%% make a list of ProcessWaveforms objects -campaign_spe = [] -for i in range(len(runs)): - if i == 2: #skipping this bias for now - continue - T = 167 - con = 'GN' - info_spe = MeasurementInfo() - info_spe.condition = con - info_spe.date = runs[i].date.decode('utf-8') - info_spe.temperature = T - info_spe.bias = runs[i].bias - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 20 - info_spe.data_type = 'h5' - wp_spe = WaveformProcessor(info_spe, run_info_self = runs[i], run_info_solicit = run_spe_solicited, baseline_correct = True, range_low = range_lows[i], range_high = range_highs[i], center = centers[i]) - wp_spe.process(do_spe = True, do_alpha = False) - campaign_spe.append(wp_spe) - -#%% check plots -for i in range(len(campaign_spe)): - campaign_spe[i].plot_peak_histograms() - -#%% check CA -for i in range(len(campaign_spe)): - print('bias: ' + str(biases[i]) + '; ' + str(campaign_spe[i].get_CA())) - -#%% plot linear fit to the breakdown voltage - -curr_campaign = campaign_spe - -filtered_spe = SPE_data(curr_campaign, invC_spe_filter, invC_spe_err_filter, filtered = True) -filtered_spe.plot_spe(in_ov = False, absolute = False, out_file = None) - -print(filtered_spe.v_bd) -print(filtered_spe.v_bd_err) - -#%% plot in units of absolute gain vs OV - -filtered_spe.plot_spe(in_ov = True, absolute = True, out_file = None) - -#%% plot CA -path = 'YOUR/PATH/HERE.csv' -filtered_spe.plot_CA(out_file=path) #saves values to spreadsheet, or leave blank diff --git a/July13_169_LXe_Package.zip b/July13_169_LXe_Package.zip deleted file mode 100644 index 85256fc..0000000 Binary files a/July13_169_LXe_Package.zip and /dev/null differ diff --git a/LXe_August_2023_no_silicon.py b/LXe_August_2023_no_silicon.py deleted file mode 100644 index 1c4e547..0000000 --- a/LXe_August_2023_no_silicon.py +++ /dev/null @@ -1,141 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Oct 16 18:41:24 2023 - -@author: Hannah -""" - -import sys -import numpy as np -# append necessary file paths, and change E -> D or vice versa -sys.path.append('D:/Xe/AnalysisScripts/LXe May 2023/') -from MeasurementInfo import MeasurementInfo -from RunInfo import RunInfo -import heapq -from scipy import signal -from scipy.optimize import curve_fit -import AnalyzePDE -from AnalyzePDE import SPE_data -from AnalyzePDE import Alpha_data -import matplotlib.pyplot as plt -import matplotlib as mpl -import ProcessWaveforms_MultiGaussian -from ProcessWaveforms_MultiGaussian import WaveformProcessor as WaveformProcessor -import h5py -plt.style.use('D:/Xe/AnalysisScripts/LXe May 2023/nexo_new.mplstyle') -#%% -#1us, 10x gain, filter off -invC =0.0132 -invC_err =0.000089 -# loop quickly loads in files -# separate files for each bias voltage -> specifyAcquisition = False -run_spe_solicited = RunInfo(['D:/Xe/DAQ/Run_1691696340.hdf5'], specifyAcquisition = False, do_filter = False, is_solicit = True, upper_limit = 0.2, baseline_correct = True) -files = ['Run_1691691406','Run_1691690935','Run_1691688275','Run_1691694839','Run_1691693056','Run_1691694534','Run_1691695317','Run_1691689385','Run_1691689812','Run_1691693423', 'Run_1691694026'] #31.5, 32, 32.5, 33, 33.5, 34, 34.5, 35, 35.5, 36, 36.5 -upperlim = [0.062, 0.062, 0.1, 0.1, 0.1, 0.1, 0.1, 0.18, 0.3, 0.3, 0.45] -proms = [0.0055, 0.0055, 0.0055, 0.006, 0.006, 0.006, 0.006, 0.006, 0.006, 0.006, 0.006] -runs = [] -for file in range(len(files)): - run_spe = RunInfo(['D:/Xe/DAQ/'+files[file]+'.hdf5'], specifyAcquisition = False, do_filter = False, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file], poly_correct = True) - runs.append(run_spe) -biases = [run.bias for run in runs] -#%% -#%% -cutoffs = [] -centers_list=[] -centers_guesses = [] - -for run in runs: - bins = int(round(np.sqrt(len(run.all_peak_data)))) - print(bins) - count, edges = np.histogram(run.all_peak_data, bins=bins) - centers = (edges[:-1] + edges[1:])/2 - if run.bias == 36.5: - d = 2 - else: - d = 3 - peaks, props = signal.find_peaks(count, prominence=25, distance=d) - fitrange = ((centers[peaks[3]] - centers[peaks[0]])/2) - if run.bias < 32.5: - range_low = centers[peaks[0]]- 0.32*fitrange - range_high = centers[peaks[3]]+ 0.42*fitrange - if run.bias == 32.5: - range_low = centers[peaks[0]]- 0.33*fitrange - range_high = centers[peaks[3]]+ 0.45*fitrange - if run.bias > 32.5: - range_low = centers[peaks[0]]- 0.24*fitrange - range_high = centers[peaks[3]]+ 0.34*fitrange - if run.bias >= 34: - range_low = centers[peaks[0]]- 0.22*fitrange - range_high = centers[peaks[3]]+ 0.37*fitrange - if run.bias == 33.5: - range_low = centers[peaks[0]]- 0.27*fitrange - range_high = centers[peaks[3]]+ 0.37*fitrange - if run.bias > 34.5: - range_low = centers[peaks[0]]- 0.28*fitrange - range_high = centers[peaks[3]]+ 0.31*fitrange - if run.bias == 36.5: - range_low = centers[peaks[0]]- 0.34*fitrange - range_high = centers[peaks[3]]+ 0.31*fitrange - cutoffs.append((range_low, range_high)) - centers_list.append(centers[peaks[0]]) - peaks = peaks[0:] - centers_guesses.append([centers[peak] for peak in peaks]) - - # plt.figure() - # plt.hist(run.all_peak_data, bins=bins) - # for peak in peaks: - # plt.scatter(centers[peak],count[peak]) - # plt.axvline(range_low, c='red') - # plt.axvline(range_high, c='black') - # plt.xlim([0,1]) - # plt.yscale('log') -#%% testing cell - plot with peak fit -# set conditions, temp -n=1 -T = 169.5 -con = 'LXe' -info_spe = MeasurementInfo() -info_spe.condition = con -info_spe.date = runs[n].date -info_spe.temperature = T -info_spe.bias = biases[n] -info_spe.baseline_numbins = 100 -info_spe.peaks_numbins = 200 -info_spe.data_type = 'h5' -wp = WaveformProcessor(info_spe, run_info_self = runs[n], run_info_solicit = run_spe_solicited, baseline_correct = True, cutoff = cutoffs[n], centers = centers_guesses[n], numpeaks = 4) -wp.process(do_spe = True, do_alpha = False) -wp.plot_peak_histograms(log_scale = False) -wp.plot_spe() -# wp.plot_both_histograms() -# wp.plot_baseline_histogram() -#%% -campaign_spe = [] -for i in range(len(runs)): - info_spe = MeasurementInfo() - info_spe.condition = 'LXe' - info_spe.date = runs[i].date - info_spe.temperature = 168 - info_spe.bias = runs[i].bias - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 200 - info_spe.data_type = 'h5' - # if i == 0: - # num = 3 - # else: - num = 4 - wp_spe = WaveformProcessor(info_spe, run_info_self = runs[i], run_info_solicit = run_spe_solicited, baseline_correct = True, cutoff = cutoffs[i], centers = centers_guesses[i], no_solicit = False, numpeaks = num) - wp_spe.process(do_spe = True, do_alpha = False) - # wp_spe.plot_peak_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/plots_no_silicon/no_silicon_gauss_'+str(info_spe.bias)+'.png') - # wp_spe.plot_spe(savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/plots_no_silicon/no_silicon_spe_'+str(info_spe.bias)+'.png') - # wp_spe.plot_both_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/plots_no_silicon/no_silicon_baseline_'+str(info_spe.bias)+'.png') - # wp_spe.plot_peak_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/plots_no_silicon/no_silicon_gauss_'+str(info_spe.bias)+'.svg') - # wp_spe.plot_spe(savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/plots_no_silicon/no_silicon_spe_'+str(info_spe.bias)+'.svg') - # wp_spe.plot_both_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/plots_no_silicon/no_silicon_baseline_'+str(info_spe.bias)+'.svg') - # plt.close() - campaign_spe.append(wp_spe) - print(info_spe.bias) - -#%% plot linear fit to the breakdown voltage -curr_campaign = campaign_spe -spe = SPE_data(curr_campaign, invC, invC_err, filtered = False) -spe.plot_spe(in_ov = False, absolute = False, out_file = 'D:/Xe/AnalysisScripts/LXe August 1 2023/vbd_bias_no_silicon.csv') # diff --git a/LXe_August_2023_no_silicon_plots.zip b/LXe_August_2023_no_silicon_plots.zip deleted file mode 100644 index 208d8bf..0000000 Binary files a/LXe_August_2023_no_silicon_plots.zip and /dev/null differ diff --git a/LXe_August_2023_silicon.py b/LXe_August_2023_silicon.py deleted file mode 100644 index a79238c..0000000 --- a/LXe_August_2023_silicon.py +++ /dev/null @@ -1,135 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Oct 16 18:41:24 2023 - -@author: Hannah -""" - -import sys -import numpy as np -# append necessary file paths, and change E -> D or vice versa -sys.path.append('D:/Xe/AnalysisScripts/LXe May 2023/') -from MeasurementInfo import MeasurementInfo -from RunInfo import RunInfo -import heapq -from scipy import signal -from scipy.optimize import curve_fit -import AnalyzePDE -from AnalyzePDE import SPE_data -from AnalyzePDE import Alpha_data -import matplotlib.pyplot as plt -import matplotlib as mpl -import ProcessWaveforms_MultiGaussian -from ProcessWaveforms_MultiGaussian import WaveformProcessor as WaveformProcessor -import h5py -plt.style.use('D:/Xe/AnalysisScripts/LXe May 2023/nexo_new.mplstyle') -#%% -#1us, 10x gain, filter off -invC =0.0132 -invC_err =0.000089 -# loop quickly loads in files -# separate files for each bias voltage -> specifyAcquisition = False -run_spe_solicited = RunInfo(['D:/Xe/DAQ/Run_1690920592.hdf5'], specifyAcquisition = False, do_filter = False, is_solicit = True, upper_limit = 0.2, baseline_correct = True) -files = ['Run_1690921033','Run_1690932970','Run_1690924626','Run_1690930429','Run_1690928479','Run_1690927092','Run_1690931305','Run_1690925548','Run_1690933780','Run_1690932183', 'Run_1690929508'] #31.5, 32, 32.5, 33, 33.5, 34, 34.5, 35, 35.5, 36, 36.5 -upperlim = [0.12, 0.12, 0.2, 0.2, 0.2, 0.6, 0.6, 0.6, 0.6, 0.6, 1.2] -proms = [0.0048, 0.0048, 0.0048, 0.006, 0.006, 0.006, 0.006, 0.006, 0.006, 0.006, 0.006] -runs = [] -for file in range(len(files)): - run_spe = RunInfo(['D:/Xe/DAQ/'+files[file]+'.hdf5'], specifyAcquisition = False, do_filter = False, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file], poly_correct = True) - runs.append(run_spe) -biases = [run.bias for run in runs] -#%% -# RunInfo(['D:/Xe/DAQ/'+files[0]+'.hdf5'], specifyAcquisition = False, do_filter = False, upper_limit = 0.1, baseline_correct = True, prominence = 0.005, poly_correct = True, plot_waveforms = True) -# test=RunInfo(['D:/Xe/DAQ/'+files[2]+'.hdf5'], specifyAcquisition = False, do_filter = True, upper_limit = 0.12, baseline_correct = True, prominence = 0.0048, poly_correct = True) -# test.plot_hists('','') -# runs[-1] = test -#%% -cutoffs = [] -centers_list=[] -centers_guesses = [] - -for run in runs: - bins = int(round(np.sqrt(len(run.all_peak_data)))) - print(bins) - count, edges = np.histogram(run.all_peak_data, bins=bins) - centers = (edges[:-1] + edges[1:])/2 - peaks, props = signal.find_peaks(count, prominence=25, distance=3) - fitrange = ((centers[peaks[3]] - centers[peaks[0]])/2) - if run.bias < 32.5: - range_low = centers[peaks[0]]- 0.3*fitrange - range_high = centers[peaks[3]]+ 0.42*fitrange - if run.bias == 32.5: - range_low = centers[peaks[0]]- 0.31*fitrange - range_high = centers[peaks[3]]+ 0.45*fitrange - if run.bias > 32.5: - range_low = centers[peaks[0]]- 0.22*fitrange - range_high = centers[peaks[3]]+ 0.32*fitrange - if run.bias >= 34: - range_low = centers[peaks[0]]- 0.31*fitrange - range_high = centers[peaks[3]]+ 0.37*fitrange - if run.bias == 33.5: - range_low = centers[peaks[0]]- 0.24*fitrange - range_high = centers[peaks[3]]+ 0.31*fitrange - if run.bias > 34.5: - range_low = centers[peaks[0]]- 0.3*fitrange - range_high = centers[peaks[3]]+ 0.31*fitrange - cutoffs.append((range_low, range_high)) - centers_list.append(centers[peaks[0]]) - peaks = peaks[0:] - centers_guesses.append([centers[peak] for peak in peaks]) - - # plt.figure() - # plt.hist(run.all_peak_data, bins=bins) - # for peak in peaks: - # plt.scatter(centers[peak],count[peak]) - # plt.axvline(range_low, c='red') - # plt.axvline(range_high, c='black') - # plt.xlim([0,1]) - # plt.yscale('log') -#%% testing cell - plot with peak fit -# set conditions, temp -n=10 -T = 169.5 -con = 'LXe' -info_spe = MeasurementInfo() -info_spe.condition = con -info_spe.date = runs[n].date -info_spe.temperature = T -info_spe.bias = biases[n] -info_spe.baseline_numbins = 100 -info_spe.peaks_numbins = 200 -info_spe.data_type = 'h5' -wp = WaveformProcessor(info_spe, run_info_self = runs[n], run_info_solicit = run_spe_solicited, baseline_correct = True, cutoff = cutoffs[n], centers = centers_guesses[n], numpeaks = 4) -wp.process(do_spe = True, do_alpha = False) -wp.plot_peak_histograms(log_scale = False) -wp.plot_spe() -# wp.plot_both_histograms() -# wp.plot_baseline_histogram() -#%% -campaign_spe = [] -for i in range(len(runs)): - info_spe = MeasurementInfo() - info_spe.condition = 'LXe' - info_spe.date = runs[i].date - info_spe.temperature = 169.5 - info_spe.bias = runs[i].bias - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 150 - info_spe.data_type = 'h5' - num = 4 - wp_spe = WaveformProcessor(info_spe, run_info_self = runs[i], run_info_solicit = run_spe_solicited, baseline_correct = True, cutoff = cutoffs[i], centers = centers_guesses[i], no_solicit = False, numpeaks = num) - wp_spe.process(do_spe = True, do_alpha = False) - # wp_spe.plot_peak_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/silicon_gauss_'+str(info_spe.bias)+'.png') - # wp_spe.plot_spe(savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/silicon_spe_'+str(info_spe.bias)+'.png') - # wp_spe.plot_both_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/siicon_baseline_'+str(info_spe.bias)+'.png') - # wp_spe.plot_peak_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/silicon_gauss_'+str(info_spe.bias)+'.svg') - # wp_spe.plot_spe(savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/silicon_spe_'+str(info_spe.bias)+'.svg') - # wp_spe.plot_both_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe August 1 2023/silicon_baseline_'+str(info_spe.bias)+'.svg') - # plt.close() - campaign_spe.append(wp_spe) - print(info_spe.bias) - -#%% plot linear fit to the breakdown voltage -curr_campaign = campaign_spe -spe = SPE_data(curr_campaign, invC, invC_err, filtered = False) -spe.plot_spe(in_ov = False, absolute = False, out_file = 'D:/Xe/AnalysisScripts/LXe August 1 2023/vbd_bias.csv') # diff --git a/LXe_August_2023_silicon_plots.zip b/LXe_August_2023_silicon_plots.zip deleted file mode 100644 index 4dd7605..0000000 Binary files a/LXe_August_2023_silicon_plots.zip and /dev/null differ diff --git a/LXe_July_2022_Analysis.py b/LXe_July_2022_Analysis.py deleted file mode 100644 index d9e7ef4..0000000 --- a/LXe_July_2022_Analysis.py +++ /dev/null @@ -1,212 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Jun 9 14:28:38 2023 - -@author: hpeltzsmalle -@author: Ed van Bruggen (evanbruggen@umass.edu) -""" - -import sys -import numpy as np -from MeasurementInfo import MeasurementInfo -from RunInfo import RunInfo -import heapq -from scipy import signal -from scipy.optimize import curve_fit -import AnalyzePDE -from AnalyzePDE import SPE_data -from AnalyzePDE import Alpha_data -import matplotlib.pyplot as plt -import matplotlib as mpl -import ProcessWaveforms_MultiGaussian -from ProcessWaveforms_MultiGaussian import WaveformProcessor as WaveformProcessor - - -#%% SPE-VBD -#100ns, new shaper, 10x gain, filtered (change as needed; make sure it is the correct factor for the data set) -invC_spe_filter = 0.011959447603692185 -invC_spe_err_filter = 3.881945391072933E-05 -file_path = 'self/' # folder with H5 data files -run_spe_solicited = RunInfo([file_path+'Run_1658337800.hdf5'], do_filter = True, is_solicit = True, upper_limit = 1, baseline_correct = True) -# loop quickly loads in files -# separate files for each bias voltage -> specifyAcquisition = False -files = ['Run_1658339042.hdf5', 'Run_1658339468.hdf5', 'Run_1658339739.hdf5', 'Run_1658339990.hdf5', 'Run_1658340318.hdf5'] -proms = [0.003,0.003,0.003,0.003,0.003,0.003,0.003,0.003,0.003] -upperlim = [0.1, 0.1, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18] -runs = [] -for file in range(len(files)): - run_spe = RunInfo([file_path+files[file]], specifyAcquisition = False, do_filter = True, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file]) - runs.append(run_spe) -biases = [run.bias for run in runs] -#%% -range_lows = [0.00225, 0.0032, 0.0031, 0.0037, 0.0037, 0.00475, 0.005, 0.0053, 0.006] -range_highs = [0.0205, 0.025, 0.025, 0.027, 0.03, 0.03, 0.033, 0.036, 0.04] -centers = [0.0046, 0.0049, 0.0059, 0.0065, 0.0069, 0.0072, 0.0075, 0.008, 0.008] -#%% testing cell - plot with peak fit -# set conditions, temp -n= 0 -T = 170 -info_spe = MeasurementInfo() -info_spe.condition = 'LXe' -info_spe.date = runs[n].date -# info_spe.date = 'NA' -info_spe.temperature = T -info_spe.bias = biases[n] -info_spe.baseline_numbins = 50 -info_spe.peaks_numbins = 150 -info_spe.data_type = 'h5' -wp = WaveformProcessor(info_spe, run_info_self = runs[n], baseline_correct = True, range_low = range_lows[n], range_high = range_highs[n], center = centers[n], no_solicit = True) -wp.process(do_spe = True, do_alpha = False) -wp.plot_peak_histograms() -wp.plot_spe() - -#%% make a list of ProcessWaveforms objects -campaign_spe = [] -for i in range(len(runs)): - info_spe = MeasurementInfo() - info_spe.condition = 'LXe' - info_spe.date = runs[i].date - info_spe.temperature = 170 - info_spe.bias = runs[i].bias - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 150 - info_spe.data_type = 'h5' - wp_spe = WaveformProcessor(info_spe, run_info_self = runs[i], run_info_solicit = run_spe_solicited, baseline_correct = True, range_low = range_lows[i], range_high = range_highs[i], center = centers[i], no_solicit = True) - wp_spe.process(do_spe = True, do_alpha = False) - campaign_spe.append(wp_spe) - -#%% plot linear fit to the breakdown voltage -curr_campaign = campaign_spe -filtered_spe = SPE_data(curr_campaign, invC_spe_filter, invC_spe_err_filter, filtered = True) -filtered_spe.plot_spe(in_ov = False, absolute = False, out_file = None) - -print(filtered_spe.v_bd) -print(filtered_spe.v_bd_err) - -#%% plot in units of absolute gain vs OV -filtered_spe.plot_spe(in_ov = True, absolute = True, out_file = None) -#%% record BD voltage -v_bd = 27.69 -v_bd_err = 0.06 -#%% - - - - - - - - - - - -#%% CORRELATED AVALANCHE SPE -file_path = 'self/' # folder with H5 data files -run_spe_solicited = RunInfo([file_path+'Run_1648191265.hdf5'], do_filter = True, is_solicit = True, upper_limit = 1, baseline_correct = True) -files = ['Run_1648176286','Run_1648179496', 'Run_1648181807', 'Run_1648184235', 'Run_1648186910'] #, 'Run_1648186910', 'Run_1648171846' -proms = [0.05, 0.05, 0.05, 0.05, 0.05, 0.05] -upperlim = [5, 5, 5, 5, 5, 5] -runs = [] -for file in range(len(files)): - run_spe = RunInfo([file_path + files[file] + '.hdf5'], do_filter = True, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file]) - runs.append(run_spe) -biases = [run.bias for run in runs] # get all the bias voltages from RunInfo (enter manually if metadata is wrong) -#%% -a_guess = 0.01689 -b_guess = -0.4739 -range_lows = [0.05, 0.059, 0.071, 0.09, 0.09, 0.04] -centers = [biases[i]*a_guess+b_guess for i in range(len(runs))] -range_highs = [centers[i]*4 + range_lows[i] for i in range(len(runs))] -#%% -campaign_spe = [] -for i in range(len(runs)): - info_spe = MeasurementInfo() - info_spe.condition = 'Vacuum' - info_spe.date = 'March 2022' - info_spe.temperature = 190 - info_spe.bias = runs[i].bias - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 200 - info_spe.data_type = 'h5' - wp_spe = WaveformProcessor(info_spe, run_info_self = runs[i], run_info_solicit = run_spe_solicited, baseline_correct = True, range_low = range_lows[i], range_high = range_highs[i], center = centers[i]) - wp_spe.process(do_spe = True, do_alpha = False) - campaign_spe.append(wp_spe) -#%% -invC_spe_filter = 0.19261918346201742 -invC_spe_err_filter = 0.0021831140214106596 -spe = SPE_data(campaign_spe, invC_spe_filter, invC_spe_err_filter, filtered = True) -#%% - - - - - - -#%% ALPHA - 100ns -#100ns, new shaper, no gain, no filter -invC_alpha_100ns = 0.004074442176917963 -invC_alpha_err_100ns = 1.4320358414009397E-05 -file_path = 'self/' # folder with H5 data files -files = ['Acquisition_1684439574', 'Acquisition_1684439834','Acquisition_1684440058', 'Acquisition_1684440328','Acquisition_1684440542', 'Acquisition_1684440766', 'Acquisition_1684441008','Acquisition_1684441249','Acquisition_1684441553', 'Acquisition_1684441781', 'Acquisition_1684442031', 'Acquisition_1684442292', 'Acquisition_1684442515', 'Acquisition_1684442713', 'Acquisition_1684442986', 'Acquisition_1684443190', 'Acquisition_1684443416'] -proms = [0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01] -upperlim = [10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10] -runs_alpha_100ns = [] -for file in range(len(files)): - run_alpha_100ns = RunInfo([file_path+'Run_1684439289.hdf5'], specifyAcquisition = True, acquisition = files[file], do_filter = False, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file], is_solicit = False) - runs_alpha_100ns.append(run_alpha_100ns) -biases = [run.bias for run in runs_alpha_100ns] # get all the bias voltages from RunInfo (enter manually if metadata is wrong) - -#%% ALPHA - 1us -#1us, no gain, no filter -invC_alpha_1us = 0.004074442176917963 # *************PLACEHOLDER -invC_alpha_err_1us = 1.4320358414009397E-05 # ********PLACEHOLDER -file_path = 'self/' # folder with H5 data files -files = [ 'Run_1658339042.hdf5', 'Run_1658339468.hdf5', 'Run_1658339739.hdf5', 'Run_1658339990.hdf5', 'Run_1658340318.hdf5' ] -proms = [ .15 for i in range(len(files)) ] -upperlim = [ 20 for i in range(len(files)) ] -runs_alpha_1us = [] -for file in range(len(files)): - run_alpha_1us = RunInfo([file_path+files[file]], do_filter = False, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file], is_solicit = False, plot_waveforms=False) - runs_alpha_1us.append(run_alpha_1us) -biases = [run.bias for run in runs_alpha_1us] # get all the bias voltages from RunInfo (enter manually if metadata is wrong) -runs_alpha_1us[0].plot_hists('169.9', '.1') -# runs_alpha_1us[0].plot_peak_waveform_hist() - -#%% -campaign_alpha = [] -runs_alpha = runs_alpha_1us #change as needed -bins = [40,40,50,50,50,50,50,50,60,60,60,70,70,70,70,70,70,70,70] -for i in range(len(runs_alpha)): - info_alpha = MeasurementInfo() - info_alpha.min_alpha_value = 0.029 - if i > 8: # set lower cutoff to be higher for higher ov - info_alpha.min_alpha_value = 0.3 - info_alpha.condition = 'LXe' - info_alpha.date = runs_alpha[i].date - info_alpha.temperature = 170 - info_alpha.bias = runs_alpha[i].bias - info_alpha.baseline_numbins = 40 - info_alpha.peaks_numbins = bins[i] - info_alpha.data_type = 'h5' - print(f"{i=}") - wp = WaveformProcessor(info_alpha, run_info_self = runs_alpha[i], baseline_correct = True, no_solicit = True, range_high = 10) - wp.process(do_spe = False, do_alpha = True) - j, k = wp.get_alpha() - campaign_alpha.append(wp) - print(f"{info_alpha.bias=}") -#%% -runs_alpha[0].plot_hists('','') -for i in range(len(runs_alpha)): - campaign_alpha[i].plot_alpha_histogram(peakcolor = 'blue') -#%% -invC_alpha = invC_alpha_1us -invC_alpha_err = invC_alpha_err_1us -alpha_data = Alpha_data(campaign_alpha, invC_alpha, invC_alpha_err, spe, v_bd, v_bd_err) -alpha_data.analyze_alpha() -#%% -alpha_data.plot_alpha(color = 'purple') -alpha_data.plot_num_det_photons() -#%% values based on Wesley's APS slides -N = 5.49/(19.6E-6) -PTE = 0.0042 -alpha_data.plot_PDE(N*PTE) diff --git a/LXe_July_2023_Analysis.py b/LXe_July_2023_Analysis.py deleted file mode 100644 index 89011df..0000000 --- a/LXe_July_2023_Analysis.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Jul 13 2023 - -@author: Ed van Bruggen (evanbruggen@umass.edu) -""" - -%load_ext autoreload -%autoreload 2 -import sys -import numpy as np -from MeasurementInfo import MeasurementInfo -from RunInfo import RunInfo -import heapq -from scipy import signal -from scipy.optimize import curve_fit -import AnalyzePDE -from AnalyzePDE import SPE_data -from AnalyzePDE import Alpha_data -import matplotlib.pyplot as plt -import matplotlib as mpl -import ProcessWaveforms_MultiGaussian -from ProcessWaveforms_MultiGaussian import WaveformProcessor as WaveformProcessor -import pickle -import dill - -#%% ALPHA - 1us -#1us, no gain, no filter -invC_alpha_1us = 0.001142 -invC_alpha_err_1us = 0.0000021 -file_path = 'alpha_july/' # folder with H5 data files -files = [ 'Run_1689278620.hdf5', 'Run_1689279162.hdf5', 'Run_1689281334.hdf5', - 'Run_1689281964.hdf5', 'Run_1689282438.hdf5', 'Run_1689278958.hdf5', - 'Run_1689280412.hdf5', 'Run_1689281693.hdf5', 'Run_1689282206.hdf5'] -files += ['Run_1689276244.hdf5', 'Run_1689277404.hdf5', 'Run_1689280793.hdf5'] -files += ['Run_1689282865.hdf5', 'Run_1689283492.hdf5', 'Run_1689278000.hdf5', 'Run_1689279935.hdf5' ] -proms = [0.15,0.15,0.15, 0.15,0.15,0.15, 0.15,0.15,0.15, 0.08,0.1,0.15, 0.05,0.8,0.03,0.15] -upperlim = [1.2,.5,2, 2,.8,10, 1,4,1.5, .3,.4,.8, .2,10,.15,.5] -runs_alpha_1us = [] -i = 0 -# files = files[i:i+1] -for file in range(len(files)): - run_alpha_1us = RunInfo([file_path+files[file]], do_filter=False, - upper_limit=upperlim[file+i], baseline_correct=True, - prominence=proms[file+i], plot_waveforms=False) - # run_alpha_1us.plot_hists('','') - runs_alpha_1us.append(run_alpha_1us) -biases = [run.bias for run in runs_alpha_1us] # get all the bias voltages from RunInfo - -#%% -campaign_alpha = [] -runs_alpha = runs_alpha_1us #change as needed -bins = [34,40,40, 40,38,40, 36,40,41, 35,38,37, 40,37,31,37] -for n in range(len(runs_alpha)): - info_alpha = MeasurementInfo() - info_alpha.min_alpha_value = 0.029 - info_alpha.condition = 'LXe' - info_alpha.date = runs_alpha[n].date - info_alpha.temperature = 167 - info_alpha.bias = runs_alpha[n].bias - info_alpha.baseline_numbins = 40 - info_alpha.peaks_numbins = bins[n] - # print(f'{n=}') - # print(f"{info_alpha.bias=}") - wp = WaveformProcessor(info_alpha, run_info_self = runs_alpha[n], baseline_correct = True, - no_solicit = True, cutoff=(0,10)) - wp.process(do_spe = False, do_alpha = True) - j, k = wp.get_alpha() - wp.plot_alpha_histogram(peakcolor = 'blue') - campaign_alpha.append(wp) - # break - -v_bd = 27.69 -v_bd_err = 0.06 -alpha_data = Alpha_data(campaign_alpha, invC_alpha_1us, invC_alpha_err_1us, spe, v_bd, v_bd_err) - -alpha_data.analyze_alpha() - -#%% -alpha_data.plot_alpha() - -alpha_data.plot_num_det_photons() - -##%% values based on Wesley's APS slides -N = 5.49/(19.6E-6) -PTE = 0.0042 -alpha_data.plot_PDE(N*PTE) diff --git a/LXe_June_28_2023_Analysis.py b/LXe_June_28_2023_Analysis.py deleted file mode 100644 index 22c2d78..0000000 --- a/LXe_June_28_2023_Analysis.py +++ /dev/null @@ -1,163 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Jun 9 14:28:38 2023 - -@author: hpeltzsmalle -@author: Ed van Bruggen (evanbruggen@umass.edu) -""" - -%load_ext autoreload -%autoreload 2 -import sys -import numpy as np -from MeasurementInfo import MeasurementInfo -from RunInfo import RunInfo -import heapq -from scipy import signal -from scipy.optimize import curve_fit -import AnalyzePDE -from AnalyzePDE import SPE_data -from AnalyzePDE import Alpha_data -import matplotlib.pyplot as plt -import matplotlib as mpl -import ProcessWaveforms_MultiGaussian -from ProcessWaveforms_MultiGaussian import WaveformProcessor as WaveformProcessor -import pickle -import dill - -run_spe_solicited = RunInfo(['Run_1666778594.hdf5'], specifyAcquisition = True, acquisition ='Acquisition_1666781843', do_filter = True, is_solicit = True, upper_limit = .5, baseline_correct = True) -files = ['Acquisition_1666778815','Acquisition_1666779156','Acquisition_1666782030','Acquisition_1666780808','Acquisition_1666779491'] -proms = [0.035,0.04,0.04,0.05,0.055] -upperlim = [4, 4, 4, 4, 4] -runs = [] -for file in range(len(files)): - run_spe = RunInfo(['Run_1666778594.hdf5'], specifyAcquisition = True, acquisition = files[file], do_filter = True, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file]) - runs.append(run_spe) -biases = [run.bias for run in runs] - -range_lows = [0.06, 0.08, 0.09, 0.1] -centers = [0.09, 0.11, 0.12, 0.14] -range_highs = [0.403, 0.5, 0.56, 0.67] -campaign_spe = [] -for i in range(len(runs)): - info_spe = MeasurementInfo() - info_spe.condition = 'GN' - info_spe.date = runs[i].date - info_spe.temperature = '167' - info_spe.bias = biases[i] - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 220 - info_spe.data_type = 'h5' - wp_spe = WaveformProcessor(info_spe, run_info_self = runs[i], run_info_solicit = run_spe_solicited, baseline_correct = True, range_low = range_lows[i], range_high = range_highs[i], center = centers[i]) - wp_spe.process(do_spe = True, do_alpha = False) - campaign_spe.append(wp_spe) -invC_spe_filter = 0.19261918346201742 -invC_spe_err_filter = 0.0021831140214106596 -spe = SPE_data(campaign_spe, invC_spe_filter, invC_spe_err_filter, filtered = True) - -##%% CORRELATED AVALANCHE SPE -#file_path = 'self/' # folder with H5 data files -#run_spe_solicited = RunInfo([file_path+'Run_1648191265.hdf5'], do_filter = True, is_solicit = True, upper_limit = 1, baseline_correct = True) -#files = ['Run_1648176286','Run_1648179496', 'Run_1648181807', 'Run_1648184235', 'Run_1648186910'] #, 'Run_1648186910', 'Run_1648171846' -#proms = [0.05, 0.05, 0.05, 0.05, 0.05, 0.05] -#upperlim = [5, 5, 5, 5, 5, 5] -#runs = [] -#for file in range(len(files)): -# run_spe = RunInfo([file_path + files[file] + '.hdf5'], do_filter = True, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file]) -# runs.append(run_spe) -#biases = [run.bias for run in runs] # get all the bias voltages from RunInfo (enter manually if metadata is wrong) -##%% -#a_guess = 0.01689 -#b_guess = -0.4739 -#range_lows = [0.05, 0.059, 0.071, 0.09, 0.09, 0.04] -#centers = [biases[i]*a_guess+b_guess for i in range(len(runs))] -#range_highs = [centers[i]*4 + range_lows[i] for i in range(len(runs))] -##%% -#campaign_spe = [] -#for i in range(len(runs)): -# info_spe = MeasurementInfo() -# info_spe.condition = 'Vacuum' -# info_spe.date = 'March 2022' -# info_spe.temperature = 190 -# info_spe.bias = runs[i].bias -# info_spe.baseline_numbins = 50 -# info_spe.peaks_numbins = 200 -# info_spe.data_type = 'h5' -# wp_spe = WaveformProcessor(info_spe, run_info_self = runs[i], run_info_solicit = run_spe_solicited, baseline_correct = True, range_low = range_lows[i], range_high = range_highs[i], center = centers[i]) -# wp_spe.process(do_spe = True, do_alpha = False) -# campaign_spe.append(wp_spe) -##%% -#invC_spe_filter = 0.19261918346201742 -#invC_spe_err_filter = 0.0021831140214106596 -#spe = SPE_data(campaign_spe, invC_spe_filter, invC_spe_err_filter, filtered = True) - - - - - - -#%% ALPHA - 1us -#1us, no gain, no filter -invC_alpha_1us = 0.001142 -invC_alpha_err_1us = 0.0000021 -file_path = 'alpha-june-28/' # folder with H5 data files -files = ['Run_1687969527.hdf5', 'Run_1687969770.hdf5', 'Run_1687970855.hdf5', - 'Run_1687971807.hdf5', 'Run_1687972206.hdf5', 'Run_1687971430.hdf5', - 'Run_1687972646.hdf5', 'Run_1687973035.hdf5', 'Run_1687973389.hdf5', - 'Run_1687973682.hdf5', 'Run_1687974000.hdf5', 'Run_1687974651.hdf5', 'Run_1687975037.hdf5'] -proms = [0.08,0.08,0.08, 0.09,0.05,0.2, 0.4,0.35,0.25, 0.25,0.5,0.8,0.2] -upperlim = [.2,.3,.4, 2,.2,.8, 1.3,1,0.5, 1.2,2.5,1.7,1] -runs_alpha_1us = [] -for file in range(len(files)): - run_alpha_1us = RunInfo([file_path+files[file]], do_filter=False, upper_limit=upperlim[file], baseline_correct=True, prominence=proms[file], plot_waveforms=False) - runs_alpha_1us.append(run_alpha_1us) -biases = [run.bias for run in runs_alpha_1us] # get all the bias voltages from RunInfo (enter manually if metadata is wrong) -# runs_alpha_1us[0].plot_hists('169.9', '.1') -# runs_alpha_1us[0].plot_peak_waveform_hist() - -#%% -# TODO 29, 31 -# TODO fix 33V? chi^2 is very high -campaign_alpha = [] -runs_alpha = runs_alpha_1us #change as needed -bins = [36,35,34, 32,29,30, 33,32,37,35, 33,43,30] -for i in range(len(runs_alpha)): - info_alpha = MeasurementInfo() - info_alpha.min_alpha_value = 0.3 if i > 8 else 0.029 - info_alpha.condition = 'LXe' - info_alpha.date = runs_alpha[i].date - info_alpha.temperature = 167 - info_alpha.bias = runs_alpha[i].bias - info_alpha.baseline_numbins = 40 - info_alpha.peaks_numbins = bins[i] - # print(f"{i=}") - # print(f"{info_alpha.bias=}") - wp = WaveformProcessor(info_alpha, run_info_self = runs_alpha[i], baseline_correct = True, no_solicit = True, range_high = 10) - wp.process(do_spe = False, do_alpha = True) - j, k = wp.get_alpha() - # wp.plot_alpha_histogram(peakcolor = 'blue') - campaign_alpha.append(wp) - -#%% -# with open('LED-SPE/campaign_alpha.pickle', 'wb') as f: -# dill.dump(campaign_alpha, f) - -# p = dill.Unpickler(open("LED-SPE/SPE-June-28.pickle","rb")) -# p.fast = True -# spe = p.load() - -v_bd = 27.69 -v_bd_err = 0.06 -alpha_data = Alpha_data(campaign_alpha, invC_alpha_1us, invC_alpha_err_1us, spe, v_bd, v_bd_err) - -alpha_data.analyze_alpha() - -#%% -alpha_data.plot_alpha() - -alpha_data.plot_num_det_photons() - -##%% values based on Wesley's APS slides -N = 5.49/(19.6E-6) -PTE = 0.0042 -alpha_data.plot_PDE(N*PTE) diff --git a/LXe_March_2023_Analysis.py b/LXe_March_2023_Analysis.py deleted file mode 100644 index 6a5d48c..0000000 --- a/LXe_March_2023_Analysis.py +++ /dev/null @@ -1,211 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sun Jun 25 14:38:28 2023 - -@author: Jaime -""" -import os -os.chdir('C:/Users/Jaime/Desktop/Analysis/SPE-Analysis') -import sys -import numpy as np -from MeasurementInfo import MeasurementInfo -from RunInfo import RunInfo -import heapq -from scipy import signal -from scipy.optimize import curve_fit -import AnalyzePDE -from AnalyzePDE import SPE_data -from AnalyzePDE import Alpha_data -import matplotlib.pyplot as plt -import matplotlib as mpl -import ProcessWaveforms_MultiGaussian -from ProcessWaveforms_MultiGaussian import WaveformProcessor as WaveformProcessor - -#%% SPE-VBD -#CR-Z Preamp, Shaper "0", 100x gain, filtered (change as needed; make sure it is the correct factor for the data set) -invC_spe_filter = 0.011959447603692185 -invC_spe_err_filter = 3.881945391072933E-05 -# loop quickly loads in files -# separate files for each bias voltage -> specifyAcquisition = False -files = ['Run_1680287257', - 'Run_1680286846', - 'Run_1680285923', - 'Run_1680285397', - 'Run_1680284969', - 'Run_1680282125'] -proms = [0.025,0.025,0.025,0.025,0.025,0.025,0.025,0.025,0.025] -upperlim = [1, 1, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8, 1.8] -runs_spe = [] -for file in range(len(files)): - run_spe = RunInfo(['C:/Users/Jaime/Desktop/Analysis/SPE-Analysis/'+files[file]+'.hdf5'], specifyAcquisition = False, do_filter = True, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file]) - runs_spe.append(run_spe) -biases = [run.bias for run in runs_spe] - -#%% -cutoffs = [] -centers_list=[] -centers_guesses = [] - -for run in runs_spe: - bins = int(round(np.sqrt(len(run.all_peak_data)))) - count, edges = np.histogram(run.all_peak_data, bins=bins) - centers = (edges[:-1] + edges[1:])/2 - - peaks, props = signal.find_peaks(count, prominence=25, distance=5) - - fitrange = ((centers[peaks[3]] - centers[peaks[1]])/2) - range_low = centers[peaks[1]]- 0.28*fitrange - range_high = centers[peaks[4]]+ 0.35*fitrange - - cutoffs.append((range_low, range_high)) - centers_list.append(centers[peaks[1]]) - peaks = peaks[1:] - centers_guesses.append([centers[peak] for peak in peaks]) - - plt.figure() - plt.hist(run.all_peak_data, bins=bins) - for peak in peaks: - plt.scatter(centers[peak],count[peak]) - plt.axvline(range_low, c='red') - plt.axvline(range_high, c='black') - plt.xlim([0,1]) - plt.yscale('log') - - -#%% compute baseline info - -run_baseline = RunInfo(['C:/Users/Jaime/Desktop/Analysis/SPE-Analysis/Run_1680287728.hdf5'], - is_solicit=True, do_filter=True, baseline_correct=True) -info_solicited = MeasurementInfo() -info_solicited.condition = 'LXe' -info_solicited.date = run_baseline.date.decode() -info_solicited.temperature = 170 -info_solicited.baseline_numbins=300 -info_solicited.date_type = 'h5' - - -#%% testing cell - plot with peak fit -# set conditions, temp -for i in range(len(biases)): - T = 170.5 - con = 'LXe' - info_spe = MeasurementInfo() - info_spe.condition = con - info_spe.date = runs_spe[i].date.decode('utf-8') - info_spe.temperature = T - info_spe.bias = biases[i] - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 150 - info_spe.data_type = 'h5' - wp = WaveformProcessor(info_spe, centers = centers_guesses[i], - run_info_self = runs_spe[i], - run_info_solicit = run_baseline, - baseline_correct = True, cutoff = cutoffs[i]) - - wp.process(do_spe = True, do_alpha = False) - wp.plot_peak_histograms() - # plt.savefig(f'hist_Run_{files[i]}_4') - wp.plot_spe() - # plt.savefig(f'SPE_Run_{files[i]}_4') - -#%% make a list of ProcessWaveforms objects -campaign_spe = [] -for i in range(len(runs_spe)): - info_spe = MeasurementInfo() - info_spe.condition = 'LXe' - info_spe.date = runs_spe[i].date.decode('utf-8') - info_spe.temperature = 170 - info_spe.bias = runs_spe[i].bias - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 150 - info_spe.data_type = 'h5' - wp_spe = WaveformProcessor(info_spe, centers = centers_guesses[i], - run_info_self = runs_spe[i], - run_info_solicit = run_baseline, - baseline_correct = True, cutoff = cutoffs[i]) - wp_spe.process(do_spe = True, do_alpha = False) - campaign_spe.append(wp_spe) - -#%% - - - -#%% -curr_campaign = campaign_spe -filtered_spe = SPE_data(curr_campaign, invC_spe_filter, invC_spe_err_filter, filtered = True) -filtered_spe.plot_spe(in_ov = False, absolute = False, out_file = None) - -print(filtered_spe.v_bd) -print(filtered_spe.v_bd_err) - -#%% plot in units of absolute gain vs OV -filtered_spe.plot_spe(in_ov = True, absolute = True, out_file = None) -#%% record BD voltage -v_bd = 27.29 -v_bd_err = 0.0579 -spe = SPE_data(campaign_spe, invC_spe_filter, invC_spe_err_filter, filtered = True) - -#%% -path = 'C:/Users/Jaime/Desktop/Analysis/SPE-Analysis/Run_1680279197.hdf5' -with h5py.File(path, 'r') as hdf: - keys = list(hdf['RunData'].keys()) - -i=0 -key = keys[i] -proms = [0.08,0.08,0.08, 0.09,0.05,0.2, 0.4,0.35,0.25, 0.25,0.5,0.8,0.2] -run_alpha = RunInfo(file, do_filter=False, upper_limit=5, - baseline_correct=True, prominence=0.01, - specifyAcquisition=True, acquisition=key, - plot_waveforms=True) -#%% Alpha Data Time -runs_alpha = [] -path = 'C:/Users/Jaime/Desktop/Analysis/SPE-Analysis/Run_1680279197.hdf5' -with h5py.File(path, 'r') as hdf: - keys = list(hdf['RunData'].keys()) - -file = [path] -for i,key in enumerate(keys): - - run_alpha = RunInfo(file, do_filter=False, upper_limit=5, - baseline_correct=True, prominence=0.01, - specifyAcquisition=True, acquisition=key) - run_alpha.plot_hists('0','0') - biases = [run.bias for run in runs_alpha] - runs_alpha.append(run_alpha) - - -#%% - -campaign_alpha = [] -min_alphas = [1,0.3,0.3,0,0,0,0,0] -for i in range(len(runs_alpha)): - info_alpha = MeasurementInfo() - info_alpha.min_alpha_value = min_alphas[i] - info_alpha.condition = 'LXe' - info_alpha.date = str(runs_alpha[i].date) - info_alpha.temperature = 170 - info_alpha.bias = runs_alpha[i].bias - info_alpha.baseline_numbins = 40 - bins = int(round(np.sqrt(len(runs_alpha[i].all_peak_data)))) - info_alpha.peaks_numbins = bins - wp = WaveformProcessor(info_alpha, run_info_self = runs_alpha[i], - run_info_solicit = run_baseline, - no_solicit=True, - baseline_correct = True) - wp.process(do_spe = False, do_alpha = True) - wp.plot_alpha_histogram(peakcolor = 'blue') - campaign_alpha.append(wp) - -#%% - -# invC_spe_filter = 0.011959447603692185 -# invC_spe_err_filter = 3.881945391072933E-05 -# spedata = SPE_data(campaign_spe, invC_spe_filter, invC_spe_err_filter, filtered=True) - -#%% -#GET NEW SPEDATA FROM GAS OR VACUUM -invC_alpha = 0.011959447603692185 -invC_alpha_err = 3.881945391072933E-05 -v_bd = spedata.v_bd -v_bd_err = spedata.v_bd_err -alphadata = Alpha_data(campaign_alpha, invC_alpha, invC_alpha_err, spedata, v_bd, v_bd_err) diff --git a/LXe_May_2023_Analysis.py b/LXe_May_2023_Analysis.py deleted file mode 100644 index 78a08bc..0000000 --- a/LXe_May_2023_Analysis.py +++ /dev/null @@ -1,394 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Jun 9 14:28:38 2023 - -@author: hpeltzsmalle -""" - -import sys -import numpy as np -# append necessary file paths, and change E -> D or vice versa -sys.path.append('D:/Xe/AnalysisScripts/LXe May 2023/') -from MeasurementInfo import MeasurementInfo -from RunInfo import RunInfo -import heapq -from scipy import signal -from scipy.optimize import curve_fit -import AnalyzePDE -from AnalyzePDE import SPE_data -from AnalyzePDE import Alpha_data -import matplotlib.pyplot as plt -import matplotlib as mpl -import ProcessWaveforms_MultiGaussian -from ProcessWaveforms_MultiGaussian import WaveformProcessor as WaveformProcessor -import h5py -plt.style.use('D:/Xe/AnalysisScripts/LXe May 2023/nexo_new.mplstyle') - -#%% SPE-VBD -#100ns, new shaper, 10x gain, filtered -invC_spe_filter = 0.011959447603692185 -invC_spe_err_filter = 3.881945391072933E-05 -# loop quickly loads in files -# separate files for each bias voltage -> specifyAcquisition = False -run_spe_solicited = RunInfo(['D:/Xe/DAQ/Run_1686747967.hdf5'], specifyAcquisition = False, do_filter = True, is_solicit = True, upper_limit = 1, baseline_correct = True) -files = ['Run_1684433317','Run_1684434365','Run_1684434800','Run_1684435362','Run_1684435943','Run_1684436416','Run_1684436838','Run_1684437151','Run_1684437508'] #32, 32.5, 33, 33.5, 34, 34.5, 35, 35.5, 36 -# proms = [0.003,0.003,0.003,0.003,0.003,0.003,0.003,0.003,0.003] -upperlim = [0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18] -runs = [] -# for file in range(len(files)): -for file in range(0,len(files)): - run_spe = RunInfo(['D:/Xe/DAQ/'+files[file]+'.hdf5'], specifyAcquisition = False, do_filter = True, upper_limit = upperlim[file], baseline_correct = True, prominence = 0.0032, poly_correct = True) - runs.append(run_spe) -biases = [run.bias for run in runs] -#%% -RunInfo(['D:/Xe/DAQ/'+files[0]+'.hdf5'], specifyAcquisition = False, do_filter = True, upper_limit = 0.1, baseline_correct = True, prominence = 0.0028, poly_correct = True, plot_waveforms = True) -#%% -cutoffs = [] -centers_list=[] -centers_guesses = [] - -for run in runs: - bins = int(round(np.sqrt(len(run.all_peak_data)))) - print(bins) - count, edges = np.histogram(run.all_peak_data, bins=bins) - centers = (edges[:-1] + edges[1:])/2 - peaks, props = signal.find_peaks(count, prominence=25, distance=5) - print(peaks) - fitrange = ((centers[peaks[3]] - centers[peaks[0]])/2) - range_low = centers[peaks[0]]- 0.28*fitrange - range_high = centers[peaks[3]]+ 0.35*fitrange - - cutoffs.append((range_low, range_high)) - centers_list.append(centers[peaks[0]]) - peaks = peaks[0:] - centers_guesses.append([centers[peak] for peak in peaks]) - - plt.figure() - plt.hist(run.all_peak_data, bins=bins) - for peak in peaks: - plt.scatter(centers[peak],count[peak]) - plt.axvline(range_low, c='red') - plt.axvline(range_high, c='black') - # plt.xlim([0,1]) - plt.yscale('log') -#%% testing cell - plot with peak fit -# set conditions, temp -n=0 -T = 170 -con = 'LXe' -info_spe = MeasurementInfo() -info_spe.condition = con -info_spe.date = runs[n].date -info_spe.temperature = T -info_spe.bias = biases[n] -info_spe.baseline_numbins = 80 -info_spe.peaks_numbins = 150 -info_spe.data_type = 'h5' -wp = WaveformProcessor(info_spe, run_info_self = runs[n], run_info_solicit = run_spe_solicited, baseline_correct = True, cutoff = cutoffs[n], centers = centers_guesses[n], numpeaks = 4) -wp.process(do_spe = True, do_alpha = False) -wp.plot_peak_histograms(log_scale = False) -wp.plot_spe() -wp.plot_both_histograms() -wp.plot_baseline_histogram() - -#%% make a list of ProcessWaveforms objects -campaign_spe = [] -for i in range(len(runs)): - info_spe = MeasurementInfo() - info_spe.condition = 'LXe' - info_spe.date = runs[i].date - info_spe.temperature = 170 - info_spe.bias = runs[i].bias - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 150 - info_spe.data_type = 'h5' - # if i == 2: - # num = 3 - # else: - num = 4 - wp_spe = WaveformProcessor(info_spe, run_info_self = runs[i], run_info_solicit = run_spe_solicited, baseline_correct = True, cutoff = cutoffs[i], centers = centers_guesses[i], no_solicit = False, numpeaks = num) - wp_spe.process(do_spe = True, do_alpha = False) - wp_spe.plot_peak_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/May_170K_gauss_'+str(info_spe.bias)+'.png') - wp_spe.plot_spe(savefig=True, path = 'D:/Xe/AnalysisScripts/May_170K_spe_'+str(info_spe.bias)+'.png') - wp_spe.plot_both_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/May_170K_baseline_'+str(info_spe.bias)+'.png') - wp_spe.plot_peak_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/May_170K_gauss_'+str(info_spe.bias)+'.svg') - wp_spe.plot_spe(savefig=True, path = 'D:/Xe/AnalysisScripts/May_170K_spe_'+str(info_spe.bias)+'.svg') - wp_spe.plot_both_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/May_170K_baseline_'+str(info_spe.bias)+'.svg') - plt.close() - campaign_spe.append(wp_spe) - -#%% plot linear fit to the breakdown voltage -curr_campaign = campaign_spe -filtered_spe = SPE_data(curr_campaign, invC_spe_filter, invC_spe_err_filter, filtered = True) -filtered_spe.plot_spe(in_ov = False, absolute = False, out_file = 'D:/Xe/AnalysisScripts/May_170K_vbd_bias_updated.csv') - -print(filtered_spe.v_bd) -print(filtered_spe.v_bd_err) - -#%% plot in units of absolute gain vs OV -filtered_spe.plot_spe(in_ov = True, absolute = True, out_file = 'D:/Xe/AnalysisScripts/May_170K_vbd_ov_updated.csv') -#%% record BD voltage -# v_bd = 27.68 -# v_bd_err = 0.05 -v_bd = 27.67 -v_bd_err = 0.09 -#%% - - - - - - - - - - - -#%% CORRELATED AVALANCHE SPE -# polynomial baseline correct off -# 405 nm 2.55V -run_spe_solicited_CA = RunInfo(['D:/Xe/DAQ/Run_1689175515.hdf5'], do_filter = True, is_solicit = True, upper_limit = 1, baseline_correct = True) -files = ['Run_1689178348','Run_1689177955', 'Run_1689177434', 'Run_1689176952', 'Run_1689175759', 'Run_1689175049'] #, 'Run_1689173976' -runs_CA = [] -for file in range(len(files)): - run_spe_CA = RunInfo(['D:/Xe/DAQ/' + files[file] + '.hdf5'], do_filter = True, upper_limit = 1, baseline_correct = True, prominence = 0.0055) - runs_CA.append(run_spe_CA) -biases = [run.bias for run in runs_CA] # get all the bias voltages from RunInfo (enter manually if metadata is wrong) - -# test = RunInfo(['D:/Xe/DAQ/' + files[-1] + '.hdf5'], do_filter = True, upper_limit = 1, baseline_correct = True, prominence = 0.005) -# test.plot_hists('','') -#%% CORRELATED AVALANCHE SPE -# polynomial baseline correct commented out in RunInfo -# 310 nm 3.65V -run_spe_solicited_CA = RunInfo(['D:/Xe/DAQ/Run_1689154239.hdf5'], do_filter = False, is_solicit = True, upper_limit = 1, baseline_correct = True) -files = ['Run_1689157735', 'Run_1689157266', 'Run_1689156867', 'Run_1689156453', 'Run_1689155459', 'Run_1689155036'] #, 'Run_1689154632' -runs_CA = [] -for file in range(len(files)): - run_spe_CA = RunInfo(['D:/Xe/DAQ/' + files[file] + '.hdf5'], do_filter = False, upper_limit = 1, baseline_correct = True, prominence = 0.005) - runs_CA.append(run_spe_CA) -biases = [run.bias for run in runs_CA] # get all the bias voltages from RunInfo (enter manually if metadata is wrong) -#%% -cutoffs = [] -centers_list=[] -centers_guesses = [] - -for run in runs_CA: - bins = int(round(np.sqrt(len(run.all_peak_data)))) - print(bins) - count, edges = np.histogram(run.all_peak_data, bins=bins) - centers = (edges[:-1] + edges[1:])/2 - peaks, props = signal.find_peaks(count, prominence=30, distance=3) - print(peaks) - fitrange = ((centers[peaks[3]] - centers[peaks[0]])/2) - range_low = centers[peaks[0]]- 0.36*fitrange - range_high = centers[peaks[3]]+ 0.4*fitrange - if run.bias < 33: - range_low = centers[peaks[0]]- 0.36*fitrange - range_high = centers[peaks[3]]+ 0.27*fitrange - - cutoffs.append((range_low, range_high)) - centers_list.append(centers[peaks[0]]) - peaks = peaks[0:] - centers_guesses.append([centers[peak] for peak in peaks]) - - # plt.figure() - # plt.hist(run.all_peak_data, bins=bins) - # for peak in peaks: - # plt.scatter(centers[peak],count[peak]) - # plt.axvline(range_low, c='red') - # plt.axvline(range_high, c='black') - # plt.xlim([0,1]) - # plt.yscale('log') - -# %% testing cell - plot with peak fit -# set conditions, temp -n=5 -T = 171 -con = 'GN' -info_spe = MeasurementInfo() -info_spe.condition = con -info_spe.date = runs_CA[n].date -info_spe.temperature = T -info_spe.bias = runs_CA[n].bias -info_spe.baseline_numbins = 50 -info_spe.peaks_numbins = 500 -info_spe.data_type = 'h5' -wp = WaveformProcessor(info_spe, run_info_self = runs_CA[n], run_info_solicit = run_spe_solicited_CA, baseline_correct = True, cutoff = cutoffs[n], centers = centers_guesses[n], numpeaks = 4) -wp.process(do_spe = True, do_alpha = False) -# wp.plot_peak_histograms(log_scale = False) -# wp.plot_spe() -wp.plot_both_histograms() -# wp.plot_baseline_histogram() - -#%% make a list of ProcessWaveforms objects -campaign_CA = [] -for i in range(len(runs_CA)): - info_spe = MeasurementInfo() - info_spe.condition = 'GN' - info_spe.date = runs_CA[i].date - info_spe.temperature = 171 - info_spe.bias = runs_CA[i].bias - info_spe.baseline_numbins = 50 - info_spe.peaks_numbins = 400 - info_spe.data_type = 'h5' - num = 4 - wp_spe = WaveformProcessor(info_spe, run_info_self = runs_CA[i], run_info_solicit = run_spe_solicited_CA, baseline_correct = True, cutoff = cutoffs[i], centers = centers_guesses[i], no_solicit = False, numpeaks = num) - wp_spe.process(do_spe = True, do_alpha = False) - wp_spe.plot_peak_histograms(log_scale = False) - campaign_CA.append(wp_spe) -#%% -invC_CA_filter = 0.01171 -invC_CA_err_filter = 4.8E-05 -spe_CA = SPE_data(campaign_CA, invC_CA_filter, invC_CA_err_filter, filtered = True) -spe_CA.plot_spe(in_ov = False, absolute = False, out_file = 'D:/Xe/AnalysisScripts/CA_vbd_bias.csv') -#%% -spe_CA.plot_CA(out_file='D:/Xe/AnalysisScripts/LXe May 2023/CA_GN.csv') -spe_CA.plot_CA_rms() -#%% -n = 0 -for i in campaign_CA: - n+=1 - i.plot_peak_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe May 2023/CA_GN_gauss_'+str(n)+'.png') - plt.close() - i.plot_peak_histograms(log_scale = False, savefig=True, path = 'D:/Xe/AnalysisScripts/LXe May 2023/CA_GN_gauss_'+str(n)+'.svg') - plt.close() - i.plot_spe(savefig=True, path = 'D:/Xe/AnalysisScripts/LXe May 2023/CA_GN_spe_'+str(n)+'.png') - plt.close() - i.plot_spe(savefig=True, path = 'D:/Xe/AnalysisScripts/LXe May 2023/CA_GN_spe_'+str(n)+'.svg') - plt.close() - i.plot_both_histograms(savefig=True, path = 'D:/Xe/AnalysisScripts/LXe May 2023/CA_GN_both_'+str(n)+'.png') - plt.close() - i.plot_both_histograms(savefig=True, path = 'D:/Xe/AnalysisScripts/LXe May 2023/CA_GN_both_'+str(n)+'.svg') - plt.close() -#%% -n = 0 -for i in campaign_CA: - n+=1 - i.plot_peak_histograms(log_scale = False) -#%% ALPHA - 1us -#1us, no gain, no filter -invC_alpha_1us = 0.001142 -invC_alpha_err_1us = 2.1E-6 -files = ['Acquisition_1684439574', 'Acquisition_1684439834','Acquisition_1684440058', 'Acquisition_1684440328','Acquisition_1684440542', 'Acquisition_1684440766', 'Acquisition_1684441008','Acquisition_1684441249','Acquisition_1684441553', 'Acquisition_1684441781', 'Acquisition_1684442031', 'Acquisition_1684442292', 'Acquisition_1684442515', 'Acquisition_1684442713', 'Acquisition_1684442986', 'Acquisition_1684443190', 'Acquisition_1684443416'] -proms = [0.007,0.007,0.007,0.01,0.01,0.01,0.02,0.05,0.05,0.06,0.07,0.07,0.07,0.07, 0.2, 0.35, 0.4, 0.5, 0.5] -upperlim = [0.18,0.18,0.18,0.35,0.35,0.35,0.5,0.8,0.8,0.8,0.8,1.75,1.75,1.75,10,10,10,10,10] -runs_alpha_1us = [] -for file in range(len(files)): - run_alpha_1us = RunInfo(['C:/Users/Hannah/Downloads/Run_1684439289.hdf5'], specifyAcquisition = True, acquisition = files[file], do_filter = False, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file], is_solicit = False) - runs_alpha_1us.append(run_alpha_1us) -biases = [run.bias for run in runs_alpha_1us] # get all the bias voltages from RunInfo (enter manually if metadata is wrong) -#%% -campaign_alpha_1us = [] -runs_alpha = runs_alpha_1us -for i in range(len(runs_alpha)): - info_alpha = MeasurementInfo() - info_alpha.min_alpha_value = 0.01 - if i > 7: # set lower cutoff to be higher for higher ov - info_alpha.min_alpha_value = 0.15 - info_alpha.condition = 'LXe' - info_alpha.date = runs_alpha[i].date - info_alpha.temperature = 170 - info_alpha.bias = runs_alpha[i].bias - info_alpha.baseline_numbins = 40 - info_alpha.peaks_numbins = 50 - info_alpha.data_type = 'h5' - wp = WaveformProcessor(info_alpha, run_info_self = runs_alpha[i], baseline_correct = True, no_solicit = True) - wp.process(do_spe = False, do_alpha = True) - j, k = wp.get_alpha() - campaign_alpha_1us.append(wp) - print(info_alpha.bias) - print(runs_alpha[i].do_filter) -#%% testing -for i in runs_alpha_1us: - i.plot_hists('','') -#%% -alpha_data_1us = Alpha_data(campaign_alpha_1us, invC_alpha_1us, invC_alpha_err_1us, spe_CA, v_bd, v_bd_err) -alpha_data_1us.analyze_alpha() -#%% -alpha_data_1us.plot_alpha(color = 'green', out_file = 'D:/Xe/AnalysisScripts/LXe May 2023/May2023_Alpha_1us.csv') -alpha_data_1us.plot_num_det_photons(color = 'green') -#%% values -N = 5.49/(19.6E-6) # based on Wesley's APS slides -PTE = 0.004928 # Sili's logbook post 12551 / copper reflection 100% specular reflective / diffusive teflon -alpha_data_1us.plot_PDE(N*PTE, color='green', out_file = 'D:/Xe/AnalysisScripts/May_170K_PDE_1us_specular_copper_on_diffusive.csv') - -#%% values -N = 5.49/(19.6E-6) # based on Wesley's APS slides -PTE = 0.014515 # Sili's logbook post 12551 / copper reflection 100% specular reflective / specular teflon -alpha_data_1us.plot_PDE(N*PTE, color='green', out_file = 'D:/Xe/AnalysisScripts/May_170K_PDE_1us_specular_copper_on_specular.csv') - -#%% -N = 5.49/(19.6E-6) # based on Wesley's APS slides -PTE = 0.003741 # Sili's logbook post 12551 / no copper reflection / diffusive teflon -alpha_data_1us.plot_PDE(N*PTE, color='green', out_file = 'D:/Xe/AnalysisScripts/May_170K_PDE_1us_copper_off_diffusive.csv') - -#%% values -N = 5.49/(19.6E-6) # based on Wesley's APS slides -PTE = 0.013578 # Sili's logbook post 12551 / no copper reflection / specular teflon -alpha_data_1us.plot_PDE(N*PTE, color='green', out_file = 'D:/Xe/AnalysisScripts/May_170K_PDE_1us_copper_off_specular.csv') - -#%% values -PTE = 0.005122 # Sili's logbook post 12551 / copper reflection 100% diffusive / diffusive teflon -alpha_data_1us.plot_PDE(N*PTE, color='green', out_file = 'D:/Xe/AnalysisScripts/May_170K_PDE_1us_diffusive_copper_on_diffusive.csv') - -#%% values -PTE = 0.014812 # Sili's logbook post 12551 / copper reflection 100% diffusive / specular teflon -alpha_data_1us.plot_PDE(N*PTE, color='green', out_file = 'D:/Xe/AnalysisScripts/May_170K_PDE_1us_diffusive_copper_on_specular.csv') - - - - -#%% ALPHA - 100ns -#100ns, no gain, no filter -invC_alpha_100ns = 0.004074442176917963 -invC_alpha_err_100ns = 1.4320358414009397E-05 -files = ['Acquisition_1684429006', 'Acquisition_1684429323','Acquisition_1684429598','Acquisition_1684429901', 'Acquisition_1684430142', 'Acquisition_1684430326','Acquisition_1684430543','Acquisition_1684430787', 'Acquisition_1684431075', 'Acquisition_1684431293', 'Acquisition_1684431526', 'Acquisition_1684431824', 'Acquisition_1684432042', 'Acquisition_1684432244', 'Acquisition_1684432473', 'Acquisition_1684432689'] #,'Acquisition_1684432883','Acquisition_1684433075' -proms = [0.01,0.01,0.07,0.07,0.07,0.07,0.07,0.07,0.07,0.07,0.07,0.07,0.07,0.07, 0.2, 0.35, 0.5, 0.5, 1] -upperlim = [0.15,0.15,0.35, 0.35,0.95,0.95,0.95,0.95,1.95,1.95,1.95,4.95,4.95,4.95,4.95,4.95] -runs_alpha_100ns = [] -for file in range(len(files)): - run_alpha_100ns = RunInfo(['C:/Users/Hannah/Downloads/Run_1684428416.hdf5'], specifyAcquisition = True, acquisition = files[file], do_filter = False, upper_limit = upperlim[file], baseline_correct = True, prominence = proms[file], is_solicit = False) - runs_alpha_100ns.append(run_alpha_100ns) -biases = [run.bias for run in runs_alpha_100ns] # get all the bias voltages from RunInfo (enter manually if metadata is wrong) -#%% -campaign_alpha_100ns = [] -runs_alpha = runs_alpha_100ns -for i in range(len(runs_alpha)): - info_alpha = MeasurementInfo() - info_alpha.min_alpha_value = 0.01 - # if i > 7: # set lower cutoff to be higher for higher ov - # info_alpha.min_alpha_value = 0.15 - info_alpha.condition = 'LXe' - info_alpha.date = runs_alpha[i].date - info_alpha.temperature = 170 - info_alpha.bias = runs_alpha[i].bias - info_alpha.baseline_numbins = 40 - info_alpha.peaks_numbins = 50 - info_alpha.data_type = 'h5' - wp = WaveformProcessor(info_alpha, run_info_self = runs_alpha[i], baseline_correct = True, no_solicit = True) - wp.process(do_spe = False, do_alpha = True) - j, k = wp.get_alpha() - campaign_alpha_100ns.append(wp) - print(info_alpha.bias) -#%% -for i in runs_alpha_100ns: - i.plot_hists('','') -#%% -invC_alpha = invC_alpha_100ns -invC_alpha_err = invC_alpha_err_100ns -alpha_data_100ns = Alpha_data(campaign_alpha_100ns, invC_alpha, invC_alpha_err, spe, v_bd, v_bd_err) -alpha_data_100ns.analyze_alpha() -#%% -n = 0 -for i in campaign_alpha_100ns: - n+=1 - i.plot_alpha_histogram(peakcolor = 'purple') - plt.savefig('D:/Xe/AnalysisScripts/LXe May 2023/100ns_'+str(n)+'.png') - plt.close() -#%% -alpha_data_100ns.plot_alpha(color = 'purple', out_file = 'D:/Xe/AnalysisScripts/LXe May 2023/2023May_100ns_alpha.csv') -alpha_data_100ns.plot_num_det_photons() -#%% values -N = 5.49/(19.6E-6) # based on Wesley's APS slides -PTE = 0.003741 # Sili's logbook post 12551 -alpha_data_100ns.plot_PDE(N*PTE, color='purple', out_file = 'D:/Xe/AnalysisScripts/May_170K_PDE_100ns.csv') diff --git a/March2023_AlphaAmplitudes.csv b/March2023_AlphaAmplitudes.csv deleted file mode 100644 index 90cbb9a..0000000 --- a/March2023_AlphaAmplitudes.csv +++ /dev/null @@ -1,9 +0,0 @@ -Bias,Amp,Err -30,0.1067,6.00E-05 -31,0.182,9.00E-05 -32,0.2799,0.0001 -33,0.4168,0.0002 -34,0.6241,0.0003 -35,0.9686,0.0006 -36,1.624,0.0009 -37,3.12,0.003 diff --git a/May2023_Alpha_1us.csv b/May2023_Alpha_1us.csv deleted file mode 100644 index 7de0ebb..0000000 --- a/May2023_Alpha_1us.csv +++ /dev/null @@ -1,18 +0,0 @@ -,Bias voltage [V],Bias voltage [V] error,Alpha Pulse Amplitude [V],Alpha Pulse Amplitude [V] error -0,28.5,0.08625000000000001,0.028412344226686967,1.9860427971378117e-05 -1,29.0,0.0875,0.06073168018159535,2.7335974074566654e-05 -2,29.5,0.08875,0.09805666600547297,4.315826134305102e-05 -3,30.0,0.09,0.1386672136584177,6.0500966742210515e-05 -4,30.5,0.09125,0.18444492276906446,8.603591932252437e-05 -5,31.0,0.0925,0.2358196457834769,9.12182802317922e-05 -6,31.5,0.09375,0.29127555633566055,0.00012649168966878826 -7,32.0,0.095,0.35958902285681477,0.00015798416921748308 -8,32.5,0.09625,0.44031489637924126,0.00022224453125044204 -9,33.0,0.0975,0.5368570359995293,0.00022959236498652145 -10,33.5,0.09875,0.6555926052204287,0.0002875845382901261 -11,34.0,0.1,0.8008286842660374,0.0004586666300871812 -12,34.5,0.10125,0.9915055501769517,0.00041668149740232394 -13,35.0,0.10250000000000001,1.2416717650370146,0.0006382695037441121 -14,35.5,0.10375,1.5666550131213186,0.0010666504264439788 -15,36.0,0.105,2.0667966268420526,0.0014912986838936473 -16,36.5,0.10625,2.7949539724186656,0.0026414316988991483 diff --git a/ProcessWaveforms_MultiGaussian.py b/ProcessWaveforms_MultiGaussian.py index 1478e5c..b967b40 100644 --- a/ProcessWaveforms_MultiGaussian.py +++ b/ProcessWaveforms_MultiGaussian.py @@ -329,20 +329,22 @@ def fit_peaks_multigauss( model = model + LinearModel(prefix= 'l_') g_center = centers[:(peak_range[1]-peak_range[0]+1)] print('CENTER GUESSES TO BE USED IN FIT: ',g_center) - #constraints for center g_center_index = 0 for peak in range(low_peak, high_peak + 1): if peak == low_peak: model.set_param_hint('g' + str(peak) + '_center', value = g_center[g_center_index], min = range_low, max = baseline_width + g_center[g_center_index]) + # model.set_param_hint('g' + str(peak) + '_center', value = g_center[g_center_index], min = range_low, max = g_center[g_center_index + 1]) g_center_index += 1 elif peak == high_peak: g_center_last = len(g_center) - 1 #last index of g_center model.set_param_hint('g' + str(peak) + '_center', value = g_center[g_center_last], min = g_center[g_center_last] - baseline_width, max = range_high) + # model.set_param_hint('g' + str(peak) + '_center', value = g_center[g_center_last], min = g_center[g_center_last - 1], max = range_high) else: model.set_param_hint('g' + str(peak) + '_center', value = g_center[ g_center_index], min = g_center[g_center_index] - baseline_width, max = baseline_width + g_center[g_center_index]) + # model.set_param_hint('g' + str(peak) + '_center', value = g_center[ g_center_index], min = g_center[g_center_index - 1], max = g_center[g_center_index + 1]) g_center_index += 1 - # print('max ', baseline_width + g_center[g_center_index]) + #constraints for sigma for peak in range(low_peak, high_peak + 1): model.set_param_hint('g' + str(peak) + '_sigma', value = 0.5 * baseline_width, min = 0, max = baseline_width) @@ -360,7 +362,7 @@ def fit_peaks_multigauss( params = model.make_params() # params.pretty_print() res = model.fit(counts, params=params, x=bin_centers, weights = 1/np.sqrt(counts), nan_policy='omit') - # print(res.fit_report()) + print(res.fit_report()) return res @@ -388,11 +390,11 @@ def fit_alpha_gauss( f_range["center"] = centers[np.argmax(counts)] std_guess = np.std(values) mean_guess = centers[np.argmax(counts)] - f_range["low"] = mean_guess - 0.25 * std_guess + print('center guess: ' + str(mean_guess) + ' with '+str(max(counts)) + ' counts') + f_range["low"] = mean_guess - 0.5 * std_guess f_range["high"] = mean_guess + 0.5 * std_guess # print(f_range['center'], f_range['low'], f_range['high']) curr_peak_data = values[(values >= f_range["low"]) & (values <= f_range["high"])] - # high_val = 3.5 # low_val = 2.4 # center_val = (high_val - low_val) / 2.0 @@ -412,9 +414,10 @@ def fit_alpha_gauss( mean_guess = res.params["center"].value std_guess = res.params["sigma"].value - f_range["low"] = mean_guess - 2.0 * std_guess - f_range["high"] = mean_guess + 3.0 * std_guess + f_range["low"] = mean_guess - 2 * std_guess + f_range["high"] = mean_guess + 3 * std_guess curr_peak_data = values[(values >= f_range["low"]) & (values <= f_range["high"])] + print('fitting alpha peak in range ['+str(f_range['low']) + ', ' + str(f_range['high']) + ']' ) curr_hist = np.histogram(curr_peak_data, bins=binnum) counts = curr_hist[0] bins = curr_hist[1] @@ -437,6 +440,7 @@ def plot_fit( binnum: int = 20, plot_hists: bool = True, label: str | None = None, + color: str = "red" ) -> None: """ Plots the histogram of the data and the Gaussian fit. @@ -459,7 +463,7 @@ def plot_fit( plt.plot( x, fit_info["fit"].eval(params=fit_info["fit"].params, x=x), - color="red", + color=color, label=label, ) @@ -600,7 +604,7 @@ def process(self, overwrite=False, do_spe=True, do_alpha=False, subtraction_meth self.baseline_mean = self.baseline_mode self.baseline_std = 0.002 # arbitrary print("baseline mode: " + str(self.baseline_mode)) - print("dummy standard deviation: " + str(self.baseline_std)) + print("baseline std: " + str(self.baseline_std)) else: self.baseline_fit = fit_baseline_gauss( self.baseline_values, binnum=self.info.baseline_numbins, alpha=do_alpha @@ -622,9 +626,9 @@ def process(self, overwrite=False, do_spe=True, do_alpha=False, subtraction_meth ) self.peak_locs = [self.peak_fit.params['g' + str(idx + 1) + '_center'].value for idx in range(self.low_peak-1, self.high_peak)] - #pprint.pprint('peak locations from fit: '+ str(self.peak_locs)) + print('peak locations from fit: '+ str(self.peak_locs)) self.peak_sigmas = [self.peak_fit.params['g' + str(idx + 1) + '_sigma'].value for idx in range(self.low_peak-1, self.high_peak)] - #pprint.pprint('peak sigmas (widths) from fit: '+ str(self.peak_sigmas)) + print('peak sigmas (widths) from fit: '+ str(self.peak_sigmas)) self.peak_stds = [self.peak_fit.params['g' + str(idx + 1) + '_center'].stderr for idx in range(self.low_peak-1, self.high_peak)] self.peak_sigmas_stds = [self.peak_fit.params['g' + str(idx + 1) + '_sigma'].stderr for idx in range(self.low_peak-1, self.high_peak)] @@ -632,14 +636,17 @@ def process(self, overwrite=False, do_spe=True, do_alpha=False, subtraction_meth for s in self.peak_sigmas: if s < self.baseline_std: print('WARNING! Fitted sigma ' + str(s) + ' is less than baseline sigma ' + str(self.baseline_std) +'!') - + + print(self.peak_stds) for i in range(len(self.peak_stds)): - if type(self.peak_stds[i]) == None: + if type(self.peak_stds[i]) == None or self.peak_stds[i] is None: + print('standard error (center): ' + str(self.peak_stds[i])) print('WARNING! Fit failed to return a standard error on the peak locations and returned None! Setting std = 1') self.peak_stds[i] = 1.0 - if type(self.peak_sigmas_stds[i]) == None: + if type(self.peak_sigmas_stds[i]) == None or self.peak_sigmas_stds[i] is None: + print('standard error (sigma): ' + str(self.peak_sigmas_stds[i])) print('WARNING! Fit failed to return a standard error on the peak sigmas and returned None! Setting std = 1') - self.peak_sigmas_stds[i] = 1 + self.peak_sigmas_stds[i] = 1.0 self.peak_wgts = [1.0 / curr_std for curr_std in self.peak_stds] @@ -650,6 +657,7 @@ def process(self, overwrite=False, do_spe=True, do_alpha=False, subtraction_meth / np.sqrt(self.peak_sigmas[i] ** 2 + self.peak_sigmas[i + 1] ** 2) for i in range(len(self.peak_locs) - 1) ] + print("sigma SNR: " + str(self.resolution)) for idx in range(self.low_peak-1, self.high_peak): @@ -723,7 +731,20 @@ def process(self, overwrite=False, do_spe=True, do_alpha=False, subtraction_meth self.peak_values, binnum=self.info.peaks_numbins ) self.alpha_res = self.alpha_fit["fit"] + self.sigma_value = self.alpha_res.params['sigma'].value + self.sigma_err = self.sigma = self.alpha_res.params['sigma'].stderr + + def get_N(self): + return len(self.peak_values) + + def get_mean_val(self): + return np.mean(self.peak_values) + def get_alpha_sigma(self): + return self.sigma_value + + def get_alpha_sigma_err(self): + return self.sigma_err def get_alpha_data(self): """Retrieves the alpha pulse peak heights. @@ -966,6 +987,7 @@ def plot_baseline_histogram( binnum=self.info.baseline_numbins, plot_hists=False, label="Solicited Baseline Fit", + color = "green" ) # plt.legend(loc = 'center left') plt.xlabel("Waveform Amplitude [V]") @@ -1026,26 +1048,35 @@ def plot_peak_histograms( textstr += f'Peak Locations ($\mu$) [V]\n' for peak in range(0,len(self.peak_sigmas)): actual_peak = self.peak_range[0] + peak - # actual_peak = peak + 1 - if type(self.peak_fit.params['g' + str(actual_peak) + '_center'].stderr) != None: + print('creating plot legend...') + if self.peak_fit.params['g' + str(actual_peak) + '_center'].stderr is None: + continue + else: textstr += f'''Peak {actual_peak}: {self.peak_fit.params['g' + str(actual_peak) + '_center'].value:0.2} $\pm$ {self.peak_fit.params['g' + str(actual_peak) + '_center'].stderr:0.2}\n''' textstr += f'--\n' textstr += 'Peak Width (\u03C3) [V]\n' for peak in range(0,len(self.peak_sigmas)): actual_peak = self.peak_range[0] + peak curr_sigma_err = self.peak_fit.params['g' + str(actual_peak) + '_sigma'].stderr - if type(curr_sigma_err)==float: + if curr_sigma_err is None: + continue + else: textstr += f'''{peak + 1}: {round(self.peak_sigmas[peak],5)} $\pm$ {curr_sigma_err:0.2}\n''' textstr += f'--\n' textstr += f'''Reduced $\chi^2$: {self.peak_fit.redchi:0.2}\n''' + textstr += r'$\frac{\mu_{i+1}-\mu_{i}}{\sqrt{\sigma_{i+1}+\sigma_{i}}}$ = ' + textstr +=f' 1-2: {self.resolution[0]:0.2}; 2-3: {self.resolution[1]:0.2}' + if len(self.resolution)>2: + textstr +=f';\n 3-4: {self.resolution[2]:0.2}' curr_hist = np.histogram(self.peak_values, bins = self.numbins) # curr_hist = np.histogram(self.peak_values, bins = self.numbins) counts = curr_hist[0] bins = curr_hist[1] centers = (bins[1:] + bins[:-1])/2 y_line_fit = self.peak_fit.eval(x=centers) - + # y_line_fit = self.peak_fit.eval(x=np.linspace(self.cutoff[0], self.cutoff[1], 200)) plt.plot(centers, y_line_fit,'r-', label='best fit') + #plt.plot(np.linspace(self.cutoff[0], self.cutoff[1], 200), y_line_fit,'r-', label='best fit') plt.plot(centers, self.peak_fit.best_values['l_intercept'] + self.peak_fit.best_values['l_slope']*centers, 'b-', label='best fit - line') plt.grid(True) props = dict(boxstyle='round', facecolor='tab:' + peakcolor, alpha=0.4) @@ -1065,7 +1096,8 @@ def plot_peak_histograms( plt.close(fig) - def plot_alpha_histogram(self, with_fit: bool = True, log_scale: bool = False, peakcolor: str = "purple")-> None: + def plot_alpha_histogram(self, with_fit: bool = True, log_scale: bool = False, peakcolor: str = "purple", savefig: bool = False, + path: Optional[str] = None)-> None: """Plots a histogram of alpha values with or without fitting. This method creates a histogram of alpha values (self.peak_values), calculated as the number of peaks (self.info.peaks_numbins) over the range of alpha fit (self.alpha_fit["high"] - self.alpha_fit["low"]). @@ -1094,7 +1126,7 @@ def plot_alpha_histogram(self, with_fit: bool = True, log_scale: bool = False, p self.alpha_fit, self.peak_values, binnum=self.info.peaks_numbins, - plot_hists=False, + plot_hists=False ) # plt.legend(loc = 'center left') plt.xlabel("Waveform Amplitude [V]") @@ -1118,17 +1150,21 @@ def plot_alpha_histogram(self, with_fit: bool = True, log_scale: bool = False, p ) plt.grid(True) plt.show() + + if savefig: + plt.savefig(path) def plot_both_histograms( self, log_scale: bool = True, density: bool = False, - # alphas: bool = False, + alphas: bool = False, baselinecolor: str = "orange", peakcolor: str = "blue", savefig: bool = False, path: Optional[str] = None, with_fit: bool = False, + with_baseline_fit: bool = False, ): """Plots histograms for both baseline and peak values. @@ -1141,6 +1177,7 @@ def plot_both_histograms( Args: log_scale (bool, optional): If True, sets the y-axis to a logarithmic scale. Defaults to True. density (bool, optional): If True, normalizes the histogram to form a probability density. Defaults to False. + alphas (bool, optional): If True, includes alpha peaks in the histogram. Defaults to False. baselinecolor (str, optional): The color of the baseline histogram bars. Defaults to "orange". peakcolor (str, optional): The color of the peak histogram bars. Defaults to "blue". savefig (bool, optional): If True, saves the plot to the file specified in 'path'. Defaults to False. @@ -1162,6 +1199,18 @@ def plot_both_histograms( color="tab:" + baselinecolor, ) + if with_baseline_fit: + baseline_fit = fit_baseline_gauss( + self.baseline_values, binnum=int(bin_density * (np.amax(self.baseline_values) - np.amin(self.baseline_values))), alpha=False) + plot_fit( + baseline_fit, + self.baseline_values, + binnum=self.info.baseline_numbins, + plot_hists=False, + label="Solicited Baseline Fit", + color = "green" + ) + total_num_bins = bin_density * (np.amax(self.all) - np.amin(self.all)) plt.hist( self.all, @@ -1177,12 +1226,17 @@ def plot_both_histograms( plt.ylabel("Frequency" if density else "Counts") plt.xlabel("Amplitude [V]") plt.grid(True) - plt.legend(loc = 'upper right') - textstr = f"Condition: {self.info.condition}\n" - textstr += f"Bias: {self.info.bias:0.4} [V]\n" - textstr += f"RTD4: {self.info.temperature} [K]" + + if not with_fit: + textstr = f"Condition: {self.info.condition}\n" + textstr += f"Bias: {self.info.bias:0.4} [V]\n" + textstr += f"RTD4: {self.info.temperature} [K]" + if with_baseline_fit: + textstr = f"""Baseline Mean: {baseline_fit['fit'].params['center'].value:0.4} +- {baseline_fit['fit'].params['center'].stderr:0.1} [V]\n""" + textstr += f"""Baseline Sigma: {baseline_fit['fit'].params['sigma'].value:0.4} +- {baseline_fit['fit'].params['sigma'].stderr:0.1} [V]\n""" + textstr += f"""Reduced $\chi^2$: {baseline_fit['fit'].redchi:0.4}""" props = dict(boxstyle="round", facecolor="tab:" + peakcolor, alpha=0.4) - fig.text(0.6, 0.33, textstr, fontsize=10, verticalalignment="top", bbox=props) + fig.text(0.2, 0.26, textstr, fontsize=9, verticalalignment="top", bbox=props) plt.tight_layout() if with_fit: @@ -1193,6 +1247,9 @@ def plot_both_histograms( plt.plot(centers, y_line_fit,'r-', label='best fit') plt.plot(centers, self.peak_fit.best_values['l_intercept'] + self.peak_fit.best_values['l_slope']*centers, 'b-', label='best fit - line') textstr = f"Date: {self.info.date}\n" + textstr += f"Condition: {self.info.condition}\n" + textstr += f"Bias: {self.info.bias:0.4} [V]\n" + textstr += f"RTD4: {self.info.temperature} [K]\n" textstr += f'Peak Locations ($\mu$) [V]\n' for peak in range(0,len(self.peak_sigmas)): actual_peak = self.peak_range[0] + peak #ensures the plot displays the actual number of p.e. if first peak was skipped @@ -1207,9 +1264,9 @@ def plot_both_histograms( textstr += f'''Reduced $\chi^2$: {self.peak_fit.redchi:0.2}\n''' props = dict(boxstyle='round', facecolor="tab:" + peakcolor, alpha=0.4) - fig.text(0.6, 0.83, textstr, fontsize=9, + fig.text(0.61, 0.7, textstr, fontsize=9, verticalalignment='top', bbox=props) - + plt.legend(loc = 'upper right') plt.grid(True) if savefig: @@ -1284,7 +1341,7 @@ def get_subtract_hist_mean(self, data1, data2, numbins = 2000, plot = False): counts2, bins2 = np.histogram(data2, bins = bins1, density = False) centers = (bins1[1:] + bins1[:-1])/2 subtracted_counts = counts1 - counts2 - + subtracted_counts[subtracted_counts < -0.2*max(subtracted_counts)] = 0 if plot: plt.step(centers, subtracted_counts, label = 'subtracted hist') plt.legend() diff --git a/RunAnalyzePhotons.py b/RunAnalyzePhotons.py new file mode 100644 index 0000000..975b102 --- /dev/null +++ b/RunAnalyzePhotons.py @@ -0,0 +1,263 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Mar 2 23:28:33 2024 + +@author: Hannah +""" +from AnalyzePhotons import CorrelatedAvalancheProbability +from AnalyzePhotons import AlphaData +from AnalyzePhotons import AnalyzePhotons +from AnalyzePhotons import AlphaRatio +from AnalyzePhotons import SPEData +from MeasurementInfo import MeasurementInfo +import matplotlib.pyplot as plt +import numpy as np +plt.style.use('C:/Users/Hannah/Documents/GitHub/SPE-Analysis/nexo_new.mplstyle') +#%% Correlated avalanche options + +CA_July13 = CorrelatedAvalancheProbability('C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/July13_171K_LXe_CA.csv') +CA_July13_GN = CorrelatedAvalancheProbability('C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/July13_171K_CA_GN.csv') +CA_Sep24 = CorrelatedAvalancheProbability('C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/Sept24th_405nm_CA_values.csv') +CA_Sep20 = CorrelatedAvalancheProbability('C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/Sept20th_405nm_CA_values.csv' + ,ov_key = ('Overvoltage [V]', 'Bias Voltage [V] error')) +CA_Nov9 = CorrelatedAvalancheProbability('C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/Nov9_169K_CA_ov_NoSource.csv') +#%% March 2023, No reflector +invC_alpha = 0.001142 +invC_alpha_err = 2.1E-6 +# invC_spe_filter = 0.1288 +invC_spe_filter = 0.1288 +invC_spe_err_filter = 0.0064 +spe_no_teflon = SPEData( + path = 'C:/Users/Hannah/Documents/Raw Results/Breakdown Voltage/2023March31_v_bd_filter.csv', + invC_spe = (invC_spe_filter,invC_spe_err_filter), + return_ov = False, # work in terms of OV or not + bias_key=("Bias Voltage [V]", "Bias Voltage [V] error"), + spe_key=('SPE Amplitude [V]','SPE Amplitude [V] error'), + shaper = '1 $\mu$s', + filtering = '400 kHz', + color = "red") +alpha_no_teflon = AlphaData(spe = spe_no_teflon, path = 'C:/Users/Hannah/Documents/Raw Results/Alpha Amplitudes/March2023_Alpha_1us.csv', + invC_alpha = (invC_alpha,invC_alpha_err), + bias_key = ("Bias Voltage [V]","Bias Voltage [V] error"), + reflector = "None", + color = 'cyan', + use_fit_result_only=True + ) +info = MeasurementInfo() +info.condition = 'LXe' +info.date = 'March 31 2023' +info.temperature = 170 +no_reflector = AnalyzePhotons(info, "No reflector", alpha_no_teflon, CA_Sep20, max_OV = 7, use_fit_results_only = True) +no_reflector.plot_num_det_photons(label=True) + +#%% May 18 2023, Teflon +invC_alpha = 0.001142 +invC_alpha_err = 2.1E-6 +invC_spe_filter = 0.011959447603692185 +invC_spe_err_filter = 3.881945391072933E-05 +spe_teflonI = SPEData( + path = 'C:/Users/Hannah/Documents/Raw Results/Breakdown Voltage/May_170K_vbd_bias_20240318.csv', + invC_spe = (invC_spe_filter,invC_spe_err_filter), + return_ov = False, # work in terms of OV or not + bias_key=("Bias Voltage [V]", "Bias Voltage [V] error"), + spe_key=('SPE Amplitude [V]','SPE Amplitude [V] error'), + shaper = '100 ns', + filtering = '400 kHz') +alpha_teflonI = AlphaData( + spe=spe_teflonI, + path = 'C:/Users/Hannah/Documents/Raw Results/Alpha Amplitudes/May2023_Alpha_1us.csv', + invC_alpha = (invC_alpha,invC_alpha_err), + reflector = 'Teflon', + color = "blue", + use_fit_result_only=True + ) +info = MeasurementInfo() +info.condition = 'LXe' +info.date = 'May 18th 2023' +info.temperature = 170 +teflonI = AnalyzePhotons(info, "Teflon", alpha_teflonI, CA_Sep20, max_OV = 7, use_fit_results_only = True) +teflonI.plot_num_det_photons(label=False,color = 'blue') + +#%% +CA_Sep20.fit_CA(max_OV=7, color = 'xkcd:green', show_label=True) +teflonI.plot_CA(color = 'purple') +#%% +ratio_tef = AlphaRatio(alpha_teflonI, alpha_no_teflon) +ratio_tef.plot_alpha() +ratio_tef.plot_alpha_ratio(ov_from_avg = True, color = 'tab:blue') +#%% August 10 2023, No silicon +invC_alpha = 0.001142 +invC_alpha_err = 2.1E-6 +invC_spe_filter = 0.01171 +invC_spe_err_filter = 0.000048 +spe_si_none = SPEData( + path = 'C:/Users/Hannah/Documents/Raw Results/Breakdown Voltage/vbd_bias_no_silicon.csv', + invC_spe = (invC_spe_filter,invC_spe_err_filter), + return_ov = False, # work in terms of OV or not + bias_key=("Bias Voltage [V]", "Bias Voltage [V] error"), + spe_key=('SPE Amplitude [V]','SPE Amplitude [V] error'), + shaper = '1 $\mu$s', + filtering = '400 kHz') +alpha_si_none = AlphaData( + spe = spe_si_none, + path = 'C:/Users/Hannah/Documents/Raw Results/Alpha Amplitudes/2023August10_Alpha.csv', + invC_alpha = (invC_alpha,invC_alpha_err), + bias_key = ('Bias Voltage [V]', 'Bias Voltage [V] error'), + color = 'olive', + use_fit_result_only=True + ) +info = MeasurementInfo() +info.condition = 'LXe' +info.date = 'May 18th 2023' +info.temperature = 170 +# si_none = AnalyzePhotons(info, "None / July 13 GN CA", alpha, CA_July13) +# si_none = AnalyzePhotons(info, "None / Nov 9 LXe Dark CA", alpha, CA_Nov9) +# si_none = AnalyzePhotons(info, "None / Sep 24 GN CA", alpha, CA_Sep24) +si_none = AnalyzePhotons(info, "None / Sep 20 CA (Vacuum)", alpha_si_none, CA_Sep20, max_OV = 7, use_fit_results_only = True) +si_none.plot_num_det_photons(label=False) + +#%% August 1 2023, silicon +invC_alpha = 0.001142 +invC_alpha_err = 2.1E-6 +invC_spe_filter = 0.01171 +invC_spe_err_filter = 0.000048 +spe_si = SPEData( + path = 'C:/Users/Hannah/Documents/Raw Results/Breakdown Voltage/August1_silicon_vbd.csv', + invC_spe = (invC_spe_filter,invC_spe_err_filter), + return_ov = False, # work in terms of OV or not + bias_key=("Bias Voltage [V]", "Bias Voltage [V] error"), + spe_key=('SPE Amplitude [V]','SPE Amplitude [V] error'), + shaper = '1 $\mu$s', + filtering = '400 kHz') +alpha_si = AlphaData( + spe = spe_si, + path = 'C:/Users/Hannah/Documents/Raw Results/Alpha Amplitudes/2023August01_Alpha.csv', + invC_alpha = (invC_alpha,invC_alpha_err), + bias_key = ('Bias Voltage [V]', 'Bias Voltage [V] error'), + reflector = "Silicon", + color = 'green', + use_fit_result_only= True + ) +info = MeasurementInfo() +info.condition = 'LXe' +info.date = 'August 1st 2023' +info.temperature = 170 +si = AnalyzePhotons(info, "Silicon / Sep 20 CA (Vacuum)", alpha_si, CA_Sep20, max_OV = 7, use_fit_results_only = True) +si.plot_num_det_photons(label=False) +#%% +ratio_si = AlphaRatio(alpha_si, alpha_si_none) +ratio_si.plot_alpha_ratio(ov_from_avg = True, color = 'xkcd:brown') +ratio_si.plot_alpha() +#%% +alpha_si.plot_alpha(unit = 'PE') +alpha_si_none.plot_alpha(unit = 'PE') +#%% +CA_Sep20.fit_CA(max_OV=7, color = 'magenta', show_label=True) +si.plot_CA(color = 'green') + +#%% June 28, copper +invC_alpha = 0.001142 +invC_alpha_err = 2.1E-6 +invC_spe_filter = 0.01171 +invC_spe_err_filter = 0.000048 +spe_copper = SPEData( + path = 'C:/Users/Hannah/Documents/Raw Results/Breakdown Voltage/LXe_June_28_2023_vbd_bias.csv', + invC_spe = (invC_spe_filter,invC_spe_err_filter), + return_ov = False, # work in terms of OV or not + bias_key=("Bias Voltage [V]", "Bias Voltage [V] error"), + spe_key=('SPE Amplitude [V]','SPE Amplitude [V] error'), + shaper = '1 $\mu$s', + filtering = '400 kHz') +alpha_copper = AlphaData( + spe = spe_copper, + path = 'C:/Users/Hannah/Documents/Raw Results/Alpha Amplitudes/2023June28_Alpha.csv', + invC_alpha = (invC_alpha,invC_alpha_err), + invC_spe = (invC_spe_filter,invC_spe_err_filter), + bias_key = ('Bias Voltage [V]', 'Bias Voltage [V] error'), + # mean_subtract= 'C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/June2023_means_subtraction_method_2.csv', + use_fit_result_only = False, + reflector = "Copper", + color = "brown" + ) +info = MeasurementInfo() +info.condition = 'LXe' +info.date = 'June 28th 2023' +info.temperature = 170 +# alpha_copper.get_CA_from_means(out_file = 'C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/June28_CA_from_subtraction_method.csv') +#%% +CA = CorrelatedAvalancheProbability('C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/June28_CA_from_subtraction_method.csv') +# CA = CA_July13_GN +copper = AnalyzePhotons(info, "Copper", alpha_copper, CA, max_OV = 7) +# copper.plot_num_det_photons(label=False) +CA.fit_CA(plot = True, color = 'brown', max_OV = 7, show_label = True) +# copper.CA.fit_CA(plot = True, color = 'pink') +copper.plot_CA(color = 'brown') +#%% July 13, no copper +invC_alpha = 0.001142 +invC_alpha_err = 2.1E-6 +invC_spe_filter = 0.01171 +invC_spe_err_filter = 0.000048 +alpha_no_copper = AlphaData(path = 'C:/Users/Hannah/Documents/Raw Results/Alpha Amplitudes/2023July_Alpha.csv', + path_spe = 'C:/Users/Hannah/Documents/Raw Results/Breakdown Voltage/July13_171K_LED_SPE.csv', + invC_alpha = (invC_alpha,invC_alpha_err), + invC_spe = (invC_spe_filter,invC_spe_err_filter), + bias_key = ('Bias Voltage [V]', 'Bias Voltage [V] error'), + spe_bias_key = ('Bias Voltage [V]', 'Bias Voltage [V] error'), + # mean_subtract= 'C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/July13_means_subtraction_method_3.csv', + use_fit_result_only = False, + reflector = "None", + color = "orange" + ) +info = MeasurementInfo() +info.condition = 'LXe' +info.date = 'July 13th 2023' +info.temperature = 170 +# alpha.get_CA_from_means(out_file = 'C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/July13_CA_from_subtraction_method.csv') +#%% +CA_copper_none = CorrelatedAvalancheProbability('C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/July13_CA_from_subtraction_method.csv') +copper_none = AnalyzePhotons(info, "None", alpha_no_copper, CA_copper_none, max_OV = 7) +copper_none.plot_num_det_photons(label=False) +# CA_copper_none.fit_CA(plot = True) +# copper_none.CA.fit_CA(plot = True, max_OV = 7, color = 'orange', show_label=True) +# copper_none.plot_CA() +#%% +ratio_copper = AlphaRatio(alpha_copper, alpha_no_copper) +ratio_copper.plot_alpha() +ratio_copper.plot_alpha_ratio(ov_from_avg = True, color = 'xkcd:red') + +#%% June 8 2023, teflon, flipped source +invC_alpha = 0.001142 +invC_alpha_err = 2.1E-6 +invC_spe_filter = 0.01171 +invC_spe_err_filter = 0.000048 +spe_teflonII = SPEData( + path = 'C:/Users/Hannah/Documents/Raw Results/Breakdown Voltage/LXe_June8_2023_vbd_bias.csv', + invC_spe = (invC_spe_filter,invC_spe_err_filter), + return_ov = False, # work in terms of OV or not + bias_key=("Bias Voltage [V]", "Bias Voltage [V] error"), + spe_key=('SPE Amplitude [V]','SPE Amplitude [V] error'), + shaper = '1 $\mu$s', + filtering = '400 kHz', + color = "red") +alpha_teflonII = AlphaData( + spe = spe_teflonII, + path = 'C:/Users/Hannah/Documents/Raw Results/Alpha Amplitudes/2023June8_Alphas.csv', + invC_alpha = (invC_alpha,invC_alpha_err), + bias_key = ('Bias Voltage [V]', 'Bias Voltage [V] error'), + reflector = "Teflon", + color = "blue" + ) +info = MeasurementInfo() +info.condition = 'LXe' +info.date = 'June 8th 2023' +info.temperature = 170 +CA_teflonII = CorrelatedAvalancheProbability('C:/Users/Hannah/Documents/Raw Results/Correlated Avalanche Data/LXe_June_2023_CA_ov.csv') +teflonII = AnalyzePhotons(info, "Teflon", alpha_teflonII, CA_teflonII, max_OV =7) +teflonII.plot_num_det_photons(label=False,color='blue') +#%% +ratio_teflonII = AlphaRatio(alpha_teflonII, alpha_no_copper) +ratio_teflonII.plot_alpha() +ratio_teflonII.plot_alpha_ratio(ov_from_avg = True, color = 'xkcd:green') +#%% +CA_teflonII.fit_CA(max_OV=7, show_label=False, color = 'blue') +CA_copper_none.fit_CA(max_OV=7, show_label=False, color = 'orange') \ No newline at end of file diff --git a/RunInfo.py b/RunInfo.py index c5cef5d..f2dddcb 100644 --- a/RunInfo.py +++ b/RunInfo.py @@ -108,11 +108,17 @@ def __init__( baseline_correct: bool = False, poly_correct: bool = False, prominence: float = 0.005, + distance: float = None, + width: float = None, + wlen: float = 100, + threshold: float = None, specifyAcquisition: bool = False, fourier: bool = False, is_led: bool = False, condition: str = "unspecified medium (GN/LXe/Vacuum)", - num_waveforms: float = 0 + num_waveforms: float = 0, + do_peak_find: bool = True, + poly_correct_degree: int = 2 ): # TODO: # combine acquisition and specify_acquisition inputs @@ -165,9 +171,15 @@ def __init__( self.specifyAcquisition = specifyAcquisition self.fourier = fourier self.prominence = prominence + self.distance = distance + self.width = width + self.wlen = wlen + self.threshold = threshold self.baseline_levels = [] # list of mode of waveforms self.num_waveforms = num_waveforms self.condition = condition + self.do_peak_find = do_peak_find + self.poly_correct_degree = poly_correct_degree if self.led: # initialize led on/off lists self.all_dark_peak_data = [] @@ -247,12 +259,12 @@ def __init__( '''searches for peaks using provided parameters''' self.peak_search_params = { "height": 0.0, # SPE - "threshold": None, # SPE - "distance": None, # SPE + "threshold": threshold, # SPE + "distance": distance, # SPE "prominence": prominence, #specified by user - "width": None, # SPE - "wlen": 100, # SPE - "rel_height": None, # SPE + "width": width, # SPE + "wlen": wlen, # SPE + "rel_height": 1, # SPE "plateau_size": None, # SPE } self.get_peak_data() @@ -423,8 +435,8 @@ def get_peaks(self, filename: str, acquisition_name: str) -> list[float]: self.baseline_levels.append(baseline_mode_raw) if self.baseline_correct: if self.poly_correct: - print('using polynomial baseline correction...') - baseline_level = peakutils.baseline(amp, deg=2) + #print('using polynomial baseline correction...') + baseline_level = peakutils.baseline(amp, deg=self.poly_correct_degree) amp = amp - baseline_level @@ -434,12 +446,21 @@ def get_peaks(self, filename: str, acquisition_name: str) -> list[float]: # self.baseline_mode = baseline_level # print('baseline:', baseline_level) amp = amp - baseline_level + self.baseline_mode = baseline_level if self.do_filter and np.shape(amp) != (0,): sos = signal.butter(3, 4E5, btype = 'lowpass', fs = fs, output = 'sos') # SPE dark/10g filtered = signal.sosfilt(sos, amp) - amp = filtered - peaks, props = signal.find_peaks(amp, **self.peak_search_params) + amp = filtered + + if self.do_peak_find: + peaks, props = signal.find_peaks(amp, **self.peak_search_params) + if self.plot_waveforms and self.num_waveforms < 200: + if len(props["peak_heights"]) > 0: + print('PEAK PROPERTIES:') + pprint.pprint(props) + else: + all_peaks += list(amp) if self.plot_waveforms: plt.title(acquisition_name) plt.tight_layout() @@ -449,14 +470,23 @@ def get_peaks(self, filename: str, acquisition_name: str) -> list[float]: plt.plot(time[peaks], amp[peaks], '.') if self.led: led_time_thresh = (time[-1] + time[1]) / 2.0 - for peak in peaks: - all_peaks.append(amp[peak]) - if self.led: - curr_time = time[peak] - if curr_time < led_time_thresh: - dark_peaks.append(amp[peak]) - else: - led_peaks.append(amp[peak]) + + if self.do_peak_find: + for peak in peaks: + all_peaks.append(amp[peak]) + if self.led: + curr_time = time[peak] + if curr_time < led_time_thresh: + dark_peaks.append(amp[peak]) + else: + led_peaks.append(amp[peak]) + if self.do_peak_find == False and self.led: + for i in range(len(time)): + curr_time = time[i] + if curr_time < led_time_thresh: + dark_peaks.append(amp[i]) + else: + led_peaks.append(amp[i]) if self.led: print(f'LED off: {np.mean(dark_peaks)} $+-$ {np.std(dark_peaks,ddof=1)/np.sqrt(len(dark_peaks))}') print(f'LED on: {np.mean(led_peaks)} $+-$ {np.std(led_peaks,ddof=1)/np.sqrt(len(led_peaks))}') diff --git a/nexo_new.mplstyle b/nexo_new.mplstyle new file mode 100644 index 0000000..b12aaa6 --- /dev/null +++ b/nexo_new.mplstyle @@ -0,0 +1,20 @@ +axes.titlesize : 10 +axes.labelsize : 10 +lines.linewidth : 1.5 +lines.markersize : 10 +xtick.labelsize : 10 +ytick.labelsize : 10 +figure.dpi : 200 +figure.facecolor: white +savefig.dpi : 600 +savefig.bbox : tight +savefig.pad_inches : 0.02 +legend.fontsize : 10 +legend.loc : upper left +errorbar.capsize : 2 +axes.autolimit_mode : round_numbers +axes.xmargin : 0 +axes.ymargin : 0 +axes.prop_cycle : cycler('color', ['1f78b4', 'e66101', '33a02c', '984ea3', 'F27781', '18298C', '04BF8A', 'F2CF1D', 'F29F05', '7155D9', '8D07F6', '9E91F2', 'F29B9B', 'F25764', '6FB7BF', 'B6ECF2', '5D1314', 'B3640F']) +font.family : serif +text.usetex: False \ No newline at end of file