CMS 3D CMS Logo

Public Member Functions | Private Types | Private Member Functions | Private Attributes

PFPhotonAlgo Class Reference

#include <PFPhotonAlgo.h>

List of all members.

Public Member Functions

bool isPhotonValidCandidate (const reco::PFBlockRef &blockRef, std::vector< bool > &active, std::auto_ptr< reco::PFCandidateCollection > &pfPhotonCandidates, std::vector< reco::PFCandidatePhotonExtra > &pfPhotonExtraCandidates, std::vector< reco::PFCandidate > &tempElectronCandidates)
 PFPhotonAlgo (std::string mvaweightfile, double mvaConvCut, bool useReg, std::string X0_Map, const reco::Vertex &primary, const boost::shared_ptr< PFEnergyCalibration > &thePFEnergyCalibration, double sumPtTrackIsoForPhoton, double sumPtTrackIsoSlopeForPhoton)
void setGBRForest (const GBRForest *LCorrForest, const GBRForest *GCorrForest, const GBRForest *ResForest)
 ~PFPhotonAlgo ()

Private Types

enum  verbosityLevel { Silent, Summary, Chatty }

Private Member Functions

void EarlyConversion (std::vector< reco::PFCandidate > &tempElectronCandidates, const reco::PFBlockElementSuperCluster *sc)
float EvaluateGCorrMVA (reco::PFCandidate)
float EvaluateLCorrMVA (reco::PFClusterRef clusterRef)
float EvaluateResMVA (reco::PFCandidate)
bool EvaluateSingleLegMVA (const reco::PFBlockRef &blockref, const reco::Vertex &primaryvtx, unsigned int track_index)
void fill5x5Map (reco::PFClusterRef clusterRef)
void GetCrysCoordinates (reco::PFClusterRef clusterRef)
std::vector< int > getPFMustacheClus (int nClust, std::vector< float > &ClustEt, std::vector< float > &ClustEta, std::vector< float > &ClustPhi)
void RunPFPhoton (const reco::PFBlockRef &blockRef, std::vector< bool > &active, std::auto_ptr< reco::PFCandidateCollection > &pfPhotonCandidates, std::vector< reco::PFCandidatePhotonExtra > &pfPhotonExtraCandidates, std::vector< reco::PFCandidate > &tempElectronCandidates)

Private Attributes

std::vector< unsigned int > AddFromElectron_
float chi2
float Clus5x5ratio_
float ClusEta_
float ClusPhi_
float ClusR9_
float CrysEta_
float CrysIEta_
float CrysIPhi_
float CrysPhi_
float del_phi
float dEta_
float dPhi_
float e1x3_
float e1x5_
float e2x5Bottom_
float e2x5Left_
float e2x5Max_
float e2x5Right_
float e2x5Top_
float e3x1_
float e3x3_
float e5x5Map [5][5]
float EB
float EoverPt
float eSeed_
float excluded_
float HoverPt
bool isvalid_
float logPFClusE_
float LowClusE_
std::vector< int > match_ind
float Mustache_Et_out_
float Mustache_EtRatio_
double MVACUT
double mvaValue
float nlayers
float nlost
float nPFClus_
std::vector< reco::PFCandidatepermElectronCandidates_
float PFCrysEtaCrack_
float PFCrysPhiCrack_
float PFPhoEt_
float PFPhoEta_
float PFPhoPhi_
float PFPhoR9_
reco::Vertex primaryVertex_
float RConv_
const GBRForestReaderGC_
const GBRForestReaderLC_
const GBRForestReaderRes_
float SCEtaWidth_
float SCPhiWidth_
float STIP
double sumPtTrackIsoForPhoton_
double sumPtTrackIsoSlopeForPhoton_
boost::shared_ptr
< PFEnergyCalibration
thePFEnergyCalibration_
TMVA::Reader * tmvaReader_
float track_pt
bool useReg_
verbosityLevel verbosityLevel_
float VtxZ_
TH2D * X0_inner
TH2D * X0_middle
TH2D * X0_outer
TH2D * X0_sum
float x0inner_
float x0middle_
float x0outer_

Detailed Description

Definition at line 29 of file PFPhotonAlgo.h.


Member Enumeration Documentation

Enumerator:
Silent 
Summary 
Chatty 

Definition at line 106 of file PFPhotonAlgo.h.


Constructor & Destructor Documentation

PFPhotonAlgo::PFPhotonAlgo ( std::string  mvaweightfile,
double  mvaConvCut,
bool  useReg,
std::string  X0_Map,
const reco::Vertex primary,
const boost::shared_ptr< PFEnergyCalibration > &  thePFEnergyCalibration,
double  sumPtTrackIsoForPhoton,
double  sumPtTrackIsoSlopeForPhoton 
)

Definition at line 30 of file PFPhotonAlgo.cc.

References chi2, del_phi, EoverPt, HoverPt, nlayers, nlost, primaryVertex_, STIP, tmvaReader_, track_pt, X0_inner, X0_middle, X0_outer, and X0_sum.

                             : 
  isvalid_(false), 
  verbosityLevel_(Silent), 
  MVACUT(mvaConvCut),
  useReg_(useReg),
  thePFEnergyCalibration_(thePFEnergyCalibration),
  sumPtTrackIsoForPhoton_(sumPtTrackIsoForPhoton),
  sumPtTrackIsoSlopeForPhoton_(sumPtTrackIsoSlopeForPhoton)
{  
    primaryVertex_=primary;  
    //Book MVA  
    tmvaReader_ = new TMVA::Reader("!Color:Silent");  
    tmvaReader_->AddVariable("del_phi",&del_phi);  
    tmvaReader_->AddVariable("nlayers", &nlayers);  
    tmvaReader_->AddVariable("chi2",&chi2);  
    tmvaReader_->AddVariable("EoverPt",&EoverPt);  
    tmvaReader_->AddVariable("HoverPt",&HoverPt);  
    tmvaReader_->AddVariable("track_pt", &track_pt);  
    tmvaReader_->AddVariable("STIP",&STIP);  
    tmvaReader_->AddVariable("nlost", &nlost);  
    tmvaReader_->BookMVA("BDT",mvaweightfile.c_str());  

    //Material Map
    TFile *XO_File = new TFile(X0_Map.c_str(),"READ");
    X0_sum=(TH2D*)XO_File->Get("TrackerSum");
    X0_inner = (TH2D*)XO_File->Get("Inner");
    X0_middle = (TH2D*)XO_File->Get("Middle");
    X0_outer = (TH2D*)XO_File->Get("Outer");
    
}
PFPhotonAlgo::~PFPhotonAlgo ( ) [inline]

Definition at line 44 of file PFPhotonAlgo.h.

References tmvaReader_.

{delete tmvaReader_;   };

Member Function Documentation

void PFPhotonAlgo::EarlyConversion ( std::vector< reco::PFCandidate > &  tempElectronCandidates,
const reco::PFBlockElementSuperCluster sc 
) [private]

Definition at line 1509 of file PFPhotonAlgo.cc.

References AddFromElectron_, prof2calltree::count, i, edm::Ref< C, T, F >::isAvailable(), edm::Ref< C, T, F >::isNonnull(), match_ind, and reco::PFBlockElementSuperCluster::superClusterRef().

Referenced by RunPFPhoton().

                                    {
  //step 1 check temp electrons for clusters that match Photon Supercluster:
  // permElectronCandidates->clear();
  int count=0;
  for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin();   ec != tempElectronCandidates.end(); ++ec ) 
    {
      //      bool matched=false;
      int mh=ec->gsfTrackRef()->trackerExpectedHitsInner().numberOfLostHits();
      if(mh==0)continue;//Case where missing hits greater than zero
      
      reco::GsfTrackRef gsf=ec->gsfTrackRef();
      //some hoopla to get Electron SC ref
      
      if(gsf->extra().isAvailable() && gsf->extra()->seedRef().isAvailable()) 
        {
          reco::ElectronSeedRef seedRef=  gsf->extra()->seedRef().castTo<reco::ElectronSeedRef>();
          if(seedRef.isAvailable() && seedRef->isEcalDriven()) 
            {
              reco::SuperClusterRef ElecscRef = seedRef->caloCluster().castTo<reco::SuperClusterRef>();
              
              if(ElecscRef.isNonnull()){
                //finally see if it matches:
                reco::SuperClusterRef PhotscRef=sc->superClusterRef();
                
                if(PhotscRef==ElecscRef)
                  {
                    match_ind.push_back(count);
                    //  matched=true; 
                    //cout<<"Matched Electron with Index "<<count<<" This is the electron "<<*ec<<endl;
                    //find that they have the same SC footprint start to collect Clusters and tracks and these will be passed to PFPhoton
                    reco::PFCandidate::ElementsInBlocks eleInBlocks = ec->elementsInBlocks();
                    for(unsigned i=0; i<eleInBlocks.size(); i++) 
                      {
                        reco::PFBlockRef blockRef = eleInBlocks[i].first;
                        unsigned indexInBlock = eleInBlocks[i].second;   
                        //const edm::OwnVector< reco::PFBlockElement >&  elements=eleInBlocks[i].first->elements();
                        //const reco::PFBlockElement& element = elements[indexInBlock];                 
                        
                        AddFromElectron_.push_back(indexInBlock);               
                      }             
                  }             
              }
            }     
        }           
      count++;
    }
}
float PFPhotonAlgo::EvaluateGCorrMVA ( reco::PFCandidate  photon) [private]

Definition at line 1043 of file PFPhotonAlgo.cc.

References reco::PFBlockElement::clusterRef(), funct::cos(), deltaR(), dEta_, dPhi_, e3x3_, ECAL, asciidump::elements, reco::PFCandidate::elementsInBlocks(), reco::LeafCandidate::energy(), eta(), reco::LeafCandidate::eta(), excluded_, fill5x5Map(), GBRForest::GetResponse(), reco::PFBlockElement::GSF, i, LowClusE_, Mustache_EtRatio_, reco::Mustache::MustacheID(), nPFClus_, PFPhoEt_, PFPhoEta_, PFPhoPhi_, PFPhoR9_, reco::LeafCandidate::phi(), phi, reco::LeafCandidate::pt(), dttmaxenums::R, RConv_, ReaderGC_, SCEtaWidth_, SCPhiWidth_, mathSSE::sqrt(), reco::PFCandidate::superClusterRef(), reco::PFBlockElement::TRACK, reco::PFBlockElement::trackRef(), reco::PFBlockElement::type(), X0_inner, X0_middle, X0_outer, X0_sum, x0inner_, x0middle_, and x0outer_.

