File indexing completed on 2024-09-07 04:36:18
0001
0002
0003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 #include "FWCore/Utilities/interface/EDMException.h"
0006
0007
0008 #include "FastSimulation/ParticlePropagator/interface/ParticlePropagator.h"
0009 #include "FastSimulation/Calorimetry/interface/CalorimetryManager.h"
0010 #include "FastSimulation/Event/interface/FSimEvent.h"
0011 #include "FastSimulation/Event/interface/FSimTrack.h"
0012 #include "FastSimulation/ShowerDevelopment/interface/EMECALShowerParametrization.h"
0013 #include "FastSimulation/ShowerDevelopment/interface/EMShower.h"
0014 #include "FastSimulation/ShowerDevelopment/interface/HDShowerParametrization.h"
0015 #include "FastSimulation/ShowerDevelopment/interface/HDShower.h"
0016 #include "FastSimulation/ShowerDevelopment/interface/HFShower.h"
0017 #include "FastSimulation/ShowerDevelopment/interface/HDRShower.h"
0018 #include "FastSimulation/ShowerDevelopment/interface/HSParameters.h"
0019 #include "FastSimulation/CaloGeometryTools/interface/CaloGeometryHelper.h"
0020
0021 #include "FastSimulation/Utilities/interface/RandomEngineAndDistribution.h"
0022 #include "FastSimulation/Utilities/interface/GammaFunctionGenerator.h"
0023 #include "FastSimulation/Utilities/interface/LandauFluctuationGenerator.h"
0024 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
0025 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
0026 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
0027 #include "DataFormats/EcalDetId/interface/EBDetId.h"
0028 #include "DataFormats/EcalDetId/interface/EEDetId.h"
0029 #include "FastSimulation/Event/interface/FSimTrackEqual.h"
0030
0031 #include "FastSimulation/MaterialEffects/interface/MaterialEffects.h"
0032 #include "FastSimulation/MaterialEffects/interface/EnergyLossSimulator.h"
0033
0034 #include "FastSimulation/MaterialEffects/interface/MuonBremsstrahlungSimulator.h"
0035
0036
0037 #include "SimGeneral/GFlash/interface/GflashHadronShowerProfile.h"
0038 #include "SimGeneral/GFlash/interface/GflashPiKShowerProfile.h"
0039 #include "SimGeneral/GFlash/interface/GflashProtonShowerProfile.h"
0040 #include "SimGeneral/GFlash/interface/GflashAntiProtonShowerProfile.h"
0041 #include "SimGeneral/GFlash/interface/GflashTrajectoryPoint.h"
0042 #include "SimGeneral/GFlash/interface/GflashHit.h"
0043 #include "SimGeneral/GFlash/interface/Gflash3Vector.h"
0044
0045
0046 #include "FastSimulation/ShowerDevelopment/interface/FastHFShowerLibrary.h"
0047
0048
0049 #include <memory>
0050
0051 #include <iostream>
0052 #include <vector>
0053
0054
0055 #include "DataFormats/DetId/interface/DetId.h"
0056 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
0057
0058 #include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h"
0059
0060
0061 #include "TROOT.h"
0062 #include "TH1.h"
0063
0064 using namespace edm;
0065
0066 typedef math::XYZVector XYZVector;
0067 typedef math::XYZVector XYZPoint;
0068
0069 std::vector<std::pair<int, float> > CalorimetryManager::myZero_ =
0070 std::vector<std::pair<int, float> >(1, std::pair<int, float>(0, 0.));
0071
0072 CalorimetryManager::CalorimetryManager() : myCalorimeter_(nullptr), initialized_(false) { ; }
0073
0074 CalorimetryManager::CalorimetryManager(FSimEvent* aSimEvent,
0075 const edm::ParameterSet& fastCalo,
0076 const edm::ParameterSet& fastMuECAL,
0077 const edm::ParameterSet& fastMuHCAL,
0078 const edm::ParameterSet& parGflash,
0079 edm::ConsumesCollector&& iC)
0080 : mySimEvent(aSimEvent),
0081 initialized_(false),
0082 theMuonEcalEffects(nullptr),
0083 theMuonHcalEffects(nullptr),
0084 bFixedLength_(false) {
0085 aLandauGenerator = new LandauFluctuationGenerator;
0086 aGammaGenerator = new GammaFunctionGenerator;
0087
0088
0089 theProfile = new GflashHadronShowerProfile(parGflash);
0090 thePiKProfile = new GflashPiKShowerProfile(parGflash);
0091 theProtonProfile = new GflashProtonShowerProfile(parGflash);
0092 theAntiProtonProfile = new GflashAntiProtonShowerProfile(parGflash);
0093
0094
0095 theHFShowerLibrary = new FastHFShowerLibrary(fastCalo, std::move(iC));
0096
0097 readParameters(fastCalo);
0098
0099 myCalorimeter_ = new CaloGeometryHelper(fastCalo);
0100 myHDResponse_ = new HCALResponse(fastCalo.getParameter<edm::ParameterSet>("HCALResponse"));
0101 myHSParameters_ = new HSParameters(fastCalo.getParameter<edm::ParameterSet>("HSParameters"));
0102
0103
0104 if (fastMuECAL.getParameter<bool>("PairProduction") || fastMuECAL.getParameter<bool>("Bremsstrahlung") ||
0105 fastMuECAL.getParameter<bool>("MuonBremsstrahlung") || fastMuECAL.getParameter<bool>("EnergyLoss") ||
0106 fastMuECAL.getParameter<bool>("MultipleScattering"))
0107 theMuonEcalEffects = new MaterialEffects(fastMuECAL);
0108
0109
0110 if (fastMuHCAL.getParameter<bool>("PairProduction") || fastMuHCAL.getParameter<bool>("Bremsstrahlung") ||
0111 fastMuHCAL.getParameter<bool>("MuonBremsstrahlung") || fastMuHCAL.getParameter<bool>("EnergyLoss") ||
0112 fastMuHCAL.getParameter<bool>("MultipleScattering"))
0113 theMuonHcalEffects = new MaterialEffects(fastMuHCAL);
0114
0115 if (fastCalo.exists("ECALResponseScaling")) {
0116 ecalCorrection =
0117 std::make_unique<KKCorrectionFactors>(fastCalo.getParameter<edm::ParameterSet>("ECALResponseScaling"));
0118 }
0119 }
0120
0121 void CalorimetryManager::clean() {
0122 EBMapping_.clear();
0123 EEMapping_.clear();
0124 HMapping_.clear();
0125 ESMapping_.clear();
0126 muonSimTracks.clear();
0127 savedMuonSimTracks.clear();
0128 }
0129
0130 CalorimetryManager::~CalorimetryManager() {
0131 if (myCalorimeter_)
0132 delete myCalorimeter_;
0133 if (myHDResponse_)
0134 delete myHDResponse_;
0135
0136 if (theMuonEcalEffects)
0137 delete theMuonEcalEffects;
0138 if (theMuonHcalEffects)
0139 delete theMuonHcalEffects;
0140
0141 if (theProfile)
0142 delete theProfile;
0143
0144 if (theHFShowerLibrary)
0145 delete theHFShowerLibrary;
0146 }
0147
0148 void CalorimetryManager::reconstruct(RandomEngineAndDistribution const* random) {
0149 if (!evtsToDebug_.empty()) {
0150 std::vector<unsigned int>::const_iterator itcheck =
0151 find(evtsToDebug_.begin(), evtsToDebug_.end(), mySimEvent->id().event());
0152 debug_ = (itcheck != evtsToDebug_.end());
0153 if (debug_)
0154 mySimEvent->print();
0155 }
0156
0157 initialize(random);
0158
0159 LogInfo("FastCalorimetry") << "Reconstructing " << (int)mySimEvent->nTracks() << " tracks." << std::endl;
0160 for (int fsimi = 0; fsimi < (int)mySimEvent->nTracks(); ++fsimi) {
0161 FSimTrack& myTrack = mySimEvent->track(fsimi);
0162
0163 reconstructTrack(myTrack, random);
0164 }
0165
0166 }
0167
0168 void CalorimetryManager::initialize(RandomEngineAndDistribution const* random) {
0169
0170 if (!initialized_) {
0171 theHFShowerLibrary->SetRandom(random);
0172
0173
0174 if (simulatePreshower_ && !myCalorimeter_->preshowerPresent()) {
0175 edm::LogWarning("CalorimetryManager")
0176 << " WARNING: The preshower simulation has been turned on; but no preshower geometry is available "
0177 << std::endl;
0178 edm::LogWarning("CalorimetryManager") << " Disabling the preshower simulation " << std::endl;
0179 simulatePreshower_ = false;
0180 }
0181
0182 initialized_ = true;
0183 }
0184 clean();
0185 }
0186
0187 void CalorimetryManager::reconstructTrack(FSimTrack& myTrack, RandomEngineAndDistribution const* random) {
0188 int pid = abs(myTrack.type());
0189
0190 if (debug_) {
0191 LogInfo("FastCalorimetry") << " ===> pid = " << pid << std::endl;
0192 }
0193
0194
0195 if (myTrack.noEndVertex()) {
0196
0197 float charge_ = (float)(myTrack.charge());
0198 if (pid == 11 || pid == 22) {
0199 if (myTrack.onEcal())
0200 EMShowerSimulation(myTrack, random);
0201 else if (myTrack.onVFcal()) {
0202 if (useShowerLibrary) {
0203 theHFShowerLibrary->recoHFShowerLibrary(myTrack);
0204 myHDResponse_->correctHF(myTrack.hcalEntrance().e(), abs(myTrack.type()));
0205 updateHCAL(theHFShowerLibrary->getHitsMap(), myTrack.id());
0206 } else
0207 reconstructHCAL(myTrack, random);
0208 }
0209 }
0210 else if (pid == 13 || pid == 1000024 || (pid > 1000100 && pid < 1999999 && fabs(charge_) > 0.001)) {
0211 MuonMipSimulation(myTrack, random);
0212 }
0213
0214
0215
0216 else if (pid < 1000000) {
0217 if (myTrack.onHcal() || myTrack.onVFcal()) {
0218 if (optionHDSim_ == 0)
0219 reconstructHCAL(myTrack, random);
0220 else
0221 HDShowerSimulation(myTrack, random);
0222 }
0223 }
0224 }
0225 }
0226
0227
0228 void CalorimetryManager::EMShowerSimulation(const FSimTrack& myTrack, RandomEngineAndDistribution const* random) {
0229 std::vector<const RawParticle*> thePart;
0230 double X0depth;
0231
0232 if (debug_) {
0233 LogInfo("FastCalorimetry") << " EMShowerSimulation " << myTrack << std::endl;
0234 }
0235
0236
0237 myPart = myTrack.ecalEntrance();
0238
0239
0240 if (myTrack.type() == 22 && myPart.e() < 0.055)
0241 return;
0242
0243
0244 int onEcal = myTrack.onEcal();
0245 int onHcal = myTrack.onHcal();
0246 int onLayer1 = myTrack.onLayer1();
0247 int onLayer2 = myTrack.onLayer2();
0248
0249
0250 XYZPoint ecalentrance = myPart.vertex().Vect();
0251
0252
0253 PreshowerHitMaker* myPreshower = nullptr;
0254 if (simulatePreshower_ && (onLayer1 || onLayer2)) {
0255 XYZPoint layer1entrance, layer2entrance;
0256 XYZVector dir1, dir2;
0257 if (onLayer1) {
0258 layer1entrance = XYZPoint(myTrack.layer1Entrance().vertex().Vect());
0259 dir1 = XYZVector(myTrack.layer1Entrance().Vect().Unit());
0260 }
0261 if (onLayer2) {
0262 layer2entrance = XYZPoint(myTrack.layer2Entrance().vertex().Vect());
0263 dir2 = XYZVector(myTrack.layer2Entrance().Vect().Unit());
0264 }
0265 myPreshower =
0266 new PreshowerHitMaker(myCalorimeter_, layer1entrance, dir1, layer2entrance, dir2, aLandauGenerator, random);
0267 myPreshower->setMipEnergy(mipValues_[0], mipValues_[1]);
0268 }
0269
0270
0271 EMECALShowerParametrization showerparam(myCalorimeter_->ecalProperties(onEcal),
0272 myCalorimeter_->hcalProperties(onHcal),
0273 myCalorimeter_->layer1Properties(onLayer1),
0274 myCalorimeter_->layer2Properties(onLayer2),
0275 theCoreIntervals_,
0276 theTailIntervals_,
0277 RCFactor_,
0278 RTFactor_);
0279
0280
0281 if (myTrack.type() == 22) {
0282
0283 X0depth = -log(random->flatShoot()) * (9. / 7.);
0284
0285
0286 double eMass = 0.000510998902;
0287 double xe = 0;
0288 double xm = eMass / myPart.e();
0289 double weight = 0.;
0290
0291
0292 do {
0293 xe = random->flatShoot() * (1. - 2. * xm) + xm;
0294 weight = 1. - 4. / 3. * xe * (1. - xe);
0295 } while (weight < random->flatShoot());
0296
0297
0298 if (myPart.e() * xe < 0.055 || myPart.e() * (1. - xe) < 0.055) {
0299 if (myPart.e() > 0.055)
0300 thePart.push_back(&myPart);
0301
0302 } else {
0303 myElec = (myPart.momentum()) * xe;
0304 myPosi = (myPart.momentum()) * (1. - xe);
0305 myElec.setVertex(myPart.vertex());
0306 myPosi.setVertex(myPart.vertex());
0307 thePart.push_back(&myElec);
0308 thePart.push_back(&myPosi);
0309 }
0310
0311 } else {
0312 X0depth = 0.;
0313 if (myPart.e() > 0.055)
0314 thePart.push_back(&myPart);
0315 }
0316
0317
0318 if (thePart.empty()) {
0319 if (myPreshower == nullptr)
0320 return;
0321 delete myPreshower;
0322 return;
0323 }
0324
0325
0326 double maxEnergy = -1.;
0327 for (unsigned ip = 0; ip < thePart.size(); ++ip)
0328 if (thePart[ip]->e() > maxEnergy)
0329 maxEnergy = thePart[ip]->e();
0330
0331
0332 int size = gridSize_;
0333 if (maxEnergy > 100)
0334 size = 11;
0335
0336 EMShower theShower(random, aGammaGenerator, &showerparam, &thePart, nullptr, nullptr, bFixedLength_);
0337
0338 double maxShower = theShower.getMaximumOfShower();
0339 if (maxShower > 20.)
0340 maxShower = 2.;
0341
0342 double depth((X0depth + maxShower) * myCalorimeter_->ecalProperties(onEcal)->radLenIncm());
0343 XYZPoint meanShower = ecalentrance + myPart.Vect().Unit() * depth;
0344
0345
0346 DetId pivot(myCalorimeter_->getClosestCell(meanShower, true, onEcal == 1));
0347
0348 if (pivot.subdetId() == 0) {
0349 edm::LogWarning("CalorimetryManager")
0350 << "Pivot for egamma e = " << myTrack.hcalEntrance().e() << " is not found at depth " << depth
0351 << " and meanShower coordinates = " << meanShower << std::endl;
0352 if (myPreshower)
0353 delete myPreshower;
0354 return;
0355 }
0356
0357 EcalHitMaker myGrid(myCalorimeter_, ecalentrance, pivot, onEcal, size, 0, random);
0358
0359
0360 myGrid.setPulledPadSurvivalProbability(pulledPadSurvivalProbability_);
0361 myGrid.setCrackPadSurvivalProbability(crackPadSurvivalProbability_);
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384 if (myTrack.onEcal() == 2)
0385 {
0386 if ((onLayer1 || onLayer2) && myPart.e() <= 250.) {
0387 double maxdepth = X0depth + theShower.getMaximumOfShower();
0388 double newRadiusFactor = radiusFactorEE_ * aTerm / (1. + bTerm * maxdepth);
0389 myGrid.setRadiusFactor(newRadiusFactor);
0390 } else
0391 {
0392 myGrid.setRadiusFactor(radiusFactorEE_);
0393 }
0394 }
0395 else
0396 {
0397 myGrid.setRadiusFactor(radiusFactorEB_);
0398 }
0399
0400
0401 myGrid.setPreshowerPresent(simulatePreshower_);
0402
0403
0404 myGrid.setTrackParameters(myPart.Vect().Unit(), X0depth, myTrack);
0405
0406 if (myPreshower)
0407 theShower.setPreshower(myPreshower);
0408
0409 HcalHitMaker myHcalHitMaker(myGrid, (unsigned)0);
0410
0411 theShower.setGrid(&myGrid);
0412 theShower.setHcal(&myHcalHitMaker);
0413 theShower.compute();
0414
0415
0416 float simE = 0;
0417 for (const auto& mapIterator : myGrid.getHits()) {
0418 simE += mapIterator.second;
0419 }
0420
0421 auto scale = ecalCorrection
0422 ? ecalCorrection->getScale(myTrack.ecalEntrance().e(), std::abs(myTrack.ecalEntrance().eta()), simE)
0423 : 1.;
0424
0425
0426 updateECAL(myGrid.getHits(), onEcal, myTrack.id(), scale);
0427
0428
0429 updateHCAL(myHcalHitMaker.getHits(), myTrack.id());
0430
0431
0432 if (myPreshower != nullptr) {
0433 updatePreshower(myPreshower->getHits(), myTrack.id());
0434 delete myPreshower;
0435 }
0436 }
0437
0438 void CalorimetryManager::reconstructHCAL(const FSimTrack& myTrack, RandomEngineAndDistribution const* random) {
0439 int hit;
0440 int pid = abs(myTrack.type());
0441 if (debug_) {
0442 LogInfo("FastCalorimetry") << " reconstructHCAL " << myTrack << std::endl;
0443 }
0444
0445 XYZTLorentzVector trackPosition;
0446 if (myTrack.onHcal()) {
0447 trackPosition = myTrack.hcalEntrance().vertex();
0448 hit = myTrack.onHcal() - 1;
0449 } else {
0450 trackPosition = myTrack.vfcalEntrance().vertex();
0451 hit = 2;
0452 }
0453
0454 double pathEta = trackPosition.eta();
0455 double pathPhi = trackPosition.phi();
0456
0457 double EGen = myTrack.hcalEntrance().e();
0458 double emeas = 0.;
0459
0460 float charge_ = (float)myTrack.charge();
0461 if (pid == 13 || pid == 1000024 || (pid > 1000100 && pid < 1999999 && fabs(charge_) > 0.001)) {
0462 emeas = myHDResponse_->responseHCAL(0, EGen, pathEta, 2, random);
0463 if (debug_)
0464 LogInfo("FastCalorimetry") << "CalorimetryManager::reconstructHCAL - MUON !!!" << std::endl;
0465 } else if (pid == 22 || pid == 11) {
0466 emeas = myHDResponse_->responseHCAL(0, EGen, pathEta, 0, random);
0467 if (debug_)
0468 LogInfo("FastCalorimetry") << "CalorimetryManager::reconstructHCAL - e/gamma !!!" << std::endl;
0469 } else {
0470 emeas = myHDResponse_->getHCALEnergyResponse(EGen, hit, random);
0471 }
0472
0473 if (debug_)
0474 LogInfo("FastCalorimetry") << "CalorimetryManager::reconstructHCAL - on-calo "
0475 << " eta = " << pathEta << " phi = " << pathPhi << " Egen = " << EGen
0476 << " Emeas = " << emeas << std::endl;
0477
0478 if (emeas > 0.) {
0479 DetId cell = myCalorimeter_->getClosestCell(trackPosition.Vect(), false, false);
0480 double tof =
0481 (((HcalGeometry*)(myCalorimeter_->getHcalGeometry()))->getPosition(cell).mag()) / 29.98;
0482 CaloHitID current_id(cell.rawId(), tof, myTrack.id());
0483 std::map<CaloHitID, float> hitMap;
0484 hitMap[current_id] = emeas;
0485 updateHCAL(hitMap, myTrack.id());
0486 }
0487 }
0488
0489 void CalorimetryManager::HDShowerSimulation(const FSimTrack& myTrack, RandomEngineAndDistribution const* random) {
0490
0491
0492 theHFShowerLibrary->SetRandom(random);
0493
0494
0495 const XYZTLorentzVector& moment = myTrack.momentum();
0496
0497 if (debug_)
0498 LogInfo("FastCalorimetry") << "CalorimetryManager::HDShowerSimulation - track param." << std::endl
0499 << " eta = " << moment.eta() << std::endl
0500 << " phi = " << moment.phi() << std::endl
0501 << " et = " << moment.Et() << std::endl
0502 << " e = " << myTrack.hcalEntrance().e() << std::endl;
0503
0504 if (debug_) {
0505 LogInfo("FastCalorimetry") << " HDShowerSimulation " << myTrack << std::endl;
0506 }
0507
0508 int hit;
0509
0510 XYZTLorentzVector trackPosition;
0511 if (myTrack.onEcal()) {
0512 trackPosition = myTrack.ecalEntrance().vertex();
0513 hit = myTrack.onEcal() - 1;
0514 myPart = myTrack.ecalEntrance();
0515 } else if (myTrack.onVFcal()) {
0516 trackPosition = myTrack.vfcalEntrance().vertex();
0517 hit = 2;
0518 myPart = myTrack.vfcalEntrance();
0519 } else {
0520 LogInfo("FastCalorimetry") << " The particle is not in the acceptance " << std::endl;
0521 return;
0522 }
0523
0524
0525
0526 int onHCAL = hit + 1;
0527 int onECAL = myTrack.onEcal();
0528
0529 double pathEta = trackPosition.eta();
0530 double pathPhi = trackPosition.phi();
0531
0532 double eint = moment.e();
0533 double eGen = myTrack.hcalEntrance().e();
0534
0535 double emeas = 0.;
0536 double pmip = myHDResponse_->getMIPfraction(eGen, pathEta);
0537
0538
0539 if (eGen > 0.) {
0540
0541 HDShowerParametrization theHDShowerparam(
0542 myCalorimeter_->ecalProperties(onECAL), myCalorimeter_->hcalProperties(onHCAL), myHSParameters_);
0543
0544
0545 XYZPoint caloentrance;
0546 XYZVector direction;
0547 if (myTrack.onEcal()) {
0548 caloentrance = myTrack.ecalEntrance().vertex().Vect();
0549 direction = myTrack.ecalEntrance().Vect().Unit();
0550 } else if (myTrack.onHcal()) {
0551 caloentrance = myTrack.hcalEntrance().vertex().Vect();
0552 direction = myTrack.hcalEntrance().Vect().Unit();
0553 } else {
0554 caloentrance = myTrack.vfcalEntrance().vertex().Vect();
0555 direction = myTrack.vfcalEntrance().Vect().Unit();
0556 }
0557
0558 if (debug_)
0559 LogInfo("FastCalorimetry") << "CalorimetryManager::HDShowerSimulation - on-calo 1 " << std::endl
0560 << " onEcal = " << myTrack.onEcal() << std::endl
0561 << " onHcal = " << myTrack.onHcal() << std::endl
0562 << " onVFcal = " << myTrack.onVFcal() << std::endl
0563 << " position = " << caloentrance << std::endl;
0564
0565 DetId pivot;
0566 if (myTrack.onEcal()) {
0567 pivot = myCalorimeter_->getClosestCell(caloentrance, true, myTrack.onEcal() == 1);
0568 } else if (myTrack.onHcal()) {
0569 pivot = myCalorimeter_->getClosestCell(caloentrance, false, false);
0570 }
0571
0572 EcalHitMaker myGrid(
0573 myCalorimeter_, caloentrance, pivot, pivot.null() ? 0 : myTrack.onEcal(), hdGridSize_, 1, random);
0574
0575
0576 myGrid.setTrackParameters(direction, 0, myTrack);
0577
0578 HcalHitMaker myHcalHitMaker(myGrid, (unsigned)1);
0579
0580
0581 bool status = false;
0582 int mip = 2;
0583
0584 if (!myTrack.onEcal() && !myTrack.onHcal()) {
0585
0586
0587
0588
0589 if (useShowerLibrary) {
0590 theHFShowerLibrary->recoHFShowerLibrary(myTrack);
0591 status = true;
0592 } else {
0593 HFShower theShower(random, &theHDShowerparam, &myGrid, &myHcalHitMaker, onECAL, eGen);
0594
0595
0596
0597 status = theShower.compute();
0598 }
0599 } else {
0600 if (hdSimMethod_ == 0) {
0601 HDShower theShower(random, &theHDShowerparam, &myGrid, &myHcalHitMaker, onECAL, eGen, pmip);
0602 status = theShower.compute();
0603 mip = theShower.getmip();
0604 } else if (hdSimMethod_ == 1) {
0605 HDRShower theShower(random, &theHDShowerparam, &myGrid, &myHcalHitMaker, onECAL, eGen);
0606 status = theShower.computeShower();
0607 mip = 2;
0608 } else if (hdSimMethod_ == 2) {
0609
0610 int particleType = myTrack.type();
0611 theProfile = thePiKProfile;
0612 if (particleType == -2212)
0613 theProfile = theAntiProtonProfile;
0614 else if (particleType == 2212)
0615 theProfile = theProtonProfile;
0616
0617
0618 int showerType = 99 + myTrack.onEcal();
0619 double globalTime = 150.0;
0620 float charge = (float)(myTrack.charge());
0621 Gflash3Vector gfpos(trackPosition.X(), trackPosition.Y(), trackPosition.Z());
0622 Gflash3Vector gfmom(moment.X(), moment.Y(), moment.Z());
0623
0624 theProfile->initialize(showerType, eGen, globalTime, charge, gfpos, gfmom);
0625 theProfile->loadParameters();
0626 theProfile->hadronicParameterization();
0627
0628
0629 std::vector<GflashHit>& gflashHitList = theProfile->getGflashHitList();
0630 std::vector<GflashHit>::const_iterator spotIter = gflashHitList.begin();
0631 std::vector<GflashHit>::const_iterator spotIterEnd = gflashHitList.end();
0632
0633 Gflash::CalorimeterNumber whichCalor = Gflash::kNULL;
0634
0635 for (; spotIter != spotIterEnd; spotIter++) {
0636 double pathLength = theProfile->getGflashShowino()->getPathLengthAtShower() +
0637 (30 * 100 / eGen) * (spotIter->getTime() - globalTime);
0638
0639 double currentDepth = std::max(0.0, pathLength - theProfile->getGflashShowino()->getPathLengthOnEcal());
0640
0641
0642 GflashTrajectoryPoint trajectoryPoint;
0643 theProfile->getGflashShowino()->getHelix()->getGflashTrajectoryPoint(trajectoryPoint, pathLength);
0644 Gflash3Vector positionAtCurrentDepth = trajectoryPoint.getPosition();
0645
0646 Gflash3Vector lateralDisplacement = positionAtCurrentDepth - spotIter->getPosition() / CLHEP::cm;
0647 double rShower = lateralDisplacement.r();
0648 double azimuthalAngle = lateralDisplacement.phi();
0649
0650 whichCalor = Gflash::getCalorimeterNumber(positionAtCurrentDepth);
0651
0652 if (whichCalor == Gflash::kESPM || whichCalor == Gflash::kENCA) {
0653 bool statusPad = myGrid.getPads(currentDepth, true);
0654 if (!statusPad)
0655 continue;
0656 myGrid.setSpotEnergy(1.2 * spotIter->getEnergy() / CLHEP::GeV);
0657 myGrid.addHit(rShower / Gflash::intLength[Gflash::kESPM], azimuthalAngle, 0);
0658 } else if (whichCalor == Gflash::kHB || whichCalor == Gflash::kHE) {
0659 bool setHDdepth = myHcalHitMaker.setDepth(currentDepth, true);
0660 if (!setHDdepth)
0661 continue;
0662 myHcalHitMaker.setSpotEnergy(1.4 * spotIter->getEnergy() / CLHEP::GeV);
0663 myHcalHitMaker.addHit(rShower / Gflash::intLength[Gflash::kHB], azimuthalAngle, 0);
0664 }
0665 }
0666 status = true;
0667 } else {
0668 edm::LogInfo("FastSimulationCalorimetry") << " SimMethod " << hdSimMethod_ << " is NOT available ";
0669 }
0670 }
0671
0672 if (status) {
0673
0674 if (optionHDSim_ == 1) {
0675 emeas = myHDResponse_->getHCALEnergyResponse(eGen, hit, random);
0676 } else {
0677 emeas = myHDResponse_->responseHCAL(mip, eGen, pathEta, 1, random);
0678 }
0679
0680 double correction = emeas / eGen;
0681
0682
0683 respCorr(eint);
0684
0685 if (debug_)
0686 LogInfo("FastCalorimetry") << "CalorimetryManager::HDShowerSimulation - on-calo 2" << std::endl
0687 << " eta = " << pathEta << std::endl
0688 << " phi = " << pathPhi << std::endl
0689 << " Egen = " << eGen << std::endl
0690 << " Emeas = " << emeas << std::endl
0691 << " corr = " << correction << std::endl
0692 << " mip = " << mip << std::endl;
0693
0694 if (myTrack.onEcal() > 0) {
0695
0696 updateECAL(myGrid.getHits(), onECAL, myTrack.id(), correction * ecorr);
0697 }
0698
0699
0700 if (myTrack.onVFcal() && useShowerLibrary) {
0701 myHDResponse_->correctHF(eGen, abs(myTrack.type()));
0702 updateHCAL(theHFShowerLibrary->getHitsMap(), myTrack.id());
0703 } else
0704 updateHCAL(myHcalHitMaker.getHits(), myTrack.id(), correction * hcorr);
0705
0706 } else {
0707 if (myTrack.onHcal() || myTrack.onVFcal()) {
0708 DetId cell = myCalorimeter_->getClosestCell(trackPosition.Vect(), false, false);
0709 double tof =
0710 (((HcalGeometry*)(myCalorimeter_->getHcalGeometry()))->getPosition(cell).mag()) / 29.98;
0711 CaloHitID current_id(cell.rawId(), tof, myTrack.id());
0712 std::map<CaloHitID, float> hitMap;
0713 hitMap[current_id] = emeas;
0714 updateHCAL(hitMap, myTrack.id());
0715 if (debug_)
0716 LogInfo("FastCalorimetry") << " HCAL simple cell " << cell.rawId() << " added E = " << emeas << std::endl;
0717 }
0718 }
0719
0720 }
0721
0722 if (debug_)
0723 LogInfo("FastCalorimetry") << std::endl << " FASTEnergyReconstructor::HDShowerSimulation finished " << std::endl;
0724 }
0725
0726 void CalorimetryManager::MuonMipSimulation(const FSimTrack& myTrack, RandomEngineAndDistribution const* random) {
0727
0728 XYZTLorentzVector moment = myTrack.momentum();
0729
0730
0731 if (!theMuonHcalEffects) {
0732 savedMuonSimTracks.push_back(myTrack);
0733
0734 if (myTrack.onHcal() || myTrack.onVFcal())
0735 reconstructHCAL(myTrack, random);
0736
0737 return;
0738 }
0739
0740 if (debug_)
0741 LogInfo("FastCalorimetry") << "CalorimetryManager::MuonMipSimulation - track param." << std::endl
0742 << " eta = " << moment.eta() << std::endl
0743 << " phi = " << moment.phi() << std::endl
0744 << " et = " << moment.Et() << std::endl;
0745
0746 XYZTLorentzVector trackPosition;
0747 if (myTrack.onEcal()) {
0748 trackPosition = myTrack.ecalEntrance().vertex();
0749 myPart = myTrack.ecalEntrance();
0750 } else if (myTrack.onVFcal()) {
0751 trackPosition = myTrack.vfcalEntrance().vertex();
0752 myPart = myTrack.vfcalEntrance();
0753 } else {
0754 LogInfo("FastCalorimetry") << " The particle is not in the acceptance " << std::endl;
0755 return;
0756 }
0757
0758
0759
0760
0761
0762 int onECAL = myTrack.onEcal();
0763
0764
0765
0766
0767
0768
0769 XYZPoint caloentrance;
0770 XYZVector direction;
0771 if (myTrack.onEcal()) {
0772 caloentrance = myTrack.ecalEntrance().vertex().Vect();
0773 direction = myTrack.ecalEntrance().Vect().Unit();
0774 } else if (myTrack.onHcal()) {
0775 caloentrance = myTrack.hcalEntrance().vertex().Vect();
0776 direction = myTrack.hcalEntrance().Vect().Unit();
0777 } else {
0778 caloentrance = myTrack.vfcalEntrance().vertex().Vect();
0779 direction = myTrack.vfcalEntrance().Vect().Unit();
0780 }
0781
0782 DetId pivot;
0783 if (myTrack.onEcal()) {
0784 pivot = myCalorimeter_->getClosestCell(caloentrance, true, myTrack.onEcal() == 1);
0785 } else if (myTrack.onHcal()) {
0786 pivot = myCalorimeter_->getClosestCell(caloentrance, false, false);
0787 }
0788
0789 EcalHitMaker myGrid(myCalorimeter_, caloentrance, pivot, pivot.null() ? 0 : myTrack.onEcal(), hdGridSize_, 0, random);
0790
0791
0792 myGrid.setTrackParameters(direction, 0, myTrack);
0793
0794
0795
0796
0797 const std::vector<CaloSegment>& segments = myGrid.getSegments();
0798 unsigned nsegments = segments.size();
0799
0800 int ifirstHcal = -1;
0801 int ilastEcal = -1;
0802
0803 EnergyLossSimulator* energyLossECAL = (theMuonEcalEffects) ? theMuonEcalEffects->energyLossSimulator() : nullptr;
0804
0805
0806
0807
0808 for (unsigned iseg = 0; iseg < nsegments && ifirstHcal < 0; ++iseg) {
0809
0810 float segmentSizeinX0 = segments[iseg].X0length();
0811
0812
0813 float energy = 0.0;
0814 if (segmentSizeinX0 > 0.001 && segments[iseg].material() == CaloSegment::PbWO4) {
0815
0816 float charge = (float)(myTrack.charge());
0817 RawParticle p = rawparticle::makeMuon(charge < 0, moment, trackPosition);
0818 ParticlePropagator theMuon(p, nullptr, nullptr, mySimEvent->theTable());
0819 if (energyLossECAL) {
0820 energyLossECAL->updateState(theMuon, segmentSizeinX0, random);
0821 energy = energyLossECAL->deltaMom().E();
0822 moment -= energyLossECAL->deltaMom();
0823 }
0824 }
0825
0826
0827 if (segments[iseg].material() == CaloSegment::PbWO4) {
0828 myGrid.getPads(segments[iseg].sX0Entrance() + segmentSizeinX0 * 0.5);
0829 myGrid.setSpotEnergy(energy);
0830 myGrid.addHit(0., 0.);
0831 ilastEcal = iseg;
0832 }
0833
0834 if (segments[iseg].material() == CaloSegment::HCAL) {
0835 ifirstHcal = iseg;
0836 }
0837 }
0838
0839
0840 HcalHitMaker myHcalHitMaker(myGrid, (unsigned)2);
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850
0851 int ilastHcal = -1;
0852 float mipenergy = 0.0;
0853
0854 EnergyLossSimulator* energyLossHCAL = (theMuonHcalEffects) ? theMuonHcalEffects->energyLossSimulator() : nullptr;
0855
0856
0857
0858
0859 if (ifirstHcal > 0 && energyLossHCAL) {
0860 for (unsigned iseg = ifirstHcal; iseg < nsegments; ++iseg) {
0861 float segmentSizeinX0 = segments[iseg].X0length();
0862 if (segments[iseg].material() == CaloSegment::HCAL) {
0863 ilastHcal = iseg;
0864 if (segmentSizeinX0 > 0.001) {
0865
0866 float charge = (float)(myTrack.charge());
0867 RawParticle p = rawparticle::makeMuon(charge < 0, moment, trackPosition);
0868 ParticlePropagator theMuon(p, nullptr, nullptr, mySimEvent->theTable());
0869 energyLossHCAL->updateState(theMuon, segmentSizeinX0, random);
0870 mipenergy = energyLossHCAL->deltaMom().E();
0871 moment -= energyLossHCAL->deltaMom();
0872 myHcalHitMaker.setSpotEnergy(mipenergy);
0873 myHcalHitMaker.addHit(segments[iseg].entrance());
0874 }
0875 }
0876 }
0877 }
0878
0879
0880 FSimTrack muonTrack(myTrack);
0881 if (energyLossHCAL && ilastHcal >= 0) {
0882 math::XYZVector hcalExit = segments[ilastHcal].exit();
0883 muonTrack.setTkPosition(hcalExit);
0884 muonTrack.setTkMomentum(moment);
0885 } else if (energyLossECAL && ilastEcal >= 0) {
0886 math::XYZVector ecalExit = segments[ilastEcal].exit();
0887 muonTrack.setTkPosition(ecalExit);
0888 muonTrack.setTkMomentum(moment);
0889 }
0890
0891 muonSimTracks.push_back(muonTrack);
0892
0893
0894 std::map<CaloHitID, float>::const_iterator mapitr;
0895 std::map<CaloHitID, float>::const_iterator endmapitr;
0896 if (myTrack.onEcal() > 0) {
0897
0898 updateECAL(myGrid.getHits(), onECAL, myTrack.id());
0899 }
0900
0901
0902 updateHCAL(myHcalHitMaker.getHits(), myTrack.id());
0903
0904 if (debug_)
0905 LogInfo("FastCalorimetry") << std::endl << " FASTEnergyReconstructor::MipShowerSimulation finished " << std::endl;
0906 }
0907
0908 void CalorimetryManager::readParameters(const edm::ParameterSet& fastCalo) {
0909 edm::ParameterSet ECALparameters = fastCalo.getParameter<edm::ParameterSet>("ECAL");
0910
0911 evtsToDebug_ = fastCalo.getUntrackedParameter<std::vector<unsigned int> >("EvtsToDebug", std::vector<unsigned>());
0912 debug_ = fastCalo.getUntrackedParameter<bool>("Debug");
0913
0914 bFixedLength_ = ECALparameters.getParameter<bool>("bFixedLength");
0915
0916 gridSize_ = ECALparameters.getParameter<int>("GridSize");
0917 spotFraction_ = ECALparameters.getParameter<double>("SpotFraction");
0918 pulledPadSurvivalProbability_ = ECALparameters.getParameter<double>("FrontLeakageProbability");
0919 crackPadSurvivalProbability_ = ECALparameters.getParameter<double>("GapLossProbability");
0920 theCoreIntervals_ = ECALparameters.getParameter<std::vector<double> >("CoreIntervals");
0921 theTailIntervals_ = ECALparameters.getParameter<std::vector<double> >("TailIntervals");
0922
0923 RCFactor_ = ECALparameters.getParameter<double>("RCFactor");
0924 RTFactor_ = ECALparameters.getParameter<double>("RTFactor");
0925
0926
0927 radiusFactorEE_ = ECALparameters.getParameter<double>("RadiusFactorEE");
0928 radiusFactorEB_ = ECALparameters.getParameter<double>("RadiusFactorEB");
0929
0930 radiusPreshowerCorrections_ = ECALparameters.getParameter<std::vector<double> >("RadiusPreshowerCorrections");
0931 aTerm = 1. + radiusPreshowerCorrections_[1] * radiusPreshowerCorrections_[0];
0932 bTerm = radiusPreshowerCorrections_[0];
0933 mipValues_ = ECALparameters.getParameter<std::vector<double> >("MipsinGeV");
0934 simulatePreshower_ = ECALparameters.getParameter<bool>("SimulatePreshower");
0935
0936 if (gridSize_ < 1)
0937 gridSize_ = 7;
0938 if (pulledPadSurvivalProbability_ < 0. || pulledPadSurvivalProbability_ > 1)
0939 pulledPadSurvivalProbability_ = 1.;
0940 if (crackPadSurvivalProbability_ < 0. || crackPadSurvivalProbability_ > 1)
0941 crackPadSurvivalProbability_ = 0.9;
0942
0943 LogInfo("FastCalorimetry") << " Fast ECAL simulation parameters " << std::endl;
0944 LogInfo("FastCalorimetry") << " =============================== " << std::endl;
0945 if (simulatePreshower_)
0946 LogInfo("FastCalorimetry") << " The preshower is present " << std::endl;
0947 else
0948 LogInfo("FastCalorimetry") << " The preshower is NOT present " << std::endl;
0949 LogInfo("FastCalorimetry") << " Grid Size : " << gridSize_ << std::endl;
0950 if (spotFraction_ > 0.)
0951 LogInfo("FastCalorimetry") << " Spot Fraction : " << spotFraction_ << std::endl;
0952 else {
0953 LogInfo("FastCalorimetry") << " Core of the shower " << std::endl;
0954 for (unsigned ir = 0; ir < theCoreIntervals_.size() / 2; ++ir) {
0955 LogInfo("FastCalorimetry") << " r < " << theCoreIntervals_[ir * 2] << " R_M : " << theCoreIntervals_[ir * 2 + 1]
0956 << " ";
0957 }
0958 LogInfo("FastCalorimetry") << std::endl;
0959
0960 LogInfo("FastCalorimetry") << " Tail of the shower " << std::endl;
0961 for (unsigned ir = 0; ir < theTailIntervals_.size() / 2; ++ir) {
0962 LogInfo("FastCalorimetry") << " r < " << theTailIntervals_[ir * 2] << " R_M : " << theTailIntervals_[ir * 2 + 1]
0963 << " ";
0964 }
0965
0966 LogInfo("FastCalorimetry") << "Radius correction factors: EB & EE " << radiusFactorEB_ << " : " << radiusFactorEE_
0967 << std::endl;
0968
0969 LogInfo("FastCalorimetry") << std::endl;
0970 if (mipValues_.size() > 2) {
0971 LogInfo("FastCalorimetry") << "Improper number of parameters for the preshower ; using 95keV" << std::endl;
0972 mipValues_.clear();
0973 mipValues_.resize(2, 0.000095);
0974 }
0975 }
0976
0977 LogInfo("FastCalorimetry") << " FrontLeakageProbability : " << pulledPadSurvivalProbability_ << std::endl;
0978 LogInfo("FastCalorimetry") << " GapLossProbability : " << crackPadSurvivalProbability_ << std::endl;
0979
0980
0981 edm::ParameterSet CalorimeterParam = fastCalo.getParameter<edm::ParameterSet>("CalorimeterProperties");
0982
0983 rsp = CalorimeterParam.getParameter<std::vector<double> >("RespCorrP");
0984 LogInfo("FastCalorimetry") << " RespCorrP (rsp) size " << rsp.size() << std::endl;
0985
0986 if (rsp.size() % 3 != 0) {
0987 LogInfo("FastCalorimetry") << " RespCorrP size is wrong -> no corrections applied !!!" << std::endl;
0988
0989 p_knots.push_back(14000.);
0990 k_e.push_back(1.);
0991 k_h.push_back(1.);
0992 } else {
0993 for (unsigned i = 0; i < rsp.size(); i += 3) {
0994 LogInfo("FastCalorimetry") << "i = " << i / 3 << " p = " << rsp[i] << " k_e(p) = " << rsp[i + 1]
0995 << " k_e(p) = " << rsp[i + 2] << std::endl;
0996
0997 p_knots.push_back(rsp[i]);
0998 k_e.push_back(rsp[i + 1]);
0999 k_h.push_back(rsp[i + 2]);
1000 }
1001 }
1002
1003
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
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
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
1030 void CalorimetryManager::respCorr(double p) {
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
1078 float energy = mapitr->second;
1079 energy *= corr;
1080
1081
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
1091 float energy = mapitr->second;
1092 energy *= corr;
1093
1094
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
1110 float energy = mapitr->second;
1111 energy *= corr;
1112
1113 float time = mapitr->first.timeSlice();
1114
1115 if (HcalDigitizer_) {
1116 HcalDetId hdetid = HcalDetId(mapitr->first.unitID());
1117 if (hdetid.subdetId() == HcalBarrel) {
1118 energy /= samplingHBHE_[hdetid.ietaAbs() - 1];
1119 time = timeShiftHB_[hdetid.ietaAbs() - ietaShiftHB_];
1120 } else if (hdetid.subdetId() == HcalEndcap) {
1121 energy /= samplingHBHE_[hdetid.ietaAbs() - 1];
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
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
1156 float energy = mapitr->second;
1157 energy *= corr;
1158
1159
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
1166 void CalorimetryManager::loadFromEcalBarrel(edm::PCaloHitContainer& c) const {
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
1176 void CalorimetryManager::loadFromEcalEndcap(edm::PCaloHitContainer& c) const {
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
1186 void CalorimetryManager::loadFromHcal(edm::PCaloHitContainer& c) const {
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
1196 void CalorimetryManager::loadFromPreshower(edm::PCaloHitContainer& c) const {
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
1207
1208 void CalorimetryManager::loadMuonSimTracks(edm::SimTrackContainer& muons) const {
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
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
1226 void CalorimetryManager::harvestMuonSimTracks(edm::SimTrackContainer& c) const {
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 }