CMS 3D CMS Logo

PFElectronAlgo.cc

Go to the documentation of this file.
00001 //
00002 // Original Author: Daniele Benedetti: daniele.benedetti@cern.ch
00003 //
00004 
00005 #include "RecoParticleFlow/PFAlgo/interface/PFElectronAlgo.h"
00006 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementGsfTrack.h"
00007 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementCluster.h"
00008 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementBrem.h"
00009 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFraction.h"
00010 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" 
00011 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00012 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00013 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00014 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
00015 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00016 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyResolution.h"
00017 
00018 using namespace std;
00019 using namespace reco;
00020 PFElectronAlgo::PFElectronAlgo(const std::vector<double> chi2values,
00021                                const double mvaEleCut,
00022                                string mvaWeightFileEleID):
00023   chi2values_(chi2values),
00024   mvaEleCut_(mvaEleCut)
00025 {
00026   // Set the tmva reader
00027   tmvaReader_ = new TMVA::Reader();
00028   tmvaReader_->AddVariable("TEtotPinMode",&TEtotPinMode);
00029   tmvaReader_->AddVariable("TEGsfPoutMode",&TEGsfPoutMode);
00030   tmvaReader_->AddVariable("TDiffEtaGSFEcalEle",&TDiffEtaGSFEcalEle);
00031   tmvaReader_->AddVariable("log(TSigmaEtaEtaEle)",&TSigmaEtaEtaEle);
00032   tmvaReader_->AddVariable("TChiEcalEle",&TChiEcalEle);
00033   tmvaReader_->AddVariable("TNumBrem",&TNumBrem);
00034   tmvaReader_->AddVariable("TSumEBremPinPoutMode",&TSumEBremPinPoutMode);
00035   tmvaReader_->AddVariable("TLateBrem",&TLateBrem);
00036   tmvaReader_->AddVariable("TEarlyBrem",&TEarlyBrem);
00037   tmvaReader_->BookMVA("BDT",mvaWeightFileEleID.c_str());
00038 }
00039 void PFElectronAlgo::RunPFElectron(const reco::PFBlockRef&  blockRef,
00040                                    std::vector<bool>& active){
00041   // General note: all the cout will be removed. 
00042 
00043   // the maps are initialized 
00044   AssMap associatedToGSF(0);
00045   AssMap associatedToBrems(0);
00046   // this function fill the previous maps: gsf and associated elements
00047   // and brem and associated elements
00048   // To be noted: for the moment the function FindClosestElement is based
00049   // only on geometrical link (by chi2) but Jonathan is working on a 
00050   // geometrical + energetic link, see presentation:
00051   // https://indico.cern.ch/getFile.py/access?contribId=0&resId=1&materialId=slides&confId=33548
00052 
00053   
00054   GsfTrackSingleEcal_.clear();
00055   GsfTrackSingleEcal_ = active;
00056   MultipleGsfTrackAssociation(blockRef);
00057 
00058   bool blockHasGSF = SetLinks(blockRef,associatedToGSF,associatedToBrems,active);
00059   
00060   if (blockHasGSF) {
00061     // If at least a gsf pre-id track has been connected to an ecal cluster
00062     // is run the electron - ID
00063     // When will have also pure tracking-ID this will be removed. 
00064     
00065     BDToutput_.clear();
00066     // For each GSF track is initialized a BDT value = -1
00067     BDToutput_.assign(associatedToGSF.size(),-1.);
00068     
00069     // The FinalID is run and BDToutput is internally changed. 
00070     SetIDOutputs(blockRef,associatedToGSF,associatedToBrems);  
00071     elCandidate_.clear();
00072     // For each GSF track that pass the BDT configurable cut is run the setcandidates.
00073     // This function computed the initial electron 4-momentum and fill the vector 
00074     // of pf candidates
00075     SetCandidates(blockRef,associatedToGSF,associatedToBrems);
00076     if (elCandidate_.size() > 0 ){
00077       isvalid_ = true;
00078       // if there is at least a candidate the active vector is modified
00079       // setting = false all the elements used to build the candidate
00080       SetActive(blockRef,associatedToGSF,associatedToBrems,active);
00081       }
00082   } // endif blockHasGSF
00083 }
00084 // For the moment this function just get the closest element by chi2: 
00085 // in future the link could be geometrical + energetic so it is good to have
00086 // this separated function
00087 uint PFElectronAlgo::FindClosestElement(const uint iele,
00088                                         std::multimap<double, unsigned>& Elems, 
00089                                         float& chi2cut,
00090                                         std::vector<bool>& active,
00091                                         const reco::PFBlockRef&  blockRef) {
00092   
00093   const reco::PFBlock& block = *blockRef;
00094   PFBlock::LinkData linkData =  block.linkData();     
00095   uint FoundIndex = 100000;
00096   if (Elems.size() > 0) {
00097     std::multimap<double, unsigned>::iterator ie = Elems.begin();
00098     // float chi2  = ie->first;
00099     uint index = ie->second;
00100     float chi2 =  block.chi2(iele,index,linkData);
00101     if (chi2 < chi2cut && active[index] == true) {
00102       chi2cut = chi2;
00103       FoundIndex = index;
00104     }
00105   }
00106   return FoundIndex;
00107 }
00108 // Like FindClosestElement, but check if the cluster has been alredy associated 
00109 // to the gsf track. It needs to understand if there is a late brems
00110 uint PFElectronAlgo::FindClosestElementCond(const uint iele,
00111                                             std::multimap<double, unsigned>& Elems, 
00112                                             float& chi2cut,float chi2Comp, 
00113                                             uint indexComp,
00114                                             std::vector<bool>& active,
00115                                             const reco::PFBlockRef&  blockRef) {
00116   const reco::PFBlock& block = *blockRef;
00117   PFBlock::LinkData linkData =  block.linkData();     
00118   uint FoundIndex = 100000;
00119   for(std::multimap<double, unsigned>::iterator ie = Elems.begin(); ie != Elems.end(); ++ie ) {
00120     if (ie->second == indexComp && (ie->first + 5.) > chi2Comp) continue; 
00121     //    double   chi2  = ie->first;
00122     unsigned index = ie->second;
00123     float chi2 =  block.chi2(iele,index,linkData);
00124     if (chi2 < chi2cut && active[index] == true ) {
00125       chi2cut = chi2;
00126       FoundIndex = index;
00127     }
00128     break;
00129   }
00130   return FoundIndex;
00131 }
00132 // Solve the double counting: for each brem the closest ecal cluster is found.
00133 // If an ecal cluster has been associated to several brems the closest is chosen. 
00134 bool PFElectronAlgo::findLinkPairs(const vector< pair<unsigned, double> >& MinRow , 
00135                                    const vector<unsigned>& brem_it, 
00136                                    const vector<unsigned>& clust_it, 
00137                                    map<unsigned, unsigned>& finallink, 
00138                                    float chi2cut){
00139 
00140 
00141   if (MinRow.size() >0 ) {
00142 
00143     for (unsigned i1=0; i1< clust_it.size(); i1++) {
00144       double final_chi2 = chi2cut;  
00145       unsigned final_brem_index = 100000;
00146       unsigned final_ecal_index = 100000;      
00147       for(unsigned i2=0;i2<MinRow.size();i2++) {
00148         if (MinRow[i2].first == clust_it[i1]) {
00149           if (MinRow[i2].second < final_chi2) {
00150             final_chi2 = MinRow[i2].second;
00151             final_brem_index = brem_it[i2];
00152             final_ecal_index = clust_it[i1];
00153           }
00154         }
00155       }
00156       if (final_chi2 < chi2cut) {  
00157         finallink.insert(make_pair(final_brem_index,final_ecal_index));
00158       }
00159     }
00160     if (finallink.size() > 0)  return true;
00161     else return false;
00162   }
00163   else {
00164     return false;
00165   }
00166 }
00167 // The maps associatedToGSF and associatedToBrems are filled. 
00168 void PFElectronAlgo::MultipleGsfTrackAssociation(const reco::PFBlockRef&  blockRef){
00169   
00170 
00171   const reco::PFBlock& block = *blockRef;
00172   const edm::OwnVector< reco::PFBlockElement >&  elements = block.elements();
00173   PFBlock::LinkData linkData =  block.linkData(); 
00174   for(unsigned iEle=0; iEle<elements.size(); iEle++) {    
00175     PFBlockElement::Type type = elements[iEle].type();
00176     if (type == reco::PFBlockElement::ECAL ) {
00177       std::multimap<double, unsigned> gsfTrack;
00178       block.associatedElements( iEle,  linkData,
00179                                 gsfTrack ,
00180                                 reco::PFBlockElement::GSF,
00181                                 reco::PFBlock::LINKTEST_ALL );
00182       if (gsfTrack.size() > 1.) {
00183         for(std::multimap<double, unsigned>::iterator ie = gsfTrack.begin(); 
00184             ie != gsfTrack.end(); ++ie ) {
00185           unsigned index_gsf = ie->second;
00186           GsfTrackSingleEcal_[index_gsf] = false;
00187         }
00188       }
00189     }
00190   }
00191   return;
00192 }
00193 // The maps associatedToGSF and associatedToBrems are filled. 
00194 bool PFElectronAlgo::SetLinks(const reco::PFBlockRef&  blockRef,
00195                               AssMap& associatedToGSF_,
00196                               AssMap& associatedToBrems_,
00197                               std::vector<bool>& active){
00198   uint CutIndex = 100000;
00199   double CutGSFECAL = chi2values_[0] ;   // Standard Value should be 900 
00200   double CutBremECAL = chi2values_[1];   // Standard Value should be 25
00201   double CutGSFHCAL = chi2values_[2];    // Standard Value sould be 100, to be studied
00202   double CutBremHCAL = chi2values_[3];   // Standard Value sould be 25, to be studied
00203   double CutGSFPS = chi2values_[4];      // Standard Value sould be 100, to be studied
00204   double CutBremPS = chi2values_[5];     // Standard Value sould be 25, to be studied
00205   bool DebugSetLinks = false;
00206   
00207   const reco::PFBlock& block = *blockRef;
00208   const edm::OwnVector< reco::PFBlockElement >&  elements = block.elements();
00209   PFBlock::LinkData linkData =  block.linkData();  
00210   
00211   bool IsThereAGSFTrack = false;
00212   for(unsigned iEle=0; iEle<elements.size(); iEle++) {
00213      
00214      std::map<unsigned, unsigned> FinalBremECALIndex;
00215      std::map<unsigned, unsigned> FinalBremHCALIndex; 
00216      std::map<unsigned, unsigned> FinalBremPS1Index;  
00217      std::map<unsigned, unsigned> FinalBremPS2Index;  
00218      unsigned ECALGSF_index = CutIndex;
00219      unsigned GSF_index = CutIndex;
00220      unsigned KFGSF_index = CutIndex;
00221      unsigned HCALGSF_index = CutIndex;
00222      unsigned PS1GSF_index = CutIndex;
00223      unsigned PS2GSF_index = CutIndex;
00224 
00225      PFBlockElement::Type type = elements[iEle].type();
00226      if (type == reco::PFBlockElement::GSF ) {
00227        IsThereAGSFTrack = true;
00228        GSF_index = iEle;
00229 
00230        if (!active[iEle]) continue;  // not use if locked by muons
00231        if (DebugSetLinks) cout << "PFElectron:: The Block " << block << endl;
00232        // Stop if more GSF tracks are associated to the same clusters.
00233        // to be modified in the future. 
00234        if(!GsfTrackSingleEcal_[iEle]) continue;
00235        
00236 
00237        // Search for elements associated to the GSF track
00238        // Find Associated KF Tracks
00239        std::multimap<double, unsigned> kfTrack;
00240        block.associatedElements( iEle,  linkData,
00241                                  kfTrack ,
00242                                  reco::PFBlockElement::TRACK,
00243                                  reco::PFBlock::LINKTEST_ALL );
00244        if (kfTrack.size() > 0) {
00245          multimap<double, unsigned>::iterator itkf = kfTrack.begin();
00246          KFGSF_index = itkf->second;
00247        }
00248 
00249 
00250        // Find Associated ECAL Clusters
00251        std::multimap<double, unsigned> ecalElems;
00252        block.associatedElements( iEle,  linkData,
00253                                  ecalElems ,
00254                                  reco::PFBlockElement::ECAL,
00255                                  reco::PFBlock::LINKTEST_ALL );     
00256        float chi2ECALGSFFinal = CutGSFECAL;   
00257        ECALGSF_index = FindClosestElement(iEle,ecalElems,
00258                                           chi2ECALGSFFinal,
00259                                           active,blockRef);
00260    
00261        if (DebugSetLinks) {
00262          if (ecalElems.size() > 0) {
00263            cout << "PFElectron:: ECALGSF_index " << ECALGSF_index  << " chi2 " << chi2ECALGSFFinal << endl;
00264          }
00265          else {
00266            cout << "PFElectron:: No Link! " << endl;
00267          }
00268        }
00269 
00270        // Find Associated HCAL Clusters
00271        std::multimap<double, unsigned> hcalElems;
00272        block.associatedElements( iEle,  linkData,
00273                                  hcalElems ,
00274                                  reco::PFBlockElement::HCAL,
00275                                  reco::PFBlock::LINKTEST_ALL );     
00276        float chi2HCALGSFFinal = CutGSFHCAL;
00277        HCALGSF_index = FindClosestElement(iEle,hcalElems,
00278                                           chi2HCALGSFFinal,
00279                                           active,blockRef);
00280        
00281        
00282        // Find Associated PS1 Clusters
00283        std::multimap<double, unsigned> ps1Elems;
00284        block.associatedElements( iEle,  linkData,
00285                                  ps1Elems ,
00286                                  reco::PFBlockElement::PS1,
00287                                  reco::PFBlock::LINKTEST_ALL );     
00288        float chi2PS1GSFFinal = CutGSFPS;
00289        PS1GSF_index = FindClosestElement(iEle,ps1Elems,
00290                                          chi2PS1GSFFinal,
00291                                          active,blockRef);
00292        
00293        
00294        // Find Associated PS2 Clusters
00295        std::multimap<double, unsigned> ps2Elems;
00296        block.associatedElements( iEle,  linkData,
00297                                  ps2Elems ,
00298                                  reco::PFBlockElement::PS1,
00299                                  reco::PFBlock::LINKTEST_ALL );     
00300        float chi2PS2GSFFinal = CutGSFPS;
00301        PS2GSF_index = FindClosestElement(iEle,ps2Elems,
00302                                          chi2PS2GSFFinal,
00303                                          active,blockRef); 
00304        // End First Part Search for elements associated to the GSF track
00305        
00306        
00307        // Second Part search for brems and elements associated to the brems 
00308        std::multimap<double, unsigned> Brems;
00309        
00310        block.associatedElements( iEle,  linkData,
00311                                  Brems ,
00312                                  reco::PFBlockElement::BREM,
00313                                  reco::PFBlock::LINKTEST_ALL );
00314        
00315        
00316 
00317        vector<unsigned> brems_index(0);
00318        vector<unsigned> mainecal_index(0);
00319        vector< pair<unsigned, double> >  BremEcal(0);
00320  
00321        for(std::multimap<double, unsigned>::iterator ieb = Brems.begin(); 
00322            ieb != Brems.end(); ++ieb ) {
00323          
00324          
00325          // ECAL associated to the brems
00326          unsigned index_brem = ieb->second;
00327          if (DebugSetLinks) cout << "PFElectron:: index brem " << index_brem  << endl; 
00328 
00329          std::multimap<double, unsigned> ecalBremsElems;
00330          block.associatedElements( index_brem,  linkData,
00331                                    ecalBremsElems,
00332                                    reco::PFBlockElement::ECAL,
00333                                    reco::PFBlock::LINKTEST_ALL );
00334          float chi2EcalBremFinal = CutBremECAL;
00335          unsigned ECALBREM_index = FindClosestElementCond(index_brem,ecalBremsElems,chi2EcalBremFinal,
00336                                                           chi2ECALGSFFinal,ECALGSF_index,
00337                                                           active,blockRef);
00338          
00339          if (ECALBREM_index < CutIndex){          
00340            bool NonAlreadyAss = true;
00341            if (BremEcal.size() > 0) {
00342              for (uint ieb = 0; ieb < BremEcal.size(); ieb++){
00343                if (ECALBREM_index == BremEcal[ieb].first) {
00344                  NonAlreadyAss = false;
00345                  break;
00346                }
00347              }
00348            }
00349            BremEcal.push_back(make_pair(ECALBREM_index,chi2EcalBremFinal));
00350            brems_index.push_back(index_brem);
00351            if (NonAlreadyAss) mainecal_index.push_back(ECALBREM_index);
00352          }
00353        }
00354        
00355        // This solves the possible double counting for ecal clusters associated to brems. 
00356        bool foundEcalLink = findLinkPairs(BremEcal,brems_index,mainecal_index, 
00357                                           FinalBremECALIndex,CutBremECAL);
00358        
00359        
00360        vector<unsigned> element_brems(0);
00361        if (foundEcalLink) {
00362          for (map<unsigned, unsigned>::iterator it = FinalBremECALIndex.begin(); 
00363               it != FinalBremECALIndex.end(); ++it ) {
00364            unsigned index_bremassoecal = it->first;
00365            element_brems.push_back(index_bremassoecal);
00366            
00367             if (DebugSetLinks) cout <<  "PFElectron:: linked index brem " << it->first  
00368                                     <<" index ecal " << it->second << endl; 
00369 
00370            // HCAL associated to the brems
00371            std::multimap<double, unsigned> hcalBrems;
00372            block.associatedElements( index_bremassoecal,  linkData,
00373                                      hcalBrems ,
00374                                      reco::PFBlockElement::HCAL,
00375                                      reco::PFBlock::LINKTEST_ALL );
00376            float chi2HcalBremFinal = CutBremHCAL;
00377            unsigned HCALBREM_index = FindClosestElementCond(index_bremassoecal,hcalBrems,chi2HcalBremFinal,
00378                                                             chi2HCALGSFFinal,HCALGSF_index,
00379                                                             active,blockRef);
00380            if (chi2HcalBremFinal < CutBremHCAL) 
00381              FinalBremHCALIndex.insert(make_pair(index_bremassoecal,HCALBREM_index));
00382            
00383            
00384 
00385            // PS1 associated to the brems
00386            std::multimap<double, unsigned> PS1Brems;
00387            block.associatedElements( index_bremassoecal,  linkData,
00388                                      PS1Brems ,
00389                                      reco::PFBlockElement::PS1,
00390                                      reco::PFBlock::LINKTEST_ALL );
00391            float chi2PS1BremFinal = CutBremPS;
00392            unsigned PS1BREM_index  = FindClosestElementCond(index_bremassoecal,PS1Brems,chi2PS1BremFinal,
00393                                                             chi2PS1GSFFinal,PS1GSF_index,
00394                                                             active,blockRef);
00395            if (chi2PS1BremFinal < CutBremPS) 
00396              FinalBremPS1Index.insert(make_pair(index_bremassoecal,PS1BREM_index));
00397            
00398            
00399 
00400            // PS2 associated to the brems
00401            std::multimap<double, unsigned> PS2Brems;
00402            block.associatedElements( index_bremassoecal,  linkData,
00403                                      PS2Brems ,
00404                                      reco::PFBlockElement::PS2,
00405                                      reco::PFBlock::LINKTEST_ALL );
00406            float chi2PS2BremFinal = CutBremPS;
00407            unsigned PS2BREM_index = FindClosestElementCond(index_bremassoecal,PS2Brems,chi2PS2BremFinal,
00408                                                            chi2PS2GSFFinal,PS2GSF_index,
00409                                                            active,blockRef);
00410            if (chi2PS2BremFinal < CutBremPS) 
00411              FinalBremPS2Index.insert(make_pair(index_bremassoecal,PS2BREM_index));
00412          }
00413        }
00414        
00415             
00416        // Save an AssMap with elements associated to the brem track
00417        // Note the order is important in setCandidate and setIDOutput 
00418        vector<unsigned> assoel(0);
00419        if (KFGSF_index < CutIndex) assoel.push_back(KFGSF_index);
00420        if (PS1GSF_index  < CutIndex) assoel.push_back(PS1GSF_index);
00421        if (PS2GSF_index  < CutIndex) assoel.push_back(PS2GSF_index);
00422        if (ECALGSF_index < CutIndex)  assoel.push_back(ECALGSF_index); 
00423        if (HCALGSF_index < CutIndex) assoel.push_back(HCALGSF_index);
00424   
00425        for (map<unsigned, unsigned>::iterator it = FinalBremECALIndex.begin(); 
00426             it != FinalBremECALIndex.end(); ++it ) {
00427          unsigned index_brem = it->first;
00428          assoel.push_back(index_brem);
00429        }
00430        associatedToGSF_.push_back(make_pair(GSF_index,assoel));
00431        
00432        // Save an AssMap with elements associated to the brem track
00433        // Note the order is important in setCandidate and setIDOutput 
00434        bool DebugBrem = false;
00435        for(unsigned iBrem=0; iBrem<element_brems.size(); iBrem++) {
00436          vector<unsigned> assobrem(0);
00437          for (map<unsigned, unsigned>::iterator it = FinalBremPS1Index.begin(); 
00438               it != FinalBremPS1Index.end(); ++it ) {
00439            if (it->first == element_brems[iBrem]) {
00440              unsigned index_clus = it->second;
00441              assobrem.push_back(index_clus);
00442              if(DebugBrem) cout << " In associate BREM " <<  element_brems[iBrem] 
00443                                 << " PS1 Cluster Associated to BREM " 
00444                                 <<  index_clus << endl;
00445            }
00446          }
00447          for (map<unsigned, unsigned>::iterator it = FinalBremPS2Index.begin(); 
00448               it != FinalBremPS2Index.end(); ++it ) {
00449            if (it->first == element_brems[iBrem]) {
00450              unsigned index_clus = it->second;
00451              assobrem.push_back(index_clus);
00452              if(DebugBrem) cout << " In associate BREM " <<  element_brems[iBrem] 
00453                                 << " PS2 Cluster Associated to BREM " 
00454                                 <<  index_clus << endl;
00455            }
00456          }
00457 
00458          for (map<unsigned, unsigned>::iterator it = FinalBremECALIndex.begin(); 
00459               it != FinalBremECALIndex.end(); ++it ) {
00460            if (it->first == element_brems[iBrem]) {
00461              unsigned index_clus = it->second;
00462              assobrem.push_back(index_clus);
00463              // if(ev == 1957) 
00464              if(DebugBrem) cout << " In associate BREM " <<  element_brems[iBrem] 
00465                                 << " ECAL Cluster Associated to BREM " 
00466                                 <<  index_clus << endl;
00467            }
00468          }
00469          for (map<unsigned, unsigned>::iterator it = FinalBremHCALIndex.begin(); 
00470               it != FinalBremHCALIndex.end(); ++it ) {
00471            if (it->first == element_brems[iBrem]) {
00472              unsigned index_clus = it->second;
00473              assobrem.push_back(index_clus);
00474              if(DebugBrem) cout << " In associate BREM " <<  element_brems[iBrem] 
00475                                 << " HCAL Cluster Associated to BREM " 
00476                                 <<  index_clus << endl;
00477            }
00478          }
00479          associatedToBrems_.push_back(make_pair(element_brems[iBrem],assobrem));
00480        } // End Loop On Brems for GSF track               
00481      }// end type GSF
00482   }// End Loop on Block's element
00483 
00484   return IsThereAGSFTrack;
00485 }
00486 // This function get the associatedToGSF and associatedToBrems maps and run the final electronID. 
00487 void PFElectronAlgo::SetIDOutputs(const reco::PFBlockRef&  blockRef,
00488                                   const AssMap& associatedToGSF_,
00489                                   const AssMap& associatedToBrems_){
00490   PFEnergyCalibration pfcalib_;
00491   const reco::PFBlock& block = *blockRef;
00492   PFBlock::LinkData linkData =  block.linkData();     
00493   const edm::OwnVector< reco::PFBlockElement >&  elements = block.elements();
00494  
00495   for (uint igsf = 0; igsf<associatedToGSF_.size();igsf++) {
00496     uint index_gsf =  associatedToGSF_[igsf].first;
00497     PFBlockElement::Type typegsf = elements[index_gsf].type();
00498 
00499     // Find position in the ECAl surface
00500 
00501     double GSF_Ein   = 0.;
00502     double GSF_Eout  = 0.;
00503     double GSF_etaout = 0.;
00504 
00505     bool DebugIDOutputs = false;
00506 
00507     if (typegsf == reco::PFBlockElement::GSF) {  // Just to be sure, but not needed
00508       const reco::PFBlockElementGsfTrack * GsfEl  =  
00509         dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[index_gsf]));
00510       math::XYZTLorentzVector p_out = GsfEl->Pout();  // can be mode or mean: see config file xyz
00511 
00512       GSF_Eout = p_out.t();
00513     
00514       reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
00515       if (RefGSF.isNonnull()) {
00516         float m_el=0.00051;
00517         GSF_Ein = sqrt(RefGSF->pMode()*
00518                        RefGSF->pMode()+m_el*m_el);
00519       }
00520 
00521       // Gsfouter position on the ECAL surface
00522       const math::XYZPointF& PosEcal = GsfEl->positionAtECALEntrance();
00523       GSF_etaout = PosEcal.eta();
00524  
00525       if (DebugIDOutputs)  cout << " setIdOutput! GSF Track " << GSF_Ein  
00526                                 << " ECAL eta,phi " << GSF_etaout   
00527                                 <<", " << PosEcal.phi() << endl;
00528     } // End if typegsf == GSF
00529     
00530     
00531     vector<uint> index_assogsf =  associatedToGSF_[igsf].second;
00532 
00533     double GSFClus_energy = 0.;
00534     double Sigmaetaeta = 0.;
00535     double DiffEtaGSFClust = 0.;
00536     unsigned GSFClus_index = 100000;
00537     double chi2GSFECAL = 0.;
00538     double Tot_BremClustEne = 0.;
00539     bool LateBrem = false;
00540     bool EarlyBrem = false;
00541     int NumBrem = 0;
00542     
00543     // The final Observables are build starting from the gsf and brem maps 
00544 
00545     for  (unsigned ielegsf=0;ielegsf<index_assogsf.size();ielegsf++) {
00546       PFBlockElement::Type typeassoele = elements[(index_assogsf[ielegsf])].type();
00547       vector<double> ps1Ene(0);
00548       vector<double> ps2Ene(0);
00549       // Important is the PS clusters are not saved before the ecal one, these
00550       // energy are not correctly assigned 
00551       // For the moment I get only the closest PS clusters: this has to be changed
00552       if  (typeassoele == reco::PFBlockElement::PS1) {  
00553         PFClusterRef  psref = elements[(index_assogsf[ielegsf])].clusterRef();
00554         ps1Ene.push_back(psref->energy());
00555       }
00556       if  (typeassoele == reco::PFBlockElement::PS2) {  
00557         PFClusterRef  psref = elements[(index_assogsf[ielegsf])].clusterRef();
00558         ps2Ene.push_back(psref->energy());
00559       }
00560       if  (typeassoele == reco::PFBlockElement::ECAL) {
00561         GSFClus_index = index_assogsf[ielegsf];
00562         reco::PFClusterRef clusterRef = elements[(index_assogsf[ielegsf])].clusterRef();
00563         //GSFClus_energy = clusterRef->energy();
00564         GSFClus_energy = pfcalib_.energyEm(*clusterRef,ps1Ene,ps2Ene);
00565 
00566         chi2GSFECAL = block.chi2(index_gsf,index_assogsf[ielegsf],linkData);
00567         double GSFClus_eta = clusterRef->position().eta();
00568         if (DebugIDOutputs)  cout << " setIdOutput! GSF ECAL Cluster E " << GSFClus_energy
00569                                   << " eta,phi " << GSFClus_eta
00570                                   <<", " <<  clusterRef->position().phi() << endl;
00571 
00572         DiffEtaGSFClust = GSFClus_eta - GSF_etaout;
00573 
00574         const vector< reco::PFRecHitFraction >& PFRecHits =  clusterRef->recHitFractions();
00575         double SeedClusEnergy = -1.;
00576         unsigned SeedDetID = 0;
00577         double SeedEta = -1.;
00578         double SeedPhi = -1.;
00579         for ( vector< reco::PFRecHitFraction >::const_iterator it = PFRecHits.begin(); 
00580               it != PFRecHits.end(); ++it) {
00581           const PFRecHitRef& RefPFRecHit = it->recHitRef(); 
00582           double energyRecHit = RefPFRecHit->energy();
00583           if (energyRecHit > SeedClusEnergy) {
00584             SeedClusEnergy = energyRecHit;
00585             SeedEta = RefPFRecHit->position().eta();
00586             SeedPhi =  RefPFRecHit->position().phi();
00587             SeedDetID = RefPFRecHit->detId();
00588           }
00589         }
00590         
00591         for ( vector< reco::PFRecHitFraction >::const_iterator it = PFRecHits.begin(); 
00592               it != PFRecHits.end(); ++it) {
00593           
00594           const PFRecHitRef& RefPFRecHit = it->recHitRef(); 
00595           double energyRecHit = RefPFRecHit->energy();
00596           if (RefPFRecHit->detId() != SeedDetID) {
00597             float diffEta =  RefPFRecHit->position().eta() - SeedEta;
00598             Sigmaetaeta += (diffEta*diffEta) * (energyRecHit/SeedClusEnergy);
00599           }
00600         }
00601         if (Sigmaetaeta == 0.) Sigmaetaeta = 0.00000001;
00602       } // End if on ECAL element
00603       // Add Preshower info for the GSF-PS-ECAL FinalID
00604 
00605       if  (typeassoele == reco::PFBlockElement::BREM) {
00606         for (uint ibrem = 0; ibrem < associatedToBrems_.size(); ibrem++){
00607           vector<unsigned> index_assobrem = (associatedToBrems_[ibrem]).second;
00608           unsigned index_brem = (associatedToBrems_[ibrem]).first;        
00609           if (index_brem == index_assogsf[ielegsf]) {   // Note: important: check that 
00610             // brem emission is from the considered gsf track
00611             const reco::PFBlockElementBrem * BremEl  =  
00612               dynamic_cast<const reco::PFBlockElementBrem*>((&elements[index_brem]));
00613             unsigned BremTrajP = BremEl->indTrajPoint();
00614             unsigned TrajPos = BremTrajP-2;
00615 //          double BremDP = (BremEl->DeltaP())*(-1.); // not used yet
00616 //          double BremSDP = BremEl->SigmaDeltaP(); // not used yet
00617             if (TrajPos <= 3) EarlyBrem = true;
00618             for (unsigned ielebrem=0;ielebrem<index_assobrem.size();ielebrem++) {
00619               vector<double> ps1EneFromBrem(0);
00620               vector<double> ps2EneFromBrem(0);
00621               // Important is the PS clusters are not saved before the ecal one, these
00622               // energy are not correctly assigned 
00623               // For the moment I get only the closest PS clusters: this has to be changed
00624               if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::PS1) {
00625                 PFClusterRef  psref = elements[(index_assobrem[ielebrem])].clusterRef();
00626                 ps1EneFromBrem.push_back(psref->energy());
00627               }
00628               if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::PS2) {
00629                 PFClusterRef  psref = elements[(index_assobrem[ielebrem])].clusterRef();
00630                 ps2EneFromBrem.push_back(psref->energy());
00631               }        
00632               if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::ECAL) {
00633                 // check if it is a compatible cluster also with the gsf track
00634                 if( index_assobrem[ielebrem] !=  GSFClus_index) {
00635                   reco::PFClusterRef clusterRef = 
00636                     elements[(index_assobrem[ielebrem])].clusterRef();
00637                   //double BremClus_energy = clusterRef->energy();
00638                   double BremClus_energy = 
00639                     pfcalib_.energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem);
00640                   double chi2BREMECAL = 
00641                     block.chi2(index_brem,(index_assobrem[ielebrem]),linkData);
00642                    if (DebugIDOutputs) cout << " setIdOutput:: GSF BREM Cluster " 
00643                                             <<  BremClus_energy << " eta,phi " 
00644                                             <<  clusterRef->position().eta()  <<", " 
00645                                             << clusterRef->position().phi() 
00646                                             << " chi " << sqrt(chi2BREMECAL) << endl;
00647                   Tot_BremClustEne += BremClus_energy;
00648                   NumBrem++;
00649                 }
00650                 else LateBrem = true;
00651               }
00652             }
00653           }       
00654         }
00655       } // End if on BREM elements
00656     } // End Loop on GSF elements
00657     if (GSFClus_energy > 0.) {
00658       TEtotPinMode        =  (GSFClus_energy + Tot_BremClustEne) / GSF_Ein;  
00659       if (TEtotPinMode > 5.) TEtotPinMode = 5.;
00660       TEGsfPoutMode       =  GSFClus_energy/GSF_Eout;
00661       if (TEGsfPoutMode > 5.) TEGsfPoutMode = 5.;
00662       TDiffEtaGSFEcalEle  = fabs(DiffEtaGSFClust);
00663       if (TDiffEtaGSFEcalEle > 0.2)  TDiffEtaGSFEcalEle = 0.2;
00664       TSigmaEtaEtaEle     = Sigmaetaeta;
00665       if (TSigmaEtaEtaEle > 0.05) TSigmaEtaEtaEle = 0.05;
00666       TSigmaEtaEtaEle = log(TSigmaEtaEtaEle);
00667       
00668       TChiEcalEle         = sqrt(chi2GSFECAL); 
00669       
00670       TNumBrem = NumBrem;
00671       TSumEBremPinPoutMode = 0.;
00672       TLateBrem = -1;
00673       TEarlyBrem = -1;
00674       if (TNumBrem > 0) {
00675         TSumEBremPinPoutMode = Tot_BremClustEne /(GSF_Ein - GSF_Eout);
00676         if (TSumEBremPinPoutMode < 0.) TSumEBremPinPoutMode = 0.;
00677         if (TSumEBremPinPoutMode > 5.) TSumEBremPinPoutMode = 5.;
00678         
00679         if (LateBrem == true) TLateBrem = 1;
00680         else TLateBrem = 0;
00681         if (EarlyBrem == true) TEarlyBrem = 1;
00682         else TEarlyBrem = 0;
00683       }
00684 
00685       if (DebugIDOutputs) cout << " variables " << 
00686         " TEtotPinMode "  << TEtotPinMode << "  " << 
00687         " TEGsfPoutMode "  << TEGsfPoutMode << "  " << 
00688         " TDiffEtaGSFEcalEle "  << TDiffEtaGSFEcalEle  << "  " << 
00689         " TSigmaEtaEtaEle "  << TSigmaEtaEtaEle << "  " << 
00690         " TChiEcalEle "  << TChiEcalEle << "  " << 
00691         " TNumBrem "  << TNumBrem << "  " << 
00692         " TSumEBremPinPoutMode "  << TSumEBremPinPoutMode << "  " << 
00693         " TLateBrem "  << TLateBrem << "  " << 
00694         " TEarlyBrem "  << TEarlyBrem  << "  " << endl;
00695       
00696       // the BDT is run 
00697       double mvaValue = tmvaReader_->EvaluateMVA("BDT");
00698       //Double_t mvaValue  = 0.5;
00699 
00700       // This condition has to be modified as soon we have
00701       // better BDT observables and training. 
00702       if (TEtotPinMode > 1.5 && TEarlyBrem != 1) {BDToutput_[igsf] = -1.;}
00703       else {BDToutput_[igsf] = mvaValue;}
00704   
00705       
00706       if (DebugIDOutputs) cout << "setIdOutput:: BDT output " 
00707                                << igsf << " mvaValue " 
00708                                << BDToutput_[igsf] << endl;
00709     }
00710   } // End Loop on Map1 
00711 
00712   return;
00713 }
00714 // This function get the associatedToGSF and associatedToBrems maps and  
00715 // compute the electron 4-mom and set the pf candidate, for
00716 // the gsf track with a BDTcut > mvaEleCut_
00717 void PFElectronAlgo::SetCandidates(const reco::PFBlockRef&  blockRef,
00718                                    const AssMap& associatedToGSF_,
00719                                    const AssMap& associatedToBrems_) {
00720 
00721   const reco::PFBlock& block = *blockRef;
00722   PFBlock::LinkData linkData =  block.linkData();     
00723   const edm::OwnVector< reco::PFBlockElement >&  elements = block.elements();
00724   PFEnergyResolution pfresol_;
00725   PFEnergyCalibration pfcalib_;
00726   bool DebugIDCandidates = false;
00727 
00728   for (uint igsf = 0; igsf<associatedToGSF_.size();igsf++) {
00729     uint index_gsf =  associatedToGSF_[igsf].first;
00730     if(BDToutput_[igsf] < mvaEleCut_) continue;  
00731     // Important enter only if good cut: to set configurable
00732 
00733     // They should be reset for each gsf track
00734     int eecal=0;
00735     int hcal=0;
00736     int charge =0; 
00737     bool goodphi=true;
00738     math::XYZTLorentzVector momentum_kf,momentum_gsf,momentum,momentum_mean;
00739     float dpt=0; float dpt_kf=0; float dpt_gsf=0; float dpt_mean=0;
00740     float Eene=0; float dene=0; float Hene=0.;
00741     float de_gs, de_me, de_kf; 
00742     float m_el=0.00051;
00743     int nhit_kf=0; int nhit_gsf=0;
00744     bool has_gsf=false;
00745     bool has_kf=false;
00746     math::XYZTLorentzVector newmomentum;
00747     float ps1TotEne = 0;
00748     float ps2TotEne = 0;
00749     vector<uint> elementsToAdd(0);
00750     reco::GsfTrackRef RefGSF;  
00751     reco::TrackRef RefKF;  
00752 
00753 
00754     PFBlockElement::Type typegsf = elements[index_gsf].type();
00755     if (typegsf == reco::PFBlockElement::GSF) { 
00756       elementsToAdd.push_back(index_gsf);
00757       const reco::PFBlockElementGsfTrack * GsfEl  =  
00758         dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[index_gsf]));
00759       RefGSF = GsfEl->GsftrackRef();
00760       if (RefGSF.isAvailable()) {
00761         if (RefGSF.isNonnull()) {
00762 
00763           has_gsf=true;
00764 
00765           charge= RefGSF->chargeMode();
00766           nhit_gsf= RefGSF->hitPattern().trackerLayersWithMeasurement();
00767 
00768           momentum_gsf.SetPx(RefGSF->pxMode());
00769           momentum_gsf.SetPy(RefGSF->pyMode());
00770           momentum_gsf.SetPz(RefGSF->pzMode());
00771           float ENE=sqrt(RefGSF->pMode()*
00772                          RefGSF->pMode()+m_el*m_el);
00773 
00774           if( DebugIDCandidates ) 
00775             cout << "SetCandidates:: GsfTrackRef: Ene " << ENE 
00776                  << " charge " << charge << endl;
00777 
00778           momentum_gsf.SetE(ENE);       
00779           dpt_gsf=RefGSF->ptModeError()*
00780             (RefGSF->pMode()/RefGSF->ptMode());
00781           
00782           momentum_mean.SetPx(RefGSF->px());
00783           momentum_mean.SetPy(RefGSF->py());
00784           momentum_mean.SetPz(RefGSF->pz());
00785           float ENEm=sqrt(RefGSF->p()*
00786                           RefGSF->p()+m_el*m_el);
00787           momentum_mean.SetE(ENEm);       
00788           dpt_mean=RefGSF->ptError()*
00789             (RefGSF->p()/RefGSF->pt());  
00790         }
00791         else {
00792           if( DebugIDCandidates ) 
00793             cout <<  "SetCandidates:: !!!!  NULL GSF Track Ref " << endl;       
00794         } 
00795       }  
00796       else {
00797         if( DebugIDCandidates ) 
00798           cout <<  "SetCandidates:: !!!! NotAvailable GSF Track Ref " << endl;
00799       }
00800     }
00801 
00802     vector<uint> index_assogsf =  associatedToGSF_[igsf].second;
00803     unsigned GSFClus_index = 100000;
00804     for  (unsigned ielegsf=0;ielegsf<index_assogsf.size();ielegsf++) {
00805       PFBlockElement::Type typeassoele = elements[(index_assogsf[ielegsf])].type();
00806       if  (typeassoele == reco::PFBlockElement::TRACK) {
00807         elementsToAdd.push_back((index_assogsf[ielegsf])); // Daniele
00808         const reco::PFBlockElementTrack * KfTk =  
00809           dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(index_assogsf[ielegsf])]));        
00810         RefKF = KfTk->trackRef();
00811         if (RefKF.isAvailable()) {
00812           if (RefKF.isNonnull()) {
00813             has_kf = true;
00814             dpt_kf=(RefKF->ptError()*RefKF->ptError());
00815             nhit_kf=RefKF->hitPattern().trackerLayersWithMeasurement();
00816             momentum_kf.SetPx(RefKF->px());
00817             momentum_kf.SetPy(RefKF->py());
00818             momentum_kf.SetPz(RefKF->pz());
00819             float ENE=sqrt(RefKF->p()*RefKF->p()+m_el*m_el);
00820             if( DebugIDCandidates ) 
00821               cout << "SetCandidates:: KFTrackRef: Ene " << ENE << endl;
00822             
00823             momentum_kf.SetE(ENE);
00824           }
00825           else {
00826             if( DebugIDCandidates ) 
00827               cout <<  "SetCandidates:: !!!! NULL KF Track Ref " << endl;
00828           }
00829         } 
00830         else {
00831           if( DebugIDCandidates ) 
00832             cout <<  "SetCandidates:: !!!! NotAvailable KF Track Ref " << endl;
00833         }
00834       } 
00835 
00836       vector<double> ps1Ene(0);
00837       vector<double> ps2Ene(0);
00838       // Important is the PS clusters are not saved before the ecal one, these
00839       // energy are not correctly assigned 
00840       // For the moment I get only the closest PS clusters: this has to be changed
00841       if  (typeassoele == reco::PFBlockElement::PS1) {  
00842         PFClusterRef  psref = elements[(index_assogsf[ielegsf])].clusterRef();
00843         ps1Ene.push_back(psref->energy());
00844         ps1TotEne += psref->energy();
00845         elementsToAdd.push_back((index_assogsf[ielegsf]));
00846       }
00847       if  (typeassoele == reco::PFBlockElement::PS2) {  
00848         PFClusterRef  psref = elements[(index_assogsf[ielegsf])].clusterRef();
00849         ps2Ene.push_back(psref->energy());
00850         ps2TotEne += psref->energy();
00851         elementsToAdd.push_back((index_assogsf[ielegsf]));
00852       }
00853 
00854       if  (typeassoele == reco::PFBlockElement::ECAL) {
00855         elementsToAdd.push_back((index_assogsf[ielegsf]));
00856 
00857         GSFClus_index = index_assogsf[ielegsf];
00858 
00859         const reco::PFBlockElementCluster * clust =  
00860           dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(index_assogsf[ielegsf])])); 
00861         
00862         eecal++;
00863         
00864         reco::PFCluster cl=*clust->clusterRef();
00865         
00866         float EE=pfcalib_.energyEm(cl,ps1Ene,ps2Ene);
00867         
00868         float ceta=clust->clusterRef()->position().eta();
00869         float cphi=clust->clusterRef()->position().phi();
00870         
00871         float mphi=-2.97025;
00872         if (ceta<0) mphi+=0.00638;
00873         for (int ip=1; ip<19; ip++){
00874           float df= cphi - (mphi+(ip*6.283185/18));
00875           if (fabs(df)<0.01) goodphi=false;
00876         }
00877         float dE=pfresol_.getEnergyResolutionEm(EE,clust->clusterRef()->position().eta());
00878         if( DebugIDCandidates ) 
00879           cout << "SetCandidates:: EcalCluster: Ene " << EE << " dE " <<  dE <<endl;
00880         
00881         Eene+=EE;
00882         dene+=dE*dE;
00883       }
00884       
00885       if  (typeassoele == reco::PFBlockElement::HCAL) {
00886         
00887         const reco::PFBlockElementCluster * clust =  
00888           dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(index_assogsf[ielegsf])])); 
00889         float df=fabs(momentum_gsf.phi()-clust->clusterRef()->position().phi());
00890         if (df<0.1) {
00891           // Not used for the moments
00892           // elementsToAdd.push_back((index_assogsf[ielegsf])); 
00893           //Eene+=clust->clusterRef()->energy();
00894           Hene+=clust->clusterRef()->energy();
00895           hcal++;
00896         }
00897       }
00898 
00899       // Important: Add energy from the brems
00900       if  (typeassoele == reco::PFBlockElement::BREM) {
00901         for (uint ibrem = 0; ibrem < associatedToBrems_.size(); ibrem++){
00902           vector<unsigned> index_assobrem = (associatedToBrems_[ibrem]).second;
00903           unsigned index_brem = (associatedToBrems_[ibrem]).first;
00904           if (index_brem == index_assogsf[ielegsf]) {   // Note: important: check that 
00905             // brem emission is from the considered gsf track
00906 
00907             // if the brem info are needed:
00908             //const reco::PFBlockElementBrem * BremEl  =  
00909             //  dynamic_cast<const reco::PFBlockElementBrem*>((&elements[index_brem]));
00910             //unsigned BremTrajP = BremEl->indTrajPoint();
00911             //unsigned TrajPos = BremTrajP-2;
00912             // if (TrajPos <= 3) do something:  This could be important because
00913             // in case of early brem the pin is badly estimated    
00914             elementsToAdd.push_back(index_brem);
00915             for (unsigned ielebrem=0;ielebrem<index_assobrem.size();ielebrem++) {
00916               vector<double> ps1EneFromBrem(0);
00917               vector<double> ps2EneFromBrem(0);
00918               // Important is the PS clusters are not saved before the ecal one, these
00919               // energy are not correctly assigned 
00920               // For the moment I get only the closest PS clusters: this has to be changed
00921               if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::PS1) {
00922                 PFClusterRef  psref = elements[(index_assobrem[ielebrem])].clusterRef();
00923                 ps1EneFromBrem.push_back(psref->energy());
00924                 ps1TotEne += psref->energy();
00925                 elementsToAdd.push_back(index_assobrem[ielebrem]);
00926               }
00927               if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::PS2) {
00928                 PFClusterRef  psref = elements[(index_assobrem[ielebrem])].clusterRef();
00929                 ps2EneFromBrem.push_back(psref->energy());
00930                 ps2TotEne += psref->energy();
00931                 elementsToAdd.push_back(index_assobrem[ielebrem]);
00932               }        
00933 
00934               if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::ECAL) {
00935                 if( index_assobrem[ielebrem] !=  GSFClus_index) {
00936                   elementsToAdd.push_back(index_assobrem[ielebrem]);
00937                   reco::PFClusterRef clusterRef = elements[(index_assobrem[ielebrem])].clusterRef();
00938                   
00939                   float EE = pfcalib_.energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem);
00940                   float ceta = clusterRef->position().eta();
00941                   // float cphi = clusterRef->position().phi();
00942                   float dE=pfresol_.getEnergyResolutionEm(EE,ceta);
00943                   if( DebugIDCandidates ) cout << "SetCandidates:: BremCluster: Ene " << EE << " dE " <<  dE <<endl;      
00944                   Eene+=EE;
00945                   dene+=dE*dE;
00946                 }
00947               } 
00948               if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::HCAL) {
00949                 reco::PFClusterRef clusterRef = elements[(index_assobrem[ielebrem])].clusterRef();
00950                 float df=fabs(momentum_gsf.phi()-clusterRef->position().phi());
00951                 if (df<0.1) {
00952                   // Not used for the moments
00953                   // elementsToAdd.push_back(index_assobrem[ielebrem]); 
00954                   //Eene+= clusterRef->energy();
00955                   Hene+= clusterRef->energy();
00956                   hcal++;
00957                 }
00958               }
00959             }
00960           }
00961         }
00962       }
00963     } // End Loop On element associated to the GSF tracks
00964     if (has_gsf) {
00965       if ((nhit_gsf<8) && (has_kf)){
00966         
00967         // Use Hene if some condition.... 
00968         
00969         
00970         de_gs=1-momentum_gsf.E()/Eene;
00971         de_me=1-momentum_mean.E()/Eene;
00972         de_kf=1-momentum_kf.E()/Eene;
00973         
00974         
00975         momentum=momentum_kf;
00976         float Fe=Eene;
00977         
00978         float scale= Fe/momentum.E();
00979         
00980         newmomentum.SetPxPyPzE(scale*momentum.Px(),
00981                                scale*momentum.Py(),
00982                                scale*momentum.Pz(),Fe);
00983         //      isvalid_=true;
00984         
00985       } 
00986       if ((nhit_gsf>7) || (has_kf==false)){
00987         
00988         de_gs=1-momentum_gsf.E()/Eene;
00989         de_me=1-momentum_mean.E()/Eene;
00990         de_kf=1-momentum_kf.E()/Eene;
00991         
00992         momentum=momentum_gsf;
00993         dpt=1/(dpt_gsf*dpt_gsf);
00994         
00995         dene= 1/dene;
00996         
00997         float Fe=((dene*Eene) +(dpt*momentum.E()))/(dene+dpt);
00998         
00999         if ((de_gs>0.05)&&(de_kf>0.05)){
01000           Fe=Eene;
01001         }
01002         if ((de_gs<-0.1)&&(de_me<-0.1) &&(de_kf<0.)){
01003           Fe=momentum.E();
01004         }
01005         float scale= Fe/momentum.E();
01006         
01007         newmomentum.SetPxPyPzE(scale*momentum.Px(),
01008                                scale*momentum.Py(),
01009                                scale*momentum.Pz(),Fe);
01010         
01011       }
01012       if (newmomentum.pt()>0.5){
01013         
01014         // the pf candidate are created: we need to set something more? 
01015         // IMPORTANT -> We need the gsftrackRef, not only the TrackRef??
01016 
01017         if( DebugIDCandidates )
01018           cout << "SetCandidates:: I am before doing candidate " <<endl;
01019         
01020         reco::PFCandidate::ParticleType particleType 
01021           = reco::PFCandidate::e;
01022         reco::PFCandidate temp_Candidate;
01023         temp_Candidate = PFCandidate(charge,newmomentum,particleType);
01024         temp_Candidate.set_mva_e_pi(BDToutput_[igsf]);
01025         temp_Candidate.setEcalEnergy(Eene);
01026         temp_Candidate.setHcalEnergy(0.);  // Use HCAL energy? 
01027         temp_Candidate.setPs1Energy(ps1TotEne);
01028         temp_Candidate.setPs2Energy(ps2TotEne);
01029         temp_Candidate.setTrackRef(RefKF);   
01030         // This reference could be NULL it is needed a protection? 
01031         temp_Candidate.setGsfTrackRef(RefGSF);
01032         
01033         if( DebugIDCandidates ) 
01034           cout << "SetCandidates:: I am after doing candidate " <<endl;
01035         
01036         for (uint elad=0; elad<elementsToAdd.size();elad++){
01037           temp_Candidate.addElementInBlock(blockRef,elementsToAdd[elad]);
01038         }
01039         
01040         elCandidate_.push_back(temp_Candidate);
01041 
01042       }
01043       else {
01044         BDToutput_[igsf] = -1.;   // if the momentum is < 0.5 ID = false, but not sure
01045         // it could be misleading. 
01046         if( DebugIDCandidates ) 
01047           cout << "SetCandidates:: No Candidate Produced because of Pt cut: 0.5 " <<endl;
01048       }
01049     } 
01050     else {
01051       BDToutput_[igsf] = -1.;  // if gsf ref does not exist
01052       if( DebugIDCandidates ) 
01053         cout << "SetCandidates:: No Candidate Produced because of No GSF Track Ref " <<endl;
01054     }
01055   } // End Loop On GSF tracks
01056   return;
01057 }
01058 // This function get the associatedToGSF and associatedToBrems maps and for each pfelectron candidate 
01059 // the element used are set active == false. 
01060 // note: the HCAL cluster are not used for the moments and also are not locked. 
01061 void PFElectronAlgo::SetActive(const reco::PFBlockRef&  blockRef,
01062                                const AssMap& associatedToGSF_,
01063                                const AssMap& associatedToBrems_,
01064                                std::vector<bool>& active){
01065   const reco::PFBlock& block = *blockRef;
01066   PFBlock::LinkData linkData =  block.linkData();     
01067   const edm::OwnVector< reco::PFBlockElement >&  elements = block.elements();
01068   for (uint igsf = 0; igsf<associatedToGSF_.size();igsf++) {
01069     if(BDToutput_[igsf] < mvaEleCut_) continue;  // Important enter only if good cut: to set configurable
01070     uint index_gsf =  associatedToGSF_[igsf].first;
01071     active[index_gsf] = false;  // the gsf
01072     vector<uint> index_assogsf =  associatedToGSF_[igsf].second;
01073     for  (unsigned ielegsf=0;ielegsf<index_assogsf.size();ielegsf++) {
01074       PFBlockElement::Type typeassoele = elements[(index_assogsf[ielegsf])].type();
01075       if (typeassoele == reco::PFBlockElement::HCAL) continue;  // the HCAL elements are not disattivated 
01076       active[(index_assogsf[ielegsf])] = false;  // the elements associated to the gsf
01077       if (typeassoele == reco::PFBlockElement::BREM) {
01078         for (uint ibrem = 0; ibrem < associatedToBrems_.size(); ibrem++){
01079           vector<unsigned> index_assobrem = (associatedToBrems_[ibrem]).second;
01080           unsigned index_brem = (associatedToBrems_[ibrem]).first;       
01081           if (index_brem == index_assogsf[ielegsf]) {   // Note: important: check that 
01082             // brem emission is from the considered gsf track
01083             for (unsigned ielebrem=0;ielebrem<index_assobrem.size();ielebrem++) {
01084               if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::HCAL) continue;
01085               active[(index_assobrem[ielebrem])] = false;  // the elements associated to the brems
01086             }
01087           }
01088         }  // End loop on elements from brem      
01089       }
01090     } // End loop on elements from gsf track
01091   }  // End loop on gsf track  
01092   return;
01093 }
01094 

Generated on Tue Jun 9 17:44:39 2009 for CMSSW by  doxygen 1.5.4