Referenced by RunPFPhoton().

                                                          {
  float BDTG=1;
  PFPhoEta_=photon.eta();
  PFPhoPhi_=photon.phi();
  PFPhoEt_=photon.pt();
  //recalculate R9 from sum PFClusterEnergy and E3x3 from Highest PFCluster Energy
  SCPhiWidth_=photon.superClusterRef()->phiWidth();
  SCEtaWidth_=photon.superClusterRef()->etaWidth();  
  //get from track with min R;
  RConv_=130;
  float ClustSumEt=0;
  std::vector<float>Clust_E(0);
  std::vector<float>Clust_Et(0);
  std::vector<float>Clust_Eta(0);
  std::vector<float>Clust_Phi(0);
  std::vector<reco::PFClusterRef> PFClusRef(0);
  std::vector<const CaloCluster*> PFclusters;
  //Multimap to sort clusters by energy
  std::multimap<float, int>Clust;
  PFCandidate::ElementsInBlocks eleInBlocks = photon.elementsInBlocks();
  for(unsigned i=0; i<eleInBlocks.size(); i++)
    {
      PFBlockRef blockRef = eleInBlocks[i].first;
      unsigned indexInBlock = eleInBlocks[i].second;
      const edm::OwnVector< reco::PFBlockElement >&  elements=eleInBlocks[i].first->elements();
      const reco::PFBlockElement& element = elements[indexInBlock];
      if(element.type()==reco::PFBlockElement::TRACK){
        float R=sqrt(element.trackRef()->innerPosition().X()*element.trackRef()->innerPosition().X()+element.trackRef()->innerPosition().Y()*element.trackRef()->innerPosition().Y());
        if(RConv_>R)RConv_=R;
      }
      
      if(element.type()==reco::PFBlockElement::ECAL){
        reco::PFClusterRef ClusterRef = element.clusterRef();
        //PFClusRef.push_back(ClusterRef);
        //clusters.push_back(ClusterRef);
        Clust_E.push_back(ClusterRef->energy());
        Clust_Et.push_back(ClusterRef->pt());   
        ClustSumEt=ClustSumEt+ClusterRef->pt();
        Clust_Eta.push_back(ClusterRef->eta());
        Clust_Phi.push_back(ClusterRef->phi());
        PFclusters.push_back(&*ClusterRef);
      }
      
      if(element.type()==reco::PFBlockElement::GSF)
        {
          //elements[indexInBlock].GsftrackRef();
          //  RConv_=sqrt(element.trackRef()->innerPosition().X()*element.trackRef()->innerPosition().X() + element.trackRef()->innerPosition().Y()*element.trackRef()->innerPosition().Y());
        }
      
    }
  
  nPFClus_=Clust_Et.size();
  
  //std::vector<int>included(0);
  //included=getPFMustacheClus(nPFClus_, Clust_Et, Clust_Eta, Clust_Phi);
  //if(included.size()>0)excluded_=nPFClus_-included.size();
  //else excluded_=0;
  //cout<<"initial excluded "<<excluded_<<endl;
  float Mustache_Et_out=0;
  int PFClus=0;
  Mustache Must;
  Must.MustacheID(PFclusters, PFClus, Mustache_Et_out);
  excluded_=PFClus;
  //order the clusters by energy
  //  float Mustache_Et=0;
  float ClusSum=0;
  for(unsigned int i=0; i<Clust_E.size(); ++i)
    {
      
      Clust.insert(make_pair(Clust_E[i], i));
      //Mustache_Et=Mustache_Et+Clust_Et[i];
      ClusSum=ClusSum+Clust_E[i];
    }
  Mustache_EtRatio_=(Mustache_Et_out)/ClustSumEt;
  std::multimap<float, int>::reverse_iterator it;
  it=Clust.rbegin();
  int max_c=(*it).second;
  it=Clust.rend();
  int min_c=(*it).second;
  if(nPFClus_>1)LowClusE_=Clust_E[min_c];
  else LowClusE_=0;
  if(nPFClus_>1){
    dEta_=fabs(Clust_Eta[max_c]-Clust_Eta[min_c]);
    dPhi_=acos(cos(Clust_Phi[max_c]-Clust_Phi[min_c]));
  }
  else{
    dEta_=0;
    dPhi_=0;
  }
  float dRmin=999;
  float SCphi=photon.superClusterRef()->position().phi();
  float SCeta=photon.superClusterRef()->position().eta();
  for(unsigned i=0; i<eleInBlocks.size(); i++)
    {
      PFBlockRef blockRef = eleInBlocks[i].first;
      unsigned indexInBlock = eleInBlocks[i].second;
      const edm::OwnVector< reco::PFBlockElement >&  elements=eleInBlocks[i].first->elements();
      const reco::PFBlockElement& element = elements[indexInBlock];
      if(element.type()==reco::PFBlockElement::ECAL){
        reco::PFClusterRef ClusterRef = element.clusterRef();
        float eta=ClusterRef->position().eta();
        float phi=ClusterRef->position().phi();
        float dR=deltaR(SCeta, SCphi, eta, phi);
        if(dR<dRmin){
          dRmin=dR;
          fill5x5Map(ClusterRef);
          PFPhoR9_=e3x3_/ClusSum;
        }
      }
    } 

  //fill Material Map:
  int ix = X0_sum->GetXaxis()->FindBin(PFPhoEta_);
  int iy = X0_sum->GetYaxis()->FindBin(PFPhoPhi_);
  x0inner_= X0_inner->GetBinContent(ix,iy);
  x0middle_=X0_middle->GetBinContent(ix,iy);
  x0outer_=X0_outer->GetBinContent(ix,iy);

  float GC_Var[16];
  GC_Var[0]=PFPhoEta_;
  GC_Var[1]=PFPhoEt_;
  GC_Var[2]=PFPhoR9_;
  GC_Var[3]=PFPhoPhi_;
  GC_Var[4]=SCEtaWidth_;
  GC_Var[5]=SCPhiWidth_;
  GC_Var[6]=x0inner_;  
  GC_Var[7]=x0middle_;
  GC_Var[8]=x0outer_;
  GC_Var[9]=nPFClus_;
  GC_Var[10]=RConv_;
  GC_Var[11]=LowClusE_/photon.energy();
  GC_Var[12]=dEta_;
  GC_Var[13]=dPhi_;
  GC_Var[14]=excluded_;
  GC_Var[15]= Mustache_EtRatio_;
  

  BDTG=ReaderGC_->GetResponse(GC_Var);
  //  cout<<"GC "<<BDTG<<endl;  
  
  //  cout<<"BDTG Parameters X0"<<x0inner_<<", "<<x0middle_<<", "<<x0outer_<<endl;
  // cout<<"Et, Eta, Phi "<<PFPhoEt_<<", "<<PFPhoEta_<<", "<<PFPhoPhi_<<endl;
  // cout<<"PFPhoR9 "<<PFPhoR9_<<endl;
  // cout<<"R "<<RConv_<<endl;
  
  return BDTG;

}
float PFPhotonAlgo::EvaluateLCorrMVA ( reco::PFClusterRef  clusterRef) [private]

Definition at line 1192 of file PFPhotonAlgo.cc.

References Clus5x5ratio_, ClusEta_, ClusPhi_, ClusR9_, CrysEta_, CrysPhi_, e1x3_, e1x5_, e2x5Bottom_, e2x5Left_, e2x5Max_, e2x5Right_, e2x5Top_, e3x1_, EB, eSeed_, fill5x5Map(), GetCrysCoordinates(), GBRForest::GetResponse(), funct::log(), logPFClusE_, PFCrysEtaCrack_, PFCrysPhiCrack_, primaryVertex_, ReaderLC_, VtxZ_, and reco::Vertex::z().

Referenced by RunPFPhoton().

                                                                {
  float BDTG=1;
  
  GetCrysCoordinates(clusterRef);
  fill5x5Map(clusterRef);
  VtxZ_=primaryVertex_.z();
  ClusPhi_=clusterRef->position().phi(); 
  ClusEta_=fabs(clusterRef->position().eta());
  EB=fabs(clusterRef->position().eta())/clusterRef->position().eta();
  logPFClusE_=log(clusterRef->energy());
   float LC_Var[20];
   LC_Var[0]=VtxZ_;
   LC_Var[1]=EB;
   LC_Var[2]=ClusEta_;
   LC_Var[3]=ClusPhi_;
   LC_Var[4]=logPFClusE_;
   LC_Var[5]=eSeed_;
   LC_Var[6]=ClusR9_;
   LC_Var[7]=e1x3_;
   LC_Var[8]=e3x1_;
   LC_Var[9]=Clus5x5ratio_;
   LC_Var[10]=e1x5_;
   LC_Var[11]=e2x5Max_;
   LC_Var[12]=e2x5Top_;
   LC_Var[13]=e2x5Bottom_;
   LC_Var[14]=e2x5Left_;
   LC_Var[15]=e2x5Right_;
   LC_Var[16]=CrysEta_;
   LC_Var[17]=CrysPhi_;
   LC_Var[18]=PFCrysPhiCrack_;
   LC_Var[19]=PFCrysEtaCrack_;
   BDTG=ReaderLC_->GetResponse(LC_Var);   
   //   cout<<"LC "<<BDTG<<endl;  
   return BDTG;
  
}
float PFPhotonAlgo::EvaluateResMVA ( reco::PFCandidate  photon) [private]

Definition at line 895 of file PFPhotonAlgo.cc.

References reco::PFBlockElement::clusterRef(), funct::cos(), deltaR(), dEta_, dPhi_, e3x3_, ECAL, asciidump::elements, reco::PFCandidate::elementsInBlocks(), eta(), reco::LeafCandidate::eta(), excluded_, fill5x5Map(), GBRForest::GetResponse(), reco::PFBlockElement::GSF, i, LowClusE_, Mustache_EtRatio_, reco::Mustache::MustacheID(), nPFClus_, PFPhoEt_, PFPhoEta_, PFPhoPhi_, PFPhoR9_, reco::LeafCandidate::phi(), phi, reco::LeafCandidate::pt(), dttmaxenums::R, RConv_, ReaderRes_, SCEtaWidth_, SCPhiWidth_, mathSSE::sqrt(), reco::PFCandidate::superClusterRef(), reco::PFBlockElement::TRACK, reco::PFBlockElement::trackRef(), reco::PFBlockElement::type(), X0_inner, X0_middle, X0_outer, X0_sum, x0inner_, x0middle_, and x0outer_.

