CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HcalQie.cc
Go to the documentation of this file.
1 // File: HcalQie.cc
3 // Description: Simulation of QIE readout for HCal
5 
7 
8 #include "CLHEP/Random/RandGaussQ.h"
9 #include "CLHEP/Random/RandPoissonQ.h"
10 #include "CLHEP/Units/GlobalPhysicalConstants.h"
11 
12 #include <iostream>
13 #include <iomanip>
14 #include <cmath>
15 
16 //#define DebugLog
17 
19 
20  //static SimpleConfigurable<double> p1(4.0, "HcalQie:qToPE");
21  //static SimpleConfigurable<int> p2(6, "HcalQie:BinOfMax");
22  //static SimpleConfigurable<int> p3(2, "HcalQie:SignalBuckets");
23  //static SimpleConfigurable<int> p4(0, "HcalQie:PreSamples");
24  //static SimpleConfigurable<int> p5(10, "HcalQie:NumOfBuckets");
25  //static SimpleConfigurable<double> p6(0.5, "HcalQie:SigmaNoise");
26  //static SimpleConfigurable<double> p7(0.0005,"HcalQie:EDepPerPE");
27  //static SimpleConfigurable<int> p8(4, "HcalQie:BaseLine");
28 
30  qToPE = m_HQ.getParameter<double>("qToPE");
31  binOfMax = m_HQ.getParameter<int>("BinOfMax");
32  signalBuckets = m_HQ.getParameter<int>("SignalBuckets");
33  preSamples = m_HQ.getParameter<int>("PreSamples");
34  numOfBuckets = m_HQ.getParameter<int>("NumOfBuckets");
35  sigma = m_HQ.getParameter<double>("SigmaNoise");
36  eDepPerPE = m_HQ.getParameter<double>("EDepPerPE");
37  int bl = m_HQ.getParameter<int>("BaseLine");
38 
39  shape_ = shape();
40  code_ = code();
41  charge_ = charge();
42  if (signalBuckets == 1) {
43  phase_ = -3; rescale_ = 1.46;
44  } else if (signalBuckets == 3) {
45  phase_ = -1; rescale_ = 1.06;
46  } else if (signalBuckets == 4) {
47  phase_ = 0; rescale_ = 1.03;
48  } else {
49  phase_ = -2; rescale_ = 1.14; signalBuckets = 2;
50  }
51  weight_ = weight(binOfMax, signalBuckets, preSamples, numOfBuckets);
52  baseline= codeToQ(bl);
53  bmin_ = binOfMax-3;
54  if (bmin_<0) bmin_ = 0;
55  if (binOfMax>numOfBuckets)
56  bmax_ = numOfBuckets+5;
57  else
58  bmax_ = binOfMax+5;
59 
60  edm::LogInfo("HcalSim") << "HcalQie: initialized with binOfMax " << binOfMax
61  << " sample from " << bmin_ << " to " << bmax_
62  << "; signalBuckets " << signalBuckets
63  << " Baseline/Phase/Scale " << baseline << "/"
64  << phase_ << "/" << rescale_ << "\n"
65  <<" Noise " << sigma
66  << "fC fCToPE " << qToPE << " EDepPerPE "
67  << eDepPerPE;
68 }
69 
71  edm::LogInfo("HcalSim") << "HcalQie:: Deleting Qie";
72 }
73 
74 std::vector<double> HcalQie::shape() {
75 
76  // pulse shape time constants in ns
77  const float ts1 = 8.; // scintillation time constants : 1,2,3
78  const float ts2 = 10.;
79  const float ts3 = 29.3;
80  const float thpd = 4.; // HPD current collection drift time
81  const float tpre = 5.; // preamp time constant
82 
83  const float wd1 = 2.; // relative weights of decay exponents
84  const float wd2 = 0.7;
85  const float wd3 = 1.;
86 
87  // HPD starts at I and rises to 2I in thpd of time
88  double norm=0.0;
89  int j, hpd_siz = (int)(thpd);
90  std::vector<double> hpd_drift(hpd_siz);
91  for (j=0; j<hpd_siz; j++) {
92  double tmp = (double)j + 0.5;
93  hpd_drift[j] = 1.0 + tmp/thpd;
94  norm += hpd_drift[j];
95  }
96  // normalize integrated current to 1.0
97  for (j=0; j<hpd_siz; j++) {
98  hpd_drift[j] /= norm;
99  }
100 
101  // Binkley shape over 6 time constants
102  int preamp_siz=(int)(6*tpre);
103  std::vector<double> preamp(preamp_siz);
104  norm = 0;
105  for (j=0; j<preamp_siz; j++) {
106  double tmp = (double)j + 0.5;
107  preamp[j] = tmp*exp(-(tmp*tmp)/(tpre*tpre));
108  norm += preamp[j];
109  }
110  // normalize pulse area to 1.0
111  for (j=0; j<preamp_siz; j++) {
112  preamp[j] /= norm;
113  }
114 
115  // ignore stochastic variation of photoelectron emission
116  // <...>
117  // effective tile plus wave-length shifter decay time over 4 time constants
118 
119  int tmax = 6 * (int)ts3;
120  std::vector<double> scnt_decay(tmax);
121  norm = 0;
122  for (j=0; j<tmax; j++) {
123  double tmp = (double)j + 0.5;
124  scnt_decay[j] = wd1*exp(-tmp/ts1) + wd2*exp(-tmp/ts2) + wd3*exp(-tmp/ts3);
125  norm += scnt_decay[j];
126  }
127  // normalize pulse area to 1.0
128  for (j=0; j<tmax; j++) {
129  scnt_decay[j] /= norm;
130  }
131 
132  int nsiz = tmax + hpd_siz + preamp_siz + 1;
133  std::vector<double> pulse(nsiz,0.0); // zeroing output pulse shape
134  norm = 0;
135  int i, k;
136  for (i=0; i<tmax; i++) {
137  int t1 = i; // and ignore jitter from optical path length
138  for (j=0; j<hpd_siz; j++) {
139  int t2 = t1 + j;
140  for (k=0; k<preamp_siz; k++) {
141  int t3 = t2 + k;
142  float tmp = scnt_decay[i]*hpd_drift[j]*preamp[k];
143  pulse[t3]+= tmp;
144  norm += tmp;
145  }
146  }
147  }
148 
149  // normalize for 1 GeV pulse height
150  edm::LogInfo("HcalSim") << "HcalQie: Convoluted Shape ============== "
151  << "Normalisation " << norm;
152  for (i=0; i<nsiz; i++) {
153  pulse[i] /= norm;
154 #ifdef DebugLog
155  LogDebug("HcalSim") << "HcalQie: Pulse[" << std::setw(3) << i << "] "
156  << std::setw(8) << pulse[i];
157 #endif
158  }
159 
160  return pulse;
161 }
162 
163 std::vector<int> HcalQie::code() {
164 
165  unsigned int CodeFADCdata[122] = {
166  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
167  10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
168  20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
169  30, 31, 34, 35, 36, 37, 38, 39,
170  40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
171  50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
172  60, 61, 62, 63, 66, 67, 68, 69,
173  70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
174  80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
175  90, 91, 92, 93, 94, 95, 98, 99,
176  100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
177  110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
178  120, 121, 122, 123, 124, 125, 126, 127 };
179 
180  std::vector<int> temp(122);
181  int i;
182  for (i = 0; i < 122; i++)
183  temp[i] = (int)CodeFADCdata[i];
184 
185 #ifdef DebugLog
186  int siz = temp.size();
187  LogDebug("HcalSim") << "HcalQie: Codes in array of size " << siz;
188  for (i=0; i<siz; i++)
189  LogDebug("HcalSim") << "HcalQie: Code[" << std::setw(3) << i << "] "
190  << std::setw(6) << temp[i];
191 #endif
192  return temp;
193 }
194 
195 std::vector<double> HcalQie::charge() {
196 
197  double ChargeFADCdata[122] = {
198  -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5,
199  8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 16.5, 18.5, 20.5,
200  22.5, 24.5, 26.5, 28.5, 31.5, 34.5, 37.5, 40.5, 44.5, 48.5,
201  52.5, 57.5, 62.5, 67.5, 72.5, 77.5, 82.5, 87.5,
202  92.5, 97.5, 102.5, 107.5, 112.5, 117.5, 122.5, 127.5, 132.5, 142.5,
203  152.5, 162.5, 172.5, 182.5, 192.5, 202.5, 217.5, 232.5, 247.5, 262.5,
204  282.5, 302.5, 322.5, 347.5, 372.5, 397.5, 422.5, 447.5,
205  472.5, 497.5, 522.5, 547.5, 572.5, 597.5, 622.5, 647.5, 672.5, 697.5,
206  722.5, 772.5, 822.5, 872.5, 922.5, 972.5, 1022.5, 1072.5, 1147.5, 1222.5,
207  1297.5,1372.5, 1472.5, 1572.5, 1672.5, 1797.5, 1922.5, 2047.5,
208  2172.5,2297.5, 2422.5, 2547.5, 2672.5, 2797.5, 2922.5, 3047.5, 3172.5, 3397.5,
209  3422.5,3547.5, 3672.5, 3922.5, 4172.5, 4422.5, 4672.5, 4922.5, 5172.5, 5422.5,
210  5797.5,6172.5, 6547.5, 6922.5, 7422.5, 7922.5, 8422.5, 9047.5 };
211 
212  std::vector<double> temp(122);
213  int i;
214  for (i = 0; i < 122; i++)
215  temp[i] = (double)(ChargeFADCdata[i]);
216 
217 #ifdef DebugLog
218  int siz = temp.size();
219  LogDebug("HcalSim") << "HcalQie: Charges in array of size " << siz;
220  for (i=0; i<siz; i++)
221  LogDebug("HcalSim") << "HcalQie: Charge[" << std::setw(3) << i << "] "
222  << std::setw(8) << temp[i];
223 #endif
224  return temp;
225 }
226 
227 std::vector<double> HcalQie::weight(int binOfMax, int mode, int npre,
228  int bucket) {
229 
230  std::vector<double> temp(bucket,0);
231  int i;
232  for (i=binOfMax-1; i<binOfMax+mode-1; i++)
233  temp[i] = 1.;
234  if (npre>0) {
235  for (i=0; i<npre; i++) {
236  int j = binOfMax-2-i;
237  temp[j] =-(double)mode/(double)npre;
238  }
239  }
240 
241 #ifdef DebugLog
242  int siz = temp.size();
243  LogDebug("HcalSim") << "HcalQie: Weights in array of size " << siz
244  << " and Npre " << npre;
245  for (i=0; i<siz; i++)
246  LogDebug("HcalSim") << "HcalQie: [Weight[" << i << "] = " << temp[i];
247 #endif
248  return temp;
249 }
250 
251 
252 double HcalQie::codeToQ(int ic) {
253 
254  double tmp=0;
255  for (unsigned int i=0; i<code_.size(); i++) {
256  if (ic == code_[i]) {
257  double delta;
258  if (i == code_.size()-1)
259  delta = charge_[i] - charge_[i-1];
260  else
261  delta = charge_[i+1] - charge_[i];
262  tmp = charge_[i] + 0.5*delta;
263  break;
264  }
265  }
266 
267  return tmp;
268 }
269 
270 
272 
273  int tmp=0;
274  for (unsigned int i=0; i<charge_.size(); i++) {
275  if (charge < charge_[i]) {
276  if (i>0) tmp = code_[i-1];
277  break;
278  }
279  }
280 
281  return tmp;
282 }
283 
284 
285 double HcalQie::getShape(double time) {
286 
287  double tmp = 0;
288  int k = (int) (time + 0.5);
289  if (k>=0 && k<((int)(shape_.size())-1))
290  tmp = 0.5*(shape_[k]+shape_[k+1]);
291 
292  return tmp;
293 }
294 
295 
296 std::vector<int> HcalQie::getCode(int nht, const std::vector<CaloHit>& hitbuf,
297  CLHEP::HepRandomEngine* engine) {
298 
299  const double bunchSpace=25.;
300  int nmax = (bmax_ > numOfBuckets ? bmax_ : numOfBuckets);
301  std::vector<double> work(nmax);
302 
303  // Noise in the channel
304  for (int i=0; i<numOfBuckets; i++)
305  work[i] = CLHEP::RandGaussQ::shoot(engine, baseline, sigma);
306 
307 #ifdef DebugLog
308  LogDebug("HcalSim") << "HcalQie::getCode: Noise with baseline " << baseline
309  << " width " << sigma << " and " << nht << " hits";
310  for (int i=0; i<numOfBuckets; i++)
311  LogDebug("HcalSim") << "HcalQie: Code[" << i << "] = " << work[i];
312 #endif
313  double etot=0, esum=0, photons=0;
314  if (nht>0) {
315 
316  // Sort the hits
317  std::vector<const CaloHit*> hits(nht);
318  std::vector<const CaloHit*>::iterator k1, k2;
319  int kk;
320  for (kk = 0; kk < nht; kk++) {
321  hits[kk] = &hitbuf[kk];
322  }
323  sort(hits.begin(),hits.end(),CaloHitMore());
324 
325  // Energy deposits
326  for (kk = 0, k1 = hits.begin(); k1 != hits.end(); kk++, k1++) {
327  double ehit = (**k1).e();
328  double jitter= (**k1).t();
329  int jump = 0;
330  for (k2 = k1+1; k2 != hits.end() && (jitter-(**k2).t())<1. &&
331  (jitter-(**k2).t())>-1.; k2++) {
332  ehit += (**k2).e();
333  jump++;
334  }
335 
336  double avpe = ehit/eDepPerPE;
337  CLHEP::RandPoissonQ randPoissonQ(*engine, avpe);
338  double photo = randPoissonQ.fire();
339  etot += ehit;
340  photons+= photo;
341 #ifdef DebugLog
342  LogDebug("HcalSim") << "HcalQie::getCode: Hit " << kk << ":" << kk+jump
343  << " Energy deposit " << ehit << " Time " << jitter
344  << " Average and true no of PE " << avpe << " "
345  << photo;
346 #endif
347  double bintime = jitter - phase_ - bunchSpace*(binOfMax-bmin_);
348 #ifdef DebugLog
349  LogDebug("HcalSim") << "HcalQie::getCode: phase " << phase_
350  << " binTime " << bintime;
351 #endif
352  std::vector<double> binsum(nmax,0);
353  double norm=0, sum=0.;
354  for (int i=bmin_; i<bmax_; i++) {
355  bintime += bunchSpace;
356  for (int j=0; j<(int)(bunchSpace); j++) {
357  double tim = bintime + j;
358  double tmp = getShape(tim);
359  binsum[i] += tmp;
360  }
361  sum += binsum[i];
362  }
363 
364  if (sum>0) norm = (photo/(sum*qToPE));
365 #ifdef DebugLog
366  LogDebug("HcalSim") << "HcalQie::getCode: PE " << photo << " Sum " << sum
367  << " Norm. " << norm;
368 #endif
369  for (int i=bmin_; i<bmax_; i++)
370  work[i] += binsum[i]*norm;
371 
372  kk += jump;
373  k1 += jump;
374  }
375  }
376 
377  std::vector<int> temp(numOfBuckets,0);
378  for (int i=0; i<numOfBuckets; i++) {
379  temp[i] = getCode(work[i]);
380  esum += work[i];
381  }
382 #ifdef DebugLog
383  LogDebug("HcalSim") << "HcalQie::getCode: Input " << etot << " GeV; Photons "
384  << photons << "; Output " << esum << " fc";
385 #endif
386  return temp;
387 }
388 
389 
390 double HcalQie::getEnergy(const std::vector<int>& code) {
391 
392  std::vector<double> work(numOfBuckets);
393  double sum=0;
394  for (int i=0; i<numOfBuckets; i++) {
395  work[i] = codeToQ (code[i]);
396  sum += work[i]*weight_[i];
397 #ifdef DebugLog
398  LogDebug("HcalSim") << "HcalQie::getEnergy: " << i << " code " << code[i]
399  << " PE " << work[i];
400 #endif
401  }
402 
403  double tmp;
404  if (preSamples == 0) {
405  tmp = (sum - signalBuckets*baseline) * rescale_ * qToPE * eDepPerPE;
406  } else {
407  tmp = sum * rescale_ * qToPE;
408  }
409 #ifdef DebugLog
410  LogDebug("HcalSim") << "HcalQie::getEnergy: PE " << sum*qToPE << " Energy "
411  << tmp << " GeV";
412 #endif
413  return tmp;
414 }
#define LogDebug(id)
dbl * delta
Definition: mlp_gen.cc:36
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
std::vector< double > shape()
Definition: HcalQie.cc:74
int preSamples
Definition: HcalQie.h:43
virtual ~HcalQie()
Definition: HcalQie.cc:70
double eDepPerPE
Definition: HcalQie.h:45
double codeToQ(int ic)
Definition: HcalQie.cc:252
int bmax_
Definition: HcalQie.h:46
double baseline
Definition: HcalQie.h:45
HcalQie(edm::ParameterSet const &p)
Definition: HcalQie.cc:18
double charge(const std::vector< uint8_t > &Ampls)
int signalBuckets
Definition: HcalQie.h:43
double getShape(double time)
Definition: HcalQie.cc:285
std::vector< double > weight_
Definition: HcalQie.h:44
auto const T2 &decltype(t1.eta()) t2
Definition: deltaR.h:18
double getEnergy(const std::vector< int > &)
Definition: HcalQie.cc:390
std::vector< double > charge()
Definition: HcalQie.cc:195
int j
Definition: DBlmapReader.cc:9
double qToPE
Definition: HcalQie.h:45
int bmin_
Definition: HcalQie.h:46
double rescale_
Definition: HcalQie.h:47
std::vector< double > charge_
Definition: HcalQie.h:42
int k[5][pyjets_maxn]
static const double tmax[3]
std::vector< int > code_
Definition: HcalQie.h:41
double phase_
Definition: HcalQie.h:47
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
std::vector< int > getCode(int, const std::vector< CaloHit > &, CLHEP::HepRandomEngine *)
Definition: HcalQie.cc:296
int binOfMax
Definition: HcalQie.h:43
std::vector< double > shape_
Definition: HcalQie.h:40
double sigma
Definition: HcalQie.h:45
std::vector< double > weight(int binofmax, int mode, int npre, int numbucket)
Definition: HcalQie.cc:227
std::vector< int > code()
Definition: HcalQie.cc:163
int numOfBuckets
Definition: HcalQie.h:43