def readSignal(inRoot, outText, freq=1000):
    sp1 = SignalProcessor()
    sp1.nSamples = 16384
    sp1.nAdcCh = 20
    sp1.fltParam.clear()
    for x in [50, 150, 200, -1.]:
        sp1.fltParam.push_back(x)

    n1 = int(1 / (0.2 * freq * 0.000001))
    sp1.sRanges.clear()
    ip = 0
    dn = 2500 % n1  ## 2500 is the expected position of the signal
    #     while ip+dn < sp1.nSamples:
    #         sp1.sRanges.push_back((ip, min(ip+n1, sp1.nSamples)))
    #         ip += n1

    sp1.sRanges.push_back((0, 400))
    #     while ip+n1<sp1.nSamples:
    #         sp1.sRanges.push_back((ip, ip+n1))
    #         ip += n1

    data1 = array('f', [0] * (sp1.nSamples * sp1.nAdcCh))

    #     inRoot = 'data/fpgaLin/Jan21b_C2_100mV_f1000.root'
    fout1 = TFile(inRoot, 'read')
    tree1 = fout1.Get('tree1')
    tree1.SetBranchAddress('adc', data1)

    with open(outText, 'w') as fout:
        fout.write(':'.join(
            ['sID/I', 'ch/I', 'B/F', 'dB/F', 'im/I', 'idx/I', 'A/F']))

        for ievt in range(tree1.GetEntries()):
            tree1.GetEntry(ievt)

            sp1.measure_pulse(data1)
            for i in range(sp1.nAdcCh):
                itmp = sp1.nMeasParam * i
                for j in range(sp1.nMeasParam / 2 - 1):
                    fout.write('\n' + ' '.join([
                        str(ievt),
                        str(i),
                        str(sp1.measParam[itmp]),
                        str(sp1.measParam[itmp + 1]),
                        str(j),
                        str(int(sp1.measParam[itmp + 2 * j + 2])),
                        str(sp1.measParam[itmp + 2 * j + 3])
                    ]))
示例#2
0
def overlayFilters(inRoot):
    sp1 = SignalProcessor()
    sp1.nSamples = 16384
    sp1.nAdcCh = 20
    sp1.fltParam.clear()
    sp1.x_thre = 0.1

    # sp3a
    for x in [30, 15, 50, 2500]:
        sp1.fltParam.push_back(x)
    #     for x in [50, 5, 15, 2500]: sp1.fltParam.push_back(x)

    # sp3b
    #     for x in [50, 500, 700, 2500]: sp1.fltParam.push_back(x)
    run = int(inRoot.rstrip('.root').split('_')[-1])

    data1 = array('f', [0] * (sp1.nSamples * sp1.nAdcCh))
    dataT = array('i', [0])

    fin1 = TFile(inRoot, 'read')
    tree1 = fin1.Get('tree1')
    tree1.SetBranchAddress('adc', data1)
    tree1.SetBranchAddress('T', dataT)

    oTag = 'flt_'
    fout1 = TFile(
        os.path.dirname(inRoot) + '/' + oTag + os.path.basename(inRoot),
        'recreate')
    tup1 = TNtuple('flt', "filter analysis tuple", 'run:evt:ch:ip:V')

    NPOINTS = 200

    ch = 19
    NEVT = tree1.GetEntries()
    for ievt in range(NEVT):
        tree1.GetEntry(ievt)

        sp1.measure_pulse2(data1, ch)

        for ip in range(NPOINTS):
            tup1.Fill(run, ievt, ch, ip, sp1.scrAry[ip])
    tup1.Write()
    fout1.Close()
def check_calib():
    sp1 = SignalProcessor()
    sp1.nSamples = 16384
    sp1.nAdcCh = 20

    ### setup the calibration file
    fin1 = TFile('fout_calib.root')
    sp1.corr_spine.clear()
    sp1.corr_TF1.clear()
    sp1.corr_spine.reserve(sp1.nAdcCh)
    sp1.corr_TF1.reserve(sp1.nAdcCh)
    for i in range(sp1.nAdcCh - 1):
        sp1.corr_spine.push_back(fin1.Get('gr_calib_ch' + str(i)))
        sp1.corr_TF1.push_back(sp1.corr_spine[i].GetFunction('pol1'))

    ## run a test
    for x in sp1.corr_spine[5].GetX():
        t = 1
        print sp1.correction(1, x) * t, sp1.correction(
            1, x, 1) * t, '|', sp1.correction(5, x) * t, sp1.correction(
                5, x, 1) * t