Referenced by RunPFPhoton().

                                                        {
  float BDTG=1;
  PFPhoEta_=photon.eta();
  PFPhoPhi_=photon.phi();
  PFPhoEt_=photon.pt();
  //recalculate R9 from sum PFClusterEnergy and E3x3 from Highest PFCluster Energy
  SCPhiWidth_=photon.superClusterRef()->phiWidth();
  SCEtaWidth_=photon.superClusterRef()->etaWidth();  
  //get from track with min R;
  RConv_=130;
  float ClustSumEt=0;
  std::vector<float>Clust_E(0);
  std::vector<float>Clust_Et(0);
  std::vector<float>Clust_Eta(0);
  std::vector<float>Clust_Phi(0);
  std::vector<reco::PFClusterRef> PFClusRef(0);
  std::vector<const CaloCluster*> PFclusters;
  //Multimap to sort clusters by energy
  std::multimap<float, int>Clust;
  PFCandidate::ElementsInBlocks eleInBlocks = photon.elementsInBlocks();
  for(unsigned i=0; i<eleInBlocks.size(); i++)
    {
      PFBlockRef blockRef = eleInBlocks[i].first;
      unsigned indexInBlock = eleInBlocks[i].second;
      const edm::OwnVector< reco::PFBlockElement >&  elements=eleInBlocks[i].first->elements();
      const reco::PFBlockElement& element = elements[indexInBlock];
      if(element.type()==reco::PFBlockElement::TRACK){
        float R=sqrt(element.trackRef()->innerPosition().X()*element.trackRef()->innerPosition().X()+element.trackRef()->innerPosition().Y()*element.trackRef()->innerPosition().Y());
        if(RConv_>R)RConv_=R;
      }
      
      if(element.type()==reco::PFBlockElement::ECAL){
        reco::PFClusterRef ClusterRef = element.clusterRef();
        //PFClusRef.push_back(ClusterRef);
        //clusters.push_back(ClusterRef);
        Clust_E.push_back(ClusterRef->energy());
        Clust_Et.push_back(ClusterRef->pt());   
        ClustSumEt=ClustSumEt+ClusterRef->pt();
        Clust_Eta.push_back(ClusterRef->eta());
        Clust_Phi.push_back(ClusterRef->phi());
        PFclusters.push_back(&*ClusterRef);
      }
      
      if(element.type()==reco::PFBlockElement::GSF)
        {
          //elements[indexInBlock].GsftrackRef();
          //  RConv_=sqrt(element.trackRef()->innerPosition().X()*element.trackRef()->innerPosition().X() + element.trackRef()->innerPosition().Y()*element.trackRef()->innerPosition().Y());
        }
      
    }
  
  nPFClus_=Clust_Et.size();
  
  //std::vector<int>included(0);
  //included=getPFMustacheClus(nPFClus_, Clust_Et, Clust_Eta, Clust_Phi);
  //if(included.size()>0)excluded_=nPFClus_-included.size();
  //else excluded_=0;
  //cout<<"initial excluded "<<excluded_<<endl;
  float Mustache_Et_out=0;
  int PFClus=0;
  Mustache Must;
  Must.MustacheID(PFclusters, PFClus, Mustache_Et_out);
  excluded_=PFClus;
  //order the clusters by energy
  //  float Mustache_Et=0;
  float ClusSum=0;
  for(unsigned int i=0; i<Clust_E.size(); ++i)
    {
      
      Clust.insert(make_pair(Clust_E[i], i));
      //Mustache_Et=Mustache_Et+Clust_Et[i];
      ClusSum=ClusSum+Clust_E[i];
    }
  Mustache_EtRatio_=(Mustache_Et_out)/ClustSumEt;
  std::multimap<float, int>::reverse_iterator it;
  it=Clust.rbegin();
  int max_c=(*it).second;
  it=Clust.rend();
  int min_c=(*it).second;
  if(nPFClus_>1)LowClusE_=Clust_E[min_c];
  else LowClusE_=0;
  if(nPFClus_>1){
    dEta_=fabs(Clust_Eta[max_c]-Clust_Eta[min_c]);
    dPhi_=acos(cos(Clust_Phi[max_c]-Clust_Phi[min_c]));
  }
  else{
    dEta_=0;
    dPhi_=0;
  }
  
  float dRmin=999;
  float SCphi=photon.superClusterRef()->position().phi();
  float SCeta=photon.superClusterRef()->position().eta();
  for(unsigned i=0; i<eleInBlocks.size(); i++)
    {
      PFBlockRef blockRef = eleInBlocks[i].first;
      unsigned indexInBlock = eleInBlocks[i].second;
      const edm::OwnVector< reco::PFBlockElement >&  elements=eleInBlocks[i].first->elements();
      const reco::PFBlockElement& element = elements[indexInBlock];
      if(element.type()==reco::PFBlockElement::ECAL){
        reco::PFClusterRef ClusterRef = element.clusterRef();
        float eta=ClusterRef->position().eta();
        float phi=ClusterRef->position().phi();
        float dR=deltaR(SCeta, SCphi, eta, phi);
        if(dR<dRmin){
          dRmin=dR;
          fill5x5Map(ClusterRef);
          PFPhoR9_=e3x3_/ClusSum;
        }
      }
    } 
  //fill Material Map:
  int ix = X0_sum->GetXaxis()->FindBin(PFPhoEta_);
  int iy = X0_sum->GetYaxis()->FindBin(PFPhoPhi_);
  x0inner_= X0_inner->GetBinContent(ix,iy);
  x0middle_=X0_middle->GetBinContent(ix,iy);
  x0outer_=X0_outer->GetBinContent(ix,iy);
  
  float GC_Var[16];
  GC_Var[0]=PFPhoEta_;
  GC_Var[1]=PFPhoEt_;
  GC_Var[2]=PFPhoR9_;
  GC_Var[3]=PFPhoPhi_;
  GC_Var[4]=SCEtaWidth_;
  GC_Var[5]=SCPhiWidth_;
  GC_Var[6]=x0inner_;  
  GC_Var[7]=x0middle_;
  GC_Var[8]=x0outer_;
  GC_Var[9]=nPFClus_;
  GC_Var[10]=RConv_;
  GC_Var[11]=LowClusE_;
  GC_Var[12]=dEta_;
  GC_Var[13]=dPhi_;
  GC_Var[14]=excluded_;
  GC_Var[15]= Mustache_EtRatio_;
  
  BDTG=ReaderRes_->GetResponse(GC_Var);
  //  cout<<"Res "<<BDTG<<endl;
  
  //  cout<<"BDTG Parameters X0"<<x0inner_<<", "<<x0middle_<<", "<<x0outer_<<endl;
  // cout<<"Et, Eta, Phi "<<PFPhoEt_<<", "<<PFPhoEta_<<", "<<PFPhoPhi_<<endl;
  // cout<<"PFPhoR9 "<<PFPhoR9_<<endl;
  // cout<<"R "<<RConv_<<endl;
  
  return BDTG;

}
bool PFPhotonAlgo::EvaluateSingleLegMVA ( const reco::PFBlockRef blockref,
const reco::Vertex primaryvtx,
unsigned int  track_index 
) [private]

Definition at line 1457 of file PFPhotonAlgo.cc.

References reco::PFBlock::associatedElements(), Association::block, chi2, del_phi, SiPixelRawToDigiRegional_cfi::deltaPhi, reco::PFBlockElement::ECAL, reco::PFBlock::elements(), asciidump::elements, EoverPt, reco::PFBlockElement::HCAL, HoverPt, reco::PFBlock::linkData(), reco::PFBlock::LINKTEST_ALL, MVACUT, mvaValue, nlayers, nlost, PV3DBase< T, PVType, FrameType >::phi(), colinearityKinematic::Phi, STIP, tmvaReader_, track_pt, reco::Vertex::x(), X, reco::Vertex::y(), and reco::Vertex::z().

Referenced by RunPFPhoton().

{  
  bool convtkfound=false;  
  const reco::PFBlock& block = *blockref;  
  const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();  
  //use this to store linkdata in the associatedElements function below  
  PFBlock::LinkData linkData =  block.linkData();  
  //calculate MVA Variables  
  chi2=elements[track_index].trackRef()->chi2()/elements[track_index].trackRef()->ndof();  
  nlost=elements[track_index].trackRef()->trackerExpectedHitsInner().numberOfLostHits();  
  nlayers=elements[track_index].trackRef()->hitPattern().trackerLayersWithMeasurement();  
  track_pt=elements[track_index].trackRef()->pt();  
  STIP=elements[track_index].trackRefPF()->STIP();  
   
  float linked_e=0;  
  float linked_h=0;  
  std::multimap<double, unsigned int> ecalAssoTrack;  
  block.associatedElements( track_index,linkData,  
                            ecalAssoTrack,  
                            reco::PFBlockElement::ECAL,  
                            reco::PFBlock::LINKTEST_ALL );  
  std::multimap<double, unsigned int> hcalAssoTrack;  
  block.associatedElements( track_index,linkData,  
                            hcalAssoTrack,  
                            reco::PFBlockElement::HCAL,  
                            reco::PFBlock::LINKTEST_ALL );  
  if(ecalAssoTrack.size() > 0) {  
    for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoTrack.begin();  
        itecal != ecalAssoTrack.end(); ++itecal) {  
      linked_e=linked_e+elements[itecal->second].clusterRef()->energy();  
    }  
  }  
  if(hcalAssoTrack.size() > 0) {  
    for(std::multimap<double, unsigned int>::iterator ithcal = hcalAssoTrack.begin();  
        ithcal != hcalAssoTrack.end(); ++ithcal) {  
      linked_h=linked_h+elements[ithcal->second].clusterRef()->energy();  
    }  
  }  
  EoverPt=linked_e/elements[track_index].trackRef()->pt();  
  HoverPt=linked_h/elements[track_index].trackRef()->pt();  
  GlobalVector rvtx(elements[track_index].trackRef()->innerPosition().X()-primaryvtx.x(),  
                    elements[track_index].trackRef()->innerPosition().Y()-primaryvtx.y(),  
                    elements[track_index].trackRef()->innerPosition().Z()-primaryvtx.z());  
  double vtx_phi=rvtx.phi();  
  //delta Phi between conversion vertex and track  
  del_phi=fabs(deltaPhi(vtx_phi, elements[track_index].trackRef()->innerMomentum().Phi()));  
  mvaValue = tmvaReader_->EvaluateMVA("BDT");  
  if(mvaValue > MVACUT)convtkfound=true;  
  return convtkfound;  
}
void PFPhotonAlgo::fill5x5Map ( reco::PFClusterRef  clusterRef) [private]

Definition at line 1326 of file PFPhotonAlgo.cc.

References abs, Clus5x5ratio_, ClusR9_, EBDetId::distanceEta(), EBDetId::distancePhi(), EEDetId::distanceX(), EEDetId::distanceY(), e1x3_, e1x5_, e2x5Bottom_, e2x5Left_, e2x5Max_, e2x5Right_, e2x5Top_, e3x1_, e3x3_, e5x5Map, EcalBarrel, EcalEndcap, eSeed_, cropTnPTrees::frac, i, EBDetId::ieta(), getHLTprescales::index, EBDetId::iphi(), EEDetId::ix(), EEDetId::iy(), j, DetId::rawId(), and DetId::subdetId().

