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