def readSignal4a(argX, runPattern='.*_data_(\d+).root'):
    '''Use non default time window'''
    args = argX.split(';')
    inRoot = args[0]
    oTag = args[1]
    print "Starting", inRoot, oTag

    ### pulse test
    dV = -1
    dvPattern = '.*_(\d+)mV_f\d+.root'
    m = re.match(dvPattern, inRoot)
    if m:
        try:
            dV = int(m.group(1))
        except ValueError:
            print "Failed to get the dV in file:", iRoot

    ### data check
    run = -1
    if runPattern is not None:
        m = re.match(runPattern, inRoot)
        if m:
            try:
                run = int(m.group(1))
            except ValueError:
                print "Run number not exatracted for file", iRoot
                return
        else:
            if dV < 0:
                print "Run number not exatracted for file", iRoot
                return

    sp1 = SignalProcessor()
    sp1.nSamples = 16384
    sp1.nAdcCh = 20
    sp1.fltParam.clear()
    #     for i in range(sp1.nAdcCh): sp1.ch_thre[i] = 0.002
    #     sp1.ch_thre[19] = 0.05
    thre = [0.002] * sp1.nAdcCh
    thre[2] = 0.0008
    thre[4] = 0.001
    thre[6] = 0.001
    thre[7] = 0.001
    thre[10] = 0.001
    thre[11] = 0.0007
    thre[14] = 0.0007
    thre[17] = 0.001
    thre[19] = 0.05

    sp1.CF_uSize = 600
    sp1.CF_dSize = 1100

    sp1.ch_thre.clear()
    for x in thre:
        sp1.ch_thre.push_back(x)

    sp1.CF_chan_en.clear()
    for i in range(20):
        sp1.CF_chan_en.push_back(1)

    flt = [50, 100, 500, -1]  # dp01a
    for x in flt:
        sp1.fltParam.push_back(x)

    fin1 = TFile(inRoot, 'read')
    tree1 = fin1.Get('tree1')

    tree2 = 0
    outRoot = os.path.dirname(inRoot) + '/' + oTag + os.path.basename(inRoot)
    tf = sp1.processFile(tree1, tree2, outRoot, run)
    tf.Close()
def readSignal2(inRoot, oTag=None, freq=1000, runPattern='.*_data_(\d+).root'):
    if oTag is None:
        oTag = readSignal2.oTag
    print "Starting", inRoot, oTag
    #     return

    run = -1
    if runPattern is not None:
        m = re.match(runPattern, inRoot)
        if m:
            run = int(m.group(1))
    print run

    sp1 = SignalProcessor()
    sp1.nSamples = 16384
    sp1.nAdcCh = 20
    sp1.fltParam.clear()
    for x in [50, 150, 250, 2500]:
        sp1.fltParam.push_back(x)
    #     for x in [50, 150, 200, -1.]: sp1.fltParam.push_back(x)
    #     for x in [50, 150, 200, 2500]: sp1.fltParam.push_back(x)
    #     for x in [50, 15, 50, 2500]: sp1.fltParam.push_back(x)
    #     for x in [500, 450, 800, 2500]: sp1.fltParam.push_back(x)

    n1 = int(1 / (0.2 * freq * 0.000001))
    sp1.sRanges.clear()
    ip = 0
    dn = 2500 % n1  ## 2500 is the expected position of the signal
    #     while ip+dn < sp1.nSamples:
    #         sp1.sRanges.push_back((ip, min(ip+n1, sp1.nSamples)))
    #         ip += n1

    #     sp1.sRanges.push_back((0, 400))
    sp1.sRanges.push_back((0, 3000))

    data1 = array('f', [0] * (sp1.nSamples * sp1.nAdcCh))
    dataT = array('i', [0])

    fin1 = TFile(inRoot, 'read')
    tree1 = fin1.Get('tree1')
    tree1.SetBranchAddress('adc', data1)
    tree1.SetBranchAddress('T', dataT)

    fout1 = TFile(
        os.path.dirname(inRoot) + '/' + oTag + os.path.basename(inRoot),
        'recreate')
    tup1 = TNtuple('tup1', "filter analysis tuple",
                   'run:sID:ch:B:dB:im:idx:A:T')

    for ievt in range(tree1.GetEntries()):
        tree1.GetEntry(ievt)

        sp1.measure_pulse(data1)
        for i in range(sp1.nAdcCh):
            itmp = sp1.nMeasParam * i
            for j in range(sp1.nMeasParam / 2 - 1):
                tup1.Fill(run, ievt, i, sp1.measParam[itmp],
                          sp1.measParam[itmp + 1], j,
                          sp1.measParam[itmp + 2 * j + 2],
                          sp1.measParam[itmp + 2 * j + 3],
                          dataT[0] - 788947200)

    tup1.Write()
    fout1.Close()