Referenced by EvaluateGCorrMVA(), EvaluateLCorrMVA(), and EvaluateResMVA().

                                                        {

  // commented out by Florian. Not used in the code
  //  float PFSeedEta=99;
  //  float PFSeedPhi=99;
  double PFSeedE=0;
  //  unsigned int SeedDetId=-1;
  //  float seedPhi=0;
  //float seedEta=0;
  DetId idseed;
  const std::vector< reco::PFRecHitFraction >& PFRecHits=
    clusterRef->recHitFractions();
  for ( std::vector< reco::PFRecHitFraction >::const_iterator it = PFRecHits.begin();
        it != PFRecHits.end(); ++it){
    const PFRecHitRef& RefPFRecHit = it->recHitRef();
    unsigned index=it-PFRecHits.begin();
    //DetId id=eclusterRef->hitsAndFractions()[index].first;
    float frac=clusterRef->hitsAndFractions()[index].second;
    float E= RefPFRecHit->energy()* frac;
    if(E>PFSeedE){
      //      SeedDetId=RefPFRecHit.index();
      PFSeedE=E;  
      //      PFSeedEta=RefPFRecHit->positionREP().eta(); 
      //      PFSeedPhi=RefPFRecHit->positionREP().phi(); 
      idseed = RefPFRecHit->detId();
    }
  }
  
  
  //initialize 5x5 map
  for(int i=0; i<5; ++i)
    for(int j=0; j<5; ++j)e5x5Map[i][j]=0;
  float E3x3=0;
  float E5x5=0;
  //  int count=0;
  for ( std::vector< reco::PFRecHitFraction >::const_iterator it = PFRecHits.begin();
        it != PFRecHits.end(); ++it){
    unsigned index=it-PFRecHits.begin();
    const PFRecHitRef& RefPFRecHit = it->recHitRef();
    float frac=clusterRef->hitsAndFractions()[index].second;
    DetId id = RefPFRecHit->detId();
    if(idseed.subdetId()==EcalBarrel){
      int deta=EBDetId::distanceEta(id,idseed);
      int dphi=EBDetId::distancePhi(id,idseed); 
      EBDetId EBidSeed=EBDetId(idseed.rawId());
      if(abs(dphi)<=1 && abs(deta)<=1)
        {
          E3x3=E3x3+(RefPFRecHit->energy()*frac);
        }
      if(abs(dphi)<=2 && abs(deta)<=2)
        {
          //center the array on [2][2] to be the Seed
          //deta and deta are unsigned so you want to recompute 
          //to get top bottom left right 
          EBDetId EBid=EBDetId(id.rawId());
          //note this is actually opposite to make it consistent to the lazy tools left right which inverts them
          int i=EBidSeed.ieta()-EBid.ieta();
          
          int j=EBid.iphi()-EBidSeed.iphi();
          int iEta=i+2;
          int iPhi=j+2;
          
          e5x5Map[iEta][iPhi]=RefPFRecHit->energy()*frac;
          E5x5=E5x5+(RefPFRecHit->energy()*frac);
        }
    }
    if(idseed.subdetId()==EcalEndcap){
      //dx and dy are unsigned so you want to recompute 
      //to get top bottom left right 
      int dx=EEDetId::distanceX(id,idseed);
      int dy=EEDetId::distanceY(id,idseed);
      EEDetId EEidSeed=EEDetId(idseed.rawId());
      //dx and dy are unsigned so you want to recompute 
      //to get top bottom left right 
      if(abs(dx)<=1 && abs(dy)<=1)
        {
          E3x3=E3x3+(RefPFRecHit->energy()*frac);
        }
      if(abs(dx)<=2 && abs(dy)<=2)
        {
          EEDetId EEid=EEDetId(id.rawId());
          int i=EEid.ix()-EEidSeed.ix();
          int j=EEid.iy()-EEidSeed.iy();
          //center the array on [2][2] to be the Seed
          int ix=i+2;
          int iy=j+2;
          e5x5Map[ix][iy]=RefPFRecHit->energy()*frac;
          E5x5=E5x5+(RefPFRecHit->energy()*frac);
        }
    }
    
  }
  e3x3_=E3x3;
  ClusR9_=E3x3/clusterRef->energy();
  Clus5x5ratio_=E5x5/clusterRef->energy();
  eSeed_= e5x5Map[2][2]/clusterRef->energy();
  e1x3_=(e5x5Map[2][2]+e5x5Map[1][2]+e5x5Map[3][2])/clusterRef->energy();
  e3x1_=(e5x5Map[2][2]+e5x5Map[2][1]+e5x5Map[2][3])/clusterRef->energy();
  e1x5_=e5x5Map[2][2]+e5x5Map[2][0]+e5x5Map[2][1]+e5x5Map[2][3]+e5x5Map[2][4];
  e2x5Top_=(e5x5Map[0][4]+e5x5Map[1][4]+e5x5Map[2][4]
            +e5x5Map[3][4]+e5x5Map[4][4]
    +e5x5Map[0][3]+e5x5Map[1][3]+e5x5Map[2][3]
            +e5x5Map[3][3]+e5x5Map[4][3])/clusterRef->energy();
  
  e2x5Bottom_=(e5x5Map[0][0]+e5x5Map[1][0]+e5x5Map[2][0]
               +e5x5Map[3][0]+e5x5Map[4][0]
               +e5x5Map[0][1]+e5x5Map[1][1]
               +e5x5Map[2][1]+e5x5Map[3][1]+e5x5Map[4][1])/clusterRef->energy();
  e2x5Left_= ( e5x5Map[0][1]+e5x5Map[0][1]
               +e5x5Map[0][2]+e5x5Map[0][3]+e5x5Map[0][4]
               +e5x5Map[1][0]+e5x5Map[1][1]+e5x5Map[1][2]
               +e5x5Map[1][3]+e5x5Map[1][4])/clusterRef->energy();
  
  e2x5Right_ =(e5x5Map[4][0]+e5x5Map[4][1]
               +e5x5Map[4][2]+e5x5Map[4][3]+e5x5Map[4][4]
               +e5x5Map[3][0]+e5x5Map[3][1]+e5x5Map[3][2]
               +e5x5Map[3][3]+e5x5Map[3][4])/clusterRef->energy(); 
  float centerstrip=e5x5Map[2][2]+e5x5Map[2][0]
    +e5x5Map[2][1]+e5x5Map[2][3]+e5x5Map[2][4];
  float rightstrip=e5x5Map[3][2]+e5x5Map[3][0]
    +e5x5Map[3][1]+e5x5Map[3][3]+e5x5Map[3][4];
  float leftstrip=e5x5Map[1][2]+e5x5Map[1][0]+e5x5Map[1][1]
    +e5x5Map[1][3]+e5x5Map[1][4];
  if(rightstrip>leftstrip)e2x5Max_=rightstrip+centerstrip;
  else e2x5Max_=leftstrip+centerstrip;
  e2x5Max_=e2x5Max_/clusterRef->energy();
}
void PFPhotonAlgo::GetCrysCoordinates ( reco::PFClusterRef  clusterRef) [private]

Definition at line 1230 of file PFPhotonAlgo.cc.

References abs, funct::cos(), CrysEta_, CrysIEta_, CrysIPhi_, CrysPhi_, cropTnPTrees::frac, EBDetId::ieta(), getHLTprescales::index, EBDetId::iphi(), PFCrysEtaCrack_, PFCrysPhiCrack_, colinearityKinematic::Phi, Phi_mpi_pi(), Pi, and DetId::rawId().

Referenced by EvaluateLCorrMVA().

                                                                {
  // Commented by Florian. Source of warnings as not used 
  //  float PFSeedEta=99;
  float PFSeedPhi=99;
  float PFSeedTheta=99;
  double PFSeedE=0;
  //  unsigned int SeedDetId=-1;
  // float seedPhi=0;
  //  float seedEta=0;
  DetId idseed;
  const std::vector< reco::PFRecHitFraction >& PFRecHits=
    clusterRef->recHitFractions();
  for ( std::vector< reco::PFRecHitFraction >::const_iterator it = PFRecHits.begin();
        it != PFRecHits.end(); ++it){
    const PFRecHitRef& RefPFRecHit = it->recHitRef();
    unsigned index=it-PFRecHits.begin();
    float frac=clusterRef->hitsAndFractions()[index].second;
    float E= RefPFRecHit->energy()* frac;
    if(E>PFSeedE){
      //      SeedDetId=RefPFRecHit.index();
      PFSeedE=E;  
      //      PFSeedEta=RefPFRecHit->positionREP().eta(); 
      PFSeedPhi=RefPFRecHit->positionREP().phi();
      PFSeedTheta=RefPFRecHit->positionREP().theta();
      RefPFRecHit->positionREP().theta();
      idseed = RefPFRecHit->detId();
    }
  }
  EBDetId EBidSeed=EBDetId(idseed.rawId());
  CrysIEta_=EBidSeed.ieta();
  CrysIPhi_=EBidSeed.iphi();
  
  //Crystal Coordinates:
  double Pi=TMath::Pi();
  float Phi=clusterRef->position().phi(); 
  //  float Eta=clusterRef->position().eta();
  double Theta = -(clusterRef->position().theta())+0.5* Pi;
  double PhiCentr = TVector2::Phi_mpi_pi(PFSeedPhi);
  double PhiWidth = (Pi/180.);
  double PhiCry = (TVector2::Phi_mpi_pi(Phi-PhiCentr))/PhiWidth;
  double ThetaCentr = -PFSeedTheta+0.5*Pi;
  double ThetaWidth = (Pi/180.)*cos(ThetaCentr);
  
  //cout<<"Clust Theta "<<Theta<<" Crys Theta "<<ThetaCentr<<endl;
  //cout<<" Width "<< ThetaWidth<<endl;
  double EtaCry = (Theta-ThetaCentr)/ThetaWidth; 
  CrysEta_=EtaCry;
  CrysPhi_=PhiCry;
 
  //check Module and crack:
  int iphi=CrysIPhi_;
  int phimod=iphi%20;
  if(phimod>1)PFCrysPhiCrack_=2;
  else PFCrysPhiCrack_=phimod; //should be 0, 1
  
  if(abs(CrysIEta_)==1 || abs(CrysIEta_)==2 )
    PFCrysEtaCrack_=abs(CrysIEta_);
  if(abs(CrysIEta_)>2 && abs(CrysIEta_)<24)
    PFCrysEtaCrack_=3;
  if(abs(CrysIEta_)==24)
    PFCrysEtaCrack_=4;
  if(abs(CrysIEta_)==25)
        PFCrysEtaCrack_=5;
      if(abs(CrysIEta_)==26)
        PFCrysEtaCrack_=6;
      if(abs(CrysIEta_)==27)
                PFCrysEtaCrack_=7;
      if(abs(CrysIEta_)>27 &&  abs(CrysIEta_)<44)
        PFCrysEtaCrack_=8;
      if(abs(CrysIEta_)==44)
                PFCrysEtaCrack_=9;
      if(abs(CrysIEta_)==45)
        PFCrysEtaCrack_=10;
      if(abs(CrysIEta_)==46)
                PFCrysEtaCrack_=11;
      if(abs(CrysIEta_)==47)
        PFCrysEtaCrack_=12;
      if(abs(CrysIEta_)>47 &&  abs(CrysIEta_)<64)
        PFCrysEtaCrack_=13;
      if(abs(CrysIEta_)==64)
        PFCrysEtaCrack_=14;
      if(abs(CrysIEta_)==65)
        PFCrysEtaCrack_=15;
      if(abs(CrysIEta_)==66)
        PFCrysEtaCrack_=16;
      if(abs(CrysIEta_)==67)
        PFCrysEtaCrack_=17;
      if(abs(CrysIEta_)>67 &&  abs(CrysIEta_)<84)
        PFCrysEtaCrack_=18;
      if(abs(CrysIEta_)==84)
        PFCrysEtaCrack_=19;
      if(abs(CrysIEta_)==85)
        PFCrysEtaCrack_=20;
      
}
std::vector<int> PFPhotonAlgo::getPFMustacheClus ( int  nClust,
std::vector< float > &  ClustEt,
std::vector< float > &  ClustEta,
std::vector< float > &  ClustPhi 
) [private]
bool PFPhotonAlgo::isPhotonValidCandidate ( const reco::PFBlockRef blockRef,
std::vector< bool > &  active,
std::auto_ptr< reco::PFCandidateCollection > &  pfPhotonCandidates,
std::vector< reco::PFCandidatePhotonExtra > &  pfPhotonExtraCandidates,
std::vector< reco::PFCandidate > &  tempElectronCandidates 
) [inline]

Definition at line 56 of file PFPhotonAlgo.h.

References i, isvalid_, match_ind, permElectronCandidates_, and RunPFPhoton().

