File indexing completed on 2024-09-11 04:33:19
0001
0002
0003 #include "FWCore/Framework/interface/MakerMacros.h"
0004 #include "Validation/EcalClusters/interface/ContainmentCorrectionAnalyzer.h"
0005
0006 using namespace cms;
0007 using namespace edm;
0008 using namespace std;
0009 using namespace reco;
0010
0011 ContainmentCorrectionAnalyzer::ContainmentCorrectionAnalyzer(const ParameterSet &ps) : pTopologyToken(esConsumes()) {
0012 BarrelSuperClusterCollection_ =
0013 consumes<reco::SuperClusterCollection>(ps.getParameter<InputTag>("BarrelSuperClusterCollection"));
0014 EndcapSuperClusterCollection_ =
0015 consumes<reco::SuperClusterCollection>(ps.getParameter<InputTag>("EndcapSuperClusterCollection"));
0016 reducedBarrelRecHitCollection_ =
0017 consumes<EcalRecHitCollection>(ps.getParameter<InputTag>("reducedBarrelRecHitCollection"));
0018 reducedEndcapRecHitCollection_ =
0019 consumes<EcalRecHitCollection>(ps.getParameter<InputTag>("reducedEndcapRecHitCollection"));
0020 SimTrackCollection_ = consumes<SimTrackContainer>(ps.getParameter<InputTag>("simTrackCollection"));
0021 SimVertexCollection_ = consumes<SimVertexContainer>(ps.getParameter<InputTag>("simVertexCollection"));
0022 }
0023
0024 ContainmentCorrectionAnalyzer::~ContainmentCorrectionAnalyzer() {}
0025
0026 void ContainmentCorrectionAnalyzer::beginJob() {
0027 Service<TFileService> fs;
0028
0029
0030 h_EB_eRecoEtrueReference = fs->make<TH1F>("EB_eRecoEtrueReference", "EB_eRecoEtrueReference", 440, 0., 1.1);
0031 h_EB_e9EtrueReference = fs->make<TH1F>("EB_e9EtrueReference", "EB_e9EtrueReference", 440, 0., 1.1);
0032 h_EB_e25EtrueReference = fs->make<TH1F>("EB_e25EtrueReference", "EB_e25EtrueReference", 440, 0., 1.1);
0033 h_EE_eRecoEtrueReference = fs->make<TH1F>("EE_eRecoEtrueReference", "EE_eRecoEtrueReference", 440, 0., 1.1);
0034 h_EE_e9EtrueReference = fs->make<TH1F>("EE_e9EtrueReference", "EE_e9EtrueReference", 440, 0., 1.1);
0035 h_EE_e25EtrueReference = fs->make<TH1F>("EE_e25EtrueReference", "EE_e25EtrueReference", 440, 0., 1.1);
0036 h_EB_eTrue = fs->make<TH1F>("EB_eTrue", "EB_eTrue", 41, 40., 60.);
0037 h_EE_eTrue = fs->make<TH1F>("EE_eTrue", "EE_eTrue", 41, 40., 60.);
0038 h_EB_converted = fs->make<TH1F>("EB_converted", "EB_converted", 2, 0., 2.);
0039 h_EE_converted = fs->make<TH1F>("EE_converted", "EE_converted", 2, 0., 2.);
0040 }
0041
0042 void ContainmentCorrectionAnalyzer::analyze(const Event &evt, const EventSetup &es) {
0043 LogInfo("ContainmentCorrectionAnalyzer") << "Analyzing event " << evt.id() << "\n";
0044
0045
0046 std::vector<SimTrack> theSimTracks;
0047 Handle<SimTrackContainer> SimTk;
0048 evt.getByToken(SimTrackCollection_, SimTk);
0049 Labels l;
0050 labelsForToken(SimTrackCollection_, l);
0051
0052 if (SimTk.isValid())
0053 theSimTracks.insert(theSimTracks.end(), SimTk->begin(), SimTk->end());
0054 else {
0055 LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << l.module;
0056 }
0057
0058 std::vector<SimVertex> theSimVertexes;
0059 Handle<SimVertexContainer> SimVtx;
0060 evt.getByToken(SimVertexCollection_, SimVtx);
0061 labelsForToken(SimVertexCollection_, l);
0062
0063 if (SimVtx.isValid())
0064 theSimVertexes.insert(theSimVertexes.end(), SimVtx->begin(), SimVtx->end());
0065 else {
0066 LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << l.module;
0067 }
0068
0069 const reco::SuperClusterCollection *BarrelSuperClusters = nullptr;
0070 Handle<reco::SuperClusterCollection> pHybridBarrelSuperClusters;
0071 evt.getByToken(BarrelSuperClusterCollection_, pHybridBarrelSuperClusters);
0072 labelsForToken(BarrelSuperClusterCollection_, l);
0073
0074 if (pHybridBarrelSuperClusters.isValid()) {
0075 BarrelSuperClusters = pHybridBarrelSuperClusters.product();
0076 } else {
0077 LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << l.module;
0078 }
0079
0080 const reco::SuperClusterCollection *EndcapSuperClusters = nullptr;
0081 Handle<reco::SuperClusterCollection> pMulti5x5EndcapSuperClusters;
0082 evt.getByToken(EndcapSuperClusterCollection_, pMulti5x5EndcapSuperClusters);
0083 labelsForToken(EndcapSuperClusterCollection_, l);
0084
0085 if (pMulti5x5EndcapSuperClusters.isValid())
0086 EndcapSuperClusters = pMulti5x5EndcapSuperClusters.product();
0087 else {
0088 LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << l.module;
0089 }
0090
0091 const EcalRecHitCollection *ebRecHits = nullptr;
0092 Handle<EcalRecHitCollection> pEBRecHits;
0093 evt.getByToken(reducedBarrelRecHitCollection_, pEBRecHits);
0094 labelsForToken(reducedBarrelRecHitCollection_, l);
0095
0096 if (pEBRecHits.isValid())
0097 ebRecHits = pEBRecHits.product();
0098 else {
0099 LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << l.module;
0100 }
0101
0102 const EcalRecHitCollection *eeRecHits = nullptr;
0103 Handle<EcalRecHitCollection> pEERecHits;
0104 evt.getByToken(reducedEndcapRecHitCollection_, pEERecHits);
0105 labelsForToken(reducedEndcapRecHitCollection_, l);
0106
0107 if (pEERecHits.isValid())
0108 eeRecHits = pEERecHits.product();
0109 else {
0110 LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << l.module;
0111 }
0112
0113 const CaloTopology *topology = nullptr;
0114 auto pTopology = es.getHandle(pTopologyToken);
0115 if (pTopology.isValid())
0116 topology = &es.getData(pTopologyToken);
0117
0118 std::vector<EcalSimPhotonMCTruth> photons = findMcTruth(theSimTracks, theSimVertexes);
0119
0120 nMCphotons = 0;
0121 nRECOphotons = 0;
0122
0123 int mc_size = photons.size();
0124 mcEnergy.resize(mc_size);
0125 mcEta.resize(mc_size);
0126 mcPhi.resize(mc_size);
0127 mcPt.resize(mc_size);
0128 isConverted.resize(mc_size);
0129 x_vtx.resize(mc_size);
0130 y_vtx.resize(mc_size);
0131 z_vtx.resize(mc_size);
0132
0133 superClusterEnergy.resize(mc_size);
0134 superClusterEta.resize(mc_size);
0135 superClusterPhi.resize(mc_size);
0136 superClusterEt.resize(mc_size);
0137 e1.resize(mc_size);
0138 e9.resize(mc_size);
0139 e25.resize(mc_size);
0140 seedXtal.resize(mc_size);
0141 iMC.resize(mc_size);
0142
0143
0144 for (unsigned int ipho = 0; ipho < photons.size(); ipho++) {
0145 math::XYZTLorentzVectorD vtx = photons[ipho].primaryVertex();
0146 double phiTrue = photons[ipho].fourMomentum().phi();
0147 double vtxPerp = sqrt(vtx.x() * vtx.x() + vtx.y() * vtx.y());
0148 double etaTrue = ecalEta(photons[ipho].fourMomentum().eta(), vtx.z(), vtxPerp);
0149 double etTrue = photons[ipho].fourMomentum().e() / cosh(etaTrue);
0150 nMCphotons++;
0151 mcEnergy[nMCphotons - 1] = photons[ipho].fourMomentum().e();
0152 mcEta[nMCphotons - 1] = etaTrue;
0153 mcPhi[nMCphotons - 1] = phiTrue;
0154 mcPt[nMCphotons - 1] = etTrue;
0155 isConverted[nMCphotons - 1] = photons[ipho].isAConversion();
0156 x_vtx[nMCphotons - 1] = vtx.x();
0157 y_vtx[nMCphotons - 1] = vtx.y();
0158 z_vtx[nMCphotons - 1] = vtx.z();
0159
0160
0161 if (std::fabs(etaTrue) < 1.479) {
0162 h_EB_eTrue->Fill(photons[ipho].fourMomentum().e());
0163 h_EB_converted->Fill(photons[ipho].isAConversion());
0164 }
0165 if (std::fabs(etaTrue) >= 1.6) {
0166 h_EE_eTrue->Fill(photons[ipho].fourMomentum().e());
0167 h_EE_converted->Fill(photons[ipho].isAConversion());
0168 }
0169
0170
0171 if (std::fabs(etaTrue) < 1.479) {
0172 double etaCurrent;
0173 double phiCurrent;
0174
0175 const reco::SuperCluster *nearSC = nullptr;
0176
0177 double closestParticleDistance = 999;
0178 for (reco::SuperClusterCollection::const_iterator aClus = BarrelSuperClusters->begin();
0179 aClus != BarrelSuperClusters->end();
0180 aClus++) {
0181 etaCurrent = aClus->position().eta();
0182 phiCurrent = aClus->position().phi();
0183
0184 double deltaR = std::sqrt(std::pow(etaCurrent - etaTrue, 2) + std::pow(phiCurrent - phiTrue, 2));
0185 if (deltaR < closestParticleDistance) {
0186
0187
0188 closestParticleDistance = deltaR;
0189 nearSC = &(*aClus);
0190 }
0191 }
0192
0193 if (closestParticleDistance < 0.3) {
0194
0195 nRECOphotons++;
0196 superClusterEnergy[nRECOphotons - 1] = nearSC->rawEnergy();
0197 superClusterEta[nRECOphotons - 1] = nearSC->position().eta();
0198 superClusterPhi[nRECOphotons - 1] = nearSC->position().phi();
0199 superClusterEt[nRECOphotons - 1] = nearSC->rawEnergy() / std::cosh(nearSC->position().eta());
0200 iMC[nRECOphotons - 1] = nMCphotons - 1;
0201
0202 const reco::CaloClusterPtr &theSeed = nearSC->seed();
0203 seedXtal[nRECOphotons - 1] = EcalClusterTools::getMaximum(*theSeed, ebRecHits).first;
0204 e1[nRECOphotons - 1] = EcalClusterTools::eMax(*theSeed, ebRecHits);
0205 e9[nRECOphotons - 1] = EcalClusterTools::e3x3(*theSeed, ebRecHits, topology);
0206 e25[nRECOphotons - 1] = EcalClusterTools::e5x5(*theSeed, ebRecHits, topology);
0207 }
0208 }
0209
0210
0211 if (std::fabs(etaTrue) >= 1.6) {
0212 double etaCurrent;
0213 double phiCurrent;
0214
0215 const reco::SuperCluster *nearSC = nullptr;
0216
0217 double closestParticleDistance = 999;
0218 for (reco::SuperClusterCollection::const_iterator aClus = EndcapSuperClusters->begin();
0219 aClus != EndcapSuperClusters->end();
0220 aClus++) {
0221 etaCurrent = aClus->position().eta();
0222 phiCurrent = aClus->position().phi();
0223
0224 double deltaR = std::sqrt(std::pow(etaCurrent - etaTrue, 2) + std::pow(phiCurrent - phiTrue, 2));
0225 if (deltaR < closestParticleDistance) {
0226
0227
0228 closestParticleDistance = deltaR;
0229 nearSC = &(*aClus);
0230 }
0231 }
0232
0233 if (closestParticleDistance < 0.3) {
0234
0235 nRECOphotons++;
0236 float psEnergy = nearSC->preshowerEnergy();
0237 superClusterEnergy[nRECOphotons - 1] = nearSC->rawEnergy() + psEnergy;
0238 superClusterEta[nRECOphotons - 1] = nearSC->position().eta();
0239 superClusterPhi[nRECOphotons - 1] = nearSC->position().phi();
0240 superClusterEt[nRECOphotons - 1] = (nearSC->rawEnergy() + psEnergy) / std::cosh(nearSC->position().eta());
0241 iMC[nRECOphotons - 1] = nMCphotons - 1;
0242
0243 const reco::CaloClusterPtr &theSeed = nearSC->seed();
0244 seedXtal[nRECOphotons - 1] = EcalClusterTools::getMaximum(*theSeed, eeRecHits).first;
0245 e1[nRECOphotons - 1] = EcalClusterTools::eMax(*theSeed, eeRecHits) + psEnergy;
0246 e9[nRECOphotons - 1] = EcalClusterTools::e3x3(*theSeed, eeRecHits, topology) + psEnergy;
0247 e25[nRECOphotons - 1] = EcalClusterTools::e5x5(*theSeed, eeRecHits, topology) + psEnergy;
0248 }
0249 }
0250 }
0251
0252
0253 for (int i = 0; i < nRECOphotons; i++) {
0254
0255 if (fabs(superClusterEta[i]) < 1.479) {
0256 if (isConverted[iMC[i]] != 1) {
0257 int ietaAbs = (seedXtal[i] >> 9) & 0x7F;
0258 int iphi = seedXtal[i] & 0x1FF;
0259 if (ietaAbs > 5 && ietaAbs < 21 && ((iphi % 20) > 5) && ((iphi % 20) < 16)) {
0260 h_EB_eRecoEtrueReference->Fill(superClusterEnergy[i] / mcEnergy[iMC[i]]);
0261 h_EB_e9EtrueReference->Fill(e9[i] / mcEnergy[iMC[i]]);
0262 h_EB_e25EtrueReference->Fill(e25[i] / mcEnergy[iMC[i]]);
0263 }
0264 }
0265 }
0266
0267
0268 if (fabs(superClusterEta[i]) > 1.6) {
0269 if (isConverted[iMC[i]] != 1) {
0270 if (fabs(superClusterEta[i]) > 1.7 && fabs(superClusterEta[i] < 2.3) &&
0271 ((superClusterPhi[i] > -CLHEP::pi / 2. + 0.1 && superClusterPhi[i] < CLHEP::pi / 2. - 0.1) ||
0272 (superClusterPhi[i] > CLHEP::pi / 2. + 0.1) || (superClusterPhi[i] < -CLHEP::pi / 2. - 0.1))) {
0273 h_EE_eRecoEtrueReference->Fill(superClusterEnergy[i] / mcEnergy[iMC[i]]);
0274 h_EE_e9EtrueReference->Fill(e9[i] / mcEnergy[iMC[i]]);
0275 h_EE_e25EtrueReference->Fill(e25[i] / mcEnergy[iMC[i]]);
0276 }
0277 }
0278 }
0279
0280 }
0281 }
0282
0283 void ContainmentCorrectionAnalyzer::endJob() {}
0284
0285 float ContainmentCorrectionAnalyzer::ecalEta(float EtaParticle, float Zvertex, float plane_Radius) {
0286 const float R_ECAL = 136.5;
0287 const float Z_Endcap = 328.0;
0288 const float etaBarrelEndcap = 1.479;
0289
0290 if (EtaParticle != 0.) {
0291 float Theta = 0.0;
0292 float ZEcal = (R_ECAL - plane_Radius) * sinh(EtaParticle) + Zvertex;
0293
0294 if (ZEcal != 0.0)
0295 Theta = atan(R_ECAL / ZEcal);
0296 if (Theta < 0.0)
0297 Theta = Theta + Geom::pi();
0298
0299 float ETA = -log(tan(0.5 * Theta));
0300
0301 if (fabs(ETA) > etaBarrelEndcap) {
0302 float Zend = Z_Endcap;
0303 if (EtaParticle < 0.0)
0304 Zend = -Zend;
0305 float Zlen = Zend - Zvertex;
0306 float RR = Zlen / sinh(EtaParticle);
0307 Theta = atan((RR + plane_Radius) / Zend);
0308 if (Theta < 0.0)
0309 Theta = Theta + Geom::pi();
0310 ETA = -log(tan(0.5 * Theta));
0311 }
0312
0313 return ETA;
0314 } else {
0315 LogWarning("") << "[ContainmentCorrectionAnalyzer::ecalEta] Warning: Eta "
0316 "equals to zero, not correcting";
0317 return EtaParticle;
0318 }
0319 }
0320
0321
0322 std::vector<EcalSimPhotonMCTruth> ContainmentCorrectionAnalyzer::findMcTruth(std::vector<SimTrack> &theSimTracks,
0323 std::vector<SimVertex> &theSimVertices) {
0324 std::vector<EcalSimPhotonMCTruth> result;
0325
0326 geantToIndex_.clear();
0327
0328
0329
0330
0331
0332
0333
0334 const int ELECTRON_FLAV = 1;
0335 const int PIZERO_FLAV = 2;
0336 const int PHOTON_FLAV = 3;
0337
0338
0339 int ievflav = 0;
0340 std::vector<SimTrack *> photonTracks;
0341 std::vector<SimTrack *> pizeroTracks;
0342 std::vector<const SimTrack *> trkFromConversion;
0343 SimVertex primVtx;
0344 std::vector<int> convInd;
0345
0346 fillMcTruth(theSimTracks, theSimVertices);
0347 int iPV = -1;
0348 int partType1 = 0;
0349 int partType2 = 0;
0350 std::vector<SimTrack>::iterator iFirstSimTk = theSimTracks.begin();
0351 if (!(*iFirstSimTk).noVertex()) {
0352 iPV = (*iFirstSimTk).vertIndex();
0353 int vtxId = (*iFirstSimTk).vertIndex();
0354 primVtx = theSimVertices[vtxId];
0355 partType1 = (*iFirstSimTk).type();
0356 }
0357
0358
0359 iFirstSimTk++;
0360 if (iFirstSimTk != theSimTracks.end()) {
0361 if ((*iFirstSimTk).vertIndex() == iPV) {
0362 partType2 = (*iFirstSimTk).type();
0363 }
0364 }
0365 int npv = 0;
0366 int iPho = 0;
0367 for (std::vector<SimTrack>::iterator iSimTk = theSimTracks.begin(); iSimTk != theSimTracks.end(); ++iSimTk) {
0368 if ((*iSimTk).noVertex())
0369 continue;
0370
0371
0372 if ((*iSimTk).vertIndex() == iPV) {
0373 npv++;
0374 if ((*iSimTk).type() == 22) {
0375 convInd.push_back(0);
0376 photonTracks.push_back(&(*iSimTk));
0377
0378 }
0379 }
0380 }
0381
0382 if (npv > 4) {
0383 } else if (npv == 1) {
0384 if (abs(partType1) == 11) {
0385 ievflav = ELECTRON_FLAV;
0386 } else if (partType1 == 111) {
0387 ievflav = PIZERO_FLAV;
0388 } else if (partType1 == 22) {
0389 ievflav = PHOTON_FLAV;
0390 }
0391 } else if (npv == 2) {
0392 if (abs(partType1) == 11 && abs(partType2) == 11) {
0393 ievflav = ELECTRON_FLAV;
0394 } else if (partType1 == 111 && partType2 == 111) {
0395 ievflav = PIZERO_FLAV;
0396 } else if (partType1 == 22 && partType2 == 22) {
0397 ievflav = PHOTON_FLAV;
0398 }
0399 }
0400
0401
0402 int isAconversion = 0;
0403 if (ievflav == PHOTON_FLAV) {
0404 int nConv = 0;
0405 iPho = 0;
0406 for (std::vector<SimTrack *>::iterator iPhoTk = photonTracks.begin(); iPhoTk != photonTracks.end(); ++iPhoTk) {
0407 trkFromConversion.clear();
0408 for (std::vector<SimTrack>::iterator iSimTk = theSimTracks.begin(); iSimTk != theSimTracks.end(); ++iSimTk) {
0409 if ((*iSimTk).noVertex())
0410 continue;
0411 if ((*iSimTk).vertIndex() == iPV)
0412 continue;
0413 if (abs((*iSimTk).type()) != 11)
0414 continue;
0415 int vertexId = (*iSimTk).vertIndex();
0416 SimVertex vertex = theSimVertices[vertexId];
0417 int motherId = -1;
0418 if (vertex.parentIndex()) {
0419 unsigned motherGeantId = vertex.parentIndex();
0420 std::map<unsigned, unsigned>::iterator association = geantToIndex_.find(motherGeantId);
0421 if (association != geantToIndex_.end())
0422 motherId = association->second;
0423
0424
0425
0426 if (theSimTracks[motherId].trackId() == (*iPhoTk)->trackId()) {
0427
0428 trkFromConversion.push_back(&(*iSimTk));
0429 }
0430 }
0431 }
0432
0433 if (!trkFromConversion.empty()) {
0434 isAconversion = 1;
0435 nConv++;
0436 convInd[iPho] = nConv;
0437 int convVtxId = trkFromConversion[0]->vertIndex();
0438 SimVertex convVtx = theSimVertices[convVtxId];
0439 const math::XYZTLorentzVectorD &vtxPosition = convVtx.position();
0440
0441
0442 result.push_back(EcalSimPhotonMCTruth(isAconversion,
0443 (*iPhoTk)->momentum(),
0444 vtxPosition.pt(),
0445 vtxPosition.z(),
0446 vtxPosition,
0447 primVtx.position(),
0448 trkFromConversion));
0449 } else {
0450 isAconversion = 0;
0451 math::XYZTLorentzVectorD vtxPosition(0., 0., 0., 0.);
0452 result.push_back(EcalSimPhotonMCTruth(isAconversion,
0453 (*iPhoTk)->momentum(),
0454 vtxPosition.pt(),
0455 vtxPosition.z(),
0456 vtxPosition,
0457 primVtx.position(),
0458 trkFromConversion));
0459 }
0460 iPho++;
0461 }
0462 }
0463
0464 return result;
0465 }
0466
0467 void ContainmentCorrectionAnalyzer::fillMcTruth(std::vector<SimTrack> &simTracks, std::vector<SimVertex> &simVertices) {
0468 unsigned nVtx = simVertices.size();
0469 unsigned nTks = simTracks.size();
0470 if (nVtx == 0)
0471 return;
0472
0473
0474 for (unsigned it = 0; it < nTks; ++it) {
0475 geantToIndex_[simTracks[it].trackId()] = it;
0476 }
0477 }