def readSignal3(argX, runPattern='.*_data_(\d+).root'):
    args = argX.split(';')
    inRoot = args[0]
    oTag = args[1]
    print "Starting", inRoot, oTag

    ### pulse test
    dV = -1
    dvPattern = '.*_(\d+)mV_f\d+.root'
    m = re.match(dvPattern, inRoot)
    if m:
        try:
            dV = int(m.group(1))
        except ValueError:
            print "Failed to get the dV in file:", iRoot

    ### data check
    run = -1
    if runPattern is not None:
        m = re.match(runPattern, inRoot)
        if m:
            try:
                run = int(m.group(1))
            except ValueError:
                print "Run number not exatracted for file", iRoot
                return
        else:
            if dV < 0:
                print "Run number not exatracted for file", iRoot
                return

    sp1 = SignalProcessor()
    sp1.nSamples = 16384
    sp1.nAdcCh = 20
    sp1.fltParam.clear()
    #     for i in range(sp1.nAdcCh): sp1.ch_thre[i] = 0.002
    #     sp1.ch_thre[19] = 0.05
    thre = [0.002] * sp1.nAdcCh
    thre[2] = 0.0008
    thre[4] = 0.001
    thre[6] = 0.001
    thre[7] = 0.001
    thre[10] = 0.001
    thre[11] = 0.0007
    thre[14] = 0.0007
    thre[17] = 0.001
    thre[19] = 0.05

    sp1.ch_thre.clear()
    for x in thre:
        sp1.ch_thre.push_back(x)

    # sp3a
    #     for x in [30, 15, 50, 2500]: sp1.fltParam.push_back(x)
    #     flt = [50, 50, 250, 2500]
    #     flt = [50, 50, 150, -1]
    flt = [50, 100, 500, -1]  # dp01a
    #     flt = [30, 250, 350, 2500]
    #     flt = [50, 10, 150, 2500]
    #     flt = [50, 500, 600, 2500]
    #     flt = [50, 5, 100, 2500]
    for x in flt:
        sp1.fltParam.push_back(x)

    # sp3b
    #     for x in [50, 500, 700, 2500]: sp1.fltParam.push_back(x)

    data1 = array('f', [0] * (sp1.nSamples * sp1.nAdcCh))
    dataT = array('i', [0])

    fin1 = TFile(inRoot, 'read')
    tree1 = fin1.Get('tree1')
    tree1.SetBranchAddress('adc', data1)
    tree1.SetBranchAddress('T', dataT)

    fout1 = TFile(
        os.path.dirname(inRoot) + '/' + oTag + os.path.basename(inRoot),
        'recreate')
    tup1 = TNtuple('tup1', "filter analysis tuple",
                   'run:evt:ch:B:dB:iA:imean:imax:A:w0:w1:w2:T:dV')
    a = TObjString("filter:" + str(flt))
    a.Write('Info')

    ### for background subtraction
    be1 = bkgEstimator()

    #     chs = [19]
    chs = None
    for ievt in range(tree1.GetEntries()):
        tree1.GetEntry(ievt)

        #         apply_wiener_filter(data1, ich=19)
        #         be1.correct(data1, 19)

        sp1.measure_pulse2(data1)
        for ich in range(sp1.nAdcCh):
            if chs and (ich not in chs): continue
            #             print "processing channle", ich
            ss = sp1.signals[ich]

            itmp = sp1.nMeasParam * ich
            iA = 0
            for ii in ss:
                tup1.Fill(run, ievt, ich, sp1.measParam[itmp],
                          sp1.measParam[itmp + 1], iA, ii.im, ii.idx, ii.Q,
                          ii.w0, ii.w1, ii.w2, dataT[0] - 788947200, dV)
                iA += 1

    tup1.Write()
    fout1.Close()