Referenced by PFAlgoTestBenchElectrons::processBlock().

                               {
    isvalid_=false;
    // RunPFPhoton has to set isvalid_ to TRUE in case it finds a valid candidate
    // ... TODO: maybe can be replaced by checking for the size of the CandCollection.....
    permElectronCandidates_.clear();
    match_ind.clear();
    RunPFPhoton(blockRef,
                active,
                pfPhotonCandidates,
                pfPhotonExtraCandidates,
                tempElectronCandidates
                );
    int ind=0;
    bool matched=false;
    int matches=match_ind.size();
    
    for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin();   ec != tempElectronCandidates.end(); ++ec){
      for(int i=0; i<matches; i++)
        {
          if(ind==match_ind[i])
            {
              matched=true; 
              //std::cout<<"This is matched in .h "<<*ec<<std::endl; 
                break;
            }
        }
      ++ind;
      if(matched)continue;
      permElectronCandidates_.push_back(*ec);     
      //std::cout<<"This is NOT matched in .h "<<*ec<<std::endl; 
    }
    
    match_ind.clear();
    
    tempElectronCandidates.clear(); 
    for ( std::vector<reco::PFCandidate>::const_iterator ec=permElectronCandidates_.begin();   ec != permElectronCandidates_.end(); ++ec)tempElectronCandidates.push_back(*ec);
    permElectronCandidates_.clear();
    
    return isvalid_;
  };
void PFPhotonAlgo::RunPFPhoton ( const reco::PFBlockRef blockRef,
std::vector< bool > &  active,
std::auto_ptr< reco::PFCandidateCollection > &  pfPhotonCandidates,
std::vector< reco::PFCandidatePhotonExtra > &  pfPhotonExtraCandidates,
std::vector< reco::PFCandidate > &  tempElectronCandidates 
) [private]

Definition at line 69 of file PFPhotonAlgo.cc.

References reco::CompositeCandidate::addDaughter(), reco::PFCandidate::addElementInBlock(), AddFromElectron_, edm::OwnVector< T, P >::begin(), Chatty, convBrem_cff::convTracks, prof2calltree::count, EarlyConversion(), ECAL, PFLayer::ECAL_BARREL, asciidump::elements, edm::OwnVector< T, P >::end(), EvaluateGCorrMVA(), EvaluateLCorrMVA(), EvaluateResMVA(), EvaluateSingleLegMVA(), reco::PFBlockElementSuperCluster::fromPhoton(), reco::PFCandidate::gamma, reco::PFCandidate::GAMMA_TO_GAMMACONV, reco::PFBlockElement::HCAL, i, getHLTprescales::index, isvalid_, prof2calltree::l, reco::PFBlock::LINKTEST_ALL, match_ind, reco::Mustache::MustacheID(), mvaValue, primaryVertex_, reco::PFBlockElement::PS1, reco::PFBlockElement::PS2, edm::OwnVector< T, P >::push_back(), edm::RefVector< C, T, F >::push_back(), FitTarget::Res, reco::PFBlockElement::SC, reco::PFCandidate::set_mva_nothing_gamma(), reco::PFCandidate::setEcalEnergy(), reco::PFCandidate::setFlag(), reco::PFCandidate::setHcalEnergy(), reco::LeafCandidate::setP4(), reco::PFCandidate::setPs1Energy(), reco::PFCandidate::setPs2Energy(), reco::PFCandidate::setSuperClusterRef(), reco::PFCandidate::setVertex(), edm::OwnVector< T, P >::size(), edm::RefVector< C, T, F >::size(), mathSSE::sqrt(), sumPtTrackIsoForPhoton_, sumPtTrackIsoSlopeForPhoton_, reco::PFBlockElementSuperCluster::superClusterRef(), reco::PFBlockElement::T_FROM_GAMMACONV, thePFEnergyCalibration_, reco::PFBlockElement::TRACK, reco::PFBlockElementTrack::trackType(), useReg_, v, verbosityLevel_, reco::Vertex::x(), reco::Vertex::y(), and reco::Vertex::z().

