Esempio 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']))))
Esempio n. 2
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)
Esempio n. 3
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()
Esempio n. 4
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()
Esempio n. 5
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)
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()
Esempio n. 7
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()