示例#7
0
def main():
    inRoot = sys.argv[1] if len(sys.argv) > 1 else "test.root"
    ich = int(sys.argv[2]) if len(sys.argv) > 2 else 0
    sp1 = SignalProcessor()
    sp1.nSamples = 16384
    sp1.nAdcCh = 20
    sp1.fltParam.clear()
    for x in [50, 150, 200, -1.]:
        sp1.fltParam.push_back(x)

    freq = 1000
    n1 = int(1 / (0.2 * freq * 0.000001))
    sp1.sRanges.clear()
    ip = 0
    dn = 2500 % n1  ## 2500 is the expected position of the signal
    while ip + dn < sp1.nSamples:
        sp1.sRanges.push_back((ip, min(ip + n1, sp1.nSamples)))
        ip += n1

    data1 = array('f', [0] * (sp1.nSamples * sp1.nAdcCh))

    fout1 = TFile(inRoot, 'read')
    tree1 = fout1.Get('tree1')
    tree1.SetBranchAddress('adc', data1)

    ### range
    eRange = None
    if len(sys.argv) > 3:
        lx = []
        r = sys.argv[3].split(',')
        for ri in r:
            si = ri.find('-')
            if si == -1:
                lx.append(int(ri))
            else:
                end = tree1.GetEntries() if si == len(ri) - 1 else int(ri[si +
                                                                          1:])
                lx += range(int(ri[:si]), end)
        eRange = lx
    else:
        eRange = range(tree1.GetEntries())

    ### plotting
    plt.ion()
    plt.show()

    fig, ax1 = plt.subplots()
    ax1.set_xlabel('time (s)')
    # Make the y-axis label, ticks and tick labels match the line color.
    ax1.set_ylabel('exp', color='b')
    ax1.tick_params('y', colors='b')
    ax2 = ax1.twinx()
    ax2.set_ylabel('sin', color='r')
    ax2.tick_params('y', colors='r')

    #     for i in range(10):
    for i in eRange:
        print i
        tree1.GetEntry(i)
        sp1.measure_pulse(data1, ich)

        ax1.clear()
        ax1.plot(data1[sp1.nSamples * ich:sp1.nSamples * (ich + 1)])
        ax2.clear()
        ax2.plot([sp1.scrAry[i] for i in range(sp1.nSamples)], 'r.')
        fig.tight_layout()
        plt.draw()
        plt.pause(0.001)
        x = raw_input("Press [enter] to continue.")
        if x == 'q': break
示例#8
0
def check1b(argX,
            chs=None,
            nEvt=None,
            runPattern='.*_data_(\d+).root',
            step2=False):
    '''Use various filters to extract the results'''
    args = argX.split(';')
    inRoot = args[0]
    oTag = args[1]
    outRoot = os.path.dirname(inRoot) + '/' + oTag + os.path.basename(inRoot)
    #     outRoot = inRoot.rstrip('.root')+oTag+'.root'
    print "Starting", inRoot, '->', outRoot

    if os.path.exists(outRoot):
        print "has:", inRoot, outRoot
        return

    run = -1
    if runPattern is not None:
        m = re.match(runPattern, inRoot)
        if m: run = int(m.group(1))
        else: print "Run number not exatracted for file", iRoot

    sp1 = SignalProcessor()
    sp1.nSamples = 16384
    sp1.nAdcCh = 20

    testPulseOnly = False
    ### look for signal peak in the expected regions only
    if testPulseOnly:
        freq = 1000
        n1 = int(1 / (0.2 * freq * 0.000001))
        sp1.sRanges.clear()
        ip = 0
        dn = 2500 % n1  ## 2500 is the expected position of the signal
        while ip + dn < sp1.nSamples:
            sp1.sRanges.push_back((ip, min(ip + n1, sp1.nSamples)))
            ip += n1

    ### for storing data
    data1 = array('f', [0] * (sp1.nSamples * sp1.nAdcCh))
    dataT = array('i', [0])

    fin1 = TFile(inRoot, 'read')
    tree1 = fin1.Get('tree1')
    tree1.SetBranchAddress('adc', data1)
    tree1.SetBranchAddress('T', dataT)
    if nEvt is None: nEvt = tree1.GetEntries()
    if chs is None: chs = range(sp1.nAdcCh)
    ch = chs[0] if len(chs) == 1 else -1

    fout1 = TFile(outRoot, 'recreate')
    #     tup1 = TNtuple('tup1',"filter analysis tuple",'evt:fR:fW:ich:b:bE:im:idx:A')
    tup1 = TNtuple('tup1', "filter analysis tuple",
                   'run:evt:fR:fW:ch:B:dB:iA:imean:imax:A:w0:w1:w2:T')

    chs = [19]

    rRange = range(10, 200, 20)
    wRange = range(50, 300, 20)
    ### start processing
    INTV = 1000 if nEvt > 10000 else max(nEvt / 10, 1)
    for ievt in range(nEvt):
        tree1.GetEntry(ievt)
        if ievt % INTV == 0: print ievt, ' events processed'

        for R in rRange:
            for W in wRange:
                sp1.fltParam.clear()
                for x in [500, R, W, 2500.]:
                    sp1.fltParam.push_back(x)
                sp1.measure_pulse2(data1, ch)

                for ich in chs:
                    ss = sp1.signals[ich]

                    iA = 0
                    for ii in ss:
                        tup1.Fill(run, ievt, R, W, ich, 0, 0, iA, ii.im,
                                  ii.idx, ii.Q, ii.w0, ii.w1, ii.w2,
                                  dataT[0] - 788947200)
                        iA += 1
    tup1.Write()

    ### save the ENC results
    tup2 = TNtuple('tup2', "filter analysis tuple enc",
                   'ich:fR:fW:m:mE:sigma:sigmaE:fq:fStatus')
    for R in rRange:
        for W in wRange:
            for ich in chs:
                gDirectory.Delete('h1*')
                tup1.Draw(
                    'A>>h1',
                    'int(fW)=={0:d}&&int(fR)=={1:d}&&ch=={2:d}'.format(
                        W, R, ich), 'goff')
                h1 = gDirectory.Get('h1')
                r = h1.Fit('gaus', 'S0')
                fun1 = h1.GetFunction('gaus')
                tup2.Fill(ich, R, W, fun1.GetParameter(1), fun1.GetParError(1),
                          fun1.GetParameter(2), fun1.GetParError(2), r.Prob(),
                          r.Status())

    tup2.Write()
    fout1.Close()
