CMS 3D CMS Logo

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