CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoParticleFlow/PFProducer/plugins/PFPhotonTranslator.cc

Go to the documentation of this file.
00001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00002 #include "FWCore/Framework/interface/ESHandle.h"
00003 #include "FWCore/Framework/interface/Event.h"
00004 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00005 #include "RecoParticleFlow/PFProducer/plugins/PFPhotonTranslator.h"
00006 
00007 #include "RecoParticleFlow/PFClusterTools/interface/PFClusterWidthAlgo.h"
00008 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00009 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
00010 #include "DataFormats/EgammaReco/interface/PreshowerCluster.h"
00011 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
00012 #include "DataFormats/EgammaCandidates/interface/PhotonCore.h"
00013 #include "DataFormats/EgammaCandidates/interface/Photon.h"
00014 #include "DataFormats/EgammaCandidates/interface/PhotonCoreFwd.h"
00015 #include "DataFormats/EgammaCandidates/interface/PhotonFwd.h"
00016 #include "DataFormats/VertexReco/interface/Vertex.h"
00017 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00018 //#include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00019 #include "DataFormats/ParticleFlowReco/interface/PFBlockElement.h"
00020 #include "DataFormats/ParticleFlowReco/interface/PFBlockFwd.h"
00021 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00022 
00023 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00024 #include "RecoEgamma/PhotonIdentification/interface/PhotonIsolationCalculator.h"
00025 #include "RecoEgamma/EgammaIsolationAlgos/interface/EgammaTowerIsolation.h"
00026 
00027 //#include "Geometry/Records/interface/CaloGeometryRecord.h"
00028 //#include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00029 //#include "Geometry/CaloTopology/interface/CaloTopology.h"
00030 //#include "Geometry/CaloEventSetup/interface/CaloTopologyRecord.h"
00031 //#include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00032 //#include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00033 //#include "RecoEcal/EgammaCoreTools/interface/PositionCalc.h"
00034 //#include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00035 //#include "RecoEcal/EgammaCoreTools/interface/PositionCalc.h"
00036 //#include "RecoEgamma/PhotonIdentification/interface/PhotonIsolationCalculator.h"
00037 //#include "RecoEcal/EgammaCoreTools/interface/EcalClusterFunctionFactory.h"
00038 //#include "RecoEcal/EgammaCoreTools/interface/EcalClusterFunctionBaseClass.h" 
00039 //#include "CondFormats/EcalObjects/interface/EcalFunctionParameters.h" 
00040 //#include "RecoEcal/EgammaCoreTools/interface/EcalClusterTools.h"
00041 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidatePhotonExtra.h"
00042 
00043 #include "DataFormats/Math/interface/Vector3D.h"
00044 #include "DataFormats/Math/interface/LorentzVector.h"
00045 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00046 #include "DataFormats/Common/interface/AssociationVector.h"
00047 #include "RecoEcal/EgammaCoreTools/interface/Mustache.h"
00048 
00049 #include <Math/VectorUtil.h>
00050 #include <vector>
00051 #include "TLorentzVector.h"
00052 #include "TMath.h"
00053 
00054 using namespace edm;
00055 using namespace std;
00056 using namespace reco;
00057 
00058 using namespace ROOT::Math::VectorUtil;
00059 typedef math::XYZTLorentzVector LorentzVector;
00060 typedef math::XYZPoint Point;
00061 typedef math::XYZVector Vector;
00062 
00063 
00064 PFPhotonTranslator::PFPhotonTranslator(const edm::ParameterSet & iConfig) {
00065 
00066   //std::cout << "PFPhotonTranslator" << std::endl;
00067 
00068   inputTagPFCandidates_ 
00069     = iConfig.getParameter<edm::InputTag>("PFCandidate");
00070   
00071   edm::ParameterSet isoVals  = iConfig.getParameter<edm::ParameterSet> ("isolationValues");
00072   inputTagIsoVals_.push_back(isoVals.getParameter<edm::InputTag>("pfChargedHadrons"));
00073   inputTagIsoVals_.push_back(isoVals.getParameter<edm::InputTag>("pfPhotons"));
00074   inputTagIsoVals_.push_back(isoVals.getParameter<edm::InputTag>("pfNeutralHadrons"));
00075   
00076 
00077   PFBasicClusterCollection_ = iConfig.getParameter<std::string>("PFBasicClusters");
00078   PFPreshowerClusterCollection_ = iConfig.getParameter<std::string>("PFPreshowerClusters");
00079   PFSuperClusterCollection_ = iConfig.getParameter<std::string>("PFSuperClusters");
00080   PFConversionCollection_ = iConfig.getParameter<std::string>("PFConversionCollection");
00081   PFPhotonCoreCollection_ = iConfig.getParameter<std::string>("PFPhotonCores");
00082   PFPhotonCollection_ = iConfig.getParameter<std::string>("PFPhotons");
00083 
00084   EGPhotonCollection_ = iConfig.getParameter<std::string>("EGPhotons");
00085 
00086   vertexProducer_   = iConfig.getParameter<std::string>("primaryVertexProducer");
00087 
00088   barrelEcalHits_   = iConfig.getParameter<edm::InputTag>("barrelEcalHits");
00089   endcapEcalHits_   = iConfig.getParameter<edm::InputTag>("endcapEcalHits");
00090 
00091   hcalTowers_ = iConfig.getParameter<edm::InputTag>("hcalTowers");
00092   hOverEConeSize_   = iConfig.getParameter<double>("hOverEConeSize");
00093 
00094   if (iConfig.exists("emptyIsOk")) emptyIsOk_ = iConfig.getParameter<bool>("emptyIsOk");
00095   else emptyIsOk_=false;
00096 
00097   produces<reco::BasicClusterCollection>(PFBasicClusterCollection_); 
00098   produces<reco::PreshowerClusterCollection>(PFPreshowerClusterCollection_); 
00099   produces<reco::SuperClusterCollection>(PFSuperClusterCollection_); 
00100   produces<reco::PhotonCoreCollection>(PFPhotonCoreCollection_);
00101   produces<reco::PhotonCollection>(PFPhotonCollection_); 
00102   produces<reco::ConversionCollection>(PFConversionCollection_);
00103 }
00104 
00105 PFPhotonTranslator::~PFPhotonTranslator() {}
00106 
00107 void PFPhotonTranslator::produce(edm::Event& iEvent,  
00108                                     const edm::EventSetup& iSetup) { 
00109 
00110   //cout << "NEW EVENT"<<endl;
00111 
00112   std::auto_ptr<reco::BasicClusterCollection> 
00113     basicClusters_p(new reco::BasicClusterCollection);
00114 
00115   std::auto_ptr<reco::PreshowerClusterCollection>
00116     psClusters_p(new reco::PreshowerClusterCollection);
00117 
00118   /*
00119   std::auto_ptr<reco::ConversionCollection>
00120     SingleLeg_p(new reco::ConversionCollection);
00121   */
00122 
00123   reco::SuperClusterCollection outputSuperClusterCollection;
00124   reco::ConversionCollection outputOneLegConversionCollection;
00125   reco::PhotonCoreCollection outputPhotonCoreCollection;
00126   reco::PhotonCollection outputPhotonCollection;
00127 
00128   outputSuperClusterCollection.clear();
00129   outputOneLegConversionCollection.clear();
00130   outputPhotonCoreCollection.clear();
00131   outputPhotonCollection.clear();
00132 
00133 
00134   edm::Handle<reco::PFCandidateCollection> pfCandidates;
00135   bool status=fetchCandidateCollection(pfCandidates, 
00136                                        inputTagPFCandidates_, 
00137                                        iEvent );
00138 
00139   edm::Handle<reco::PhotonCollection> egPhotons;
00140   iEvent.getByLabel(EGPhotonCollection_, egPhotons);
00141   
00142 
00143   Handle<reco::VertexCollection> vertexHandle;
00144 
00145   
00146   IsolationValueMaps isolationValues(inputTagIsoVals_.size());
00147   for (size_t j = 0; j<inputTagIsoVals_.size(); ++j) {
00148     iEvent.getByLabel(inputTagIsoVals_[j], isolationValues[j]);
00149   }
00150   
00151 
00152   // clear the vectors
00153   photPFCandidateIndex_.clear();
00154   basicClusters_.clear();
00155   pfClusters_.clear();
00156   preshowerClusters_.clear();
00157   superClusters_.clear();
00158   basicClusterPtr_.clear();
00159   preshowerClusterPtr_.clear();
00160   CandidatePtr_.clear();
00161   egSCRef_.clear();
00162   egPhotonRef_.clear();
00163   pfPhotonMva_.clear();
00164   energyRegression_.clear();
00165   energyRegressionError_.clear();
00166   pfConv_.clear();
00167   pfSingleLegConv_.clear();
00168   pfSingleLegConvMva_.clear();
00169   conv1legPFCandidateIndex_.clear();
00170   conv2legPFCandidateIndex_.clear();
00171 
00172   // loop on the candidates 
00173   //CC@@
00174   // we need first to create AND put the SuperCluster, 
00175   // basic clusters and presh clusters collection 
00176   // in order to get a working Handle
00177   unsigned ncand=(status)?pfCandidates->size():0;
00178 
00179   unsigned iphot=0;
00180   unsigned iconv1leg=0;
00181   unsigned iconv2leg=0;
00182 
00183   for( unsigned i=0; i<ncand; ++i ) {
00184 
00185     const reco::PFCandidate& cand = (*pfCandidates)[i];    
00186     if(cand.particleId()!=reco::PFCandidate::gamma) continue;
00187     //cout << "cand.mva_nothing_gamma()="<<cand. mva_nothing_gamma()<<endl;
00188     if(cand. mva_nothing_gamma()>0.001)//Found PFPhoton with PFPhoton Extras saved
00189       {
00190 
00191         //cout << "NEW PHOTON" << endl;
00192 
00193         //std::cout << "nDoubleLegConv="<<cand.photonExtraRef()->conversionRef().size()<<std::endl;
00194 
00195         if (cand.photonExtraRef()->conversionRef().size()>0){
00196 
00197           pfConv_.push_back(reco::ConversionRefVector());
00198 
00199           const reco::ConversionRefVector & doubleLegConvColl = cand.photonExtraRef()->conversionRef();
00200           for (unsigned int iconv=0; iconv<doubleLegConvColl.size(); iconv++){
00201             pfConv_[iconv2leg].push_back(doubleLegConvColl[iconv]);
00202           }
00203 
00204           conv2legPFCandidateIndex_.push_back(iconv2leg);
00205           iconv2leg++;
00206         }
00207         else conv2legPFCandidateIndex_.push_back(-1);
00208 
00209         const std::vector<reco::TrackRef> & singleLegConvColl = cand.photonExtraRef()->singleLegConvTrackRef();
00210         const std::vector<float>& singleLegConvCollMva = cand.photonExtraRef()->singleLegConvMva();
00211         
00212         //std::cout << "nSingleLegConv=" <<singleLegConvColl.size() << std::endl;
00213 
00214         if (singleLegConvColl.size()>0){
00215 
00216           pfSingleLegConv_.push_back(std::vector<reco::TrackRef>());
00217           pfSingleLegConvMva_.push_back(std::vector<float>());
00218 
00219           //cout << "nTracks="<< singleLegConvColl.size()<<endl;
00220           for (unsigned int itk=0; itk<singleLegConvColl.size(); itk++){
00221             //cout << "Track pt="<< singleLegConvColl[itk]->pt() <<endl;
00222 
00223             pfSingleLegConv_[iconv1leg].push_back(singleLegConvColl[itk]);
00224             pfSingleLegConvMva_[iconv1leg].push_back(singleLegConvCollMva[itk]);
00225           }
00226 
00227 
00228           conv1legPFCandidateIndex_.push_back(iconv1leg);
00229         
00230           iconv1leg++;
00231         }
00232         else conv1legPFCandidateIndex_.push_back(-1);
00233         
00234       }
00235 
00236     photPFCandidateIndex_.push_back(i);
00237     pfPhotonMva_.push_back(cand.mva_nothing_gamma());
00238     energyRegression_.push_back(cand.photonExtraRef()->MVAGlobalCorrE());
00239     energyRegressionError_.push_back(cand.photonExtraRef()->MVAGlobalCorrEError());
00240     basicClusters_.push_back(reco::BasicClusterCollection());
00241     pfClusters_.push_back(std::vector<const reco::PFCluster *>());
00242     preshowerClusters_.push_back(reco::PreshowerClusterCollection());
00243     superClusters_.push_back(reco::SuperClusterCollection());
00244 
00245     reco::PFCandidatePtr ptrToPFPhoton(pfCandidates,i);
00246     CandidatePtr_.push_back(ptrToPFPhoton);  
00247     egSCRef_.push_back(cand.superClusterRef());
00248     //std::cout << "PFPhoton cand " << iphot << std::endl;
00249 
00250     int iegphot=0;
00251     for (reco::PhotonCollection::const_iterator gamIter = egPhotons->begin(); gamIter != egPhotons->end(); ++gamIter){
00252       if (cand.superClusterRef()==gamIter->superCluster()){
00253         reco::PhotonRef PhotRef(reco::PhotonRef(egPhotons, iegphot));
00254         egPhotonRef_.push_back(PhotRef);
00255       }
00256       iegphot++;
00257     }
00258 
00259 
00260     //std::cout << "Cand elements in blocks : " << cand.elementsInBlocks().size() << std::endl;
00261 
00262     for(unsigned iele=0; iele<cand.elementsInBlocks().size(); ++iele) {
00263       // first get the block 
00264       reco::PFBlockRef blockRef = cand.elementsInBlocks()[iele].first;
00265       //
00266       unsigned elementIndex = cand.elementsInBlocks()[iele].second;
00267       // check it actually exists 
00268       if(blockRef.isNull()) continue;
00269       
00270       // then get the elements of the block
00271       const edm::OwnVector< reco::PFBlockElement >&  elements = (*blockRef).elements();
00272       
00273       const reco::PFBlockElement & pfbe (elements[elementIndex]); 
00274       // The first ECAL element should be the cluster associated to the GSF; defined as the seed
00275       if(pfbe.type()==reco::PFBlockElement::ECAL)
00276         {         
00277 
00278           //std::cout << "BlockElement ECAL" << std::endl;
00279           // the Brem photons are saved as daughter PFCandidate; this 
00280           // is convenient to access the corrected energy
00281           //      std::cout << " Found candidate "  << correspondingDaughterCandidate(coCandidate,pfbe) << " " << coCandidate << std::endl;
00282           createBasicCluster(pfbe,basicClusters_[iphot],pfClusters_[iphot],correspondingDaughterCandidate(cand,pfbe));
00283         }
00284       if(pfbe.type()==reco::PFBlockElement::PS1)
00285         {
00286           //std::cout << "BlockElement PS1" << std::endl;
00287           createPreshowerCluster(pfbe,preshowerClusters_[iphot],1);
00288         }
00289       if(pfbe.type()==reco::PFBlockElement::PS2)
00290         {
00291           //std::cout << "BlockElement PS2" << std::endl;
00292           createPreshowerCluster(pfbe,preshowerClusters_[iphot],2);
00293         }    
00294 
00295 
00296     }   // loop on the elements
00297 
00298         // save the basic clusters
00299     basicClusters_p->insert(basicClusters_p->end(),basicClusters_[iphot].begin(), basicClusters_[iphot].end());
00300     // save the preshower clusters
00301     psClusters_p->insert(psClusters_p->end(),preshowerClusters_[iphot].begin(),preshowerClusters_[iphot].end());
00302 
00303     ++iphot;
00304 
00305   } // loop on PFCandidates
00306 
00307 
00308    //Save the basic clusters and get an handle as to be able to create valid Refs (thanks to Claude)
00309   //  std::cout << " Number of basic clusters " << basicClusters_p->size() << std::endl;
00310   const edm::OrphanHandle<reco::BasicClusterCollection> bcRefProd = 
00311     iEvent.put(basicClusters_p,PFBasicClusterCollection_);
00312 
00313   //preshower clusters
00314   const edm::OrphanHandle<reco::PreshowerClusterCollection> psRefProd = 
00315     iEvent.put(psClusters_p,PFPreshowerClusterCollection_);
00316   
00317   // now that the Basic clusters are in the event, the Ref can be created
00318   createBasicClusterPtrs(bcRefProd);
00319   // now that the preshower clusters are in the event, the Ref can be created
00320   createPreshowerClusterPtrs(psRefProd);
00321 
00322   // and now the Super cluster can be created with valid references  
00323   //if(status) createSuperClusters(*pfCandidates,*superClusters_p);
00324   if(status) createSuperClusters(*pfCandidates,outputSuperClusterCollection);
00325   
00326   //std::cout << "nb superclusters in collection : "<<outputSuperClusterCollection.size()<<std::endl;
00327 
00328   // Let's put the super clusters in the event
00329   std::auto_ptr<reco::SuperClusterCollection> superClusters_p(new reco::SuperClusterCollection(outputSuperClusterCollection));  
00330   const edm::OrphanHandle<reco::SuperClusterCollection> scRefProd = iEvent.put(superClusters_p,PFSuperClusterCollection_); 
00331 
00332 
00333   /*
00334   int ipho=0;
00335   for (reco::SuperClusterCollection::const_iterator gamIter = scRefProd->begin(); gamIter != scRefProd->end(); ++gamIter){
00336     std::cout << "SC i="<<ipho<<" energy="<<gamIter->energy()<<std::endl;
00337     ipho++;
00338   }
00339   */
00340 
00341 
00342   //1-leg conversions
00343 
00344 
00345   if (status) createOneLegConversions(scRefProd, outputOneLegConversionCollection);
00346 
00347 
00348   std::auto_ptr<reco::ConversionCollection> SingleLeg_p(new reco::ConversionCollection(outputOneLegConversionCollection));  
00349   const edm::OrphanHandle<reco::ConversionCollection> ConvRefProd = iEvent.put(SingleLeg_p,PFConversionCollection_);
00350   /*
00351   int iconv = 0;
00352   for (reco::ConversionCollection::const_iterator convIter = ConvRefProd->begin(); convIter != ConvRefProd->end(); ++convIter){
00353 
00354     std::cout << "OneLegConv i="<<iconv<<" nTracks="<<convIter->nTracks()<<" EoverP="<<convIter->EoverP() <<std::endl;
00355     std::vector<edm::RefToBase<reco::Track> > convtracks = convIter->tracks();
00356     for (unsigned int itk=0; itk<convtracks.size(); itk++){
00357       std::cout << "Track pt="<< convtracks[itk]->pt() << std::endl;
00358     }  
00359 
00360     iconv++;
00361   }
00362   */
00363 
00364   //create photon cores
00365   //if(status) createPhotonCores(pfCandidates, scRefProd, *photonCores_p);
00366   if(status) createPhotonCores(scRefProd, ConvRefProd, outputPhotonCoreCollection);
00367   
00368   //std::cout << "nb photoncores in collection : "<<outputPhotonCoreCollection.size()<<std::endl;
00369 
00370   // Put the photon cores in the event
00371   std::auto_ptr<reco::PhotonCoreCollection> photonCores_p(new reco::PhotonCoreCollection(outputPhotonCoreCollection));  
00372   //std::cout << "photon core collection put in auto_ptr"<<std::endl;
00373   const edm::OrphanHandle<reco::PhotonCoreCollection> pcRefProd = iEvent.put(photonCores_p,PFPhotonCoreCollection_); 
00374   
00375   //std::cout << "photon core have been put in the event"<<std::endl;
00376   /*
00377   int ipho=0;
00378   for (reco::PhotonCoreCollection::const_iterator gamIter = pcRefProd->begin(); gamIter != pcRefProd->end(); ++gamIter){
00379     std::cout << "PhotonCore i="<<ipho<<" energy="<<gamIter->pfSuperCluster()->energy()<<std::endl;
00380     //for (unsigned int i=0; i<)
00381 
00382     std::cout << "PhotonCore i="<<ipho<<" nconv2leg="<<gamIter->conversions().size()<<" nconv1leg="<<gamIter->conversionsOneLeg().size()<<std::endl;
00383 
00384     const reco::ConversionRefVector & conv = gamIter->conversions();
00385     for (unsigned int iconv=0; iconv<conv.size(); iconv++){
00386       cout << "2-leg iconv="<<iconv<<endl;
00387       cout << "2-leg nTracks="<<conv[iconv]->nTracks()<<endl;
00388       cout << "2-leg EoverP="<<conv[iconv]->EoverP()<<endl;
00389       cout << "2-leg ConvAlgorithm="<<conv[iconv]->algo()<<endl;
00390     }
00391 
00392     const reco::ConversionRefVector & convbis = gamIter->conversionsOneLeg();
00393     for (unsigned int iconv=0; iconv<convbis.size(); iconv++){
00394       cout << "1-leg iconv="<<iconv<<endl;
00395       cout << "1-leg nTracks="<<convbis[iconv]->nTracks()<<endl;
00396       cout << "1-leg EoverP="<<convbis[iconv]->EoverP()<<endl;
00397       cout << "1-leg ConvAlgorithm="<<convbis[iconv]->algo()<<endl;
00398     }
00399 
00400     ipho++;
00401   }
00402   */
00403 
00404   //load vertices
00405   reco::VertexCollection vertexCollection;
00406   bool validVertex=true;
00407   iEvent.getByLabel(vertexProducer_, vertexHandle);
00408   if (!vertexHandle.isValid()) {
00409     edm::LogWarning("PhotonProducer") << "Error! Can't get the product primary Vertex Collection "<< "\n";
00410     validVertex=false;
00411   }
00412   if (validVertex) vertexCollection = *(vertexHandle.product());
00413 
00414   /*
00415   //load Ecal rechits
00416   bool validEcalRecHits=true;
00417   Handle<EcalRecHitCollection> barrelHitHandle;
00418   EcalRecHitCollection barrelRecHits;
00419   iEvent.getByLabel(barrelEcalHits_, barrelHitHandle);
00420   if (!barrelHitHandle.isValid()) {
00421     edm::LogError("PhotonProducer") << "Error! Can't get the product "<<barrelEcalHits_.label();
00422     validEcalRecHits=false; 
00423   }
00424   if (  validEcalRecHits)  barrelRecHits = *(barrelHitHandle.product());
00425   
00426   Handle<EcalRecHitCollection> endcapHitHandle;
00427   iEvent.getByLabel(endcapEcalHits_, endcapHitHandle);
00428   EcalRecHitCollection endcapRecHits;
00429   if (!endcapHitHandle.isValid()) {
00430     edm::LogError("PhotonProducer") << "Error! Can't get the product "<<endcapEcalHits_.label();
00431     validEcalRecHits=false; 
00432   }
00433   if( validEcalRecHits) endcapRecHits = *(endcapHitHandle.product());
00434 
00435   //load detector topology & geometry
00436   iSetup.get<CaloGeometryRecord>().get(theCaloGeom_);
00437 
00438   edm::ESHandle<CaloTopology> pTopology;
00439   iSetup.get<CaloTopologyRecord>().get(theCaloTopo_);
00440   const CaloTopology *topology = theCaloTopo_.product();
00441 
00442   // get Hcal towers collection 
00443   Handle<CaloTowerCollection> hcalTowersHandle;
00444   iEvent.getByLabel(hcalTowers_, hcalTowersHandle);
00445   */
00446 
00447   //create photon collection
00448   //if(status) createPhotons(vertexCollection, pcRefProd, topology, &barrelRecHits, &endcapRecHits, hcalTowersHandle, isolationValues, outputPhotonCollection);
00449   if(status) createPhotons(vertexCollection, egPhotons, pcRefProd, isolationValues, outputPhotonCollection);
00450 
00451   // Put the photons in the event
00452   std::auto_ptr<reco::PhotonCollection> photons_p(new reco::PhotonCollection(outputPhotonCollection));  
00453   //std::cout << "photon collection put in auto_ptr"<<std::endl;
00454   const edm::OrphanHandle<reco::PhotonCollection> photonRefProd = iEvent.put(photons_p,PFPhotonCollection_); 
00455   //std::cout << "photons have been put in the event"<<std::endl;
00456   
00457   /*
00458   ipho=0;
00459   for (reco::PhotonCollection::const_iterator gamIter = photonRefProd->begin(); gamIter != photonRefProd->end(); ++gamIter){
00460     std::cout << "Photon i="<<ipho<<" pfEnergy="<<gamIter->pfSuperCluster()->energy()<<std::endl;
00461     
00462     const reco::ConversionRefVector & conv = gamIter->conversions();
00463     cout << "conversions obtained : conv.size()="<< conv.size()<<endl;
00464     for (unsigned int iconv=0; iconv<conv.size(); iconv++){
00465       cout << "iconv="<<iconv<<endl;
00466       cout << "nTracks="<<conv[iconv]->nTracks()<<endl;
00467       cout << "EoverP="<<conv[iconv]->EoverP()<<endl;
00468       
00469       cout << "Vtx x="<<conv[iconv]->conversionVertex().x() << " y="<< conv[iconv]->conversionVertex().y()<<" z="<<conv[iconv]->conversionVertex().z()<< endl;
00470       cout << "VtxError x=" << conv[iconv]->conversionVertex().xError() << endl;
00471       
00472       std::vector<edm::RefToBase<reco::Track> > convtracks = conv[iconv]->tracks();
00473       //cout << "nTracks="<< convtracks.size()<<endl;
00474       for (unsigned int itk=0; itk<convtracks.size(); itk++){
00475         double convtrackpt = convtracks[itk]->pt();
00476         const edm::RefToBase<reco::Track> & mytrack = convtracks[itk];
00477         cout << "Track pt="<< convtrackpt <<endl;
00478         cout << "Track origin="<<gamIter->conversionTrackOrigin(mytrack)<<endl;
00479       }
00480     }
00481     
00482     //1-leg
00483     const reco::ConversionRefVector & convbis = gamIter->conversionsOneLeg();
00484     cout << "conversions obtained : conv.size()="<< convbis.size()<<endl;
00485     for (unsigned int iconv=0; iconv<convbis.size(); iconv++){
00486       cout << "iconv="<<iconv<<endl;
00487       cout << "nTracks="<<convbis[iconv]->nTracks()<<endl;
00488       cout << "EoverP="<<convbis[iconv]->EoverP()<<endl;
00489       
00490       cout << "Vtx x="<<convbis[iconv]->conversionVertex().x() << " y="<< convbis[iconv]->conversionVertex().y()<<" z="<<convbis[iconv]->conversionVertex().z()<< endl;
00491       cout << "VtxError x=" << convbis[iconv]->conversionVertex().xError() << endl;
00492        
00493       std::vector<edm::RefToBase<reco::Track> > convtracks = convbis[iconv]->tracks();
00494       //cout << "nTracks="<< convtracks.size()<<endl;
00495       for (unsigned int itk=0; itk<convtracks.size(); itk++){
00496         double convtrackpt = convtracks[itk]->pt();
00497         cout << "Track pt="<< convtrackpt <<endl;
00498         cout << "Track origin="<<gamIter->conversionTrackOrigin((convtracks[itk]))<<endl;
00499       }
00500     }
00501     ipho++;
00502   }
00503   */
00504   
00505 }
00506 
00507 bool PFPhotonTranslator::fetchCandidateCollection(edm::Handle<reco::PFCandidateCollection>& c, 
00508                                               const edm::InputTag& tag, 
00509                                               const edm::Event& iEvent) const {  
00510   bool found = iEvent.getByLabel(tag, c);
00511 
00512   if(!found && !emptyIsOk_)
00513     {
00514       std::ostringstream  err;
00515       err<<" cannot get PFCandidates: "
00516          <<tag<<std::endl;
00517       edm::LogError("PFPhotonTranslator")<<err.str();
00518     }
00519   return found;
00520       
00521 }
00522 
00523 // The basic cluster is a copy of the PFCluster -> the energy is not corrected 
00524 // It should be possible to get the corrected energy (including the associated PS energy)
00525 // from the PFCandidate daugthers ; Needs some work 
00526 void PFPhotonTranslator::createBasicCluster(const reco::PFBlockElement & PFBE, 
00527                                               reco::BasicClusterCollection & basicClusters, 
00528                                               std::vector<const reco::PFCluster *> & pfClusters,
00529                                               const reco::PFCandidate & coCandidate) const
00530 {
00531   reco::PFClusterRef myPFClusterRef = PFBE.clusterRef();
00532   if(myPFClusterRef.isNull()) return;  
00533 
00534   const reco::PFCluster & myPFCluster (*myPFClusterRef);
00535   pfClusters.push_back(&myPFCluster);
00536   //std::cout << " Creating BC " << myPFCluster.energy() << " " << coCandidate.ecalEnergy() <<" "<<  coCandidate.rawEcalEnergy() <<std::endl;
00537   //std::cout << " # hits " << myPFCluster.hitsAndFractions().size() << std::endl;
00538 
00539 //  basicClusters.push_back(reco::CaloCluster(myPFCluster.energy(),
00540   basicClusters.push_back(reco::CaloCluster(//coCandidate.rawEcalEnergy(),
00541                                             myPFCluster.energy(),
00542                                             myPFCluster.position(),
00543                                             myPFCluster.caloID(),
00544                                             myPFCluster.hitsAndFractions(),
00545                                             myPFCluster.algo(),
00546                                             myPFCluster.seed()));
00547 }
00548 
00549 void PFPhotonTranslator::createPreshowerCluster(const reco::PFBlockElement & PFBE, reco::PreshowerClusterCollection& preshowerClusters,unsigned plane) const
00550 {
00551   reco::PFClusterRef  myPFClusterRef= PFBE.clusterRef();
00552   preshowerClusters.push_back(reco::PreshowerCluster(myPFClusterRef->energy(),myPFClusterRef->position(),
00553                                                myPFClusterRef->hitsAndFractions(),plane));
00554 }
00555 
00556 void PFPhotonTranslator::createBasicClusterPtrs(const edm::OrphanHandle<reco::BasicClusterCollection> & basicClustersHandle )
00557 {
00558   unsigned size=photPFCandidateIndex_.size();
00559   unsigned basicClusterCounter=0;
00560   basicClusterPtr_.resize(size);
00561 
00562   for(unsigned iphot=0;iphot<size;++iphot) // loop on tracks
00563     {
00564       unsigned nbc=basicClusters_[iphot].size();
00565       for(unsigned ibc=0;ibc<nbc;++ibc) // loop on basic clusters
00566         {
00567           //      std::cout <<  "Track "<< iGSF << " ref " << basicClusterCounter << std::endl;
00568           reco::CaloClusterPtr bcPtr(basicClustersHandle,basicClusterCounter);
00569           basicClusterPtr_[iphot].push_back(bcPtr);
00570           ++basicClusterCounter;
00571         }
00572     }
00573 }
00574 
00575 void PFPhotonTranslator::createPreshowerClusterPtrs(const edm::OrphanHandle<reco::PreshowerClusterCollection> & preshowerClustersHandle )
00576 {
00577   unsigned size=photPFCandidateIndex_.size();
00578   unsigned psClusterCounter=0;
00579   preshowerClusterPtr_.resize(size);
00580 
00581   for(unsigned iphot=0;iphot<size;++iphot) // loop on tracks
00582     {
00583       unsigned nbc=preshowerClusters_[iphot].size();
00584       for(unsigned ibc=0;ibc<nbc;++ibc) // loop on basic clusters
00585         {
00586           //      std::cout <<  "Track "<< iGSF << " ref " << basicClusterCounter << std::endl;
00587           reco::CaloClusterPtr psPtr(preshowerClustersHandle,psClusterCounter);
00588           preshowerClusterPtr_[iphot].push_back(psPtr);
00589           ++psClusterCounter;
00590         }
00591     }
00592 }
00593 
00594 void PFPhotonTranslator::createSuperClusters(const reco::PFCandidateCollection & pfCand,
00595                                                reco::SuperClusterCollection &superClusters) const
00596 {
00597   unsigned nphot=photPFCandidateIndex_.size();
00598   for(unsigned iphot=0;iphot<nphot;++iphot)
00599     {
00600 
00601       //cout << "SC iphot=" << iphot << endl;
00602 
00603       // Computes energy position a la e/gamma 
00604       double sclusterE=0;
00605       double posX=0.;
00606       double posY=0.;
00607       double posZ=0.;
00608       
00609       unsigned nbasics=basicClusters_[iphot].size();
00610       for(unsigned ibc=0;ibc<nbasics;++ibc)
00611         {
00612           //cout << "BC in SC : iphot="<<iphot<<endl;
00613           
00614           double e = basicClusters_[iphot][ibc].energy();
00615           sclusterE += e;
00616           posX += e * basicClusters_[iphot][ibc].position().X();
00617           posY += e * basicClusters_[iphot][ibc].position().Y();
00618           posZ += e * basicClusters_[iphot][ibc].position().Z();          
00619         }
00620       posX /=sclusterE;
00621       posY /=sclusterE;
00622       posZ /=sclusterE;
00623       
00624       /*
00625       if(pfCand[gsfPFCandidateIndex_[iphot]].gsfTrackRef()!=GsfTrackRef_[iphot])
00626         {
00627           edm::LogError("PFElectronTranslator") << " Major problem in PFElectron Translator" << std::endl;
00628         }
00629       */      
00630 
00631       // compute the width
00632       PFClusterWidthAlgo pfwidth(pfClusters_[iphot]);
00633       
00634       double correctedEnergy=pfCand[photPFCandidateIndex_[iphot]].ecalEnergy();
00635       reco::SuperCluster mySuperCluster(correctedEnergy,math::XYZPoint(posX,posY,posZ));
00636       // protection against empty basic cluster collection ; the value is -2 in this case
00637       if(nbasics)
00638         {
00639 //        std::cout << "SuperCluster creation; energy " << pfCand[gsfPFCandidateIndex_[iphot]].ecalEnergy();
00640 //        std::cout << " " <<   pfCand[gsfPFCandidateIndex_[iphot]].rawEcalEnergy() << std::endl;
00641 //        std::cout << "Seed energy from basic " << basicClusters_[iphot][0].energy() << std::endl;
00642           mySuperCluster.setSeed(basicClusterPtr_[iphot][0]);
00643         }
00644       else
00645         {
00646           //      std::cout << "SuperCluster creation ; seed energy " << 0 << std::endl;
00647           //std::cout << "SuperCluster creation ; energy " << pfCand[photPFCandidateIndex_[iphot]].ecalEnergy();
00648           //std::cout << " " <<   pfCand[photPFCandidateIndex_[iphot]].rawEcalEnergy() << std::endl;
00649 //        std::cout << " No seed found " << 0 << std::endl;       
00650 //        std::cout << " MVA " << pfCand[gsfPFCandidateIndex_[iphot]].mva_e_pi() << std::endl;
00651           mySuperCluster.setSeed(reco::CaloClusterPtr());
00652         }
00653       // the seed should be the first basic cluster
00654 
00655       for(unsigned ibc=0;ibc<nbasics;++ibc)
00656         {
00657           mySuperCluster.addCluster(basicClusterPtr_[iphot][ibc]);
00658           //      std::cout <<"Adding Ref to SC " << basicClusterPtr_[iphot][ibc].index() << std::endl;
00659           const std::vector< std::pair<DetId, float> > & v1 = basicClusters_[iphot][ibc].hitsAndFractions();
00660           //      std::cout << " Number of cells " << v1.size() << std::endl;
00661           for( std::vector< std::pair<DetId, float> >::const_iterator diIt = v1.begin();
00662                diIt != v1.end();
00663                ++diIt ) {
00664             //      std::cout << " Adding DetId " << (diIt->first).rawId() << " " << diIt->second << std::endl;
00665             mySuperCluster.addHitAndFraction(diIt->first,diIt->second);
00666           } // loop over rechits      
00667         }      
00668 
00669       unsigned nps=preshowerClusterPtr_[iphot].size();
00670       for(unsigned ips=0;ips<nps;++ips)
00671         {
00672           mySuperCluster.addPreshowerCluster(preshowerClusterPtr_[iphot][ips]);
00673         }
00674       
00675 
00676       // Set the preshower energy
00677       mySuperCluster.setPreshowerEnergy(pfCand[photPFCandidateIndex_[iphot]].pS1Energy()+
00678                                         pfCand[photPFCandidateIndex_[iphot]].pS2Energy());
00679 
00680       // Set the cluster width
00681       mySuperCluster.setEtaWidth(pfwidth.pflowEtaWidth());
00682       mySuperCluster.setPhiWidth(pfwidth.pflowPhiWidth());
00683       // Force the computation of rawEnergy_ of the reco::SuperCluster
00684       mySuperCluster.rawEnergy();
00685 
00686       //cout << "SC energy="<< mySuperCluster.energy()<<endl;
00687 
00688       superClusters.push_back(mySuperCluster);
00689       //std::cout << "nb super clusters in collection : "<<superClusters.size()<<std::endl;
00690     }
00691 }
00692 
00693 void PFPhotonTranslator::createOneLegConversions(const edm::OrphanHandle<reco::SuperClusterCollection> & superClustersHandle, reco::ConversionCollection &oneLegConversions)
00694 {
00695 
00696   //std::cout << "createOneLegConversions" << std::endl;
00697 
00698     unsigned nphot=photPFCandidateIndex_.size();
00699     for(unsigned iphot=0;iphot<nphot;++iphot)
00700       {
00701 
00702         //if (conv1legPFCandidateIndex_[iphot]==-1) cout << "No OneLegConversions to add"<<endl;
00703         //else std::cout << "Phot "<<iphot<< " nOneLegConversions to add : "<<pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]].size()<<endl;
00704 
00705 
00706         if (conv1legPFCandidateIndex_[iphot]>-1){
00707 
00708           for (unsigned iConv=0; iConv<pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]].size(); iConv++){
00709 
00710             reco::CaloClusterPtrVector scPtrVec;
00711             std::vector<reco::CaloClusterPtr>matchingBC;
00712             math::Error<3>::type error;
00713             const reco::Vertex  * convVtx = new reco::Vertex(pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->innerPosition(), error);
00714             
00715             //cout << "Vtx x="<<convVtx->x() << " y="<< convVtx->y()<<" z="<<convVtx->z()<< endl;
00716             //cout << "VtxError x=" << convVtx->xError() << endl;
00717 
00718             std::vector<reco::TrackRef> OneLegConvVector;
00719             OneLegConvVector.push_back(pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]);
00720             
00721             reco::CaloClusterPtrVector clu=scPtrVec;
00722             std::vector<reco::TrackRef> tr=OneLegConvVector;
00723             std::vector<math::XYZPointF>trackPositionAtEcalVec;
00724             std::vector<math::XYZPointF>innPointVec;
00725             std::vector<math::XYZVectorF>trackPinVec;
00726             std::vector<math::XYZVectorF>trackPoutVec;
00727             math::XYZPointF trackPositionAtEcal(pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00728                                                 outerPosition().X(), 
00729                                                 pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00730                                                 outerPosition().Y(),
00731                                                 pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00732                                                 outerPosition().Z());
00733             math::XYZPointF innPoint(pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00734                                      innerPosition().X(), 
00735                                      pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00736                                      innerPosition().Y(),
00737                                      pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00738                                      innerPosition().Z());
00739             math::XYZVectorF trackPin(pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00740                                      innerMomentum().X(), 
00741                                      pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00742                                      innerMomentum().Y(),
00743                                      pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00744                                      innerMomentum().Z());
00745             math::XYZVectorF trackPout(pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00746                                       outerMomentum().X(), 
00747                                       pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00748                                       outerMomentum().Y(),
00749                                       pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->
00750                                       outerMomentum().Z());
00751             float DCA=pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]][iConv]->d0();
00752             trackPositionAtEcalVec.push_back(trackPositionAtEcal);
00753             innPointVec.push_back(innPoint);
00754             trackPinVec.push_back(trackPin);
00755             trackPoutVec.push_back(trackPout);
00756             std::vector< float > OneLegMvaVector;
00757             reco::Conversion myOneLegConversion(scPtrVec, 
00758                                                 OneLegConvVector,
00759                                                 trackPositionAtEcalVec,
00760                                                 *convVtx,
00761                                                 matchingBC,
00762                                                 DCA,
00763                                                 innPointVec,
00764                                                 trackPinVec,
00765                                                 trackPoutVec,
00766                                                 pfSingleLegConvMva_[conv1legPFCandidateIndex_[iphot]][iConv],                     
00767                                                 reco::Conversion::pflow);
00768             OneLegMvaVector.push_back(pfSingleLegConvMva_[conv1legPFCandidateIndex_[iphot]][iConv]);
00769             myOneLegConversion.setOneLegMVA(OneLegMvaVector);
00770             //reco::Conversion myOneLegConversion(scPtrVec, 
00771             //OneLegConvVector, *convVtx, reco::Conversion::pflow);
00772             
00773             /*
00774             std::cout << "One leg conversion created" << endl;
00775             std::vector<edm::RefToBase<reco::Track> > convtracks = myOneLegConversion.tracks();
00776             const std::vector<float> mvalist = myOneLegConversion.oneLegMVA();
00777 
00778             cout << "nTracks="<< convtracks.size()<<endl;
00779             for (unsigned int itk=0; itk<convtracks.size(); itk++){
00780               //double convtrackpt = convtracks[itk]->pt();
00781               std::cout << "Track pt="<< convtracks[itk]->pt() << std::endl;
00782               std::cout << "Track mva="<< mvalist[itk] << std::endl;
00783             }   
00784             */
00785             oneLegConversions.push_back(myOneLegConversion);
00786             
00787             //cout << "OneLegConv added"<<endl;
00788             
00789           }
00790         }
00791       }
00792 }
00793 
00794 
00795 void PFPhotonTranslator::createPhotonCores(const edm::OrphanHandle<reco::SuperClusterCollection> & superClustersHandle, const edm::OrphanHandle<reco::ConversionCollection> & oneLegConversionHandle, reco::PhotonCoreCollection &photonCores)
00796 {
00797   
00798   //std::cout << "createPhotonCores" << std::endl;
00799 
00800   unsigned nphot=photPFCandidateIndex_.size();
00801 
00802   unsigned i1legtot = 0;
00803 
00804   for(unsigned iphot=0;iphot<nphot;++iphot)
00805     {
00806       //std::cout << "iphot="<<iphot<<std::endl;
00807 
00808       reco::PhotonCore myPhotonCore;
00809 
00810       reco::SuperClusterRef SCref(reco::SuperClusterRef(superClustersHandle, iphot));
00811       
00812       myPhotonCore.setPFlowPhoton(true);
00813       myPhotonCore.setStandardPhoton(false);
00814       myPhotonCore.setPflowSuperCluster(SCref);
00815       myPhotonCore.setSuperCluster(egSCRef_[iphot]);
00816 
00817       reco::ElectronSeedRefVector pixelSeeds = egPhotonRef_[iphot]->electronPixelSeeds();
00818       for (unsigned iseed=0; iseed<pixelSeeds.size(); iseed++){
00819         myPhotonCore.addElectronPixelSeed(pixelSeeds[iseed]);
00820       }
00821 
00822       //cout << "PhotonCores : SC OK" << endl;
00823 
00824       //cout << "conv1legPFCandidateIndex_[iphot]="<<conv1legPFCandidateIndex_[iphot]<<endl;
00825       //cout << "conv2legPFCandidateIndex_[iphot]="<<conv2legPFCandidateIndex_[iphot]<<endl;
00826 
00827       if (conv1legPFCandidateIndex_[iphot]>-1){
00828         for (unsigned int iConv=0; iConv<pfSingleLegConv_[conv1legPFCandidateIndex_[iphot]].size(); iConv++){
00829           
00830           const reco::ConversionRef & OneLegRef(reco::ConversionRef(oneLegConversionHandle, i1legtot));
00831           myPhotonCore.addOneLegConversion(OneLegRef);
00832           
00833           //cout << "PhotonCores : 1-leg OK" << endl;
00834           /*
00835           cout << "Testing 1-leg :"<<endl;
00836           const reco::ConversionRefVector & conv = myPhotonCore.conversionsOneLeg();
00837           for (unsigned int iconv=0; iconv<conv.size(); iconv++){
00838             cout << "Testing 1-leg : iconv="<<iconv<<endl;
00839             cout << "Testing 1-leg : nTracks="<<conv[iconv]->nTracks()<<endl;
00840             cout << "Testing 1-leg : EoverP="<<conv[iconv]->EoverP()<<endl;
00841             std::vector<edm::RefToBase<reco::Track> > convtracks = conv[iconv]->tracks();
00842             for (unsigned int itk=0; itk<convtracks.size(); itk++){
00843               //double convtrackpt = convtracks[itk]->pt();
00844               std::cout << "Testing 1-leg : Track pt="<< convtracks[itk]->pt() << std::endl;
00845               // std::cout << "Track mva="<< mvalist[itk] << std::endl;
00846             }  
00847           }
00848           */
00849 
00850           i1legtot++;
00851         }
00852       }
00853 
00854       if (conv2legPFCandidateIndex_[iphot]>-1){
00855         for(unsigned int iConv=0; iConv<pfConv_[conv2legPFCandidateIndex_[iphot]].size(); iConv++) {
00856 
00857           const reco::ConversionRef & TwoLegRef(pfConv_[conv2legPFCandidateIndex_[iphot]][iConv]);
00858           myPhotonCore.addConversion(TwoLegRef);
00859 
00860         }
00861         //cout << "PhotonCores : 2-leg OK" << endl;
00862 
00863         /*
00864         cout << "Testing 2-leg :"<<endl;
00865         const reco::ConversionRefVector & conv = myPhotonCore.conversions();
00866         for (unsigned int iconv=0; iconv<conv.size(); iconv++){
00867           cout << "Testing 2-leg : iconv="<<iconv<<endl;
00868           cout << "Testing 2-leg : nTracks="<<conv[iconv]->nTracks()<<endl;
00869           cout << "Testing 2-leg : EoverP="<<conv[iconv]->EoverP()<<endl;
00870           std::vector<edm::RefToBase<reco::Track> > convtracks = conv[iconv]->tracks();
00871           for (unsigned int itk=0; itk<convtracks.size(); itk++){
00872             //double convtrackpt = convtracks[itk]->pt();
00873             std::cout << "Testing 2-leg : Track pt="<< convtracks[itk]->pt() << std::endl;
00874             // std::cout << "Track mva="<< mvalist[itk] << std::endl;
00875           }  
00876         }
00877         */
00878       }
00879 
00880       photonCores.push_back(myPhotonCore);
00881       
00882     }
00883 
00884   //std::cout << "end of createPhotonCores"<<std::endl;
00885 }
00886 
00887 
00888 void PFPhotonTranslator::createPhotons(reco::VertexCollection &vertexCollection, edm::Handle<reco::PhotonCollection> &egPhotons, const edm::OrphanHandle<reco::PhotonCoreCollection> & photonCoresHandle, const IsolationValueMaps& isolationValues, reco::PhotonCollection &photons) 
00889 {
00890 
00891   //cout << "createPhotons" << endl;
00892   
00893   unsigned nphot=photPFCandidateIndex_.size();
00894 
00895   for(unsigned iphot=0;iphot<nphot;++iphot)
00896     {
00897       //std::cout << "iphot="<<iphot<<std::endl;
00898 
00899       reco::PhotonCoreRef PCref(reco::PhotonCoreRef(photonCoresHandle, iphot));
00900 
00901       math::XYZPoint vtx(0.,0.,0.);
00902       if (vertexCollection.size()>0) vtx = vertexCollection.begin()->position();
00903       //std::cout << "vtx made" << std::endl;
00904 
00905       math::XYZVector direction =  PCref->pfSuperCluster()->position() - vtx;
00906 
00907       //It could be that pfSC energy gives not the best resolution : use smaller agregates for some cases ?
00908       math::XYZVector P3 = direction.unit() * PCref->pfSuperCluster()->energy();
00909       LorentzVector P4(P3.x(), P3.y(), P3.z(), PCref->pfSuperCluster()->energy());
00910 
00911       reco::Photon myPhoton(P4, PCref->pfSuperCluster()->position(), PCref, vtx);
00912       //cout << "photon created"<<endl;
00913 
00914 
00915 
00916       reco::Photon::ShowerShape  showerShape;
00917       reco::Photon::FiducialFlags fiducialFlags;
00918       reco::Photon::IsolationVariables isolationVariables03;
00919       reco::Photon::IsolationVariables isolationVariables04;
00920 
00921       showerShape.e1x5= egPhotonRef_[iphot]->e1x5();
00922       showerShape.e2x5= egPhotonRef_[iphot]->e2x5();
00923       showerShape.e3x3= egPhotonRef_[iphot]->e3x3();
00924       showerShape.e5x5= egPhotonRef_[iphot]->e5x5();
00925       showerShape.maxEnergyXtal =  egPhotonRef_[iphot]->maxEnergyXtal();
00926       showerShape.sigmaEtaEta =    egPhotonRef_[iphot]->sigmaEtaEta();
00927       showerShape.sigmaIetaIeta =  egPhotonRef_[iphot]->sigmaIetaIeta();
00928       showerShape.hcalDepth1OverEcal = egPhotonRef_[iphot]->hadronicDepth1OverEm();
00929       showerShape.hcalDepth2OverEcal = egPhotonRef_[iphot]->hadronicDepth2OverEm();
00930       myPhoton.setShowerShapeVariables ( showerShape ); 
00931           
00932       fiducialFlags.isEB = egPhotonRef_[iphot]->isEB();
00933       fiducialFlags.isEE = egPhotonRef_[iphot]->isEE();
00934       fiducialFlags.isEBEtaGap = egPhotonRef_[iphot]->isEBEtaGap();
00935       fiducialFlags.isEBPhiGap = egPhotonRef_[iphot]->isEBPhiGap();
00936       fiducialFlags.isEERingGap = egPhotonRef_[iphot]->isEERingGap();
00937       fiducialFlags.isEEDeeGap = egPhotonRef_[iphot]->isEEDeeGap();
00938       fiducialFlags.isEBEEGap = egPhotonRef_[iphot]->isEBEEGap();
00939       myPhoton.setFiducialVolumeFlags ( fiducialFlags );
00940 
00941       isolationVariables03.ecalRecHitSumEt = egPhotonRef_[iphot]->ecalRecHitSumEtConeDR03();
00942       isolationVariables03.hcalTowerSumEt = egPhotonRef_[iphot]->hcalTowerSumEtConeDR03();
00943       isolationVariables03.hcalDepth1TowerSumEt = egPhotonRef_[iphot]->hcalDepth1TowerSumEtConeDR03();
00944       isolationVariables03.hcalDepth2TowerSumEt = egPhotonRef_[iphot]->hcalDepth2TowerSumEtConeDR03();
00945       isolationVariables03.trkSumPtSolidCone = egPhotonRef_[iphot]->trkSumPtSolidConeDR03();
00946       isolationVariables03.trkSumPtHollowCone = egPhotonRef_[iphot]->trkSumPtHollowConeDR03();
00947       isolationVariables03.nTrkSolidCone = egPhotonRef_[iphot]->nTrkSolidConeDR03();
00948       isolationVariables03.nTrkHollowCone = egPhotonRef_[iphot]->nTrkHollowConeDR03();
00949       isolationVariables04.ecalRecHitSumEt = egPhotonRef_[iphot]->ecalRecHitSumEtConeDR04();
00950       isolationVariables04.hcalTowerSumEt = egPhotonRef_[iphot]->hcalTowerSumEtConeDR04();
00951       isolationVariables04.hcalDepth1TowerSumEt = egPhotonRef_[iphot]->hcalDepth1TowerSumEtConeDR04();
00952       isolationVariables04.hcalDepth2TowerSumEt = egPhotonRef_[iphot]->hcalDepth2TowerSumEtConeDR04();
00953       isolationVariables04.trkSumPtSolidCone = egPhotonRef_[iphot]->trkSumPtSolidConeDR04();
00954       isolationVariables04.trkSumPtHollowCone = egPhotonRef_[iphot]->trkSumPtHollowConeDR04();
00955       isolationVariables04.nTrkSolidCone = egPhotonRef_[iphot]->nTrkSolidConeDR04();
00956       isolationVariables04.nTrkHollowCone = egPhotonRef_[iphot]->nTrkHollowConeDR04();
00957       myPhoton.setIsolationVariables(isolationVariables04, isolationVariables03);
00958      
00959           
00960       
00961 
00962       reco::Photon::PflowIsolationVariables myPFIso;
00963       myPFIso.chargedHadronIso=(*isolationValues[0])[CandidatePtr_[iphot]];
00964       myPFIso.photonIso=(*isolationValues[1])[CandidatePtr_[iphot]];
00965       myPFIso.neutralHadronIso=(*isolationValues[2])[CandidatePtr_[iphot]];   
00966       myPhoton.setPflowIsolationVariables(myPFIso);
00967       
00968       reco::Photon::PflowIDVariables myPFVariables;
00969 
00970       reco::Mustache myMustache;
00971       myMustache.MustacheID(*(myPhoton.pfSuperCluster()), myPFVariables.nClusterOutsideMustache, myPFVariables.etOutsideMustache );
00972       myPFVariables.mva = pfPhotonMva_[iphot];
00973       myPhoton.setPflowIDVariables(myPFVariables);
00974 
00975       //cout << "chargedHadronIso="<<myPhoton.chargedHadronIso()<<" photonIso="<<myPhoton.photonIso()<<" neutralHadronIso="<<myPhoton.neutralHadronIso()<<endl;
00976       
00977       // set PF-regression energy
00978       myPhoton.setCorrectedEnergy(reco::Photon::regression2,energyRegression_[iphot],energyRegressionError_[iphot],false);
00979       
00980 
00981       /*
00982       if (basicClusters_[iphot].size()>0){
00983       // Cluster shape variables
00984       //Algorithms from EcalClusterTools could be adapted to PF photons ? (not based on 5x5 BC)
00985       //It happens that energy computed in eg e5x5 is greater than pfSC energy (EcalClusterTools gathering energies from adjacent crystals even if not belonging to the SC)
00986       const EcalRecHitCollection* hits = 0 ;
00987       int subdet = PCref->pfSuperCluster()->seed()->hitsAndFractions()[0].first.subdetId();
00988       if (subdet==EcalBarrel) hits = barrelRecHits;
00989       else if  (subdet==EcalEndcap) hits = endcapRecHits;
00990       const CaloGeometry* geometry = theCaloGeom_.product();
00991 
00992       float maxXtal =   EcalClusterTools::eMax( *(PCref->pfSuperCluster()->seed()), &(*hits) );
00993       //cout << "maxXtal="<<maxXtal<<endl;
00994       float e1x5    =   EcalClusterTools::e1x5(  *(PCref->pfSuperCluster()->seed()), &(*hits), &(*topology)); 
00995       //cout << "e1x5="<<e1x5<<endl;
00996       float e2x5    =   EcalClusterTools::e2x5Max(  *(PCref->pfSuperCluster()->seed()), &(*hits), &(*topology)); 
00997       //cout << "e2x5="<<e2x5<<endl;
00998       float e3x3    =   EcalClusterTools::e3x3(  *(PCref->pfSuperCluster()->seed()), &(*hits), &(*topology)); 
00999       //cout << "e3x3="<<e3x3<<endl;
01000       float e5x5    =   EcalClusterTools::e5x5( *(PCref->pfSuperCluster()->seed()), &(*hits), &(*topology)); 
01001       //cout << "e5x5="<<e5x5<<endl;
01002       std::vector<float> cov =  EcalClusterTools::covariances( *(PCref->pfSuperCluster()->seed()), &(*hits), &(*topology), geometry); 
01003       float sigmaEtaEta = sqrt(cov[0]);
01004       //cout << "sigmaEtaEta="<<sigmaEtaEta<<endl;
01005       std::vector<float> locCov =  EcalClusterTools::localCovariances( *(PCref->pfSuperCluster()->seed()), &(*hits), &(*topology)); 
01006       float sigmaIetaIeta = sqrt(locCov[0]);
01007       //cout << "sigmaIetaIeta="<<sigmaIetaIeta<<endl;
01008       //float r9 =e3x3/(PCref->pfSuperCluster()->rawEnergy());
01009 
01010 
01011       // calculate HoE
01012       const CaloTowerCollection* hcalTowersColl = hcalTowersHandle.product();
01013       EgammaTowerIsolation towerIso1(hOverEConeSize_,0.,0.,1,hcalTowersColl) ;  
01014       EgammaTowerIsolation towerIso2(hOverEConeSize_,0.,0.,2,hcalTowersColl) ;  
01015       double HoE1=towerIso1.getTowerESum(&(*PCref->pfSuperCluster()))/PCref->pfSuperCluster()->energy();
01016       double HoE2=towerIso2.getTowerESum(&(*PCref->pfSuperCluster()))/PCref->pfSuperCluster()->energy(); 
01017       //cout << "HoE1="<<HoE1<<endl;
01018       //cout << "HoE2="<<HoE2<<endl;  
01019 
01020       reco::Photon::ShowerShape  showerShape;
01021       showerShape.e1x5= e1x5;
01022       showerShape.e2x5= e2x5;
01023       showerShape.e3x3= e3x3;
01024       showerShape.e5x5= e5x5;
01025       showerShape.maxEnergyXtal =  maxXtal;
01026       showerShape.sigmaEtaEta =    sigmaEtaEta;
01027       showerShape.sigmaIetaIeta =  sigmaIetaIeta;
01028       showerShape.hcalDepth1OverEcal = HoE1;
01029       showerShape.hcalDepth2OverEcal = HoE2;
01030       myPhoton.setShowerShapeVariables ( showerShape ); 
01031       //cout << "shower shape variables filled"<<endl;
01032       }
01033       */
01034       
01035 
01036       photons.push_back(myPhoton);
01037 
01038     }
01039 
01040   //std::cout << "end of createPhotons"<<std::endl;
01041 }
01042 
01043 
01044 const reco::PFCandidate & PFPhotonTranslator::correspondingDaughterCandidate(const reco::PFCandidate & cand, const reco::PFBlockElement & pfbe) const
01045 {
01046   unsigned refindex=pfbe.index();
01047   //  std::cout << " N daughters " << cand.numberOfDaughters() << std::endl;
01048   reco::PFCandidate::const_iterator myDaughterCandidate=cand.begin();
01049   reco::PFCandidate::const_iterator itend=cand.end();
01050 
01051   for(;myDaughterCandidate!=itend;++myDaughterCandidate)
01052     {
01053       const reco::PFCandidate * myPFCandidate = (const reco::PFCandidate*)&*myDaughterCandidate;
01054       if(myPFCandidate->elementsInBlocks().size()!=1)
01055         {
01056           //      std::cout << " Daughter with " << myPFCandidate.elementsInBlocks().size()<< " element in block " << std::endl;
01057           return cand;
01058         }
01059       if(myPFCandidate->elementsInBlocks()[0].second==refindex) 
01060         {
01061           //      std::cout << " Found it " << cand << std::endl;
01062           return *myPFCandidate;
01063         }      
01064     }
01065   return cand;
01066 }
01067