Exemplo n.º 1
0
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']))))
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
    #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)
Exemplo n.º 5
0
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()
Exemplo n.º 6
0
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()
Exemplo n.º 7
0
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()
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
    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()
Exemplo n.º 11
0
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()
Exemplo n.º 12
0
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()
Exemplo n.º 13
0
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()