Belle II Software  release-08-01-10
eclComputePulseTemplates_Step2.py
1 #!/usr/bin/env python3
2 
3 
10 
11 import numpy as np
12 from scipy.fftpack import fft, ifft
13 import ROOT
14 from ROOT import TFile
15 import sys
16 from array import array
17 import 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 
25 def 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 
36 def 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 
44 def 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 
52 def 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 
65 def 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 
111 OutputDirectory = "./"
112 if(OutputDirectory == ""):
113  print("Error set ouput directory")
114  sys.exit()
115 
116 
117 def 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 
124 args = argument_parser().parse_args()
125 Low = args.Low
126 High = args.High
127 
128 print(Low, High)
129 
130 f1 = ROOT.TFile(OutputDirectory + "PhotonShapes_Low" + str(Low) + "_High" + str(High) + ".root", "update")
131 f1.cd()
132 mt = f1.Get("mtree")
133 entries = mt.GetEntries()
134 print(entries)
135 
136 TFactor = 30
137 
138 outFile = TFile(OutputDirectory + "HadronShapes_Low" + str(Low) + "_High" + str(High) + ".root", "RECREATE")
139 outTree = ROOT.TTree("HadronTree", "")
140 TimeAll_A = array('d', 1000 * [0.])
141 ValuePhoton_A = array('d', 1000 * [0.])
142 ValueHadron_A = array('d', 1000 * [0.])
143 ValueDiode_A = array('d', 1000 * [0.])
144 outTree.Branch("TimeAll_A", TimeAll_A, 'TimeAll_A[1000]/D')
145 outTree.Branch("ValuePhoton_A", ValuePhoton_A, 'ValuePhoton_A[1000]/D')
146 outTree.Branch("ValueHadron_A", ValueHadron_A, 'ValueHadron_A[1000]/D')
147 outTree.Branch("ValueDiode_A", ValueDiode_A, 'ValueDiode_A[1000]/D')
148 
149 i = 0
150 for 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()
174 outFile.cd()
175 outTree.Write()
176 outFile.Write()
177 sys.exit()