CMS 3D CMS Logo

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