def get_ext_pulser_data(): """ Adapted from ext2.py::getEff Just gets data and save into a npz file. """ from ROOT import TChain, GATDataSet import glob # this is the output extData = {} # {run: [pIdx, runTime, extChan, hitE, fSlo]} for pIdx in [19, 20, 21]: # for pIdx in [19]: extPulserInfo = cal.GetSpecialList()["extPulserInfo"] attList = extPulserInfo[pIdx][0] # unused extChan = extPulserInfo[pIdx][-1] syncChan = wl.getChan(0, 10, 0) # 672 runList = cal.GetSpecialRuns("extPulser", pIdx) for run in runList: # elogs: "20 Hz, 150 second runs" gds = GATDataSet(run) runTime = gds.GetRunTime() # sec # pulseRate = 20 # Hz fList = glob.glob(dsi.specialDir + "/lat/latSkimDS0_run%d_*.root" % run) tt = TChain("skimTree") for f in fList: tt.Add(f) tCut = "(channel==%d || channel==%d) && mH==2" % ( syncChan, extChan) # enforce correct sync n = tt.Draw("trapENFCal:channel:fitSlo", tCut, "goff") hitE, chan, fSlo = tt.GetV1(), tt.GetV2(), tt.GetV3() hitE = np.asarray( [hitE[i] for i in range(n) if chan[i] == extChan]) fSlo = np.asarray( [fSlo[i] for i in range(n) if chan[i] == extChan]) if len(hitE) == 0: continue extData[run] = [pIdx, runTime, extChan, hitE, fSlo] tt.Reset()
def getSloParams(): from ROOT import TChain, GATDataSet extPulserInfo = calInfo.GetSpecialList()["extPulserInfo"] syncChan = wl.getChan(0, 10, 0) # 672 # for pIdx in [19,20,21]: pIdx = 20 runList = calInfo.GetSpecialRuns("extPulser", pIdx) attList = extPulserInfo[pIdx][0] extChan = extPulserInfo[pIdx][-1] sloVals = {} for i, run in enumerate(runList): # elogs: "20 Hz, 150 second runs" gds = GATDataSet(run) runTime = gds.GetRunTime() / 1e9 # sec pulseRate = 20 # Hz fileList = ds.getLATRunList([run], "%s/lat" % (ds.specialDir)) latChain = TChain("skimTree") for f in fileList: latChain.Add("%s/lat/%s" % (ds.specialDir, f)) theCut = "(channel==%d || channel==%d) && mH==2" % (syncChan, extChan) tNames = [ "Entry$", "mH", "channel", "trapENFCal", "fitSlo", "den90", "den10", "kvorrT", "wfStd" ] tvals = wl.GetVX(latChain, tNames, theCut) n = len(tvals["Entry$"]) if n == 0: continue hitE = [ tvals["trapENFCal"][i] for i in range(n) if tvals["channel"][i] == extChan ] fSlo = [ tvals["fitSlo"][i] for i in range(n) if tvals["channel"][i] == extChan ] kvTE = [ tvals["kvorrT"][i] / tvals["trapENFCal"][i] for i in range(n) if tvals["channel"][i] == extChan ] rt90 = [ tvals["den90"][i] - tvals["den10"][i] for i in range(n) if tvals["channel"][i] == extChan ] wStd = [ tvals["wfStd"][i] for i in range(n) if tvals["channel"][i] == extChan ] trigEff = 100 * len(hitE) / (runTime * pulseRate) print("%d %.2f %.2f" % (run, trigEff, np.mean(hitE))) sloVals[run] = [trigEff, hitE, fSlo, kvTE, rt90, wStd] np.savez("../plots/ext2-compare.npz", sloVals)
def getEff(): """ Efficiency vs. energy, each detector in Test 3""" from ROOT import TChain, GATDataSet f = plt.figure() plt.cla() extPulserInfo = calInfo.GetSpecialList()["extPulserInfo"] syncChan = wl.getChan(0, 10, 0) # 672 dsNum, modNum, calIdx = 0, 1, 33 calDB = db.TinyDB('../calDB.json') pars = db.Query() fsD = ds.getDBRecord( "fitSlo_ds%d_idx%d_m%d_Peak" % (dsNum, calIdx, modNum), False, calDB, pars) bkgIdx = 75 # runs 6887-6963 thD = ds.getDBRecord("thresh_ds%d_bkgidx%d" % (dsNum, bkgIdx), False, calDB, pars) for pIdx in [19, 20, 21]: # for pIdx in [19]: runList = calInfo.GetSpecialRuns("extPulser", pIdx) attList = extPulserInfo[pIdx][0] extChan = extPulserInfo[pIdx][-1] fsCut = fsD[extChan][2] # 90% value (used in LAT3) effVals, threshVals, trigVals = [], [], [] eneVals, sloVals, rtVals = [], [], [] for i, run in enumerate(runList): if run in [7225, 7233]: continue # elogs: "20 Hz, 150 second runs" gds = GATDataSet(run) runTime = gds.GetRunTime() # sec pulseRate = 20 # Hz fileList = ds.getLATRunList([run], "%s/lat" % (ds.specialDir)) latChain = TChain("skimTree") for f in fileList: latChain.Add("%s/lat/%s" % (ds.specialDir, f)) tNames = [ "Entry$", "mH", "channel", "trapENFCal", "fitSlo", "den90", "den10", "threshKeV", "threshSigma" ] theCut = "(channel==%d || channel==%d) && mH==2" % ( syncChan, extChan) # enforce correct sync tVals = wl.GetVX(latChain, tNames, theCut) nPass = len(tVals["Entry$"]) enfArr = [ tVals["trapENFCal"][i] for i in range(nPass) if tVals["channel"][i] == extChan ] sloArr = [ tVals["fitSlo"][i] for i in range(nPass) if tVals["channel"][i] == extChan ] rtArr = [ tVals["den90"][i] - tVals["den10"][i] for i in range(nPass) if tVals["channel"][i] == extChan ] if len(enfArr) == 0: print("Run %d, No hits in channel %d found. Continuing ..." % (run, extChan)) continue eneVals.extend(enfArr) sloVals.extend(sloArr) rtVals.extend(rtArr) thr = [ tVals["threshKeV"][i] for i in range(nPass) if tVals["channel"][i] == extChan ][0] sig = [ tVals["threshSigma"][i] for i in range(nPass) if tVals["channel"][i] == extChan ][0] if thr < 99999 and sig < 99999: threshVals.append((thr, sig)) muE, stdE = np.mean(np.asarray(enfArr)), np.std(np.asarray(enfArr)) muF, stdF = np.mean(np.asarray(sloArr)), np.std(np.asarray(sloArr)) nTot = len(sloArr) nAcc = len([fs for fs in sloArr if fs < fsCut]) eff = (nAcc / nTot) effVals.append((muE, eff)) nHits = len(enfArr) expHits = runTime * pulseRate trigEff = nHits / expHits trigVals.append((muE, trigEff)) print( "pIdx %d run %d chan %d nHits %d (exp %d) muE %.2f muFS %.2f eff %.2f trigEff %.2f" % (pIdx, run, extChan, nHits, expHits, muE, muF, eff, trigEff)) eneVals, sloVals, rtVals = np.asarray(eneVals), np.asarray( sloVals), np.asarray(rtVals) fig = plt.figure(figsize=(8, 8), facecolor='w') p1 = plt.subplot(211) p2 = plt.subplot(212) xLo, xHi, bpX = 0, 50, 0.2 yLo, yHi, bpY = 0, 300, 1. nbX, nbY = int((xHi - xLo) / bpX), int((yHi - yLo) / bpY) _, _, _, im = p1.hist2d(eneVals, sloVals, bins=[nbX, nbY], range=[[xLo, xHi], [yLo, yHi]], norm=LogNorm(), cmap='jet') fig.colorbar(im, ax=p1) p1.axhline(fsCut, color='black', linewidth=3) p1.set_title("pIdx %d channel %d fsCut %.2f" % (pIdx, extChan, fsCut)) p1.set_xlabel("trapENFCal (keV)", horizontalalignment='right', x=1.0) p1.set_ylabel("fitSlo", horizontalalignment='right', y=1.0) xvals = np.asarray( [val[0] for val in sorted(effVals) if 1. < val[0] < 10.]) yvals = np.asarray( [val[1] for val in sorted(effVals) if 1. < val[0] < 10.]) p2.plot(xvals, yvals, "o", c='b', markersize=5, label='data') popt1kev, _ = curve_fit(threshFunc, xvals, yvals) xnew = np.arange(0, max(xvals), 0.1) p2.plot(xnew, threshFunc(xnew, *popt1kev), 'r-', label="fit mu=%.2f\nfit sig=%.2f" % tuple(popt1kev)) p2.set_title("fitSlo efficiency vs. trapENFCal") p2.set_xlabel("trapENFCal (keV)", horizontalalignment='right', x=1.0) p2.set_ylabel("fitSlo Efficiency (%)", horizontalalignment='right', y=1.0) p2.legend(loc='best') plt.tight_layout() plt.savefig("../plots/efficiency_idx%d.pdf" % pIdx) # plot 3 - show how the trigger efficiency is hurting us # compare run by run avg, db vals, and measured trig. efficiency fig2 = plt.figure(figsize=(9, 7), facecolor='w') xvals = np.asarray([val[0] for val in sorted(effVals) if val[0] < 10]) yvals = np.asarray([val[1] for val in sorted(effVals) if val[0] < 10]) plt.plot(xvals, yvals, "o", c='b', markersize=10, label='data') plt.plot(xnew, threshFunc(xnew, *popt1kev), 'b-', label="efficiency > 1 keV\nmu=%.2f sig=%.2f" % tuple(popt1kev)) # threshMu = np.mean(np.asarray([val[0] for val in threshVals])) # threshSig = np.mean(np.asarray([val[1] for val in threshVals])) threshMu = thD[extChan][0] threshSig = thD[extChan][1] ytrigDB = threshFunc(xnew, threshMu, threshSig) plt.plot(xnew, ytrigDB, '-', color='gray', label="DB trigger efficiency\nmu %.2f sig %.2f" % (threshMu, threshSig)) trigVals = np.asarray( [val[1] for val in sorted(trigVals) if val[0] < 10]) print("trigVals:", trigVals) plt.plot(xvals, trigVals, marker='o', linestyle='-', color='black', label="Meas. trigger efficiency") ycorr = [] for idx in range(len(xvals)): corr = threshFunc(xvals[idx], threshMu, threshSig) print("kev %.2f eff %.2f corr %.2f corrected eff %.2f" % (xvals[idx], yvals[idx], corr, yvals[idx] / corr)) ycorr.append(yvals[idx] / corr) ycorr = np.asarray(ycorr) plt.plot(xvals, ycorr, "o", c='r', markersize=7, label='trigger eff. corrected') poptPt7kev, _ = curve_fit(threshFunc, xvals, ycorr) plt.plot(xnew, threshFunc(xnew, *poptPt7kev), 'r-', label="efficiency fit to corrected\nmu %.2f sig %.2f" % tuple(poptPt7kev)) plt.title("fitSlo efficiency vs. trapENFCal") plt.xlabel("trapENFCal (keV)", horizontalalignment='right', x=1.0) plt.ylabel("fitSlo Efficiency (%)", horizontalalignment='right', y=1.0) plt.legend(loc='best') plt.savefig("../plots/efficiency_idx%d_corr.pdf" % pIdx)
def getEff(): """ Efficiency vs. energy, each detector in Test 3""" from ROOT import TChain, GATDataSet f = plt.figure() plt.cla() extPulserInfo = calInfo.GetSpecialList()["extPulserInfo"] syncChan = wl.getChan(0, 10, 0) # 672 dsNum, modNum, calIdx = 0, 1, 33 calDB = db.TinyDB('../calDB.json') pars = db.Query() fsD = ds.getDBRecord( "fitSlo_ds%d_idx%d_m%d_Peak" % (dsNum, calIdx, modNum), False, calDB, pars) bkgIdx = 75 # runs 6887-6963 thD = ds.getDBRecord("thresh_ds%d_bkgidx%d" % (dsNum, bkgIdx), False, calDB, pars) for pIdx in [19, 20, 21]: # for pIdx in [19]: runList = calInfo.GetSpecialRuns("extPulser", pIdx) attList = extPulserInfo[pIdx][0] extChan = extPulserInfo[pIdx][-1] fsCut = fsD[extChan][2] # 90% value (used in LAT3) effVals, threshVals, trigVals = [], [], [] eneVals, sloVals, rtVals = [], [], [] for i, run in enumerate(runList): if run in [7225, 7233]: continue # elogs: "20 Hz, 150 second runs" gds = GATDataSet(run) runTime = gds.GetRunTime() # sec pulseRate = 20 # Hz fileList = ds.getLATRunList([run], "%s/lat" % (ds.specialDir)) latChain = TChain("skimTree") for f in fileList: latChain.Add("%s/lat/%s" % (ds.specialDir, f)) tNames = [ "Entry$", "mH", "channel", "trapENFCal", "fitSlo", "den90", "den10", "threshKeV", "threshSigma" ] theCut = "(channel==%d || channel==%d) && mH==2" % ( syncChan, extChan) # enforce correct sync tVals = wl.GetVX(latChain, tNames, theCut) nPass = len(tVals["Entry$"]) enfArr = [ tVals["trapENFCal"][i] for i in range(nPass) if tVals["channel"][i] == extChan ] sloArr = [ tVals["fitSlo"][i] for i in range(nPass) if tVals["channel"][i] == extChan ] rtArr = [ tVals["den90"][i] - tVals["den10"][i] for i in range(nPass) if tVals["channel"][i] == extChan ] if len(enfArr) == 0: print("Run %d, No hits in channel %d found. Continuing ..." % (run, extChan)) continue eneVals.extend(enfArr) sloVals.extend(sloArr) rtVals.extend(rtArr)
def runByRun(): """ Directly confirm settings of ext pulser scripts. """ import time from ROOT import TFile, TChain, GATDataSet, gROOT gROOT.ProcessLine( "gErrorIgnoreLevel = 3001;") # suppress ROOT error messages extPDict = { 7: 674, 8: 624, 9: 688, 10: 662, 11: 608, 12: 674, 14: 608, 15: 624, 16: 688, 17: 662, 18: 674, 19: 624, 20: 688, 21: 662, 22: 690 } syncChan = wl.getChan(0, 10, 0) # 672 syncRateNominal = 20 # Hz calInfo = ds.CalInfo() fig = plt.figure(figsize=(10, 6), facecolor='w') # pIdxs = [12,14,15,16,17] # test 2 - rise time # pIdxs = [18,19,20,21] # test 3 - attenuation pIdxs = [22] for pIdx in pIdxs: runList = calInfo.GetSpecialRuns("extPulser", pIdx) print("Range", pIdx) extChan = extPDict[pIdx] xArr, yArr = [], [] # we're gonna plot these # runList = [7234] for run in runList: # if run in [6936,6937,6940,6942,6944, 6974, 6977]: continue # test 2 # if run in [7224] or run > 7266: continue # test 3 fileList = [] subFiles = glob.glob("%s/lat/latSkimDS%d_run%d_*.root" % (ds.specialDir, ds.GetDSNum(run), run)) for idx in range(len(subFiles)): thisFile = "%s/lat/latSkimDS%d_run%d_%d.root" % ( ds.specialDir, ds.GetDSNum(run), run, idx) if not os.path.isfile(thisFile): print("File doesn't exist: ", thisFile) else: fileList.append(thisFile) latChain = TChain("skimTree") for f in fileList: latChain.Add(f) tNames = [ "Entry$", "run", "channel", "mH", "trapENFCal", "den90", "den10", "fitSlo", "localTime_s", "tOffset", "fitAmp" ] # theCut = "(channel==%d || channel==%d) && mH==2" % (syncChan,extChan) # theCut += " && Entry$ < 100" theCut = "Entry$ < 200 && gain==0" tVals = wl.GetVX(latChain, tNames, theCut) # don't delete this for idx in range(tVals["run"].size): ent = tVals["Entry$"][idx] run = tVals["run"][idx] chan = tVals["channel"][idx] mH = tVals["mH"][idx] enf = tVals["trapENFCal"][idx] d90 = tVals["den90"][idx] d10 = tVals["den10"][idx] fitSlo = tVals["fitSlo"][idx] gt = tVals["localTime_s"][idx] tOff = tVals["tOffset"][idx] * 1e-9 hitTime = gt + tOff print("%d e%d m%d t%.8f c%-4d %-9.2f %-8.2f %.2f" % (run, ent, mH, hitTime, chan, enf, d90 - d10, fitSlo)) continue # make sure we only have hits from syncChan and extChan # for entry in set(tVals["Entry$"]): # idxs = [idx for idx in range(len(tVals["Entry$"])) if tVals["Entry$"][idx]==entry] # chans = [tVals["channel"][idx] for idx in idxs] # if not set([extChan,syncChan]).issubset(set(chans)): # print("NOPE:",chans) gds = GATDataSet(int(run)) runTime = gds.GetRunTime() / 1e9 if len(tVals["Entry$"]) == 0: print("Run %d, %.2f sec. Found no cts." % (run, runTime)) continue syncRate = len(set(tVals["Entry$"])) / runTime expectedCts = runTime * syncRateNominal extPCts = len([ch for ch in tVals["channel"] if ch == extChan]) syncCts = len([ch for ch in tVals["channel"] if ch == syncChan]) extPRate = extPCts / runTime syncRate = syncCts / runTime syncAmp = [ tVals["fitAmp"][i] for i in range(len(tVals["fitAmp"])) if tVals["channel"][i] == syncChan ] syncAmp = np.asarray(syncAmp) muS, sigS = 0, 0 if len(syncAmp) > 0: muS, sigS = np.mean(syncAmp), np.std(syncAmp) extENF = [ tVals["trapENFCal"][i] for i in range(len(tVals["trapENFCal"])) if tVals["channel"][i] == extChan ] extENF = np.asarray(extENF) muE, sigE = 0, 0 if len(extENF) > 0: muE, sigE = np.mean(extENF), np.std(extENF) print( "Run %d, %.2f sec. #Expect %d #Sync %d (%.2f Hz) #extP %d (%.2f Hz) muE %.2f sigE %.2f muS %.2f sigS %.2f" % (run, runTime, expectedCts, syncCts, syncRate, extPCts, extPRate, muE, sigE, muS, sigS)) # fill the plot arrays xArr.extend([ tVals["trapENFCal"][i] for i in range(len(tVals["trapENFCal"])) if tVals["channel"][i] == extChan ]) yArr.extend([ tVals["fitSlo"][i] for i in range(len(tVals["fitSlo"])) if tVals["channel"][i] == extChan ]) return # make a plot for this range fig.clear() xLo, xHi, yLo, yHi = 0, 10, -20, 300 # test 3 # xLo, xHi, yLo, yHi = 50, 100, -20, 200 # test 2 bpY, bpX = 2, 0.1 nBinsY, nBinsX = int((yHi - yLo) / bpY), int((xHi - xLo) / bpX) try: plt.hist2d(xArr, yArr, bins=[nBinsX, nBinsY], range=[[xLo, xHi], [yLo, yHi]], norm=LogNorm()) plt.colorbar() plt.xlabel("trapENFCal (keV)", horizontalalignment='right', x=1.0) plt.ylabel("fitSlo", horizontalalignment='right', y=1.0) plt.title("Range %d, Channel %d" % (pIdx, extChan)) plt.tight_layout() plt.savefig("../plots/extPulser_idx%d.pdf" % pIdx) except ValueError: pass