Referenced by isPhotonValidCandidate().

 {
  
  //std::cout<<" calling RunPFPhoton "<<std::endl;
  
  /*      For now we construct the PhotonCandidate simply from 
          a) adding the CORRECTED energies of each participating ECAL cluster
          b) build the energy-weighted direction for the Photon
  */


  // define how much is printed out for debugging.
  // ... will be setable via CFG file parameter
  verbosityLevel_ = Chatty;          // Chatty mode.
  

  // loop over all elements in the Block
  const edm::OwnVector< reco::PFBlockElement >&          elements         = blockRef->elements();
  edm::OwnVector< reco::PFBlockElement >::const_iterator ele              = elements.begin();
  std::vector<bool>::const_iterator                      actIter          = active.begin();
  PFBlock::LinkData                                      linkData         = blockRef->linkData();
  bool                                                   isActive         = true;


  if(elements.size() != active.size()) {
    // throw excpetion...
    //std::cout<<" WARNING: Size of collection and active-vectro don't agree!"<<std::endl;
    return;
  }
  
  // local vecotr to keep track of the indices of the 'elements' for the Photon candidate
  // once we decide to keep the candidate, the 'active' entriesd for them must be set to false
  std::vector<unsigned int> elemsToLock;
  elemsToLock.resize(0);
  
  for( ; ele != elements.end(); ++ele, ++actIter ) {

    // if it's not a SuperCluster, go to the next element
    if( !( ele->type() == reco::PFBlockElement::SC ) ) continue;
    
    // Photon kienmatics, will be updated for each identified participating element
    float photonEnergy_        =   0.;
    float photonX_             =   0.;
    float photonY_             =   0.;
    float photonZ_             =   0.;
    float RawEcalEne           =   0.;

    // Total pre-shower energy
    float ps1TotEne      = 0.;
    float ps2TotEne      = 0.;
    
    bool hasConvTrack=false;  
    bool hasSingleleg=false;  
    std::vector<unsigned int> AddClusters(0);  
    std::vector<unsigned int> IsoTracks(0);  
    std::multimap<unsigned int, unsigned int>ClusterAddPS1;  
    std::multimap<unsigned int, unsigned int>ClusterAddPS2;
    std::vector<reco::TrackRef>singleLegRef;
    std::vector<float>MVA_values(0);
    std::vector<float>MVALCorr;
    std::vector<const CaloCluster*>PFClusters;
    reco::ConversionRefVector ConversionsRef_;
    isActive = *(actIter);
    //cout << " Found a SuperCluster.  Energy " ;
    const reco::PFBlockElementSuperCluster *sc = dynamic_cast<const reco::PFBlockElementSuperCluster*>(&(*ele));
    //std::cout << sc->superClusterRef()->energy () << " Track/Ecal/Hcal Iso " << sc->trackIso()<< " " << sc->ecalIso() ;
    //std::cout << " " << sc->hcalIso() <<std::endl;
    if (!(sc->fromPhoton()))continue;

    // check the status of the SC Element... 
    // ..... I understand it should *always* be active, since PFElectronAlgo does not touch this (yet?) RISHI: YES
    if( !isActive ) {
      //std::cout<<" SuperCluster is NOT active.... "<<std::endl;
      continue;
    }
    elemsToLock.push_back(ele-elements.begin()); //add SC to elements to lock
    // loop over its constituent ECAL cluster
    std::multimap<double, unsigned int> ecalAssoPFClusters;
    blockRef->associatedElements( ele-elements.begin(), 
                                  linkData,
                                  ecalAssoPFClusters,
                                  reco::PFBlockElement::ECAL,
                                  reco::PFBlock::LINKTEST_ALL );
    
    // loop over the ECAL clusters linked to the iEle 
    if( ! ecalAssoPFClusters.size() ) {
      // This SC element has NO ECAL elements asigned... *SHOULD NOT HAPPEN*
      //std::cout<<" Found SC element with no ECAL assigned "<<std::endl;
      continue;
    }
    
    // This is basically CASE 2
    // .... we loop over all ECAL cluster linked to each other by this SC
    for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoPFClusters.begin(); 
        itecal != ecalAssoPFClusters.end(); ++itecal) { 
      
      // to get the reference to the PF clusters, this is needed.
      reco::PFClusterRef clusterRef = elements[itecal->second].clusterRef();    
      
      // from the clusterRef get the energy, direction, etc
      //      float ClustRawEnergy = clusterRef->energy();
      //      float ClustEta = clusterRef->position().eta();
      //      float ClustPhi = clusterRef->position().phi();

      // initialize the vectors for the PS energies
      vector<double> ps1Ene(0);
      vector<double> ps2Ene(0);
      double ps1=0;  
      double ps2=0;  
      hasSingleleg=false;  
      hasConvTrack=false;

      /*
      cout << " My cluster index " << itecal->second 
           << " energy " <<  ClustRawEnergy
           << " eta " << ClustEta
           << " phi " << ClustPhi << endl;
      */
      // check if this ECAL element is still active (could have been eaten by PFElectronAlgo)
      // ......for now we give the PFElectron Algo *ALWAYS* Shot-Gun on the ECAL elements to the PFElectronAlgo
      
      if( !( active[itecal->second] ) ) {
        //std::cout<< "  .... this ECAL element is NOT active anymore. Is skipped. "<<std::endl;
        continue;
      }
      
      // ------------------------------------------------------------------------------------------
      // TODO: do some tests on the ECAL cluster itself, deciding to use it or not for the Photons
      // ..... ??? Do we need this?
      if ( false ) {
        // Check if there are a large number tracks that do not pass pre-ID around this ECAL cluster
        bool useIt = true;
        int mva_reject=0;  
        bool isClosest=false;  
        std::multimap<double, unsigned int> Trackscheck;  
        blockRef->associatedElements( itecal->second,  
                                      linkData,  
                                      Trackscheck,  
                                      reco::PFBlockElement::TRACK,  
                                      reco::PFBlock::LINKTEST_ALL);  
        for(std::multimap<double, unsigned int>::iterator track = Trackscheck.begin();  
            track != Trackscheck.end(); ++track) {  
           
          // first check if is it's still active  
          if( ! (active[track->second]) ) continue;  
          hasSingleleg=EvaluateSingleLegMVA(blockRef,  primaryVertex_, track->second);  
          //check if it is the closest linked track  
          std::multimap<double, unsigned int> closecheck;  
          blockRef->associatedElements(track->second,  
                                       linkData,  
                                       closecheck,  
                                       reco::PFBlockElement::ECAL,  
                                       reco::PFBlock::LINKTEST_ALL);  
          if(closecheck.begin()->second ==itecal->second)isClosest=true;  
          if(!hasSingleleg)mva_reject++;  
        }  
         
        if(mva_reject>0 &&  isClosest)useIt=false;  
        //if(mva_reject==1 && isClosest)useIt=false;
        if( !useIt ) continue;    // Go to next ECAL cluster within SC
      }
      // ------------------------------------------------------------------------------------------
      
      // We decided to keep the ECAL cluster for this Photon Candidate ...
      elemsToLock.push_back(itecal->second);
      
      // look for PS in this Block linked to this ECAL cluster      
      std::multimap<double, unsigned int> PS1Elems;
      std::multimap<double, unsigned int> PS2Elems;
      //PS Layer 1 linked to ECAL cluster
      blockRef->associatedElements( itecal->second,
                                    linkData,
                                    PS1Elems,
                                    reco::PFBlockElement::PS1,
                                    reco::PFBlock::LINKTEST_ALL );
      //PS Layer 2 linked to the ECAL cluster
      blockRef->associatedElements( itecal->second,
                                    linkData,
                                    PS2Elems,
                                    reco::PFBlockElement::PS2,
                                    reco::PFBlock::LINKTEST_ALL );
      
      // loop over all PS1 and compute energy
      for(std::multimap<double, unsigned int>::iterator iteps = PS1Elems.begin();
          iteps != PS1Elems.end(); ++iteps) {

        // first chekc if it's still active
        if( !(active[iteps->second]) ) continue;
        
        //Check if this PS1 is not closer to another ECAL cluster in this Block          
        std::multimap<double, unsigned int> ECALPS1check;  
        blockRef->associatedElements( iteps->second,  
                                      linkData,  
                                      ECALPS1check,  
                                      reco::PFBlockElement::ECAL,  
                                      reco::PFBlock::LINKTEST_ALL );  
        if(itecal->second==ECALPS1check.begin()->second)//then it is closest linked  
          {
            reco::PFClusterRef ps1ClusterRef = elements[iteps->second].clusterRef();
            ps1Ene.push_back( ps1ClusterRef->energy() );
            ps1=ps1+ps1ClusterRef->energy(); //add to total PS1
            // incativate this PS1 Element
            elemsToLock.push_back(iteps->second);
          }
      }
      for(std::multimap<double, unsigned int>::iterator iteps = PS2Elems.begin();
          iteps != PS2Elems.end(); ++iteps) {

        // first chekc if it's still active
        if( !(active[iteps->second]) ) continue;
        
        // Check if this PS2 is not closer to another ECAL cluster in this Block:
        std::multimap<double, unsigned int> ECALPS2check;  
        blockRef->associatedElements( iteps->second,  
                                      linkData,  
                                      ECALPS2check,  
                                      reco::PFBlockElement::ECAL,  
                                      reco::PFBlock::LINKTEST_ALL );  
        if(itecal->second==ECALPS2check.begin()->second)//is closest linked  
          {
            reco::PFClusterRef ps2ClusterRef = elements[iteps->second].clusterRef();
            ps2Ene.push_back( ps2ClusterRef->energy() );
            ps2=ps2ClusterRef->energy()+ps2; //add to total PS2
            // incativate this PS2 Element
            elemsToLock.push_back(iteps->second);
          }
      }
            
      // loop over the HCAL Clusters linked to the ECAL cluster (CASE 6)
      std::multimap<double, unsigned int> hcalElems;
      blockRef->associatedElements( itecal->second,linkData,
                                    hcalElems,
                                    reco::PFBlockElement::HCAL,
                                    reco::PFBlock::LINKTEST_ALL );

      for(std::multimap<double, unsigned int>::iterator ithcal = hcalElems.begin();
          ithcal != hcalElems.end(); ++ithcal) {

        if ( ! (active[ithcal->second] ) ) continue; // HCAL Cluster already used....
        
        // TODO: Decide if this HCAL cluster is to be used
        // .... based on some Physics
        // .... To we need to check if it's closer to any other ECAL/TRACK?

        bool useHcal = false;
        if ( !useHcal ) continue;
        //not locked
        //elemsToLock.push_back(ithcal->second);
      }

      // This is entry point for CASE 3.
      // .... we loop over all Tracks linked to this ECAL and check if it's labeled as conversion
      // This is the part for looping over all 'Conversion' Tracks
      std::multimap<double, unsigned int> convTracks;
      blockRef->associatedElements( itecal->second,
                                    linkData,
                                    convTracks,
                                    reco::PFBlockElement::TRACK,
                                    reco::PFBlock::LINKTEST_ALL);
      for(std::multimap<double, unsigned int>::iterator track = convTracks.begin();
          track != convTracks.end(); ++track) {

        // first check if is it's still active
        if( ! (active[track->second]) ) continue;
        
        // check if it's a CONV track
        const reco::PFBlockElementTrack * trackRef = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[track->second]));        
        
        //Check if track is a Single leg from a Conversion  
        mvaValue=-999;  
        hasSingleleg=EvaluateSingleLegMVA(blockRef,  primaryVertex_, track->second);  

        // Daniele; example for mvaValues, do the same for single leg trackRef and convRef
        //          
        //      if(hasSingleleg)
        //        mvaValues.push_back(mvaValue);

        //If it is not then it will be used to check Track Isolation at the end  
        if(!hasSingleleg)  
          {  
            bool included=false;  
            //check if this track is already included in the vector so it is linked to an ECAL cluster that is already examined  
            for(unsigned int i=0; i<IsoTracks.size(); i++)  
              {if(IsoTracks[i]==track->second)included=true;}  
            if(!included)IsoTracks.push_back(track->second);  
          }  
        //For now only Pre-ID tracks that are not already identified as Conversions  
        if(hasSingleleg &&!(trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)))  
          {  
            elemsToLock.push_back(track->second);
            
            reco::TrackRef t_ref=elements[track->second].trackRef();
            bool matched=false;
            for(unsigned int ic=0; ic<singleLegRef.size(); ic++)
              if(singleLegRef[ic]==t_ref)matched=true;
            
            if(!matched){
              singleLegRef.push_back(t_ref);
              MVA_values.push_back(mvaValue);
            }
            //find all the clusters linked to this track  
            std::multimap<double, unsigned int> moreClusters;  
            blockRef->associatedElements( track->second,  
                                          linkData,  
                                          moreClusters,  
                                          reco::PFBlockElement::ECAL,  
                                          reco::PFBlock::LINKTEST_ALL);  
             
            float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x() * elements[track->second].trackRef()->innerMomentum().x() +  
                            elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+  
                            elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());  
            float linked_E=0;  
            for(std::multimap<double, unsigned int>::iterator clust = moreClusters.begin();  
                clust != moreClusters.end(); ++clust)  
              {  
                if(!active[clust->second])continue;  
                //running sum of linked energy  
                linked_E=linked_E+elements[clust->second].clusterRef()->energy();  
                //prevent too much energy from being added  
                if(linked_E/p_in>1.5)break;  
                bool included=false;  
                //check if these ecal clusters are already included with the supercluster  
                for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();  
                    cluscheck != ecalAssoPFClusters.end(); ++cluscheck)  
                  {  
                    if(cluscheck->second==clust->second)included=true;  
                  }  
                if(!included)AddClusters.push_back(clust->second);//Add to a container of clusters to be Added to the Photon candidate  
              }  
          }

        // Possibly need to be more smart about them (CASE 5)
        // .... for now we simply skip non id'ed tracks
        if( ! (trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) ) continue;  
        hasConvTrack=true;  
        elemsToLock.push_back(track->second);
        //again look at the clusters linked to this track  
        //if(elements[track->second].convRef().isNonnull())
        //{         
        //  ConversionsRef_.push_back(elements[track->second].convRef());
        //}
        std::multimap<double, unsigned int> moreClusters;  
        blockRef->associatedElements( track->second,  
                                      linkData,  
                                      moreClusters,  
                                      reco::PFBlockElement::ECAL,  
                                      reco::PFBlock::LINKTEST_ALL);
        
        float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x() * elements[track->second].trackRef()->innerMomentum().x() +  
                        elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+  
                        elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());  
        float linked_E=0;  
        for(std::multimap<double, unsigned int>::iterator clust = moreClusters.begin();  
            clust != moreClusters.end(); ++clust)  
          {  
            if(!active[clust->second])continue;  
            linked_E=linked_E+elements[clust->second].clusterRef()->energy();  
            if(linked_E/p_in>1.5)break;  
            bool included=false;  
            for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();  
                cluscheck != ecalAssoPFClusters.end(); ++cluscheck)  
              {  
                if(cluscheck->second==clust->second)included=true;  
              }  
            if(!included)AddClusters.push_back(clust->second);//again only add if it is not already included with the supercluster  
          }
        
        // we need to check for other TRACKS linked to this conversion track, that point possibly no an ECAL cluster not included in the SC
        // .... This is basically CASE 4.
        
        std::multimap<double, unsigned int> moreTracks;
        blockRef->associatedElements( track->second,
                                      linkData,
                                      moreTracks,
                                      reco::PFBlockElement::TRACK,
                                      reco::PFBlock::LINKTEST_ALL);
        
        for(std::multimap<double, unsigned int>::iterator track2 = moreTracks.begin();
            track2 != moreTracks.end(); ++track2) {
          
          // first check if is it's still active
          if( ! (active[track2->second]) ) continue;
          //skip over the 1st leg already found above  
          if(track->second==track2->second)continue;      
          // check if it's a CONV track
          const reco::PFBlockElementTrack * track2Ref = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[track2->second]));    
          if( ! (track2Ref->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) ) continue;  // Possibly need to be more smart about them (CASE 5)
          elemsToLock.push_back(track2->second);
          // so it's another active conversion track, that is in the Block and linked to the conversion track we already found
          // find the ECAL cluster linked to it...
          std::multimap<double, unsigned int> convEcal;
          blockRef->associatedElements( track2->second,
                                        linkData,
                                        convEcal,
                                        reco::PFBlockElement::ECAL,
                                        reco::PFBlock::LINKTEST_ALL);
          float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x()*elements[track->second].trackRef()->innerMomentum().x()+
                          elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+  
                          elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());  
          
          
          float linked_E=0;
          for(std::multimap<double, unsigned int>::iterator itConvEcal = convEcal.begin();
              itConvEcal != convEcal.end(); ++itConvEcal) {
            
            if( ! (active[itConvEcal->second]) ) continue;
            bool included=false;  
            for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();  
                cluscheck != ecalAssoPFClusters.end(); ++cluscheck)  
              {  
                if(cluscheck->second==itConvEcal->second)included=true;  
              }
            linked_E=linked_E+elements[itConvEcal->second].clusterRef()->energy();
            if(linked_E/p_in>1.5)break;
            if(!included){AddClusters.push_back(itConvEcal->second);
            }
            
            // it's still active, so we have to add it.
            // CAUTION: we don't care here if it's part of the SC or not, we include it anyways
            
            // loop over the HCAL Clusters linked to the ECAL cluster (CASE 6)
            std::multimap<double, unsigned int> hcalElems_conv;
            blockRef->associatedElements( itecal->second,linkData,
                                          hcalElems_conv,
                                          reco::PFBlockElement::HCAL,
                                          reco::PFBlock::LINKTEST_ALL );
            
            for(std::multimap<double, unsigned int>::iterator ithcal2 = hcalElems_conv.begin();
                ithcal2 != hcalElems_conv.end(); ++ithcal2) {
              
              if ( ! (active[ithcal2->second] ) ) continue; // HCAL Cluster already used....
              
              // TODO: Decide if this HCAL cluster is to be used
              // .... based on some Physics
              // .... To we need to check if it's closer to any other ECAL/TRACK?
              
              bool useHcal = true;
              if ( !useHcal ) continue;
              
              //elemsToLock.push_back(ithcal2->second);

            } // end of loop over HCAL clusters linked to the ECAL cluster from second CONVERSION leg
            
          } // end of loop over ECALs linked to second T_FROM_GAMMACONV
          
        } // end of loop over SECOND conversion leg

        // TODO: Do we need to check separatly if there are HCAL cluster linked to the track?
        
      } // end of loop over tracks
      
            
      // Calibrate the Added ECAL energy
      float addedCalibEne=0;
      float addedRawEne=0;
      std::vector<double>AddedPS1(0);
      std::vector<double>AddedPS2(0);  
      double addedps1=0;  
      double addedps2=0;  
      for(unsigned int i=0; i<AddClusters.size(); i++)  
        {  
          std::multimap<double, unsigned int> PS1Elems_conv;  
          std::multimap<double, unsigned int> PS2Elems_conv;  
          blockRef->associatedElements(AddClusters[i],  
                                       linkData,  
                                       PS1Elems_conv,  
                                       reco::PFBlockElement::PS1,  
                                       reco::PFBlock::LINKTEST_ALL );  
          blockRef->associatedElements( AddClusters[i],  
                                        linkData,  
                                        PS2Elems_conv,  
                                        reco::PFBlockElement::PS2,  
                                        reco::PFBlock::LINKTEST_ALL );  
           
          for(std::multimap<double, unsigned int>::iterator iteps = PS1Elems_conv.begin();  
              iteps != PS1Elems_conv.end(); ++iteps)  
            {  
              if(!active[iteps->second])continue;  
              std::multimap<double, unsigned int> PS1Elems_check;  
              blockRef->associatedElements(iteps->second,  
                                           linkData,  
                                           PS1Elems_check,  
                                           reco::PFBlockElement::ECAL,  
                                           reco::PFBlock::LINKTEST_ALL );  
              if(PS1Elems_check.begin()->second==AddClusters[i])  
                {  
                   
                  reco::PFClusterRef ps1ClusterRef = elements[iteps->second].clusterRef();  
                  AddedPS1.push_back(ps1ClusterRef->energy());  
                  addedps1=addedps1+ps1ClusterRef->energy();  
                  elemsToLock.push_back(iteps->second);  
                }  
            }  
           
          for(std::multimap<double, unsigned int>::iterator iteps = PS2Elems_conv.begin();  
              iteps != PS2Elems_conv.end(); ++iteps) {  
            if(!active[iteps->second])continue;  
            std::multimap<double, unsigned int> PS2Elems_check;  
            blockRef->associatedElements(iteps->second,  
                                         linkData,  
                                         PS2Elems_check,  
                                         reco::PFBlockElement::ECAL,  
                                         reco::PFBlock::LINKTEST_ALL );  
             
            if(PS2Elems_check.begin()->second==AddClusters[i])  
              {  
                reco::PFClusterRef ps2ClusterRef = elements[iteps->second].clusterRef();  
                AddedPS2.push_back(ps2ClusterRef->energy());  
                addedps2=addedps2+ps2ClusterRef->energy();  
                elemsToLock.push_back(iteps->second);  
              }  
          }  
          reco::PFClusterRef AddclusterRef = elements[AddClusters[i]].clusterRef();  
          addedRawEne = AddclusterRef->energy()+addedRawEne;  
          addedCalibEne = thePFEnergyCalibration_->energyEm(*AddclusterRef,AddedPS1,AddedPS2,false)+addedCalibEne;  
          AddedPS2.clear(); 
          AddedPS1.clear();  
          elemsToLock.push_back(AddClusters[i]);  
        }  
      AddClusters.clear();
      float EE=thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,false)+addedCalibEne;
      PFClusters.push_back(&*clusterRef);
      if(useReg_){
        if(clusterRef->layer()==PFLayer::ECAL_BARREL){
          float LocCorr=EvaluateLCorrMVA(clusterRef);
          EE=LocCorr*clusterRef->energy()+addedCalibEne;
        }
        else{
          EE = thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,false)+addedCalibEne; 
          MVALCorr.push_back(thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,false));
        }       
      }
      else{
        if(clusterRef->layer()==PFLayer::ECAL_BARREL){
          float LocCorr=EvaluateLCorrMVA(clusterRef);
          MVALCorr.push_back(LocCorr*clusterRef->energy());
            }
        else{
          
          MVALCorr.push_back(thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,false));         
        }
      }
      
      //cout<<"Original Energy "<<EE<<"Added Energy "<<addedCalibEne<<endl;
      
      photonEnergy_ +=  EE;
      RawEcalEne    +=  clusterRef->energy()+addedRawEne;
      photonX_      +=  EE * clusterRef->position().X();
      photonY_      +=  EE * clusterRef->position().Y();
      photonZ_      +=  EE * clusterRef->position().Z();                
      ps1TotEne     +=  ps1+addedps1;
      ps2TotEne     +=  ps2+addedps2;
    } // end of loop over all ECAL cluster within this SC
    AddFromElectron_.clear();
    float Elec_energy=0;
    float Elec_rawEcal=0;
    float Elec_totPs1=0;
    float Elec_totPs2=0;
    float ElectronX=0;
    float ElectronY=0;
    float ElectronZ=0;  
    std::vector<double>AddedPS1(0);
    std::vector<double>AddedPS2(0);
    
    EarlyConversion(    
            tempElectronCandidates,
            sc
            );   
    
    if(AddFromElectron_.size()>0)
      { 
        //collect elements from early Conversions that are reconstructed as Electrons
        
        for(std::vector<unsigned int>::const_iterator it = 
              AddFromElectron_.begin();
            it != AddFromElectron_.end(); ++it)
          {
            
            if(elements[*it].type()== reco::PFBlockElement::ECAL)
              {
                //cout<<"Cluster ind "<<*it<<endl;
                AddedPS1.clear();
                AddedPS2.clear();
                unsigned int index=*it;
                reco::PFClusterRef clusterRef = 
                elements[index].clusterRef();
                //match to PS1 and PS2 to this cluster for calibration
                Elec_rawEcal=Elec_rawEcal+
                  elements[index].clusterRef()->energy();
                std::multimap<double, unsigned int> PS1Elems;  
                std::multimap<double, unsigned int> PS2Elems;  
                
                blockRef->associatedElements(index,  
                                             linkData,  
                                             PS1Elems,                                               reco::PFBlockElement::PS1,  
                                             reco::PFBlock::LINKTEST_ALL );  
                blockRef->associatedElements( index,  
                                              linkData,  
                                              PS2Elems,  
                                              reco::PFBlockElement::PS2,  
                                              reco::PFBlock::LINKTEST_ALL );
                
                
                for(std::multimap<double, unsigned int>::iterator iteps = 
                      PS1Elems.begin();  
                    iteps != PS1Elems.end(); ++iteps) 
                  {  
                    std::multimap<double, unsigned int> Clustcheck;                         blockRef->associatedElements( iteps->second,                                                                   linkData,  
                                                                                                                          Clustcheck,  
                                                                                                                          reco::PFBlockElement::ECAL,  
                                                                                                                          reco::PFBlock::LINKTEST_ALL );
                    if(Clustcheck.begin()->second==index)
                      {
                        AddedPS1.push_back(elements[iteps->second].clusterRef()->energy());
                        Elec_totPs1=Elec_totPs1+elements[iteps->second].clusterRef()->energy();
                      }
                  }
                
                for(std::multimap<double, unsigned int>::iterator iteps = 
                      PS2Elems.begin();  
                    iteps != PS2Elems.end(); ++iteps) 
                  {  
                    std::multimap<double, unsigned int> Clustcheck;                         blockRef->associatedElements( iteps->second,                                                                   linkData,  
                                                                                                                          Clustcheck,  
                                                                                                                          reco::PFBlockElement::ECAL,  
                                                                                                                          reco::PFBlock::LINKTEST_ALL );
                    if(Clustcheck.begin()->second==index)
                      {
                        AddedPS2.push_back(elements[iteps->second].clusterRef()->energy());
                        Elec_totPs2=Elec_totPs2+elements[iteps->second].clusterRef()->energy();
                      }
                  }
                
              //energy calibration 
                float EE=thePFEnergyCalibration_->
                  energyEm(*clusterRef,AddedPS1,AddedPS2,false);
                PFClusters.push_back(&*clusterRef);
                if(useReg_){
                  if(clusterRef->layer()==PFLayer::ECAL_BARREL){
                    float LocCorr=EvaluateLCorrMVA(clusterRef);
                    EE=LocCorr*clusterRef->energy();      
                    MVALCorr.push_back(LocCorr*clusterRef->energy());
                  }
                  else {
                    EE=thePFEnergyCalibration_->energyEm(*clusterRef,AddedPS1,AddedPS2,false);
                    MVALCorr.push_back(EE);
                  }
                }
                else{
                  if(clusterRef->layer()==PFLayer::ECAL_BARREL){
                    float LocCorr=EvaluateLCorrMVA(clusterRef);
                    MVALCorr.push_back(LocCorr*clusterRef->energy());
                  }
                  else{
                    
                    MVALCorr.push_back(thePFEnergyCalibration_->energyEm(*clusterRef, AddedPS1,AddedPS2,false));          
                  }
                }
                
                Elec_energy    += EE;
                ElectronX      +=  EE * clusterRef->position().X();
                ElectronY      +=  EE * clusterRef->position().Y();
                ElectronZ      +=  EE * clusterRef->position().Z();
                
              }
          }
        
      }
    
    //std::cout<<"Added Energy to Photon "<<Elec_energy<<" to "<<photonEnergy_<<std::endl;   
    photonEnergy_ +=  Elec_energy;
    RawEcalEne    +=  Elec_rawEcal;
    photonX_      +=  ElectronX;
    photonY_      +=  ElectronY;
    photonZ_      +=  ElectronZ;                
    ps1TotEne     +=  Elec_totPs1;
    ps2TotEne     +=  Elec_totPs2;
    
    // we've looped over all ECAL clusters, ready to generate PhotonCandidate
    if( ! (photonEnergy_ > 0.) ) continue;    // This SC is not a Photon Candidate
    float sum_track_pt=0;
    //Now check if there are tracks failing isolation outside of the Jurassic isolation region  
    for(unsigned int i=0; i<IsoTracks.size(); i++)sum_track_pt=sum_track_pt+elements[IsoTracks[i]].trackRef()->pt();  
    


    math::XYZVector photonPosition(photonX_,
                                   photonY_,
                                   photonZ_);

    math::XYZVector photonDirection=photonPosition.Unit();
    
    math::XYZTLorentzVector photonMomentum(photonEnergy_* photonDirection.X(),
                                           photonEnergy_* photonDirection.Y(),
                                           photonEnergy_* photonDirection.Z(),
                                           photonEnergy_           );

    if(sum_track_pt>(sumPtTrackIsoForPhoton_ + sumPtTrackIsoSlopeForPhoton_ * photonMomentum.pt()))
      {
        //cout<<"Hit Continue "<<endl;
        match_ind.clear(); //release the matched Electron candidates
        continue;
      }

        //THIS SC is not a Photon it fails track Isolation
    //if(sum_track_pt>(2+ 0.001* photonMomentum.pt()))
    //continue;//THIS SC is not a Photon it fails track Isolation

    /*
    std::cout<<" Created Photon with energy = "<<photonEnergy_<<std::endl;
    std::cout<<"                         pT = "<<photonMomentum.pt()<<std::endl;
    std::cout<<"                     RawEne = "<<RawEcalEne<<std::endl;
    std::cout<<"                          E = "<<photonMomentum.e()<<std::endl;
    std::cout<<"                        eta = "<<photonMomentum.eta()<<std::endl;
    std::cout<<"             TrackIsolation = "<< sum_track_pt <<std::endl;
    */

    reco::PFCandidate photonCand(0,photonMomentum, reco::PFCandidate::gamma);
    
    photonCand.setPs1Energy(ps1TotEne);
    photonCand.setPs2Energy(ps2TotEne);
    photonCand.setEcalEnergy(RawEcalEne,photonEnergy_);
    photonCand.setHcalEnergy(0.,0.);
    photonCand.set_mva_nothing_gamma(1.);  
    photonCand.setSuperClusterRef(sc->superClusterRef());
    math::XYZPoint v(primaryVertex_.x(), primaryVertex_.y(), primaryVertex_.z());
    photonCand.setVertex( v  );
    if(hasConvTrack || hasSingleleg)photonCand.setFlag( reco::PFCandidate::GAMMA_TO_GAMMACONV, true);
    int matches=match_ind.size();
    int count=0;
    for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin();   ec != tempElectronCandidates.end(); ++ec ){
      for(int i=0; i<matches; i++)
        {
          if(count==match_ind[i])photonCand.addDaughter(*ec);
          count++;
        }
    }
    //photonCand.setPositionAtECALEntrance(math::XYZPointF(photonMom_.position()));
    // set isvalid_ to TRUE since we've found at least one photon candidate
    isvalid_ = true;
    // push back the candidate into the collection ...
    //Add Elements from Electron
        for(std::vector<unsigned int>::const_iterator it = 
              AddFromElectron_.begin();
            it != AddFromElectron_.end(); ++it)photonCand.addElementInBlock(blockRef,*it);


    // ... and lock all elemts used
    for(std::vector<unsigned int>::const_iterator it = elemsToLock.begin();
        it != elemsToLock.end(); ++it)
      {
        if(active[*it])
          {
            photonCand.addElementInBlock(blockRef,*it);
            if( elements[*it].type() == reco::PFBlockElement::TRACK  )
              {
                if(elements[*it].convRef().isNonnull())
                  {
                    //make sure it is not stored already as the partner track
                    bool matched=false;
                    for(unsigned int ic = 0; ic < ConversionsRef_.size(); ic++)
                      {
                        if(ConversionsRef_[ic]==elements[*it].convRef())matched=true;
                      }
                    if(!matched)ConversionsRef_.push_back(elements[*it].convRef());
                  }
              }
          }
        active[*it] = false;    
      }
    //Do Global Corrections here:
   float GCorr=EvaluateGCorrMVA(photonCand);
    if(useReg_){
    math::XYZTLorentzVector photonCorrMomentum(GCorr*photonEnergy_* photonDirection.X(),
                                               GCorr*photonEnergy_* photonDirection.Y(),
                                               GCorr*photonEnergy_* photonDirection.Z(),
                                               GCorr * photonEnergy_           );
    photonCand.setP4(photonCorrMomentum);
    }
    // here add the extra information
    PFCandidatePhotonExtra myExtra(sc->superClusterRef());
    //Mustache ID variables
    int excl=0;
    float Mustache_et_out=0; 
    Mustache Must;
    Must.MustacheID(PFClusters, excl, Mustache_et_out);
    myExtra.setMustache_Et(Mustache_et_out);
    myExtra.setExcludedClust(excl);
    //Store regressed energy
    myExtra.setMVAGlobalCorrE(GCorr * photonEnergy_);
    float Res=EvaluateResMVA(photonCand);
    myExtra.SetPFPhotonRes(Res*1.253);
    for(unsigned int l=0; l<MVALCorr.size(); ++l)
      {
        myExtra.addLCorrClusEnergy(MVALCorr[l]);
      }

    //    Daniele example for mvaValues
    //    do the same for single leg trackRef and convRef
    for(unsigned int ic = 0; ic < MVA_values.size(); ic++)
      {
        myExtra.addSingleLegConvMva(MVA_values[ic]);
        myExtra.addSingleLegConvTrackRef(singleLegRef[ic]);
        //cout<<"Single Leg Tracks "<<singleLegRef[ic]->pt()<<" MVA "<<MVA_values[ic]<<endl;
      }
    for(unsigned int ic = 0; ic < ConversionsRef_.size(); ic++)
      {
        myExtra.addConversionRef(ConversionsRef_[ic]);
        //cout<<"Conversion Pairs "<<ConversionsRef_[ic]->pairMomentum()<<endl;
      }
    pfPhotonExtraCandidates.push_back(myExtra);
    pfCandidates->push_back(photonCand);
    // ... and reset the vector
    elemsToLock.resize(0);
    hasConvTrack=false;
    hasSingleleg=false;
  } // end of loops over all elements in block
  
  return;
}
void PFPhotonAlgo::setGBRForest ( const GBRForest LCorrForest,
const GBRForest GCorrForest,
const GBRForest ResForest 
) [inline]