示例#9
0
def check0():
    inRoot = sys.argv[1] if len(sys.argv) > 1 else "test.root"
    ich = int(sys.argv[2]) if len(sys.argv) > 2 else 0
    sp1 = SignalProcessor()
    sp1.nSamples = 16384
    sp1.nAdcCh = 20
    freq = 1000
    n1 = int(1 / (0.2 * freq * 0.000001))
    sp1.sRanges.clear()
    ip = 0
    dn = 2500 % n1  ## 2500 is the expected position of the signal
    while ip + dn < sp1.nSamples:
        sp1.sRanges.push_back((ip, min(ip + n1, sp1.nSamples)))
        ip += n1

    data1 = array('f', [0] * (sp1.nSamples * sp1.nAdcCh))

    fout1 = TFile(inRoot, 'read')
    tree1 = fout1.Get('tree1')
    tree1.SetBranchAddress('adc', data1)

    ### range
    eRange = None
    if len(sys.argv) > 3:
        lx = []
        r = sys.argv[3].split(',')
        for ri in r:
            si = ri.find('-')
            if si == -1:
                lx.append(int(ri))
            else:
                end = tree1.GetEntries() if si == len(ri) - 1 else int(ri[si +
                                                                          1:])
                lx += range(int(ri[:si]), end)
        eRange = lx
    else:
        eRange = range(tree1.GetEntries())

    ### plotting
    plt.ion()
    plt.show()

    fig, ax1 = plt.subplots()
    ax1.set_xlabel('time (s)')
    # Make the y-axis label, ticks and tick labels match the line color.
    ax1.set_ylabel('exp', color='b')
    ax1.tick_params('y', colors='b')
    ax2 = ax1.twinx()
    ax2.set_ylabel('sin', color='r')
    ax2.tick_params('y', colors='r')

    #     fl1 = Filter_ibl(sp1.nSamples)
    #     fl1.setup(2,3e-3)
    fl1 = Filter_ibb(sp1.nSamples)
    fl1.setup(4, 2e-3, 5e-3)

    #     for i in range(10):

    for i in eRange:
        print i
        tree1.GetEntry(i)
        ax1.clear()
        ax1.plot(data1[sp1.nSamples * ich:sp1.nSamples * (ich + 1)])
        ax2.clear()

        sp1.fltParam.clear()
        #         for x in [500, 150, 200, 2500]: sp1.fltParam.push_back(x)
        for x in [500, 800, 2000, 2500]:
            sp1.fltParam.push_back(x)
        sp1.measure_pulse(data1, ich)
        ax2.plot([sp1.scrAry[i] for i in range(sp1.nSamples)], 'r.')

        sp1.fltParam.clear()
        for x in [500, 15, 50, 2500]:
            sp1.fltParam.push_back(x)
        #         for x in [500, 150, 200, 2500]: sp1.fltParam.push_back(x)
        sp1.measure_pulse(data1, ich)
        #         ax2.plot([sp1.scrAry[i] for i in range(sp1.nSamples)], 'g.')

        vx = np.array([sp1.scrAry[i] for i in range(sp1.nSamples)])
        ax2.plot(vx, 'g.')

        fl1.apply(sp1.scrAry)
        vf1 = np.array([fl1.outWav[i] for i in range(sp1.nSamples)])
        ax2.plot(vf1, 'm.')

        #         peakind = find_peaks_cwt(vx, np.arange(1,100))
        #         peaks = find_peaks_cwt(vx, np.array([5, 10, 20,30,50,100,200,350]), min_snr=50)
        #         print peaks, vx[peaks]
        #         peaks, properties = signal.find_peaks(vx, prominence=1, width=20)
        #         plt.plot(peaks, vx[peaks], "x")

        fig.tight_layout()
        plt.draw()
        plt.grid(True)
        plt.pause(0.001)
        x = raw_input("Press [enter] to continue.")
        if x == 'q': break
