CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/Validation/EcalClusters/src/ContainmentCorrectionAnalyzer.cc

Go to the documentation of this file.
00001 /*\class to compute not containment parameter */
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   // Define reference histograms
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   // taking the needed collections
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   // loop over MC truth photons
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     // check histos for MC truth
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     // barrel
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         // Is a matched particle dumping informations
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     // endcap
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         //Is a matched particle dumping informations
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   // containment analysis for unconverted photons in the reference region only
00222   for (int i=0;i<nRECOphotons;i++) {
00223 
00224     // barrel
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     // endcap
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   } // loop over reco photons
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 // taken from an old version of RecoEgamma/EgammaMCTools/src/PhotonMCTruthFinder
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   // Local variables  
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   // Look at a second track
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   //  Look into converted photons  
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           //int motherType = motherId == -1 ? 0 : theSimTracks[motherId].type();
00384           
00385           if ( theSimTracks[motherId].trackId() == (*iPhoTk)->trackId() ) {
00387             trkFromConversion.push_back(&(*iSimTk ) );
00388           }
00389         }        
00390       } // loop over the SimTracks      
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     } // loop over the primary photons
00419   }   // Event with one or two photons 
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   // create a map associating geant particle id and position in the event SimTrack vector
00430   for( unsigned it=0; it<nTks; ++it ) {
00431     geantToIndex_[ simTracks[it].trackId() ] = it;
00432   }  
00433 }
00434