def save_data(self, txtfl=None): """ Saves all data for that run to a text file Input textfile for use with run.py UI """ if txtfl == None: txtfl = open(self.filedir + "//voltagedata.txt", 'w') printfl("txtfl opened, saving...") txtfl.write(str(self.dta)) txtfl.close() else: printfl("saving to txt...") txtfl.write("Raw data:\n") txtfl.write(str(self.dta) + "\n") txtfl.write("Data saved at: %s\n" % timing.log_return()) timing.log("data saved", timing.log_return())
def plot_heights(self, trigger, bins=None, savetxt=False, showimg=False, saveimg=False, txtfl=None): """Plots max height of pulses in a histogram""" if not self.listofpars: printfl("run fit() first") else: def powerfunc(t, tau, A_i, offset, c): return A_i * ((t - offset) / tau)**2 * math.e**(-(t - offset) / tau + (2 - math.log(4, math.e))) + c listofmax = [] count = 0 for num in self.listofpars: if not (2 * num[0] + num[2] < 0 and num[2] < 0): # Ensures that the found point is a max not a min max1 = powerfunc(2 * num[0] + num[2], *num) max2 = powerfunc(num[2], *num) if max1 > max2 and max1 > trigger and max1 < 2**13: listofmax.append(max1) count += 1 elif max2 > trigger and max2 < 2**13: listofmax.append(max2) count += 1 if showimg == True or saveimg == True: plt.hist([x * (3.3 / 2**13) * 1000 for x in listofmax], bins) plt.xlabel("Pulse Height (mV)") plt.ylabel("# of Pulses") plt.title("%s Pulses, %s Bins" % (count, bins)) if savetxt == True: if txtfl == None: txtfl = open(self.filedir + "//pulseheights.txt", 'w') printfl("opened txtfl") txtfl.write(str(listofmax)) txtfl.close() else: printfl("saving to txt...") txtfl.write("Max heights:\n") txtfl.write(str(listofmax) + "\n") txtfl.write("Heights saved at: %s\n" % timing.log_return()) if saveimg == True: plt.savefig(self.filedir + "//heighthist.png") if showimg == True: plt.show() if showimg == True or saveimg == True: plt.close() timing.log("histogram created", timing.log_return())
def fit(self, savepars=False, showimg=False, saveimg=False, txtfl=None): """ Fits all pulses to a curve and saves the resulting fit parameters if specified. Saves the plot. """ printfl("fitting data...") def powerfunc(t, tau, amplitude, offset, c): """The function being used for the fit, identical in all the fitting methods below""" return amplitude * ((t - offset) / tau)**2 * math.e**(-(t - offset) / tau + (2 - math.log(4, math.e))) + c count = 0 for i in range(len(self.listofdata)): x = np.linspace(0, len(self.listofdata[i]), len(self.listofdata[i])) try: pars, covariance_matrix = sciopt.curve_fit(powerfunc, x, self.listofdata[i], [1, 100, 0, 284]) self.listofpars.append(pars.tolist()) if showimg == True or saveimg == True: x = np.linspace(0, len(self.listofdata[i]), 100) plt.plot(x, [y * (3.3 / 2**13) * 1000 for y in powerfunc(x, *pars)]) #Sometimes curve_fit can't fit except (RuntimeError, TypeError): count += 1 if showimg == True or saveimg == True: plt.xlabel("microsec") plt.ylabel("mV") plt.title("%s Pulses" % (len(self.listofdata) - count)) if saveimg == True: plt.savefig(self.filedir + "//fits.png", dpi=500) if showimg == True: plt.show() if saveimg == True or showimg == True: plt.close() if savepars == True: if txtfl == None: txtfl = open(self.filedir + "//fitpars.txt", 'w') printfl("txtfl opened") txtfl.write(str(self.listofpars)) txtfl.close() else: printfl("saving to txt...") txtfl.write("Parameters:\n") txtfl.write(str(self.listofpars) + "\n") txtfl.write("Parameters saved at: %s\n" % timing.log_return()) timing.log("data fitted", timing.log_return())
def splice_data(self, trigger, save=False, txtfl=None): """ given a a trigger value, and expected rise/fall times, returns a list of pulses and saves it if specified input textfile for use with run.py """ printfl("splicing data...") i = 0 while i < len(self.dta) - 1: if self.dta[i] >= trigger and self.dta[i + 1] >= trigger: if i - self.rise < 0: a = 0 else: a = i - self.rise if i + self.tail > len(self.dta): b = len(self.dta) else: b = i + self.tail flag = False for j in range(len(self.dta[a:b])): if self.dta[a:b][j] == 0: flag = True if a == 0: i = j + 1 else: i += j + self.rise + 1 if flag == False: self.listofdata.append(self.dta[a:b]) i += self.tail else: i += 1 if save == True: if txtfl == None: txtfl = open(self.filedir + "//pulses.txt", 'w') printfl("txtfl opened") txtfl.write(str(self.listofdata)) txtfl.close() else: printfl("saving to txt...") txtfl.write("Pulses:\n") txtfl.write(str(self.listofdata) + "\n") txtfl.write("Pulses saved at: %s\n" % timing.log_return()) printfl("%s pulses detected" % len(self.listofdata)) timing.log("data spliced", timing.log_return())
def source(serialportname, chunkSize, nmax): """returns voltage data from the serial port, looping forever""" # Get handle to serial port s = serial.Serial(serialportname) print("collecting data...") curr = 0 while curr < nmax: data = s.read(chunkSize) data = np.fromstring(data, dtype=np.uint16) q.put(data) curr = curr + 1 timing.log("data collected", timing.log_return())
def plot(self): """Plots all pulses together on one graph, then saves it as plot.png""" printfl("plotting data...") for item in self.listofdata: plt.plot([x * (3.3 / 2**13) * 1000 for x in item]) plt.xlabel("microsec") plt.ylabel("mV") plt.title("%s Pulses (%s Rise, %s Tail)" % (len(self.listofdata), self.rise, self.tail)) plt.savefig(self.filedir + "//plot.png", dpi=500) plt.show() plt.close() timing.log("data plotted", timing.log_return())
def analyze_secondary(voltages, rise, tail, filedir): """Used to perform secondary analysis on already collected data""" printfl("initalizing object...") pltr = Plotter(voltages, rise, tail, filedir) timing.log("object initalized", timing.log_return()) trg = pltr.get_avg() + pltr.get_noise() * 4 printfl("Trigger value:" + str(trg * (3.3 / 2**13) * 1000)) pltr.splice_data(trg) # Add and remove methods below as needed per run pltr.fit() pltr.plot_heights(trg, 100, True, True)
def get_data_from_text(filedir): """returns voltage data from a previously saved text file""" printfl("txtfl open") txtfl = open(filedir, 'r') printfl("reading data...") voltages = txtfl.read().split() voltagelist = [] printfl("translating data...") for i in range(len(voltages)): temp = voltages[i].translate(None, '[],') if temp == "": pass else: voltagelist.append(float(temp)) timing.log("data read", timing.log_return()) return voltagelist
def get_data(serialportname, loops, chunkSize): """returns voltage data from the serial port""" # Get handle to serial port s = serial.Serial(serialportname) printfl("port init") voltages = [] printfl("collecting data...") for i in range(loops): printfl(i) data = s.read(chunkSize * 2) data = np.fromstring(data, dtype=np.uint16) np.set_printoptions(threshold='nan') voltages.append(0) voltages += data.tolist() timing.log("data collected", timing.log_return()) return voltages
def get_data_from_previous_run(filename): """function used to read in data from a previously written text file""" printfl("txtfl open") textfile = open(filename, 'r') printfl("reading data...") while textfile.readline().strip() != 'Raw Data:': pass voltages_str = textfile.readline().strip() voltages = voltages_str.split() voltagelist = [] printfl("translating data...") for voltage in voltages: translated = voltage.translate(None, '[],') if translated != "" and translated != " ": voltagelist.append(float(translated)) timing.log("data read", timing.log_return()) return voltagelist
def analyze_default(voltages, rise, tail, filedir): """Used to analyze new data from the Arduino""" printfl("initalizing object...") pltr = Plotter(voltages, rise, tail, filedir) timing.log("object initalized", timing.log_return()) pltr.save_data() printfl("calculating trigger...") trg = pltr.get_avg() + pltr.get_noise() * 4 printfl("Trigger value:" + str(trg * (3.3 / 2**13) * 1000)) pltr.splice_data(trg) # Add and remove methods below as needed per run pltr.plot() pltr.fit(True, True, True) pltr.plot_heights(trg, 100, True, True)
folder_dir += "//" + str(crystal_label) + "_" + month_str + "_" + date_str + "_" + year_str + "_" + hour_str\ + minute_str + "_" + second_str os.makedirs(folder_dir) txtfl = open(folder_dir + "//data.txt", 'w') txtfl.write("crystal: " + crystal_label + "\n") txtfl.write("loops: %s\n" % loops) printfl("initalizing object...") # If specified as default, replace with default values if rise == "default": rise = 1 if tail == "default": tail = 30 pltr = tester.Plotter(get_data(serialportname, loops, chunkSize), rise, tail, folder_dir) timing.log("object initalized") txtfl.write("object initalized at: %s\n" % timing.log_return()) # If requested, save raw data to text file if save_bool == "y": pltr.save_data(txtfl) # Uncomment this below if you want the raw data written to a separate text file # You might want this because for longer loops, raw data can take up a lot of space and make it difficult to # open the text file """ raw_data_txtfl = open(folder_dir + "//raw_data.txt", 'w') pltr.save_data(raw_data_txtfl) raw_data_txtfl.close() """ printfl("calculating trigger...") avg = pltr.get_avg(downsample)