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  // The correlation matrix
104  double theCorrelation = myParam->correlationAlphaT(lny);
105  double rhop = std::sqrt( (1.+theCorrelation)/2. );
106  double rhom = std::sqrt( (1.-theCorrelation)/2. );
107 
108  // The number of spots in ECAL / HCAL
109  theNumberOfSpots.push_back(myParam->nSpots(E[i]));
110  // theNumberOfSpots.push_back(myParam->nSpots(E[i])*spotFraction);
111  //theNumberOfSpots = random->poissonShoot(myParam->nSpots(myPart->e()));
112 
113  // Photo-statistics
114  photos.push_back(E[i] * fotos);
115 
116  // The longitudinal shower development parameters
117  // Fluctuations of alpha, T and beta
118  double z1=0.;
119  double z2=0.;
120  double aa=0.;
121 
122  // Protect against too large fluctuations (a < 1) for small energies
123  while ( aa <= 1. ) {
124  z1 = random->gaussShoot(0.,1.);
125  z2 = random->gaussShoot(0.,1.);
126  aa = std::exp(theMeanLnAlpha + theSigmaLnAlpha * (z1*rhop-z2*rhom));
127  }
128 
129  a.push_back(aa);
130  T.push_back(std::exp(theMeanLnT + theSigmaLnT * (z1*rhop+z2*rhom)));
131  b.push_back((a[i]-1.)/T[i]);
132  maximumOfShower.push_back((a[i]-1.)/b[i]);
134  meanDepth += a[i]/b[i]*E[i];
135  // std::cout << " Adding max " << maximumOfShower[i] << " " << E[i] << " " <<maximumOfShower[i]*E[i] << std::endl;
136  // std::cout << std::setw(8) << std::setprecision(5) << " a /b " << a[i] << " " << b[i] << std::endl;
137  Ti.push_back(
138  a[i]/b[i] * (std::exp(theMeanLnAlpha)-1.) / std::exp(theMeanLnAlpha));
139 
140  // The parameters for the number of energy spots
141  TSpot.push_back(theParam->meanTSpot(theMeanT));
142  aSpot.push_back(theParam->meanAlphaSpot(theMeanAlpha));
143  bSpot.push_back((aSpot[i]-1.)/TSpot[i]);
144  // myHistos->fill("h7000",a[i]);
145  // myHistos->fill("h7002",E[i],a[i]);
146  }
147 // std::cout << " PS1 : " << myGrid->ps1TotalX0()
148 // << " PS2 : " << myGrid->ps2TotalX0()
149 // << " ECAL : " << myGrid->ecalTotalX0()
150 // << " HCAL : " << myGrid->hcalTotalX0()
151 // << " Offset : " << myGrid->x0DepthOffset()
152 // << std::endl;
153 
155  meanDepth/=totalEnergy;
156  // std::cout << " Total Energy " << totalEnergy << " Global max " << globalMaximum << std::endl;
157 }
158 
160 {
161  // TimeMe theT("EMShower::compute");
162 
163  // Determine the longitudinal intervals
164  // std::cout << " EMShower compute" << std::endl;
165  double dt;
166  double radlen;
167  int stps;
168  int first_Ecal_step=0;
169  int last_Ecal_step=0;
170 
171  // The maximum is in principe 8 (with 5X0 steps in the ECAL)
172  steps.reserve(24);
173 
174  /*
175  std::cout << " PS1 : " << theGrid->ps1TotalX0()
176  << " PS2 : " << theGrid->ps2TotalX0()
177  << " PS2 and ECAL : " << theGrid->ps2eeTotalX0()
178  << " ECAL : " << theGrid->ecalTotalX0()
179  << " HCAL : " << theGrid->hcalTotalX0()
180  << " Offset : " << theGrid->x0DepthOffset()
181  << std::endl;
182  */
183 
184  radlen = -theGrid->x0DepthOffset();
185 
186  // Preshower Layer 1
187  radlen += theGrid->ps1TotalX0();
188  if ( radlen > 0. ) {
189  steps.push_back(Step(0,radlen));
190  radlen = 0.;
191  }
192 
193  // Preshower Layer 2
194  radlen += theGrid->ps2TotalX0();
195  if ( radlen > 0. ) {
196  steps.push_back(Step(1,radlen));
197  radlen = 0.;
198  }
199 
200  // add a step between preshower and ee
201  radlen += theGrid->ps2eeTotalX0();
202  if ( radlen > 0.) {
203  steps.push_back(Step(5,radlen));
204  radlen = 0.;
205  }
206 
207  // ECAL
208  radlen += theGrid->ecalTotalX0();
209 
210  if ( radlen > 0. ) {
211 
212  if (!bFixedLength_){
213  stps=(int)((radlen+2.5)/5.);
214  // stps=(int)((radlen+.5)/1.);
215  if ( stps == 0 ) stps = 1;
216  dt = radlen/(double)stps;
217  Step step(2,dt);
218  first_Ecal_step=steps.size();
219  for ( int ist=0; ist<stps; ++ist )
220  steps.push_back(step);
221  last_Ecal_step=steps.size()-1;
222  radlen = 0.;
223  } else {
224  dt = 1.0;
225  stps = static_cast<int>(radlen);
226  if (stps == 0) stps = 1;
227  Step step(2,dt);
228  first_Ecal_step=steps.size();
229  for ( int ist=0; ist<stps; ++ist ) steps.push_back(step);
230  dt = radlen-stps;
231  if (dt>0) {
232  Step stepLast (2,dt);
233  steps.push_back(stepLast);
234  }
235  last_Ecal_step=steps.size()-1;
236  // std::cout << "radlen = " << radlen << " stps = " << stps << " dt = " << dt << std::endl;
237  radlen = 0.;
238 
239  }
240  }
241 
242  // I should had a gap here !
243 
244  // HCAL
245  radlen += theGrid->hcalTotalX0();
246  if ( radlen > 0. ) {
247  double dtFrontHcal=theGrid->totalX0()-theGrid->hcalTotalX0();
248  // One single step for the full HCAL
249  if(dtFrontHcal<30.)
250  {
251  dt=30.-dtFrontHcal;
252  Step step(3,dt);
253  steps.push_back(step);
254  }
255  }
256 
257  nSteps=steps.size();
258  if(nSteps==0) return;
259  double ESliceTot=0.;
260  double MeanDepth=0.;
261  depositedEnergy.resize(nSteps);
262  meanDepth.resize(nSteps);
263  double t=0.;
264 
265  int offset=0;
266  for(unsigned iStep=0;iStep<nSteps;++iStep)
267  {
268  ESliceTot=0.;
269  MeanDepth=0.;
270  double realTotalEnergy=0;
271  dt=steps[iStep].second;
272  t+=dt;
273  for ( unsigned int i=0; i<nPart; ++i ) {
274  depositedEnergy[iStep].push_back(deposit(t,a[i],b[i],dt));
275  ESliceTot +=depositedEnergy[iStep][i];
276  MeanDepth += deposit(t,a[i]+1.,b[i],dt)/b[i]*a[i];
277  realTotalEnergy+=depositedEnergy[iStep][i]*E[i];
278  }
279 
280  if( ESliceTot > 0. ) // can happen for the shower tails; this depth will be skipped anyway
281  MeanDepth/=ESliceTot;
282  else
283  MeanDepth=t-dt;
284 
285  meanDepth[iStep]=MeanDepth;
286  if(realTotalEnergy<0.001)
287  {
288  offset-=1;
289  }
290  }
291 
292  innerDepth=meanDepth[first_Ecal_step];
293  if(last_Ecal_step+offset>=0)
294  outerDepth=meanDepth[last_Ecal_step+offset];
295  else
297 
298  stepsCalculated=true;
299 }
300 
301 void
303 
304  double t = 0.;
305  double dt = 0.;
307 
308  // Prepare the grids in EcalHitMaker
309  // theGrid->setInnerAndOuterDepth(innerDepth,outerDepth);
310  float pstot=0.;
311  float ps2tot=0.;
312  float ps1tot=0.;
313  bool status=false;
314  // double E1 = 0.; // Energy layer 1
315  // double E2 = 0.; // Energy layer 2
316  // double n1 = 0.; // #mips layer 1
317  // double n2 = 0.; // #mips layer 2
318  // double E9 = 0.; // Energy ECAL
319 
320  // Loop over all segments for the longitudinal development
321  double totECalc = 0;
322 
323 
324 
325  for (unsigned iStep=0; iStep<nSteps; ++iStep ) {
326 
327  // The length of the shower in this segment
328  dt = steps[iStep].second;
329 
330  // std::cout << " Detector " << steps[iStep].first << " t " << t << " " << dt << std::endl;
331 
332  // The elapsed length
333  t += dt;
334 
335  // In what detector are we ?
336  unsigned detector=steps[iStep].first;
337 
338  bool presh1 = detector==0;
339  bool presh2 = detector==1;
340  bool ecal = detector==2;
341  bool hcal = detector==3;
342  bool vfcal = detector==4;
343  bool gap = detector==5;
344 
345  // Temporary. Will be removed
346  if ( theHCAL==NULL) hcal=false;
347 
348  // Keep only ECAL for now
349  if ( vfcal ) continue;
350 
351  // Nothing to do in the gap
352  if( gap ) continue;
353 
354  // cout << " t = " << t << endl;
355  // Build the grid of crystals at this ECAL depth
356  // Actually, it might be useful to check if this grid is empty or not.
357  // If it is empty (because no crystal at this depth), it is of no use
358  // (and time consuming) to generate the spots
359 
360 
361  // middle of the step
362  double tt = t-0.5*dt;
363 
364  double realTotalEnergy=0.;
365  for ( unsigned int i=0; i<nPart; ++i ) {
366  realTotalEnergy += depositedEnergy[iStep][i]*E[i];
367  }
368 
369 // std::cout << " Step " << tt << std::endl;
370 // std::cout << "ecal " << ecal << " hcal " << hcal <<std::endl;
371 
372  // If the amount of energy is greater than 1 MeV, make a new grid
373  // otherwise put in the previous one.
374  bool usePreviousGrid=(realTotalEnergy<0.001);
375 
376  // If the amount of energy is greater than 1 MeV, make a new grid
377  // otherwise put in the previous one.
378 
379  // If less than 1 kEV. Just skip
380  if(iStep>2&&realTotalEnergy<0.000001) continue;
381 
382  if (ecal && !usePreviousGrid)
383  {
384  status=theGrid->getPads(meanDepth[iStep]);
385  }
386  if (hcal)
387  {
388  status=theHcalHitMaker->setDepth(tt);
389  }
390  if((ecal || hcal) && !status) continue;
391 
392  bool detailedShowerTail=false;
393  // check if a detailed treatment of the rear leakage should be applied
394  if(ecal && !usePreviousGrid)
395  {
396  detailedShowerTail=(t-dt > theGrid->getX0back());
397  }
398 
399  // The particles of the shower are processed in parallel
400  for ( unsigned int i=0; i<nPart; ++i ) {
401 
402  // double Edepo=deposit(t,a[i],b[i],dt);
403 
404  // integration of the shower profile between t-dt and t
405  double dE = (!hcal)? depositedEnergy[iStep][i]:1.-deposit(a[i],b[i],t-dt);
406 
407  totECalc +=dE;
408 
409  if (dbe && fabs(dt-1.)< 1e-5 && ecal) {
410  dbe->cd();
411  if (!dbe->get("EMShower/LongitudinalShape")) {}//std::cout << "NOT FOUND IN Shower.cc" << std::endl;}
412  else {
413  double dx = 1.;
414  // dE is aready in relative units from 0 to 1
415  dbe->get("EMShower/LongitudinalShape")->Fill(t, dE/dx);
416  }
417  //(dbe->get("TransverseShape"))->Fill(ri,log10(1./1000.*eSpot/0.2));
418 
419  }
420 
421 
422 
423  // no need to do the full machinery if there is ~nothing to distribute)
424  if(dE*E[i]<0.000001) continue;
425 
426  if(detailedShowerTail)
427  {
428  myGammaGenerator->setParameters(floor(a[i]+0.5),b[i],t-dt);
429  }
430 
431  // The number of energy spots (or mips)
432  double nS = 0;
433 
434  // ECAL case : Account for photostatistics and long'al non-uniformity
435  if (ecal) {
436 
437  dE = random->poissonShoot(dE*photos[i])/photos[i];
438  double z0 = random->gaussShoot(0.,1.);
439  dE *= 1. + z0*theECAL->lightCollectionUniformity();
440 
441  // Expected spot number
442  nS = ( theNumberOfSpots[i] * gam(bSpot[i]*tt,aSpot[i])
443  * bSpot[i] * dt
444  / tgamma(aSpot[i]) );
445 
446  // Preshower : Expected number of mips + fluctuation
447  }
448  else if ( hcal ) {
449 
450  nS = ( theNumberOfSpots[i] * gam(bSpot[i]*tt,aSpot[i])
451  * bSpot[i] * dt
452  / tgamma(aSpot[i]))* theHCAL->spotFraction();
453  double nSo = nS ;
454  nS = random->poissonShoot(nS);
455  // 'Quick and dirty' fix (but this line should be better removed):
456  if( nSo > 0. && nS/nSo < 10.) dE *= nS/nSo;
457 
458 // if(true)
459 // {
460 // std::cout << " theHCAL->spotFraction = " <<theHCAL->spotFraction() <<std::endl;
461 // std::cout << " nSpot Ecal : " << nSo/theHCAL->spotFraction() << " Final " << nS << std::endl;
462 // }
463  }
464  else if ( presh1 ) {
465 
466  nS = random->poissonShoot(dE*E[i]*theLayer1->mipsPerGeV());
467  // std::cout << " dE *E[i] (1)" << dE*E[i] << " " << dE*E[i]*theLayer1->mipsPerGeV() << " "<< nS << std::endl;
468  pstot+=dE*E[i];
469  ps1tot+=dE*E[i];
470  dE = nS/(E[i]*theLayer1->mipsPerGeV());
471 
472  // E1 += dE*E[i];
473  // n1 += nS;
474  // if (presh2) { E2 += SpotEnergy; ++n2; }
475 
476  } else if ( presh2 ) {
477 
478  nS = random->poissonShoot(dE*E[i]*theLayer2->mipsPerGeV());
479  // std::cout << " dE *E[i] (2) " << dE*E[i] << " " << dE*E[i]*theLayer2->mipsPerGeV() << " "<< nS << std::endl;
480  pstot+=dE*E[i];
481  ps2tot+=dE*E[i];
482  dE = nS/(E[i]*theLayer2->mipsPerGeV());
483 
484  // E2 += dE*E[i];
485  // n2 += nS;
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 
575 
576  //Fig. 12
577  /*
578  if ( 2. < t && t < 3. )
579  dbe->fill("h401",ri,1./1000.*eSpot/dE/0.2);
580  if ( 6. < t && t < 7. )
581  dbe->fill("h402",ri,1./1000.*eSpot/dE/0.2);
582  if ( 19. < t && t < 20. )
583  dbe->fill("h403",ri,1./1000.*eSpot/dE/0.2);
584  */
585  // Fig. 13 (top)
586  if (dbe && fabs(dt-1.)< 1e-5 && ecal) {
587  dbe->cd();
588  if (!dbe->get("EMShower/TransverseShape")) {}//std::cout << "NOT FOUND IN Shower.cc" << std::endl;}
589  else {
590  double drho = 0.1;
591  double dx = 1;
592  // spote is a real energy we have to normalise it by E[i] which is the energy of the particle i
593  dbe->get("EMShower/TransverseShape")->Fill(ri,1/E[i]*spote/drho);
594  dbe->get("EMShower/ShapeRhoZ")->Fill(ri, t, 1/E[i]*spote/(drho*dx));
595  }
596  } else {
597  // std::cout << "dt = " << dt << " length = " << t << std::endl;
598  }
599 
600 
601  // Generate phi
602  double phi = 2.*M_PI*random->flatShoot();
603 
604  // Add the hit in the crystal
605  // if( ecal ) theGrid->addHit(ri*theECAL->moliereRadius(),phi);
606  // Now the *moliereRadius is done in EcalHitMaker
607  if ( ecal )
608  {
609  if(detailedShowerTail)
610  {
611  // std::cout << "About to call addHitDepth " << std::endl;
612  double depth;
613  do
614  {
615  depth=myGammaGenerator->shoot();
616  }
617  while(depth>t);
618  theGrid->addHitDepth(ri,phi,depth);
619  // std::cout << " Done " << std::endl;
620  }
621  else
622  theGrid->addHit(ri,phi);
623  }
624  else if (hasPreshower&&presh1) thePreshower->addHit(ri,phi,1);
625  else if (hasPreshower&&presh2) thePreshower->addHit(ri,phi,2);
626  else if (hcal)
627  {
628  // std::cout << " About to add a spot in the HCAL" << status << std::endl;
629  theHcalHitMaker->addHit(ri,phi);
630  // std::cout << " Added a spot in the HCAL" << status << std::endl;
631  }
632  // if (ecal) E9 += SpotEnergy;
633  // if (presh1) { E1 += SpotEnergy; ++n1; }
634  // if (presh2) { E2 += SpotEnergy; ++n2; }
635 
636  Etot[i] += spote;
637  }
638  }
639  }
640  // std::cout << " Done with the step " << std::endl;
641  // The shower!
642  //myHistos->fill("h500",theSpot.z(),theSpot.perp());
643  }
644  // std::cout << " nPart " << nPart << std::endl;
645  }
646  // std::cout << " Finshed the step loop " << std::endl;
647  // myHistos->fill("h500",E1+0.7*E2,E9);
648  // myHistos->fill("h501",n1+0.7*n2,E9);
649  // myHistos->fill("h400",n1);
650  // myHistos->fill("h401",n2);
651  // myHistos->fill("h402",E9+E1+0.7*E2);
652  // if(!standalone)theGrid->printGrid();
653  double Etotal=0.;
654  for(unsigned i=0;i<nPart;++i)
655  {
656  // myHistos->fill("h10",Etot[i]);
657  Etotal+=Etot[i];
658  }
659 
660  // std::cout << "Etotal = " << Etotal << " nPart = "<< nPart << std::endl;
661  // std::cout << "totECalc = " << totECalc << std::endl;
662 
663  // myHistos->fill("h20",Etotal);
664  // if(thePreshower)
665  // std::cout << " PS " << thePreshower->layer1Calibrated() << " " << thePreshower->layer2Calibrated() << " " << thePreshower->totalCalibrated() << " " << ps1tot << " " <<ps2tot << " " << pstot << std::endl;
666 }
667 
668 
669 double
670 EMShower::gam(double x, double a) const {
671  // A stupid gamma function
672  return std::pow(x,a-1.)*std::exp(-x);
673 }
674 
675 //double
676 //EMShower::deposit(double t, double a, double b, double dt) {
677 //
678 // // The number of integration steps (about 1 / X0)
679 // int numberOfSteps = (int)dt+1;
680 //
681 // // The size if the integration step
682 // double integrationstep = dt/(double)numberOfSteps;
683 //
684 // // Half this size
685 // double halfis = 0.5*integrationstep;
686 //
687 // double dE = 0.;
688 //
689 // for(double tt=t-dt+halfis;tt<t;tt+=integrationstep) {
690 //
691 // // Simpson integration over each of these steps
692 // dE += gam(b*(tt-halfis),a)
693 // + 4.*gam(b* tt ,a)
694 // + gam(b*(tt+halfis),a);
695 //
696 // }
697 //
698 // // Normalization
699 // dE *= b*integrationstep/tgamma(a)/6.;
700 //
701 // // There we go.
702 // return dE;
703 //}
704 
705 double
706 EMShower::deposit(double t, double a, double b, double dt) {
707  myIncompleteGamma.a().setValue(a);
708  double b1=b*(t-dt);
709  double b2=b*t;
710  double result = 0.;
711  double rb1=(b1!=0.) ? myIncompleteGamma(b1) : 0.;
712  double rb2=(b2!=0.) ? myIncompleteGamma(b2) : 0.;
713  result = (rb2-rb1);
714  return result;
715 }
716 
717 
718 void EMShower::setIntervals(unsigned icomp, RadialInterval& rad)
719 {
720  // std::cout << " Got the pointer " << std::endl;
721  const std::vector<double>& myValues((icomp)?theParam->getTailIntervals():theParam->getCoreIntervals());
722  // std::cout << " Got the vector " << myValues.size () << std::endl;
723  unsigned nvals=myValues.size()/2;
724  for(unsigned iv=0;iv<nvals;++iv)
725  {
726  // std::cout << myValues[2*iv] << " " << myValues[2*iv+1] <<std::endl;
727  rad.addInterval(myValues[2*iv],myValues[2*iv+1]);
728  }
729 }
730 
732 {
733  if(myPresh!=NULL)
734  {
735  thePreshower = myPresh;
736  hasPreshower=true;
737  }
738 }
739 
740 
741 void EMShower::setHcal(HcalHitMaker * const myHcal)
742 {
743  theHcalHitMaker = myHcal;
744 }
745 
746 double
747 EMShower::deposit( double a, double b, double t) {
748  // std::cout << " Deposit " << std::endl;
749  myIncompleteGamma.a().setValue(a);
750  double b2=b*t;
751  double result = 0.;
752  if(fabs(b2) < 1.e-9 ) b2 = 1.e-9;
753  result=myIncompleteGamma(b2);
754  // std::cout << " deposit t = " << t << " " << result <<std::endl;
755  return result;
756 
757 }
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
double sigmaLnT(double lny) const
const HCALProperties * hcalProperties() const
void prepareSteps()
Computes the steps before the real compute.
Definition: EMShower.cc:159
std::vector< double > maximumOfShower
Definition: EMShower.h:115
bool addHit(double r, double phi, unsigned layer=0)
double meanAlphaSpot(double alpha) const
void setSpotEnergy(double e)
Definition: EcalHitMaker.h:117
std::vector< double > aSpot
Definition: EMShower.h:109
unsigned getNumberOfSpots(unsigned i) const
Number of spots in a given interval.
list step
Definition: launcher.py:15
bool addHit(double r, double phi, unsigned layer=0)
double deposit(double t, double a, double b, double dt)
Definition: EMShower.cc:706
void cd(void)
go to top directory (ie. root)
Definition: DQMStore.cc:406
double gam(double x, double a) const
Definition: EMShower.cc:670
const HCALProperties * theHCAL
Definition: EMShower.h:91
void setPreshower(PreshowerHitMaker *const myPresh)
set the preshower address
Definition: EMShower.cc:731
#define NULL
Definition: scimark2.h:8
double rC(double tau, double E) const
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:718
const std::vector< double > & getTailIntervals() const
void compute()
Compute the shower longitudinal and lateral development.
Definition: EMShower.cc:302
const std::vector< double > & getCoreIntervals() const
double gaussShoot(double mean=0.0, double sigma=1.0) const
Definition: RandomEngine.h:37
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
bool addHitDepth(double r, double phi, double depth=-1)
T sqrt(T t)
Definition: SSEVec.h:46
unsigned int poissonShoot(double mean) const
Definition: RandomEngine.h:44
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
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:1468
bool bFixedLength_
Definition: EMShower.h:153
std::vector< double > photos
Definition: EMShower.h:103
const PreshowerLayer1Properties * layer1Properties() const
void setSpotEnergy(double e)
double correlationAlphaT(double lny) const
const ECALProperties * ecalProperties() const
#define M_PI
Definition: BFit3D.cc:3
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
double flatShoot(double xmin=0.0, double xmax=1.0) const
Definition: RandomEngine.h:30
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
EMShower(const RandomEngine *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
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.
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
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
x
Definition: VDTMath.h:216
double ps1TotalX0() const
Definition: EcalHitMaker.h:62
double totalEnergy
Definition: EMShower.h:122
std::vector< double > E
Definition: EMShower.h:102
const RandomEngine * random
Definition: EMShower.h:148
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:741
std::vector< double > bSpot
Definition: EMShower.h:110
Definition: DDAxes.h:10