CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoEgamma/EgammaTools/src/ggPFPhotons.cc

Go to the documentation of this file.
00001 #include "RecoEgamma/EgammaTools/interface/ggPFPhotons.h"
00002 #include "DataFormats/Math/interface/deltaPhi.h"
00003 #include "DataFormats/Math/interface/deltaR.h"
00004 #include "RecoEgamma/EgammaTools/interface/ConversionTools.h"
00005 /*
00006 Class by Rishi Patel rpatel@cern.ch
00007 */
00008 ggPFPhotons::ggPFPhotons(
00009                          reco::Photon phot,
00010                          edm::Handle<reco::PhotonCollection>& pfPhotons,
00011                          edm::Handle<reco::GsfElectronCollection>& pfElectrons,
00012                          edm::Handle<PFCandidateCollection>& pfCandidates,
00013                          edm::Handle<EcalRecHitCollection>& EBReducedRecHits,
00014                          edm::Handle<EcalRecHitCollection>& EEReducedRecHits,
00015                          edm::Handle<EcalRecHitCollection>& ESRecHits,
00016                          const CaloSubdetectorGeometry* geomBar,
00017                          const CaloSubdetectorGeometry* geomEnd,
00018                          edm::Handle<BeamSpot>& beamSpotHandle
00019                          ):
00020   matchedPhot_(phot),
00021   pfPhotons_(pfPhotons),
00022   EBReducedRecHits_(EBReducedRecHits),
00023   EEReducedRecHits_(EEReducedRecHits),
00024   ESRecHits_(ESRecHits),
00025   geomBar_(geomBar),
00026   geomEnd_(geomEnd),
00027   beamSpotHandle_(beamSpotHandle),
00028   matchPFReco_(false),
00029   isPFEle_(false),
00030   EleVeto_(false),
00031   isConv_(false),
00032   hasSLConv_(false)
00033 {
00034   //do Matching:
00035   //std::cout<<"HERE IN NEW CLASS "<<std::endl;
00036   
00037   reco::PhotonCollection::const_iterator pfphot=pfPhotons_->begin();
00038   for(;pfphot!=pfPhotons_->end();++pfphot){
00039     if(pfphot->superCluster()==matchedPhot_.superCluster()){
00040       PFPhoton_= *(pfphot);
00041       matchPFReco_=true;
00042       break;
00043     }
00044   }
00045   reco::GsfElectronCollection::const_iterator pfele=pfElectrons->begin();
00046   for(;pfele!=pfElectrons->end();++pfele){
00047     if(pfele->superCluster().isNull())continue;
00048     
00049     if(pfele->superCluster()==matchedPhot_.superCluster()){
00050       if(pfele->pflowSuperCluster().isNull())continue;
00051       
00052       PFElectron_= *(pfele);
00053       
00054       matchPFReco_=true;
00055       isPFEle_=true;
00056       break;
00057     }
00058     for(PFCandidateCollection::const_iterator pfParticle =pfCandidates->begin(); pfParticle!=pfCandidates->end(); pfParticle++){
00059       if(abs(pfParticle->pdgId())!=11)continue;
00060       if(pfParticle->superClusterRef().isNull())continue;
00061       double dR=deltaR(pfParticle->superClusterRef()->eta(), 
00062                        pfParticle->superClusterRef()->phi(),
00063                        matchedPhot_.superCluster()->eta(), 
00064                        matchedPhot_.superCluster()->phi());
00065       if(pfele->superCluster()==pfParticle->superClusterRef() &&dR<0.1){
00066         PFElectron_= *(pfele);
00067         matchPFReco_=true;
00068         isPFEle_=true;
00069         break;
00070       } 
00071     }  
00072   }
00073 
00074 }
00075 ggPFPhotons::~ggPFPhotons(){;}
00076 //Prompt Electron Veto:
00077 bool ggPFPhotons::PFElectronVeto(edm::Handle<reco::ConversionCollection>& convH, edm::Handle<reco::GsfElectronCollection>& gsfElectronsHandle){
00078   bool isprompt=false;
00079   if(!isPFEle_)return isprompt;
00080   isprompt= ConversionTools::hasMatchedPromptElectron(PFElectron_.superCluster(), gsfElectronsHandle, convH, beamSpotHandle_->position());
00081   return isprompt;
00082 }
00083 //get Vtx Z along beam line from Single Leg Pointing if Track exists
00084 //else it returns Vtx Z from Conversion Pair or Beamspot Z
00085 std::pair<float, float> ggPFPhotons::SLPoint(){
00086   ggPFTracks pfTks(beamSpotHandle_);
00087   std::pair<float, float> SLPoint(0,0);
00088   TVector3 bs(beamSpotHandle_->position().x(),beamSpotHandle_->position().y(),
00089               beamSpotHandle_->position().z());
00090   if(isPFEle_){
00091     isConv_=true;
00092     SLPoint=pfTks.gsfElectronProj(PFElectron_);
00093     return SLPoint;
00094   }
00095   SLPoint=pfTks.SLCombZVtx(PFPhoton_, hasSLConv_);
00096   isConv_=pfTks.isConv();//bool to flag if there are conv tracks
00097   return SLPoint; 
00098 }
00099 
00100 void ggPFPhotons::fillPFClusters(){
00101   //PFClusterCollection object with appropriate variables:
00102   
00103   ggPFClusters PFClusterCollection(EBReducedRecHits_, EEReducedRecHits_, geomBar_,   geomEnd_);
00104   //if(isPFEle_)cout<<"PFElectron "<<endl;
00105   //else cout<<"PFPHoton "<<endl;
00106   //fill PFClusters
00107   if(isPFEle_)PFClusters_=PFClusterCollection.getPFClusters(*(PFElectron_.pflowSuperCluster()));
00108   else PFClusters_=PFClusterCollection.getPFClusters(*(PFPhoton_.pfSuperCluster()));
00109   //fill PFClusters with Cluster energy from Rechits inside SC
00110   
00111   PFSCFootprintClusters_.clear();
00112   for(unsigned int i=0; i<PFClusters_.size(); ++i){
00113     float SCFootPrintE=PFClusterCollection.getPFSuperclusterOverlap(PFClusters_[i],matchedPhot_);
00114     CaloCluster calo(SCFootPrintE, PFClusters_[i].position());
00115     PFSCFootprintClusters_.push_back(calo);
00116   }
00117   //Mustache Variables:
00118   
00119   
00120   Mustache Must;
00121   std::vector<unsigned int> insideMust;
00122   std::vector<unsigned int> outsideMust;
00123   Must.MustacheClust(PFClusters_, insideMust, outsideMust);
00124  
00125   //Must.MustacheID(PFClusters_, insideMust, outsideMust);
00126   // cout<<"Inside "<<insideMust.size()<<", Total"<<PFClusters_.size()<<endl;
00127   //sum MustacheEnergy and order clusters by Energy:
00128   
00129   std::multimap<float, unsigned int>OrderedClust;
00130   float MustacheE=0;
00131   for(unsigned int i=0; i<insideMust.size(); ++i){
00132     unsigned int index=insideMust[i];
00133     OrderedClust.insert(make_pair(PFClusters_[index].energy(), index));
00134     MustacheE=MustacheE+PFSCFootprintClusters_[index].energy();
00135   }
00136   
00137   float MustacheEOut=0;
00138   float MustacheEtOut=0;
00139   for(unsigned int i=0; i<outsideMust.size(); ++i){
00140     unsigned int index=outsideMust[i];
00141     MustacheEOut=MustacheEOut+PFClusters_[index].energy();
00142     MustacheEtOut=MustacheEtOut+PFClusters_[index].energy()*sin(PFClusters_[index].position().theta());
00143   }
00144   MustacheEOut_=MustacheEOut;
00145   MustacheEtOut_=MustacheEtOut;
00146   EinMustache_=MustacheE;
00147   
00148   //find lowest energy Cluster
00149   std::multimap<float, unsigned int>::iterator it;
00150   it=OrderedClust.begin();
00151   unsigned int lowEindex=(*it).second;   
00152   PFLowClusE_=PFSCFootprintClusters_[lowEindex].energy();
00153   
00154   //dEta and dPhi to this Cluster:
00155   dEtaLowestC_=PFSCFootprintClusters_[lowEindex].eta()-PFPhoton_.eta();
00156   dPhiLowestC_=deltaPhi(PFSCFootprintClusters_[lowEindex].phi(),PFPhoton_.phi());
00157   //RMS Of All PFClusters inside SuperCluster:
00158   
00159   std::pair<double, double> RMS=CalcRMS(PFSCFootprintClusters_, PFPhoton_);
00160   PFClPhiRMS_=RMS.second;
00161   std::vector<CaloCluster>MustacheNLClust;
00162   for(it=OrderedClust.begin(); it!=OrderedClust.end(); ++it){
00163     unsigned int index=(*it).second;
00164     if(index==lowEindex)continue; //skip lowest cluster which could be from PU
00165     MustacheNLClust.push_back(PFSCFootprintClusters_[index]);
00166   }
00167   if(insideMust.size()>3){
00168   std::pair<double, double> RMSMust=CalcRMS(MustacheNLClust, PFPhoton_);
00169   PFClPhiRMSMust_=RMSMust.second;
00170   }
00171   if(insideMust.size()==2){
00172     MustacheNLClust.push_back(PFSCFootprintClusters_[lowEindex]);
00173     std::pair<double, double> RMSMust=CalcRMS(MustacheNLClust, PFPhoton_);
00174     PFClPhiRMSMust_=RMSMust.second;
00175   }
00176   if(insideMust.size()==1){
00177     PFClPhiRMSMust_=matchedPhot_.superCluster()->phiWidth();
00178     PFClPhiRMS_=PFClPhiRMSMust_;
00179   }
00180   
00181   //fill ES Clusters
00182   
00183   ggPFESClusters PFPSClusterCollection(ESRecHits_, geomEnd_);
00184   vector<reco::PreshowerCluster>PFPS;
00185   if(isPFEle_)PFPS=PFPSClusterCollection.getPFESClusters(*((PFElectron_.pflowSuperCluster())));
00186   else PFPS=PFPSClusterCollection.getPFESClusters(*(PFPhoton_.pfSuperCluster()));
00187   float PFPS1=0;
00188   float PFPS2=0;
00189   for(unsigned int i=0; i<PFPS.size(); ++i){
00190     if(PFPS[i].plane()==1)PFPS1=PFPS1+PFPS[i].energy();
00191     if(PFPS[i].plane()==2)PFPS2=PFPS2+PFPS[i].energy();
00192   }
00193   PFPreShower1_=PFPS1;
00194   PFPreShower2_=PFPS2;
00195   
00196 }
00197 
00198 std::pair<double, double> ggPFPhotons::CalcRMS(vector<reco::CaloCluster> PFClust, reco::Photon PFPhoton){
00199   double delPhi2=0;
00200   double delPhiSum=0;
00201   double delEta2=0;
00202   double delEtaSum=0;
00203   double ClusSum=0;
00204   float PFPhoPhi=PFPhoton.phi();
00205   float PFPhoEta=PFPhoton.eta();
00206 
00207   float PFClusPhiRMS=0;
00208   float PFClusEtaRMS=0;
00209   std::pair<double, double> RMS;  
00210   for(unsigned int c=0; c<PFClust.size(); ++c){
00211     delPhi2=(acos(cos(PFPhoPhi-PFClust[c].phi()))* acos(cos(PFPhoPhi-PFClust[c].phi())) )+delPhi2;
00212     delPhiSum=delPhiSum+ acos(cos(PFPhoPhi-PFClust[c].phi()))*PFClust[c].energy();
00213     delEta2=(PFPhoEta-PFClust[c].eta())*(PFPhoEta-PFClust[c].eta()) *PFClust[c].energy() + delEta2;
00214     delEtaSum=delEtaSum+((PFPhoEta-PFClust[c].eta())*PFClust[c].energy());
00215     ClusSum=ClusSum+PFClust[c].energy();
00216   }
00217   double meandPhi=delPhiSum/ClusSum;
00218   PFClusPhiRMS=sqrt(fabs(delPhi2/ClusSum - (meandPhi*meandPhi)));
00219   double meandEta=delEtaSum/ClusSum;
00220   PFClusEtaRMS=sqrt(fabs(delEta2/ClusSum - (meandEta*meandEta)));
00221   RMS.first=PFClusEtaRMS;
00222   RMS.second=PFClusPhiRMS;
00223   return RMS;
00224 }
00225 
00226 double ggPFPhotons::getPFPhoECorr( std::vector<reco::CaloCluster>PFClusters, const GBRForest *ReaderLCEB, const GBRForest *ReaderLCEE){
00227   TVector3 bs(beamSpotHandle_->position().x(),beamSpotHandle_->position().y(),
00228               beamSpotHandle_->position().z());
00229   float beamspotZ=bs.Z();
00230   //PFClusterCollection object with appropriate variables:
00231   ggPFClusters PFClusterCollection(EBReducedRecHits_, EEReducedRecHits_, geomBar_,   geomEnd_);
00232   //fill PFClusters
00233   PFClusters_.clear();
00234   if(isPFEle_)PFClusters_=PFClusterCollection.getPFClusters(*(PFElectron_.pflowSuperCluster()));
00235   else PFClusters_=PFClusterCollection.getPFClusters(*(PFPhoton_.pfSuperCluster()));
00236   Mustache Must;
00237   std::vector<unsigned int> insideMust;
00238   std::vector<unsigned int> outsideMust;
00239   Must.MustacheClust(PFClusters_, insideMust, outsideMust);
00240   float ECorr=0;
00241   for(unsigned int i=0; i<insideMust.size();++i){
00242     unsigned int index=insideMust[i];
00243     ECorr=ECorr+PFClusterCollection.LocalEnergyCorrection(ReaderLCEB, ReaderLCEE, PFClusters_[index], beamspotZ);
00244   }
00245   PFPhoLocallyCorrE_=ECorr;
00246   
00247   return PFPhoLocallyCorrE_;
00248 }
00249 
00250 std::vector<reco::CaloCluster> ggPFPhotons::recoPhotonClusterLink(reco::Photon phot, 
00251                                                                  edm::Handle<PFCandidateCollection>& pfCandidates
00252                                                                  ){
00253   PFClusters_.clear();
00254   //initialize variables:
00255   EinMustache_=0;
00256   MustacheEOut_=0;
00257   MustacheEtOut_=0;
00258   PFPreShower1_=0;
00259   PFPreShower2_=0;
00260   PFLowClusE_=0;
00261   dEtaLowestC_=0;
00262   dPhiLowestC_=0;
00263   PFClPhiRMS_=0;
00264   PFClPhiRMSMust_=0;
00265   //find SC boundaries from RecHits:
00266   std::pair<double,double>Boundary=SuperClusterSize(phot);              
00267   double etabound=Boundary.first;
00268   double phibound=Boundary.second;
00269   double seedEta=phot.superCluster()->seed()->eta();
00270   double seedPhi=phot.superCluster()->seed()->phi();
00271   for (PFCandidateCollection::const_iterator pfParticle =pfCandidates->begin(); pfParticle!=pfCandidates->end(); pfParticle++){
00272     if(pfParticle->pdgId()!=22) continue; //if photon
00273     //use a box about superCluster Width:
00274     float dphi=acos(cos(seedPhi-pfParticle->phi()));
00275     float deta=fabs(seedEta-pfParticle->eta());
00276     PFPreShower1_=0;
00277     PFPreShower2_=0;
00278     if(deta<etabound && dphi<phibound){
00279       //hard coded size for now but will make it more dynamic
00280       //based on SuperCluster Shape
00281       math::XYZPoint position(pfParticle->positionAtECALEntrance().X(), pfParticle->positionAtECALEntrance().Y(), pfParticle->positionAtECALEntrance().Z()) ;
00282       CaloCluster calo(pfParticle->rawEcalEnergy() ,position );
00283       PFClusters_.push_back(calo);
00284       PFPreShower1_=PFPreShower1_+pfParticle->pS1Energy();
00285       PFPreShower2_=PFPreShower2_+pfParticle->pS2Energy();
00286     }
00287   }
00288  
00289     //Mustache Variables:
00290   
00291   if(PFClusters_.size()>0){
00292   Mustache Must;
00293   std::vector<unsigned int> insideMust;
00294   std::vector<unsigned int> outsideMust;
00295   Must.MustacheClust(PFClusters_, insideMust, outsideMust);
00296   //sum MustacheEnergy and order clusters by Energy:
00297   
00298   std::multimap<float, unsigned int>OrderedClust;
00299   float MustacheE=0;
00300   for(unsigned int i=0; i<insideMust.size(); ++i){
00301     unsigned int index=insideMust[i];
00302     OrderedClust.insert(make_pair(PFClusters_[index].energy(), index));
00303     MustacheE=MustacheE+PFClusters_[index].energy();
00304   }
00305   
00306   float MustacheEOut=0;
00307   float MustacheEtOut=0;
00308   for(unsigned int i=0; i<outsideMust.size(); ++i){
00309     unsigned int index=outsideMust[i];
00310     MustacheEOut=MustacheEOut+PFClusters_[index].energy();
00311     MustacheEtOut=MustacheEtOut+PFClusters_[index].energy()*sin(PFClusters_[index].position().theta());
00312   }
00313   MustacheEOut_=MustacheEOut;
00314   MustacheEtOut_=MustacheEtOut;
00315   EinMustache_=MustacheE;
00316   
00317   //find lowest energy Cluster
00318   std::multimap<float, unsigned int>::iterator it;
00319   it=OrderedClust.begin();
00320   unsigned int lowEindex=(*it).second;   
00321   PFLowClusE_=PFClusters_[lowEindex].energy();
00322   //dEta and dPhi to this Cluster:
00323   dEtaLowestC_=PFClusters_[lowEindex].eta()-PFPhoton_.eta();
00324   dPhiLowestC_=deltaPhi(PFClusters_[lowEindex].phi(),PFPhoton_.phi());
00325   //RMS Of All PFClusters inside SuperCluster:
00326   if(insideMust.size()==1){
00327     PFLowClusE_=0;
00328     dEtaLowestC_=0;
00329     dPhiLowestC_=0;
00330   }
00331   std::pair<double, double> RMS=CalcRMS(PFClusters_, PFPhoton_);
00332   PFClPhiRMS_=RMS.second;
00333   std::vector<CaloCluster>MustacheNLClust;
00334   for(it=OrderedClust.begin(); it!=OrderedClust.end(); ++it){
00335     unsigned int index=(*it).second;
00336     if(index==lowEindex)continue; //skip lowest cluster which could be from PU
00337     MustacheNLClust.push_back(PFClusters_[index]);
00338   }
00339   if(insideMust.size()>3){
00340   std::pair<double, double> RMSMust=CalcRMS(MustacheNLClust, PFPhoton_);
00341   PFClPhiRMSMust_=RMSMust.second;
00342   }
00343   if(insideMust.size()==2){
00344     MustacheNLClust.push_back(PFClusters_[lowEindex]);
00345     std::pair<double, double> RMSMust=CalcRMS(MustacheNLClust, PFPhoton_);
00346     PFClPhiRMSMust_=RMSMust.second;
00347   }
00348   if(insideMust.size()==1){
00349     PFClPhiRMSMust_=matchedPhot_.superCluster()->phiWidth();
00350     PFClPhiRMS_=PFClPhiRMSMust_;
00351   }
00352   
00353   }
00354   return PFClusters_;
00355   
00356 }
00357 
00358 std::pair<double, double>ggPFPhotons::SuperClusterSize(
00359                                                        reco::Photon phot
00360                                                        ){
00361   std::pair<double, double>SCsize(0.1,0.4);//Eta, Phi
00362   //find maximum distance between SuperCluster Seed and Rec Hits
00363   SuperClusterRef recoSC=phot.superCluster();
00364   reco::CaloCluster_iterator cit=recoSC->clustersBegin();
00365   double seedeta=recoSC->seed()->eta();
00366   double seedphi=recoSC->seed()->phi();
00367   EcalRecHitCollection::const_iterator eb;
00368   EcalRecHitCollection::const_iterator ee;
00369   double MaxEta=-99;
00370   double MaxPhi=-99;
00371   double MaxR=-99;
00372   for(;cit!=recoSC->clustersEnd();++cit){
00373     std::vector< std::pair<DetId, float> >bcCells=(*cit)->hitsAndFractions();
00374     if(phot.isEB()){
00375       for(unsigned int i=0; i<bcCells.size(); ++i){
00376         for(eb=EBReducedRecHits_->begin();eb!= EBReducedRecHits_->end();++eb){
00377           if(eb->id().rawId()==bcCells[i].first.rawId()){
00378             DetId id=bcCells[i].first;
00379             float eta=geomBar_->getGeometry(id)->getPosition().eta();
00380             float dEta = fabs(seedeta-eta);
00381             if(dEta>MaxEta){
00382               MaxEta=dEta;
00383               float phi=geomBar_->getGeometry(id)->getPosition().phi();
00384               float dPhi = acos(cos( seedphi-phi));
00385               if(dPhi>MaxPhi){
00386                 MaxPhi=dPhi;
00387               }
00388             }
00389           }
00390         }
00391         
00392       }
00393     }
00394     else{
00395       for(unsigned int i=0; i<bcCells.size(); ++i){
00396         for(ee=EEReducedRecHits_->begin();ee!= EEReducedRecHits_->end();++ee){
00397           if(ee->id().rawId()==bcCells[i].first.rawId()){
00398             DetId id=bcCells[i].first;
00399             float eta=geomEnd_->getGeometry(id)->getPosition().eta();
00400             float phi=geomEnd_->getGeometry(id)->getPosition().phi();
00401             float dR=deltaR(eta, phi, seedeta, seedphi);
00402             if(dR>MaxR){
00403               MaxR=dR;
00404               MaxEta=fabs(seedeta-eta);
00405               MaxPhi= acos(cos(seedphi-phi));
00406             }
00407           }
00408         }
00409       }
00410     }
00411   }
00412   SCsize.first=MaxEta; SCsize.second=MaxPhi;
00413   return SCsize;
00414 }
00415 
00416 void ggPFPhotons::recoPhotonClusterLink(
00417                                         reco::SuperCluster sc, 
00418                                         std::vector<reco::PFCandidatePtr>&insideMust, 
00419                                         std::vector<reco::PFCandidatePtr>&outsideMust,
00420                                         edm::Handle<PFCandidateCollection>& pfCandidates,
00421                                         double etabound,
00422                                         double phibound
00423                                         
00424                                         
00425                                         ){
00426   std::vector<reco::CaloCluster>PFClusters;
00427   std::vector<reco::PFCandidatePtr>PFCand;
00428   double seedEta=sc.seed()->eta();
00429   double seedPhi=sc.seed()->phi();
00430   for(PFCandidateCollection::const_iterator pfParticle =pfCandidates->begin(); pfParticle!=pfCandidates->end(); pfParticle++){
00431     unsigned int index=pfParticle - pfCandidates->begin();
00432     if(pfParticle->pdgId()!=22) continue; //if photon
00433     //use a box about superCluster Width:
00434     float dphi=acos(cos(seedPhi-pfParticle->phi()));
00435     float deta=fabs(seedEta-pfParticle->eta());
00436     if(deta<etabound && dphi<phibound){
00437       //hard coded size for now but will make it more dynamic
00438       //based on SuperCluster Shape
00439       math::XYZPoint position(pfParticle->positionAtECALEntrance().X(), pfParticle->positionAtECALEntrance().Y(), pfParticle->positionAtECALEntrance().Z()) ;
00440       CaloCluster calo(pfParticle->rawEcalEnergy() ,position );
00441       PFClusters.push_back(calo);
00442       reco::PFCandidatePtr pfRef(pfCandidates,index);
00443       PFCand.push_back(pfRef);
00444     }
00445     
00446   }
00447   Mustache Must;
00448   std::vector<unsigned int> insideMustindex;
00449   std::vector<unsigned int> outsideMustindex;
00450   Must.MustacheClust(PFClusters, insideMustindex, outsideMustindex);
00451   for(unsigned int i=0; i<insideMustindex.size(); ++i){
00452     unsigned int index=insideMustindex[i];
00453     insideMust.push_back(PFCand[index]);
00454   }
00455   for(unsigned int i=0; i<outsideMustindex.size(); ++i){
00456     unsigned int index=outsideMustindex[i];
00457     outsideMust.push_back(PFCand[index]);
00458   }
00459     
00460 }
00461 std::pair<double, double>ggPFPhotons::SuperClusterSize(reco::SuperCluster sc,
00462                                                  Handle<EcalRecHitCollection>&   EBReducedRecHits,
00463                                                  Handle<EcalRecHitCollection>&   EEReducedRecHits,
00464                                                  const CaloSubdetectorGeometry* geomBar,
00465                                                  const CaloSubdetectorGeometry* geomEnd
00466                                                  ){
00467   std::pair<double, double>SCsize(0.1,0.4);//Eta, Phi
00468   //find maximum distance between SuperCluster Seed and Rec Hits
00469   reco::CaloCluster_iterator cit=sc.clustersBegin();
00470   double seedeta=sc.eta();
00471   double seedphi=sc.phi();
00472   EcalRecHitCollection::const_iterator eb;
00473   EcalRecHitCollection::const_iterator ee;
00474   double MaxEta=-99;
00475   double MaxPhi=-99;
00476   for(;cit!=sc.clustersEnd();++cit){
00477     std::vector< std::pair<DetId, float> >bcCells=(*cit)->hitsAndFractions();
00478     DetId seedXtalId = bcCells[0].first ;
00479     int detector = seedXtalId.subdetId(); //use Seed to check if EB or EE
00480     bool isEb;
00481     if(detector==1)isEb=true;
00482     else isEb=false;
00483     if(isEb){
00484       for(unsigned int i=0; i<bcCells.size(); ++i){
00485         for(eb=EBReducedRecHits->begin();eb!= EBReducedRecHits->end();++eb){
00486           if(eb->id().rawId()==bcCells[i].first.rawId()){
00487             DetId id=bcCells[i].first;
00488             float eta=geomBar->getGeometry(id)->getPosition().eta();
00489             float dEta = fabs(seedeta-eta);
00490             if(dEta>MaxEta){
00491               MaxEta=dEta;
00492               float phi=geomBar->getGeometry(id)->getPosition().phi();
00493               float dPhi = acos(cos( seedphi-phi));
00494               if(dPhi>MaxPhi){
00495                 MaxPhi=dPhi;
00496               }
00497             }
00498           }
00499         }
00500         
00501       }
00502     }
00503     else{
00504       for(unsigned int i=0; i<bcCells.size(); ++i){
00505         for(ee=EEReducedRecHits->begin();ee!= EEReducedRecHits->end();++ee){
00506           if(ee->id().rawId()==bcCells[i].first.rawId()){
00507             DetId id=bcCells[i].first;
00508             float eta=geomEnd->getGeometry(id)->getPosition().eta();
00509             float dEta = fabs(seedeta-eta);
00510             if(dEta>MaxEta){
00511               MaxEta=dEta;
00512             }
00513             float phi=geomEnd->getGeometry(id)->getPosition().phi();
00514             float dPhi = acos(cos(seedphi-phi));
00515             if(dPhi>MaxPhi){
00516               MaxPhi=dPhi;
00517             }
00518           }
00519         }
00520         
00521       }
00522     }
00523   }
00524   SCsize.first=MaxEta; SCsize.second=MaxPhi;
00525   return SCsize;
00526   
00527   
00528 }
00529 
00530 void ggPFPhotons::PhotonPFCandMatch(  
00531                                      reco::SuperCluster sc,             
00532                                      std::vector<reco::PFCandidatePtr>&insideBox, 
00533                                      edm::Handle<PFCandidateCollection>& pfCandidates,
00534                                      vector<reco::CaloCluster> &PFClust,
00535                                      std::vector<DetId>& MatchedRH
00536                                      )
00537 {
00538   std::vector<reco::PFCandidatePtr>ChgHad;
00539   std::vector<reco::PFCandidatePtr>PFPho;
00540   std::pair<double, double>scSize=SuperClusterSize(matchedPhot_);
00541   double etabound=scSize.first;
00542   double phibound=scSize.second;
00543   double dRbound=sqrt(etabound*etabound+phibound*phibound);
00544   double seedEta=sc.eta();
00545   double seedPhi=sc.phi();
00546   for(PFCandidateCollection::const_iterator pfParticle =pfCandidates->begin(); pfParticle!=pfCandidates->end(); pfParticle++){
00547     if(pfParticle->pdgId()==130)continue;
00548     unsigned int index=pfParticle - pfCandidates->begin();
00549     math::XYZVector photon_directionWrtVtx(sc.x() - pfParticle->vx(),
00550                                            sc.y() - pfParticle->vy(),
00551                                            sc.z() - pfParticle->vz());
00552     seedEta= photon_directionWrtVtx.Eta();
00553     seedPhi=photon_directionWrtVtx.Phi();
00554     double dphi=acos(cos(seedPhi-pfParticle->momentum().Phi()));
00555     double deta=fabs(seedEta-pfParticle->momentum().Eta());
00556     if(deta<etabound && dphi<phibound && matchedPhot_.isEB()){
00557       reco::PFCandidatePtr pfRef(pfCandidates,index);
00558       insideBox.push_back(pfRef); //Fill PFCandidates in a box around SC
00559       if(pfParticle->pdgId()==22)PFPho.push_back(pfRef);
00560       if(abs(pfParticle->pdgId())==211)ChgHad.push_back(pfRef);
00561     }
00562     double dR=deltaR(seedEta,seedPhi, pfParticle->momentum().Eta(), pfParticle->momentum().Phi());
00563     if(matchedPhot_.isEE() && dR<dRbound){
00564       //if(dR<0.4){
00565       reco::PFCandidatePtr pfRef(pfCandidates,index);
00566       insideBox.push_back(pfRef); //Fill PFCandidates in a box around SC
00567       if(pfParticle->pdgId()==22)PFPho.push_back(pfRef);
00568       if(abs(pfParticle->pdgId())==211)ChgHad.push_back(pfRef);
00569     }
00570   }
00571   
00572   ggPFClusters PFClusterCollection(EBReducedRecHits_, EEReducedRecHits_, geomBar_,   geomEnd_);
00573   //Link PFCandidates to Basic Clusters
00574   std::vector<reco::PFCandidatePtr>copy=insideBox;
00575   
00576   PFClusterCollection.BasicClusterPFCandLink(sc, insideBox, MatchedRH);
00577   PFPho.clear();
00578   ChgHad.clear();
00579   for(unsigned int i=0; i<insideBox.size(); ++i){
00580     if(insideBox[i]->pdgId()==22)PFPho.push_back(insideBox[i]);
00581     if(abs(insideBox[i]->pdgId())==211)ChgHad.push_back(insideBox[i]);
00582   }
00583   //finally compute frac of shared ECal Energy between PFPhotons and PFChgHad
00584   std::vector<unsigned int > orbitPho;
00585   std::vector<unsigned int > overlapChgHad;
00586   std::vector<float > fractionShared;
00587   for(unsigned int c=0; c<ChgHad.size(); ++c){
00588     bool satPho=false;
00589     float frac=1.0;
00590     CaloCluster calo;
00591     float drmin=999;
00592     reco::CaloCluster_iterator cit=sc.clustersBegin();
00593     math::XYZPointF positionvtx(ChgHad[c]->positionAtECALEntrance().x()-ChgHad[c]->vx(), 
00594                                 ChgHad[c]->positionAtECALEntrance().y()-ChgHad[c]->vy(),
00595                                 ChgHad[c]->positionAtECALEntrance().z()-ChgHad[c]->vz());
00596     for(; cit!=sc.clustersEnd(); ++cit){
00597       float dR=deltaR((*cit)->eta(), (*cit)->phi(), positionvtx.eta(), positionvtx.phi());
00598       if(dR<drmin){
00599         calo.setPosition((*cit)->position());
00600         drmin=dR;
00601       }
00602     }
00603     
00604     for(unsigned int ipho=0; ipho<PFPho.size(); ++ipho){
00605       double deta=fabs(ChgHad[c]->positionAtECALEntrance().Eta()- PFPho[ipho]->positionAtECALEntrance().Eta());
00606       double dphi=acos(cos(ChgHad[c]->positionAtECALEntrance().Phi()-PFPho[ipho]->positionAtECALEntrance().Phi()));
00607       
00608       if(deta<0.05 && dphi<0.07){
00609         orbitPho.push_back(ipho);
00610         frac=ChgHad[c]->ecalEnergy()/(PFPho[ipho]->ecalEnergy()+ChgHad[c]->ecalEnergy());
00611         fractionShared.push_back(frac);
00612         satPho=true;
00613       }
00614     }
00615     if(satPho){
00616       calo.setEnergy(frac*ChgHad[c]->rawEcalEnergy());
00617     }
00618     else{
00619       calo.setEnergy(ChgHad[c]->rawEcalEnergy());
00620     }
00621     PFClust.push_back(calo); //pushBack PFClusters from Charged Hadrons
00622   }
00623   for(unsigned int ipho=0; ipho<PFPho.size(); ++ipho){
00624     CaloCluster calo;
00625     float frac=1.0;
00626     math::XYZPoint caloPos(PFPho[ipho]->positionAtECALEntrance().x(), 
00627                            PFPho[ipho]->positionAtECALEntrance().y(),
00628                            PFPho[ipho]->positionAtECALEntrance().z());
00629     calo.setPosition(caloPos);
00630     for(unsigned int i=0; i<orbitPho.size(); ++i){
00631       if(ipho==orbitPho[i]){
00632         frac=1-fractionShared[i];
00633         break;
00634       }
00635     }
00636     calo.setEnergy(frac*PFPho[ipho]->rawEcalEnergy());
00637     PFClust.push_back(calo);//PFClusters from PFPhotons
00638   }
00639 }
00640