CMS 3D CMS Logo

PhotonProducer.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <vector>
00003 #include <memory>
00004 
00005 // Framework
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "FWCore/Utilities/interface/Exception.h"
00008 
00009 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00010 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00011 #include "Geometry/CaloTopology/interface/CaloTopology.h"
00012 #include "Geometry/CaloEventSetup/interface/CaloTopologyRecord.h"
00013 
00014 
00015 #include "DataFormats/VertexReco/interface/Vertex.h"
00016 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00017 #include "DataFormats/EgammaReco/interface/ClusterShape.h"
00018 #include "DataFormats/EgammaCandidates/interface/PhotonFwd.h"
00019 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
00020 
00021 #include "DataFormats/EgammaReco/interface/ElectronPixelSeed.h"
00022 #include "RecoCaloTools/Selectors/interface/CaloConeSelector.h"
00023 #include "RecoEgamma/EgammaPhotonProducers/interface/PhotonProducer.h"
00024 
00025 
00026 
00027 PhotonProducer::PhotonProducer(const edm::ParameterSet& config) : 
00028   conf_(config), 
00029   theLikelihoodCalc_(0)
00030 
00031 {
00032 
00033   // use onfiguration file to setup input/output collection names
00034   scHybridBarrelProducer_       = conf_.getParameter<edm::InputTag>("scHybridBarrelProducer");
00035   scIslandEndcapProducer_       = conf_.getParameter<edm::InputTag>("scIslandEndcapProducer");
00036   barrelEcalHits_   = conf_.getParameter<edm::InputTag>("barrelEcalHits");
00037   endcapEcalHits_   = conf_.getParameter<edm::InputTag>("endcapEcalHits");
00038 
00039   conversionProducer_ = conf_.getParameter<std::string>("conversionProducer");
00040   conversionCollection_ = conf_.getParameter<std::string>("conversionCollection");
00041   vertexProducer_   = conf_.getParameter<std::string>("primaryVertexProducer");
00042   PhotonCollection_ = conf_.getParameter<std::string>("photonCollection");
00043   pixelSeedProducer_   = conf_.getParameter<std::string>("pixelSeedProducer");
00044 
00045   hbheLabel_        = conf_.getParameter<std::string>("hbheModule");
00046   hbheInstanceName_ = conf_.getParameter<std::string>("hbheInstance");
00047   hOverEConeSize_   = conf_.getParameter<double>("hOverEConeSize");
00048   maxHOverE_        = conf_.getParameter<double>("maxHOverE");
00049   minSCEt_        = conf_.getParameter<double>("minSCEt");
00050   minR9_        = conf_.getParameter<double>("minR9");
00051   likelihoodWeights_= conf_.getParameter<std::string>("MVA_weights_location");
00052 
00053   usePrimaryVertex_ = conf_.getParameter<bool>("usePrimaryVertex");
00054   risolveAmbiguity_ = conf_.getParameter<bool>("risolveConversionAmbiguity");
00055 
00056  
00057   // Parameters for the position calculation:
00058   std::map<std::string,double> providedParameters;
00059   providedParameters.insert(std::make_pair("LogWeighted",conf_.getParameter<bool>("posCalc_logweight")));
00060   providedParameters.insert(std::make_pair("T0_barl",conf_.getParameter<double>("posCalc_t0_barl")));
00061   providedParameters.insert(std::make_pair("T0_endc",conf_.getParameter<double>("posCalc_t0_endc")));
00062   providedParameters.insert(std::make_pair("T0_endcPresh",conf_.getParameter<double>("posCalc_t0_endcPresh")));
00063   providedParameters.insert(std::make_pair("W0",conf_.getParameter<double>("posCalc_w0")));
00064   providedParameters.insert(std::make_pair("X0",conf_.getParameter<double>("posCalc_x0")));
00065   posCalculator_ = PositionCalc(providedParameters);
00066 
00067   // Register the product
00068   produces< reco::PhotonCollection >(PhotonCollection_);
00069 
00070 }
00071 
00072 PhotonProducer::~PhotonProducer() {
00073 
00074   delete theLikelihoodCalc_;
00075 
00076 }
00077 
00078 
00079 void  PhotonProducer::beginJob (edm::EventSetup const & theEventSetup) {
00080   theLikelihoodCalc_ = new ConversionLikelihoodCalculator();
00081   edm::FileInPath path_mvaWeightFile(likelihoodWeights_.c_str() );
00082   theLikelihoodCalc_->setWeightsFile(path_mvaWeightFile.fullPath().c_str());
00083 
00084   // nEvt_=0;
00085 }
00086 
00087 
00088 void PhotonProducer::produce(edm::Event& theEvent, const edm::EventSetup& theEventSetup) {
00089 
00090   using namespace edm;
00091   //  nEvt_++;
00092 
00093   reco::PhotonCollection outputPhotonCollection;
00094   std::auto_ptr< reco::PhotonCollection > outputPhotonCollection_p(new reco::PhotonCollection);
00095 
00096   // Get the  Barrel Super Cluster collection
00097   bool validBarrelSCHandle=true;
00098   Handle<reco::SuperClusterCollection> scBarrelHandle;
00099   theEvent.getByLabel(scHybridBarrelProducer_,scBarrelHandle);
00100   if (!scBarrelHandle.isValid()) {
00101     edm::LogError("PhotonProducer") << "Error! Can't get the product "<<scHybridBarrelProducer_.label();
00102     bool validBarrelSCHandle=false;
00103   }
00104 
00105 
00106  // Get the  Endcap Super Cluster collection
00107   bool validEndcapSCHandle=true;
00108   Handle<reco::SuperClusterCollection> scEndcapHandle;
00109   theEvent.getByLabel(scIslandEndcapProducer_,scEndcapHandle);
00110   if (!scEndcapHandle.isValid()) {
00111     edm::LogError("PhotonProducer") << "Error! Can't get the product "<<scIslandEndcapProducer_.label();
00112     validEndcapSCHandle=false;
00113   }
00114 
00115   
00116  // Get EcalRecHits
00117   bool validEcalRecHits=true;
00118   Handle<EcalRecHitCollection> barrelHitHandle;
00119   EcalRecHitCollection barrelRecHits;
00120   theEvent.getByLabel(barrelEcalHits_, barrelHitHandle);
00121   if (!barrelHitHandle.isValid()) {
00122     edm::LogError("PhotonProducer") << "Error! Can't get the product "<<barrelEcalHits_.label();
00123     validEcalRecHits=false; 
00124   }
00125   if (  validEcalRecHits)  barrelRecHits = *(barrelHitHandle.product());
00126 
00127   
00128   Handle<EcalRecHitCollection> endcapHitHandle;
00129   theEvent.getByLabel(endcapEcalHits_, endcapHitHandle);
00130   EcalRecHitCollection endcapRecHits;
00131   if (!endcapHitHandle.isValid()) {
00132     edm::LogError("PhotonProducer") << "Error! Can't get the product "<<endcapEcalHits_.label();
00133     validEcalRecHits=false; 
00134   }
00135   if( validEcalRecHits) endcapRecHits = *(endcapHitHandle.product());
00136 
00137 
00138   // get the geometry from the event setup:
00139   theEventSetup.get<CaloGeometryRecord>().get(theCaloGeom_);
00140   const CaloSubdetectorGeometry *barrelGeometry = theCaloGeom_->getSubdetectorGeometry(DetId::Ecal, EcalBarrel);
00141   const CaloSubdetectorGeometry *endcapGeometry = theCaloGeom_->getSubdetectorGeometry(DetId::Ecal, EcalEndcap);
00142   const CaloSubdetectorGeometry *preshowerGeometry = theCaloGeom_->getSubdetectorGeometry(DetId::Ecal, EcalPreshower);
00143 
00144   edm::ESHandle<CaloTopology> pTopology;
00145   theEventSetup.get<CaloTopologyRecord>().get(theCaloTopo_);
00146   const CaloTopology *topology = theCaloTopo_.product();
00147 
00148 
00150   validConversions_=true;
00151   edm::Handle<reco::ConversionCollection> conversionHandle; 
00152   theEvent.getByLabel(conversionProducer_, conversionCollection_ , conversionHandle);
00153   if (!conversionHandle.isValid()) {
00154     //if ( nEvt_%10==0 ) edm::LogError("PhotonProducer") << "Error! Can't get the product  "<<conversionCollection_.c_str() << " but keep running. Photons will be produced with null reference to conversions " << "\n";
00155     validConversions_=false;
00156   }
00157  
00158 
00159 
00160   // Get HoverE
00161   bool validHcalRecHits=true;
00162   Handle<HBHERecHitCollection> hbhe;
00163   std::auto_ptr<HBHERecHitMetaCollection> mhbhe;
00164   theEvent.getByLabel(hbheLabel_,hbheInstanceName_,hbhe);  
00165   if (!hbhe.isValid()) {
00166     edm::LogError("PhotonProducer") << "Error! Can't get the product "<<hbheInstanceName_.c_str();
00167     validHcalRecHits=false;
00168   }
00169 
00170   if ( hOverEConeSize_ > 0.) {
00171     if ( validHcalRecHits ) mhbhe=  std::auto_ptr<HBHERecHitMetaCollection>(new HBHERecHitMetaCollection(*hbhe));
00172   }
00173 
00174   
00175   theHoverEcalc_=HoECalculator(theCaloGeom_);
00176 
00177   // Get ElectronPixelSeeds
00178   validPixelSeeds_=true;
00179   Handle<reco::ElectronPixelSeedCollection> pixelSeedHandle;
00180   reco::ElectronPixelSeedCollection pixelSeeds;
00181   theEvent.getByLabel(pixelSeedProducer_, pixelSeedHandle);
00182   if (!pixelSeedHandle.isValid()) {
00183     //if ( nEvt_%100==0 ) std::cout << " PhotonProducer Can't get the product ElectronPixelSeedHandle but Photons will be produced anyway with pixel seed flag set to false "<< "\n";
00184     validPixelSeeds_=false;
00185   }
00186   if ( validPixelSeeds_) pixelSeeds = *(pixelSeedHandle.product());
00187 
00188 
00189 
00190   // Get the primary event vertex
00191   Handle<reco::VertexCollection> vertexHandle;
00192   reco::VertexCollection vertexCollection;
00193   bool validVertex=true;
00194   if ( usePrimaryVertex_ ) {
00195     theEvent.getByLabel(vertexProducer_, vertexHandle);
00196     if (!vertexHandle.isValid()) {
00197       edm::LogError("PhotonProducer") << "Error! Can't get the product primary Vertex Collection "<< "\n";
00198       validVertex=false;
00199     }
00200     if (validVertex) vertexCollection = *(vertexHandle.product());
00201   }
00202   math::XYZPoint vtx(0.,0.,0.);
00203   if (vertexCollection.size()>0) vtx = vertexCollection.begin()->position();
00204 
00205   edm::LogInfo("PhotonProducer") << "Constructing Photon 4-vectors assuming primary vertex position: " << vtx << std::endl;
00206 
00207   int iSC=0; // index in photon collection
00208   // Loop over barrel and endcap SC collections and fill the  photon collection
00209   if ( validBarrelSCHandle) fillPhotonCollection(scBarrelHandle,barrelGeometry,preshowerGeometry,topology,&barrelRecHits,mhbhe.get(),conversionHandle,pixelSeeds,vtx,outputPhotonCollection,iSC);
00210   if ( validEndcapSCHandle) fillPhotonCollection(scEndcapHandle,endcapGeometry,preshowerGeometry,topology,&endcapRecHits,mhbhe.get(),conversionHandle,pixelSeeds,vtx,outputPhotonCollection,iSC);
00211 
00212   // put the product in the event
00213   edm::LogInfo("PhotonProducer") << " Put in the event " << iSC << " Photon Candidates \n";
00214   outputPhotonCollection_p->assign(outputPhotonCollection.begin(),outputPhotonCollection.end());
00215   theEvent.put( outputPhotonCollection_p, PhotonCollection_);
00216 
00217 }
00218 
00219 void PhotonProducer::fillPhotonCollection(
00220                    const edm::Handle<reco::SuperClusterCollection> & scHandle,
00221                    const CaloSubdetectorGeometry *geometry,
00222                    const CaloSubdetectorGeometry *geometryES,
00223                    const CaloTopology *topology,
00224                    const EcalRecHitCollection* hits,
00225                    HBHERecHitMetaCollection *mhbhe,
00226                    const edm::Handle<reco::ConversionCollection> & conversionHandle,
00227                    const reco::ElectronPixelSeedCollection& pixelSeeds,
00228                    math::XYZPoint & vtx,
00229                    reco::PhotonCollection & outputPhotonCollection, int& iSC) {
00230 
00231 
00232   reco::ElectronPixelSeedCollection::const_iterator pixelSeedItr;
00233   for(unsigned int lSC=0; lSC < scHandle->size(); lSC++) {
00234     
00235     // get SuperClusterRef
00236     reco::SuperClusterRef scRef(reco::SuperClusterRef(scHandle, lSC));
00237     iSC++;
00238     const reco::SuperCluster* pClus=&(*scRef);
00239     
00240     // preselection
00241     if (scRef->energy()/cosh(scRef->eta()) <= minSCEt_) continue;
00242     // calculate HoE
00243     double HoE=theHoverEcalc_(pClus,mhbhe);
00244     if (HoE>=maxHOverE_)  continue;
00245     
00246     
00247     
00248     // recalculate position of seed BasicCluster taking shower depth for unconverted photon
00249     math::XYZPoint unconvPos = posCalculator_.Calculate_Location(scRef->seed()->getHitsByDetId(),hits,geometry,geometryES);
00250     
00251     // compute position of ECAL shower
00252     float e3x3=   EcalClusterTools::e3x3(  *(scRef->seed()), &(*hits), &(*topology)); 
00253     float r9 =e3x3/(scRef->rawEnergy());
00254     float e5x5= EcalClusterTools::e5x5( *(scRef->seed()), &(*hits), &(*topology)); 
00255 
00256     math::XYZPoint caloPosition;
00257     double photonEnergy=0;
00258     if (r9>minR9_) {
00259       caloPosition = unconvPos;
00260       photonEnergy=e5x5;
00261     } else {
00262       caloPosition = scRef->position();
00263       photonEnergy=scRef->energy();
00264     }
00265     
00266     // does the SuperCluster have a matched pixel seed?
00267     bool hasSeed = false;
00268     if ( validPixelSeeds_) {
00269       for(pixelSeedItr = pixelSeeds.begin(); pixelSeedItr != pixelSeeds.end(); pixelSeedItr++) {
00270         if (fabs(pixelSeedItr->superCluster()->eta() - scRef->eta()) < 0.0001 &&
00271             fabs(pixelSeedItr->superCluster()->phi() - scRef->phi()) < 0.0001) {
00272           hasSeed=true;
00273           break;
00274         }
00275       }
00276     }
00277     
00278     // compute momentum vector of photon from primary vertex and cluster position
00279     math::XYZVector direction = caloPosition - vtx;
00280     math::XYZVector momentum = direction.unit() * photonEnergy ;
00281 
00282     const reco::Particle::LorentzVector  p4(momentum.x(), momentum.y(), momentum.z(), photonEnergy );
00283 
00284     
00285     reco::Photon newCandidate(p4, caloPosition, scRef, HoE, hasSeed, vtx);
00286 
00287     if ( validConversions_) {
00288       
00289       if ( risolveAmbiguity_ ) { 
00290         
00291         reco::ConversionRef bestRef=solveAmbiguity( conversionHandle , scRef);  
00292 
00293         if (bestRef.isNonnull() ) newCandidate.addConversion(bestRef);  
00294                 
00295         
00296       } else {
00297         
00298 
00299         for( unsigned int icp = 0;  icp < conversionHandle->size(); icp++) {
00300           
00301           reco::ConversionRef cpRef(reco::ConversionRef(conversionHandle,icp));
00302           
00303           if (!( scRef.id() == cpRef->caloCluster()[0].id() && scRef.key() == cpRef->caloCluster()[0].key() )) continue; 
00304           if ( !cpRef->isConverted() ) continue;  
00305           newCandidate.addConversion(cpRef);     
00306 
00307         }         
00308         
00309       } // solve or not the ambiguity        
00310       
00311     }
00312 
00313 
00314     outputPhotonCollection.push_back(newCandidate);
00315     
00316     
00317   }
00318 
00319 }
00320 
00321 
00322 
00323 reco::ConversionRef  PhotonProducer::solveAmbiguity(const edm::Handle<reco::ConversionCollection> & conversionHandle, reco::SuperClusterRef& scRef) {
00324 
00325   std::multimap<reco::ConversionRef, double >   convMap;
00326 
00327 
00328   for ( unsigned int icp=0; icp< conversionHandle->size(); icp++) {
00329     reco::ConversionRef cpRef(reco::ConversionRef(conversionHandle,icp));
00330     //icp++;      
00331 
00332     if (!( scRef.id() == cpRef->caloCluster()[0].id() && scRef.key() == cpRef->caloCluster()[0].key() )) continue;    
00333     if ( !cpRef->isConverted() ) continue;  
00334     
00335     double like = theLikelihoodCalc_->calculateLikelihood(cpRef);
00336     //    std::cout << " Like " << like << std::endl;
00337     convMap.insert ( std::make_pair(cpRef,like) ) ;
00338   }                  
00339   
00340   
00341   
00342   std::multimap<reco::ConversionRef, double >::iterator  iMap; 
00343   double max_lh = -1.;
00344   reco::ConversionRef bestRef;
00345   //std::cout << " Pick up the best conv " << std::endl;
00346   for (iMap=convMap.begin();  iMap!=convMap.end(); iMap++) {
00347     double like = iMap->second;
00348     if (like > max_lh) { 
00349       max_lh = like;
00350       bestRef=iMap->first;
00351     }
00352   }            
00353   
00354   //std::cout << " Best conv like " << max_lh << std::endl;    
00355   
00356   float ep=0;
00357   if ( max_lh <0 ) {
00358     //  std::cout << " Candidates with only one track " << std::endl;
00360     float epMin=999; 
00361     
00362     for (iMap=convMap.begin();  iMap!=convMap.end(); iMap++) {
00363       reco::ConversionRef convRef=iMap->first;
00364       std::vector<reco::TrackRef> tracks = convRef->tracks();   
00365             float px=tracks[0]->innerMomentum().x();
00366             float py=tracks[0]->innerMomentum().y();
00367             float pz=tracks[0]->innerMomentum().z();
00368             float p=sqrt(px*px+py*py+pz*pz);
00369             ep=fabs(1.-convRef->caloCluster()[0]->energy()/p);
00370             //    std::cout << " 1-E/P = " << ep << std::endl;
00371             if ( ep<epMin) {
00372               epMin=ep;
00373               bestRef=iMap->first;
00374             }
00375     }
00376     //std::cout << " Best conv 1-E/P " << ep << std::endl;    
00377             
00378   }
00379   
00380 
00381   return bestRef;
00382   
00383   
00384 } 
00385 
00386 double PhotonProducer::hOverE(const reco::SuperClusterRef & scRef,
00387                               HBHERecHitMetaCollection *mhbhe){
00388 
00390   double HoE=0;
00391   if (mhbhe) {
00392     CaloConeSelector sel(hOverEConeSize_, theCaloGeom_.product(), DetId::Hcal);
00393     GlobalPoint pclu((*scRef).x(),(*scRef).y(),(*scRef).z());
00394     double hcalEnergy = 0.;
00395     std::auto_ptr<CaloRecHitMetaCollectionV> chosen=sel.select(pclu,*mhbhe);
00396     for (CaloRecHitMetaCollectionV::const_iterator i=chosen->begin(); i!=chosen->end(); i++) {
00397       hcalEnergy += i->energy();
00398     }
00399     HoE= hcalEnergy/(*scRef).energy();
00400     LogDebug("") << "H/E : " << HoE;
00401   }
00402   return HoE;
00403 }

Generated on Tue Jun 9 17:43:27 2009 for CMSSW by  doxygen 1.5.4