def s1_means_and_vars(dst): hr = divide_np_arrays(dst.S1h.values, dst.S1e.values) return S1D( E=Measurement( *weighted_mean_and_std(dst.S1e.values, np.ones(len(dst)))), W=Measurement(*weighted_mean_and_std(dst.S1w, np.ones(len(dst)))), H=Measurement(*weighted_mean_and_std(dst.S1h, np.ones(len(dst)))), R=Measurement(*weighted_mean_and_std(hr, np.ones(len(dst)))), T=Measurement(*weighted_mean_and_std(dst.S1t, np.ones(len(dst)))))
def plot_stat(x, y, loc='upper right'): """ Input x and y from a binned histogram Return mu and sigma statistics and add to the plot """ mean, std = weighted_mean_and_std(x, y, frequentist=True, unbiased=True) entries = f'Entries = {sum(y):.0f}' mean = f'$\mu$ = {mean:7.2f}' sigma = f'$\sigma$ = {std:7.2f}' stat = f'{entries}\n{mean}\n{sigma}' plt.legend([stat], loc=loc)
def s2_means_and_vars(dst): return S2D( E=Measurement( *weighted_mean_and_std(dst.S2e.values, np.ones(len(dst)))), W=Measurement(*weighted_mean_and_std(dst.S2w, np.ones(len(dst)))), Q=Measurement(*weighted_mean_and_std(dst.S2q, np.ones(len(dst)))), N=Measurement(*weighted_mean_and_std(dst.Nsipm, np.ones(len(dst)))), X=Measurement(*weighted_mean_and_std(dst.X, np.ones(len(dst)))), Y=Measurement(*weighted_mean_and_std(dst.Y, np.ones(len(dst)))))
def h1n(n, nx, ny, names, h1ds, bins, ranges, xlabels, ylabels, titles=None, legends=None, figsize=(10, 10)): fig = plt.figure(figsize=figsize) stats = {} for i in range(n): ax = fig.add_subplot(nx, ny, i + 1) x = h1ds[i] r = ranges[i] x1 = loc_elem_1d(x, find_nearest(x, r[0])) x2 = loc_elem_1d(x, find_nearest(x, r[1])) xmin = min(x1, x2) xmax = max(x1, x2) x2 = x[xmin:xmax] o = np.ones(len(x2)) mu, std = weighted_mean_and_std(x2, o) stats[names[i]] = Measurement(mu, std) ax.set_xlabel(xlabels[i], fontsize=11) ax.set_ylabel(ylabels[i], fontsize=11) ax.hist(x, bins=bins[i], range=r, histtype='step', edgecolor='black', linewidth=1.5, label=r'$\mu={:7.2f},\ \sigma={:7.2f}$'.format(mu, std)) ax.legend(fontsize=10, loc=legends[i]) plt.grid(True) if titles: plt.title(titles[i]) plt.tight_layout() return stats
def h1d(x, bins=None, range=None, weights=None, xlabel='Variable', ylabel='Frequency', title=None, legend='upper right', figsize=(6, 6)): fig = plt.figure(figsize=figsize) ax = fig.add_subplot(1, 1, 1) x1 = loc_elem_1d(x, find_nearest(x, range[0])) x2 = loc_elem_1d(x, find_nearest(x, range[1])) xmin = min(x1, x2) xmax = max(x1, x2) mu, std = weighted_mean_and_std(x[xmin:xmax], np.ones(len(x[xmin:xmax]))) ax.set_xlabel(xlabel, fontsize=11) ax.set_ylabel(ylabel, fontsize=11) ax.hist(x, bins=bins, range=range, weights=weights, histtype='step', edgecolor='black', linewidth=1.5, label=r'$\mu={:7.2f},\ \sigma={:7.2f}$'.format(mu, std)) ax.legend(fontsize=10, loc=legend) plt.grid(True) if title: plt.title(title) return mu, std
def plot_pdfs(): file_name = sys.argv[1] if '.h5' in file_name: print('Single file mode') all_files = [file_name] runs = [file_name[-7:-3]] else: all_files = sorted(glob(file_name + '*.h5'), key=file_sorter) runs = [fn[-7:-3] for fn in all_files] pdf_type = 'adc' if len(sys.argv) > 2: pdf_type = sys.argv[2] sipmIn = [tb.open_file(fn) for fn in all_files] #with tb.open_file(file_name, 'r') as sipmIn: bins = np.array(sipmIn[0].get_node('/HIST/', pdf_type + '_bins')) pdfs = [ np.array(siIn.get_node('/HIST/', pdf_type)).sum(axis=0) for siIn in sipmIn ] if 'Sensors' in sipmIn[0].root: atcaNos = np.fromiter( (x['channel'] for x in sipmIn[0].root.Sensors.DataSiPM), np.int) chNos = np.fromiter( (x['sensorID'] for x in sipmIn[0].root.Sensors.DataSiPM), np.int) if np.all(chNos == -1): dats = DB.DataSiPM(5166) chns = dats.ChannelID chNos = np.fromiter( (dats.loc[chns == x, 'SensorID'] for x in atcaNos), np.int) else: ## print('No sensor info in file, assuming DB ordering for run 5166') ## atcaNos = DB.DataSiPM(5166).ChannelID.values ## chNos = DB.DataSiPM(5166).SensorID.values print('No sensor info in file, hardwired') dices = [14, 15, 17, 21] atcaNos = np.fromiter((d * 1000 + i for d in dices for i in range(64)), np.int) chNos = atcaNos means = [] rmss = [] peak1 = [] grads = [] cable = [] n_cable = [1, 2, 3, 4, 5, 6, 7] for ich, pdf in enumerate(zip(*pdfs)): if chNos[ich] < 21000: continue #plt.cla() #plt.ion() #plt.show() for j, pf in enumerate(pdf): mean, rms = weighted_mean_and_std(bins, pf, True) means.append(mean) rmss.append(rms) cable.append(n_cable[j]) peaks = find_peaks(pf, 100, distance=15) try: peak1.append(bins[peaks[0][1]]) except IndexError: ## Fake to save hassle peak1.append(-1) #plt.bar(bins, pf, width=1, log=True, label='Run '+runs[j]) grads.append( (peak1[-1] - peak1[-len(pdf)]) / (cable[-1] - cable[-len(pdf)])) #plt.title('Zero suppressed PDF for sensor '+str(chNos[ich])+', atca '+str(atcaNos[ich])) #plt.xlabel('ADC') #plt.ylabel('AU') #plt.legend() #plt.draw() #plt.pause(0.001) #plt.show() #status = input('next?') #if 'q' in status: # exit() plt.scatter(cable, means) plt.title('Scatter of distribution mean with number of cables') plt.xlabel('Number of cables') plt.ylabel('PDF mean') plt.show() plt.scatter(cable, rmss) plt.title('Scatter of distribution rms with number of cables') plt.xlabel('Number of cables') plt.ylabel('PDF rms') plt.show() plt.scatter(cable, peak1) plt.xlabel('Number of cables') plt.ylabel('Approximate 1 pe peak position') plt.show() plt.hist(grads) plt.title('histogram of 1 pe peak pos / no. cables gradient') plt.xlabel('gradient') plt.ylabel('AU') plt.show()
def plot_histogram(histogram, ax=None, plot_errors=False, draw_color='black', stats=True, normed=True): """Plot a Histogram. Parameters ---------- ax : axes object, optional If None, a new axes will be created. plot_errors : bool, optional If True, plot the associated errors instead of data. draw_color : string, optional Sets the linecolor. stats : bool, optional If True, histogram statistics info is added to the plotself. normed : bool, optional If True, histogram is normalized. """ if ax is None: fig, ax = plt.subplots(1, 1, figsize=(8, 6)) bins = histogram.bins out_range = histogram.out_range labels = histogram.labels title = histogram.title scale = histogram.scale if plot_errors: entries = histogram.errors else: entries = histogram.data if len(bins) == 1: ax.hist(shift_to_bin_centers(bins[0]), bins[0], weights=entries, histtype='step', edgecolor=draw_color, linewidth=1.5, density=normed) ax.grid(True) ax.set_axisbelow(True) ax.set_ylabel("Entries", weight='bold', fontsize=20) ax.set_yscale(scale[0]) if stats: entries_string = f'Entries = {np.sum(entries):.0f}\n' out_range_string = 'Out range (%) = [{0:.2f}, {1:.2f}]'.format( get_percentage(out_range[0, 0], np.sum(entries)), get_percentage(out_range[1, 0], np.sum(entries))) if np.sum(entries) > 0: mean, std = weighted_mean_and_std(shift_to_bin_centers( bins[0]), entries, frequentist=True, unbiased=True) else: mean, std = 0, 0 ax.annotate(entries_string + 'Mean = {0:.2f}\n'.format(mean) + 'RMS = {0:.2f}\n'.format(std) + out_range_string, xy=(0.99, 0.99), xycoords='axes fraction', fontsize=11, weight='bold', color='black', horizontalalignment='right', verticalalignment='top') elif len(bins) == 2: ax.pcolormesh(bins[0], bins[1], entries.T) ax.set_ylabel(labels[1], weight='bold', fontsize=20) if stats: entries_string = f'Entries = {np.sum(entries):.0f}\n' out_range_stringX = 'Out range X (%) = [{0:.2f}, {1:.2f}]'.format( get_percentage(out_range[0, 0], np.sum(entries)), get_percentage(out_range[1, 0], np.sum(entries))) out_range_stringY = 'Out range Y (%) = [{0:.2f}, {1:.2f}]'.format( get_percentage(out_range[0, 1], np.sum(entries)), get_percentage(out_range[1, 1], np.sum(entries))) if np.sum(entries) > 0: meanX, stdX = weighted_mean_and_std(shift_to_bin_centers( bins[0]), np.sum(entries, axis=1), frequentist=True, unbiased=True) meanY, stdY = weighted_mean_and_std(shift_to_bin_centers( bins[1]), np.sum(entries, axis=0), frequentist=True, unbiased=True) else: meanX, stdX = 0, 0 meanY, stdY = 0, 0 ax.annotate(entries_string + 'Mean X = {0:.2f}\n'.format(meanX) + 'Mean Y = {0:.2f}\n'.format(meanY) + 'RMS X = {0:.2f}\n'.format(stdX) + 'RMS Y = {0:.2f}\n'.format(stdY) + out_range_stringX + '\n' + out_range_stringY, xy=(0.99, 0.99), xycoords='axes fraction', fontsize=11, weight='bold', color='white', horizontalalignment='right', verticalalignment='top') elif len(bins) == 3: ave = np.apply_along_axis(average_empty, 2, entries, shift_to_bin_centers(bins[2])) ave = np.ma.masked_array(ave, ave < 0.00001) img = ax.pcolormesh(bins[0], bins[1], ave.T) cb = plt.colorbar(img, ax=ax) cb.set_label(labels[2], weight='bold', fontsize=20) for label in cb.ax.yaxis.get_ticklabels(): label.set_weight('bold') label.set_fontsize(16) ax.set_ylabel(labels[1], weight='bold', fontsize=20) ax.set_xlabel(labels[0], weight='bold', fontsize=20) ax.ticklabel_format(axis='x', style='sci', scilimits=(-3, 3)) for label in (ax.get_xticklabels() + ax.get_yticklabels()): label.set_fontweight('bold') label.set_fontsize(16) ax.xaxis.offsetText.set_fontsize(14) ax.xaxis.offsetText.set_fontweight('bold')
def ns2_stats(nsdf): mu, std = weighted_mean_and_std(nsdf.nS2, np.ones(len(nsdf.nS2))) hist, bins = np.histogram(nsdf.nS2, bins=5, range=(0, 5)) s1r = [bin_ratio(hist, bins, i) for i in range(0, 3)] s1r.append(bin_to_last_ratio(hist, bins, 3)) return mu, std, s1r
def sipm_connectivity_check(elec_name, dark_name, RUN_NO): """ Compare basic parameters of electronics only and dark current runs and have the user classify channels with little difference """ sensors = DB.DataSiPM(int(RUN_NO)).SensorID.values with tb.open_file(elec_name, 'r') as eFile, \ tb.open_file(dark_name, 'r') as dFile: min_incr = 0.5 if 'HIST' not in eFile.root: print('Error, this check requires spectra') exit() binsE = np.array(eFile.root.HIST.sipm_dark_bins) binsD = np.array(dFile.root.HIST.sipm_dark_bins) specsE = np.array(eFile.root.HIST.sipm_dark).sum(axis=0) specsD = np.array(dFile.root.HIST.sipm_dark).sum(axis=0) ## Bin half widths as x errors xerrE = 0.5 * np.diff(binsE)[0] xerrD = 0.5 * np.diff(binsD)[0] with open('dodgy_channels.txt', 'a') as dChan: dChan.write('Run \t Channel \t classification \n') for ich, (espec, dspec) in enumerate(zip(specsE, specsD)): ## Maybe should be replaced with ## database access. chan_no = sensors[ich] avE, rmsE = weighted_mean_and_std(binsE, espec, unbiased=True) avD, rmsD = weighted_mean_and_std(binsD, dspec, unbiased=True) mean_low = avE + min_incr >= avD rms_low = rmsE + min_incr >= rmsD #stats_diff = espec.sum() != dspec.sum() if mean_low or rms_low:# or stats_diff: print("Possible dodgy channel: "+str(chan_no)) print("identified as having: ") if mean_low: print('low mean: meanE='+str(avE)+', meanD='+str(avD)) if rms_low: print('low rms: rmsE='+str(rmsE)+', rmsD='+str(rmsD)) #if stats_diff: print('missing entries: sumE/sumD='+str(espec.sum()/dspec.sum())) plt.yscale('log') plt.errorbar(binsE, espec, xerr=xerrE, yerr=np.sqrt(espec), fmt='b.', label='Electronics only') plt.errorbar(binsD, dspec, xerr=xerrD, yerr=np.sqrt(dspec), fmt='r.', ecolor='r', label='Dark current') plt.title('Elec/dark current comparison ch'+str(chan_no)) plt.xlabel('ADC') plt.ylabel('AU') plt.legend() plt.show(block=False) clif = input("How do you classify this channel? [dead/noisy/suspect/ok]") dChan.write(RUN_NO+' \t '+str(chan_no)+' \t '+clif+' \n'); plt.clf() plt.close() check_chan = input("Want to check specific channels? [y/n]") if check_chan == 'y': check_chan = input("Which channel number? [num/stop]") while check_chan != 'stop': indx = np.argwhere(sensors==int(check_chan)) if len(indx) == 0: print('Channel not found') continue indx = indx[0][0] plt.yscale('log') plt.errorbar(binsE, specsE[indx], xerr=xerrE, yerr=np.sqrt(specsE[indx]), fmt='b.', label='Electronics only') plt.errorbar(binsD, specsD[indx], xerr=xerrD, yerr=np.sqrt(specsD[indx]), fmt='r.', ecolor='r', label='Dark current') plt.title('Elec/dark current comparison ch'+str(check_chan)) plt.xlabel('ADC') plt.ylabel('AU') plt.legend() plt.show(block=False) clif = input("How do you classify this channel? [dead/noisy/suspect/ok]") dChan.write(RUN_NO+' \t '+str(check_chan)+' \t '+clif+' \n'); plt.clf() plt.close() check_chan = input("Another channel? [num/stop]") return
def main(): """ Plot some pdfs """ old_pdfs = sys.argv[1] new_pdfs = sys.argv[2] db1 = DB.DataSiPM(6499) db2 = DB.DataSiPM(6562) active = (db1.Active & db2.Active) == 1 changed = (db1.SensorID >= 5000) & (db1.SensorID < 8064) sensor_x = db1.X.values sensor_y = db1.Y.values with tb.open_file(new_pdfs) as newfile, tb.open_file(old_pdfs) as oldfile: ## obins = np.array(oldfile.root.HIST.sipm_mode_bins) ## ospecs = np.array(oldfile.root.HIST.sipm_mode).sum(0) ## nbins = np.array(newfile.root.HIST.sipm_mode_bins) ## nspecs = np.array(newfile.root.HIST.sipm_mode).sum(0) obins = np.array(oldfile.root.HIST.sipm_adc_bins) ospecs = np.array(oldfile.root.HIST.sipm_adc).sum(0) nbins = np.array(newfile.root.HIST.sipm_adc_bins) nspecs = np.array(newfile.root.HIST.sipm_adc).sum(0) omerms = [weighted_mean_and_std(obins, spec, True) for spec in ospecs] nmerms = [weighted_mean_and_std(nbins, spec, True) for spec in nspecs] norm_old = np.apply_along_axis(normalize_distribution, 1, ospecs) thr_old = general_thresholds(obins, norm_old, 0.99) norm_new = np.apply_along_axis(normalize_distribution, 1, nspecs) thr_new = general_thresholds(nbins, norm_new, 0.99) fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(20, 6)) ptitles = [ 'MEAN new', 'MEAN old', 'Mean new - Mean old', 'RMS new', 'RMS old', 'RMS new - RMS old', 'Thr new', 'Thr old', 'Thr new - Thr old' ] vals = [ np.fromiter((v[0] for v in nmerms), np.float), np.fromiter((v[0] for v in omerms), np.float), np.zeros(2), np.fromiter((v[1] for v in nmerms), np.float), np.fromiter((v[1] for v in omerms), np.float), np.zeros(2), thr_new, thr_old, np.zeros(2) ] for i, (ax, val) in enumerate(zip(axes.flatten(), vals)): if not np.any(val): diff = vals[i - 2] - vals[i - 1] pinfo = ax.scatter(sensor_x[active & changed], sensor_y[active & changed], c=diff[active & changed], s=1.5) else: pinfo = ax.scatter(sensor_x[active & changed], sensor_y[active & changed], c=val[active & changed], s=1.5) ax.set_title(ptitles[i]) ax.set_xlabel('X (mm)') ax.set_ylabel('Y (mm)') plt.colorbar(pinfo, ax=ax) plt.tight_layout() fig.show() plt.show()
def elec_dark_comp(run_no, infiles): elec_file = infiles[0] dark_file = infiles[1] sensor_id = DB.DataSiPM(det_db, run_no).SensorID.values sensor_x = DB.DataSiPM(det_db, run_no).X.values sensor_y = DB.DataSiPM(det_db, run_no).Y.values chans = [ 19040, 19041, 19042, 19048, 19049, 19050, 19056, 19057, 19058, 17043, 17044, 17045, 17051, 17052, 17053, 17059, 17060, 17061 ] mu_vals = [] chi_vals = [] dark_mean = [] elec_mean = [] with tb.open_file(elec_file) as efile, tb.open_file(dark_file) as dfile: bins = np.array(dfile.root.HIST.sipm_dark_bins) specsD = np.array(dfile.root.HIST.sipm_spe).sum(axis=0) specsE = np.array(efile.root.HIST.sipm_dark).sum(axis=0) for ich, (dar, ele) in enumerate(zip(specsD, specsE)): valid_bins = np.argwhere(dar >= 10) b1 = valid_bins[0][0] b2 = np.argwhere(bins <= 0)[-1][0] dscale = dar[b1:b2].sum() / ele[b1:b2].sum() pfit = leastsq(scale_chi, dscale, args=(ele[b1:b2], dar[b1:b2])) chi2 = np.sum(scale_chi(pfit[0], ele[b1:b2], dar[b1:b2])** 2) / (b2 - b1 - 1) #if sensor_id[ich] in chans: ## if pfit[0] < 0: ## print('Interesting channel ', sensor_id[ich]) ## print('Poisson mu = ', pfit[0][0], ' chi2 = ', chi2) ## plt.errorbar(bins, dar, ## xerr=0.5*np.diff(bins)[0], ## yerr=np.sqrt(dar), fmt='b.') ## plt.errorbar(bins, ele, ## xerr=0.5*np.diff(bins)[0], ## yerr=np.sqrt(ele), fmt='g.') ## plt.plot(bins, np.exp(-pfit[0]) * ele, 'r') ## plt.title('Scale fit to channel '+str(sensor_id[ich])) ## plt.xlabel('ADC') ## plt.ylabel('AU') ## plt.show() mu_vals.append(pfit[0][0]) chi_vals.append(chi2) dmean, _ = weighted_mean_and_std(bins, dar) if dmean > 70.: dark_mean.append(2) elec_mean.append(0) continue dark_mean.append(dmean) emean, _ = weighted_mean_and_std(bins, ele) elec_mean.append(emean) a_dark_mean = np.array(dark_mean) a_elec_mean = np.array(elec_mean) plt.scatter(sensor_x, sensor_y, c=dark_mean) plt.title("Mean dark spectrum") plt.xlabel("X (mm)") plt.ylabel("Y (mm)") plt.colorbar() plt.show() plt.scatter(sensor_x, sensor_y, c=elec_mean) plt.title("Mean elec spectrum") plt.xlabel("X (mm)") plt.ylabel("Y (mm)") plt.colorbar() plt.show() plt.scatter(sensor_x, sensor_y, c=a_dark_mean - a_elec_mean) plt.title("Mean dark - elec spectrum") plt.xlabel("X (mm)") plt.ylabel("Y (mm)") plt.colorbar() plt.show() plt.scatter(sensor_x, sensor_y, c=chi_vals) plt.title("Chi^2 map for scale") plt.xlabel("X (mm)") plt.ylabel("Y (mm)") plt.colorbar() plt.show() plt.scatter(sensor_x, sensor_y, c=mu_vals) plt.title("Poisson mu map, average dark counts") plt.xlabel("X (mm)") plt.ylabel("Y (mm)") plt.colorbar() plt.show()