示例#10
0
def check1(inRoot, chRange=None, nEvt=None, oTag='_tt'):
    '''Use various filters to extract the results'''

    if os.path.exists(inRoot.rstrip('.root') + oTag + '.root'):
        print "has:", inRoot
        return


#     print inRoot
#     return
    sp1 = SignalProcessor()
    sp1.nSamples = 16384
    sp1.nAdcCh = 20
    freq = 1000
    n1 = int(1 / (0.2 * freq * 0.000001))
    sp1.sRanges.clear()
    ip = 0
    dn = 2500 % n1  ## 2500 is the expected position of the signal
    while ip + dn < sp1.nSamples:
        sp1.sRanges.push_back((ip, min(ip + n1, sp1.nSamples)))
        ip += n1

    data1 = array('f', [0] * (sp1.nSamples * sp1.nAdcCh))

    fin1 = TFile(inRoot, 'read')
    tree1 = fin1.Get('tree1')
    tree1.SetBranchAddress('adc', data1)
    if nEvt is None: nEvt = tree1.GetEntries()
    if chRange is None: chRange = range(sp1.nAdcCh)

    fout1 = TFile(inRoot.rstrip('.root') + oTag + '.root', 'recreate')
    tup1 = TNtuple('tup1', "filter analysis tuple",
                   'evt:fR:fW:ich:b:bE:im:idx:A')

    ### start processing
    INTV = 1000 if nEvt > 10000 else max(nEvt / 10, 1)
    for ievt in range(nEvt):
        tree1.GetEntry(ievt)

        if ievt % INTV == 0: print ievt, ' events processed'

        for R in range(50, 300, 50):
            for W in range(50, 600, 50):
                sp1.fltParam.clear()
                for x in [500, R, W, -1.]:
                    sp1.fltParam.push_back(x)
                sp1.measure_pulse(data1)

                for ich in chRange:
                    itmp = sp1.nMeasParam * ich
                    for j in range(sp1.nMeasParam / 2 - 1):
                        tup1.Fill(ievt, R, W, ich, sp1.measParam[itmp],
                                  sp1.measParam[itmp + 1], j,
                                  sp1.measParam[itmp + 2 * j + 2],
                                  sp1.measParam[itmp + 2 * j + 3])
    tup1.Write()

    ### save the ENC results
    tup2 = TNtuple('tup2', "filter analysis tuple enc",
                   'ich:fR:fW:m:mE:sigma:sigmaE:fq:fStatus')
    for R in range(50, 300, 50):
        for W in range(50, 600, 50):
            for ich in chRange:
                gDirectory.Delete('h1*')
                tup1.Draw(
                    'A>>h1',
                    'int(fW)=={0:d}&&int(fR)=={1:d}&&ich=={2:d}'.format(
                        W, R, ich), 'goff')
                h1 = gDirectory.Get('h1')
                r = h1.Fit('gaus', 'S0')
                fun1 = h1.GetFunction('gaus')
                tup2.Fill(ich, R, W, fun1.GetParameter(1), fun1.GetParError(1),
                          fun1.GetParameter(2), fun1.GetParError(2), r.Prob(),
                          r.Status())

    tup2.Write()
    fout1.Close()