CMS 3D CMS Logo

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