00001
00002
00003 #include "Validation/EcalClusters/interface/ContainmentCorrectionAnalyzer.h"
00004
00005 #include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
00006
00007 using namespace cms;
00008 using namespace edm;
00009 using namespace std;
00010
00011 ContainmentCorrectionAnalyzer::ContainmentCorrectionAnalyzer( const ParameterSet& ps ) {
00012
00013 BarrelSuperClusterCollection_ = ps.getParameter<InputTag>("BarrelSuperClusterCollection");
00014 EndcapSuperClusterCollection_ = ps.getParameter<InputTag>("EndcapSuperClusterCollection");
00015 reducedBarrelRecHitCollection_ = ps.getParameter<InputTag>("reducedBarrelRecHitCollection");
00016 reducedEndcapRecHitCollection_ = ps.getParameter<InputTag>("reducedEndcapRecHitCollection");
00017 SimTrackCollection_ = ps.getParameter<InputTag>("simTrackCollection");
00018 SimVertexCollection_ = ps.getParameter<InputTag>("simVertexCollection");
00019 }
00020
00021 ContainmentCorrectionAnalyzer::~ContainmentCorrectionAnalyzer() { }
00022
00023 void ContainmentCorrectionAnalyzer::beginJob() {
00024
00025 Service<TFileService> fs;
00026
00027
00028 h_EB_eRecoEtrueReference = fs->make<TH1F>("EB_eRecoEtrueReference","EB_eRecoEtrueReference",440,0.,1.1);
00029 h_EB_e9EtrueReference = fs->make<TH1F>("EB_e9EtrueReference", "EB_e9EtrueReference", 440,0.,1.1);
00030 h_EB_e25EtrueReference = fs->make<TH1F>("EB_e25EtrueReference", "EB_e25EtrueReference", 440,0.,1.1);
00031 h_EE_eRecoEtrueReference = fs->make<TH1F>("EE_eRecoEtrueReference","EE_eRecoEtrueReference",440,0.,1.1);
00032 h_EE_e9EtrueReference = fs->make<TH1F>("EE_e9EtrueReference", "EE_e9EtrueReference", 440,0.,1.1);
00033 h_EE_e25EtrueReference = fs->make<TH1F>("EE_e25EtrueReference", "EE_e25EtrueReference", 440,0.,1.1);
00034 h_EB_eTrue = fs->make<TH1F>("EB_eTrue", "EB_eTrue", 41,40.,60.);
00035 h_EE_eTrue = fs->make<TH1F>("EE_eTrue", "EE_eTrue", 41,40.,60.);
00036 h_EB_converted = fs->make<TH1F>("EB_converted", "EB_converted", 2,0.,2.);
00037 h_EE_converted = fs->make<TH1F>("EE_converted", "EE_converted", 2,0.,2.);
00038 }
00039
00040 void ContainmentCorrectionAnalyzer::analyze( const Event& evt, const EventSetup& es ) {
00041
00042 LogInfo("ContainmentCorrectionAnalyzer") << "Analyzing event " << evt.id() << "\n";
00043
00044
00045 std::vector<SimTrack> theSimTracks;
00046 Handle<SimTrackContainer> SimTk;
00047 evt.getByLabel(SimTrackCollection_,SimTk);
00048 if (SimTk.isValid() ) theSimTracks.insert(theSimTracks.end(),SimTk->begin(),SimTk->end());
00049 else { LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << SimTrackCollection_.label(); }
00050
00051 std::vector<SimVertex> theSimVertexes;
00052 Handle<SimVertexContainer> SimVtx;
00053 evt.getByLabel(SimVertexCollection_,SimVtx);
00054 if (SimVtx.isValid()) theSimVertexes.insert(theSimVertexes.end(),SimVtx->begin(),SimVtx->end());
00055 else {LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << SimVertexCollection_.label(); }
00056
00057 const reco::SuperClusterCollection* BarrelSuperClusters = 0;
00058 Handle<reco::SuperClusterCollection> pHybridBarrelSuperClusters;
00059 evt.getByLabel(BarrelSuperClusterCollection_, pHybridBarrelSuperClusters);
00060 if (pHybridBarrelSuperClusters.isValid()) { BarrelSuperClusters = pHybridBarrelSuperClusters.product(); }
00061 else {LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << BarrelSuperClusterCollection_.label(); }
00062
00063 const reco::SuperClusterCollection* EndcapSuperClusters = 0;
00064 Handle<reco::SuperClusterCollection> pMulti5x5EndcapSuperClusters;
00065 evt.getByLabel(EndcapSuperClusterCollection_, pMulti5x5EndcapSuperClusters);
00066 if (pMulti5x5EndcapSuperClusters.isValid()) EndcapSuperClusters = pMulti5x5EndcapSuperClusters.product();
00067 else {LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << EndcapSuperClusterCollection_.label(); }
00068
00069 const EcalRecHitCollection *ebRecHits = 0;
00070 Handle< EcalRecHitCollection > pEBRecHits;
00071 evt.getByLabel( reducedBarrelRecHitCollection_, pEBRecHits );
00072 if (pEBRecHits.isValid()) ebRecHits = pEBRecHits.product();
00073 else {LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << reducedBarrelRecHitCollection_.label(); }
00074
00075 const EcalRecHitCollection *eeRecHits = 0;
00076 Handle< EcalRecHitCollection > pEERecHits;
00077 evt.getByLabel( reducedEndcapRecHitCollection_, pEERecHits );
00078 if (pEERecHits.isValid()) eeRecHits = pEERecHits.product();
00079 else {LogError("ContainmentCorrectionAnalyzer") << "Error! can't get collection with label " << reducedEndcapRecHitCollection_.label(); }
00080
00081 const CaloTopology *topology = 0;
00082 ESHandle<CaloTopology> pTopology;
00083 es.get<CaloTopologyRecord>().get(pTopology);
00084 if(pTopology.isValid()) topology = pTopology.product();
00085
00086 std::vector<EcalSimPhotonMCTruth> photons=findMcTruth(theSimTracks,theSimVertexes);
00087
00088 nMCphotons = 0;
00089 nRECOphotons = 0;
00090
00091 int mc_size = photons.size();
00092 mcEnergy.resize(mc_size);
00093 mcEta.resize(mc_size);
00094 mcPhi.resize(mc_size);
00095 mcPt.resize(mc_size);
00096 isConverted.resize(mc_size);
00097 x_vtx.resize(mc_size);
00098 y_vtx.resize(mc_size);
00099 z_vtx.resize(mc_size);
00100
00101 superClusterEnergy.resize(mc_size);
00102 superClusterEta.resize(mc_size);
00103 superClusterPhi.resize(mc_size);
00104 superClusterEt.resize(mc_size);
00105 e1.resize(mc_size);
00106 e9.resize(mc_size);
00107 e25.resize(mc_size);
00108 seedXtal.resize(mc_size);
00109 iMC.resize(mc_size);
00110
00111
00112
00113 for (unsigned int ipho=0;ipho<photons.size();ipho++) {
00114
00115 math::XYZTLorentzVectorD vtx = photons[ipho].primaryVertex();
00116 double phiTrue = photons[ipho].fourMomentum().phi();
00117 double vtxPerp = sqrt(vtx.x()*vtx.x() + vtx.y()*vtx.y());
00118 double etaTrue = ecalEta(photons[ipho].fourMomentum().eta(), vtx.z(), vtxPerp);
00119 double etTrue = photons[ipho].fourMomentum().e()/cosh(etaTrue);
00120 nMCphotons++;
00121 mcEnergy[nMCphotons-1]=photons[ipho].fourMomentum().e();
00122 mcEta[nMCphotons-1]=etaTrue;
00123 mcPhi[nMCphotons-1]=phiTrue;
00124 mcPt[nMCphotons-1]=etTrue;
00125 isConverted[nMCphotons-1]=photons[ipho].isAConversion();
00126 x_vtx[nMCphotons-1]=vtx.x();
00127 y_vtx[nMCphotons-1]=vtx.y();
00128 z_vtx[nMCphotons-1]=vtx.z();
00129
00130
00131 if(std::fabs(etaTrue) < 1.479) {
00132 h_EB_eTrue ->Fill(photons[ipho].fourMomentum().e());
00133 h_EB_converted ->Fill(photons[ipho].isAConversion());
00134 }
00135 if(std::fabs(etaTrue) >= 1.6) {
00136 h_EE_eTrue ->Fill(photons[ipho].fourMomentum().e());
00137 h_EE_converted ->Fill(photons[ipho].isAConversion());
00138 }
00139
00140
00141 if(std::fabs(etaTrue) < 1.479) {
00142 double etaCurrent, etaFound = 0;
00143 double phiCurrent;
00144 double etCurrent, etFound = 0;
00145 const reco::SuperCluster* nearSC = 0;
00146
00147 double closestParticleDistance = 999;
00148 for(reco::SuperClusterCollection::const_iterator aClus = BarrelSuperClusters->begin();
00149 aClus != BarrelSuperClusters->end(); aClus++) {
00150 etaCurrent = aClus->position().eta();
00151 phiCurrent = aClus->position().phi();
00152 etCurrent = aClus->energy()/std::cosh(etaCurrent);
00153 double deltaR = std::sqrt(std::pow(etaCurrent-etaTrue,2)+std::pow(phiCurrent-phiTrue,2));
00154 if(deltaR < closestParticleDistance) {
00155 etFound = etCurrent;
00156 etaFound = etaCurrent;
00157 closestParticleDistance = deltaR;
00158 nearSC=&(*aClus);
00159 }
00160 }
00161
00162 if(closestParticleDistance < 0.3) {
00163
00164 nRECOphotons++;
00165 superClusterEnergy[nRECOphotons-1]=nearSC->rawEnergy();
00166 superClusterEta[nRECOphotons-1]=nearSC->position().eta();
00167 superClusterPhi[nRECOphotons-1]=nearSC->position().phi();
00168 superClusterEt[nRECOphotons-1]=nearSC->rawEnergy()/std::cosh(nearSC->position().eta());
00169 iMC[nRECOphotons-1]=nMCphotons-1;
00170
00171 reco::CaloClusterPtr theSeed = nearSC->seed();
00172 seedXtal[nRECOphotons-1] = EcalClusterTools::getMaximum(*theSeed, ebRecHits).first;
00173 e1[nRECOphotons-1] = EcalClusterTools::eMax(*theSeed, ebRecHits);
00174 e9[nRECOphotons-1] = EcalClusterTools::e3x3(*theSeed, ebRecHits, topology );
00175 e25[nRECOphotons-1] = EcalClusterTools::e5x5(*theSeed, ebRecHits, topology );
00176 }
00177 }
00178
00179
00180 if(std::fabs(etaTrue) >= 1.6) {
00181 double etaCurrent, etaFound = 0;
00182 double phiCurrent;
00183 double etCurrent, etFound = 0;
00184 const reco::SuperCluster* nearSC = 0;
00185
00186 double closestParticleDistance = 999;
00187 for(reco::SuperClusterCollection::const_iterator aClus = EndcapSuperClusters->begin();
00188 aClus != EndcapSuperClusters->end(); aClus++) {
00189 etaCurrent = aClus->position().eta();
00190 phiCurrent = aClus->position().phi();
00191 etCurrent = aClus->energy()/std::cosh(etaCurrent);
00192 double deltaR = std::sqrt(std::pow(etaCurrent-etaTrue,2)+std::pow(phiCurrent-phiTrue,2));
00193 if(deltaR < closestParticleDistance) {
00194 etFound = etCurrent;
00195 etaFound = etaCurrent;
00196 closestParticleDistance = deltaR;
00197 nearSC=&(*aClus);
00198 }
00199 }
00200
00201 if(closestParticleDistance < 0.3) {
00202
00203 nRECOphotons++;
00204 float psEnergy = nearSC->preshowerEnergy();
00205 superClusterEnergy[nRECOphotons-1]=nearSC->rawEnergy() + psEnergy;
00206 superClusterEta[nRECOphotons-1]=nearSC->position().eta();
00207 superClusterPhi[nRECOphotons-1]=nearSC->position().phi();
00208 superClusterEt[nRECOphotons-1]=(nearSC->rawEnergy() + psEnergy)/std::cosh(nearSC->position().eta());
00209 iMC[nRECOphotons-1]=nMCphotons-1;
00210
00211 reco::CaloClusterPtr theSeed = nearSC->seed();
00212 seedXtal[nRECOphotons-1] = EcalClusterTools::getMaximum(*theSeed, eeRecHits).first;
00213 e1[nRECOphotons-1] = EcalClusterTools::eMax(*theSeed, eeRecHits) + psEnergy;
00214 e9[nRECOphotons-1] = EcalClusterTools::e3x3(*theSeed, eeRecHits, topology ) + psEnergy;
00215 e25[nRECOphotons-1] = EcalClusterTools::e5x5(*theSeed, eeRecHits, topology ) + psEnergy;
00216 }
00217 }
00218 }
00219
00220
00221
00222 for (int i=0;i<nRECOphotons;i++) {
00223
00224
00225 if (fabs(superClusterEta[i]) < 1.479 ) {
00226 if (isConverted[iMC[i]] != 1){
00227 int ietaAbs = (seedXtal[i]>>9)&0x7F;
00228 int iphi = seedXtal[i]&0x1FF;
00229 if (ietaAbs > 5 && ietaAbs < 21 && ((iphi % 20) > 5) && ((iphi % 20) < 16) ) {
00230 h_EB_eRecoEtrueReference -> Fill(superClusterEnergy[i]/mcEnergy[iMC[i]]);
00231 h_EB_e9EtrueReference -> Fill(e9[i]/mcEnergy[iMC[i]]);
00232 h_EB_e25EtrueReference -> Fill(e25[i]/mcEnergy[iMC[i]]);
00233 }
00234 }
00235 }
00236
00237
00238 if (fabs(superClusterEta[i]) > 1.6 ) {
00239 if (isConverted[iMC[i]] != 1) {
00240 if ( fabs(superClusterEta[i]) > 1.7 && fabs(superClusterEta[i] < 2.3) &&
00241 ((superClusterPhi[i] > -CLHEP::pi/2. + 0.1 && superClusterPhi[i] < CLHEP::pi/2. - 0.1) ||
00242 (superClusterPhi[i] > CLHEP::pi/2. + 0.1) ||
00243 (superClusterPhi[i] < -CLHEP::pi/2. - 0.1)
00244 ))
00245 {
00246 h_EE_eRecoEtrueReference -> Fill(superClusterEnergy[i]/mcEnergy[iMC[i]]);
00247 h_EE_e9EtrueReference -> Fill(e9[i]/mcEnergy[iMC[i]]);
00248 h_EE_e25EtrueReference -> Fill(e25[i]/mcEnergy[iMC[i]]);
00249 }
00250 }
00251 }
00252
00253 }
00254 }
00255
00256 void ContainmentCorrectionAnalyzer::endJob() { }
00257
00258 float ContainmentCorrectionAnalyzer::ecalEta(float EtaParticle , float Zvertex, float plane_Radius) {
00259
00260 const float R_ECAL = 136.5;
00261 const float Z_Endcap = 328.0;
00262 const float etaBarrelEndcap = 1.479;
00263
00264 if(EtaParticle != 0.) {
00265 float Theta = 0.0 ;
00266 float ZEcal = (R_ECAL-plane_Radius)*sinh(EtaParticle)+Zvertex;
00267
00268 if(ZEcal != 0.0) Theta = atan(R_ECAL/ZEcal);
00269 if(Theta<0.0) Theta = Theta+Geom::pi() ;
00270
00271 float ETA = - log(tan(0.5*Theta));
00272
00273 if( fabs(ETA) > etaBarrelEndcap ) {
00274 float Zend = Z_Endcap ;
00275 if(EtaParticle<0.0 ) Zend = -Zend ;
00276 float Zlen = Zend - Zvertex ;
00277 float RR = Zlen/sinh(EtaParticle);
00278 Theta = atan((RR+plane_Radius)/Zend);
00279 if(Theta<0.0) Theta = Theta+Geom::pi() ;
00280 ETA = - log(tan(0.5*Theta));
00281 }
00282
00283 return ETA;
00284 }
00285 else {
00286 LogWarning("") << "[ContainmentCorrectionAnalyzer::ecalEta] Warning: Eta equals to zero, not correcting" ;
00287 return EtaParticle;
00288 }
00289 }
00290
00291
00292 std::vector<EcalSimPhotonMCTruth> ContainmentCorrectionAnalyzer::findMcTruth(std::vector<SimTrack>& theSimTracks, std::vector<SimVertex>& theSimVertices ) {
00293
00294 std::vector<EcalSimPhotonMCTruth> result;
00295
00296 geantToIndex_.clear();
00297 int idTrk1_[10];
00298 int idTrk2_[10];
00299
00300
00301 const int SINGLE=1;
00302 const int DOUBLE=2;
00303 const int PYTHIA=3;
00304 const int ELECTRON_FLAV=1;
00305 const int PIZERO_FLAV=2;
00306 const int PHOTON_FLAV=3;
00307
00308 int ievtype=0;
00309 int ievflav=0;
00310 std::vector<SimTrack*> photonTracks;
00311 std::vector<SimTrack*> pizeroTracks;
00312 std::vector<const SimTrack *> trkFromConversion;
00313 SimVertex primVtx;
00314 std::vector<int> convInd;
00315
00316 fillMcTruth(theSimTracks, theSimVertices);
00317 int iPV=-1;
00318 int partType1=0;
00319 int partType2=0;
00320 std::vector<SimTrack>::iterator iFirstSimTk = theSimTracks.begin();
00321 if ( !(*iFirstSimTk).noVertex() ) {
00322 iPV = (*iFirstSimTk).vertIndex();
00323 int vtxId = (*iFirstSimTk).vertIndex();
00324 primVtx = theSimVertices[vtxId];
00325 partType1 = (*iFirstSimTk).type();
00326 }
00327
00328
00329 iFirstSimTk++;
00330 if ( iFirstSimTk!= theSimTracks.end() ) {
00331 if ( (*iFirstSimTk).vertIndex() == iPV) {
00332 partType2 = (*iFirstSimTk).type();
00333 }
00334 }
00335 int npv=0;
00336 int iPho=0;
00337 for (std::vector<SimTrack>::iterator iSimTk = theSimTracks.begin(); iSimTk != theSimTracks.end(); ++iSimTk){
00338 if ( (*iSimTk).noVertex() ) continue;
00339 int vertexId = (*iSimTk).vertIndex();
00340 SimVertex vertex = theSimVertices[vertexId];
00341 if ( (*iSimTk).vertIndex() == iPV ) {
00342 npv++;
00343 if ( (*iSimTk).type() == 22) {
00344 convInd.push_back(0);
00345 photonTracks.push_back( &(*iSimTk) );
00346 math::XYZTLorentzVectorD momentum = (*iSimTk).momentum();
00347 }
00348 }
00349 }
00350
00351 if(npv > 4) { ievtype = PYTHIA;
00352 } else if(npv == 1) {
00353 if( abs(partType1) == 11 ) { ievtype = SINGLE; ievflav = ELECTRON_FLAV; }
00354 else if(partType1 == 111) { ievtype = SINGLE; ievflav = PIZERO_FLAV; }
00355 else if(partType1 == 22) { ievtype = SINGLE; ievflav = PHOTON_FLAV; }
00356 } else if(npv == 2) {
00357 if ( abs(partType1) == 11 && abs(partType2) == 11 ) { ievtype = DOUBLE; ievflav = ELECTRON_FLAV; }
00358 else if(partType1 == 111 && partType2 == 111) { ievtype = DOUBLE; ievflav = PIZERO_FLAV; }
00359 else if(partType1 == 22 && partType2 == 22) { ievtype = DOUBLE; ievflav = PHOTON_FLAV; }
00360 }
00361
00362
00363 int isAconversion=0;
00364 if(ievflav == PHOTON_FLAV) {
00365
00366 int nConv=0;
00367 int iConv=0;
00368 iPho=0;
00369 for (std::vector<SimTrack*>::iterator iPhoTk = photonTracks.begin(); iPhoTk != photonTracks.end(); ++iPhoTk){
00370 trkFromConversion.clear();
00371 for (std::vector<SimTrack>::iterator iSimTk = theSimTracks.begin(); iSimTk != theSimTracks.end(); ++iSimTk){
00372 if ( (*iSimTk).noVertex() ) continue;
00373 if ( (*iSimTk).vertIndex() == iPV ) continue;
00374 if ( abs((*iSimTk).type()) != 11 ) continue;
00375 int vertexId = (*iSimTk).vertIndex();
00376 SimVertex vertex = theSimVertices[vertexId];
00377 int motherId=-1;
00378 if ( vertex.parentIndex() ) {
00379 unsigned motherGeantId = vertex.parentIndex();
00380 std::map<unsigned, unsigned >::iterator association = geantToIndex_.find( motherGeantId );
00381 if(association != geantToIndex_.end() )
00382 motherId = association->second;
00383
00384
00385 if ( theSimTracks[motherId].trackId() == (*iPhoTk)->trackId() ) {
00387 trkFromConversion.push_back(&(*iSimTk ) );
00388 }
00389 }
00390 }
00391
00392 if ( trkFromConversion.size() > 0 ) {
00393 isAconversion=1;
00394 nConv++;
00395 convInd[iPho]=nConv;
00396 int convVtxId = trkFromConversion[0]->vertIndex();
00397 SimVertex convVtx = theSimVertices[convVtxId];
00398 math::XYZTLorentzVectorD vtxPosition = convVtx.position();
00399 math::XYZTLorentzVectorD momentum = (*iPhoTk)->momentum();
00400 if ( nConv <= 10) {
00401 if ( trkFromConversion.size() > 1) {
00402 idTrk1_[iConv]= trkFromConversion[0]->trackId();
00403 idTrk2_[iConv]= trkFromConversion[1]->trackId();
00404 } else {
00405 idTrk1_[iConv]=trkFromConversion[0]->trackId();
00406 idTrk2_[iConv]=-1;
00407 }
00408 }
00409 iConv++;
00410
00411 result.push_back( EcalSimPhotonMCTruth(isAconversion, (*iPhoTk)->momentum(), vtxPosition.pt(), vtxPosition.z() , vtxPosition, primVtx.position(), trkFromConversion ));
00412 } else {
00413 isAconversion=0;
00414 math::XYZTLorentzVectorD vtxPosition(0.,0.,0.,0.);
00415 result.push_back( EcalSimPhotonMCTruth(isAconversion, (*iPhoTk)->momentum(), vtxPosition.pt(), vtxPosition.z() , vtxPosition, primVtx.position(), trkFromConversion ));
00416 }
00417 iPho++;
00418 }
00419 }
00420
00421 return result;
00422 }
00423
00424 void ContainmentCorrectionAnalyzer::fillMcTruth(std::vector<SimTrack>& simTracks, std::vector<SimVertex>& simVertices ) {
00425
00426 unsigned nVtx = simVertices.size();
00427 unsigned nTks = simTracks.size();
00428 if ( nVtx == 0 ) return;
00429
00430 for( unsigned it=0; it<nTks; ++it ) {
00431 geantToIndex_[ simTracks[it].trackId() ] = it;
00432 }
00433 }
00434