Definition at line 46 of file PFPhotonAlgo.h.

References ReaderGC_, ReaderLC_, and ReaderRes_.

Referenced by PFAlgo::setPFPhotonRegWeights().

  {
    ReaderLC_=LCorrForest;
    ReaderGC_=GCorrForest;
    ReaderRes_=ResForest;
  }  

Member Data Documentation

std::vector<unsigned int> PFPhotonAlgo::AddFromElectron_ [private]

Definition at line 160 of file PFPhotonAlgo.h.

Referenced by EarlyConversion(), and RunPFPhoton().

float PFPhotonAlgo::chi2 [private]

Definition at line 135 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

float PFPhotonAlgo::Clus5x5ratio_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::ClusEta_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA().

float PFPhotonAlgo::ClusPhi_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA().

float PFPhotonAlgo::ClusR9_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::CrysEta_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and GetCrysCoordinates().

float PFPhotonAlgo::CrysIEta_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by GetCrysCoordinates().

float PFPhotonAlgo::CrysIPhi_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by GetCrysCoordinates().

float PFPhotonAlgo::CrysPhi_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and GetCrysCoordinates().

float PFPhotonAlgo::del_phi [private]

Definition at line 135 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

float PFPhotonAlgo::dEta_ [private]

Definition at line 149 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

