CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EMShower.cc
Go to the documentation of this file.
1 //FAMOS Headers
6 
9 
12 
13 
14 #include <cmath>
15 
16 //#include "FastSimulation/Utilities/interface/Histos.h"
17 
18 using std::vector;
19 
20 
23  EMECALShowerParametrization* const myParam,
24  vector<const RawParticle*>* const myPart,
25  DQMStore * const dbeIn,
26  EcalHitMaker * const myGrid,
27  PreshowerHitMaker * const myPresh,
28  bool bFixedLength)
29 
30  : theParam(myParam),
31  thePart(myPart),
32  theGrid(myGrid),
33  thePreshower(myPresh),
34  random(engine),
35  myGammaGenerator(gamma),
36  bFixedLength_(bFixedLength)
37 {
38 
39  // Get the Famos Histos pointer
40  // myHistos = Histos::instance();
41  // myGammaGenerator = GammaFunctionGenerator::instance();
42  stepsCalculated=false;
43  hasPreshower = myPresh!=NULL;
44  theECAL = myParam->ecalProperties();
45  theHCAL = myParam->hcalProperties();
46  theLayer1 = myParam->layer1Properties();
47  theLayer2 = myParam->layer2Properties();
48 
49 
50  double fotos = theECAL->photoStatistics()
52 
53  dbe = dbeIn;
54 
55  nPart = thePart->size();
56  totalEnergy = 0.;
57  globalMaximum = 0.;
58  double meanDepth=0.;
59  // Initialize the shower parameters for each particle
60 
61  if (dbe) {
62  dbe->cd();
63  if (!dbe->get("EMShower/NumberOfParticles")) {}//std::cout << "NOT FOUND IN Shower.cc" << std::endl;}
64  else {
65  dbe->get("EMShower/NumberOfParticles")->Fill(nPart);
66  }
67  }
68 
69 
70  for ( unsigned int i=0; i<nPart; ++i ) {
71  // std::cout << " AAA " << *(*thePart)[i] << std::endl;
72  // The particle and the shower energy
73  Etot.push_back(0.);
74  E.push_back(((*thePart)[i])->e());
75  totalEnergy+=E[i];
76 
77 
78 
79  if (dbe) {
80  dbe->cd();
81  if (!dbe->get("EMShower/ParticlesEnergy")) {}//std::cout << "NOT FOUND IN Shower.cc" << std::endl;}
82  else {
83  dbe->get("EMShower/ParticlesEnergy")->Fill(log10(E[i]));
84  }
85  }
86 
87 
88 
89 
90 
91 
92 
93  double lny = std::log ( E[i] / theECAL->criticalEnergy() );
94 
95  // Average and Sigma for T and alpha
96  double theMeanT = myParam->meanT(lny);
97  double theMeanAlpha = myParam->meanAlpha(lny);
98  double theMeanLnT = myParam->meanLnT(lny);
99  double theMeanLnAlpha = myParam->meanLnAlpha(lny);
100  double theSigmaLnT = myParam->sigmaLnT(lny);
101  double theSigmaLnAlpha = myParam->sigmaLnAlpha(lny);
102 
103 
104  // The correlation matrix
105  double theCorrelation = myParam->correlationAlphaT(lny);
106  double rhop = std::sqrt( (1.+theCorrelation)/2. );
107  double rhom = std::sqrt( (1.-theCorrelation)/2. );
108 
109  // The number of spots in ECAL / HCAL
110  theNumberOfSpots.push_back(myParam->nSpots(E[i]));
111  // theNumberOfSpots.push_back(myParam->nSpots(E[i])*spotFraction);
112  //theNumberOfSpots = random->poissonShoot(myParam->nSpots(myPart->e()));
113 
114  // Photo-statistics
115  photos.push_back(E[i] * fotos);
116 
117  // The longitudinal shower development parameters
118  // Fluctuations of alpha, T and beta
119  double z1=0.;
120  double z2=0.;
121  double aa=0.;
122 
123  // Protect against too large fluctuations (a < 1) for small energies
124  while ( aa <= 1. ) {
125  z1 = random->gaussShoot(0.,1.);
126  z2 = random->gaussShoot(0.,1.);
127  aa = std::exp(theMeanLnAlpha + theSigmaLnAlpha * (z1*rhop-z2*rhom));
128  }
129 
130  a.push_back(aa);
131  T.push_back(std::exp(theMeanLnT + theSigmaLnT * (z1*rhop+z2*rhom)));
132  b.push_back((a[i]-1.)/T[i]);
133  maximumOfShower.push_back((a[i]-1.)/b[i]);
135  meanDepth += a[i]/b[i]*E[i];
136  // std::cout << " Adding max " << maximumOfShower[i] << " " << E[i] << " " <<maximumOfShower[i]*E[i] << std::endl;
137  // std::cout << std::setw(8) << std::setprecision(5) << " a /b " << a[i] << " " << b[i] << std::endl;
138  Ti.push_back(
139  a[i]/b[i] * (std::exp(theMeanLnAlpha)-1.) / std::exp(theMeanLnAlpha));
140 
141  // The parameters for the number of energy spots
142  TSpot.push_back(theParam->meanTSpot(theMeanT));
143  aSpot.push_back(theParam->meanAlphaSpot(theMeanAlpha));
144  bSpot.push_back((aSpot[i]-1.)/TSpot[i]);
145  // myHistos->fill("h7000",a[i]);
146  // myHistos->fill("h7002",E[i],a[i]);
147  }
148 // std::cout << " PS1 : " << myGrid->ps1TotalX0()
149 // << " PS2 : " << myGrid->ps2TotalX0()
150 // << " ECAL : " << myGrid->ecalTotalX0()
151 // << " HCAL : " << myGrid->hcalTotalX0()
152 // << " Offset : " << myGrid->x0DepthOffset()
153 // << std::endl;
154 
156  meanDepth/=totalEnergy;
157  // std::cout << " Total Energy " << totalEnergy << " Global max " << globalMaximum << std::endl;
158 }
159 
161 {
162  // TimeMe theT("EMShower::compute");
163 
164  // Determine the longitudinal intervals
165  // std::cout << " EMShower compute" << std::endl;
166  double dt;
167  double radlen;
168  int stps;
169  int first_Ecal_step=0;
170  int last_Ecal_step=0;
171 
172  // The maximum is in principe 8 (with 5X0 steps in the ECAL)
173  steps.reserve(24);
174 
175  /*
176  std::cout << " PS1 : " << theGrid->ps1TotalX0()
177  << " PS2 : " << theGrid->ps2TotalX0()
178  << " PS2 and ECAL : " << theGrid->ps2eeTotalX0()
179  << " ECAL : " << theGrid->ecalTotalX0()
180  << " HCAL : " << theGrid->hcalTotalX0()
181  << " Offset : " << theGrid->x0DepthOffset()
182  << std::endl;
183  */
184 
185  radlen = -theGrid->x0DepthOffset();
186 
187  // Preshower Layer 1
188  radlen += theGrid->ps1TotalX0();
189  if ( radlen > 0. ) {
190  steps.push_back(Step(0,radlen));
191  radlen = 0.;
192  }
193 
194  // Preshower Layer 2
195  radlen += theGrid->ps2TotalX0();
196  if ( radlen > 0. ) {
197  steps.push_back(Step(1,radlen));
198  radlen = 0.;
199  }
200 
201  // add a step between preshower and ee
202  radlen += theGrid->ps2eeTotalX0();
203  if ( radlen > 0.) {
204  steps.push_back(Step(5,radlen));
205  radlen = 0.;
206  }
207 
208  // ECAL
209  radlen += theGrid->ecalTotalX0();
210 
211  // std::cout << "theGrid->ecalTotalX0() = " << theGrid->ecalTotalX0() << std::endl;
212 
213  if ( radlen > 0. ) {
214 
215  if (!bFixedLength_){
216  stps=(int)((radlen+2.5)/5.);
217  // stps=(int)((radlen+.5)/1.);
218  if ( stps == 0 ) stps = 1;
219  dt = radlen/(double)stps;
220  Step step(2,dt);
221  first_Ecal_step=steps.size();
222  for ( int ist=0; ist<stps; ++ist )
223  steps.push_back(step);
224  last_Ecal_step=steps.size()-1;
225  radlen = 0.;
226  } else {
227  dt = 1.0;
228  stps = static_cast<int>(radlen);
229  if (stps == 0) stps = 1;
230  Step step(2,dt);
231  first_Ecal_step=steps.size();
232  for ( int ist=0; ist<stps; ++ist ) steps.push_back(step);
233  dt = radlen-stps;
234  if (dt>0) {
235  Step stepLast (2,dt);
236  steps.push_back(stepLast);
237  }
238  last_Ecal_step=steps.size()-1;
239  // std::cout << "radlen = " << radlen << " stps = " << stps << " dt = " << dt << std::endl;
240  radlen = 0.;
241 
242  }
243  }
244 
245  // I should had a gap here !
246 
247  // HCAL
248  radlen += theGrid->hcalTotalX0();
249  if ( radlen > 0. ) {
250  double dtFrontHcal=theGrid->totalX0()-theGrid->hcalTotalX0();
251  // One single step for the full HCAL
252  if(dtFrontHcal<30.)
253  {
254  dt=30.-dtFrontHcal;
255  Step step(3,dt);
256  steps.push_back(step);
257  }
258  }
259 
260  nSteps=steps.size();
261  if(nSteps==0) return;
262  double ESliceTot=0.;
263  double MeanDepth=0.;
264  depositedEnergy.resize(nSteps);
265  meanDepth.resize(nSteps);
266  double t=0.;
267 
268  int offset=0;
269  for(unsigned iStep=0;iStep<nSteps;++iStep)
270  {
271  ESliceTot=0.;
272  MeanDepth=0.;
273  double realTotalEnergy=0;
274  dt=steps[iStep].second;
275  t+=dt;
276  for ( unsigned int i=0; i<nPart; ++i ) {
277  depositedEnergy[iStep].push_back(deposit(t,a[i],b[i],dt));
278  ESliceTot +=depositedEnergy[iStep][i];
279  MeanDepth += deposit(t,a[i]+1.,b[i],dt)/b[i]*a[i];
280  realTotalEnergy+=depositedEnergy[iStep][i]*E[i];
281  }
282 
283  if( ESliceTot > 0. ) // can happen for the shower tails; this depth will be skipped anyway
284  MeanDepth/=ESliceTot;
285  else
286  MeanDepth=t-dt;
287 
288  meanDepth[iStep]=MeanDepth;
289  if(realTotalEnergy<0.001)
290  {
291  offset-=1;
292  }
293  }
294 
295  innerDepth=meanDepth[first_Ecal_step];
296  if(last_Ecal_step+offset>=0)
297  outerDepth=meanDepth[last_Ecal_step+offset];
298  else
300 
301  stepsCalculated=true;
302 }
303 
304 void
306 
307  double samplingWidth = theECAL->da() + theECAL->dp();
308  double theECALX0 = theECAL->radLenIncm();
309 
310  // double one_over_resoSquare = 1./(theECAL->resE()*theECAL->resE());
311 
312 
313 
314 
315 
316  double t = 0.;
317  double dt = 0.;
319 
320  // Prepare the grids in EcalHitMaker
321  // theGrid->setInnerAndOuterDepth(innerDepth,outerDepth);
322  float pstot=0.;
323  float ps2tot=0.;
324  float ps1tot=0.;
325  bool status=false;
326  // double E1 = 0.; // Energy layer 1
327  // double E2 = 0.; // Energy layer 2
328  // double n1 = 0.; // #mips layer 1
329  // double n2 = 0.; // #mips layer 2
330  // double E9 = 0.; // Energy ECAL
331 
332  // Loop over all segments for the longitudinal development
333  double totECalc = 0;
334 
335 
336 
337  for (unsigned iStep=0; iStep<nSteps; ++iStep ) {
338 
339  // The length of the shower in this segment
340  dt = steps[iStep].second;
341 
342  // std::cout << " Detector " << steps[iStep].first << " t " << t << " " << dt << std::endl;
343 
344  // The elapsed length
345  t += dt;
346 
347  // In what detector are we ?
348  unsigned detector=steps[iStep].first;
349 
350  bool presh1 = detector==0;
351  bool presh2 = detector==1;
352  bool ecal = detector==2;
353  bool hcal = detector==3;
354  bool vfcal = detector==4;
355  bool gap = detector==5;
356 
357  // Temporary. Will be removed
358  if ( theHCAL==NULL) hcal=false;
359 
360  // Keep only ECAL for now
361  if ( vfcal ) continue;
362 
363  // Nothing to do in the gap
364  if( gap ) continue;
365 
366  // cout << " t = " << t << endl;
367  // Build the grid of crystals at this ECAL depth
368  // Actually, it might be useful to check if this grid is empty or not.
369  // If it is empty (because no crystal at this depth), it is of no use
370  // (and time consuming) to generate the spots
371 
372 
373  // middle of the step
374  double tt = t-0.5*dt;
375 
376  double realTotalEnergy=0.;
377  for ( unsigned int i=0; i<nPart; ++i ) {
378  realTotalEnergy += depositedEnergy[iStep][i]*E[i];
379  }
380 
381 // std::cout << " Step " << tt << std::endl;
382 // std::cout << "ecal " << ecal << " hcal " << hcal <<std::endl;
383 
384  // If the amount of energy is greater than 1 MeV, make a new grid
385  // otherwise put in the previous one.
386  bool usePreviousGrid=(realTotalEnergy<0.001);
387 
388  // If the amount of energy is greater than 1 MeV, make a new grid
389  // otherwise put in the previous one.
390 
391  // If less than 1 kEV. Just skip
392  if(iStep>2&&realTotalEnergy<0.000001) continue;
393 
394  if (ecal && !usePreviousGrid)
395  {
396  status=theGrid->getPads(meanDepth[iStep]);
397  }
398  if (hcal)
399  {
400  status=theHcalHitMaker->setDepth(tt);
401  }
402  if((ecal || hcal) && !status) continue;
403 
404  bool detailedShowerTail=false;
405  // check if a detailed treatment of the rear leakage should be applied
406  if(ecal && !usePreviousGrid)
407  {
408  detailedShowerTail=(t-dt > theGrid->getX0back());
409  }
410 
411  // The particles of the shower are processed in parallel
412  for ( unsigned int i=0; i<nPart; ++i ) {
413 
414  // double Edepo=deposit(t,a[i],b[i],dt);
415 
416  // integration of the shower profile between t-dt and t
417  double dE = (!hcal)? depositedEnergy[iStep][i]:1.-deposit(a[i],b[i],t-dt);
418 
419  // no need to do the full machinery if there is ~nothing to distribute)
420  if(dE*E[i]<0.000001) continue;
421 
422 
423  if (ecal && !theECAL->isHom()) {
424  double mean = dE*E[i];
425  double sigma = theECAL->resE()*sqrt(mean);
426 
427  /*
428  double meanLn = log(mean);
429  double kLn = sigma/mean+1;
430  double sigmaLn = log(kLn);
431  */
432 
433  double dE0 = dE;
434 
435  // std::cout << "dE before shoot = " << dE << std::endl;
436  dE = random->gaussShoot(mean, sigma)/E[i];
437 
438  // myGammaGenerator->setParameters(aSam,bSam,0);
439  // dE = myGammaGenerator->shoot()/E[i];
440  // std::cout << "dE shooted = " << dE << " E[i] = " << E[i] << std::endl;
441  if (dE*E[i] < 0.000001) continue;
442  photos[i] = photos[i]*dE/dE0;
443 
444  }
445 
446 
447 
448  /*
449  if (ecal && !theParam->ecalProperties()->isHom()){
450 
451  double cSquare = TMath::Power(theParam->ecalProperties()->resE(),2);
452  double aSam = dE/cSquare;
453  double bSam = 1./cSquare;
454 
455  // dE = dE*gam(bSam*dE, aSam)/tgamma(aSam);
456  }
457  */
458 
459  totECalc +=dE;
460 
461  if (dbe && fabs(dt-1.)< 1e-5 && ecal) {
462  dbe->cd();
463  if (!dbe->get("EMShower/LongitudinalShape")) {}//std::cout << "NOT FOUND IN Shower.cc" << std::endl;}
464  else {
465  double dx = 1.;
466  // dE is aready in relative units from 0 to 1
467  dbe->get("EMShower/LongitudinalShape")->Fill(t, dE/dx);
468 
469  double step = theECALX0/samplingWidth;
470  double binMin = abs((t-1)*step)+1;
471  double binMax = abs(t*step)+1;
472  double dBins = binMax-binMin;
473 
474  /*
475  std::cout << "X0 = " << theECALX0 << " Sampling Width = " << samplingWidth << " t = " << t
476  << " binMin = " << binMin << " binMax = " << binMax << " (t-1)*step = "
477  << (t-1)*step+1 << " t*step = " << t*step+1 << std::endl;
478  */
479 
480  if ( dBins < 1) {
481  dbe->get("EMShower/LongitudinalShapeLayers")->Fill(binMin, dE/dx);
482  // std::cout << "bin " << binMin << " filled" << std::endl;
483  }
484  else {
485 
486 
487  double w1 = (binMin + 1 - (t-1)*step - 1)/step;
488  double w2 = 1./step;
489  double w3 = (t*step+1-binMax)/step;
490 
491  //double Esum = 0;
492 
493  /*
494  std::cout <<" ((t-1)*step - binMin) = " << (binMin + 1 - (t-1)*step - 1)
495  <<" w1 = " << w1 << " w2 = " << w2 << " w3 = " << w3
496  << " (t*step+1 - binMax) = " << (t*step+1 - binMax) << std::endl;
497 
498  std::cout << "fill bin = " << binMin << std::endl;
499  */
500 
501  dbe->get("EMShower/LongitudinalShapeLayers")->Fill(binMin, dE/dx*w1);
502  //Esum = dE/dx*w1;
503 
504  for (int iBin = 1; iBin < dBins; iBin++){
505  // std::cout << "fill bin = " << binMin+iBin << std::endl;
506  dbe->get("EMShower/LongitudinalShapeLayers")->Fill(binMin+iBin, dE/dx*w2);
507  // Esum += dE/dx*w2;
508  }
509 
510  // std::cout << "fill bin = " << binMax << std::endl;
511  dbe->get("EMShower/LongitudinalShapeLayers")->Fill(binMax, dE/dx*w3);
512  // Esum += dE/dx*w3;
513  // std::cout << "Esum = " << Esum << " dE/dx = " << dE/dx << std::endl;
514  }
515 
516 
517  }
518  //(dbe->get("TransverseShape"))->Fill(ri,log10(1./1000.*eSpot/0.2));
519 
520  }
521 
522  // The number of energy spots (or mips)
523  double nS = 0;
524 
525  // ECAL case : Account for photostatistics and long'al non-uniformity
526  if (ecal) {
527 
528 
529  // double aSam = E[i]*dE*one_over_resoSquare;
530  // double bSam = one_over_resoSquare;
531 
532 
533  dE = random->poissonShoot(dE*photos[i])/photos[i];
534  double z0 = random->gaussShoot(0.,1.);
535  dE *= 1. + z0*theECAL->lightCollectionUniformity();
536 
537  // Expected spot number
538  nS = ( theNumberOfSpots[i] * gam(bSpot[i]*tt,aSpot[i])
539  * bSpot[i] * dt
540  / tgamma(aSpot[i]) );
541 
542  // Preshower : Expected number of mips + fluctuation
543  }
544  else if ( hcal ) {
545 
546  nS = ( theNumberOfSpots[i] * gam(bSpot[i]*tt,aSpot[i])
547  * bSpot[i] * dt
548  / tgamma(aSpot[i]))* theHCAL->spotFraction();
549  double nSo = nS ;
550  nS = random->poissonShoot(nS);
551  // 'Quick and dirty' fix (but this line should be better removed):
552  if( nSo > 0. && nS/nSo < 10.) dE *= nS/nSo;
553 
554 // if(true)
555 // {
556 // std::cout << " theHCAL->spotFraction = " <<theHCAL->spotFraction() <<std::endl;
557 // std::cout << " nSpot Ecal : " << nSo/theHCAL->spotFraction() << " Final " << nS << std::endl;
558 // }
559  }
560  else if ( presh1 ) {
561 
562  nS = random->poissonShoot(dE*E[i]*theLayer1->mipsPerGeV());
563  // std::cout << " dE *E[i] (1)" << dE*E[i] << " " << dE*E[i]*theLayer1->mipsPerGeV() << " "<< nS << std::endl;
564  pstot+=dE*E[i];
565  ps1tot+=dE*E[i];
566  dE = nS/(E[i]*theLayer1->mipsPerGeV());
567 
568  // E1 += dE*E[i];
569  // n1 += nS;
570  // if (presh2) { E2 += SpotEnergy; ++n2; }
571 
572  } else if ( presh2 ) {
573 
574  nS = random->poissonShoot(dE*E[i]*theLayer2->mipsPerGeV());
575  // std::cout << " dE *E[i] (2) " << dE*E[i] << " " << dE*E[i]*theLayer2->mipsPerGeV() << " "<< nS << std::endl;
576  pstot+=dE*E[i];
577  ps2tot+=dE*E[i];
578  dE = nS/(E[i]*theLayer2->mipsPerGeV());
579 
580  // E2 += dE*E[i];
581  // n2 += nS;
582 
583  }
584 
585  if(detailedShowerTail)
586  myGammaGenerator->setParameters(floor(a[i]+0.5),b[i],t-dt);
587 
588 
589 
590  // myHistos->fill("h100",t,dE);
591 
592  // The lateral development parameters
593 
594  // Energy of the spots
595  double eSpot = (nS>0.) ? dE/nS : 0.;
596  double SpotEnergy=eSpot*E[i];
597 
598  if(hasPreshower&&(presh1||presh2)) thePreshower->setSpotEnergy(0.00009);
599  if(hcal)
600  {
601  SpotEnergy*=theHCAL->hOverPi();
602  theHcalHitMaker->setSpotEnergy(SpotEnergy);
603  }
604  // Poissonian fluctuations for the number of spots
605  // int nSpot = random->poissonShoot(nS);
606  int nSpot = (int)(nS+0.5);
607 
608 
609  // Fig. 11 (right) *** Does not match.
610  // myHistos->fill("h101",t,(double)nSpot/theNumberOfSpots);
611 
612  //double taui = t/T;
613  double taui = tt/Ti[i];
614  double proba = theParam->p(taui,E[i]);
615  double theRC = theParam->rC(taui,E[i]);
616  double theRT = theParam->rT(taui,E[i]);
617 
618  // Fig. 10
619  // myHistos->fill("h300",taui,theRC);
620  // myHistos->fill("h301",taui,theRT);
621  // myHistos->fill("h302",taui,proba);
622 
623  double dSpotsCore =
624  random->gaussShoot(proba*nSpot,std::sqrt(proba*(1.-proba)*nSpot));
625 
626  if(dSpotsCore<0) dSpotsCore=0;
627 
628  unsigned nSpots_core = (unsigned)(dSpotsCore+0.5);
629  unsigned nSpots_tail = ((unsigned)nSpot>nSpots_core) ? nSpot-nSpots_core : 0;
630 
631  for(unsigned icomp=0;icomp<2;++icomp)
632  {
633 
634  double theR=(icomp==0) ? theRC : theRT ;
635  unsigned ncompspots=(icomp==0) ? nSpots_core : nSpots_tail;
636 
637  RadialInterval radInterval(theR,ncompspots,SpotEnergy,random);
638  if(ecal)
639  {
640  if(icomp==0)
641  {
642  setIntervals(icomp,radInterval);
643  }
644  else
645  {
646  setIntervals(icomp,radInterval);
647  }
648  }
649  else
650  {
651  radInterval.addInterval(100.,1.);// 100% of the spots
652  }
653 
654  radInterval.compute();
655  // irad = 0 : central circle; irad=1 : outside
656 
657  unsigned nrad=radInterval.nIntervals();
658 
659  for(unsigned irad=0;irad<nrad;++irad)
660  {
661  double spote=radInterval.getSpotEnergy(irad);
662  if(ecal) theGrid->setSpotEnergy(spote);
663  if(hcal) theHcalHitMaker->setSpotEnergy(spote);
664  unsigned nradspots=radInterval.getNumberOfSpots(irad);
665  double umin=radInterval.getUmin(irad);
666  double umax=radInterval.getUmax(irad);
667  // Go for the lateral development
668  // std::cout << "Couche " << iStep << " irad = " << irad << " Ene = " << E[i] << " eSpot = " << eSpot << " spote = " << spote << " nSpot = " << nS << std::endl;
669 
670  for ( unsigned ispot=0; ispot<nradspots; ++ispot )
671  {
672  double z3=random->flatShoot(umin,umax);
673  double ri=theR * std::sqrt(z3/(1.-z3)) ;
674 
675 
676 
677  //Fig. 12
678  /*
679  if ( 2. < t && t < 3. )
680  dbe->fill("h401",ri,1./1000.*eSpot/dE/0.2);
681  if ( 6. < t && t < 7. )
682  dbe->fill("h402",ri,1./1000.*eSpot/dE/0.2);
683  if ( 19. < t && t < 20. )
684  dbe->fill("h403",ri,1./1000.*eSpot/dE/0.2);
685  */
686  // Fig. 13 (top)
687  if (dbe && fabs(dt-1.)< 1e-5 && ecal) {
688  dbe->cd();
689  if (!dbe->get("EMShower/TransverseShape")) {}//std::cout << "NOT FOUND IN Shower.cc" << std::endl;}
690  else {
691  double drho = 0.1;
692  double dx = 1;
693  // spote is a real energy we have to normalise it by E[i] which is the energy of the particle i
694  dbe->get("EMShower/TransverseShape")->Fill(ri,1/E[i]*spote/drho);
695  dbe->get("EMShower/ShapeRhoZ")->Fill(ri, t, 1/E[i]*spote/(drho*dx));
696  }
697  } else {
698  // std::cout << "dt = " << dt << " length = " << t << std::endl;
699  }
700 
701 
702  // Generate phi
703  double phi = 2.*M_PI*random->flatShoot();
704 
705  // Add the hit in the crystal
706  // if( ecal ) theGrid->addHit(ri*theECAL->moliereRadius(),phi);
707  // Now the *moliereRadius is done in EcalHitMaker
708  if ( ecal )
709  {
710  if(detailedShowerTail)
711  {
712  // std::cout << "About to call addHitDepth " << std::endl;
713  double depth;
714  do
715  {
716  depth=myGammaGenerator->shoot(random);
717  }
718  while(depth>t);
719  theGrid->addHitDepth(ri,phi,depth);
720  // std::cout << " Done " << std::endl;
721  }
722  else
723  theGrid->addHit(ri,phi);
724  }
725  else if (hasPreshower&&presh1) thePreshower->addHit(ri,phi,1);
726  else if (hasPreshower&&presh2) thePreshower->addHit(ri,phi,2);
727  else if (hcal)
728  {
729  // std::cout << " About to add a spot in the HCAL" << status << std::endl;
730  theHcalHitMaker->addHit(ri,phi);
731  // std::cout << " Added a spot in the HCAL" << status << std::endl;
732  }
733  // if (ecal) E9 += SpotEnergy;
734  // if (presh1) { E1 += SpotEnergy; ++n1; }
735  // if (presh2) { E2 += SpotEnergy; ++n2; }
736 
737  Etot[i] += spote;
738  }
739  }
740  }
741  // std::cout << " Done with the step " << std::endl;
742  // The shower!
743  //myHistos->fill("h500",theSpot.z(),theSpot.perp());
744  }
745  // std::cout << " nPart " << nPart << std::endl;
746  }
747  // std::cout << " Finshed the step loop " << std::endl;
748  // myHistos->fill("h500",E1+0.7*E2,E9);
749  // myHistos->fill("h501",n1+0.7*n2,E9);
750  // myHistos->fill("h400",n1);
751  // myHistos->fill("h401",n2);
752  // myHistos->fill("h402",E9+E1+0.7*E2);
753  // if(!standalone)theGrid->printGrid();
754  double Etotal=0.;
755  for(unsigned i=0;i<nPart;++i)
756  {
757  // myHistos->fill("h10",Etot[i]);
758  Etotal+=Etot[i];
759  }
760 
761  // std::cout << "Etotal = " << Etotal << " nPart = "<< nPart << std::endl;
762  // std::cout << "totECalc = " << totECalc << std::endl;
763 
764  // myHistos->fill("h20",Etotal);
765  // if(thePreshower)
766  // std::cout << " PS " << thePreshower->layer1Calibrated() << " " << thePreshower->layer2Calibrated() << " " << thePreshower->totalCalibrated() << " " << ps1tot << " " <<ps2tot << " " << pstot << std::endl;
767 }
768 
769 
770 double
771 EMShower::gam(double x, double a) const {
772  // A stupid gamma function
773  return std::pow(x,a-1.)*std::exp(-x);
774 }
775 
776 //double
777 //EMShower::deposit(double t, double a, double b, double dt) {
778 //
779 // // The number of integration steps (about 1 / X0)
780 // int numberOfSteps = (int)dt+1;
781 //
782 // // The size if the integration step
783 // double integrationstep = dt/(double)numberOfSteps;
784 //
785 // // Half this size
786 // double halfis = 0.5*integrationstep;
787 //
788 // double dE = 0.;
789 //
790 // for(double tt=t-dt+halfis;tt<t;tt+=integrationstep) {
791 //
792 // // Simpson integration over each of these steps
793 // dE += gam(b*(tt-halfis),a)
794 // + 4.*gam(b* tt ,a)
795 // + gam(b*(tt+halfis),a);
796 //
797 // }
798 //
799 // // Normalization
800 // dE *= b*integrationstep/tgamma(a)/6.;
801 //
802 // // There we go.
803 // return dE;
804 //}
805 
806 double
807 EMShower::deposit(double t, double a, double b, double dt) {
808  myIncompleteGamma.a().setValue(a);
809  double b1=b*(t-dt);
810  double b2=b*t;
811  double result = 0.;
812  double rb1=(b1!=0.) ? myIncompleteGamma(b1) : 0.;
813  double rb2=(b2!=0.) ? myIncompleteGamma(b2) : 0.;
814  result = (rb2-rb1);
815  return result;
816 }
817 
818 
819 void EMShower::setIntervals(unsigned icomp, RadialInterval& rad)
820 {
821  // std::cout << " Got the pointer " << std::endl;
822  const std::vector<double>& myValues((icomp)?theParam->getTailIntervals():theParam->getCoreIntervals());
823  // std::cout << " Got the vector " << myValues.size () << std::endl;
824  unsigned nvals=myValues.size()/2;
825  for(unsigned iv=0;iv<nvals;++iv)
826  {
827  // std::cout << myValues[2*iv] << " " << myValues[2*iv+1] <<std::endl;
828  rad.addInterval(myValues[2*iv],myValues[2*iv+1]);
829  }
830 }
831 
833 {
834  if(myPresh!=NULL)
835  {
836  thePreshower = myPresh;
837  hasPreshower=true;
838  }
839 }
840 
841 
842 void EMShower::setHcal(HcalHitMaker * const myHcal)
843 {
844  theHcalHitMaker = myHcal;
845 }
846 
847 double
848 EMShower::deposit( double a, double b, double t) {
849  // std::cout << " Deposit " << std::endl;
850  myIncompleteGamma.a().setValue(a);
851  double b2=b*t;
852  double result = 0.;
853  if(fabs(b2) < 1.e-9 ) b2 = 1.e-9;
854  result=myIncompleteGamma(b2);
855  // std::cout << " deposit t = " << t << " " << result <<std::endl;
856  return result;
857 
858 }
void setSpotEnergy(double e)
Set the spot energy.
Definition: HcalHitMaker.h:28
double getX0back() const
Definition: EcalHitMaker.h:109
float dt
Definition: AMPTWrapper.h:126
int i
Definition: DBlmapReader.cc:9
double ps2TotalX0() const
total number of X0 in the PS (Layer2).
Definition: EcalHitMaker.h:65
std::vector< const RawParticle * > *const thePart
Definition: EMShower.h:96
std::vector< double > theNumberOfSpots
Definition: EMShower.h:100
static std::vector< std::string > checklist log
double sigmaLnT(double lny) const
const HCALProperties * hcalProperties() const
void prepareSteps()
Computes the steps before the real compute.
Definition: EMShower.cc:160
std::vector< double > maximumOfShower
Definition: EMShower.h:115
bool addHit(double r, double phi, unsigned layer=0)
double meanAlphaSpot(double alpha) const
common ppss p3p6s2 common epss epspn46 common const1 w2
Definition: inclppp.h:1
void setSpotEnergy(double e)
Definition: EcalHitMaker.h:117
double flatShoot(double xmin=0.0, double xmax=1.0) const
std::vector< double > aSpot
Definition: EMShower.h:109
unsigned getNumberOfSpots(unsigned i) const
Number of spots in a given interval.
double radLenIncm() const
Radiation length in cm.
bool addHit(double r, double phi, unsigned layer=0)
double deposit(double t, double a, double b, double dt)
Definition: EMShower.cc:807
void cd(void)
go to top directory (ie. root)
Definition: DQMStore.cc:644
const RandomEngineAndDistribution * random
Definition: EMShower.h:148
double gam(double x, double a) const
Definition: EMShower.cc:771
const HCALProperties * theHCAL
Definition: EMShower.h:91
void setPreshower(PreshowerHitMaker *const myPresh)
set the preshower address
Definition: EMShower.cc:832
#define NULL
Definition: scimark2.h:8
double rC(double tau, double E) const
bool isHom() const
a rough estimate of ECAL resolution sigma/E = resE/sqrt(E)
const ECALProperties * theECAL
Definition: EMShower.h:90
double ps2eeTotalX0() const
Definition: EcalHitMaker.h:68
TRandom random
Definition: MVATrainer.cc:138
void setIntervals(unsigned icomp, RadialInterval &rad)
Definition: EMShower.cc:819
const std::vector< double > & getTailIntervals() const
void compute()
Compute the shower longitudinal and lateral development.
Definition: EMShower.cc:305
const std::vector< double > & getCoreIntervals() const
std::vector< double > Etot
Definition: EMShower.h:101
void Fill(long long x)
bool stepsCalculated
Definition: EMShower.h:127
double spotFraction() const
Spot fraction wrt ECAL.
double hOverPi() const
PreshowerHitMaker * thePreshower
Definition: EMShower.h:133
std::vector< std::vector< double > > depositedEnergy
Definition: EMShower.h:116
double ecalTotalX0() const
in the ECAL
Definition: EcalHitMaker.h:71
Steps steps
Definition: EMShower.h:125
EMShower(RandomEngineAndDistribution const *engine, GammaFunctionGenerator *gamma, EMECALShowerParametrization *const myParam, std::vector< const RawParticle * > *const myPart, DQMStore *const dbeIn=NULL, EcalHitMaker *const myGrid=NULL, PreshowerHitMaker *const myPreshower=NULL, bool bFixedLength=false)
Definition: EMShower.cc:21
double dp() const
the width of the passive layer in the case of the homogeneous detector
bool addHitDepth(double r, double phi, double depth=-1)
T sqrt(T t)
Definition: SSEVec.h:48
double da() const
the width of the active layer in the case of the homogeneous detector
tuple result
Definition: query.py:137
double getUmin(unsigned i) const
Lower limit of the argument in the radius generator.
double innerDepth
Definition: EMShower.h:118
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
HcalHitMaker * theHcalHitMaker
Definition: EMShower.h:136
double hcalTotalX0() const
in the HCAL
Definition: EcalHitMaker.h:77
unsigned int nPart
Definition: EMShower.h:97
std::vector< double > meanDepth
Definition: EMShower.h:117
double rT(double tau, double E) const
void setParameters(double a, double b, double xm)
The parameters must be set before shooting.
unsigned int offset(bool)
MonitorElement * get(const std::string &path) const
get ME from full pathname (e.g. &quot;my/long/dir/my_histo&quot;)
Definition: DQMStore.cc:1708
bool bFixedLength_
Definition: EMShower.h:153
std::vector< double > photos
Definition: EMShower.h:103
#define M_PI
const PreshowerLayer1Properties * layer1Properties() const
double shoot(RandomEngineAndDistribution const *) const
void setSpotEnergy(double e)
double correlationAlphaT(double lny) const
const ECALProperties * ecalProperties() const
unsigned nIntervals() const
Number of intervals.
bool hasPreshower
Definition: EMShower.h:139
double mipsPerGeV() const
Number of Mips/GeV [Default : 41.7 Mips/GeV or 24 MeV/Mips].
double mipsPerGeV() const
Number of Mips/GeV [Default : 59.5 Mips/GeV or 0.7*24 MeV/Mips].
double criticalEnergy() const
Critical energy in GeV (2.66E-3*(x0*Z/A)^1.1): 8.74E-3 for Standard ECAL.
double globalMaximum
Definition: EMShower.h:120
double p(double tau, double E) const
double b
Definition: hdecay.h:120
const PreshowerLayer2Properties * layer2Properties() const
const PreshowerLayer2Properties * theLayer2
Definition: EMShower.h:93
bool getPads(double depth, bool inCm=false)
double meanLnAlpha(double lny) const
virtual double lightCollectionEfficiency() const =0
Light Collection efficiency.
const PreshowerLayer1Properties * theLayer1
Definition: EMShower.h:92
common ppss p3p6s2 common epss epspn46 common const1 w3
Definition: inclppp.h:1
std::vector< double > a
Definition: EMShower.h:105
double a
Definition: hdecay.h:121
double outerDepth
Definition: EMShower.h:118
double meanAlpha(double lny) const
virtual double lightCollectionUniformity() const =0
Light Collection uniformity.
double gaussShoot(double mean=0.0, double sigma=1.0) const
unsigned int poissonShoot(double mean) const
EMECALShowerParametrization *const theParam
Definition: EMShower.h:87
EcalHitMaker * theGrid
Definition: EMShower.h:130
GammaFunctionGenerator * myGammaGenerator
Definition: EMShower.h:151
double sigmaLnAlpha(double lny) const
std::vector< double > Ti
Definition: EMShower.h:107
std::vector< double > TSpot
Definition: EMShower.h:108
Definition: DDAxes.h:10
double getSpotEnergy(unsigned i) const
Spot energy in a given interval.
unsigned nSteps
Definition: EMShower.h:126
Genfun::IncompleteGamma myIncompleteGamma
Definition: EMShower.h:145
tuple status
Definition: ntuplemaker.py:245
std::vector< double > b
Definition: EMShower.h:106
double ps1TotalX0() const
Definition: EcalHitMaker.h:62
double totalEnergy
Definition: EMShower.h:122
std::vector< double > E
Definition: EMShower.h:102
bool addHit(double r, double phi, unsigned layer=0)
add the hit in the HCAL in local coordinates
Definition: HcalHitMaker.cc:28
long double T
double getUmax(unsigned i) const
Upper limit of the argument in the radius generator.
virtual double photoStatistics() const =0
Photostatistics (photons/GeV) in the homegeneous material.
double x0DepthOffset() const
get the offset (e.g the number of X0 after which the shower starts)
Definition: EcalHitMaker.h:59
std::pair< unsigned int, double > Step
Definition: EMShower.h:34
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
bool setDepth(double, bool inCm=false)
set the depth in X0 or Lambda0 units depending on showerType
double totalX0() const
Definition: EcalHitMaker.h:53
void addInterval(double, double)
DQMStore * dbe
Definition: EMShower.h:143
void setHcal(HcalHitMaker *const myHcal)
set the HCAL address
Definition: EMShower.cc:842
std::vector< double > bSpot
Definition: EMShower.h:110
double resE() const
a rough estimate of ECAL resolution sigma/E = resE/sqrt(E)
Definition: DDAxes.h:10