Belle II Software development
eclComputePulseTemplates_Step2.py
1#!/usr/bin/env python3
2
3
10
11import numpy as np
12from scipy.fftpack import fft, ifft
13import ROOT
14from ROOT import TFile
15import sys
16from array import array
17import argparse
18
19# '''
20# Third step in waveform template calibrations. Computes hadron pulse shape using photon template input.
21# See eclComputePulseTemplates_Step0.cc for README instructions.
22# '''
23
24
25def EvalGamComp(tin, ttrg):
26 if tin < ttrg:
27 return 0
28 Ratio = 0.56936
29 FastTau = 851.28 * (0.88348588) # Converting to sample number time scale
30 SlowTau = 5802.0 * (0.88348588) # Converting to sample number time scale
31 val = Ratio * ((1. / FastTau) * np.exp(-(tin - ttrg) / FastTau)) + \
32 (1 - Ratio) * ((1. / SlowTau) * np.exp(-(tin - ttrg) / SlowTau))
33 return val
34
35
36def EvalHadronComp(tin, ttrg):
37 HadronTau = 630. * (0.88348588) # Converting to sample number time scale
38 if tin < ttrg:
39 return 0
40 val = ((1. / HadronTau) * np.exp(-(tin - ttrg) / HadronTau))
41 return val
42
43
44def EvalAnyComp(tin, ttrg, TauIn):
45 TauIn *= (0.88348588) # Converting to sample number time scale
46 if tin < ttrg:
47 return 0
48 val = ((1. / TauIn) * np.exp(-(tin - ttrg) / TauIn))
49 return val
50
51
52def CalcShaperOutput(muonShaper, muonInitial, inputPreShaper, ITER):
53 impulse = (ifft(fft(muonShaper) / fft(muonInitial)))
54 outputShaper = np.real(ifft(fft(impulse) * fft(inputPreShaper)))
55 base = outputShaper[ITER]
56 i = 0
57 while i < len(outputShaper):
58 outputShaper[i] -= base
59 i = i + 1
60 outputShaper[0] = 0
61 print(outputShaper.max())
62 return outputShaper
63
64
65def GetShaperOutput(ratio, flg, shaperMuonFunc):
66
67 Ns = 100000
68 TLen = 100000.
69 to_ns = TLen/Ns
70
71 PMT_trigger_time = 1000. * to_ns
72
73 Time = []
74 TimeShp = []
75 ShaperDSP_output_muon_array = []
76 PMT_output_muon_array = []
77 PMT_output_array = []
78
79 for i in range(0, Ns):
80 t = i * to_ns
81 Time.append(t)
82 TimeShp.append(t)
83 ShaperDSP_output_muon_array.append(shaperMuonFunc[i])
84 PMT_output_muon_array.append(EvalGamComp(t, PMT_trigger_time))
85 if ratio <= 1.:
86 PMT_output_array.append((1 - ratio) * EvalGamComp(t, PMT_trigger_time) + ratio * (EvalHadronComp(t, PMT_trigger_time)))
87 else:
88 PMT_output_array.append((2 - ratio) * EvalGamComp(t, PMT_trigger_time) +
89 (ratio - 1) * (EvalAnyComp(t, PMT_trigger_time, 10)))
90
91 if(flg == 0):
92 return Time, PMT_output_array
93 if(flg == 1):
94 return Time, PMT_output_muon_array
95 if(flg == 2):
96 return Time, ShaperDSP_output_muon_array
97 if(flg == 3):
98 ShaperDSP_output_array = []
99 if(ratio <= 1.):
100 ShaperDSP_output_array = CalcShaperOutput(ShaperDSP_output_muon_array, PMT_output_muon_array, PMT_output_array, 0)
101 else:
102 ShaperDSP_output_array = CalcShaperOutput(ShaperDSP_output_muon_array, PMT_output_muon_array, PMT_output_array, 30)
103 j = 0
104 Time_us = []
105 while j < len(Time):
106 Time_us.append(Time[j] / (1000.))
107 j = j + 1
108 return Time_us, ShaperDSP_output_array
109
110
111OutputDirectory = "./"
112if(OutputDirectory == ""):
113 print("Error set ouput directory")
114 sys.exit()
115
116
117def argument_parser():
118 parser = argparse.ArgumentParser(description=__doc__)
119 parser.add_argument('Low', type=int, help='First CellID to be processed')
120 parser.add_argument('High', type=int, help='Last CellID to be processed')
121 return parser
122
123
124args = argument_parser().parse_args()
125Low = args.Low
126High = args.High
127
128print(Low, High)
129
130f1 = ROOT.TFile(OutputDirectory + "PhotonShapes_Low" + str(Low) + "_High" + str(High) + ".root", "update")
131f1.cd()
132mt = f1.Get("mtree")
133entries = mt.GetEntries()
134print(entries)
135
136TFactor = 30
137
138outFile = TFile(OutputDirectory + "HadronShapes_Low" + str(Low) + "_High" + str(High) + ".root", "RECREATE")
139outTree = ROOT.TTree("HadronTree", "")
140TimeAll_A = array('d', 1000 * [0.])
141ValuePhoton_A = array('d', 1000 * [0.])
142ValueHadron_A = array('d', 1000 * [0.])
143ValueDiode_A = array('d', 1000 * [0.])
144outTree.Branch("TimeAll_A", TimeAll_A, 'TimeAll_A[1000]/D')
145outTree.Branch("ValuePhoton_A", ValuePhoton_A, 'ValuePhoton_A[1000]/D')
146outTree.Branch("ValueHadron_A", ValueHadron_A, 'ValueHadron_A[1000]/D')
147outTree.Branch("ValueDiode_A", ValueDiode_A, 'ValueDiode_A[1000]/D')
148
149i = 0
150for i in range(entries):
151 mt.GetEntry(i)
152 if(mt.PhotonArray[1] < -100):
153 for j in range(1000):
154 ValuePhoton_A[j] = -999
155 TimeAll_A[j] = -999
156 ValueHadron_A[j] = -999
157 ValueDiode_A[j] = -999
158 else:
159 flag = 3
160 Time3, ValuesHadron_A = GetShaperOutput(1, flag, mt.PhotonArray)
161 Time4, ValuesDiode_A = GetShaperOutput(2, flag, mt.PhotonArray)
162 Time6, ValuesPhoton_A = GetShaperOutput(0, flag, mt.PhotonArray)
163
164 factor = TFactor
165 for j in range(1000):
166 if(flag == 3):
167 ValuePhoton_A[j] = mt.PhotonArray[j * factor]
168 else:
169 ValuePhoton_A[j] = ValuesPhoton_A[j * factor]
170 TimeAll_A[j] = Time3[j * factor]
171 ValueHadron_A[j] = ValuesHadron_A[j * factor]
172 ValueDiode_A[j] = ValuesDiode_A[j * factor]
173 outTree.Fill()
174outFile.cd()
175outTree.Write()
176outFile.Write()
177sys.exit()