float PFPhotonAlgo::dPhi_ [private]

Definition at line 149 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

float PFPhotonAlgo::e1x3_ [private]

Definition at line 145 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::e1x5_ [private]

Definition at line 145 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::e2x5Bottom_ [private]

Definition at line 145 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::e2x5Left_ [private]

Definition at line 145 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::e2x5Max_ [private]

Definition at line 146 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::e2x5Right_ [private]

Definition at line 145 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::e2x5Top_ [private]

Definition at line 145 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::e3x1_ [private]

Definition at line 145 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::e3x3_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), EvaluateResMVA(), and fill5x5Map().

float PFPhotonAlgo::e5x5Map[5][5] [private]

Definition at line 138 of file PFPhotonAlgo.h.

Referenced by fill5x5Map().

float PFPhotonAlgo::EB [private]

Definition at line 143 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA().

float PFPhotonAlgo::EoverPt [private]

Definition at line 135 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

float PFPhotonAlgo::eSeed_ [private]

Definition at line 145 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and fill5x5Map().

float PFPhotonAlgo::excluded_ [private]

Definition at line 158 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

float PFPhotonAlgo::HoverPt [private]

Definition at line 135 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

bool PFPhotonAlgo::isvalid_ [private]

Definition at line 113 of file PFPhotonAlgo.h.

Referenced by isPhotonValidCandidate(), and RunPFPhoton().

float PFPhotonAlgo::logPFClusE_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA().

float PFPhotonAlgo::LowClusE_ [private]

Definition at line 149 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

std::vector<int> PFPhotonAlgo::match_ind [private]

Definition at line 130 of file PFPhotonAlgo.h.

Referenced by EarlyConversion(), isPhotonValidCandidate(), and RunPFPhoton().

Definition at line 158 of file PFPhotonAlgo.h.

Definition at line 158 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

double PFPhotonAlgo::MVACUT [private]

Definition at line 120 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA().

double PFPhotonAlgo::mvaValue [private]

Definition at line 136 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and RunPFPhoton().

float PFPhotonAlgo::nlayers [private]

Definition at line 134 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

float PFPhotonAlgo::nlost [private]

Definition at line 134 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

float PFPhotonAlgo::nPFClus_ [private]

Definition at line 149 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

Definition at line 133 of file PFPhotonAlgo.h.

Referenced by isPhotonValidCandidate().

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and GetCrysCoordinates().

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and GetCrysCoordinates().

float PFPhotonAlgo::PFPhoEt_ [private]

Definition at line 148 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

float PFPhotonAlgo::PFPhoEta_ [private]

Definition at line 148 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

float PFPhotonAlgo::PFPhoPhi_ [private]

Definition at line 148 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

float PFPhotonAlgo::PFPhoR9_ [private]

Definition at line 148 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

Definition at line 122 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), PFPhotonAlgo(), and RunPFPhoton().

float PFPhotonAlgo::RConv_ [private]

Definition at line 148 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

Definition at line 125 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and setGBRForest().

Definition at line 124 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA(), and setGBRForest().

Definition at line 126 of file PFPhotonAlgo.h.

Referenced by EvaluateResMVA(), and setGBRForest().

float PFPhotonAlgo::SCEtaWidth_ [private]

Definition at line 148 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

float PFPhotonAlgo::SCPhiWidth_ [private]

Definition at line 148 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

float PFPhotonAlgo::STIP [private]

Definition at line 135 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

Definition at line 128 of file PFPhotonAlgo.h.

Referenced by RunPFPhoton().

Definition at line 129 of file PFPhotonAlgo.h.

Referenced by RunPFPhoton().

Definition at line 127 of file PFPhotonAlgo.h.

Referenced by RunPFPhoton().

TMVA::Reader* PFPhotonAlgo::tmvaReader_ [private]

Definition at line 123 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), PFPhotonAlgo(), and ~PFPhotonAlgo().

float PFPhotonAlgo::track_pt [private]

Definition at line 135 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

bool PFPhotonAlgo::useReg_ [private]

Definition at line 121 of file PFPhotonAlgo.h.

Referenced by RunPFPhoton().

Definition at line 114 of file PFPhotonAlgo.h.

Referenced by RunPFPhoton().

float PFPhotonAlgo::VtxZ_ [private]

Definition at line 141 of file PFPhotonAlgo.h.

Referenced by EvaluateLCorrMVA().

TH2D* PFPhotonAlgo::X0_inner [private]

Definition at line 153 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), EvaluateResMVA(), and PFPhotonAlgo().

TH2D* PFPhotonAlgo::X0_middle [private]

Definition at line 154 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), EvaluateResMVA(), and PFPhotonAlgo().

TH2D* PFPhotonAlgo::X0_outer [private]

Definition at line 155 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), EvaluateResMVA(), and PFPhotonAlgo().

TH2D* PFPhotonAlgo::X0_sum [private]

Definition at line 152 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), EvaluateResMVA(), and PFPhotonAlgo().

float PFPhotonAlgo::x0inner_ [private]

Definition at line 156 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

float PFPhotonAlgo::x0middle_ [private]

Definition at line 156 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().

float PFPhotonAlgo::x0outer_ [private]

Definition at line 156 of file PFPhotonAlgo.h.

Referenced by EvaluateGCorrMVA(), and EvaluateResMVA().