CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoParticleFlow/PFProducer/plugins/PFElectronTranslator.cc

Go to the documentation of this file.
00001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00002 #include "FWCore/Framework/interface/ESHandle.h"
00003 #include "FWCore/Framework/interface/Event.h"
00004 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00005 #include "RecoParticleFlow/PFProducer/plugins/PFElectronTranslator.h"
00006 #include "RecoParticleFlow/PFClusterTools/interface/PFClusterWidthAlgo.h"
00007 #include "RecoEcal/EgammaCoreTools/interface/Mustache.h"
00008 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00009 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateElectronExtra.h"
00010 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
00011 #include "DataFormats/EgammaReco/interface/PreshowerCluster.h"
00012 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
00013 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
00014 #include "DataFormats/EgammaCandidates/interface/GsfElectronCore.h"
00015 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00016 #include "DataFormats/ParticleFlowReco/interface/PFBlockElement.h"
00017 #include "DataFormats/ParticleFlowReco/interface/PFBlockFwd.h"
00018 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00019 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementGsfTrack.h"
00020 
00021 
00022 PFElectronTranslator::PFElectronTranslator(const edm::ParameterSet & iConfig) {
00023   inputTagPFCandidates_ 
00024     = iConfig.getParameter<edm::InputTag>("PFCandidate");
00025   inputTagPFCandidateElectrons_ 
00026     = iConfig.getParameter<edm::InputTag>("PFCandidateElectron");
00027   inputTagGSFTracks_
00028     = iConfig.getParameter<edm::InputTag>("GSFTracks");
00029 
00030   bool useIsolationValues = iConfig.getParameter<bool>("useIsolationValues") ;
00031   if ( useIsolationValues ) {
00032         if( ! iConfig.exists("isolationValues") )
00033                 throw cms::Exception("PFElectronTranslator|InternalError")
00034                         <<"Missing ParameterSet isolationValues" ;
00035         else {
00036                 edm::ParameterSet isoVals  = 
00037                         iConfig.getParameter<edm::ParameterSet> ("isolationValues");
00038                 inputTagIsoVals_.push_back
00039                         (isoVals.getParameter<edm::InputTag>("pfChargedHadrons"));
00040                 inputTagIsoVals_.push_back
00041                         (isoVals.getParameter<edm::InputTag>("pfPhotons"));
00042                 inputTagIsoVals_.push_back
00043                         (isoVals.getParameter<edm::InputTag>("pfNeutralHadrons"));
00044         }
00045   }
00046 
00047   PFBasicClusterCollection_ = iConfig.getParameter<std::string>("PFBasicClusters");
00048   PFPreshowerClusterCollection_ = iConfig.getParameter<std::string>("PFPreshowerClusters");
00049   PFSuperClusterCollection_ = iConfig.getParameter<std::string>("PFSuperClusters");
00050   GsfElectronCoreCollection_ = iConfig.getParameter<std::string>("PFGsfElectronCore");
00051   GsfElectronCollection_ = iConfig.getParameter<std::string>("PFGsfElectron");
00052   
00053   PFMVAValueMap_ = iConfig.getParameter<std::string>("ElectronMVA");
00054   PFSCValueMap_ = iConfig.getParameter<std::string>("ElectronSC");
00055   MVACut_ = (iConfig.getParameter<edm::ParameterSet>("MVACutBlock")).getParameter<double>("MVACut");
00056   checkStatusFlag_ = iConfig.getParameter<bool>("CheckStatusFlag");
00057   
00058   if (iConfig.exists("emptyIsOk")) emptyIsOk_ = iConfig.getParameter<bool>("emptyIsOk");
00059   else emptyIsOk_=false;
00060 
00061   produces<reco::BasicClusterCollection>(PFBasicClusterCollection_); 
00062   produces<reco::PreshowerClusterCollection>(PFPreshowerClusterCollection_); 
00063   produces<reco::SuperClusterCollection>(PFSuperClusterCollection_); 
00064   produces<reco::GsfElectronCoreCollection>(GsfElectronCoreCollection_);
00065   produces<reco::GsfElectronCollection>(GsfElectronCollection_);
00066   produces<edm::ValueMap<float> >(PFMVAValueMap_);
00067   produces<edm::ValueMap<reco::SuperClusterRef> >(PFSCValueMap_);
00068 }
00069 
00070 PFElectronTranslator::~PFElectronTranslator() {}
00071 
00072 void PFElectronTranslator::produce(edm::Event& iEvent,  
00073                                     const edm::EventSetup& iSetup) { 
00074   
00075   std::auto_ptr<reco::GsfElectronCoreCollection>
00076     gsfElectronCores_p(new reco::GsfElectronCoreCollection);
00077 
00078   std::auto_ptr<reco::GsfElectronCollection>
00079     gsfElectrons_p(new reco::GsfElectronCollection);
00080 
00081   std::auto_ptr<reco::SuperClusterCollection> 
00082     superClusters_p(new reco::SuperClusterCollection);
00083 
00084   std::auto_ptr<reco::BasicClusterCollection> 
00085     basicClusters_p(new reco::BasicClusterCollection);
00086 
00087   std::auto_ptr<reco::PreshowerClusterCollection>
00088     psClusters_p(new reco::PreshowerClusterCollection);
00089   
00090   std::auto_ptr<edm::ValueMap<float> > mvaMap_p(new edm::ValueMap<float>());
00091   edm::ValueMap<float>::Filler mvaFiller(*mvaMap_p);
00092 
00093   std::auto_ptr<edm::ValueMap<reco::SuperClusterRef> > 
00094     scMap_p(new edm::ValueMap<reco::SuperClusterRef>());
00095   edm::ValueMap<reco::SuperClusterRef>::Filler scRefFiller(*scMap_p);
00096   
00097 
00098   edm::Handle<reco::PFCandidateCollection> pfCandidates;
00099   bool status=fetchCandidateCollection(pfCandidates, 
00100                                        inputTagPFCandidates_, 
00101                                        iEvent );
00102 
00103   IsolationValueMaps isolationValues(inputTagIsoVals_.size());
00104   for (size_t j = 0; j<inputTagIsoVals_.size(); ++j) {
00105     iEvent.getByLabel(inputTagIsoVals_[j], isolationValues[j]);
00106   }
00107 
00108 
00109   // clear the vectors
00110   GsfTrackRef_.clear();
00111   CandidatePtr_.clear();
00112   ambiguousGsfTracks_.clear();
00113   kfTrackRef_.clear();
00114   basicClusters_.clear();
00115   pfClusters_.clear();
00116   preshowerClusters_.clear();
00117   superClusters_.clear();
00118   basicClusterPtr_.clear();
00119   preshowerClusterPtr_.clear();
00120   gsfPFCandidateIndex_.clear();
00121   gsfElectronCoreRefs_.clear();
00122   scMap_.clear();
00123 
00124  
00125   // loop on the candidates 
00126   //CC@@
00127   // we need first to create AND put the SuperCluster, 
00128   // basic clusters and presh clusters collection 
00129   // in order to get a working Handle
00130   unsigned ncand=(status)?pfCandidates->size():0;
00131   unsigned iGSF=0;
00132   for( unsigned i=0; i<ncand; ++i ) {
00133 
00134     const reco::PFCandidate& cand = (*pfCandidates)[i];    
00135     if(cand.particleId()!=reco::PFCandidate::e) continue; 
00136     if(cand.gsfTrackRef().isNull()) continue;
00137     // Note that -1 will still cut some total garbage candidates 
00138     // Fill the MVA map
00139     if(cand.mva_e_pi()<MVACut_) continue;
00140     
00141     // Check the status flag
00142     if(checkStatusFlag_ && !cand.electronExtraRef()->electronStatus(reco::PFCandidateElectronExtra::Selected)) {
00143       continue;
00144     }
00145 
00146     GsfTrackRef_.push_back(cand.gsfTrackRef());
00147     kfTrackRef_.push_back(cand.trackRef());
00148     gsfPFCandidateIndex_.push_back(i);
00149 
00150     reco::PFCandidatePtr ptrToPFElectron(pfCandidates,i);
00151     //CandidatePtr_.push_back(ptrToPFElectron->sourceCandidatePtr(0));
00152     CandidatePtr_.push_back(ptrToPFElectron);    
00153 
00154     basicClusters_.push_back(reco::BasicClusterCollection());
00155     pfClusters_.push_back(std::vector<const reco::PFCluster *>());
00156     preshowerClusters_.push_back(reco::PreshowerClusterCollection());
00157     ambiguousGsfTracks_.push_back(std::vector<reco::GsfTrackRef>());
00158 
00159     for(unsigned iele=0; iele<cand.elementsInBlocks().size(); ++iele) {
00160       // first get the block 
00161       reco::PFBlockRef blockRef = cand.elementsInBlocks()[iele].first;
00162       //
00163       unsigned elementIndex = cand.elementsInBlocks()[iele].second;
00164       // check it actually exists 
00165       if(blockRef.isNull()) continue;
00166       
00167       // then get the elements of the block
00168       const edm::OwnVector< reco::PFBlockElement >&  elements = (*blockRef).elements();
00169       
00170       const reco::PFBlockElement & pfbe (elements[elementIndex]); 
00171       // The first ECAL element should be the cluster associated to the GSF; defined as the seed
00172       if(pfbe.type()==reco::PFBlockElement::ECAL)
00173         {         
00174           //      const reco::PFCandidate * coCandidate = &cand;
00175           // the Brem photons are saved as daughter PFCandidate; this 
00176           // is convenient to access the corrected energy
00177           //      std::cout << " Found candidate "  << correspondingDaughterCandidate(coCandidate,pfbe) << " " << coCandidate << std::endl;
00178           createBasicCluster(pfbe,basicClusters_[iGSF],pfClusters_[iGSF],correspondingDaughterCandidate(cand,pfbe));
00179         }
00180       if(pfbe.type()==reco::PFBlockElement::PS1)
00181         {
00182           createPreshowerCluster(pfbe,preshowerClusters_[iGSF],1);
00183         }
00184       if(pfbe.type()==reco::PFBlockElement::PS2)
00185         {
00186           createPreshowerCluster(pfbe,preshowerClusters_[iGSF],2);
00187         }      
00188       if(pfbe.type()==reco::PFBlockElement::GSF)
00189         {
00190           getAmbiguousGsfTracks(pfbe,ambiguousGsfTracks_[iGSF]);
00191         }
00192 
00193     }   // loop on the elements
00194 
00195     // save the basic clusters
00196     basicClusters_p->insert(basicClusters_p->end(),basicClusters_[iGSF].begin(), basicClusters_[iGSF].end());
00197     // save the preshower clusters
00198     psClusters_p->insert(psClusters_p->end(),preshowerClusters_[iGSF].begin(),preshowerClusters_[iGSF].end());
00199 
00200     ++iGSF;
00201   } // loop on PFCandidates
00202 
00203   
00204    //Save the basic clusters and get an handle as to be able to create valid Refs (thanks to Claude)
00205   //  std::cout << " Number of basic clusters " << basicClusters_p->size() << std::endl;
00206   const edm::OrphanHandle<reco::BasicClusterCollection> bcRefProd = 
00207     iEvent.put(basicClusters_p,PFBasicClusterCollection_);
00208 
00209   //preshower clusters
00210   const edm::OrphanHandle<reco::PreshowerClusterCollection> psRefProd = 
00211     iEvent.put(psClusters_p,PFPreshowerClusterCollection_);
00212 
00213   // now that the Basic clusters are in the event, the Ref can be created
00214   createBasicClusterPtrs(bcRefProd);
00215   // now that the preshower clusters are in the event, the Ref can be created
00216   createPreshowerClusterPtrs(psRefProd);
00217   
00218   // and now the Super cluster can be created with valid references  
00219   if(status) createSuperClusters(*pfCandidates,*superClusters_p);
00220   
00221   // Let's put the super clusters in the event
00222   const edm::OrphanHandle<reco::SuperClusterCollection> scRefProd = iEvent.put(superClusters_p,PFSuperClusterCollection_); 
00223   // create the super cluster Ref
00224   createSuperClusterGsfMapRefs(scRefProd);
00225 
00226   // Now create the GsfElectronCoers
00227   createGsfElectronCores(*gsfElectronCores_p);
00228   // Put them in the as to get to be able to build a Ref
00229   const edm::OrphanHandle<reco::GsfElectronCoreCollection> gsfElectronCoreRefProd = 
00230     iEvent.put(gsfElectronCores_p,GsfElectronCoreCollection_);
00231 
00232   // now create the Refs 
00233   createGsfElectronCoreRefs(gsfElectronCoreRefProd);
00234 
00235   // now make the GsfElectron
00236   createGsfElectrons(*pfCandidates,isolationValues,*gsfElectrons_p);
00237   iEvent.put(gsfElectrons_p,GsfElectronCollection_);
00238 
00239   fillMVAValueMap(iEvent,mvaFiller);
00240   mvaFiller.fill();
00241 
00242   fillSCRefValueMap(iEvent,scRefFiller);
00243   scRefFiller.fill();
00244 
00245   // MVA map
00246   iEvent.put(mvaMap_p,PFMVAValueMap_);
00247   // Gsf-SC map
00248   iEvent.put(scMap_p,PFSCValueMap_);
00249 
00250 
00251   
00252 }
00253 
00254 
00255 
00256 bool PFElectronTranslator::fetchCandidateCollection(edm::Handle<reco::PFCandidateCollection>& c, 
00257                                               const edm::InputTag& tag, 
00258                                               const edm::Event& iEvent) const {  
00259   bool found = iEvent.getByLabel(tag, c);
00260 
00261   if(!found && !emptyIsOk_)
00262     {
00263       std::ostringstream  err;
00264       err<<" cannot get PFCandidates: "
00265          <<tag<<std::endl;
00266       edm::LogError("PFElectronTranslator")<<err.str();
00267     }
00268   return found;
00269       
00270 }
00271 
00272 void PFElectronTranslator::fetchGsfCollection(edm::Handle<reco::GsfTrackCollection>& c, 
00273                                               const edm::InputTag& tag, 
00274                                               const edm::Event& iEvent) const {  
00275   bool found = iEvent.getByLabel(tag, c);
00276   
00277   if(!found ) {
00278     std::ostringstream  err;
00279     err<<" cannot get GSFTracks: "
00280        <<tag<<std::endl;
00281     edm::LogError("PFElectronTranslator")<<err.str();
00282     throw cms::Exception( "MissingProduct", err.str());
00283   }  
00284 }
00285 
00286 // The basic cluster is a copy of the PFCluster -> the energy is not corrected 
00287 // It should be possible to get the corrected energy (including the associated PS energy)
00288 // from the PFCandidate daugthers ; Needs some work 
00289 void PFElectronTranslator::createBasicCluster(const reco::PFBlockElement & PFBE, 
00290                                               reco::BasicClusterCollection & basicClusters, 
00291                                               std::vector<const reco::PFCluster *> & pfClusters,
00292                                               const reco::PFCandidate & coCandidate) const
00293 {
00294   reco::PFClusterRef myPFClusterRef= PFBE.clusterRef();
00295   if(myPFClusterRef.isNull()) return;  
00296 
00297   const reco::PFCluster & myPFCluster (*myPFClusterRef);
00298   pfClusters.push_back(&myPFCluster);
00299 //  std::cout << " Creating BC " << myPFCluster.energy() << " " << coCandidate.ecalEnergy() <<" "<<  coCandidate.rawEcalEnergy() <<std::endl;
00300 //  std::cout << " # hits " << myPFCluster.hitsAndFractions().size() << std::endl;
00301 
00302 //  basicClusters.push_back(reco::CaloCluster(myPFCluster.energy(),
00303   basicClusters.push_back(reco::CaloCluster(
00304                                             //      myPFCluster.energy(),
00305                                             coCandidate.rawEcalEnergy(),
00306                                             myPFCluster.position(),
00307                                             myPFCluster.caloID(),
00308                                             myPFCluster.hitsAndFractions(),
00309                                             myPFCluster.algo(),
00310                                             myPFCluster.seed()));
00311 }
00312 
00313 
00314 void PFElectronTranslator::createPreshowerCluster(const reco::PFBlockElement & PFBE, reco::PreshowerClusterCollection& preshowerClusters,unsigned plane) const
00315 {
00316   reco::PFClusterRef  myPFClusterRef= PFBE.clusterRef();
00317   preshowerClusters.push_back(reco::PreshowerCluster(myPFClusterRef->energy(),myPFClusterRef->position(),
00318                                                myPFClusterRef->hitsAndFractions(),plane));
00319 }
00320 
00321 void PFElectronTranslator::createBasicClusterPtrs(const edm::OrphanHandle<reco::BasicClusterCollection> & basicClustersHandle )
00322 {
00323   unsigned size=GsfTrackRef_.size();
00324   unsigned basicClusterCounter=0;
00325   basicClusterPtr_.resize(size);
00326 
00327   for(unsigned iGSF=0;iGSF<size;++iGSF) // loop on tracks
00328     {
00329       unsigned nbc=basicClusters_[iGSF].size();
00330       for(unsigned ibc=0;ibc<nbc;++ibc) // loop on basic clusters
00331         {
00332           //      std::cout <<  "Track "<< iGSF << " ref " << basicClusterCounter << std::endl;
00333           reco::CaloClusterPtr bcPtr(basicClustersHandle,basicClusterCounter);
00334           basicClusterPtr_[iGSF].push_back(bcPtr);
00335           ++basicClusterCounter;
00336         }
00337     }
00338 }
00339 
00340 void PFElectronTranslator::createPreshowerClusterPtrs(const edm::OrphanHandle<reco::PreshowerClusterCollection> & preshowerClustersHandle )
00341 {
00342   unsigned size=GsfTrackRef_.size();
00343   unsigned psClusterCounter=0;
00344   preshowerClusterPtr_.resize(size);
00345 
00346   for(unsigned iGSF=0;iGSF<size;++iGSF) // loop on tracks
00347     {
00348       unsigned nbc=preshowerClusters_[iGSF].size();
00349       for(unsigned ibc=0;ibc<nbc;++ibc) // loop on basic clusters
00350         {
00351           //      std::cout <<  "Track "<< iGSF << " ref " << basicClusterCounter << std::endl;
00352           reco::CaloClusterPtr psPtr(preshowerClustersHandle,psClusterCounter);
00353           preshowerClusterPtr_[iGSF].push_back(psPtr);
00354           ++psClusterCounter;
00355         }
00356     }
00357 }
00358 
00359 void PFElectronTranslator::createSuperClusterGsfMapRefs(const edm::OrphanHandle<reco::SuperClusterCollection> & superClustersHandle )
00360 {
00361   unsigned size=GsfTrackRef_.size();
00362 
00363   for(unsigned iGSF=0;iGSF<size;++iGSF) // loop on tracks
00364     {
00365       edm::Ref<reco::SuperClusterCollection> scRef(superClustersHandle,iGSF);
00366       scMap_[GsfTrackRef_[iGSF]]=scRef;
00367     }
00368 }
00369 
00370 
00371 void PFElectronTranslator::fillMVAValueMap(edm::Event& iEvent, edm::ValueMap<float>::Filler & filler) 
00372 {
00373   gsfMvaMap_.clear();
00374   edm::Handle<reco::PFCandidateCollection> pfCandidates;
00375   bool status=fetchCandidateCollection(pfCandidates, 
00376                                        inputTagPFCandidateElectrons_, 
00377                                        iEvent );
00378   
00379   unsigned ncand=(status)?pfCandidates->size():0;
00380   for( unsigned i=0; i<ncand; ++i ) {
00381     
00382     const reco::PFCandidate& cand = (*pfCandidates)[i];    
00383     if(cand.particleId()!=reco::PFCandidate::e) continue; 
00384     if(cand.gsfTrackRef().isNull()) continue;
00385     // Fill the MVA map
00386     gsfMvaMap_[cand.gsfTrackRef()]=cand.mva_e_pi();       
00387   }
00388   
00389   edm::Handle<reco::GsfTrackCollection> gsfTracks;
00390   fetchGsfCollection(gsfTracks,
00391                      inputTagGSFTracks_,
00392                      iEvent);
00393   unsigned ngsf=gsfTracks->size();
00394   std::vector<float> values;
00395   for(unsigned igsf=0;igsf<ngsf;++igsf)
00396     {
00397       reco::GsfTrackRef theTrackRef(gsfTracks, igsf);
00398       std::map<reco::GsfTrackRef,float>::const_iterator itcheck=gsfMvaMap_.find(theTrackRef);
00399       if(itcheck==gsfMvaMap_.end())
00400         {
00401           //      edm::LogWarning("PFElectronTranslator") << "MVA Map, missing GSF track ref " << std::endl;
00402           values.push_back(-99.);
00403           //      std::cout << " Push_back -99. " << std::endl;
00404         }
00405       else
00406         {
00407           //      std::cout <<  " Value " << itcheck->second << std::endl;
00408           values.push_back(itcheck->second);      
00409         }
00410     }
00411   filler.insert(gsfTracks,values.begin(),values.end());
00412 }
00413 
00414 
00415 void PFElectronTranslator::fillSCRefValueMap(edm::Event& iEvent, 
00416                                              edm::ValueMap<reco::SuperClusterRef>::Filler & filler) const
00417 {
00418   edm::Handle<reco::GsfTrackCollection> gsfTracks;
00419   fetchGsfCollection(gsfTracks,
00420                      inputTagGSFTracks_,
00421                      iEvent);
00422   unsigned ngsf=gsfTracks->size();
00423   std::vector<reco::SuperClusterRef> values;
00424   for(unsigned igsf=0;igsf<ngsf;++igsf)
00425     {
00426       reco::GsfTrackRef theTrackRef(gsfTracks, igsf);
00427       std::map<reco::GsfTrackRef,reco::SuperClusterRef>::const_iterator itcheck=scMap_.find(theTrackRef);
00428       if(itcheck==scMap_.end())
00429         {
00430           //      edm::LogWarning("PFElectronTranslator") << "SCRef Map, missing GSF track ref" << std::endl;
00431           values.push_back(reco::SuperClusterRef());
00432         }
00433       else
00434         {
00435           values.push_back(itcheck->second);      
00436         }
00437     }
00438   filler.insert(gsfTracks,values.begin(),values.end());
00439 }
00440 
00441 
00442 void PFElectronTranslator::createSuperClusters(const reco::PFCandidateCollection & pfCand,
00443                                                reco::SuperClusterCollection &superClusters) const
00444 {
00445   unsigned nGSF=GsfTrackRef_.size();
00446   for(unsigned iGSF=0;iGSF<nGSF;++iGSF)
00447     {
00448 
00449       // Computes energy position a la e/gamma 
00450       double sclusterE=0;
00451       double posX=0.;
00452       double posY=0.;
00453       double posZ=0.;
00454       
00455       unsigned nbasics=basicClusters_[iGSF].size();
00456       for(unsigned ibc=0;ibc<nbasics;++ibc)
00457         {
00458           double e = basicClusters_[iGSF][ibc].energy();
00459           sclusterE += e;
00460           posX += e * basicClusters_[iGSF][ibc].position().X();
00461           posY += e * basicClusters_[iGSF][ibc].position().Y();
00462           posZ += e * basicClusters_[iGSF][ibc].position().Z();   
00463         }
00464       posX /=sclusterE;
00465       posY /=sclusterE;
00466       posZ /=sclusterE;
00467       
00468       if(pfCand[gsfPFCandidateIndex_[iGSF]].gsfTrackRef()!=GsfTrackRef_[iGSF])
00469         {
00470           edm::LogError("PFElectronTranslator") << " Major problem in PFElectron Translator" << std::endl;
00471         }
00472       
00473       // compute the width
00474       PFClusterWidthAlgo pfwidth(pfClusters_[iGSF]);
00475       
00476       double correctedEnergy=pfCand[gsfPFCandidateIndex_[iGSF]].ecalEnergy();
00477       reco::SuperCluster mySuperCluster(correctedEnergy,math::XYZPoint(posX,posY,posZ));
00478       // protection against empty basic cluster collection ; the value is -2 in this case
00479       if(nbasics)
00480         {
00481 //        std::cout << "SuperCluster creation; energy " << pfCand[gsfPFCandidateIndex_[iGSF]].ecalEnergy();
00482 //        std::cout << " " <<   pfCand[gsfPFCandidateIndex_[iGSF]].rawEcalEnergy() << std::endl;
00483 //        std::cout << "Seed energy from basic " << basicClusters_[iGSF][0].energy() << std::endl;
00484           mySuperCluster.setSeed(basicClusterPtr_[iGSF][0]);
00485         }
00486       else
00487         {
00488           //      std::cout << "SuperCluster creation ; seed energy " << 0 << std::endl;
00489 //        std::cout << "SuperCluster creation ; energy " << pfCand[gsfPFCandidateIndex_[iGSF]].ecalEnergy();
00490 //        std::cout << " " <<   pfCand[gsfPFCandidateIndex_[iGSF]].rawEcalEnergy() << std::endl;
00491 //        std::cout << " No seed found " << 0 << std::endl;       
00492 //        std::cout << " MVA " << pfCand[gsfPFCandidateIndex_[iGSF]].mva_e_pi() << std::endl;
00493           mySuperCluster.setSeed(reco::CaloClusterPtr());
00494         }
00495       // the seed should be the first basic cluster
00496 
00497       for(unsigned ibc=0;ibc<nbasics;++ibc)
00498         {
00499           mySuperCluster.addCluster(basicClusterPtr_[iGSF][ibc]);
00500           //      std::cout <<"Adding Ref to SC " << basicClusterPtr_[iGSF][ibc].index() << std::endl;
00501           const std::vector< std::pair<DetId, float> > & v1 = basicClusters_[iGSF][ibc].hitsAndFractions();
00502           //      std::cout << " Number of cells " << v1.size() << std::endl;
00503           for( std::vector< std::pair<DetId, float> >::const_iterator diIt = v1.begin();
00504                diIt != v1.end();
00505                ++diIt ) {
00506             //      std::cout << " Adding DetId " << (diIt->first).rawId() << " " << diIt->second << std::endl;
00507             mySuperCluster.addHitAndFraction(diIt->first,diIt->second);
00508           } // loop over rechits      
00509         }      
00510 
00511       unsigned nps=preshowerClusterPtr_[iGSF].size();
00512       for(unsigned ips=0;ips<nps;++ips)
00513         {
00514           mySuperCluster.addPreshowerCluster(preshowerClusterPtr_[iGSF][ips]);
00515         }
00516       
00517 
00518       // Set the preshower energy
00519       mySuperCluster.setPreshowerEnergy(pfCand[gsfPFCandidateIndex_[iGSF]].pS1Energy()+
00520                                         pfCand[gsfPFCandidateIndex_[iGSF]].pS2Energy());
00521 
00522       // Set the cluster width
00523       mySuperCluster.setEtaWidth(pfwidth.pflowEtaWidth());
00524       mySuperCluster.setPhiWidth(pfwidth.pflowPhiWidth());
00525       // Force the computation of rawEnergy_ of the reco::SuperCluster
00526       mySuperCluster.rawEnergy();
00527       superClusters.push_back(mySuperCluster);
00528    }
00529 }
00530 
00531 
00532 const reco::PFCandidate & PFElectronTranslator::correspondingDaughterCandidate(const reco::PFCandidate & cand, const reco::PFBlockElement & pfbe) const
00533 {
00534   unsigned refindex=pfbe.index();
00535   //  std::cout << " N daughters " << cand.numberOfDaughters() << std::endl;
00536   reco::PFCandidate::const_iterator myDaughterCandidate=cand.begin();
00537   reco::PFCandidate::const_iterator itend=cand.end();
00538 
00539   for(;myDaughterCandidate!=itend;++myDaughterCandidate)
00540     {
00541       const reco::PFCandidate * myPFCandidate = (const reco::PFCandidate*)&*myDaughterCandidate;
00542       if(myPFCandidate->elementsInBlocks().size()!=1)
00543         {
00544           //      std::cout << " Daughter with " << myPFCandidate.elementsInBlocks().size()<< " element in block " << std::endl;
00545           return cand;
00546         }
00547       if(myPFCandidate->elementsInBlocks()[0].second==refindex) 
00548         {
00549           //      std::cout << " Found it " << cand << std::endl;
00550           return *myPFCandidate;
00551         }      
00552     }
00553   return cand;
00554 }
00555 
00556 void PFElectronTranslator::createGsfElectronCores(reco::GsfElectronCoreCollection & gsfElectronCores) const {
00557   unsigned nGSF=GsfTrackRef_.size();
00558   for(unsigned iGSF=0;iGSF<nGSF;++iGSF)
00559     {
00560       reco::GsfElectronCore myElectronCore(GsfTrackRef_[iGSF]);
00561       myElectronCore.setCtfTrack(kfTrackRef_[iGSF],-1.);
00562       std::map<reco::GsfTrackRef,reco::SuperClusterRef>::const_iterator 
00563         itcheck=scMap_.find(GsfTrackRef_[iGSF]);
00564       if(itcheck!=scMap_.end())
00565         myElectronCore.setPflowSuperCluster(itcheck->second);
00566       gsfElectronCores.push_back(myElectronCore);
00567     }
00568 }
00569 
00570 void PFElectronTranslator::createGsfElectronCoreRefs(const edm::OrphanHandle<reco::GsfElectronCoreCollection> & gsfElectronCoreHandle) {
00571   unsigned size=GsfTrackRef_.size();
00572   
00573   for(unsigned iGSF=0;iGSF<size;++iGSF) // loop on tracks
00574     {
00575       edm::Ref<reco::GsfElectronCoreCollection> elecCoreRef(gsfElectronCoreHandle,iGSF);
00576       gsfElectronCoreRefs_.push_back(elecCoreRef);
00577     }  
00578 }
00579 
00580 void PFElectronTranslator::getAmbiguousGsfTracks(const reco::PFBlockElement & PFBE, std::vector<reco::GsfTrackRef>& tracks) const {
00581   const reco::PFBlockElementGsfTrack *  GsfEl =  dynamic_cast<const reco::PFBlockElementGsfTrack*>(&PFBE);
00582   if(GsfEl==0) return;
00583   const std::vector<reco::GsfPFRecTrackRef>& ambPFRecTracks(GsfEl->GsftrackRefPF()->convBremGsfPFRecTrackRef());
00584   unsigned ntracks=ambPFRecTracks.size();
00585   for(unsigned it=0;it<ntracks;++it) {
00586     tracks.push_back(ambPFRecTracks[it]->gsfTrackRef());
00587   }
00588 }
00589 
00590 
00591 void PFElectronTranslator::createGsfElectrons(const reco::PFCandidateCollection & pfcand, 
00592                                               const IsolationValueMaps& isolationValues,
00593                                               reco::GsfElectronCollection &gsfelectrons) {
00594   unsigned size=GsfTrackRef_.size();
00595   
00596   for(unsigned iGSF=0;iGSF<size;++iGSF) // loop on tracks
00597     {
00598       const reco::PFCandidate& pfCandidate(pfcand[gsfPFCandidateIndex_[iGSF]]);
00599       // Electron
00600       reco::GsfElectron myElectron(gsfElectronCoreRefs_[iGSF]);
00601       // Warning set p4 error ! 
00602       myElectron.setP4(reco::GsfElectron::P4_PFLOW_COMBINATION, pfCandidate.p4(),pfCandidate.deltaP(), true);
00603       
00604       // MVA inputs
00605       reco::GsfElectron::MvaInput myMvaInput;
00606       myMvaInput.earlyBrem = pfCandidate.electronExtraRef()->mvaVariable(reco::PFCandidateElectronExtra::MVA_FirstBrem);
00607       myMvaInput.lateBrem = pfCandidate.electronExtraRef()->mvaVariable(reco::PFCandidateElectronExtra::MVA_LateBrem);
00608       myMvaInput.deltaEta = pfCandidate.electronExtraRef()->mvaVariable(reco::PFCandidateElectronExtra::MVA_DeltaEtaTrackCluster);
00609       myMvaInput.sigmaEtaEta = pfCandidate.electronExtraRef()->sigmaEtaEta();
00610       myMvaInput.hadEnergy = pfCandidate.electronExtraRef()->hadEnergy();
00611 
00612       // Mustache
00613       reco::Mustache myMustache;
00614       myMustache.MustacheID(*(myElectron. pflowSuperCluster()), myMvaInput.nClusterOutsideMustache, myMvaInput.etOutsideMustache );
00615 
00616       myElectron.setMvaInput(myMvaInput);
00617 
00618       // MVA output
00619       reco::GsfElectron::MvaOutput myMvaOutput;
00620       myMvaOutput.status = pfCandidate.electronExtraRef()->electronStatus();
00621       myMvaOutput.mva = pfCandidate.mva_e_pi();
00622       myElectron.setMvaOutput(myMvaOutput);
00623       
00624       // ambiguous tracks
00625       unsigned ntracks=ambiguousGsfTracks_[iGSF].size();
00626       for(unsigned it=0;it<ntracks;++it) {
00627         myElectron.addAmbiguousGsfTrack(ambiguousGsfTracks_[iGSF][it]);
00628       }
00629 
00630       // isolation
00631       if( isolationValues.size() != 0 ) {
00632         reco::GsfElectron::PflowIsolationVariables myPFIso;
00633         myPFIso.chargedHadronIso=(*isolationValues[0])[CandidatePtr_[iGSF]];
00634         myPFIso.photonIso=(*isolationValues[1])[CandidatePtr_[iGSF]];
00635         myPFIso.neutralHadronIso=(*isolationValues[2])[CandidatePtr_[iGSF]];      
00636         myElectron.setPfIsolationVariables(myPFIso);
00637       }
00638 
00639       gsfelectrons.push_back(myElectron);
00640     }
00641 
00642 }
00643 
00644