CMS 3D CMS Logo

CalorimetryManager.cc
Go to the documentation of this file.
1 //updated by Reza Goldouzian
2 //Framework headers
5 
6 // Fast Simulation headers
18 //#include "FastSimulation/Utilities/interface/Histos.h"
28 // New headers for Muon Mip Simulation
31 // Muon Brem
33 
34 //Gflash Hadronic Model
42 
43 //FastHFShowerLibrary
45 
46 // STL headers
47 #include <vector>
48 #include <iostream>
49 
50 //CMSSW headers
53 //#include "DataFormats/EcalDetId/interface/EcalDetId.h"
55 
58 
59 //ROOT headers
60 #include "TROOT.h"
61 #include "TH1.h"
62 
63 using namespace edm;
64 
67 
68 std::vector<std::pair<int,float> > CalorimetryManager::myZero_ = std::vector<std::pair<int,float> >
69  (1,std::pair<int,float>(0,0.));
70 
72  myCalorimeter_(nullptr),
73  initialized_(false)
74 {;}
75 
77  const edm::ParameterSet& fastCalo,
78  const edm::ParameterSet& fastMuECAL,
79  const edm::ParameterSet& fastMuHCAL,
80  const edm::ParameterSet& parGflash)
81  :
82  mySimEvent(aSimEvent),
85 {
86 
89 
90  //Gflash
91  theProfile = new GflashHadronShowerProfile(parGflash);
92  thePiKProfile = new GflashPiKShowerProfile(parGflash);
95 
96  // FastHFShowerLibrary
98 
99  readParameters(fastCalo);
100 
101  myCalorimeter_ =
102  new CaloGeometryHelper(fastCalo);
103  myHDResponse_ =
104  new HCALResponse(fastCalo.getParameter<edm::ParameterSet>("HCALResponse"));
105  myHSParameters_ =
106  new HSParameters(fastCalo.getParameter<edm::ParameterSet>("HSParameters"));
107 
108  // Material Effects for Muons in ECAL (only EnergyLoss implemented so far)
109  if ( fastMuECAL.getParameter<bool>("PairProduction") ||
110  fastMuECAL.getParameter<bool>("Bremsstrahlung") ||
111  fastMuECAL.getParameter<bool>("MuonBremsstrahlung") ||
112  fastMuECAL.getParameter<bool>("EnergyLoss") ||
113  fastMuECAL.getParameter<bool>("MultipleScattering") )
114  theMuonEcalEffects = new MaterialEffects(fastMuECAL);
115 
116  // Material Effects for Muons in HCAL (only EnergyLoss implemented so far)
117  if ( fastMuHCAL.getParameter<bool>("PairProduction") ||
118  fastMuHCAL.getParameter<bool>("Bremsstrahlung") ||
119  fastMuHCAL.getParameter<bool>("MuonBremsstrahlung") ||
120  fastMuHCAL.getParameter<bool>("EnergyLoss") ||
121  fastMuHCAL.getParameter<bool>("MultipleScattering") )
122  theMuonHcalEffects = new MaterialEffects(fastMuHCAL);
123 
124  if( fastCalo.exists("ECALResponseScaling") ) {
125  ecalCorrection = std::unique_ptr<KKCorrectionFactors>( new KKCorrectionFactors( fastCalo.getParameter<edm::ParameterSet>("ECALResponseScaling") ) );
126  }
127 
128 }
129 
131 {
132  EBMapping_.clear();
133  EEMapping_.clear();
134  HMapping_.clear();
135  ESMapping_.clear();
136  muonSimTracks.clear();
137  savedMuonSimTracks.clear();
138 }
139 
141 {
142  if(myCalorimeter_) delete myCalorimeter_;
143  if(myHDResponse_) delete myHDResponse_;
144 
147 
148  if ( theProfile ) delete theProfile;
149 
151 }
152 
154 {
155  if(!evtsToDebug_.empty())
156  {
157  std::vector<unsigned int>::const_iterator itcheck=find(evtsToDebug_.begin(),evtsToDebug_.end(),mySimEvent->id().event());
158  debug_=(itcheck!=evtsToDebug_.end());
159  if(debug_)
160  mySimEvent->print();
161  }
162 
163  initialize(random);
164 
165  LogInfo("FastCalorimetry") << "Reconstructing " << (int) mySimEvent->nTracks() << " tracks." << std::endl;
166  for( int fsimi=0; fsimi < (int) mySimEvent->nTracks() ; ++fsimi) {
167 
168  FSimTrack& myTrack = mySimEvent->track(fsimi);
169 
170  reconstructTrack(myTrack, random);
171  } // particle loop
172 
173 } // reconstruct
174 
176 
177  // Clear the content of the calorimeters
178  if(!initialized_)
179  {
180  theHFShowerLibrary->SetRandom(random);
181 
182  // Check if the preshower is really available
184  {
185  edm::LogWarning("CalorimetryManager") << " WARNING: The preshower simulation has been turned on; but no preshower geometry is available " << std::endl;
186  edm::LogWarning("CalorimetryManager") << " Disabling the preshower simulation " << std::endl;
187  simulatePreshower_ = false;
188  }
189 
190  initialized_=true;
191  }
192  clean();
193 }
194 
196  int pid = abs(myTrack.type());
197 
198  if (debug_) {
199  LogInfo("FastCalorimetry") << " ===> pid = " << pid << std::endl;
200  }
201 
202  // Check that the particle hasn't decayed
203  if(myTrack.noEndVertex()) {
204  // Simulate energy smearing for photon and electrons
205  if ( pid == 11 || pid == 22 ) {
206 
207  if ( myTrack.onEcal() )
208  EMShowerSimulation(myTrack, random);
209  else if ( myTrack.onVFcal() ) {
210  if(useShowerLibrary) {
212  myHDResponse_->correctHF(myTrack.hcalEntrance().e(),abs(myTrack.type()));
214  }
215  else reconstructHCAL(myTrack, random);
216  }
217  } // electron or photon
218  else if (pid==13)
219  {
220  MuonMipSimulation(myTrack, random);
221  }
222  // Simulate energy smearing for hadrons (i.e., everything
223  // but muons... and SUSY particles that deserve a special
224  // treatment.
225  else if ( pid < 1000000 ) {
226  if ( myTrack.onHcal() || myTrack.onVFcal() ) {
227  if(optionHDSim_ == 0 ) reconstructHCAL(myTrack, random);
228  else HDShowerSimulation(myTrack, random);
229  }
230  } // pid < 1000000
231  } // myTrack.noEndVertex()
232 }
233 
234 // Simulation of electromagnetic showers in PS, ECAL, HCAL
237  std::vector<const RawParticle*> thePart;
238  double X0depth;
239 
240  if (debug_) {
241  LogInfo("FastCalorimetry") << " EMShowerSimulation " <<myTrack << std::endl;
242  }
243 
244  // The Particle at ECAL entrance
245  myPart = myTrack.ecalEntrance();
246 
247  // protection against infinite loop.
248  if ( myTrack.type() == 22 && myPart.e()<0.055) return;
249 
250 
251  // Barrel or Endcap ?
252  int onEcal = myTrack.onEcal();
253  int onHcal = myTrack.onHcal();
254  int onLayer1 = myTrack.onLayer1();
255  int onLayer2 = myTrack.onLayer2();
256 
257  // The entrance in ECAL
258  XYZPoint ecalentrance = myPart.vertex().Vect();
259 
260  // The preshower
261  PreshowerHitMaker * myPreshower = nullptr;
262  if(simulatePreshower_ && (onLayer1 || onLayer2))
263  {
264  XYZPoint layer1entrance,layer2entrance;
265  XYZVector dir1,dir2;
266  if(onLayer1)
267  {
268  layer1entrance = XYZPoint(myTrack.layer1Entrance().vertex().Vect());
269  dir1 = XYZVector(myTrack.layer1Entrance().Vect().Unit());
270  }
271  if(onLayer2)
272  {
273  layer2entrance = XYZPoint(myTrack.layer2Entrance().vertex().Vect());
274  dir2 = XYZVector(myTrack.layer2Entrance().Vect().Unit());
275  }
276  myPreshower = new PreshowerHitMaker(myCalorimeter_,
277  layer1entrance,
278  dir1,
279  layer2entrance,
280  dir2,
282  random);
283  myPreshower->setMipEnergy(mipValues_[0],mipValues_[1]);
284  }
285 
286  // The ECAL Properties
288  showerparam(myCalorimeter_->ecalProperties(onEcal),
289  myCalorimeter_->hcalProperties(onHcal),
290  myCalorimeter_->layer1Properties(onLayer1),
291  myCalorimeter_->layer2Properties(onLayer2),
294  RCFactor_,
295  RTFactor_);
296 
297  // Photons : create an e+e- pair
298  if ( myTrack.type() == 22 ) {
299 
300  // Depth for the first e+e- pair creation (in X0)
301  X0depth = -log(random->flatShoot()) * (9./7.);
302 
303  // Initialization
304  double eMass = 0.000510998902;
305  double xe=0;
306  double xm=eMass/myPart.e();
307  double weight = 0.;
308 
309  // Generate electron energy between emass and eGamma-emass
310  do {
311  xe = random->flatShoot()*(1.-2.*xm) + xm;
312  weight = 1. - 4./3.*xe*(1.-xe);
313  } while ( weight < random->flatShoot() );
314 
315  // Protection agains infinite loop in Famos Shower
316  if ( myPart.e()*xe < 0.055 || myPart.e()*(1.-xe) < 0.055 ) {
317 
318  if ( myPart.e() > 0.055 ) thePart.push_back(&myPart);
319 
320  } else {
321 
322  myElec = (myPart) * xe;
323  myPosi = (myPart) * (1.-xe);
326  thePart.push_back(&myElec);
327  thePart.push_back(&myPosi);
328  }
329  // Electrons
330  } else {
331 
332  X0depth = 0.;
333  if ( myPart.e() > 0.055 ) thePart.push_back(&myPart);
334 
335  }
336 
337  // After the different protections, this shouldn't happen.
338  if(thePart.empty())
339  {
340  if(myPreshower==nullptr) return;
341  delete myPreshower;
342  return;
343  }
344 
345  // find the most energetic particle
346  double maxEnergy=-1.;
347  for(unsigned ip=0;ip < thePart.size();++ip)
348  if(thePart[ip]->e() > maxEnergy) maxEnergy = thePart[ip]->e();
349 
350  // Initialize the Grid in ECAL
351  int size = gridSize_;
352  if(maxEnergy>100) size=11;
353 
354  EMShower theShower(random,aGammaGenerator,&showerparam,&thePart,nullptr,nullptr,bFixedLength_);
355 
356  double maxShower = theShower.getMaximumOfShower();
357  if (maxShower > 20.) maxShower = 2.; // simple pivot-searching protection
358 
359  double depth((X0depth + maxShower) *
361  XYZPoint meanShower = ecalentrance + myPart.Vect().Unit()*depth;
362 
363 
364  // The closest crystal
365  DetId pivot(myCalorimeter_->getClosestCell(meanShower, true, onEcal==1));
366 
367  if(pivot.subdetId() == 0) { // further protection against avbsence of pivot
368  edm::LogWarning("CalorimetryManager") << "Pivot for egamma e = " << myTrack.hcalEntrance().e() << " is not found at depth " << depth << " and meanShower coordinates = " << meanShower << std::endl;
369  if(myPreshower) delete myPreshower;
370  return;
371  }
372 
373  EcalHitMaker myGrid(myCalorimeter_,ecalentrance,pivot,onEcal,size,0,random);
374  // ^^^^
375  // for EM showers
378 
379  //maximumdepth dependence of the radiusfactorbehindpreshower
380  //First tuning: Shilpi Jain (Mar-Apr 2010); changed after tuning - Feb-July - Shilpi Jain
381  /* **************
382  myGrid.setRadiusFactor(radiusFactor_);
383  if(onLayer1 || onLayer2)
384  {
385  float b = radiusPreshowerCorrections_[0];
386  float a = radiusFactor_*( 1.+radiusPreshowerCorrections_[1]*radiusPreshowerCorrections_[0] );
387  float maxdepth = X0depth+theShower.getMaximumOfShower();
388  float newRadiusFactor = radiusFactor_;
389  if(myPart.e()<=250.)
390  {
391  newRadiusFactor = a/(1.+b*maxdepth);
392  }
393  myGrid.setRadiusFactor(newRadiusFactor);
394  }
395  else // otherwise use the normal radius factor
396  {
397  myGrid.setRadiusFactor(radiusFactor_);
398  }
399  ************** */
400  if(myTrack.onEcal() == 2) // if on EE
401  {
402  if( (onLayer1 || onLayer2) && myPart.e()<=250.)
403  {
404  double maxdepth = X0depth+theShower.getMaximumOfShower();
405  double newRadiusFactor = radiusFactorEE_ * aTerm/(1.+bTerm*maxdepth);
406  myGrid.setRadiusFactor(newRadiusFactor);
407  }
408  else // otherwise use the normal radius factor
409  {
411  }
412  }//if(myTrack.onEcal() == 2)
413  else // else if on EB
414  {
416  }
417  //(end of) changed after tuning - Feb-July - Shilpi Jain
418 
420 
421  // The shower simulation
422  myGrid.setTrackParameters(myPart.Vect().Unit(),X0depth,myTrack);
423 
424  if(myPreshower) theShower.setPreshower(myPreshower);
425 
426  HcalHitMaker myHcalHitMaker(myGrid,(unsigned)0);
427 
428  theShower.setGrid(&myGrid);
429  theShower.setHcal(&myHcalHitMaker);
430  theShower.compute();
431 
432  // calculate the total simulated energy for this particle
433  float simE = 0;
434  for( const auto& mapIterator : myGrid.getHits() ) {
435  simE += mapIterator.second;
436  }
437 
438  auto scale = ecalCorrection ? ecalCorrection->getScale( myTrack.ecalEntrance().e(),
439  std::abs( myTrack.ecalEntrance().eta() ), simE ) : 1.;
440 
441  // Save the hits !
442  updateECAL( myGrid.getHits(), onEcal,myTrack.id(), scale );
443 
444  // Now fill the HCAL hits
445  updateHCAL(myHcalHitMaker.getHits(),myTrack.id());
446 
447  // delete the preshower
448  if(myPreshower!=nullptr) {
449  updatePreshower(myPreshower->getHits(),myTrack.id());
450  delete myPreshower;
451  }
452 
453 }
454 
457 {
458  int hit;
459  int pid = abs(myTrack.type());
460  if (debug_) {
461  LogInfo("FastCalorimetry") << " reconstructHCAL " << myTrack << std::endl;
462  }
463 
464  XYZTLorentzVector trackPosition;
465  if (myTrack.onHcal()) {
466  trackPosition=myTrack.hcalEntrance().vertex();
467  hit = myTrack.onHcal()-1;
468  } else {
469  trackPosition=myTrack.vfcalEntrance().vertex();
470  hit = 2;
471  }
472 
473  double pathEta = trackPosition.eta();
474  double pathPhi = trackPosition.phi();
475 
476  double EGen = myTrack.hcalEntrance().e();
477  double emeas = 0.;
478 
479  if(pid == 13) {
480  emeas = myHDResponse_->responseHCAL(0, EGen, pathEta, 2, random); // 2=muon
481  if(debug_)
482  LogInfo("FastCalorimetry") << "CalorimetryManager::reconstructHCAL - MUON !!!" << std::endl;
483  }
484  else if( pid == 22 || pid == 11) {
485  emeas = myHDResponse_->responseHCAL(0, EGen, pathEta, 0, random); // last par. = 0 = e/gamma
486  if(debug_)
487  LogInfo("FastCalorimetry") << "CalorimetryManager::reconstructHCAL - e/gamma !!!" << std::endl;
488  }
489  else {
490  emeas = myHDResponse_->getHCALEnergyResponse(EGen, hit, random);
491  }
492 
493  if(debug_)
494  LogInfo("FastCalorimetry") << "CalorimetryManager::reconstructHCAL - on-calo "
495  << " eta = " << pathEta
496  << " phi = " << pathPhi
497  << " Egen = " << EGen
498  << " Emeas = " << emeas << std::endl;
499 
500  if(emeas > 0.) {
501  DetId cell = myCalorimeter_->getClosestCell(trackPosition.Vect(),false,false);
502  double tof = (((HcalGeometry*)(myCalorimeter_->getHcalGeometry()))->getPosition(cell).mag())/29.98;//speed of light
503  CaloHitID current_id(cell.rawId(),tof,myTrack.id());
504  std::map<CaloHitID,float> hitMap;
505  hitMap[current_id] = emeas;
506  updateHCAL(hitMap,myTrack.id());
507  }
508 }
509 
511  // const edm::ParameterSet& fastCalo){
512 
513  theHFShowerLibrary->SetRandom(random);
514 
515  // TimeMe t(" FASTEnergyReconstructor::HDShower");
516  const XYZTLorentzVector& moment = myTrack.momentum();
517 
518  if(debug_)
519  LogInfo("FastCalorimetry")
520  << "CalorimetryManager::HDShowerSimulation - track param."
521  << std::endl
522  << " eta = " << moment.eta() << std::endl
523  << " phi = " << moment.phi() << std::endl
524  << " et = " << moment.Et() << std::endl
525  << " e = " << myTrack.hcalEntrance().e() << std::endl;
526 
527  if (debug_) {
528  LogInfo("FastCalorimetry") << " HDShowerSimulation " << myTrack << std::endl;
529  }
530 
531 
532  int hit;
533 
534  XYZTLorentzVector trackPosition;
535  if ( myTrack.onEcal() ) {
536  trackPosition=myTrack.ecalEntrance().vertex();
537  hit = myTrack.onEcal()-1; //
538  myPart = myTrack.ecalEntrance();
539  } else if ( myTrack.onVFcal()) {
540  trackPosition=myTrack.vfcalEntrance().vertex();
541  hit = 2;
542  myPart = myTrack.vfcalEntrance();
543  }
544  else
545  {
546  LogInfo("FastCalorimetry") << " The particle is not in the acceptance " << std::endl;
547  return;
548  }
549 
550  // int onHCAL = hit + 1; - specially for myCalorimeter->hcalProperties(onHCAL)
551  // (below) to get VFcal properties ...
552  int onHCAL = hit + 1;
553  int onECAL = myTrack.onEcal();
554 
555  double pathEta = trackPosition.eta();
556  double pathPhi = trackPosition.phi();
557 
558  double eint = moment.e();
559  double eGen = myTrack.hcalEntrance().e();
560 
561  double emeas = 0.;
562  double pmip= myHDResponse_->getMIPfraction(eGen, pathEta);
563 
564 
565  //===========================================================================
566  if(eGen > 0.) {
567 
568  // ECAL and HCAL properties to get
570  theHDShowerparam(myCalorimeter_->ecalProperties(onECAL),
573 
574  //Making ECAL Grid (and segments calculation)
575  XYZPoint caloentrance;
576  XYZVector direction;
577  if(myTrack.onEcal())
578  {
579  caloentrance = myTrack.ecalEntrance().vertex().Vect();
580  direction = myTrack.ecalEntrance().Vect().Unit();
581  }
582  else if(myTrack.onHcal())
583  {
584  caloentrance = myTrack.hcalEntrance().vertex().Vect();
585  direction = myTrack.hcalEntrance().Vect().Unit();
586  }
587  else
588  {
589  caloentrance = myTrack.vfcalEntrance().vertex().Vect();
590  direction = myTrack.vfcalEntrance().Vect().Unit();
591  }
592 
593  if(debug_)
594  LogInfo("FastCalorimetry")
595  << "CalorimetryManager::HDShowerSimulation - on-calo 1 "
596  << std::endl
597  << " onEcal = " << myTrack.onEcal() << std::endl
598  << " onHcal = " << myTrack.onHcal() << std::endl
599  << " onVFcal = " << myTrack.onVFcal() << std::endl
600  << " position = " << caloentrance << std::endl;
601 
602 
603  DetId pivot;
604  if(myTrack.onEcal())
605  {
606  pivot=myCalorimeter_->getClosestCell(caloentrance,
607  true, myTrack.onEcal()==1);
608  }
609  else if(myTrack.onHcal())
610  {
611  pivot=myCalorimeter_->getClosestCell(caloentrance,
612  false, false);
613  }
614 
615  EcalHitMaker myGrid(myCalorimeter_,caloentrance,pivot,
616  pivot.null()? 0 : myTrack.onEcal(),hdGridSize_,1,
617  random);
618  // 1=HAD shower
619 
620  myGrid.setTrackParameters(direction,0,myTrack);
621  // Build the FAMOS HCAL
622  HcalHitMaker myHcalHitMaker(myGrid,(unsigned)1);
623 
624  // Shower simulation
625  bool status = false;
626  int mip = 2;
627  // Use HFShower for HF
628  if ( !myTrack.onEcal() && !myTrack.onHcal() ) {
629  // Warning : We give here the particle energy with the response
630  // but without the resolution/gaussian smearing
631  // For HF, the resolution is due to the PE statistic
632 
633  if(useShowerLibrary) {
635  status = true;
636  } else {
637  HFShower theShower(random,
638  &theHDShowerparam,
639  &myGrid,
640  &myHcalHitMaker,
641  onECAL,
642  eGen);
643  // eGen);
644  // e); // PV Warning : temporarly set the energy to the generated E
645 
646  status = theShower.compute();
647  }
648  } else {
649  if(hdSimMethod_ == 0) {
650  HDShower theShower(random,
651  &theHDShowerparam,
652  &myGrid,
653  &myHcalHitMaker,
654  onECAL,
655  eGen,
656  pmip);
657  status = theShower.compute();
658  mip = theShower.getmip();
659  }
660  else if (hdSimMethod_ == 1) {
661  HDRShower theShower(random,
662  &theHDShowerparam,
663  &myGrid,
664  &myHcalHitMaker,
665  onECAL,
666  eGen);
667  status = theShower.computeShower();
668  mip = 2;
669  }
670  else if (hdSimMethod_ == 2 ) {
671  //dynamically loading a corresponding profile by the particle type
672  int particleType = myTrack.type();
674  if(particleType == -2212) theProfile = theAntiProtonProfile;
675  else if(particleType == 2212) theProfile = theProtonProfile;
676 
677  //input variables for GflashHadronShowerProfile
678  int showerType = 99 + myTrack.onEcal();
679  double globalTime = 150.0; // a temporary reference hit time in nanosecond
680  float charge = (float)(myTrack.charge());
681  Gflash3Vector gfpos(trackPosition.X(),trackPosition.Y(),trackPosition.Z());
682  Gflash3Vector gfmom(moment.X(),moment.Y(),moment.Z());
683 
684  theProfile->initialize(showerType,eGen,globalTime,charge,gfpos,gfmom);
687 
688  //make hits
689  std::vector<GflashHit>& gflashHitList = theProfile->getGflashHitList();
690  std::vector<GflashHit>::const_iterator spotIter = gflashHitList.begin();
691  std::vector<GflashHit>::const_iterator spotIterEnd = gflashHitList.end();
692 
694 
695  for( ; spotIter != spotIterEnd; spotIter++){
696 
697  double pathLength = theProfile->getGflashShowino()->getPathLengthAtShower()
698  + (30*100/eGen)*(spotIter->getTime() - globalTime);
699 
700  double currentDepth = std::max(0.0,pathLength - theProfile->getGflashShowino()->getPathLengthOnEcal());
701 
702  //find the the showino position at the currentDepth
703  GflashTrajectoryPoint trajectoryPoint;
704  theProfile->getGflashShowino()->getHelix()->getGflashTrajectoryPoint(trajectoryPoint,pathLength);
705  Gflash3Vector positionAtCurrentDepth = trajectoryPoint.getPosition();
706  //find radial distrance
707  Gflash3Vector lateralDisplacement = positionAtCurrentDepth - spotIter->getPosition()/CLHEP::cm;
708  double rShower = lateralDisplacement.r();
709  double azimuthalAngle = lateralDisplacement.phi();
710 
711  whichCalor = Gflash::getCalorimeterNumber(positionAtCurrentDepth);
712 
713  if(whichCalor==Gflash::kESPM || whichCalor==Gflash::kENCA) {
714  bool statusPad = myGrid.getPads(currentDepth,true);
715  if(!statusPad) continue;
716  myGrid.setSpotEnergy(1.2*spotIter->getEnergy()/CLHEP::GeV);
717  myGrid.addHit(rShower/Gflash::intLength[Gflash::kESPM],azimuthalAngle,0);
718  }
719  else if(whichCalor==Gflash::kHB || whichCalor==Gflash::kHE) {
720  bool setHDdepth = myHcalHitMaker.setDepth(currentDepth,true);
721  if(!setHDdepth) continue;
722  myHcalHitMaker.setSpotEnergy(1.4*spotIter->getEnergy()/CLHEP::GeV);
723  myHcalHitMaker.addHit(rShower/Gflash::intLength[Gflash::kHB],azimuthalAngle,0);
724  }
725  }
726  status = true;
727  }
728  else {
729  edm::LogInfo("FastSimulationCalorimetry") << " SimMethod " << hdSimMethod_ <<" is NOT available ";
730  }
731  }
732 
733 
734  if(status) {
735 
736  // Here to switch between simple formulae and parameterized response
737  if(optionHDSim_ == 1) {
738  emeas = myHDResponse_->getHCALEnergyResponse(eGen, hit, random);
739  }
740  else { // optionHDsim == 2
741  emeas = myHDResponse_->responseHCAL(mip, eGen, pathEta, 1, random); // 1=hadron
742  }
743 
744  double correction = emeas / eGen;
745 
746  // RespCorrP factors (ECAL and HCAL separately) calculation
747  respCorr(eint);
748 
749  if(debug_)
750  LogInfo("FastCalorimetry")
751  << "CalorimetryManager::HDShowerSimulation - on-calo 2" << std::endl
752  << " eta = " << pathEta << std::endl
753  << " phi = " << pathPhi << std::endl
754  << " Egen = " << eGen << std::endl
755  << " Emeas = " << emeas << std::endl
756  << " corr = " << correction << std::endl
757  << " mip = " << mip << std::endl;
758 
759  if(myTrack.onEcal() > 0) {
760  // Save ECAL hits
761  updateECAL(myGrid.getHits(),onECAL,myTrack.id(),correction*ecorr);
762  }
763 
764  // Save HCAL hits
765  if(myTrack.onVFcal() && useShowerLibrary) {
766  myHDResponse_->correctHF(eGen,abs(myTrack.type()));
768  }
769  else
770  updateHCAL(myHcalHitMaker.getHits(),myTrack.id(),correction*hcorr);
771 
772  }
773  else { // shower simulation failed
774  if(myTrack.onHcal() || myTrack.onVFcal())
775  {
776  DetId cell = myCalorimeter_->getClosestCell(trackPosition.Vect(),false,false);
777  double tof = (((HcalGeometry*)(myCalorimeter_->getHcalGeometry()))->getPosition(cell).mag())/29.98;//speed of light
778  CaloHitID current_id(cell.rawId(),tof,myTrack.id());
779  std::map<CaloHitID,float> hitMap;
780  hitMap[current_id] = emeas;
781  updateHCAL(hitMap,myTrack.id());
782  if(debug_)
783  LogInfo("FastCalorimetry") << " HCAL simple cell "
784  << cell.rawId() << " added E = "
785  << emeas << std::endl;
786  }
787  }
788 
789  } // e > 0. ...
790 
791  if(debug_)
792  LogInfo("FastCalorimetry") << std::endl << " FASTEnergyReconstructor::HDShowerSimulation finished "
793  << std::endl;
794 }
795 
796 
798 {
799  // TimeMe t(" FASTEnergyReconstructor::HDShower");
800  XYZTLorentzVector moment = myTrack.momentum();
801 
802  // Backward compatibility behaviour
803  if(!theMuonHcalEffects)
804  {
805  savedMuonSimTracks.push_back(myTrack);
806 
807  if(myTrack.onHcal() || myTrack.onVFcal() )
808  reconstructHCAL(myTrack, random);
809 
810  return;
811  }
812 
813 
814  if(debug_)
815  LogInfo("FastCalorimetry") << "CalorimetryManager::MuonMipSimulation - track param."
816  << std::endl
817  << " eta = " << moment.eta() << std::endl
818  << " phi = " << moment.phi() << std::endl
819  << " et = " << moment.Et() << std::endl;
820 
821  XYZTLorentzVector trackPosition;
822  if ( myTrack.onEcal() ) {
823  trackPosition=myTrack.ecalEntrance().vertex();
824  myPart = myTrack.ecalEntrance();
825  } else if ( myTrack.onVFcal()) {
826  trackPosition=myTrack.vfcalEntrance().vertex();
827  myPart = myTrack.vfcalEntrance();
828  }
829  else
830  {
831  LogInfo("FastCalorimetry") << " The particle is not in the acceptance " << std::endl;
832  return;
833  }
834 
835  // int onHCAL = hit + 1; - specially for myCalorimeter->hcalProperties(onHCAL)
836  // (below) to get VFcal properties ...
837  // not needed ?
838  // int onHCAL = hit + 1;
839  int onECAL = myTrack.onEcal();
840 
841  //===========================================================================
842 
843  // ECAL and HCAL properties to get
844 
845  //Making ECAL Grid (and segments calculation)
846  XYZPoint caloentrance;
847  XYZVector direction;
848  if(myTrack.onEcal())
849  {
850  caloentrance = myTrack.ecalEntrance().vertex().Vect();
851  direction = myTrack.ecalEntrance().Vect().Unit();
852  }
853  else if(myTrack.onHcal())
854  {
855  caloentrance = myTrack.hcalEntrance().vertex().Vect();
856  direction = myTrack.hcalEntrance().Vect().Unit();
857  }
858  else
859  {
860  caloentrance = myTrack.vfcalEntrance().vertex().Vect();
861  direction = myTrack.vfcalEntrance().Vect().Unit();
862  }
863 
864  DetId pivot;
865  if(myTrack.onEcal())
866  {
867  pivot=myCalorimeter_->getClosestCell(caloentrance,
868  true, myTrack.onEcal()==1);
869  }
870  else if(myTrack.onHcal())
871  {
872  pivot=myCalorimeter_->getClosestCell(caloentrance,
873  false, false);
874  }
875 
876  EcalHitMaker myGrid(myCalorimeter_,caloentrance,pivot,
877  pivot.null()? 0 : myTrack.onEcal(),hdGridSize_,0,
878  random);
879  // 0 =EM shower -> Unit = X0
880 
881  myGrid.setTrackParameters(direction,0,myTrack);
882 
883  // Now get the path in the Preshower, ECAL and HCAL along a straight line extrapolation
884  // but only those in the ECAL are used
885 
886  const std::vector<CaloSegment>& segments=myGrid.getSegments();
887  unsigned nsegments=segments.size();
888 
889  int ifirstHcal=-1;
890  int ilastEcal=-1;
891 
892  EnergyLossSimulator* energyLossECAL = (theMuonEcalEffects) ?
894  // // Muon brem in ECAL
895  // MuonBremsstrahlungSimulator* muonBremECAL = 0;
896  // if (theMuonEcalEffects) muonBremECAL = theMuonEcalEffects->muonBremsstrahlungSimulator();
897 
898  for(unsigned iseg=0;iseg<nsegments&&ifirstHcal<0;++iseg)
899  {
900 
901  // in the ECAL, there are two types of segments: PbWO4 and GAP
902  float segmentSizeinX0=segments[iseg].X0length();
903 
904  // Martijn - insert your computations here
905  float energy=0.0;
906  if (segmentSizeinX0>0.001 && segments[iseg].material()==CaloSegment::PbWO4 ) {
907  // The energy loss simulator
908  float charge = (float)(myTrack.charge());
909  ParticlePropagator theMuon(moment,trackPosition,charge,nullptr);
910  theMuon.setID(-(int)charge*13);
911  if ( energyLossECAL ) {
912  energyLossECAL->updateState(theMuon, segmentSizeinX0, random);
913  energy = energyLossECAL->deltaMom().E();
914  moment -= energyLossECAL->deltaMom();
915  }
916  }
917  // that's all for ECAL, Florian
918  // Save the hit only if it is a crystal
919  if(segments[iseg].material()==CaloSegment::PbWO4)
920  {
921  myGrid.getPads(segments[iseg].sX0Entrance()+segmentSizeinX0*0.5);
922  myGrid.setSpotEnergy(energy);
923  myGrid.addHit(0.,0.);
924  ilastEcal=iseg;
925  }
926  // Check for end of loop:
927  if(segments[iseg].material()==CaloSegment::HCAL)
928  {
929  ifirstHcal=iseg;
930  }
931  }
932 
933 
934  // Build the FAMOS HCAL
935  HcalHitMaker myHcalHitMaker(myGrid,(unsigned)2);
936  // float mipenergy=0.1;
937  // Create the helix with the stepping helix propagator
938  // to add a hit, just do
939  // myHcalHitMaker.setSpotEnergy(mipenergy);
940  // math::XYZVector hcalEntrance;
941  // if(ifirstHcal>=0) hcalEntrance=segments[ifirstHcal].entrance();
942  // myHcalHitMaker.addHit(hcalEntrance);
946  int ilastHcal=-1;
947  float mipenergy=0.0;
948 
949  EnergyLossSimulator* energyLossHCAL = (theMuonHcalEffects) ?
951  // // Muon Brem effect
952  // MuonBremsstrahlungSimulator* muonBremHCAL = 0;
953  // if (theMuonHcalEffects) muonBremHCAL = theMuonHcalEffects->muonBremsstrahlungSimulator();
954 
955  if(ifirstHcal>0 && energyLossHCAL){
956  for(unsigned iseg=ifirstHcal;iseg<nsegments;++iseg)
957  {
958  float segmentSizeinX0=segments[iseg].X0length();
959  if(segments[iseg].material()==CaloSegment::HCAL) {
960  ilastHcal=iseg;
961  if (segmentSizeinX0>0.001) {
962  // The energy loss simulator
963  float charge = (float)(myTrack.charge());
964  ParticlePropagator theMuon(moment,trackPosition,charge,nullptr);
965  theMuon.setID(-(int)charge*13);
966  energyLossHCAL->updateState(theMuon, segmentSizeinX0, random);
967  mipenergy = energyLossHCAL->deltaMom().E();
968  moment -= energyLossHCAL->deltaMom();
969  myHcalHitMaker.setSpotEnergy(mipenergy);
970  myHcalHitMaker.addHit(segments[iseg].entrance());
971  }
972  }
973  }
974  }
975 
976  // Copy the muon SimTrack (Only for Energy loss)
977  FSimTrack muonTrack(myTrack);
978  if(energyLossHCAL && ilastHcal>=0) {
979  math::XYZVector hcalExit=segments[ilastHcal].exit();
980  muonTrack.setTkPosition(hcalExit);
981  muonTrack.setTkMomentum(moment);
982  } else if(energyLossECAL && ilastEcal>=0) {
983  math::XYZVector ecalExit=segments[ilastEcal].exit();
984  muonTrack.setTkPosition(ecalExit);
985  muonTrack.setTkMomentum(moment);
986  } // else just leave tracker surface position and momentum...
987 
988  muonSimTracks.push_back(muonTrack);
989 
990  // no need to change below this line
991  std::map<CaloHitID,float>::const_iterator mapitr;
992  std::map<CaloHitID,float>::const_iterator endmapitr;
993  if(myTrack.onEcal() > 0) {
994  // Save ECAL hits
995  updateECAL(myGrid.getHits(),onECAL,myTrack.id());
996  }
997 
998  // Save HCAL hits
999  updateHCAL(myHcalHitMaker.getHits(),myTrack.id());
1000 
1001  if(debug_)
1002  LogInfo("FastCalorimetry") << std::endl << " FASTEnergyReconstructor::MipShowerSimulation finished "
1003  << std::endl;
1004 }
1005 
1006 
1008 
1009  edm::ParameterSet ECALparameters = fastCalo.getParameter<edm::ParameterSet>("ECAL");
1010 
1011  evtsToDebug_ = fastCalo.getUntrackedParameter<std::vector<unsigned int> >("EvtsToDebug",std::vector<unsigned>());
1012  debug_ = fastCalo.getUntrackedParameter<bool>("Debug");
1013 
1014  bFixedLength_ = ECALparameters.getParameter<bool>("bFixedLength");
1015 
1016  gridSize_ = ECALparameters.getParameter<int>("GridSize");
1017  spotFraction_ = ECALparameters.getParameter<double>("SpotFraction");
1018  pulledPadSurvivalProbability_ = ECALparameters.getParameter<double>("FrontLeakageProbability");
1019  crackPadSurvivalProbability_ = ECALparameters.getParameter<double>("GapLossProbability");
1020  theCoreIntervals_ = ECALparameters.getParameter<std::vector<double> >("CoreIntervals");
1021  theTailIntervals_ = ECALparameters.getParameter<std::vector<double> >("TailIntervals");
1022 
1023  RCFactor_ = ECALparameters.getParameter<double>("RCFactor");
1024  RTFactor_ = ECALparameters.getParameter<double>("RTFactor");
1025  //changed after tuning - Feb-July - Shilpi Jain
1026  // radiusFactor_ = ECALparameters.getParameter<double>("RadiusFactor");
1027  radiusFactorEE_ = ECALparameters.getParameter<double>("RadiusFactorEE");
1028  radiusFactorEB_ = ECALparameters.getParameter<double>("RadiusFactorEB");
1029  //(end of) changed after tuning - Feb-July - Shilpi Jain
1030  radiusPreshowerCorrections_ = ECALparameters.getParameter<std::vector<double> >("RadiusPreshowerCorrections");
1031  aTerm = 1.+radiusPreshowerCorrections_[1]*radiusPreshowerCorrections_[0];
1032  bTerm = radiusPreshowerCorrections_[0];
1033  mipValues_ = ECALparameters.getParameter<std::vector<double> >("MipsinGeV");
1034  simulatePreshower_ = ECALparameters.getParameter<bool>("SimulatePreshower");
1035 
1036  if(gridSize_ <1) gridSize_= 7;
1037  if(pulledPadSurvivalProbability_ <0. || pulledPadSurvivalProbability_>1 ) pulledPadSurvivalProbability_= 1.;
1038  if(crackPadSurvivalProbability_ <0. || crackPadSurvivalProbability_>1 ) crackPadSurvivalProbability_= 0.9;
1039 
1040  LogInfo("FastCalorimetry") << " Fast ECAL simulation parameters " << std::endl;
1041  LogInfo("FastCalorimetry") << " =============================== " << std::endl;
1042  if(simulatePreshower_)
1043  LogInfo("FastCalorimetry") << " The preshower is present " << std::endl;
1044  else
1045  LogInfo("FastCalorimetry") << " The preshower is NOT present " << std::endl;
1046  LogInfo("FastCalorimetry") << " Grid Size : " << gridSize_ << std::endl;
1047  if(spotFraction_>0.)
1048  LogInfo("FastCalorimetry") << " Spot Fraction : " << spotFraction_ << std::endl;
1049  else
1050  {
1051  LogInfo("FastCalorimetry") << " Core of the shower " << std::endl;
1052  for(unsigned ir=0; ir < theCoreIntervals_.size()/2;++ir)
1053  {
1054  LogInfo("FastCalorimetry") << " r < " << theCoreIntervals_[ir*2] << " R_M : " << theCoreIntervals_[ir*2+1] << " ";
1055  }
1056  LogInfo("FastCalorimetry") << std::endl;
1057 
1058  LogInfo("FastCalorimetry") << " Tail of the shower " << std::endl;
1059  for(unsigned ir=0; ir < theTailIntervals_.size()/2;++ir)
1060  {
1061  LogInfo("FastCalorimetry") << " r < " << theTailIntervals_[ir*2] << " R_M : " << theTailIntervals_[ir*2+1] << " ";
1062  }
1063  //changed after tuning - Feb-July - Shilpi Jain
1064  LogInfo("FastCalorimetry") << "Radius correction factors: EB & EE " << radiusFactorEB_ << " : "<< radiusFactorEE_ << std::endl;
1065  //(end of) changed after tuning - Feb-July - Shilpi Jain
1066  LogInfo("FastCalorimetry") << std::endl;
1067  if(mipValues_.size()>2) {
1068  LogInfo("FastCalorimetry") << "Improper number of parameters for the preshower ; using 95keV" << std::endl;
1069  mipValues_.clear();
1070  mipValues_.resize(2,0.000095);
1071  }
1072  }
1073 
1074  LogInfo("FastCalorimetry") << " FrontLeakageProbability : " << pulledPadSurvivalProbability_ << std::endl;
1075  LogInfo("FastCalorimetry") << " GapLossProbability : " << crackPadSurvivalProbability_ << std::endl;
1076 
1077 
1078  // RespCorrP: p (momentum), ECAL and HCAL corrections = f(p)
1079  edm::ParameterSet CalorimeterParam = fastCalo.getParameter<edm::ParameterSet>("CalorimeterProperties");
1080 
1081  rsp = CalorimeterParam.getParameter<std::vector<double> >("RespCorrP");
1082  LogInfo("FastCalorimetry") << " RespCorrP (rsp) size " << rsp.size() << std::endl;
1083 
1084  if( rsp.size()%3 !=0 ) {
1085  LogInfo("FastCalorimetry")
1086  << " RespCorrP size is wrong -> no corrections applied !!!"
1087  << std::endl;
1088 
1089  p_knots.push_back(14000.);
1090  k_e.push_back (1.);
1091  k_h.push_back (1.);
1092  }
1093  else {
1094  for(unsigned i = 0; i < rsp.size(); i += 3) {
1095  LogInfo("FastCalorimetry") << "i = " << i/3 << " p = " << rsp [i]
1096  << " k_e(p) = " << rsp[i+1]
1097  << " k_e(p) = " << rsp[i+2] << std::endl;
1098 
1099  p_knots.push_back(rsp[i]);
1100  k_e.push_back (rsp[i+1]);
1101  k_h.push_back (rsp[i+2]);
1102  }
1103  }
1104 
1105 
1106  //FR
1107  edm::ParameterSet HCALparameters = fastCalo.getParameter<edm::ParameterSet>("HCAL");
1108  optionHDSim_ = HCALparameters.getParameter<int>("SimOption");
1109  hdGridSize_ = HCALparameters.getParameter<int>("GridSize");
1110  hdSimMethod_ = HCALparameters.getParameter<int>("SimMethod");
1111  //RF
1112 
1113  EcalDigitizer_ = ECALparameters.getUntrackedParameter<bool>("Digitizer",false);
1114  HcalDigitizer_ = HCALparameters.getUntrackedParameter<bool>("Digitizer",false);
1115  samplingHBHE_ = HCALparameters.getParameter< std::vector<double> >("samplingHBHE");
1116  samplingHF_ = HCALparameters.getParameter< std::vector<double> >("samplingHF");
1117  samplingHO_ = HCALparameters.getParameter< std::vector<double> >("samplingHO");
1118  ietaShiftHB_ = HCALparameters.getParameter< int >("ietaShiftHB");
1119  ietaShiftHE_ = HCALparameters.getParameter< int >("ietaShiftHE");
1120  ietaShiftHF_ = HCALparameters.getParameter< int >("ietaShiftHF");
1121  ietaShiftHO_ = HCALparameters.getParameter< int >("ietaShiftHO");
1122  timeShiftHB_ = HCALparameters.getParameter< std::vector<double> >("timeShiftHB");
1123  timeShiftHE_ = HCALparameters.getParameter< std::vector<double> >("timeShiftHE");
1124  timeShiftHF_ = HCALparameters.getParameter< std::vector<double> >("timeShiftHF");
1125  timeShiftHO_ = HCALparameters.getParameter< std::vector<double> >("timeShiftHO");
1126 
1127  // FastHFShowerLibrary
1128  edm::ParameterSet m_HS = fastCalo.getParameter<edm::ParameterSet>("HFShowerLibrary");
1129  useShowerLibrary = m_HS.getUntrackedParameter<bool>("useShowerLibrary",false);
1130  useCorrectionSL = m_HS.getUntrackedParameter<bool>("useCorrectionSL",false);
1131 }
1132 
1134 
1135  int sizeP = p_knots.size();
1136 
1137  if(sizeP <= 1) {
1138  ecorr = 1.;
1139  hcorr = 1.;
1140  }
1141  else {
1142  int ip = -1;
1143  for (int i = 0; i < sizeP; i++) {
1144  if (p < p_knots[i]) { ip = i; break;}
1145  }
1146  if (ip == 0) {
1147  ecorr = k_e[0];
1148  hcorr = k_h[0];
1149  }
1150  else {
1151  if(ip == -1) {
1152  ecorr = k_e[sizeP-1];
1153  hcorr = k_h[sizeP-1];
1154  }
1155  else {
1156  double x1 = p_knots[ip-1];
1157  double x2 = p_knots[ip];
1158  double y1 = k_e[ip-1];
1159  double y2 = k_e[ip];
1160 
1161  ecorr = (y1 + (y2 - y1) * (p - x1)/(x2 - x1));
1162 
1163  y1 = k_h[ip-1];
1164  y2 = k_h[ip];
1165  hcorr = (y1 + (y2 - y1) * (p - x1)/(x2 - x1));
1166 
1167  }
1168  }
1169  }
1170 
1171  if(debug_)
1172  LogInfo("FastCalorimetry") << " p, ecorr, hcorr = " << p << " "
1173  << ecorr << " " << hcorr << std::endl;
1174 
1175 }
1176 
1177 void CalorimetryManager::updateECAL(const std::map<CaloHitID,float>& hitMap, int onEcal, int trackID, float corr)
1178 {
1179  std::map<CaloHitID,float>::const_iterator mapitr;
1180  std::map<CaloHitID,float>::const_iterator endmapitr=hitMap.end();
1181  if(onEcal==1) {
1182  EBMapping_.reserve(EBMapping_.size()+hitMap.size());
1183  endmapitr=hitMap.end();
1184  for(mapitr=hitMap.begin();mapitr!=endmapitr;++mapitr) {
1185  //correct energy
1186  float energy = mapitr->second;
1187  energy *= corr;
1188 
1189  //make finalized CaloHitID
1190  CaloHitID current_id(mapitr->first.unitID(),mapitr->first.timeSlice(),trackID);
1191 
1192  EBMapping_.push_back(std::pair<CaloHitID,float>(current_id,energy));
1193  }
1194  }
1195  else if(onEcal==2) {
1196  EEMapping_.reserve(EEMapping_.size()+hitMap.size());
1197  endmapitr=hitMap.end();
1198  for(mapitr=hitMap.begin();mapitr!=endmapitr;++mapitr) {
1199  //correct energy
1200  float energy = mapitr->second;
1201  energy *= corr;
1202 
1203  //make finalized CaloHitID
1204  CaloHitID current_id(mapitr->first.unitID(),mapitr->first.timeSlice(),trackID);
1205 
1206  EEMapping_.push_back(std::pair<CaloHitID,float>(current_id,energy));
1207  }
1208  }
1209 
1210 }
1211 
1212 void CalorimetryManager::updateHCAL(const std::map<CaloHitID,float>& hitMap, int trackID, float corr)
1213 {
1214  std::vector<double> hfcorrEm = myHDResponse_->getCorrHFem();
1215  std::vector<double> hfcorrHad = myHDResponse_->getCorrHFhad();
1216  std::map<CaloHitID,float>::const_iterator mapitr;
1217  std::map<CaloHitID,float>::const_iterator endmapitr=hitMap.end();
1218  HMapping_.reserve(HMapping_.size()+hitMap.size());
1219  for(mapitr=hitMap.begin(); mapitr!=endmapitr; ++mapitr) {
1220  //correct energy
1221  float energy = mapitr->second;
1222  energy *= corr;
1223 
1224  float time = mapitr->first.timeSlice();
1225  //put energy into uncalibrated state for digitizer && correct timing
1226  if(HcalDigitizer_){
1227  HcalDetId hdetid = HcalDetId(mapitr->first.unitID());
1228  if (hdetid.subdetId()== HcalBarrel){
1229  energy /= samplingHBHE_[hdetid.ietaAbs()-1]; //re-convert to GeV
1230  time = timeShiftHB_[hdetid.ietaAbs()-ietaShiftHB_];
1231  }
1232  else if (hdetid.subdetId()== HcalEndcap){
1233  energy /= samplingHBHE_[hdetid.ietaAbs()-1]; //re-convert to GeV
1234  time = timeShiftHE_[hdetid.ietaAbs()-ietaShiftHE_];
1235  }
1236  else if (hdetid.subdetId()== HcalForward){
1237  if(useShowerLibrary) {
1238  if(useCorrectionSL) {
1239  if(hdetid.depth()== 1 or hdetid.depth()==3) energy *= hfcorrEm[hdetid.ietaAbs()-ietaShiftHF_];
1240  if(hdetid.depth()== 2 or hdetid.depth()==4) energy *= hfcorrHad[hdetid.ietaAbs()-ietaShiftHF_];
1241  }
1242  } else {
1243  if(hdetid.depth()== 1 or hdetid.depth()==3) energy *= samplingHF_[0];
1244  if(hdetid.depth()== 2 or hdetid.depth()==4) energy *= samplingHF_[1];
1245  time = timeShiftHF_[hdetid.ietaAbs()-ietaShiftHF_];
1246  }
1247  }
1248  else if (hdetid.subdetId()== HcalOuter){
1249  energy /= samplingHO_[hdetid.ietaAbs()-1];
1250  time = timeShiftHO_[hdetid.ietaAbs()-ietaShiftHO_];
1251  }
1252  }
1253 
1254  //make finalized CaloHitID
1255  CaloHitID current_id(mapitr->first.unitID(),time,trackID);
1256  HMapping_.push_back(std::pair<CaloHitID,float>(current_id,energy));
1257  }
1258 }
1259 
1260 void CalorimetryManager::updatePreshower(const std::map<CaloHitID,float>& hitMap, int trackID, float corr)
1261 {
1262  std::map<CaloHitID,float>::const_iterator mapitr;
1263  std::map<CaloHitID,float>::const_iterator endmapitr=hitMap.end();
1264  ESMapping_.reserve(ESMapping_.size()+hitMap.size());
1265  for(mapitr=hitMap.begin();mapitr!=endmapitr;++mapitr) {
1266  //correct energy
1267  float energy = mapitr->second;
1268  energy *= corr;
1269 
1270  //make finalized CaloHitID
1271  CaloHitID current_id(mapitr->first.unitID(),mapitr->first.timeSlice(),trackID);
1272 
1273  ESMapping_.push_back(std::pair<CaloHitID,float>(current_id,energy));
1274  }
1275 }
1276 
1278 {
1279  c.reserve(c.size()+EBMapping_.size());
1280  for(unsigned i=0; i<EBMapping_.size(); i++) {
1281  c.push_back(PCaloHit(EBDetId::unhashIndex(EBMapping_[i].first.unitID()),EBMapping_[i].second,EBMapping_[i].first.timeSlice(),EBMapping_[i].first.trackID()));
1282  }
1283 }
1284 
1286 {
1287  c.reserve(c.size()+EEMapping_.size());
1288  for(unsigned i=0; i<EEMapping_.size(); i++) {
1289  c.push_back(PCaloHit(EEDetId::unhashIndex(EEMapping_[i].first.unitID()),EEMapping_[i].second,EEMapping_[i].first.timeSlice(),EEMapping_[i].first.trackID()));
1290  }
1291 }
1292 
1294 {
1295  c.reserve(c.size()+HMapping_.size());
1296  for(unsigned i=0; i<HMapping_.size(); i++) {
1297  c.push_back(PCaloHit(DetId(HMapping_[i].first.unitID()),HMapping_[i].second,HMapping_[i].first.timeSlice(),HMapping_[i].first.trackID()));
1298  }
1299 }
1300 
1301 
1303 {
1304  c.reserve(c.size()+ESMapping_.size());
1305  for(unsigned i=0; i<ESMapping_.size(); i++) {
1306  c.push_back(PCaloHit(ESMapping_[i].first.unitID(),ESMapping_[i].second,ESMapping_[i].first.timeSlice(),ESMapping_[i].first.trackID()));
1307  }
1308 }
1309 
1310 // The main danger in this method is to screw up to relationships between particles
1311 // So, the muon FSimTracks created by FSimEvent.cc are simply to be updated
1313 {
1314  unsigned size=muons.size();
1315  for(unsigned i=0; i<size;++i)
1316  {
1317  int id=muons[i].trackId();
1318  if(abs(muons[i].type())!=13) continue;
1319  // identify the corresponding muon in the local collection
1320 
1321  std::vector<FSimTrack>::const_iterator itcheck=find_if(muonSimTracks.begin(),muonSimTracks.end(),FSimTrackEqual(id));
1322  if(itcheck!=muonSimTracks.end())
1323  {
1324  muons[i].setTkPosition(itcheck->trackerSurfacePosition());
1325  muons[i].setTkMomentum(itcheck->trackerSurfaceMomentum());
1326  }
1327  }
1328 
1329 }
1330 
1331 
1333 {
1334  c.reserve(int(0.2*muonSimTracks.size()+0.2*savedMuonSimTracks.size()+0.5));
1335  for(const auto & track : muonSimTracks){
1336  if(track.momentum().perp2() > 1.0 && fabs(track.momentum().eta()) < 3.0 && track.isGlobal()) c.push_back(track);
1337  }
1338  for(const auto & track : savedMuonSimTracks){
1339  if(track.momentum().perp2() > 1.0 && fabs(track.momentum().eta()) < 3.0 && track.isGlobal()) c.push_back(track);
1340  }
1341  c.shrink_to_fit();
1342 }
1343 
size
Write out results.
type
Definition: HCALResponse.h:21
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:41
T getUntrackedParameter(std::string const &, T const &) const
std::vector< double > rsp
std::vector< double > k_h
bool noEndVertex() const
no end vertex
RawParticle myElec
A few pointers to save time.
std::vector< std::pair< CaloHitID, float > > ESMapping_
float charge() const
charge
Definition: FSimTrack.h:51
void reconstructHCAL(const FSimTrack &myTrack, RandomEngineAndDistribution const *)
std::vector< PCaloHit > PCaloHitContainer
const double GeV
Definition: MathUtil.h:16
const ECALProperties * ecalProperties(int onEcal) const
ECAL properties.
Definition: Calorimeter.cc:76
double responseHCAL(int _mip, double energy, double eta, int partype, RandomEngineAndDistribution const *)
const RawParticle & vfcalEntrance() const
The particle at VFCAL entrance.
Definition: FSimTrack.h:144
void updateHCAL(const std::map< CaloHitID, float > &hitMap, int trackID=0, float corr=1.0)
int onLayer2() const
Definition: FSimTrack.h:101
GflashPiKShowerProfile * thePiKProfile
double flatShoot(double xmin=0.0, double xmax=1.0) const
std::vector< double > timeShiftHO_
void updatePreshower(const std::map< CaloHitID, float > &hitMap, int trackID=0, float corr=1.0)
GflashTrajectory * getHelix()
Definition: GflashShowino.h:30
constexpr bool null() const
is this a null id ?
Definition: DetId.h:52
MaterialEffects * theMuonEcalEffects
MaterialEffects * theMuonHcalEffects
void recoHFShowerLibrary(const FSimTrack &myTrack)
const XYZTLorentzVector & momentum() const
Temporary (until move of SimTrack to Mathcore) - No! Actually very useful.
Definition: FSimTrack.h:204
void setCrackPadSurvivalProbability(double val)
Definition: EcalHitMaker.h:134
double getHCALEnergyResponse(double e, int hit, RandomEngineAndDistribution const *)
GflashHadronShowerProfile * theProfile
const RawParticle & layer1Entrance() const
The particle at Preshower Layer 1.
Definition: FSimTrack.h:132
bool compute()
Compute the shower longitudinal and lateral development.
Definition: HDShower.cc:447
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
bool exists(std::string const &parameterName) const
checks if a parameter exists
void correctHF(double e, int type)
void reconstructTrack(FSimTrack &myTrack, RandomEngineAndDistribution const *)
void setPreshower(PreshowerHitMaker *const myPresh)
set the preshower address
Definition: EMShower.cc:704
void loadFromPreshower(edm::PCaloHitContainer &c) const
Definition: weight.py:1
void updateState(ParticlePropagator &myTrack, double radlen, RandomEngineAndDistribution const *)
Compute the material effect (calls the sub class)
void updateECAL(const std::map< CaloHitID, float > &hitMap, int onEcal, int trackID=0, float corr=1.0)
const std::map< CaloHitID, float > & getHits() override
const CaloSubdetectorGeometry * getHcalGeometry() const
Definition: Calorimeter.h:57
void MuonMipSimulation(const FSimTrack &myTrack, RandomEngineAndDistribution const *)
void readParameters(const edm::ParameterSet &fastCalo)
TRandom random
Definition: MVATrainer.cc:138
const PreshowerLayer1Properties * layer1Properties(int onLayer1) const
Preshower Layer1 properties.
Definition: Calorimeter.cc:103
static EEDetId unhashIndex(int hi)
Definition: EEDetId.cc:99
#define nullptr
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
static double constexpr eMass
Electron mass[GeV].
Definition: Constants.h:17
std::vector< double > timeShiftHF_
std::vector< double > p_knots
void compute()
Compute the shower longitudinal and lateral development.
Definition: EMShower.cc:273
std::vector< std::pair< CaloHitID, float > > EBMapping_
int onEcal() const
Definition: FSimTrack.h:106
std::vector< FSimTrack > muonSimTracks
double radLenIncm() const override
Radiation length in cm.
U second(std::pair< T, U > const &p)
void HDShowerSimulation(const FSimTrack &myTrack, RandomEngineAndDistribution const *)
Hadronic Shower Simulation.
const LandauFluctuationGenerator * aLandauGenerator
std::vector< double > samplingHF_
bool compute()
Compute the shower longitudinal and lateral development.
Definition: HFShower.cc:475
void setRadiusFactor(double r)
Definition: EcalHitMaker.h:130
bool addHit(double r, double phi, unsigned layer=0) override
add the hit in the HCAL in local coordinates
Definition: HcalHitMaker.cc:28
int depth() const
get the tower depth
Definition: HcalDetId.h:166
void reconstruct(RandomEngineAndDistribution const *)
CalorimeterNumber getCalorimeterNumber(const Gflash3Vector &position)
GflashAntiProtonShowerProfile * theAntiProtonProfile
math::XYZVector XYZVector
int getmip()
Definition: HDShower.h:42
GflashProtonShowerProfile * theProtonProfile
const PreshowerLayer2Properties * layer2Properties(int onLayer2) const
Preshower Layer2 properties.
Definition: Calorimeter.cc:111
double getPathLengthAtShower()
Definition: GflashShowino.h:26
const std::map< CaloHitID, float > & getHits() override
not been done.
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void setTrackParameters(const XYZNormal &normal, double X0depthoffset, const FSimTrack &theTrack)
void loadFromEcalEndcap(edm::PCaloHitContainer &c) const
void setID(const int id)
Definition: RawParticle.cc:102
const XYZTLorentzVector & deltaMom() const
Returns the actual energy lost.
std::vector< double > radiusPreshowerCorrections_
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
const HCALProperties * hcalProperties(int onHcal) const
HCAL properties.
Definition: Calorimeter.cc:87
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double getMIPfraction(double energy, double eta)
vec1 & getCorrHFhad()
Definition: HCALResponse.h:49
const RawParticle & ecalEntrance() const
The particle at ECAL entrance.
Definition: FSimTrack.h:138
int onVFcal() const
Definition: FSimTrack.h:116
void setSpotEnergy(double e) override
Set the spot energy.
Definition: HcalHitMaker.h:28
std::vector< double > theTailIntervals_
std::vector< double > samplingHBHE_
void loadMuonSimTracks(edm::SimTrackContainer &m) const
unsigned int nTracks() const
Number of tracks.
Definition: FSimEvent.cc:36
JetCorrectorParameters corr
Definition: classes.h:5
HCALResponse * myHDResponse_
vec1 & getCorrHFem()
Definition: HCALResponse.h:48
CaloGeometryHelper * myCalorimeter_
std::vector< double > timeShiftHB_
int ietaAbs() const
get the absolute value of the cell ieta
Definition: HcalDetId.h:154
void initialize(RandomEngineAndDistribution const *random)
const double intLength[kNumberCalorimeter]
std::vector< double > theCoreIntervals_
void getGflashTrajectoryPoint(GflashTrajectoryPoint &point, double s) const
edm::EventID id() const
Method to return the EventId.
Definition: FSimEvent.cc:27
const XYZTLorentzVector & vertex() const
the vertex fourvector
Definition: RawParticle.h:285
Definition: DetId.h:18
void loadFromHcal(edm::PCaloHitContainer &c) const
GammaFunctionGenerator * aGammaGenerator
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
CLHEP::Hep3Vector Gflash3Vector
Definition: Gflash3Vector.h:6
std::vector< double > mipValues_
static std::vector< std::pair< int, float > > myZero_
std::vector< FSimTrack > savedMuonSimTracks
std::vector< std::pair< CaloHitID, float > > EEMapping_
void setTkPosition(const math::XYZVectorD &pos)
Definition: SimTrack.h:40
double getPathLengthOnEcal()
Definition: GflashShowino.h:25
void SetRandom(const RandomEngineAndDistribution *)
static EBDetId unhashIndex(int hi)
get a DetId from a compact index for arrays
Definition: EBDetId.h:114
math::XYZVector XYZPoint
int type() const
particle type (HEP PDT convension)
Definition: CoreSimTrack.h:25
HLT enums.
void harvestMuonSimTracks(edm::SimTrackContainer &m) const
std::vector< unsigned int > evtsToDebug_
int id() const
the index in FBaseSimEvent and other vectors
Definition: FSimTrack.h:91
bool preshowerPresent() const
const std::map< CaloHitID, float > & getHitsMap()
void setPulledPadSurvivalProbability(double val)
Definition: EcalHitMaker.h:132
const RawParticle & layer2Entrance() const
The particle at Preshower Layer 2.
Definition: FSimTrack.h:135
int onLayer1() const
Definition: FSimTrack.h:96
std::vector< double > k_e
std::vector< GflashHit > & getGflashHitList()
int onHcal() const
Definition: FSimTrack.h:111
const std::map< CaloHitID, float > & getHits() override
Definition: HcalHitMaker.h:37
void setTkMomentum(const math::XYZTLorentzVectorD &mom)
Definition: SimTrack.h:42
double eta() const
Definition: RawParticle.h:267
const RawParticle & hcalEntrance() const
The particle at HCAL entrance.
Definition: FSimTrack.h:141
std::vector< std::pair< CaloHitID, float > > HMapping_
std::vector< double > samplingHO_
void setPreshowerPresent(bool ps)
Definition: EcalHitMaker.h:137
FastHFShowerLibrary * theHFShowerLibrary
DetId getClosestCell(const XYZPoint &point, bool ecal, bool central) const
EnergyLossSimulator * energyLossSimulator() const
Return the Energy Loss engine.
std::unique_ptr< KKCorrectionFactors > ecalCorrection
HSParameters * myHSParameters_
std::vector< SimTrack > SimTrackContainer
void setVertex(const XYZTLorentzVector &vtx)
set the vertex
Definition: RawParticle.h:288
bool setDepth(double, bool inCm=false)
set the depth in X0 or Lambda0 units depending on showerType
void initialize(int showerType, double energy, double globalTime, double charge, Gflash3Vector &position, Gflash3Vector &momentum)
bool computeShower()
Definition: HDRShower.cc:47
math::XYZTLorentzVector XYZTLorentzVector
Definition: RawParticle.h:15
void print() const
print the FBaseSimEvent in an intelligible way
void setHcal(HcalHitMaker *const myHcal)
set the HCAL address
Definition: EMShower.cc:714
void setGrid(EcalHitMaker *const myGrid)
set the grid address
Definition: EMShower.h:61
void EMShowerSimulation(const FSimTrack &myTrack, RandomEngineAndDistribution const *)
std::vector< double > timeShiftHE_
FSimTrack & track(int id) const
Return track with given Id.
double getMaximumOfShower() const
get the depth of the centre of gravity of the shower(s)
Definition: EMShower.h:58
void loadFromEcalBarrel(edm::PCaloHitContainer &c) const