CMS 3D CMS Logo

HcalPulseShapes.cc
Go to the documentation of this file.
14 #include "CLHEP/Random/RandFlat.h"
15 
16 // #include "CalibCalorimetry/HcalAlgos/interface/HcalDbASCIIIO.h"
17 #include <cmath>
18 #include <iostream>
19 #include <fstream>
20 #include "TMath.h"
21 
23 : theMCParams(0),
24  theTopology(0),
25  theRecoParams(0),
26  theShapes()
27 {
28 /*
29 
30 Reco MC
31 --------------------------------------------------------------------------------------
32 000 not used (reserved)
33 101 101 hpdShape_ HPD (original version)
34 102 102 =101 HPD BV 30 volts in HBP iphi54
35 103 123 hpdShape_v2, hpdShapeMC_v2 HPD (2011. oct version)
36 104 124 hpdBV30Shape_v2, hpdBV30ShapeMC_v2 HPD bv30 in HBP iph54
37 105 125 hpdShape_v2, hpdShapeMC_v2 HPD (2011.11.12 version)
38 201 201 siPMShape_ SiPMs Zecotec shape (HO)
39 202 202 =201, SiPMs Hamamatsu shape (HO)
40 203 203 siPMShape2017_ SiPMs Hamamatsu shape (HE 2017)
41 301 301 hfShape_ regular HF PMT shape
42 401 401 regular ZDC shape
43 --------------------------------------------------------------------------------------
44 
45 */
46 
47 
48  float ts1, ts2, ts3, thpd, tpre, wd1, wd2, wd3;
49 
50  // HPD Shape Version 1 (used before CMSSW5, until Oct 2011)
51  ts1=8. ; ts2=10. ; ts3=29.3; thpd=4.0; tpre=9.0; wd1=2.0; wd2=0.7; wd3=1.0;
52  computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdShape_);
53  theShapes[101] = &hpdShape_;
54  theShapes[102] = theShapes[101];
55 
56  // HPD Shape Version 2 for CMSSW 5. Nov 2011 (RECO and MC separately)
57  ts1=8. ; ts2=10. ; ts3=25.0; thpd=4.0; tpre=9.0; wd1=2.0; wd2=0.7; wd3=1.0;
58  computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdShape_v2);
59  theShapes[103] = &hpdShape_v2;
60 
61  ts1=8. ; ts2=10. ; ts3=29.3; thpd=4.0; tpre=7.0; wd1=2.0; wd2=0.7; wd3=1.0;
62  computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdShapeMC_v2);
63  theShapes[123] = &hpdShapeMC_v2;
64 
65  // HPD Shape Version 3 for CMSSW 5. Nov 2011 (RECO and MC separately)
66  ts1=8. ; ts2=19. ; ts3=29.3; thpd=4.0; tpre=9.0; wd1=2.0; wd2=0.7; wd3=0.32;
67  computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdShape_v3);
68  theShapes[105] = &hpdShape_v3;
69 
70  ts1=8. ; ts2=10. ; ts3=22.3; thpd=4.0; tpre=7.0; wd1=2.0; wd2=0.7; wd3=1.0;
71  computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdShapeMC_v3);
72  theShapes[125] = &hpdShapeMC_v3;
73 
74  // HPD with Bias Voltage 30 volts, wider pulse. (HBPlus iphi54)
75 
76  ts1=8. ; ts2=12. ; ts3=31.7; thpd=9.0; tpre=9.0; wd1=2.0; wd2=0.7; wd3=1.0;
77  computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdBV30Shape_v2);
78  theShapes[104] = &hpdBV30Shape_v2;
79 
80  ts1=8. ; ts2=12. ; ts3=31.7; thpd=9.0; tpre=9.0; wd1=2.0; wd2=0.7; wd3=1.0;
81  computeHPDShape(ts1,ts2,ts3,thpd,tpre,wd1,wd2,wd3, hpdBV30ShapeMC_v2);
83 
84  // HF and SiPM
85 
89 
90  theShapes[201] = &siPMShape_;
91  theShapes[202] = theShapes[201];
92  theShapes[203] = &siPMShape2017_;
93  theShapes[301] = &hfShape_;
94  //theShapes[401] = new CaloCachedShapeIntegrator(&theZDCShape);
95 
96 }
97 
98 
100  if (theMCParams) delete theMCParams;
101  if (theRecoParams) delete theRecoParams;
102  if (theTopology) delete theTopology;
103 }
104 
105 
107 {
109  es.get<HcalMCParamsRcd>().get(p);
110  theMCParams = new HcalMCParams(*p.product());
111 
113  es.get<HcalRecNumberingRecord>().get(htopo);
114  theTopology=new HcalTopology(*htopo);
116 
118  es.get<HcalRecoParamsRcd>().get(q);
121 }
122 
123 
125 {
126  if (theMCParams) delete theMCParams;
127  if (theRecoParams) delete theRecoParams;
128  if (theTopology) delete theTopology;
129 
130 
131  theMCParams = 0;
132  theRecoParams = 0;
133  theTopology = 0;
134 }
135 
136 
137 //void HcalPulseShapes::computeHPDShape()
138 void HcalPulseShapes::computeHPDShape(float ts1, float ts2, float ts3, float thpd, float tpre,
139  float wd1, float wd2, float wd3, Shape &tmphpdShape_)
140 {
141 
142 // pulse shape time constants in ns
143 /*
144  const float ts1 = 8.; // scintillation time constants : 1,2,3
145  const float ts2 = 10.;
146  const float ts3 = 29.3;
147  const float thpd = 4.; // HPD current collection drift time
148  const float tpre = 9.; // preamp time constant (refit on TB04 data)
149 
150  const float wd1 = 2.; // relative weights of decay exponents
151  const float wd2 = 0.7;
152  const float wd3 = 1.;
153 */
154  // pulse shape components over a range of time 0 ns to 255 ns in 1 ns steps
155  unsigned int nbin = 256;
156  tmphpdShape_.setNBin(nbin);
157  std::vector<float> ntmp(nbin,0.0); // zeroing output pulse shape
158  std::vector<float> nth(nbin,0.0); // zeroing HPD drift shape
159  std::vector<float> ntp(nbin,0.0); // zeroing Binkley preamp shape
160  std::vector<float> ntd(nbin,0.0); // zeroing Scintillator decay shape
161 
162  unsigned int i,j,k;
163  float norm;
164 
165  // HPD starts at I and rises to 2I in thpd of time
166  norm=0.0;
167  for(j=0;j<thpd && j<nbin;j++){
168  nth[j] = 1.0 + ((float)j)/thpd;
169  norm += nth[j];
170  }
171  // normalize integrated current to 1.0
172  for(j=0;j<thpd && j<nbin;j++){
173  nth[j] /= norm;
174  }
175 
176  // Binkley shape over 6 time constants
177  norm=0.0;
178  for(j=0;j<6*tpre && j<nbin;j++){
179  ntp[j] = ((float)j)*exp(-((float)(j*j))/(tpre*tpre));
180  norm += ntp[j];
181  }
182  // normalize pulse area to 1.0
183  for(j=0;j<6*tpre && j<nbin;j++){
184  ntp[j] /= norm;
185  }
186 
187 // ignore stochastic variation of photoelectron emission
188 // <...>
189 
190 // effective tile plus wave-length shifter decay time over 4 time constants
191  unsigned int tmax = 6 * (int)ts3;
192 
193  norm=0.0;
194  for(j=0;j<tmax && j<nbin;j++){
195  ntd[j] = wd1 * exp(-((float)j)/ts1) +
196  wd2 * exp(-((float)j)/ts2) +
197  wd3 * exp(-((float)j)/ts3) ;
198  norm += ntd[j];
199  }
200  // normalize pulse area to 1.0
201  for(j=0;j<tmax && j<nbin;j++){
202  ntd[j] /= norm;
203  }
204 
205  unsigned int t1,t2,t3,t4;
206  for(i=0;i<tmax && i<nbin;i++){
207  t1 = i;
208  // t2 = t1 + top*rand;
209  // ignoring jitter from optical path length
210  t2 = t1;
211  for(j=0;j<thpd && j<nbin;j++){
212  t3 = t2 + j;
213  for(k=0;k<4*tpre && k<nbin;k++){ // here "4" is set deliberately,
214  t4 = t3 + k; // as in test fortran toy MC ...
215  if(t4<nbin){
216  unsigned int ntb=t4;
217  ntmp[ntb] += ntd[i]*nth[j]*ntp[k];
218  }
219  }
220  }
221  }
222 
223  // normalize for 1 GeV pulse height
224  norm = 0.;
225  for(i=0;i<nbin;i++){
226  norm += ntmp[i];
227  }
228 
229  for(i=0; i<nbin; i++){
230  ntmp[i] /= norm;
231  }
232 
233  for(i=0; i<nbin; i++){
234  tmphpdShape_.setShapeBin(i,ntmp[i]);
235  }
236 }
237 
239  // first create pulse shape over a range of time 0 ns to 255 ns in 1 ns steps
240  unsigned int nbin = 256;
241  hfShape_.setNBin(nbin);
242  std::vector<float> ntmp(nbin,0.0); //
243 
244  const float k0=0.7956; // shape parameters
245  const float p2=1.355;
246  const float p4=2.327;
247  const float p1=4.3; // position parameter
248 
249  float norm = 0.0;
250 
251  for(unsigned int j = 0; j < 25 && j < nbin; ++j){
252 
253  float r0 = j-p1;
254  float sigma0 = (r0<0) ? p2 : p2*p4;
255  r0 /= sigma0;
256  if(r0 < k0) ntmp[j] = exp(-0.5*r0*r0);
257  else ntmp[j] = exp(0.5*k0*k0-k0*r0);
258  norm += ntmp[j];
259  }
260  // normalize pulse area to 1.0
261  for(unsigned int j = 0; j < 25 && j < nbin; ++j){
262  ntmp[j] /= norm;
263  hfShape_.setShapeBin(j,ntmp[j]);
264  }
265 }
266 
267 
269 {
270 
271  unsigned int nbin = 128;
272 
273 //From Jake Anderson: toy MC convolution of SiPM pulse + WLS fiber shape + SiPM nonlinear response
274  std::vector<float> nt = {
275  2.782980485851731e-6,
276  4.518134885954626e-5,
277  2.7689305197392056e-4,
278  9.18328418900969e-4,
279  .002110072599166349,
280  .003867856860331454,
281  .006120046224897771,
282  .008754774090536956,
283  0.0116469503358586,
284  .01467007449455966,
285  .01770489955229477,
286  .02064621450689512,
287  .02340678093764222,
288  .02591874610854916,
289  .02813325527435303,
290  0.0300189241965647,
291  .03155968107671164,
292  .03275234052577155,
293  .03360415306318798,
294  .03413048377960748,
295  .03435270899678218,
296  .03429637464659661,
297  .03398962975487166,
298  .03346192884394954,
299  .03274298516247742,
300  .03186195009136525,
301  .03084679116113031,
302  0.0297238406141036,
303  .02851748748929785,
304  .02724998816332392,
305  .02594137274487424,
306  .02460942736731527,
307  .02326973510736116,
308  .02193576080366117,
309  0.0206189674254987,
310  .01932895378564653,
311  0.0180736052958666,
312  .01685925112650875,
313  0.0156908225633535,
314  .01457200857138456,
315  .01350540559602467,
316  .01249265947824805,
317  .01153459805300423,
318  .01063135355597282,
319  .009782474412011936,
320  .008987026319784546,
321  0.00824368281357106,
322  .007550805679909604,
323  .006906515742762193,
324  .006308754629755056,
325  .005755338185695127,
326  .005244002229973356,
327  .004772441359900532,
328  .004338341490928299,
329  .003939406800854143,
330  0.00357338171220501,
331  0.0032380685079891,
332  .002931341133259233,
333  .002651155690306086,
334  .002395558090237333,
335  .002162689279320922,
336  .001950788415487319,
337  .001758194329648101,
338  .001583345567913682,
339  .001424779275191974,
340  .001281129147671334,
341  0.00115112265163774,
342  .001033577678808199,
343  9.273987838127585e-4,
344  8.315731274976846e-4,
345  7.451662302008696e-4,
346  6.673176219006913e-4,
347  5.972364609644049e-4,
348  5.341971801529036e-4,
349  4.775352065178378e-4,
350  4.266427928961177e-4,
351  3.8096498904225923e-4,
352  3.3999577417327287e-4,
353  3.032743659102713e-4,
354  2.703817158798329e-4,
355  2.4093719775272793e-4,
356  2.145954900503894e-4,
357  1.9104365317752797e-4,
358  1.6999839784346724e-4,
359  1.5120354022478893e-4,
360  1.3442763782650755e-4,
361  1.1946179895521507e-4,
362  1.0611765796993575e-4,
363  9.422550797617687e-5,
364  8.363258233342666e-5,
365  7.420147621931836e-5,
366  6.580869950304933e-5,
367  5.834335229919868e-5,
368  5.17059147771959e-5,
369  4.5807143072062634e-5,
370  4.0567063461299446e-5,
371  3.591405732740723e-5,
372  3.178402980354131e-5,
373  2.811965539165646e-5,
374  2.4869694240316126e-5,
375  2.1988373166730962e-5,
376  1.9434825899529382e-5,
377  1.717258740121378e-5,
378  1.5169137499243157e-5,
379  1.339548941011129e-5,
380  1.1825819079078403e-5,
381  1.0437131581057595e-5,
382  9.208961130078894e-6,
383  8.12310153137994e-6,
384  7.163364176588591e-6,
385  6.315360932244386e-6,
386  5.566309502463164e-6,
387  4.904859063429651e-6,
388  4.320934164082596e-6,
389  3.8055950719111903e-6,
390  3.350912911083174e-6,
391  2.9498580949517117e-6,
392  2.596200697612328e-6,
393  2.2844215378879293e-6,
394  2.0096328693141094e-6,
395  1.7675076766686654e-6,
396  1.5542166787225756e-6,
397  1.366372225473431e-6,
398  1.200978365778838e-6,
399  1.0553864128982371e-6,
400  9.272554464808518e-7,
401  8.145171945902259e-7,
402  7.153448381918271e-7
403  };
404 
405  siPMShape_.setNBin(nbin);
406 
407  double norm = 0.;
408  for (unsigned int j = 0; j < nbin; ++j) {
409  norm += (nt[j]>0) ? nt[j] : 0.;
410  }
411 
412  for (unsigned int j = 0; j < nbin; ++j) {
413  nt[j] /= norm;
414  siPMShape_.setShapeBin(j,nt[j]);
415  }
416 }
417 
419 {
420  //numerical convolution of SiPM pulse + WLS fiber shape
422 
424 
425  //skip first bin, always 0
426  double norm = 0.;
427  for (unsigned int j = 1; j <= nBinsSiPM_; ++j) {
428  norm += (nt[j]>0) ? nt[j] : 0.;
429  }
430 
431  for (unsigned int j = 1; j <= nBinsSiPM_; ++j) {
432  nt[j] /= norm;
433  siPMShape2017_.setShapeBin(j,nt[j]);
434  }
435 }
436 
438 HcalPulseShapes::getShape(int shapeType) const
439 {
440  ShapeMap::const_iterator shapeMapItr = theShapes.find(shapeType);
441  if(shapeMapItr == theShapes.end()) {
442  throw cms::Exception("HcalPulseShapes") << "unknown shapeType";
443  return hpdShape_; // should not return this, but...
444  } else {
445  return *(shapeMapItr->second);
446  }
447 }
448 
449 
451 HcalPulseShapes::shape(const HcalDetId & detId) const
452 {
453  if(!theMCParams) {
454  return defaultShape(detId);
455  }
456  int shapeType = theMCParams->getValues(detId)->signalShape();
457 
458  ShapeMap::const_iterator shapeMapItr = theShapes.find(shapeType);
459  if(shapeMapItr == theShapes.end()) {
460  return defaultShape(detId);
461  } else {
462  return *(shapeMapItr->second);
463  }
464 }
465 
468 {
469  if(!theRecoParams) {
470  return defaultShape(detId);
471  }
472  int shapeType = theRecoParams->getValues(detId.rawId())->pulseShapeID();
473 
474  ShapeMap::const_iterator shapeMapItr = theShapes.find(shapeType);
475  if(shapeMapItr == theShapes.end()) {
476  return defaultShape(detId);
477  } else {
478  return *(shapeMapItr->second);
479  }
480 }
481 
482 
485 {
486  edm::LogWarning("HcalPulseShapes") << "Cannot find HCAL MC Params ";
487  HcalSubdetector subdet = detId.subdet();
488  switch(subdet) {
489  case HcalBarrel:
490  return hbShape();
491  case HcalEndcap:
492  return heShape();
493  case HcalForward:
494  return hfShape();
495  case HcalOuter:
496  //FIXME doesn't look for SiPMs
497  return hoShape(false);
498  default:
499  throw cms::Exception("HcalPulseShapes") << "unknown detId";
500  break;
501  }
502 }
503 
504 //SiPM helpers
505 
506 inline double gexp(double t, double A, double c, double t0, double s) {
507  static double const root2(sqrt(2));
508  return -A*0.5*exp(c*t+0.5*c*c*s*s-c*s)*(erf(-0.5*root2/s*(t-t0+c*s*s))-1);
509 }
510 
511 inline double onePulse(double t, double A, double sigma, double theta, double m) {
512  return (t<theta) ? 0 : A*TMath::LogNormal(t,sigma,theta,m);
513 }
514 
516  // HO SiPM pulse shape fit from Jake Anderson ca. 2013
517  double A1(0.08757), c1(-0.5257), t01(2.4013), s1(0.6721);
518  double A2(0.007598), c2(-0.1501), t02(6.9412), s2(0.8710);
519  return gexp(t,A1,c1,t01,s1) + gexp(t,A2,c2,t02,s2);
520 }
521 
523  // taken from fit to laser measurement taken by Iouri M. in Spring 2016.
524  double A1(5.204/6.94419), sigma1_shape(0.5387), theta1_loc(-0.3976), m1_scale(4.428);
525  double A2(1.855/6.94419), sigma2_shape(0.8132), theta2_loc(7.025), m2_scale(12.29);
526  return
527  onePulse(t,A1,sigma1_shape,theta1_loc,m1_scale) +
528  onePulse(t,A2,sigma2_shape,theta2_loc,m2_scale);
529 }
530 
531 double HcalPulseShapes::generatePhotonTime(CLHEP::HepRandomEngine* engine) {
532  double result(0.);
533  while (true) {
534  result = CLHEP::RandFlat::shoot(engine, HcalPulseShapes::Y11RANGE_);
535  if (CLHEP::RandFlat::shoot(engine, HcalPulseShapes::Y11MAX_) < HcalPulseShapes::Y11TimePDF(result))
536  return result;
537  }
538 }
539 
541  return exp(-0.0635-0.1518*t)*pow(t, 2.528)/2485.9;
542 }
const Shape & getShape(int shapeType) const
void setNBin(int n)
const Shape & heShape() const
HcalSubdetector subdet() const
get the subdetector
Definition: HcalDetId.h:49
void setShapeBin(int i, float f)
const Shape & hoShape(bool sipm=false) const
void beginRun(edm::EventSetup const &es)
Geom::Theta< T > theta() const
static constexpr float Y11MAX_
const Item * getValues(DetId fId, bool throwOnFail=true) const
static const int nBinsSiPM_
const Shape & shapeForReco(const HcalDetId &detId) const
static double analyticPulseShapeSiPMHE(double t)
double onePulse(double t, double A, double sigma, double theta, double m)
const Shape & shape(const HcalDetId &detId) const
automatically figures out which shape to return
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
HcalRecoParams * theRecoParams
static std::vector< double > convolve(unsigned nbin, F1 f1, F2 f2)
auto const T2 &decltype(t1.eta()) t2
Definition: deltaR.h:16
T sqrt(T t)
Definition: SSEVec.h:18
double p4[4]
Definition: TauolaWrapper.h:92
HcalSubdetector
Definition: HcalAssistant.h:31
static double generatePhotonTime(CLHEP::HepRandomEngine *engine)
double p2[4]
Definition: TauolaWrapper.h:90
int nt
Definition: AMPTWrapper.h:32
int k[5][pyjets_maxn]
static const double tmax[3]
const Shape & defaultShape(const HcalDetId &detId) const
in case of conditions problems
const Shape & hfShape() const
void computeHPDShape(float, float, float, float, float, float, float, float, Shape &)
const HcalTopology * theTopology
HcalMCParams * theMCParams
const T & get() const
Definition: EventSetup.h:56
double gexp(double t, double A, double c, double t0, double s)
unsigned int signalShape() const
Definition: HcalMCParam.h:40
const Shape & hbShape() const
double p1[4]
Definition: TauolaWrapper.h:89
static constexpr float Y11RANGE_
static double Y11TimePDF(double t)
T const * product() const
Definition: ESHandle.h:86
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
void setTopo(const HcalTopology *topo)
static double analyticPulseShapeSiPMHO(double t)