def EventSelectionLosses(df, df_trig): print("TOTAL NUMBER OF EVENT TIME TANKS SET: " + str(len(set(df_trig['eventTimeTank'])))) print("TOTAL NUMBER OF EVENT TIME TANKS, LIST: " + str(len(df_trig['eventTimeTank']))) print("TOTAL NUMBER OF ENTRIES: " + str(len(df_trig))) df_cleanSiPM = es.SingleSiPMPulses(df_trig) print("TOTAL NUMBER OF EVENTS W/ ONE PULSE IN EACH SIPM: " + str(len(set(df_cleanSiPM['eventTimeTank'])))) df_SinglePulses = es.SingleSiPMPulses( df) #Clusters with a single SiPM pulse df_cleanSiPMDT = es.SingleSiPMPulsesDeltaT(df_trig, 200) print( "TOTAL NUMBER OF EVENTS W/ ONE PULSE IN EACH SIPM, PEAKS WITHIN 200 NS: " + str(len(set(df_cleanSiPMDT['eventTimeTank'])))) df_trig_cleanSiPM = df_trig.loc[(df_trig['SiPM1NPulses'] == 1) & ( df_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) df_cleanPrompt = es.NoPromptClusters(df_SinglePulses, 2000) df_trig_cleanPrompt = es.NoPromptClusters_WholeFile( df_SinglePulses, df_trig_cleanSiPM, 2000) print( "TOTAL NUMBER OF EVENTS W/ ONE PULSE IN EACH SIPM AND NO PROMPT CLUSTER: " + str(len(set(df_trig_cleanPrompt['eventTimeTank'])))) #Late burst cut df_trig_cleanWindow = es.NoBurst_WholeFile(df_cleanPrompt, df_trig_cleanPrompt, 2000, 150) print( "TOTAL NUMBER OF EVENTS W/ CLEAN PROMPT AND NO BURST ABOVE 150 PE AND 2 MICROSECONDS: " + str(len(set(df_trig_cleanWindow['eventTimeTank']))))
mytrigbranches = [ 'eventNumber', 'eventTimeTank', 'eventTimeMRD', 'vetoHit' ] myMRDbranches = [ 'eventNumber', 'eventTimeTank', 'eventTimeMRD', 'clusterTime', 'clusterHits', 'vetoHit', 'numClusterTracks', 'MRDTrackAngle', 'MRDPenetrationDepth', 'MRDEntryPointRadius', 'MRDEnergyLoss', 'MRDEnergyLossError', 'MRDTrackLength' ] PositionDict = {} for j, direc in enumerate(SIGNAL_DIRS): direcfiles = glob.glob(direc + "*.ntuple.root") livetime_estimate = es.EstimateLivetime(direcfiles) print("SIGNAL LIVETIME ESTIMATE IN SECONDS IS: " + str(livetime_estimate)) PositionDict[SIGNAL_LABELS[j]] = [] PositionDict[SIGNAL_LABELS[j]].append( GetDataFrame("phaseIITankClusterTree", mybranches, direcfiles)) PositionDict[SIGNAL_LABELS[j]].append( GetDataFrame("phaseIITriggerTree", mytrigbranches, direcfiles)) PositionDict[SIGNAL_LABELS[j]].append( GetDataFrame("phaseIIMRDClusterTree", myMRDbranches, direcfiles)) Sdf = PositionDict["Beam"][0] Sdf_trig = PositionDict["Beam"][1] Sdf_mrd = PositionDict["Beam"][2] Sdf = Sdf.loc[Sdf["eventTimeTank"] > -9].reset_index(drop=True)
def WMPlots(Sdf, Bdf, Sdf_trig, Bdf_trig): Sdf_SinglePulses = es.SingleSiPMPulses(Sdf) Sdf_CleanPrompt = es.NoPromptClusters(Sdf_SinglePulses, 2000) Sdf_CleanWindow = es.NoBurstClusters(Sdf_CleanPrompt, 2000, 150) Sdf_LateWindow = Sdf_CleanWindow.loc[(Sdf_CleanWindow["clusterTime"] > 2000)].reset_index(drop=True) Sdf_trig_goodSiPM = Sdf_trig.loc[(Sdf_trig['SiPM1NPulses'] == 1) & ( Sdf_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) Sdf_trig_CleanPrompt = es.NoPromptClusters_WholeFile( Sdf_SinglePulses, Sdf_trig_goodSiPM, 2000) Sdf_trig_CleanWindow = es.NoBurst_WholeFile(Sdf_CleanPrompt, Sdf_trig_CleanPrompt, 2000, 150) Bdf_SinglePulses = es.SingleSiPMPulses(Bdf) Bdf_CleanPrompt = es.NoPromptClusters(Bdf_SinglePulses, 2000) Bdf_CleanWindow = es.NoBurstClusters(Bdf_CleanPrompt, 2000, 150) Bdf_LateWindow = Bdf_CleanWindow.loc[(Bdf_CleanWindow['clusterTime'] > 2000)].reset_index(drop=True) Bdf_trig_cleanSiPM = Bdf_trig.loc[(Bdf_trig['SiPM1NPulses'] == 1) & ( Bdf_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) Bdf_trig_cleanPrompt = es.NoPromptClusters_WholeFile( Bdf_SinglePulses, Bdf_trig_cleanSiPM, 2000) Bdf_trig_BurstCut = es.NoBurst_WholeFile(Bdf_CleanPrompt, Bdf_trig_cleanPrompt, 2000, 150) All_PE = np.hstack(Sdf_LateWindow['hitPE']) All_T = np.hstack(Sdf_LateWindow['hitT']) All_ID = np.hstack(Sdf_LateWindow['hitDetID']) WM = np.where((All_ID == 382) | (All_ID == 393) | (All_ID == 404))[0] LateTime = np.where(All_T > 12000)[0] WMDelayed = np.intersect1d(LateTime, WM) WM_PE = All_PE[WMDelayed] plt.hist(WM_PE, bins=30, range=(0, 100)) plt.title( "PE distribution for three WATCHMAN tubes in hit clusters \n (AmBe source data, all preliminary cuts)" ) plt.xlabel("Hit PE") plt.show() #Sdf_Odd = Sdf.loc[(Sdf["clusterChargePointY"]>0.125)&(Sdf["clusterChargePointY"]<0.2)].reset_index(drop=True) Sdf_Odd = Sdf.loc[(Sdf["clusterChargeBalance"] > 0.9)].reset_index( drop=True) HiCB_PE = np.hstack(Sdf_Odd.hitPE) HiCB_DetID = np.hstack(Sdf_Odd.hitDetID) plt.hist2d(HiCB_DetID, HiCB_PE, bins=(138, 20), range=[(331, 469), (0, 20)], cmap=plt.cm.inferno) plt.colorbar() plt.title( "PE distribution for all hits in clusters \n (Central source, $t_{c}>2 \, \mu s$, CB>0.9)" ) plt.xlabel("Tube ID") plt.ylabel("PE") plt.show() #Sdf_Odd = Sdf.loc[(Sdf["clusterChargePointY"]>0.125)&(Sdf["clusterChargePointY"]<0.2)].reset_index(drop=True) Sdf_Mid = Sdf.loc[(Sdf["clusterChargeBalance"] > 0.4) & (Sdf["clusterChargeBalance"] < 0.6)].reset_index( drop=True) MidCB_PE = np.hstack(Sdf_Mid.hitPE) MidCB_DetID = np.hstack(Sdf_Mid.hitDetID) plt.hist2d(MidCB_DetID, MidCB_PE, bins=(138, 20), range=[(331, 469), (0, 20)], cmap=plt.cm.inferno) plt.colorbar() plt.title( "PE distribution for all hits in clusters \n (Central source, $t_{c}>2 \, \mu s$, 0.4<CB<0.6)" ) plt.xlabel("Tube ID") plt.ylabel("PE") plt.show() Sdf_Lo = Sdf.loc[(Sdf["clusterChargeBalance"] < 0.4)].reset_index( drop=True) LoCB_PE = np.hstack(Sdf_Lo.hitPE) LoCB_DetID = np.hstack(Sdf_Lo.hitDetID) plt.hist2d(LoCB_DetID, LoCB_PE, bins=(138, 20), range=[(331, 469), (0, 20)], cmap=plt.cm.inferno) plt.colorbar() plt.title( "PE distribution for all hits in clusters \n (Central source, $t_{c}>2 \, \mu s$, CB<0.4)" ) plt.xlabel("Tube ID") plt.ylabel("PE") plt.show() All_PE = np.hstack(Sdf_Odd['hitPE']) All_T = np.hstack(Sdf_Odd['hitT']) All_ID = np.hstack(Sdf_Odd['hitDetID']) WM = np.where((All_ID == 382) | (All_ID == 393) | (All_ID == 404))[0] LateTime = np.where(All_T > 12000)[0] WMDelayed = np.intersect1d(LateTime, WM) WM_PE = All_PE[WMDelayed] plt.hist(WM_PE, bins=30, range=(0, 100)) plt.title( "PE distribution for three WATCHMAN tubes in hit clusters \n (Source, 0.9 < CB < 1.0 clusters only" ) plt.xlabel("Hit PE") plt.show() Sdf_rawLate = Sdf.loc[(Sdf["clusterTime"] > 2000)].reset_index(drop=True) labels = { 'title': 'Comparison of total PE to charge balance parameter \n (Source, $t_{c}>2 \, \mu s$)', 'xlabel': 'Total PE', 'ylabel': 'Charge balance parameter' } ranges = {'xbins': 40, 'ybins': 40, 'xrange': [0, 80], 'yrange': [0, 1]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist(Sdf_rawLate, 'clusterPE', 'clusterChargeBalance', labels, ranges) plt.show() labels = { 'title': 'Charge balance parameters in time window \n (Source, $t_{c}>2 \, \mu s$)', 'xlabel': 'Cluster time (ns)', 'ylabel': 'Charge balance' } ranges = { 'xbins': 40, 'ybins': 40, 'xrange': [2000, 67000], 'yrange': [0, 1] } #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist(Sdf_rawLate, 'clusterTime', 'clusterChargeBalance', labels, ranges) plt.show() labels = { 'title': 'Comparison of total PE to charge balance parameter \n (Central source w/ preliminary cuts, $t_{c}>2 \, \mu s$)', 'xlabel': 'Total PE', 'ylabel': 'Charge balance parameter' } ranges = {'xbins': 40, 'ybins': 40, 'xrange': [0, 80], 'yrange': [0, 1]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist(Sdf_LateWindow, 'clusterPE', 'clusterChargeBalance', labels, ranges) plt.show() labels = { 'title': 'Comparison of total PE to charge balance parameter \n (Central background, >2 $\mu$s)', 'xlabel': 'Total PE', 'ylabel': 'Charge balance parameter' } ranges = {'xbins': 50, 'ybins': 50, 'xrange': [0, 80], 'yrange': [0, 1]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) Bdf_latewindow = Bdf.loc[Bdf['clusterTime'] > 12000] abp.Make2DHist(Bdf_latewindow, 'clusterPE', 'clusterChargeBalance', labels, ranges) plt.show() labels = { 'title': 'Comparison of total PE to charge balance parameter \n (Central background w\ preliminary cuts, >2 $\mu$s)', 'xlabel': 'Total PE', 'ylabel': 'Charge balance parameter' } ranges = {'xbins': 50, 'ybins': 50, 'xrange': [0, 80], 'yrange': [0, 1]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist(Bdf_LateWindow, 'clusterPE', 'clusterChargeBalance', labels, ranges) plt.show() #Apply late window and charge balance cuts for data cleaning Bdf_latewindow = Bdf.loc[Bdf['clusterTime'] > 12000] Sdf_CleanPromptCB = Sdf_CleanPrompt.loc[ Sdf_CleanPrompt['clusterChargeBalance'] < 0.4].reset_index(drop=True)
#plt.show() #Bdf_latewindow_CBCut = Bdf_latewindow.loc[Bdf_latewindow['clusterChargeBalance']<0.4] #labels = {'title': 'Comparison of total PE to Charge Point Y-component (No source, >12 $\mu$s, Charge Balance < 0.4)', # 'xlabel': 'Total PE', 'ylabel': 'Charge Point Y'} #ranges = {'xbins': 30, 'ybins':30, 'xrange':[0,60],'yrange':[-1,1]} ##abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) #abp.Make2DHist(Bdf_latewindow_CBCut,'clusterPE','clusterChargePointY',labels,ranges) #plt.show() if __name__ == '__main__': slist = glob.glob(SIGNAL_DIR + "*.ntuple.root") blist = glob.glob(BKG_DIR + "*.ntuple.root") livetime_estimate = es.EstimateLivetime(slist) print("SIGNAL LIVETIME ESTIMATE IN SECONDS IS: " + str(livetime_estimate)) livetime_estimate = es.EstimateLivetime(blist) print("BKG LIVETIME ESTIMATE IN SECONDS IS: " + str(livetime_estimate)) mybranches = [ 'eventNumber', 'eventTimeTank', 'clusterTime', 'SiPMhitQ', 'SiPMNum', 'SiPMhitT', 'hitT', 'hitQ', 'hitPE', 'hitDetID', 'clusterChargeBalance', 'clusterPE', 'SiPM1NPulses', 'SiPM2NPulses' ] SProcessor = rp.ROOTProcessor(treename="phaseIITankClusterTree") for f1 in slist: SProcessor.addROOTFile(f1, branches_to_get=mybranches) Sdata = SProcessor.getProcessedData() Sdf = pd.DataFrame(Sdata)
def PlotDemo(Sdf, Bdf, Sdf_trig, Bdf_trig): print("EVENT SELECTION LOSSES FOR CENTRAL SOURCE RUN") EventSelectionLosses(Sdf, Sdf_trig) print("EVENT SELECTION LOSSES FOR BKG CENTRAL SOURCE RUN") EventSelectionLosses(Bdf, Bdf_trig) Sdf_SinglePulses = es.SingleSiPMPulses(Sdf) Sdf_CleanPrompt = es.NoPromptClusters(Sdf_SinglePulses, 2000) Sdf_CleanWindow = es.NoBurstClusters(Sdf_CleanPrompt, 2000, 150) Sdf_CleanWindow_CBClean = Sdf_CleanWindow.loc[ Sdf_CleanWindow['clusterChargeBalance'] < 0.4] Sdf_trig_goodSiPM = Sdf_trig.loc[(Sdf_trig['SiPM1NPulses'] == 1) & ( Sdf_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) Sdf_trig_CleanPrompt = es.NoPromptClusters_WholeFile( Sdf_SinglePulses, Sdf_trig_goodSiPM, 2000) Sdf_trig_CleanWindow = es.NoBurst_WholeFile(Sdf_CleanPrompt, Sdf_trig_CleanPrompt, 2000, 150) #Line of cuts applied to background clusters Bdf_SinglePulses = es.SingleSiPMPulses(Bdf) Bdf_CleanPrompt = es.NoPromptClusters(Bdf_SinglePulses, 2000) Bdf_CleanWindow = es.NoBurstClusters(Bdf_CleanPrompt, 2000, 150) Bdf_latewindow = Bdf_CleanWindow.loc[(Bdf_CleanWindow['clusterTime'] > 2000)].reset_index(drop=True) Bdf_latewindow = Bdf_latewindow.loc[(Bdf_latewindow['clusterChargeBalance'] < 0.4)].reset_index(drop=True) Bdf_trig_cleanSiPM = Bdf_trig.loc[(Bdf_trig['SiPM1NPulses'] == 1) & ( Bdf_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) Bdf_trig_cleanPrompt = es.NoPromptClusters_WholeFile( Bdf_SinglePulses, Bdf_trig_cleanSiPM, 2000) Bdf_trig_BurstCut = es.NoBurst_WholeFile(Bdf_CleanPrompt, Bdf_trig_cleanPrompt, 2000, 150) #Special case Bdf_NoBurstLateWindow = es.NoBurstClusters(Bdf_SinglePulses, 12000, 150) Bdf_NBlatewindow = Bdf_NoBurstLateWindow.loc[( Bdf_NoBurstLateWindow['clusterTime'] > 12000)].reset_index(drop=True) Bdf_NBCBCut = Bdf_NBlatewindow.loc[ Bdf_NBlatewindow['clusterChargeBalance'] < 0.4].reset_index(drop=True) #Get prompt clusters within a 100 ns window of the mean SiPM single pulse time Sdf_SPPrompt = es.SiPMCorrelatedPrompts(Sdf_SinglePulses, 100, 1000, 2000) print("NUMBER OF PROMPT CLUSTERS PASSING SINGLE SIPM PULSE CUTS: " + str(len(Sdf_SinglePulses.eventTimeTank))) Sdf_SPPrompt = Sdf_SPPrompt.loc[ Sdf_SPPrompt['clusterChargeBalance'] < 0.4].reset_index(drop=True) Sdf_SPPrompt_trig = es.SiPMCorrelatedPrompts_WholeFile( Sdf_SPPrompt, Sdf_trig) print("NUMBER OF PROMPT CLUSTERS PASSING CORRELATED PROMPT CUTS: " + str(len(Sdf_SPPrompt.eventTimeTank))) print("NUMBER OF TRIGS WITH AT LEAST ONE CORRELATED PROMPT: " + str(len(Sdf_SPPrompt_trig.eventTimeTank))) MSData = abp.MakeClusterMultiplicityPlot(Sdf_SPPrompt, Sdf_SPPrompt_trig) #s_bins, s_edges = np.histogram(MSData,bins=20, range=(0,20)) #plt.hist(MSData,bins=20, range=(0,20), label="Source",alpha=0.7) plt.hist(MSData, bins=100, label="Source", alpha=0.7) plt.xlabel("False start candidate cluster multiplicity") plt.title( "Cluster multiplicity of false starts in source data \n (One pulse each SiPM, cluster within prompt window)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() S1Delta, S2Delta = abp.SiPMClusterDifferences(Sdf_SPPrompt, 100) plt.hist(S1Delta, bins=100, label="S1Time-clusterTime", alpha=0.7) plt.hist(S2Delta, bins=100, label="S2Time-clusterTime", alpha=0.7) plt.xlabel("SiPM time - Cluster time (ns)") plt.title( "Difference between SiPM peak time and cluster time \n (One pulse each SiPM, cluster within prompt window)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() Sdf_SPPromptLoPE = Sdf_SPPrompt.loc[ Sdf_SPPrompt['clusterPE'] < 80].reset_index(drop=True) print( "NUMBER OF PROMPT CLUSTERS PASSING CORRELATED PROMPT CUTS LT 80 PE: " + str(len(Sdf_SPPromptLoPE.eventTimeTank))) NumTrigs = len(set(Sdf_SPPromptLoPE.eventNumber)) print( "NUMBER OF TRIGS WITH A PASSING CORRELATED PROMPT CUTS CLUSTER LT 80 PE: " + str(NumTrigs)) labels = { 'title': 'Comparison of cluster PE to total SiPM Charge \n (Position 0, AmBe source installed)', 'xlabel': 'Cluster PE', 'ylabel': 'Total SiPM charge [nC]' } ranges = { 'xbins': 30, 'ybins': 40, 'xrange': [0, 60], 'yrange': [0, 0.5], 'promptTime': 2000 } #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist_PEVsQ(Sdf_SPPrompt, labels, ranges) plt.show() plt.hist(np.hstack(Sdf_SPPrompt['clusterPE']), bins=30, range=(0, 80), alpha=0.5, histtype='stepfilled', linewidth=6) plt.hist(np.hstack(Sdf_SPPrompt['clusterPE']), bins=30, range=(0, 80), alpha=0.75, histtype='step', linewidth=6, color='green') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title( "False start candidate PE distribution (AmBe central source data)") plt.xlabel("Cluster PE") plt.show() Sdf_SPPrompt_10N = Sdf_SPPrompt.loc[Sdf_SPPrompt['clusterHits'] == 10].reset_index(drop=True) Sdf_SPPrompt_11N = Sdf_SPPrompt.loc[Sdf_SPPrompt['clusterHits'] == 11].reset_index(drop=True) Sdf_SPPrompt_12N = Sdf_SPPrompt.loc[Sdf_SPPrompt['clusterHits'] == 12].reset_index(drop=True) Sdf_SPPrompt_8N = Sdf_SPPrompt.loc[Sdf_SPPrompt['clusterHits'] == 8].reset_index(drop=True) Sdf_SPPrompt_9N = Sdf_SPPrompt.loc[Sdf_SPPrompt['clusterHits'] == 9].reset_index(drop=True) #plt.hist(np.hstack(Sdf_SPPrompt_10N['clusterPE']),bins=30,range=(0,80),alpha=0.5,histtype='stepfilled',linewidth=6) plt.hist(np.hstack(Sdf_SPPrompt_8N['clusterPE']), bins=30, range=(0, 80), label='8 hits', alpha=0.75, histtype='step', linewidth=6, color='green') plt.hist(np.hstack(Sdf_SPPrompt_9N['clusterPE']), bins=30, range=(0, 80), label='9 hits', alpha=0.75, histtype='step', linewidth=6, color='black') plt.hist(np.hstack(Sdf_SPPrompt_10N['clusterPE']), bins=30, range=(0, 80), label='10 hits', alpha=0.75, histtype='step', linewidth=6, color='blue') #plt.hist(np.hstack(Sdf_SPPrompt_11N['clusterPE']),bins=30,range=(0,80),alpha=0.5,histtype='stepfilled',linewidth=6) plt.hist(np.hstack(Sdf_SPPrompt_11N['clusterPE']), bins=30, range=(0, 80), label='11 hits', alpha=0.75, histtype='step', linewidth=6, color='red') #plt.hist(np.hstack(Sdf_SPPrompt_12N['clusterPE']),bins=30,range=(0,80),alpha=0.5,histtype='stepfilled',linewidth=6) plt.hist(np.hstack(Sdf_SPPrompt_12N['clusterPE']), bins=30, range=(0, 80), label='12 hits', alpha=0.75, histtype='step', linewidth=6, color='purple') #plt.hist(np.hstack(Sdf_SPPrompt_8N['clusterPE']),bins=30,range=(0,80),alpha=0.5,histtype='stepfilled',linewidth=6) #plt.hist(np.hstack(Sdf_SPPrompt_9N['clusterPE']),bins=30,range=(0,80),alpha=0.5,histtype='stepfilled',linewidth=6) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title("Cluster PE distribution for clusters of varying nhit") plt.xlabel("Cluster PE") plt.show() labels = { 'title': "Amplitude of SiPM1 hits", 'xlabel': 'Pulse amplitude [V]', 'llabel': 'SiPM1' } ranges = {'bins': 160, 'range': (0, 0.3)} abp.MakeSiPMVariableDistribution(Sdf_trig_goodSiPM, "SiPMhitAmplitude", 1, labels, ranges, True) labels = { 'title': "Amplitude of SiPM hits (Runs 1594-1596)", 'xlabel': 'Pulse amplitude [V]', 'llabel': 'SiPM2' } abp.MakeSiPMVariableDistribution(Sdf_trig_goodSiPM, "SiPMhitAmplitude", 2, labels, ranges, False) plt.show() labels = { 'title': "Total charge of SiPM1 hits", 'xlabel': 'Pulse charge [nC]', 'llabel': 'SiPM1' } ranges = {'bins': 250, 'range': (0, 5.0)} abp.MakeSiPMVariableDistribution(Sdf_trig_goodSiPM, "SiPMhitQ", 1, labels, ranges, True) labels = { 'title': "Total Charge of SiPM hits (Runs 1594-1596)", 'xlabel': 'Pulse charge [nC]', 'llabel': 'SiPM2' } abp.MakeSiPMVariableDistribution(Sdf_trig_goodSiPM, "SiPMhitQ", 2, labels, ranges, False) plt.show() labels = { 'title': "Amplitude of SiPM1 hits (No Source)", 'xlabel': 'Pulse amplitude [V]', 'llabel': 'SiPM1' } ranges = {'bins': 160, 'range': (0, 0.3)} abp.MakeSiPMVariableDistribution(Bdf_trig_cleanSiPM, "SiPMhitAmplitude", 1, labels, ranges, True) labels = { 'title': "Amplitude of SiPM hits (Runs 1611-1612)", 'xlabel': 'Pulse amplitude [V]', 'llabel': 'SiPM2' } abp.MakeSiPMVariableDistribution(Bdf_trig_cleanSiPM, "SiPMhitAmplitude", 2, labels, ranges, False) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() labels = { 'title': "Charge of SiPM hits (No Source)", 'xlabel': 'Pulse charge [nC]', 'llabel': 'SiPM1' } ranges = {'bins': 250, 'range': (0, 5.0)} abp.MakeSiPMVariableDistribution(Bdf_trig_cleanSiPM, "SiPMhitQ", 1, labels, ranges, True) labels = { 'title': "Total charge of SiPM hits (Runs 1611-1612)", 'xlabel': 'Pulse charge [nC]', 'llabel': 'SiPM2' } abp.MakeSiPMVariableDistribution(Bdf_trig_cleanSiPM, "SiPMhitQ", 2, labels, ranges, False) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() labels = { 'title': "Sum of SiPM Charges (Source)", 'xlabel': 'Total SiPM charge [nC]', 'ylabel': 'Number of acquisitions' } ranges = {'bins': 200, 'range': (0, 10.0)} abp.SiPMVariableSum(Sdf_trig_goodSiPM, "SiPMhitQ", labels, ranges) plt.show() labels = { 'title': "Sum of SiPM Charges (No Source)", 'xlabel': 'Total SiPM charge [nC]', 'ylabel': 'Number of acquisitions' } ranges = {'bins': 200, 'range': (0, 10.0)} abp.SiPMVariableSum(Bdf_trig_cleanSiPM, "SiPMhitQ", labels, ranges) plt.show() labels = { 'title': "Sum of SiPM Charges (Source, all preliminary cuts applied)", 'xlabel': 'Total SiPM charge [nC]', 'ylabel': 'Number of acquisitions' } ranges = {'bins': 200, 'range': (0, 10.0)} abp.SiPMVariableSum(Sdf_trig_CleanWindow, "SiPMhitQ", labels, ranges) plt.show() labels = { 'title': "Sum of SiPM Charges (No Source, all preliminary cuts applied)", 'xlabel': 'Total SiPM charge [nC]', 'ylabel': 'Number of acquisitions' } ranges = {'bins': 200, 'range': (0, 10.0)} abp.SiPMVariableSum(Bdf_trig_BurstCut, "SiPMhitQ", labels, ranges) plt.show() labels = { 'title': "Sum of SiPM Charges \n (Single SiPM pulse cut only)", 'xlabel': 'Total SiPM charge [nC]', 'llabel': 'Source data', 'ylabel': 'Number of acquisitions' } ranges = {'bins': 200, 'range': (0, 10.0)} abp.SiPMVariableSum(Sdf_trig_goodSiPM, "SiPMhitQ", labels, ranges) labels = { 'title': "Sum of SiPM Charges \n (Single SiPM pulse cut only)", 'xlabel': 'Total SiPM charge [nC]', 'llabel': 'Background data', 'ylabel': 'Number of acquisitions' } abp.SiPMVariableSum(Bdf_trig_cleanSiPM, "SiPMhitQ", labels, ranges) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() labels = { 'title': "Sum of SiPM Charges \n (All preliminary cuts applied)", 'xlabel': 'Total SiPM charge [nC]', 'llabel': 'Source data', 'ylabel': 'Number of acquisitions' } ranges = {'bins': 200, 'range': (0, 10.0)} abp.SiPMVariableSum(Sdf_trig_CleanWindow, "SiPMhitQ", labels, ranges) labels = { 'title': "Sum of SiPM Charges \n (All preliminary cuts applied)", 'xlabel': 'Total SiPM charge [nC]', 'llabel': 'Background data', 'ylabel': 'Number of acquisitions' } abp.SiPMVariableSum(Bdf_trig_BurstCut, "SiPMhitQ", labels, ranges) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() plt.hist(np.hstack(Sdf_SinglePulses['SiPMhitT']), bins=30, range=(0, 1500), alpha=0.5, histtype='stepfilled', linewidth=6) plt.hist(np.hstack(Sdf_SinglePulses['SiPMhitT']), bins=30, range=(0, 1500), alpha=0.75, histtype='step', linewidth=6) plt.title("Distribution of pulse peak times for SiPMs (Prompt window)") plt.xlabel("Peak time [ns]") plt.show() #plt.hist(Sdf_SinglePulses['clusterTime'],,bins=30,range=(0,1500),alpha=0.5,histtype='stepfilled',linewidth=6) #plt.hist(np.hstack(Sdf_SinglePulses['SiPMhitT']),bins=30,range=(0,1500),alpha=0.75,histtype='step',linewidth=6) plt.hist(Bdf_SinglePulses['clusterTime'], 70, alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(Bdf_SinglePulses['clusterTime'], 70, label='No source', alpha=0.8, histtype='step', linewidth=6) plt.hist(Sdf_SinglePulses['clusterTime'], 70, alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(Sdf_SinglePulses['clusterTime'], 70, label='Source', alpha=0.8, histtype='step', linewidth=6) plt.xlabel("Cluster time (ns)") plt.ylabel("Number of clusters") plt.title( "Time distribution of all hit clusters \n AmBe data, (SiPM cut only, central deployment position)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() plt.hist(Bdf_CleanWindow['clusterTime'], 70, alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(Bdf_CleanWindow['clusterTime'], 70, label='No source', alpha=0.8, histtype='step', linewidth=6) plt.hist(Sdf_CleanWindow['clusterTime'], 70, alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(Sdf_CleanWindow['clusterTime'], 70, label='Source', alpha=0.8, histtype='step', linewidth=6) plt.xlabel("Neutron candidate time (ns)") plt.ylabel("Number of candidates") plt.title( "Time distribution of neutron candidates \n (All preliminary cuts applied, central AmBe data)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() plt.hist(Sdf_CleanWindow['clusterTime'], 35, range=(15000, 65000), alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(Sdf_CleanWindow['clusterTime'], 35, range=(15000, 65000), label='Source data', alpha=0.8, histtype='step', linewidth=6) hist, bin_edges = np.histogram(Sdf_CleanWindow['clusterTime'], 35, range=(15000, 65000)) bin_lefts = bin_edges[0:len(bin_edges) - 1] print(len(hist)) print(len(bin_lefts)) bin_width = bin_lefts[1] - bin_lefts[0] bin_centers = bin_lefts + bin_width / 2. #try making some nice bins init_params = [200, 30000, 10000, 10] popt, pcov = scp.curve_fit(expoPFlat, bin_centers, hist, p0=init_params, maxfev=6000) print("WE HERE") print(popt) print(pcov) myy = expoPFlat(bin_centers, popt[0], popt[1], popt[2], popt[3]) myy_line = np.ones(len(bin_centers)) * popt[3] tau_mean = int(popt[1] / 1000) tau_unc = int(np.sqrt(pcov[1][1]) / 1000) plt.plot(bin_centers, myy, marker='None', linewidth=6, label=r'Best total fit $\tau = %i\pm%i \mu s$' % (tau_mean, tau_unc), color='black') plt.plot(bin_centers, myy_line, marker='None', linewidth=6, label=r'Flat bkg. fit', color='gray') plt.xlabel("Neutron candidate time (ns)") plt.ylabel("Number of candidates") plt.title( "Time distribution of neutron candidates \n (All preliminary cuts applied, AmBe central source data)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Calculate chi^2/ndof chisq = np.sum(((hist - myy)**2) / hist) ndof = np.size(hist) print("CHISQ/NDOF: %s/%s" % (str(chisq), str(ndof))) #Find the baseline with the bin resolution used in Vincent's plot plt.hist(Sdf_CleanWindow['clusterTime'], 75, range=(15000, 65000), alpha=0.8) plt.show() plt.hist(Sdf_CleanWindow['clusterTime'], 75, range=(15000, 65000), alpha=0.8) dhist, dbin_edges = np.histogram(Sdf_CleanWindow['clusterTime'], 75, range=(15000, 65000)) dbin_lefts = dbin_edges[0:len(dbin_edges) - 1] dbin_width = dbin_lefts[1] - dbin_lefts[0] dbin_centers = dbin_lefts + dbin_width / 2. init_params = [40, 30000, 15000, 5] popt, pcov = scp.curve_fit(expoPFlat, dbin_centers, dhist, p0=init_params, maxfev=6000) print("WE ARE HERE") print(popt) print(pcov) myy = expoPFlat(dbin_centers, popt[0], popt[1], popt[2], popt[3]) myy_line = np.ones(len(dbin_centers)) * popt[3] flat_bkg = popt[3] tau_mean = int(popt[1] / 1000) tau_unc = int(np.sqrt(pcov[1][1]) / 1000) plt.plot(dbin_centers, myy, marker='None', linewidth=6, label=r'Best total fit $\tau = %i\pm%i \mu s$' % (tau_mean, tau_unc), color='black') plt.plot(dbin_centers, myy_line, marker='None', linewidth=6, label=r'Flat bkg. fit', color='gray') plt.xlabel("Cluster time (ns)") plt.ylabel("Number of clusters") plt.title( "Time distribution of delayed hit clusters (MCBins) \n (One pulse in each SiPM, no prompt cluster)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Get MC #mchist,mcbin_lefts = fr.ReadHistFile(MCDELTAT) #mcrange = np.where(mcbin_lefts<70100)[0] #mchist = mchist[mcrange] #mcbin_lefts = mcbin_lefts[mcrange] mchist, mcbin_lefts = fr.ReadHistFileSimple(MCDELTAT) print(mchist) print(mcbin_lefts) mchist, mcbin_lefts = hu.AggregateBins(mchist, mcbin_lefts, 100, 0, 67000) mchist_unc = np.sqrt(mchist) mchist_normed = mchist / np.sum(mchist) mchist_normed_unc = mchist_unc / np.sum(mchist) #Plot data over MC range, subtract baseline dhist, dbin_edges = np.histogram(Sdf_CleanWindow['clusterTime'], 100, range=(0, 67000)) dbin_lefts = dbin_edges[0:len(dbin_edges) - 1] dhist_nobkg = dhist - popt[3] #dhist_nobkg = dhist neg_bins = np.where(dhist_nobkg < 0)[0] dhist_nobkg[neg_bins] = 0 dhist_nobkg_unc = np.sqrt( dhist_nobkg) #TODO: could propagate uncertainty on flat fit too dhist_nobkg_normed = dhist_nobkg / np.sum(dhist_nobkg) dhist_nobkg_normed_unc = dhist_nobkg_unc / np.sum(dhist_nobkg) plt.errorbar(dbin_lefts, dhist_nobkg_normed, yerr=dhist_nobkg_normed_unc, linestyle='None', marker='o', label='AmBe source data') plt.errorbar(mcbin_lefts, mchist_normed, yerr=mchist_normed_unc, marker='o', linestyle='None', label='RATPAC MC') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title( "Comparison of neutron candidate time distribution in central data/MC") plt.xlabel("Neutron candidate time (ns)") plt.ylabel("Arb. units") plt.show() #CleanEventNumbers = Sdf_CleanPrompt["eventNumber"] #Return DF with triggers that have no prompt and one of each SiPM pulse #MSData = abp.MakeClusterMultiplicityPlot(Sdf_CleanPrompt,Sdf_trig_CleanPrompt) MSData = abp.MakeClusterMultiplicityPlot(Sdf_CleanWindow_CBClean, Sdf_trig_CleanWindow) print("NUMBER OF TRIGS: " + str(len(MSData))) print("NUMBER OF ZERO MULTIPLICITY TRIGS: " + str(len(np.where(MSData == 0)[0]))) s_bins, s_edges = np.histogram(MSData, bins=20, range=(0, 20)) print("SIGNAL_BINS: " + str(s_bins)) print("SIGNAL_BIN_EDGES: " + str(s_edges)) plt.hist(MSData, bins=20, range=(0, 20), label="Source", alpha=0.7) plt.xlabel("Delayed cluster multiplicity") plt.title( "Cluster multiplicity for delayed window of central source run \n (One pulse each SiPM, no prompt cluster)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() plt.hist(Bdf_NBCBCut['clusterTime'], 100, range=(12000, 65000), label='No source', color='purple', alpha=0.7) #plt.hist(Bdf_SinglePulses['clusterTime'],100,label='No source', color='purple',alpha=0.7) plt.xlabel("Cluster time (ns)") plt.ylabel("Number of candidates") plt.title( "Region to characterize flat background distribution \n (No source data, SiPM cut + Burst cut)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() Bdf_trig_goodSiPM = Bdf_trig.loc[(Bdf_trig['SiPM1NPulses'] == 1) & ( Bdf_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) Bdf_trig_CleanWindow = es.NoBurst_WholeFile(Bdf_SinglePulses, Bdf_trig_goodSiPM, 12000, 150) #Bdf_trig_bkgclean = es.FilterByEventNumber(Bdf_trig,CleanBkgNumbers) #Get cluster multiplicity of late window in events passing prompt criteria MBData = abp.MakeClusterMultiplicityPlot(Bdf_NBCBCut, Bdf_trig_CleanWindow) MBData = abp.MakeClusterMultiplicityPlot(Bdf_latewindow, Bdf_trig_BurstCut) print("NUMBER OF TRIGS: " + str(len(MBData))) print("NUMBER OF ZERO MULTIPLICITY TRIGS (LATE WINDOW): " + str(len(np.where(MBData == 0)[0]))) b_bins, b_edges = np.histogram(MBData, bins=20, range=(0, 20)) print("BKG_BINS: " + str(b_bins)) print("BKG_BIN_EDGES: " + str(b_edges)) plt.hist(MBData, bins=20, range=(0, 20), label="No source", alpha=0.7) plt.xlabel("Delayed cluster multiplicity") plt.ylabel("Number of acquisitions") plt.title( "Cluster multiplicity for delayed window of central source run \n (One pulse each SiPM, no prompt cluster)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Plotting the PE distribution Sdf_latewindow = Sdf_SinglePulses.loc[(Sdf_SinglePulses['clusterTime'] > 2000)].reset_index(drop=True) plt.hist(Sdf_CleanWindow['clusterPE'], 70, alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(Sdf_CleanWindow['clusterPE'], 70, label='Source ($>2 \, \mu s$)', alpha=0.8, histtype='step', linewidth=6) plt.hist(Bdf_NBCBCut['clusterPE'], 70, alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(Bdf_NBCBCut['clusterPE'], 70, label='No source ($>12 \, \mu s$)', alpha=0.8, histtype='step', linewidth=6) plt.xlabel("PE") plt.ylabel("Number of clusters") plt.title( "PE distribution for delayed clusters \n (SiPM cut only, AmBe central data" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Get MC #mchist,mcbin_lefts = fr.ReadHistFile(MCPE) mchist, mcbin_lefts = fr.ReadHistFileSimple(MCPE) mchist, mcbin_lefts = hu.AggregateBins(mchist, mcbin_lefts, 75, 0, 150) mchist_normed = mchist / np.sum(mchist) mchist_unc = np.sqrt(mchist) mchist_normed_unc = mchist_unc / np.sum(mchist) #Plot data over MC range, subtract baseline dhist, dbin_edges = np.histogram(Sdf_CleanWindow['clusterPE'], 75, range=(0, 150)) dbin_lefts = dbin_edges[0:len(dbin_edges) - 1] dhist_unc = np.sqrt( dhist) #TODO: could propagate uncertainty on flat fit too dhist_normed = dhist / np.sum(dhist) dhist_normed_unc = dhist_unc / np.sum(dhist) plt.errorbar(dbin_lefts, dhist_normed, yerr=dhist_normed_unc, linestyle='None', marker='o', label='AmBe source data') plt.errorbar(mcbin_lefts, mchist_normed, yerr=mchist_normed_unc, marker='o', linestyle='None', label='RATPAC MC') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title( "Comparison of neutron candidate PE distribution in central data/MC") plt.xlabel("Neutron candidate PE") plt.ylabel("Arb. units") plt.show() #Same as above, but plotting past 25 PE mchist, mcbin_lefts = fr.ReadHistFileSimple(MCPE) mchist, mcbin_lefts = hu.AggregateBins(mchist, mcbin_lefts, 70, 20, 160) mchist_normed = mchist / np.sum(mchist) mchist_unc = np.sqrt(mchist) mchist_normed_unc = mchist_unc / np.sum(mchist) dhist, dbin_edges = np.histogram(Sdf_CleanWindow['clusterPE'], 70, range=(20, 160)) dbin_lefts = dbin_edges[0:len(dbin_edges) - 1] dhist_unc = np.sqrt(dhist) dhist_normed = dhist / np.sum(dhist) dhist_normed_unc = dhist_unc / np.sum(dhist) plt.errorbar(dbin_lefts, dhist_normed, yerr=dhist_normed_unc, linestyle='None', marker='o', label='AmBe source data') plt.errorbar(mcbin_lefts, mchist_normed, yerr=mchist_normed_unc, marker='o', linestyle='None', label='RATPAC MC') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title( "Comparison of neutron candidate PE distribution in central data/MC \n (Preliminary cuts applied except CB cut)" ) plt.xlabel("Neutron candidate PE") plt.ylabel("Arb. units") plt.show() #Plotting the PE distribution Bdf_latewindow_CBClean = Bdf_NBlatewindow.loc[ Bdf_NBlatewindow['clusterChargeBalance'] < 0.4] Sdf_CleanWindow_CBClean = Sdf_CleanWindow.loc[ Sdf_CleanWindow['clusterChargeBalance'] < 0.4] plt.hist(Sdf_CleanWindow_CBClean['clusterPE'], 70, alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(Sdf_CleanWindow_CBClean['clusterPE'], 70, label='Source ($>2 \, \mu s$)', alpha=0.8, histtype='step', linewidth=6) plt.hist(Bdf_latewindow_CBClean['clusterPE'], 70, alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(Bdf_latewindow_CBClean['clusterPE'], 70, label='No source \n (No tank cut, $>12 \, \mu s$ clusters)', alpha=0.8, histtype='step', linewidth=6) plt.xlabel("PE") plt.ylabel("Number of clusters") plt.title( "PE distribution for delayed clusters \n (All preliminary cuts applied, AmBe central runs)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() labels = { 'title': 'Comparison of total PE to charge balance parameter \n (Position 0, AmBe source installed)', 'xlabel': 'Total PE', 'ylabel': 'Charge balance parameter' } ranges = {'xbins': 50, 'ybins': 50, 'xrange': [0, 80], 'yrange': [0, 1]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist(Sdf_CleanWindow, 'clusterPE', 'clusterChargeBalance', labels, ranges) plt.show() labels = { 'title': 'Comparison of total PE to charge balance parameter \n (Position 0, no AmBe source installed, >12 $\mu$s)', 'xlabel': 'Total PE', 'ylabel': 'Charge balance parameter' } ranges = {'xbins': 50, 'ybins': 50, 'xrange': [0, 80], 'yrange': [0, 1]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) Bdf_latewindow = Bdf.loc[Bdf['clusterTime'] > 12000] abp.Make2DHist(Bdf_latewindow, 'clusterPE', 'clusterChargeBalance', labels, ranges) plt.show() labels = { 'title': 'Comparison of total PE to charge balance parameter', 'xlabel': 'Total PE', 'ylabel': 'Charge balance parameter', 'llabel': 'No source', 'color': 'Reds' } ranges = {'xbins': 50, 'ybins': 50, 'xrange': [0, 150], 'yrange': [0, 1]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) Bdf_window = Bdf_latewindow.loc[(Bdf_latewindow['clusterPE']<150) & \ (Bdf_latewindow['clusterChargeBalance']>0) & (Bdf_latewindow['clusterChargeBalance']<1)] Sdf_window = Sdf_CleanWindow.loc[(Sdf_CleanWindow['clusterPE']<150) & \ (Sdf_CleanWindow['clusterChargeBalance']>0) & (Sdf_CleanWindow['clusterChargeBalance']<1)] abp.MakeKDEPlot(Bdf_window, 'clusterPE', 'clusterChargeBalance', labels, ranges) labels = { 'title': 'Comparison of total PE to charge balance parameter', 'xlabel': 'Total PE', 'ylabel': 'Charge balance parameter', 'llabel': 'No source', 'color': 'Blues' } abp.MakeKDEPlot(Sdf_window, 'clusterPE', 'clusterChargeBalance', labels, ranges) plt.show()
def PlotDemo(Sdf, Sdf_trig): #Cuts can be applied to pandas dataframes; EventSelection.py has some cuts defined, #And some are directly applied here as well. Examples of applying cuts at both the #Cluster level and trigger level are shown. #Cluster level cuts Sdf_SinglePulses = es.SingleSiPMPulses(Sdf) Sdf_PlusCleanSiPMPrompt = es.NoPromptClusters(Sdf_SinglePulses, 2000) Sdf_PlusNoHighPEClusters = es.NoBurstClusters(Sdf_PlusCleanSiPMPrompt, 2000, 150) Sdf_PlusGoodCB = Sdf_PlusNoHighPEClusters.loc[ Sdf_PlusNoHighPEClusters['clusterChargeBalance'] < 0.4] #Trigger level cuts Sdf_trig_goodSiPM = Sdf_trig.loc[(Sdf_trig['SiPM1NPulses'] == 1) & ( Sdf_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) Sdf_trig_CleanPrompt = es.NoPromptClusters_WholeFile( Sdf_SinglePulses, Sdf_trig_goodSiPM, 2000) Sdf_trig_CleanWindow = es.NoBurst_WholeFile(Sdf_PlusCleanSiPMPrompt, Sdf_trig_CleanPrompt, 2000, 150) Sdf_clean = Sdf_PlusGoodCB Sdf_trig_clean = Sdf_trig_CleanWindow #Access hit information in first cluster print(np.array(Sdf_clean['hitX'][0])) print(np.array(Sdf_clean['hitY'][0])) print(np.array(Sdf_clean['hitZ'][0])) print(np.array(Sdf_clean['hitT'][0])) print(np.array(Sdf_clean['hitQ'][0])) print(np.array(Sdf_clean['hitPE'][0])) #Example of how to filter and only show hits in front-half of tank front_hits = np.where(np.array(Sdf_clean['hitZ'][0]) > 0)[0] print(np.array(Sdf_clean['hitX'][0])[front_hits]) print(np.array(Sdf_clean['hitY'][0])[front_hits]) print(np.array(Sdf_clean['hitZ'][0])[front_hits]) print(np.array(Sdf_clean['hitT'][0])[front_hits]) print(np.array(Sdf_clean['hitPE'][0])[front_hits]) #Access some cluster-level information for all clusters and of first cluster print(Sdf_clean['clusterPE']) print(Sdf_clean['clusterPE'][0]) print(Sdf_clean['clusterChargeBalance']) print(Sdf_clean['clusterChargeBalance'][0]) #Simple 1D histogram; plot total PE of all clusters plt.hist(Sdf_clean['clusterPE'], bins=30, range=(0, 80), alpha=0.75, histtype='stepfilled', linewidth=6, color='blue') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title("Cluster PE distribution ") plt.xlabel("Cluster PE") plt.ylabel("Number of clusters") plt.show() #Simple 1D histogram; PE distribution of all hits in all clusters plt.hist(np.hstack(Sdf_clean['hitPE']), bins=120, range=(0, 40), alpha=0.75, histtype='stepfilled', linewidth=6, color='blue') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title("Hit PE distribution") plt.xlabel("Hit PE") plt.ylabel("Number of hits") plt.show() #Simple 1D histogram; the exact same plot as above, but I think the step & stepfilled #Combo looks nice! plt.hist(np.hstack(Sdf_clean['hitPE']), bins=120, range=(0, 40), histtype='step', linewidth=6, color='blue') plt.hist(np.hstack(Sdf_clean['hitPE']), bins=120, range=(0, 40), histtype='stepfilled', linewidth=6, color='blue', alpha=0.6) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title("Hit PE distribution") plt.xlabel("Hit PE") plt.ylabel("Number of hits") plt.show() #Simple 2D histogram labels = { 'title': 'Charge balance parameter as a function of cluster PE', 'xlabel': 'Total PE', 'ylabel': 'Charge balance parameter' } ranges = {'xbins': 50, 'ybins': 50, 'xrange': [0, 80], 'yrange': [0, 1]} variables = {'x': 'clusterPE', 'y': 'clusterChargeBalance'} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) plt.hist2d(Sdf_clean[variables['x']], Sdf_clean[variables['y']], bins=(ranges['xbins'], ranges['ybins']), range=[ranges['xrange'], ranges['yrange']], cmap=plt.cm.inferno) plt.colorbar() plt.title(labels['title']) plt.xlabel(labels['xlabel']) plt.ylabel(labels['ylabel']) plt.show()
def BeamPlotDemo(PositionDict,MCdf): Sdf = PositionDict["Beam"][0] Sdf_trig = PositionDict["Beam"][1] Sdf_mrd = PositionDict["Beam"][2] Sdf = Sdf.loc[Sdf["eventTimeTank"]>-9].reset_index(drop=True) Sdf_trig = Sdf_trig.loc[Sdf_trig["eventTimeTank"]>-9].reset_index(drop=True) Sdf_mrd = Sdf_mrd.loc[Sdf_mrd["eventTimeTank"]>-9].reset_index(drop=True) Sdf_TankVeto = es.HasVetoHit_TankClusters(Sdf,Sdf_trig) print("NUM TANK CLUSTERS WITH VETO HIT: " + str(len(Sdf_TankVeto))) print("NUM TRIGS: " + str(len(Sdf_trig))) HasVetoHit = np.where(Sdf_mrd["vetoHit"].values==1)[0] print("NUM MRD CLUSTERS WITH VETO HIT: " + str(len(HasVetoHit))) #Let's list some plots we want to make here: # - Get delayed clusters that have eventTimeTanks matching the prompt/delayed # cluster times. Apply # - clusterPE>10 and clusterChargeBalance<0.4 and plot the time distribution Sdf_prompt_noCB = Sdf.loc[Sdf['clusterTime']<2000].reset_index(drop=True) Sdf_prompt = Sdf_prompt_noCB.loc[Sdf_prompt_noCB['clusterChargeBalance']<0.9].reset_index(drop=True) plt.hist(Sdf_prompt['clusterTime'],bins=100,range=(0,2000)) plt.title("Prompt window Tank cluster times") plt.xlabel("Cluster time [ns]") plt.show() print("TOTAL PROMPT TANK CLUSTERS, NO CB: " + str(len(Sdf_prompt_noCB))) print("TOTAL PROMPT TANK CLUSTERS: " + str(len(Sdf_prompt))) print("TOTAL PROMPT MRD CLUSTERS: " + str(len(Sdf_mrd))) labels = {'title': 'Charge balance parameters in time window \n (Beam data, $t_{c}<2 \, \mu s$)', 'xlabel': 'Cluster time (ns)', 'ylabel': 'Charge balance'} ranges = {'xbins': 40, 'ybins':40, 'xrange':[0,2000],'yrange':[0,1]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist(Sdf_prompt_noCB,'clusterTime','clusterChargeBalance',labels,ranges) plt.show() labels = {'title': 'Tank PMT hit cluster count as a function of time \n (Beam data, $t_{c}<2 \, \mu s$)', 'xlabel': 'Cluster time (ns)', 'ylabel': 'Cluster PE'} ranges = {'xbins': 40, 'ybins':250, 'xrange':[0,2000],'yrange':[0,500]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist(Sdf_prompt_noCB,'clusterTime','clusterPE',labels,ranges) plt.show() labels = {'title': 'Tank PMT hit cluster count as a function of time \n (Beam data, $t_{c}<2 \, \mu s$)', 'xlabel': 'Cluster time (ns)', 'ylabel': 'Cluster PE'} ranges = {'xbins': 40, 'ybins':250, 'xrange':[0,2000],'yrange':[500,5000]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist(Sdf_prompt_noCB,'clusterTime','clusterPE',labels,ranges) plt.show() labels = {'title': 'Tank PMT hit cluster count as a function of time \n (Beam data, $t_{c}<2 \, \mu s$)', 'xlabel': 'Cluster time (ns)', 'ylabel': 'Cluster PE'} ranges = {'xbins': 40, 'ybins':25, 'xrange':[0,2000],'yrange':[0,5000]} #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist(Sdf_prompt_noCB,'clusterTime','clusterPE',labels,ranges) plt.show() plt.hist(Sdf_mrd['clusterTime'].values,bins=80,range=(0,4000),label="All MRD clusters") plt.title("Prompt window MRD cluster times") plt.xlabel("Cluster time [ns]") plt.show() #Get largest cluster in each acquisition in prompt window Sdf_maxPE = es.MaxPEClusters(Sdf_prompt) print("TOTAL HIGHEST PE PROMPT CLUSTERS: " + str(len(Sdf_maxPE))) Sdf_mrd_maxhit = es.MaxHitClusters(Sdf_mrd) print("TOTAL MOST PADDLE MRD CLUSTERS: " + str(len(Sdf_mrd_maxhit))) #Now, get the index number for clusterTime pairs in the same triggers TankIndices, MRDIndices = es.MatchingEventTimes(Sdf_maxPE,Sdf_mrd_maxhit) TankTimes = Sdf_maxPE["clusterTime"].values[TankIndices] MRDTimes = Sdf_mrd_maxhit["clusterTime"].values[MRDIndices] Pairs_HaveVeto = Sdf_mrd_maxhit.loc[(Sdf_mrd_maxhit["vetoHit"].values[MRDIndices]==1)] print("NUM OF MRD CLUSTERS IN TRIG WITH A TANK CLUSTER: " + str(len(MRDTimes))) print("NUM OF MRD CLUSTERS WITH VETO IN SUBSET: " + str(len(Pairs_HaveVeto))) plt.scatter(TankTimes,MRDTimes,marker='o',s=15,color='blue',alpha=0.7) plt.title("Tank and MRD cluster times in prompt window \n (Largest PE tank clusters, largest paddle count MRD clusters)") plt.xlabel("Tank Cluster time [ns]") plt.ylabel("MRD Cluster time [ns]") plt.show() plt.hist(MRDTimes - TankTimes, bins = 160, color='blue', alpha=0.7) plt.axvline(x=700,color='black',linewidth=6) plt.axvline(x=800,color='black',linewidth=6) plt.title("Difference in MRD and Tank cluster times in acquisitions \n (Largest PE tank clusters, largest paddle count MRD clusters)") plt.xlabel("MRD cluster time - Tank cluster time [ns]") plt.show() #Get indices for MRD/Tank cluster times within the coincident window clusterIndices_match = np.where(((MRDTimes - TankTimes)<800) & ((MRDTimes - TankTimes) > 600))[0] MRDIndices_match = MRDIndices[clusterIndices_match] TankIndices_match = TankIndices[clusterIndices_match] MatchedMRDTimes = Sdf_mrd_maxhit['clusterTime'].values[MRDIndices_match] MatchedTankTimes = Sdf_maxPE['clusterTime'].values[TankIndices_match] print("NUMBER OF MATCHED TANKS: " + str(len(MatchedTankTimes))) print("NUMBER OF MATCHED MRDS: " + str(len(MatchedMRDTimes))) plt.hist(MatchedMRDTimes - MatchedTankTimes, bins = 80,color='blue') plt.axvline(x=700,color='black',linewidth=6) plt.axvline(x=800,color='black',linewidth=6) plt.title("Time distribution for matched MRD and Tank times") plt.xlabel("MRD cluster time - Tank cluster time [ns]") plt.show() plt.hist(Sdf_mrd['clusterTime'].values,bins=80,range=(0,4000),label="All MRD clusters") plt.hist(Sdf_mrd_maxhit['clusterTime'].values,bins=80,range=(0,4000),label="MRD clusters with most hits") #plt.hist(Sdf_mrd_maxhit['clusterTime'].values[MRDIndices],bins=80,range=(0,4000),label="+ Tank Cluster pair") plt.hist(Sdf_mrd_maxhit['clusterTime'].values[MRDIndices_match],bins=80,range=(0,4000),label="+ Tank cluster match") plt.title("Prompt window MRD cluster times \n event selection impact") plt.xlabel("Cluster time [ns]") plt.ylabel("Number of clusters") leg = plt.legend(loc=1,fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() plt.hist(Sdf_prompt_noCB['clusterTime'].values,bins=80,range=(0,2000),label="All Tank clusters") plt.hist(Sdf_prompt['clusterTime'].values,bins=80,range=(0,2000),label="+ CB<0.9") plt.hist(Sdf_maxPE['clusterTime'].values,bins=80,range=(0,2000),label="+ cluster with highest PE") #plt.hist(Sdf_maxPE['clusterTime'].values[TankIndices],bins=80,range=(0,2000),label="+ MRD Cluster Match") plt.hist(Sdf_maxPE['clusterTime'].values[TankIndices_match],bins=80,range=(0,2000),label="+ MRD cluster match") plt.title("Prompt window Tank cluster times \n event selection impact") plt.ylabel("Number of clusters") plt.xlabel("Cluster time [ns]") leg = plt.legend(loc=1,fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Now, Get all clusters past 12 us with the Event Times from TankIndices TankEventTimes_match = Sdf_maxPE["eventTimeTank"].values[TankIndices_match] Sdf_ClustersInPromptCandidates = es.FilterByEventTime(Sdf,TankEventTimes_match) #All clusters in events with a PMT/MRD match print("ALL CLUSTER COUNT IN EVENTS WITH PMT/MRD ACTIVITY: " + str(len(Sdf_ClustersInPromptCandidates))) plt.hist(Sdf_ClustersInPromptCandidates['clusterTime'].values,bins=40,range=(0,67000),label="All clusters") plt.title("All tank cluster times \n (Acquisitions with valid prompt event selection)") plt.ylabel("Number of clusters") plt.xlabel("Cluster time [ns]") plt.show() print("CLUSTER COUNT IN EVENTS BEFORE 2 US: " + str(len(Sdf_ClustersInPromptCandidates.loc[Sdf_ClustersInPromptCandidates["clusterTime"]<2000].values))) Sdf_ValidDelayedClusters = Sdf_ClustersInPromptCandidates.loc[Sdf_ClustersInPromptCandidates['clusterTime']>12000].reset_index(drop=True) Sdf_ValidDelayedClustersCB = Sdf_ClustersInPromptCandidates.loc[Sdf_ClustersInPromptCandidates['clusterChargeBalance']<0.4].reset_index(drop=True) print("CLUSTER COUNT IN EVENTS WITH PMT/MRD ACTIVITY PAST 12 US: " + str(len(Sdf_ValidDelayedClusters))) plt.hist(Sdf.loc[Sdf["clusterTime"]>12000,"clusterTime"],bins=20,range=(12000,65000),label='No PMT/MRD pairing in prompt',alpha=0.8) plt.hist(Sdf_ValidDelayedClusters["clusterTime"], bins=20, range=(12000,65000),label='PMT/MRD pair required in prompt',alpha=0.8) plt.hist(Sdf_ValidDelayedClustersCB["clusterTime"], bins=20, range=(12000,65000),label=' + CB < 0.4',alpha=0.8) plt.title("Delayed cluster times in beam runs") plt.ylabel("Number of clusters") plt.xlabel("Cluster time [ns]") leg = plt.legend(loc=1,fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Let's try to make the energy calibration plot #plt.hist(Sdf_maxPE["clusterPE"], bins=40, range=(0,5000)) #plt.title("Prompt cluster PE \n (Highest PE cluster in prompt window)") #plt.xlabel("Cluster PE") #leg = plt.legend(loc=1,fontsize=24) #leg.set_frame_on(True) #leg.draw_frame(True) #plt.show() Sdf_MatchingPrompts = Sdf_maxPE.loc[TankIndices_match].reset_index(drop=True) Sdf_MatchingPromptsMRD = Sdf_mrd_maxhit.loc[MRDIndices_match].reset_index(drop=True) #print("LEN OF TANK MATCHES: " + str(len(Sdf_MatchingPrompts))) #print("LEN OF MRD MATCHES: " + str(len(Sdf_MatchingPromptsMRD))) HasVetoHit = np.where(Sdf_MatchingPromptsMRD["vetoHit"].values==1)[0] print("NUMBER OF INTERACTIONS WITH A VETO HIT: " + str(len(HasVetoHit))) OneTrack = np.where(Sdf_MatchingPromptsMRD["numClusterTracks"].values==1)[0] print("NUMBER OF INTERACTIONS WITH ONE TRACK: " + str(len(OneTrack))) ThroughGoingCandidates = np.intersect1d(HasVetoHit,OneTrack) Sdf_ThroughGoingCandidates = Sdf_MatchingPrompts.loc[ThroughGoingCandidates].reset_index(drop=True) #plt.hist(Sdf_ThroughGoingCandidates["clusterPE"], bins=40, range=(0,5000)) #plt.title("Prompt cluster PE \n (Matching MRD cluster + one track + veto hit)") #plt.xlabel("Cluster PE") #leg = plt.legend(loc=1,fontsize=24) #leg.set_frame_on(True) #leg.draw_frame(True) #plt.show() ##Now, apply track event selection #TGValidTrackInds = es.SingleTrackSelection(Sdf_MatchingPromptsMRD.loc[ThroughGoingCandidates].reset_index(drop=True),100,1.0,10) #print("VALID TRACK INDICES: " + str(TGValidTrackInds)) #Sdf_TGValidTracks = Sdf_ThroughGoingCandidates.loc[TGValidTrackInds].reset_index(drop=True) #plt.hist(Sdf_TGValidTracks["clusterPE"], bins=40, range=(0,5000)) #plt.title("Prompt cluster PE \n (Matching MRD cluster + one track + veto hit + track cuts)") #plt.xlabel("Cluster PE") #leg = plt.legend(loc=1,fontsize=24) #leg.set_frame_on(True) #leg.draw_frame(True) #plt.show() ##Now, apply aggressive track event selection #TGValidTrackInds = es.SingleTrackSelection(Sdf_MatchingPromptsMRD.loc[ThroughGoingCandidates].reset_index(drop=True),60,0.4,60) #Sdf_TGValidTracks = Sdf_ThroughGoingCandidates.loc[TGValidTrackInds].reset_index(drop=True) #Sdf_TGValidTracks = Sdf_TGValidTracks.loc[Sdf_TGValidTracks['clusterHits']>70].reset_index(drop=True) #plt.hist(Sdf_TGValidTracks["clusterPE"], bins=40, range=(0,5000)) #plt.title("Prompt cluster PE, aggressive cuts \n (Matching MRD cluster + one track + veto hit + track cuts)") #plt.xlabel("Cluster PE") #leg = plt.legend(loc=1,fontsize=24) #leg.set_frame_on(True) #leg.draw_frame(True) #plt.show() #Let's estimate the visible energy for coincident Tank/Cluster events NoVetoHit = np.where(Sdf_MatchingPromptsMRD["vetoHit"].values==0)[0] print("NUMBER OF INTERACTIONS WITH NO VETO HIT: " + str(len(NoVetoHit))) OneTrack = np.where(Sdf_MatchingPromptsMRD["numClusterTracks"].values==1)[0] NuCandidates = np.intersect1d(NoVetoHit,OneTrack) Sdf_NuCandidates = Sdf_MatchingPrompts.loc[NuCandidates].reset_index(drop=True) print("NUMBER OF NU INTERACTION CANDIDATES: " + str(len(Sdf_NuCandidates))) Sdf_NuCandidatesMRD = Sdf_MatchingPromptsMRD.loc[NuCandidates].reset_index(drop=True) NUC_PE = Sdf_NuCandidates['clusterPE'].values NUC_EVENTTIMETANKS = Sdf_NuCandidates['eventTimeTank'].values NUC_TANKMEV = NUC_PE / PEPERMEV NUC_MRDENERGY = es.SingleTrackEnergies(Sdf_NuCandidatesMRD) VISIBLE_ENERGY = (NUC_TANKMEV + NUC_MRDENERGY)/1000 plt.hist(VISIBLE_ENERGY,bins=40,range=(0,4)) plt.xlabel("Visible energy estimate [GeV]") plt.ylabel("Normalized count rate (A.U.)") plt.title("Visible energy for single track event in tank and MRD") plt.show() #Try to do a normalized comparison. mc_energy = MCdf["trueMuonEnergy"].values/1000. mc_energy = MCdf.loc[(MCdf["Pi0Count"]==0) & (MCdf["PiPlusCount"]==0) & (MCdf["PiMinusCount"]==0),"trueMuonEnergy"].values/1000. mc_bins, mc_binedges = np.histogram(mc_energy,bins=15,range=(0,2)) mc_binlefts =mc_binedges[0:len(mc_binedges)-1] binwidth = (mc_binlefts[1]-mc_binlefts[0]) mc_binrights = mc_binlefts + binwidth mc_bincenters = mc_binlefts + (binwidth/2.) mc_bins_unc = np.sqrt(mc_bins) mc_bins_normed = mc_bins/np.sum(mc_bins) mc_bins_unc_normed = mc_bins_unc/np.sum(mc_bins) data_bins, data_binedges = np.histogram(VISIBLE_ENERGY,bins=15,range=(0,2)) data_binlefts =data_binedges[0:len(data_binedges)-1] binwidth = (data_binlefts[1]-data_binlefts[0]) data_bincenters = data_binlefts + (binwidth/2.) data_bins_unc = np.sqrt(data_bins) data_bins_normed = data_bins/np.sum(data_bins) data_bins_unc_normed = data_bins_unc/np.sum(data_bins) fig = plt.figure() ax = fig.add_subplot(1,1,1) ax = abp.NiceBins(ax,mc_binlefts,mc_binrights,mc_bins_normed,'dark blue',"$E_{\mu}$ MC truth") ax.errorbar(data_bincenters,data_bins_normed,xerr=binwidth/2., yerr=data_bins_unc_normed, color='black',linestyle='None',markersize=6,label='ANNIE beam data') #plt.hist(mc_energy,density=True,bins=20,range=(0,2),label='$E_{\mu}$ MC Truth') #plt.hist(VISIBLE_ENERGY,normed=True,bins=20,range=(0,2), label='Beam data') plt.xlabel("Visible energy estimate [GeV]") plt.ylabel("Normalized count rate (A.U.)") #plt.title("Visible energy of neutrino interaction candidates \n compared to MC truth information") plt.title("Visible energy of neutrino interaction candidates") leg = plt.legend(loc=1,fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() zerobins = np.where(data_bins_unc==0)[0] data_bins_unc_normed[zerobins] = 1.15/np.sum(data_bins) print("CHISQUARE: " + str(np.sum(((data_bins_normed-mc_bins_normed)/np.sqrt(data_bins_unc_normed**2 + mc_bins_unc_normed**2))**2))) print("NDOF: " + str(len(data_bins_normed))) plt.hist(Sdf_maxPE['clusterTime'].values[TankIndices_match],bins=80,range=(0,2000),label="PMT clusters w/ matched MRD") plt.hist(Sdf_NuCandidates['clusterTime'],bins=80,range=(0,2000),label="+ single track and no veto") plt.title("Prompt window Tank cluster times \n (Highest PE cluster in event)") plt.xlabel("Cluster time [ns]") plt.ylabel("Number of clusters") leg = plt.legend(loc=1,fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Last plots... Average delayed cluster multiplicity as a function of visible energy #Delayed cluster multiplicity for these candidates in a histogram NuEventClusters = es.FilterByEventTime(Sdf,Sdf_NuCandidates['eventTimeTank'].values) NuEventClusters_trig = es.FilterByEventTime(Sdf_trig,Sdf_NuCandidates['eventTimeTank'].values) NuEventDelayedClusters = NuEventClusters.loc[NuEventClusters['clusterTime']>12000].reset_index(drop=True) NuEventDelayedClusters = NuEventDelayedClusters.loc[NuEventDelayedClusters['clusterChargeBalance']<0.4].reset_index(drop=True) MData = abp.MakeClusterMultiplicityPlot(NuEventDelayedClusters,NuEventClusters_trig) plt.hist(MData,bins=6, range=(0,6), label="Beam data", alpha=0.5,histtype='stepfilled',linewidth=6,color='green') plt.hist(MData,bins=6, range=(0,6), label="Beam data", alpha=0.9,histtype='step',linewidth=6,color='green') Michael_NM = [64200, 26663, 7045, 4229, 3121, 2288, 1609, 1024, 258, 4] Michael_NMCounts = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Michael_NMX = np.array(Michael_NM)+0.5 #plt.errorbar(Michael_NMX, Michael_NM, xerr=0.5,color='black',label='GENIE MC') plt.xlabel("Neutron candidate multiplicity") plt.ylabel("Number of neutrino candidates") plt.title("Neutron candidate multiplicity for neutrino candidate events \n (CB<0.4, [12,67] $\mu s$ interval)") #leg = plt.legend(loc=1,fontsize=24) #leg.set_frame_on(True) #leg.draw_frame(True) plt.show() energy_min = 0 energy_max = 1.4 EnergyBins, ClusterMultiplicity,ClusterMultiplicity_unc = bp.EstimateEnergyPerClusterRelation(VISIBLE_ENERGY, NUC_EVENTTIMETANKS, NuEventDelayedClusters,energy_min,energy_max,8) errwidth = (EnergyBins[1] - EnergyBins[0])/2 plt.errorbar(EnergyBins+errwidth, ClusterMultiplicity,xerr=errwidth,yerr=ClusterMultiplicity_unc,linestyle='None',marker='o',markersize=10,color='green',alpha=0.8,linewidth=5) plt.xlabel("Visible energy [GeV]") plt.ylabel("Neutron candidates per event") plt.title("Mean number of neutron candidates per neutrino candidate") plt.show() Sdf_NuCandidates_Aggressive = Sdf_NuCandidates.loc[(Sdf_NuCandidates['clusterPE']>500)&(Sdf_NuCandidates['clusterPE']<3500)] theinds = Sdf_NuCandidates_Aggressive.index.values Sdf_NuCandidatesMRD_Aggressive = Sdf_NuCandidatesMRD.loc[theinds] NUC_PE_AGG = Sdf_NuCandidates_Aggressive['clusterPE'] NUC_EVENTTIMETANKS_AGG = Sdf_NuCandidates_Aggressive['eventTimeTank'].values NUC_TANKMEV_AGG = NUC_PE_AGG / PEPERMEV NUC_MRDENERGY_AGG = es.SingleTrackEnergies(Sdf_NuCandidatesMRD_Aggressive) VISIBLE_ENERGY_AGG = (NUC_TANKMEV_AGG + NUC_MRDENERGY_AGG)/1000 NuEventClusters_Agg = es.FilterByEventTime(Sdf,Sdf_NuCandidates_Aggressive['eventTimeTank'].values) NuEventDelayedClusters_Agg = NuEventClusters_Agg.loc[NuEventClusters_Agg['clusterTime']>12000].reset_index(drop=True) NuEventDelayedClusters_Agg = NuEventDelayedClusters_Agg.loc[NuEventDelayedClusters_Agg['clusterChargeBalance']<0.4].reset_index(drop=True) energy_min = 0 energy_max = 1.4 EnergyBins, ClusterMultiplicity,ClusterMultiplicity_unc = bp.EstimateEnergyPerClusterRelation(VISIBLE_ENERGY_AGG, NUC_EVENTTIMETANKS_AGG, NuEventDelayedClusters_Agg,energy_min,energy_max,8) errwidth = (EnergyBins[1] - EnergyBins[0])/2 plt.errorbar(EnergyBins+errwidth, ClusterMultiplicity,xerr=errwidth,yerr=ClusterMultiplicity_unc,linestyle='None',marker='o',markersize=10,color='green',alpha=0.8,linewidth=5) plt.xlabel("Visible energy [GeV]") plt.ylabel("Neutron candidates per event") plt.title("Mean number of neutron candidates per neutrino candidate \n (500 < Tank cluster PE < 3500)") plt.show() pe_min = 0 pe_max = 6000 PEBins, ClusterMultiplicity,ClusterMultiplicity_unc = bp.EstimatePEPerClusterRelation(NUC_PE, NUC_EVENTTIMETANKS, NuEventDelayedClusters,pe_min,pe_max,8) errwidth = (PEBins[1] - PEBins[0])/2 plt.errorbar(PEBins+errwidth, ClusterMultiplicity,xerr=errwidth,yerr=ClusterMultiplicity_unc,linestyle='None',marker='o',markersize=10,color='green',alpha=0.8,linewidth=5) plt.xlabel("Visible tank energy [p.e.]") plt.ylabel("Neutron candidates per event") plt.title("Mean number of neutron candidates per neutrino candidate") plt.show()
flist = glob.glob(SIGNAL_DIR+"*.ntuple.root") mybranches = ['eventNumber','eventTimeTank','clusterTime','clusterChargeBalance','SiPMNum','SiPMhitT','hitX','hitY','hitZ','hitT','hitQ','hitPE','hitDetID','SiPM1NPulses','SiPM2NPulses','clusterPE'] SProcessor = rp.ROOTProcessor(treename="phaseIITankClusterTree") for f1 in flist: SProcessor.addROOTFile(f1,branches_to_get=mybranches) Sdata = SProcessor.getProcessedData() Sdf = pd.DataFrame(Sdata) SProcessor = rp.ROOTProcessor(treename="phaseIITriggerTree") for f1 in flist: SProcessor.addROOTFile(f1,branches_to_get=mybranches) Sdata = SProcessor.getProcessedData() Sdf_trig = pd.DataFrame(Sdata) Sdf_SinglePulses = es.SingleSiPMPulses(Sdf) Sdf_CleanPrompt = es.NoPromptClusters(Sdf_SinglePulses,2000) Sdf_CleanWindow = es.NoBurstClusters(Sdf_CleanPrompt,2000,150) Sdf_LateWindow = Sdf_CleanWindow.loc[(Sdf_CleanWindow["clusterTime"]>2000)].reset_index(drop=True) Sdf_trig_goodSiPM = Sdf_trig.loc[(Sdf_trig['SiPM1NPulses']==1) & (Sdf_trig['SiPM2NPulses']==1)].reset_index(drop=True) Sdf_trig_CleanPrompt = es.NoPromptClusters_WholeFile(Sdf_SinglePulses,Sdf_trig_goodSiPM,2000) Sdf_trig_CleanWindow = es.NoBurst_WholeFile(Sdf_CleanPrompt,Sdf_trig_CleanPrompt,2000,150) Sdf_Mid = Sdf_SinglePulses.loc[(Sdf_SinglePulses["clusterChargeBalance"]>0.4)&(Sdf_SinglePulses["clusterChargeBalance"]<0.6)].reset_index(drop=True) Sdf_Lo = Sdf_SinglePulses.loc[(Sdf_SinglePulses["clusterChargeBalance"]<0.4)].reset_index(drop=True) enums = np.arange(10,20,1) for j in enums: hp.YVSTheta(Sdf_Lo,j,'hitT','Hit Times (ns)') hp.YVSTheta(Sdf_Lo,j,'hitPE','Hit PE count') hp.YVSTheta_Nhit(Sdf_Lo,j)
myMRDbranches = ['eventNumber','eventTimeTank','eventTimeMRD','clusterTime','clusterHits','vetoHit', 'numClusterTracks','MRDTrackAngle','MRDPenetrationDepth','MRDEntryPointRadius','MRDEnergyLoss','MRDEnergyLossError','MRDTrackLength'] MCbranches = ['trueMuonEnergy','Pi0Count','PiPlusCount','PiMinusCount'] mclist = ["./Data/V3_5PE100ns/MCProfiles/PMTVolumeReco_Full_06262019.ntuple.root"] #mybkgbranches = ['eventNumber','eventTimeTank','clusterTime','hitT','hitQ','hitPE','clusterChargeBalance','clusterPE','clusterMaxPE','clusterChargePointZ','SiPM1NPulses','SiPM2NPulses','clusterHits'] #mybkgtrigbranches = ['eventNumber','eventTimeTank','eventTimeMRD','vetoHit','SiPM1NPulses','SiPM2NPulses'] #blist = glob.glob(BKG_DIR+"*.ntuple.root") #Bdf = GetDataFrame("phaseIITankClusterTree",mybkgbranches,blist) #Bdf_trig = GetDataFrame("phaseIITriggerTree",mybranches,blist) MCdf = GetDataFrame("phaseII",MCbranches,mclist) PositionDict = {} for j,direc in enumerate(SIGNAL_DIRS): direcfiles = glob.glob(direc+"*.ntuple.root") livetime_estimate = es.EstimateLivetime(direcfiles) print("SIGNAL LIVETIME ESTIMATE IN SECONDS IS: " + str(livetime_estimate)) PositionDict[SIGNAL_LABELS[j]] = [] PositionDict[SIGNAL_LABELS[j]].append(GetDataFrame("phaseIITankClusterTree",mybranches,direcfiles)) PositionDict[SIGNAL_LABELS[j]].append(GetDataFrame("phaseIITriggerTree",mytrigbranches,direcfiles)) PositionDict[SIGNAL_LABELS[j]].append(GetDataFrame("phaseIIMRDClusterTree",myMRDbranches,direcfiles)) print("THE GOOD STUFF") BeamPlotDemo(PositionDict,MCdf) #EstimateNeutronEfficiencyAllPosns(PositionDict,Bdf,Bdf_trig)
def EstimateNeutronEfficiency(Sdf, Bdf, Sdf_trig, Bdf_trig): #First, apply event selection cuts to background data an dform background multiplicity model Bdf_SinglePulses = es.SingleSiPMPulses(Bdf) Bdf_CleanPrompt = es.NoPromptClusters(Bdf_SinglePulses, 2000) Bdf_BurstCut = es.NoBurstClusters(Bdf_CleanPrompt, BKG_WINDOW_START, 150) Bdf_latewindow = Bdf_BurstCut.loc[( Bdf_BurstCut['clusterTime'] > BKG_WINDOW_START)].reset_index(drop=True) Bdf_latewindow = Bdf_latewindow.loc[(Bdf_latewindow['clusterChargeBalance'] < 0.4)].reset_index(drop=True) Bdf_trig_cleanSiPM = Bdf_trig.loc[(Bdf_trig['SiPM1NPulses'] == 1) & ( Bdf_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) Bdf_trig_cleanPrompt = es.NoPromptClusters_WholeFile( Bdf_SinglePulses, Bdf_trig_cleanSiPM, 2000) Bdf_trig_BurstCut = es.NoBurst_WholeFile(Bdf_CleanPrompt, Bdf_trig_cleanPrompt, BKG_WINDOW_START, 150) MBData = abp.MakeClusterMultiplicityPlot(Bdf_latewindow, Bdf_trig_BurstCut) plt.hist(MBData, bins=20, range=(0, 20), alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(MBData, bins=20, range=(0, 20), histtype='step', linewidth=6) plt.xlabel("Delayed neutron candidate multiplicity") plt.ylabel("Number of acquisitions") plt.title( "Neutron candidate multiplicity, AmBe central background run \n (All preliminary cuts, [2,67] $\mu s$ window)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() print("MBData:" + str(MBData)) Bbins, Bbin_edges = np.histogram(MBData, range=(0, 5), bins=5) print("BINS AND EDGES") print(Bbins) print(Bbin_edges) Bbins_lefts = Bbin_edges[ 0:len(Bbin_edges) - 1] #Combine clusters of 19 and 20 at end... negligible effect Bbins_normed = Bbins / float(np.sum(Bbins)) Bbins_normed_unc = np.sqrt(Bbins) / float(np.sum(Bbins)) zero_bins = np.where(Bbins_normed_unc == 0)[0] Bbins_normed_unc[zero_bins] = 1.15 / float(np.sum(Bbins)) print("BBins_normed: " + str(Bbins_normed)) init_params = [1] popt, pcov = scp.curve_fit(mypoisson, Bbins_lefts, Bbins_normed, p0=init_params, maxfev=6000, sigma=Bbins_normed_unc) #init_params = [5000,0.04,100,1] #popt, pcov = scp.curve_fit(mypoissons, Bbins_lefts,Bbins_normed,p0=init_params, maxfev=6000,sigma=Bbins_normed_unc) print('BEST FIT POPTS: ' + str(popt)) myy = mypoisson(Bbins_lefts, popt[0]) myy_upper = mypoisson(Bbins_lefts, popt[0] + np.sqrt(pcov[0][0])) #myy = mypoissons(Bbins_lefts,popt[0],popt[1],popt[2],popt[3]) plt.errorbar(x=Bbins_lefts, y=Bbins_normed, yerr=Bbins_normed_unc, linestyle='None', marker='o', label='No source ($t>20 \, \mu s$)') plt.plot(Bbins_lefts, myy, marker='None', linewidth=6, label=r'Best poiss. fit $\mu= %s \pm %s$' % (str(np.round(popt[0], 2)), str(np.round(np.sqrt(pcov[0]), 2))), color='black') plt.plot(Bbins_lefts, myy_upper, marker='None', linewidth=6, label=r'Best poiss. fit upper bound', color='gray') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Now, apply same event selection cuts to background data and form background multiplicity model Sdf_SinglePulses = es.SingleSiPMPulses(Sdf) Sdf_CleanPrompt = es.NoPromptClusters(Sdf_SinglePulses, SIGNAL_WINDOW_START) Sdf_CleanWindow = es.NoBurstClusters(Sdf_CleanPrompt, SIGNAL_WINDOW_START, 150) Sdf_CleanWindow_noCB = Sdf_CleanWindow.loc[ Sdf_CleanWindow["clusterChargeBalance"] < 0.4].reset_index(drop=True) Sdf_trig_SinglePulses = Sdf_trig.loc[(Sdf_trig['SiPM1NPulses'] == 1) & ( Sdf_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) Sdf_trig_CleanPrompt = es.NoPromptClusters_WholeFile( Sdf_SinglePulses, Sdf_trig_SinglePulses, 2000) Sdf_trig_CleanWindow = es.NoBurst_WholeFile(Sdf_CleanPrompt, Sdf_trig_CleanPrompt, 2000, 150) MSData = abp.MakeClusterMultiplicityPlot(Sdf_CleanWindow_noCB, Sdf_trig_CleanWindow) plt.hist(MSData, bins=20, range=(0, 20), alpha=0.2, histtype='stepfilled', linewidth=6) plt.hist(MSData, bins=20, range=(0, 20), histtype='step', linewidth=6) plt.xlabel("Neutron candidate multiplicity") plt.ylabel("Number of acquisitions") plt.title( "Neutron candidate multiplicity, AmBe central source run \n (All preliminary cuts, [2,67] $\mu s$ window)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() Sbins, Sbin_edges = np.histogram(MSData, range=(0, 5), bins=5) print("SIGNAL BINS AND EDGES") print(Sbins) print(Sbin_edges) Sbins_lefts = Sbin_edges[ 0:len(Bbin_edges) - 1] #Combine clusters of 19 and 20 at end... negligible effect Sbins_normed = Sbins / float(np.sum(Sbins)) Sbins_normed_unc = np.sqrt(Sbins) / float(np.sum(Sbins)) zero_bins = np.where(Sbins_normed_unc == 0)[0] Sbins_normed_unc[zero_bins] = 1.15 / float(np.sum(Sbins)) plt.errorbar(x=Sbins_lefts, y=Sbins_normed, yerr=Sbins_normed_unc, linestyle='None', marker='o', label='Source ($t>2 \, \mu s$)', markersize=12) plt.errorbar(x=Bbins_lefts, y=Bbins_normed, yerr=Bbins_normed_unc, linestyle='None', marker='o', label='No source ($t>20 \, \mu s$)', markersize=12) plt.plot(Bbins_lefts, myy, marker='None', linewidth=6, label=r'Best poiss. fit $\mu= %s \pm %s$' % (str(np.round(popt[0], 2)), str(np.round(np.sqrt(pcov[0]), 2))), color='black') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Find best-fit assuming data-driven background model PLBuilder = plb.ProfileLikelihoodBuilder() BkgScaleFactor = (67000 - SIGNAL_WINDOW_START) / ( 67000 - BKG_WINDOW_START) #Scale mean neutrons per window up by this PLBuilder.SetBkgMean(BkgScaleFactor * popt[0]) PLBuilder.SetBkgMeanUnc(np.sqrt(pcov[0][0])) NeutronProbProfile = EffRanges[POSITION_TO_ANALYZE] #TODO: Also return the multiplicity array to make a histogram ChiSquare, lowestChiSqProfile = PLBuilder.BuildLikelihoodProfile( NeutronProbProfile, Sbins_normed, Sbins_normed_unc, NUMTHROWS, Bbins_normed, Bbins_normed_unc) print("MINIMUM CHI SQUARE: " + str(np.min(ChiSquare))) ChiSquare_normed = ChiSquare / np.min(ChiSquare) plt.errorbar(x=Sbins_lefts + 0.5, y=Sbins_normed, yerr=Sbins_normed_unc, linestyle='None', marker='o', label='Source ($t>2 \, \mu s$)', markersize=12) #TODO: replace this with the multiplicity histogram returned above plt.plot(Sbins_lefts + 0.5, lowestChiSqProfile, linestyle='None', marker='o', label='Data-driven best fit', markersize=12, color='blue') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title("Best fit model profiles to central AmBe source data") plt.xlabel("Delayed cluster multiplicity") plt.show() plt.plot(NeutronProbProfile, ChiSquare_normed, marker='None', linewidth=6, label='Data-driven model', color='red') plt.title( "Normalized Chi-square test parameter \n as a function of neutron detection efficiency" ) plt.xlabel("Neutron detection efficiency $\epsilon_{n}$") plt.ylabel("$\chi^{2}$/$\chi^{2}_{min}$") leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() plt.plot(NeutronProbProfile, ChiSquare - np.min(ChiSquare), marker='None', linewidth=6, label='Data-driven model', color='red') plt.title( "Chi-square test parameter \n as a function of neutron detection efficiency" ) plt.xlabel("Neutron detection efficiency $\epsilon_{n}$") plt.ylabel("$\chi^{2} - \chi^{2}_{min}$") leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Find best-fit assuming uncorrelated background model PLBuilder2D = plb.ProfileLikelihoodBuilder2D() neutron_efficiencies = EffRanges[POSITION_TO_ANALYZE] background_mean = BkgRanges[POSITION_TO_ANALYZE] PLBuilder2D.SetEffProfile(neutron_efficiencies) PLBuilder2D.SetBkgMeanProfile(background_mean) x_var, y_var, ChiSquare, lowestChiSqProfileUncorr = PLBuilder2D.BuildLikelihoodProfile( Sbins_normed, Sbins_normed_unc, NUMTHROWS) print("MINIMUM CHI SQUARE: " + str(np.min(ChiSquare))) plt.errorbar(x=Sbins_lefts, y=Sbins_normed, yerr=Sbins_normed_unc, linestyle='None', marker='o', label='Source ($t>2 \, \mu s$)', markersize=12) plt.plot(Sbins_lefts, lowestChiSqProfileUncorr, linestyle='None', marker='o', label='Best fit model profile', markersize=12) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title("Best fit MC profile relative to central source data") plt.xlabel("Delayed cluster multiplicity") plt.show() #Look at 2D chi-squared map chisq_map = pd.DataFrame({ "Neutron detection efficiency": np.round(x_var, 3), "Background rate [candidates/trigger]": np.round(y_var, 3), "ChiSq": ChiSquare / np.min(ChiSquare) }) cmap = chisq_map.pivot(index="Neutron detection efficiency", columns="Background rate [candidates/trigger]", values="ChiSq") ax = sns.heatmap(cmap, vmin=1, vmax=10) plt.title("$\chi^{2}$/$\chi_{min}^{2}$ for profile likelihood parameters") plt.show() chisq_map = pd.DataFrame({ "Neutron detection efficiency": np.round(x_var, 3), "Background rate [candidates/trigger]": np.round(y_var, 3), "ChiSq": ChiSquare - np.min(ChiSquare) }) cmap = chisq_map.pivot(index="Neutron detection efficiency", columns="Background rate [candidates/trigger]", values="ChiSq") ax = sns.heatmap(cmap, vmin=0, vmax=80) plt.title("$\chi^{2} - \chi_{min}^{2}$ for profile likelihood parameters") plt.show() LowestInd = np.where(ChiSquare == np.min(ChiSquare))[0] best_eff = x_var[LowestInd] best_mean = y_var[LowestInd] best_eff_chisquareinds = np.where(x_var == best_eff)[0] best_eff_chisquares = ChiSquare[best_eff_chisquareinds] best_eff_bkgmeans = y_var[best_eff_chisquareinds] plt.plot(best_eff_bkgmeans, best_eff_chisquares / np.min(ChiSquare), marker='None', linewidth=6, label='Uncorr. bkg. model', color='blue') plt.title( "Normalized Chi-square test parameter as $\lambda_{n}$ varies \n (best-fit detection efficiency $\epsilon_{n}$ fixed)" ) plt.xlabel("Background mean $\lambda_{n}$ [clusters/trigger]") plt.ylabel("$\chi^{2}$/$\chi^{2}_{min}$") leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() plt.plot(best_eff_bkgmeans, best_eff_chisquares - np.min(ChiSquare), marker='None', linewidth=6, label='Uncorr. bkg. model', color='blue') plt.title( "Normalized Chi-square test parameter as $\lambda_{n}$ varies \n (best-fit detection efficiency $\epsilon_{n}$ fixed)" ) plt.xlabel("Background mean $\lambda_{n}$ [clusters/trigger]") plt.ylabel("$\chi^{2} - \chi^{2}_{min}$") leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() best_mean_chisquareinds = np.where(y_var == best_mean)[0] best_mean_chisquares = ChiSquare[best_mean_chisquareinds] best_mean_efficiencypro = x_var[best_mean_chisquareinds] plt.plot(best_mean_efficiencypro, best_mean_chisquares / np.min(ChiSquare), marker='None', linewidth=6, label='Uncorr. bkg. model', color='blue') plt.title( "Normalized Chi-square test parameter as $\epsilon_{n}$ varies \n (best-fit background rate $\lambda_{n}$ fixed)" ) plt.xlabel("Neutron detection efficiency $\epsilon_{n}$") plt.ylabel("$\chi^{2}$/$\chi^{2}_{min}$") leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() plt.plot(best_mean_efficiencypro, best_mean_chisquares - np.min(ChiSquare), marker='None', linewidth=6, label='Uncorr. bkg. model', color='blue') plt.title( "Normalized Chi-square test parameter as $\epsilon_{n}$ varies \n (best-fit background rate $\lambda_{n}$ fixed)" ) plt.xlabel("Neutron detection efficiency $\epsilon_{n}$") plt.ylabel("$\chi^{2} - \chi^{2}_{min}$") leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() #Compare the two model fits to the signal data fig = plt.figure() ax = fig.add_subplot(1, 1, 1) bin_rights = Sbins_lefts + (Sbins_lefts[1] - Sbins_lefts[0]) ax = abp.NiceBins(ax, Sbins_lefts, bin_rights, lowestChiSqProfileUncorr, 'dark blue', "Uncorr. bkg. best fit") ax = abp.NiceBins(ax, Sbins_lefts, bin_rights, lowestChiSqProfile, 'dark red', "Data-driven bkg. best fit") ax.errorbar(x=Sbins_lefts + 0.5, y=Sbins_normed, yerr=Sbins_normed_unc, linestyle='None', marker='o', label='AmBe data', markersize=12, color='black') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title("Best fit multiplicity distributions to central source data") plt.xlabel("Neutron candidate multiplicity") plt.show()
def EstimateDarkRates(Sdf, Sdf_trig): #Sdf_NoClusterWindow = es.NoBurstClusters(Sdf_CleanPrompt,0,5) Sdf_trig_NoClusterWindow = es.NoBurst_WholeFile(Sdf, Sdf_trig, 0, 5) print("SIZE OF DATAFRAME BEFORE BURST CUT: " + str(len(Sdf_trig))) print("SIZE OF DATAFRAME AFTER BURST CUT: " + str(len(Sdf_trig_NoClusterWindow))) All_PE = np.hstack(Sdf_trig_NoClusterWindow['hitPE']) All_T = np.hstack(Sdf_trig_NoClusterWindow['hitT']) All_ID = np.hstack(Sdf_trig_NoClusterWindow['hitDetID']) plt.hist(Sdf["clusterPE"], bins=200, range=(0, 50)) plt.title("cluster PE distribution \n (All acquisitions in tank)") plt.xlabel("Hit PE") plt.show() plt.hist(All_PE, bins=200, range=(0, 50)) plt.title( "PE distribution for all PMT hits \n (AmBe background run 1718, housing in dark box)" ) plt.ylabel("Number of hits") plt.xlabel("Hit PE") plt.show() plt.hist(All_T, bins=350, range=(0, 70000)) plt.title( "Hit time distribution for all PMT hits \n (AmBe background run 1718, housing in dark box)" ) plt.ylabel("Number of hits") plt.xlabel("Hit time (ns)") plt.show() #Still some prompt activity in window; let's only use the last 50 microseconds latewin = np.where((All_T > 20000) & (All_T < 70000))[0] late_PE = All_PE[latewin] late_T = All_T[latewin] late_ID = All_ID[latewin] IDSet = set(late_ID) Acquisition_Time = (50E-6 * len(Sdf_trig_NoClusterWindow)) print("ACQUISITION TIME IN LATE WINDOW ESTIMATE IS: " + str(Acquisition_Time)) hit_counts = [] dark_rate = [] print("ALL HIT IDS SEEN: " + str(IDSet)) for theid in IDSet: IDhits = np.where(late_ID == theid)[0] IDnumhits = len(late_ID[IDhits]) hit_counts.append(IDnumhits) dark_rate.append(IDnumhits / Acquisition_Time) hit_counts = np.array(hit_counts) dark_rates = np.array(dark_rate) plt.hist(hit_counts, bins=30, histtype='stepfilled', range=(0, 10000), linewidth=6) #plt.hist(hit_counts,bins=30,alpha=0.75,histtype='step',range=(0,10000),linewidth=6) plt.title( "Total number of hits for each PMT \n (All PMT hits with $t_{hit}>20 \, \mu s$)" ) plt.xlabel("Number of hits") plt.show() plt.hist(dark_rate, bins=30, histtype='stepfilled', range=(0, 30000)) #plt.hist(dark_rate,bins=30,alpha=0.75,histtype='step',range=(0,30000)) plt.title( "Total number of hits for each PMT \n (All PMT hits with $t_{hit}>20 \, \mu s$)" ) plt.xlabel("Dark count rate (Hz)") plt.ylabel("Number of PMTs") plt.show() wm_hit_counts = [] wm_dark_rate = [] WM_IDs = [382, 393, 404] print("ALL HIT IDS SEEN: " + str(WM_IDs)) for theid in WM_IDs: IDhits = np.where(late_ID == theid)[0] IDnumhits = len(late_ID[IDhits]) wm_hit_counts.append(IDnumhits) wm_dark_rate.append(IDnumhits / Acquisition_Time) plt.hist(wm_hit_counts, bins=30, histtype='stepfilled', range=(0, 10000), linewidth=6) #plt.hist(hit_counts,bins=30,alpha=0.75,histtype='step',range=(0,10000),linewidth=6) plt.title( "Total number of hits for WATCHMAN tubes \n (All PMT hits with $t_{hit}>20 \, \mu s$)" ) plt.xlabel("Number of hits") plt.show() plt.hist(wm_dark_rate, bins=30, histtype='stepfilled', range=(0, 30000)) #plt.hist(dark_rate,bins=30,alpha=0.75,histtype='step',range=(0,30000)) plt.title( "Total number of hits for WATCHMAN tubes \n (All PMT hits with $t_{hit}>20 \, \mu s$)" ) plt.xlabel("Dark count rate (Hz)") plt.ylabel("Number of PMTs") plt.show()
def BeamPlotDemo(PositionDict, MCdf): Sdf = PositionDict["Beam"][0] Sdf_trig = PositionDict["Beam"][1] Sdf_mrd = PositionDict["Beam"][2] print("Sdf ", Sdf.head()) print("All columns are: ", Sdf.columns.values.tolist()) Sdf = Sdf.loc[Sdf["eventTimeTank"] > -9].reset_index(drop=True) Sdf_trig = Sdf_trig.loc[Sdf_trig["eventTimeTank"] > -9].reset_index( drop=True) Sdf_mrd = Sdf_mrd.loc[Sdf_mrd["eventTimeTank"] > -9].reset_index(drop=True) Sdf_TankVeto = es.HasVetoHit_TankClusters(Sdf, Sdf_trig) print("NUM TANK CLUSTERS WITH VETO HIT: " + str(len(Sdf_TankVeto))) print("NUM TRIGS: " + str(len(Sdf_trig))) HasVetoHit = np.where(Sdf_mrd["vetoHit"].values == 1)[0] print("NUM MRD CLUSTERS WITH VETO HIT: " + str(len(HasVetoHit))) #---- My Plots: Sdf_prompt = Sdf.loc[Sdf['clusterTime'] < 2000].reset_index( drop=True) #prompt events plt.hist(Sdf_prompt['clusterTime'], bins=100, range=(0, 2000)) plt.title("Prompt window Tank cluster times - no cuts") plt.xlabel("Cluster time [ns]") plt.show() # plt.savefig("plots/time_prompt.png") Sdf_del = Sdf.loc[Sdf['clusterTime'] >= 2000].reset_index( drop=True) #delayed events plt.hist(Sdf_del['clusterTime']) #,bins=100,range=(10000,70000)) plt.title("Delayed window Tank cluster times - no cuts") plt.xlabel("Cluster time [ns]") plt.show() # plt.savefig("plots/time_del.png") #--- CB to cluster Time: labels = { 'title': 'Charge balance parameters in time window \n (Beam data, $t_{c}>=2 \, \mu s$)', 'xlabel': 'Cluster time (ns)', 'ylabel': 'Charge balance' } ranges = { 'xbins': 58, 'ybins': 50, 'xrange': [2000, 60000], 'yrange': [0, 1] } abp.Make2DHist(Sdf_del, 'clusterTime', 'clusterChargeBalance', labels, ranges) plt.show() # plt.savefig("plots/CB_time_del.png") labels = { 'title': 'Charge balance parameters in time window \n (Beam data, $t_{c}<2 \, \mu s$)', 'xlabel': 'Cluster time (ns)', 'ylabel': 'Charge balance' } ranges = {'xbins': 20, 'ybins': 50, 'xrange': [0, 2000], 'yrange': [0, 1]} abp.Make2DHist(Sdf_prompt, 'clusterTime', 'clusterChargeBalance', labels, ranges) plt.show() # plt.savefig("plots/CB_time_prompt.png") #--- CB to clusterPE: labels = { 'title': 'Charge balance parameters in time window \n (Beam data, $t_{c}>=2 \, \mu s$)', 'xlabel': 'Cluster PE', 'ylabel': 'Charge balance' } ranges = {'xbins': 58, 'ybins': 50, 'xrange': [0, 500], 'yrange': [0, 1]} abp.Make2DHist(Sdf_del, 'clusterPE', 'clusterChargeBalance', labels, ranges) plt.show() # plt.savefig("plots/CB_PE_del.png") labels = { 'title': 'Charge balance parameters in time window \n (Beam data, $t_{c}<2 \, \mu s$)', 'xlabel': 'Cluster PE', 'ylabel': 'Charge balance' } ranges = {'xbins': 20, 'ybins': 50, 'xrange': [0, 500], 'yrange': [0, 1]} abp.Make2DHist(Sdf_prompt, 'clusterPE', 'clusterChargeBalance', labels, ranges) plt.show() # plt.savefig("plots/CB_PE_prompt.png") #splitting to CB categories: #--- CB>=0.9 Sdf_prompt_highCB = Sdf_prompt.loc[ Sdf_prompt['clusterChargeBalance'] >= 0.9].reset_index(drop=True) Sdf_del_highCB = Sdf_del.loc[ Sdf_del['clusterChargeBalance'] >= 0.9].reset_index(drop=True) labels = { 'title': 'Total PE vs Maximum PE in Cluster for \n (Beam data, $t_{c}<2 \, \mu s$) \n CB>=0.9 ', 'xlabel': 'Cluster PE', 'ylabel': 'Maximum PE in Cluster' } ranges = { 'xbins': 200, 'ybins': 200, 'xrange': [0, 200], 'yrange': [0, 200] } #abp.Make2DHist(Sdf_prompt_highCB,'clusterPE','clusterMaxPE',labels,ranges) abp.Make2DHist(Sdf_prompt_highCB, 'clusterPE', 'clusterMaxPE', labels, ranges) plt.show() # plt.savefig("plots/PE_maxPE_prompt_highCB.png") #PE = np.hstack(Sdf_del_highCB['hitPE']) #ID = np.hstack(Sdf_del_highCB['hitDetID']) #T = np.hstack(Sdf_del_highCB['hitT']) #maxPE_highCB = max(np.hstack(Sdf_prompt_highCB.hitPE)) #print("maxPE_highCB ",maxPE_highCB," clusterMaxPE ",Sdf_prompt_highCB.clusterMaxPE) highCB_PE = np.hstack(Sdf_prompt_highCB.hitPE) highCB_DetID = np.hstack(Sdf_prompt_highCB.hitDetID) # highCB_PE = np.hstack(Sdf_del_highCB.hitPE) # highCB_DetID = np.hstack(Sdf_del_highCB.hitDetID) plt.hist2d(highCB_DetID, highCB_PE) plt.title("PE distribution for all hits in clusters, CB>=0.9)") plt.xlabel("Tube ID") plt.ylabel("PE") plt.show() # plt.savefig("plots/TubeID_PE_prompt_highCB.png") #--- 0.6<CB<0.9 Sdf_prompt_upperCB = Sdf_prompt.loc[ (Sdf_prompt['clusterChargeBalance'] < 0.9) & (Sdf_prompt['clusterChargeBalance'] >= 0.6)].reset_index(drop=True) Sdf_del_upperCB = Sdf_del.loc[(Sdf_del['clusterChargeBalance'] < 0.9) & ( Sdf_prompt['clusterChargeBalance'] >= 0.6)].reset_index(drop=True) labels = { 'title': 'Total PE vs Maximum PE in Cluster for \n (Beam data, $t_{c}<2 \, \mu s$) \n 0.6<=CB<0.9', 'xlabel': 'Cluster PE', 'ylabel': 'Maximum PE in Cluster' } ranges = { 'xbins': 200, 'ybins': 200, 'xrange': [0, 200], 'yrange': [0, 200] } abp.Make2DHist(Sdf_prompt_upperCB, 'clusterPE', 'clusterMaxPE', labels, ranges) plt.show() # plt.savefig("plots/PE_maxPE_prompt_upperCB.png") upperCB_PE = np.hstack(Sdf_prompt_upperCB.hitPE) upperCB_DetID = np.hstack(Sdf_prompt_upperCB.hitDetID) plt.hist2d(upperCB_DetID, upperCB_PE) plt.title("PE distribution for all hits in clusters, 0.6=<CB<0.9)") plt.xlabel("Tube ID") plt.ylabel("PE") plt.show() # plt.savefig("plots/TubeID_PE_prompt_upperCB.png") #--- 0.4<CB<0.6 Sdf_prompt_midCB = Sdf_prompt.loc[ (Sdf_prompt['clusterChargeBalance'] < 0.6) & (Sdf_prompt['clusterChargeBalance'] >= 0.4)].reset_index(drop=True) Sdf_del_midCB = Sdf_del.loc[(Sdf_del['clusterChargeBalance'] < 0.6) & ( Sdf_prompt['clusterChargeBalance'] >= 0.4)].reset_index(drop=True) labels = { 'title': 'Total PE vs Maximum PE in Cluster for \n (Beam data, $t_{c}<2 \, \mu s$)\n 0.4<=CB<0.6', 'xlabel': 'Cluster PE', 'ylabel': 'Maximum PE in Cluster' } ranges = { 'xbins': 200, 'ybins': 200, 'xrange': [0, 200], 'yrange': [0, 200] } abp.Make2DHist(Sdf_prompt_midCB, 'clusterPE', 'clusterMaxPE', labels, ranges) plt.show() # plt.savefig("plots/PE_maxPE_prompt_midCB.png") midCB_PE = np.hstack(Sdf_prompt_midCB.hitPE) midCB_DetID = np.hstack(Sdf_prompt_midCB.hitDetID) plt.hist2d(midCB_DetID, midCB_PE) plt.title("PE distribution for all hits in clusters, 0.4=<CB<0.6)") plt.xlabel("Tube ID") plt.ylabel("PE") plt.show() # plt.savefig("plots/TubeID_PE_prompt_midCB.png") #--- CB<0.4 Sdf_prompt_lowCB = Sdf_prompt.loc[ Sdf_prompt['clusterChargeBalance'] < 0.4].reset_index(drop=True) Sdf_del_lowCB = Sdf_del.loc[ Sdf_del['clusterChargeBalance'] < 0.4].reset_index(drop=True) labels = { 'title': 'Total PE vs Maximum PE in Cluster for \n (Beam data, $t_{c}<2 \, \mu s$) \n CB<0.4', 'xlabel': 'Cluster PE', 'ylabel': 'Maximum PE in Cluster' } ranges = { 'xbins': 200, 'ybins': 200, 'xrange': [0, 200], 'yrange': [0, 200] } abp.Make2DHist(Sdf_prompt_lowCB, 'clusterPE', 'clusterMaxPE', labels, ranges) plt.show() # plt.savefig("plots/PE_maxPE_prompt_lowCB.png") lowCB_PE = np.hstack(Sdf_prompt_lowCB.hitPE) lowCB_DetID = np.hstack(Sdf_prompt_lowCB.hitDetID) plt.hist2d(lowCB_DetID, lowCB_PE) plt.title("PE distribution for all hits in clusters, CB<=0.4)") plt.xlabel("Tube ID") plt.ylabel("PE") plt.show()
def PlotDemo(Sdf, Bdf, Sdf_trig, Bdf_trig): Sdf_SinglePulses = es.SingleSiPMPulses(Sdf) Sdf_CleanPrompt = es.NoPromptClusters(Sdf_SinglePulses, 2000) Sdf_CleanWindow = es.NoBurstClusters(Sdf_CleanPrompt, 2000, 150) Sdf_CleanWindow_CBClean = Sdf_CleanWindow.loc[ Sdf_CleanWindow['clusterChargeBalance'] < 0.4] Sdf_trig_goodSiPM = Sdf_trig.loc[(Sdf_trig['SiPM1NPulses'] == 1) & ( Sdf_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) Sdf_trig_CleanPrompt = es.NoPromptClusters_WholeFile( Sdf_SinglePulses, Sdf_trig_goodSiPM, 2000) Sdf_trig_CleanWindow = es.NoBurst_WholeFile(Sdf_CleanPrompt, Sdf_trig_CleanPrompt, 2000, 150) #Line of cuts applied to background clusters Bdf_SinglePulses = es.SingleSiPMPulses(Bdf) Bdf_CleanPrompt = es.NoPromptClusters(Bdf_SinglePulses, 2000) Bdf_CleanWindow = es.NoBurstClusters(Bdf_CleanPrompt, 2000, 150) Bdf_latewindow = Bdf_CleanWindow.loc[(Bdf_CleanWindow['clusterTime'] > 2000)].reset_index(drop=True) Bdf_latewindow = Bdf_latewindow.loc[(Bdf_latewindow['clusterChargeBalance'] < 0.4)].reset_index(drop=True) Bdf_trig_cleanSiPM = Bdf_trig.loc[(Bdf_trig['SiPM1NPulses'] == 1) & ( Bdf_trig['SiPM2NPulses'] == 1)].reset_index(drop=True) Bdf_trig_cleanPrompt = es.NoPromptClusters_WholeFile( Bdf_SinglePulses, Bdf_trig_cleanSiPM, 2000) Bdf_trig_BurstCut = es.NoBurst_WholeFile(Bdf_CleanPrompt, Bdf_trig_cleanPrompt, 2000, 150) #Special case Bdf_NoBurstLateWindow = es.NoBurstClusters(Bdf_SinglePulses, 12000, 150) Bdf_NBlatewindow = Bdf_NoBurstLateWindow.loc[( Bdf_NoBurstLateWindow['clusterTime'] > 12000)].reset_index(drop=True) Bdf_NBCBCut = Bdf_NBlatewindow.loc[ Bdf_NBlatewindow['clusterChargeBalance'] < 0.4].reset_index(drop=True) #Now, we've gotta get the total PE observed around the SiPM pulses df = Sdf_trig_goodSiPM SiPMTimeThreshold = 100 TotalPE = [] for j in df.index.values: #disgusting... if df["SiPM1NPulses"][j] != 1 or df["SiPM2NPulses"][j] != 1: continue elif abs(df["SiPMhitT"][j][0] - df["SiPMhitT"][j][1]) > SiPMTimeThreshold: continue SiPMMeanTime = (df["SiPMhitT"][j][0] + df["SiPMhitT"][j][1]) / 2. clusterHitInds = np.where(( (SiPMMeanTime - np.array(df["hitT"][j])) < 0) & ( (SiPMMeanTime - np.array(df["hitT"][j])) > -600))[0] clusterHits = np.array(df["hitPE"][j])[clusterHitInds] clusterPE = np.sum(clusterHits) TotalPE.append(clusterPE) TotalPE = np.array(TotalPE) TotalPE_neut = np.where(TotalPE < 200)[0] TotalPE = TotalPE[TotalPE_neut] plt.hist(TotalPE, bins=200, label="Source", alpha=0.7) plt.xlabel("False start candidate PE") plt.title("Manual cluster-finding PE neighboring SiPM pulses \n " + r"(One pulse each SiPM, $-600<\mu_{SiPM} - t_{PMT}<0$)") leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() print("AFTER MANUAL FINDING STUFF") #Get prompt clusters within a 100 ns window of the mean SiPM single pulse time Sdf_SPPrompt = es.SiPMCorrelatedPrompts(Sdf_SinglePulses, 100, 1000, 2000) print("NUMBER OF PROMPT CLUSTERS PASSING SINGLE SIPM PULSE CUTS: " + str(len(Sdf_SinglePulses.eventTimeTank))) #Sdf_SPPrompt = Sdf_SPPrompt.loc[Sdf_SPPrompt['clusterChargeBalance']<0.4].reset_index(drop=True) plt.hist(TotalPE, bins=200, range=(0, 200), label="Source, all hits near SiPM", alpha=0.8, histtype='step', color='blue', linewidth=6) plt.hist(np.hstack(Sdf_SPPrompt['clusterPE']), bins=200, range=(0, 200), alpha=0.75, histtype='step', linewidth=6, color='green', label='Source, TA clusters') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title( "Comparison of FS candidate cluster PE \n using manual clustering and ToolAnalysis clustering" ) plt.xlabel("Cluster PE") plt.show() #plt.hist(TotalPE,bins=200,range=(0,200),label="Source, all hits near SiPM",alpha=0.8,histtype='step',color='blue',linewidth=6) plt.hist(TotalPE, bins=200, range=(0, 200), alpha=0.8, histtype='step', color='blue', linewidth=6) plt.hist(TotalPE, bins=200, range=(0, 200), alpha=0.5, histtype='stepfilled', color='blue', linewidth=6) #plt.hist(np.hstack(Sdf_SPPrompt['clusterPE']),bins=200,range=(0,200),alpha=0.75,histtype='step',linewidth=6,color='green',label='Source, TA clusters') #leg = plt.legend(loc=1,fontsize=24) #leg.set_frame_on(True) #leg.draw_frame(True) #plt.title("Comparison of FS candidate cluster PE \n using manual clustering and ToolAnalysis clustering") plt.title( "SiPM-correlated tank PE for position 0 AmBe source data \n (Sum of all PMT hits within 300 ns of SiPM pulses)" ) plt.ylabel("Number of acquisitions") plt.xlabel("Total PE") plt.show() Sdf_SPPrompt_trig = es.SiPMCorrelatedPrompts_WholeFile( Sdf_SPPrompt, Sdf_trig) print("NUMBER OF PROMPT CLUSTERS PASSING CORRELATED PROMPT CUTS: " + str(len(Sdf_SPPrompt.eventTimeTank))) print("NUMBER OF TRIGS WITH AT LEAST ONE CORRELATED PROMPT: " + str(len(Sdf_SPPrompt_trig.eventTimeTank))) MSData = abp.MakeClusterMultiplicityPlot(Sdf_SPPrompt, Sdf_SPPrompt_trig) #s_bins, s_edges = np.histogram(MSData,bins=20, range=(0,20)) #plt.hist(MSData,bins=20, range=(0,20), label="Source",alpha=0.7) plt.hist(MSData, bins=100, label="Source", alpha=0.7) plt.xlabel("False start candidate cluster multiplicity") plt.title( "Cluster multiplicity of false starts in source data \n (One pulse each SiPM, cluster within prompt window)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() S1Delta, S2Delta = abp.SiPMClusterDifferences(Sdf_SPPrompt, 100) plt.hist(S1Delta, bins=100, label="S1Time-clusterTime", alpha=0.7) plt.hist(S2Delta, bins=100, label="S2Time-clusterTime", alpha=0.7) plt.xlabel("SiPM time - Cluster time (ns)") plt.title( "Difference between SiPM peak time and cluster time \n (One pulse each SiPM, cluster within prompt window)" ) leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.show() Sdf_SPPromptLoPE = Sdf_SPPrompt.loc[ Sdf_SPPrompt['clusterPE'] < 80].reset_index(drop=True) print( "NUMBER OF PROMPT CLUSTERS PASSING CORRELATED PROMPT CUTS LT 80 PE: " + str(len(Sdf_SPPromptLoPE.eventTimeTank))) NumTrigs = len(set(Sdf_SPPromptLoPE.eventNumber)) print( "NUMBER OF TRIGS WITH A PASSING CORRELATED PROMPT CUTS CLUSTER LT 80 PE: " + str(NumTrigs)) labels = { 'title': 'Comparison of cluster PE to total SiPM Charge \n (Position 0, AmBe source installed)', 'xlabel': 'Cluster PE', 'ylabel': 'Total SiPM charge [nC]' } ranges = { 'xbins': 30, 'ybins': 40, 'xrange': [0, 60], 'yrange': [0, 0.5], 'promptTime': 2000 } #abp.MakeHexJointPlot(Sdf,'clusterPE','clusterChargeBalance',labels,ranges) abp.Make2DHist_PEVsQ(Sdf_SPPrompt, labels, ranges) plt.show() plt.hist(np.hstack(Sdf_SPPrompt['clusterPE']), bins=30, range=(0, 80), alpha=0.5, histtype='stepfilled', linewidth=6) plt.hist(np.hstack(Sdf_SPPrompt['clusterPE']), bins=30, range=(0, 80), alpha=0.75, histtype='step', linewidth=6, color='green') leg = plt.legend(loc=1, fontsize=24) leg.set_frame_on(True) leg.draw_frame(True) plt.title( "False start candidate PE distribution (AmBe central source data)") plt.xlabel("Cluster PE") plt.show()