CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 #include "RecoParticleFlow/PFProducer/plugins/PFProducer.h"
00002 #include "RecoParticleFlow/PFProducer/interface/PFAlgo.h"
00003 
00004 #include "FWCore/Framework/interface/ESHandle.h"
00005 #include "FWCore/Framework/interface/EventSetup.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00008 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibrationHF.h"
00009 #include "RecoParticleFlow/PFClusterTools/interface/PFSCEnergyCalibration.h"
00010 #include "CondFormats/PhysicsToolsObjects/interface/PerformancePayloadFromTFormula.h"
00011 #include "CondFormats/DataRecord/interface/PFCalibrationRcd.h"
00012 #include "CondFormats/DataRecord/interface/GBRWrapperRcd.h"
00013 #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h"
00014 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
00015 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h"
00016 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00017 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementSuperClusterFwd.h"
00018 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementSuperCluster.h"
00019 #include <sstream>
00020 
00021 #include "TFile.h"
00022 
00023 using namespace std;
00024 
00025 using namespace boost;
00026 
00027 using namespace edm;
00028 
00029 
00030 
00031 PFProducer::PFProducer(const edm::ParameterSet& iConfig) {
00032   
00033   //--ab: get calibration factors for HF:
00034   bool calibHF_use;
00035   std::vector<double>  calibHF_eta_step;
00036   std::vector<double>  calibHF_a_EMonly;
00037   std::vector<double>  calibHF_b_HADonly;
00038   std::vector<double>  calibHF_a_EMHAD;
00039   std::vector<double>  calibHF_b_EMHAD;
00040   calibHF_use =     iConfig.getParameter<bool>("calibHF_use");
00041   calibHF_eta_step  = iConfig.getParameter<std::vector<double> >("calibHF_eta_step");
00042   calibHF_a_EMonly  = iConfig.getParameter<std::vector<double> >("calibHF_a_EMonly");
00043   calibHF_b_HADonly = iConfig.getParameter<std::vector<double> >("calibHF_b_HADonly");
00044   calibHF_a_EMHAD   = iConfig.getParameter<std::vector<double> >("calibHF_a_EMHAD");
00045   calibHF_b_EMHAD   = iConfig.getParameter<std::vector<double> >("calibHF_b_EMHAD");
00046   boost::shared_ptr<PFEnergyCalibrationHF>  
00047     thepfEnergyCalibrationHF ( new PFEnergyCalibrationHF(calibHF_use,calibHF_eta_step,calibHF_a_EMonly,calibHF_b_HADonly,calibHF_a_EMHAD,calibHF_b_EMHAD) ) ;
00048   //-----------------
00049 
00050   inputTagBlocks_ 
00051     = iConfig.getParameter<InputTag>("blocks");
00052 
00053   //Post cleaning of the muons
00054   inputTagMuons_ 
00055     = iConfig.getParameter<InputTag>("muons");
00056   postMuonCleaning_
00057     = iConfig.getParameter<bool>("postMuonCleaning");
00058 
00059   usePFElectrons_
00060     = iConfig.getParameter<bool>("usePFElectrons");    
00061 
00062   usePFPhotons_
00063     = iConfig.getParameter<bool>("usePFPhotons");    
00064 
00065   usePhotonReg_
00066     = (usePFPhotons_) ? iConfig.getParameter<bool>("usePhotonReg") : false ;
00067 
00068   useRegressionFromDB_
00069     = (usePFPhotons_) ? iConfig.getParameter<bool>("useRegressionFromDB") : false; 
00070 
00071   useEGammaElectrons_
00072     = iConfig.getParameter<bool>("useEGammaElectrons");    
00073 
00074   if(  useEGammaElectrons_) {
00075     inputTagEgammaElectrons_ = iConfig.getParameter<edm::InputTag>("egammaElectrons");
00076   }
00077 
00078   electronOutputCol_
00079     = iConfig.getParameter<std::string>("pf_electron_output_col");
00080 
00081   bool usePFSCEleCalib;
00082   std::vector<double>  calibPFSCEle_Fbrem_barrel; 
00083   std::vector<double>  calibPFSCEle_Fbrem_endcap;
00084   std::vector<double>  calibPFSCEle_barrel;
00085   std::vector<double>  calibPFSCEle_endcap;
00086   usePFSCEleCalib =     iConfig.getParameter<bool>("usePFSCEleCalib");
00087   calibPFSCEle_Fbrem_barrel = iConfig.getParameter<std::vector<double> >("calibPFSCEle_Fbrem_barrel");
00088   calibPFSCEle_Fbrem_endcap = iConfig.getParameter<std::vector<double> >("calibPFSCEle_Fbrem_endcap");
00089   calibPFSCEle_barrel = iConfig.getParameter<std::vector<double> >("calibPFSCEle_barrel");
00090   calibPFSCEle_endcap = iConfig.getParameter<std::vector<double> >("calibPFSCEle_endcap");
00091   boost::shared_ptr<PFSCEnergyCalibration>  
00092     thePFSCEnergyCalibration ( new PFSCEnergyCalibration(calibPFSCEle_Fbrem_barrel,calibPFSCEle_Fbrem_endcap,
00093                                                          calibPFSCEle_barrel,calibPFSCEle_endcap )); 
00094                                
00095   bool useEGammaSupercluster = iConfig.getParameter<bool>("useEGammaSupercluster");
00096   double sumEtEcalIsoForEgammaSC_barrel = iConfig.getParameter<double>("sumEtEcalIsoForEgammaSC_barrel");
00097   double sumEtEcalIsoForEgammaSC_endcap = iConfig.getParameter<double>("sumEtEcalIsoForEgammaSC_endcap");
00098   double coneEcalIsoForEgammaSC = iConfig.getParameter<double>("coneEcalIsoForEgammaSC");
00099   double sumPtTrackIsoForEgammaSC_barrel = iConfig.getParameter<double>("sumPtTrackIsoForEgammaSC_barrel");
00100   double sumPtTrackIsoForEgammaSC_endcap = iConfig.getParameter<double>("sumPtTrackIsoForEgammaSC_endcap");
00101   double coneTrackIsoForEgammaSC = iConfig.getParameter<double>("coneTrackIsoForEgammaSC");
00102   unsigned int nTrackIsoForEgammaSC  = iConfig.getParameter<unsigned int>("nTrackIsoForEgammaSC");
00103 
00104 
00105   // register products
00106   produces<reco::PFCandidateCollection>();
00107   produces<reco::PFCandidateCollection>("CleanedHF");
00108   produces<reco::PFCandidateCollection>("CleanedCosmicsMuons");
00109   produces<reco::PFCandidateCollection>("CleanedTrackerAndGlobalMuons");
00110   produces<reco::PFCandidateCollection>("CleanedFakeMuons");
00111   produces<reco::PFCandidateCollection>("CleanedPunchThroughMuons");
00112   produces<reco::PFCandidateCollection>("CleanedPunchThroughNeutralHadrons");
00113   produces<reco::PFCandidateCollection>("AddedMuonsAndHadrons");
00114 
00115 
00116   if (usePFElectrons_) {
00117     produces<reco::PFCandidateCollection>(electronOutputCol_);
00118     produces<reco::PFCandidateElectronExtraCollection>(electronExtraOutputCol_);
00119   }
00120 
00121   if (usePFPhotons_) {
00122     produces<reco::PFCandidatePhotonExtraCollection>(photonExtraOutputCol_);
00123   }
00124 
00125 
00126   double nSigmaECAL 
00127     = iConfig.getParameter<double>("pf_nsigma_ECAL");
00128   double nSigmaHCAL 
00129     = iConfig.getParameter<double>("pf_nsigma_HCAL");
00130   
00131   //PFElectrons Configuration
00132   double mvaEleCut
00133     = iConfig.getParameter<double>("pf_electron_mvaCut");
00134 
00135   
00136   string mvaWeightFileEleID
00137     = iConfig.getParameter<string>("pf_electronID_mvaWeightFile");
00138 
00139   bool applyCrackCorrectionsForElectrons
00140     = iConfig.getParameter<bool>("pf_electronID_crackCorrection");
00141   
00142   string path_mvaWeightFileEleID;
00143   if(usePFElectrons_)
00144     {
00145       path_mvaWeightFileEleID = edm::FileInPath ( mvaWeightFileEleID.c_str() ).fullPath();
00146      }
00147 
00148   //PFPhoton Configuration
00149 
00150   string path_mvaWeightFileConvID;
00151   string mvaWeightFileConvID;
00152   string path_mvaWeightFileGCorr;
00153   string path_mvaWeightFileLCorr;
00154   string path_X0_Map;
00155   string path_mvaWeightFileRes;
00156   double mvaConvCut=-99.;
00157   double sumPtTrackIsoForPhoton = 99.;
00158   double sumPtTrackIsoSlopeForPhoton = 99.;
00159 
00160   if(usePFPhotons_ )
00161     {
00162       mvaWeightFileConvID =iConfig.getParameter<string>("pf_convID_mvaWeightFile");
00163       mvaConvCut = iConfig.getParameter<double>("pf_conv_mvaCut");
00164       path_mvaWeightFileConvID = edm::FileInPath ( mvaWeightFileConvID.c_str() ).fullPath();  
00165       sumPtTrackIsoForPhoton = iConfig.getParameter<double>("sumPtTrackIsoForPhoton");
00166       sumPtTrackIsoSlopeForPhoton = iConfig.getParameter<double>("sumPtTrackIsoSlopeForPhoton");
00167 
00168       string X0_Map=iConfig.getParameter<string>("X0_Map");
00169       path_X0_Map = edm::FileInPath( X0_Map.c_str() ).fullPath();
00170 
00171       if(!useRegressionFromDB_) {
00172         string mvaWeightFileLCorr=iConfig.getParameter<string>("pf_locC_mvaWeightFile");
00173         path_mvaWeightFileLCorr = edm::FileInPath( mvaWeightFileLCorr.c_str() ).fullPath();
00174         string mvaWeightFileGCorr=iConfig.getParameter<string>("pf_GlobC_mvaWeightFile");
00175         path_mvaWeightFileGCorr = edm::FileInPath( mvaWeightFileGCorr.c_str() ).fullPath();
00176         string mvaWeightFileRes=iConfig.getParameter<string>("pf_Res_mvaWeightFile");
00177         path_mvaWeightFileRes=edm::FileInPath(mvaWeightFileRes.c_str()).fullPath();
00178 
00179         TFile *fgbr = new TFile(path_mvaWeightFileGCorr.c_str(),"READ");
00180         ReaderGC_  =(const GBRForest*)fgbr->Get("GBRForest");
00181         TFile *fgbr2 = new TFile(path_mvaWeightFileLCorr.c_str(),"READ");
00182         ReaderLC_  = (const GBRForest*)fgbr2->Get("GBRForest");
00183         TFile *fgbr3 = new TFile(path_mvaWeightFileRes.c_str(),"READ");
00184         ReaderRes_  = (const GBRForest*)fgbr3->Get("GBRForest");
00185         LogDebug("PFProducer")<<"Will set regressions from binary files " <<endl;
00186       }
00187 
00188     }
00189   
00190 
00191   //Secondary tracks and displaced vertices parameters
00192 
00193   bool rejectTracks_Bad
00194     = iConfig.getParameter<bool>("rejectTracks_Bad");
00195 
00196   bool rejectTracks_Step45
00197     = iConfig.getParameter<bool>("rejectTracks_Step45");
00198 
00199   bool usePFNuclearInteractions
00200     = iConfig.getParameter<bool>("usePFNuclearInteractions");
00201 
00202   bool usePFConversions
00203     = iConfig.getParameter<bool>("usePFConversions");  
00204 
00205   bool usePFDecays
00206     = iConfig.getParameter<bool>("usePFDecays");
00207 
00208   double dptRel_DispVtx
00209     = iConfig.getParameter<double>("dptRel_DispVtx");
00210 
00211   edm::ParameterSet iCfgCandConnector 
00212     = iConfig.getParameter<edm::ParameterSet>("iCfgCandConnector");
00213 
00214 
00215   // fToRead =  iConfig.getUntrackedParameter<vector<string> >("toRead");
00216 
00217   useCalibrationsFromDB_
00218     = iConfig.getParameter<bool>("useCalibrationsFromDB");    
00219 
00220   boost::shared_ptr<PFEnergyCalibration> 
00221     calibration( new PFEnergyCalibration() ); 
00222 
00223   int algoType 
00224     = iConfig.getParameter<unsigned>("algoType");
00225   
00226   switch(algoType) {
00227   case 0:
00228     pfAlgo_.reset( new PFAlgo);
00229     break;
00230    default:
00231     assert(0);
00232   }
00233   
00234   pfAlgo_->setParameters( nSigmaECAL, 
00235                           nSigmaHCAL,
00236                           calibration,
00237                           thepfEnergyCalibrationHF);
00238 
00239   //PFElectrons: call the method setpfeleparameters
00240   pfAlgo_->setPFEleParameters(mvaEleCut,
00241                               path_mvaWeightFileEleID,
00242                               usePFElectrons_,
00243                               thePFSCEnergyCalibration,
00244                               calibration,
00245                               sumEtEcalIsoForEgammaSC_barrel,
00246                               sumEtEcalIsoForEgammaSC_endcap,
00247                               coneEcalIsoForEgammaSC,
00248                               sumPtTrackIsoForEgammaSC_barrel,
00249                               sumPtTrackIsoForEgammaSC_endcap,
00250                               nTrackIsoForEgammaSC,
00251                               coneTrackIsoForEgammaSC,
00252                               applyCrackCorrectionsForElectrons,
00253                               usePFSCEleCalib,
00254                               useEGammaElectrons_,
00255                               useEGammaSupercluster);
00256   
00257   //  pfAlgo_->setPFConversionParameters(usePFConversions);
00258 
00259   // PFPhotons: 
00260   pfAlgo_->setPFPhotonParameters(usePFPhotons_,
00261                                  path_mvaWeightFileConvID,
00262                                  mvaConvCut,
00263                                  usePhotonReg_,
00264                                  path_X0_Map,
00265                                  calibration,
00266                                  sumPtTrackIsoForPhoton,
00267                                  sumPtTrackIsoSlopeForPhoton);
00268 
00269 
00270   //Secondary tracks and displaced vertices parameters
00271   
00272   pfAlgo_->setDisplacedVerticesParameters(rejectTracks_Bad,
00273                                           rejectTracks_Step45,
00274                                           usePFNuclearInteractions,
00275                                           usePFConversions,
00276                                           usePFDecays,
00277                                           dptRel_DispVtx);
00278   
00279   if (usePFNuclearInteractions)
00280     pfAlgo_->setCandConnectorParameters( iCfgCandConnector );
00281 
00282   // Muon parameters
00283   std::vector<double> muonHCAL
00284     = iConfig.getParameter<std::vector<double> >("muon_HCAL");  
00285   std::vector<double> muonECAL
00286     = iConfig.getParameter<std::vector<double> >("muon_ECAL");  
00287   std::vector<double> muonHO
00288     = iConfig.getParameter<std::vector<double> >("muon_HO");  
00289 
00290   assert ( muonHCAL.size() == 2 && muonECAL.size() == 2 && muonHO.size() == 2);
00291   
00292   // Fake track parameters
00293   double nSigmaTRACK
00294     = iConfig.getParameter<double>("nsigma_TRACK");  
00295   
00296   double ptError
00297     = iConfig.getParameter<double>("pt_Error");  
00298   
00299   std::vector<double> factors45
00300     = iConfig.getParameter<std::vector<double> >("factors_45");  
00301   assert ( factors45.size() == 2 );
00302   
00303   bool usePFMuonMomAssign
00304     = iConfig.getParameter<bool>("usePFMuonMomAssign");
00305 
00306   bool useBestMuonTrack
00307     = iConfig.getParameter<bool>("useBestMuonTrack");
00308 
00309   // Set muon and fake track parameters
00310   pfAlgo_->setPFMuonAndFakeParameters(muonHCAL,
00311                                       muonECAL,
00312                                       muonHO,
00313                                       nSigmaTRACK,
00314                                       ptError,
00315                                       factors45,
00316                                       usePFMuonMomAssign,
00317                                       useBestMuonTrack);
00318   
00319   //Post cleaning of the HF
00320   bool postHFCleaning
00321     = iConfig.getParameter<bool>("postHFCleaning");
00322 
00323   double minHFCleaningPt 
00324     = iConfig.getParameter<double>("minHFCleaningPt");
00325   double minSignificance
00326     = iConfig.getParameter<double>("minSignificance");
00327   double maxSignificance
00328     = iConfig.getParameter<double>("maxSignificance");
00329   double minSignificanceReduction
00330     = iConfig.getParameter<double>("minSignificanceReduction");
00331   double maxDeltaPhiPt
00332     = iConfig.getParameter<double>("maxDeltaPhiPt");
00333   double minDeltaMet
00334     = iConfig.getParameter<double>("minDeltaMet");
00335 
00336   // Set post HF cleaning muon parameters
00337   pfAlgo_->setPostHFCleaningParameters(postHFCleaning,
00338                                        minHFCleaningPt,
00339                                        minSignificance,
00340                                        maxSignificance,
00341                                        minSignificanceReduction,
00342                                        maxDeltaPhiPt,
00343                                        minDeltaMet);
00344 
00345   // Input tags for HF cleaned rechits
00346   inputTagCleanedHF_ 
00347     = iConfig.getParameter< std::vector<edm::InputTag> >("cleanedHF");
00348 
00349   //MIKE: Vertex Parameters
00350   vertices_ = iConfig.getParameter<edm::InputTag>("vertexCollection");
00351   useVerticesForNeutral_ = iConfig.getParameter<bool>("useVerticesForNeutral");
00352 
00353   // Use HO clusters and links in the PF reconstruction
00354   useHO_= iConfig.getParameter<bool>("useHO");
00355   pfAlgo_->setHOTag(useHO_);
00356 
00357   verbose_ = 
00358     iConfig.getUntrackedParameter<bool>("verbose",false);
00359 
00360   bool debug_ = 
00361     iConfig.getUntrackedParameter<bool>("debug",false);
00362 
00363   pfAlgo_->setDebug( debug_ );
00364 
00365 }
00366 
00367 
00368 
00369 PFProducer::~PFProducer() {}
00370 
00371 
00372 void 
00373 PFProducer::beginJob() {}
00374 
00375 void 
00376 PFProducer::beginRun(edm::Run & run, 
00377                      const edm::EventSetup & es) 
00378 {
00379 
00380 
00381   /*
00382   static map<string, PerformanceResult::ResultType> functType;
00383 
00384   functType["PFfa_BARREL"] = PerformanceResult::PFfa_BARREL;
00385   functType["PFfa_ENDCAP"] = PerformanceResult::PFfa_ENDCAP;
00386   functType["PFfb_BARREL"] = PerformanceResult::PFfb_BARREL;
00387   functType["PFfb_ENDCAP"] = PerformanceResult::PFfb_ENDCAP;
00388   functType["PFfc_BARREL"] = PerformanceResult::PFfc_BARREL;
00389   functType["PFfc_ENDCAP"] = PerformanceResult::PFfc_ENDCAP;
00390   functType["PFfaEta_BARREL"] = PerformanceResult::PFfaEta_BARREL;
00391   functType["PFfaEta_ENDCAP"] = PerformanceResult::PFfaEta_ENDCAP;
00392   functType["PFfbEta_BARREL"] = PerformanceResult::PFfbEta_BARREL;
00393   functType["PFfbEta_ENDCAP"] = PerformanceResult::PFfbEta_ENDCAP;
00394   */
00395 
00396   if ( useCalibrationsFromDB_ ) { 
00397   // Read the PFCalibration functions from the global tags.
00398     edm::ESHandle<PerformancePayload> perfH;
00399     es.get<PFCalibrationRcd>().get(perfH);
00400     
00401     const PerformancePayloadFromTFormula *pfCalibrations = static_cast< const PerformancePayloadFromTFormula *>(perfH.product());
00402     
00403     pfAlgo_->thePFEnergyCalibration()->setCalibrationFunctions(pfCalibrations);
00404   }
00405   
00406   /*
00407   for(vector<string>::const_iterator name = fToRead.begin(); name != fToRead.end(); ++name) {    
00408     
00409     cout << "Function: " << *name << endl;
00410     PerformanceResult::ResultType fType = functType[*name];
00411     pfCalibrations->printFormula(fType);
00412     
00413     // evaluate it @ 10 GeV
00414     float energy = 10.;
00415     
00416     BinningPointByMap point;
00417     point.insert(BinningVariables::JetEt, energy);
00418     
00419     if(pfCalibrations->isInPayload(fType, point)) {
00420       float value = pfCalibrations->getResult(fType, point);
00421       cout << "   Energy before:: " << energy << " after: " << value << endl;
00422     } else cout <<  "outside limits!" << endl;
00423     
00424   }
00425   */
00426   
00427   if(useRegressionFromDB_) {
00428     edm::ESHandle<GBRForest> readerPFLCEB;
00429     edm::ESHandle<GBRForest> readerPFLCEE;    
00430     edm::ESHandle<GBRForest> readerPFGCEB;
00431     edm::ESHandle<GBRForest> readerPFGCEEHR9;
00432     edm::ESHandle<GBRForest> readerPFGCEELR9;
00433     edm::ESHandle<GBRForest> readerPFRes;
00434     es.get<GBRWrapperRcd>().get("PFLCorrectionBar",readerPFLCEB);
00435     ReaderLCEB_=readerPFLCEB.product();
00436     es.get<GBRWrapperRcd>().get("PFLCorrectionEnd",readerPFLCEE);
00437     ReaderLCEE_=readerPFLCEE.product();
00438     es.get<GBRWrapperRcd>().get("PFGCorrectionBar",readerPFGCEB);       
00439     ReaderGCBarrel_=readerPFGCEB.product();
00440     es.get<GBRWrapperRcd>().get("PFGCorrectionEndHighR9",readerPFGCEEHR9);
00441     ReaderGCEndCapHighr9_=readerPFGCEEHR9.product();
00442     es.get<GBRWrapperRcd>().get("PFGCorrectionEndLowR9",readerPFGCEELR9);
00443     ReaderGCEndCapLowr9_=readerPFGCEELR9.product();
00444     es.get<GBRWrapperRcd>().get("PFEcalResolution",readerPFRes);
00445     ReaderEcalRes_=readerPFRes.product();
00446     
00447     /*
00448     LogDebug("PFProducer")<<"setting regressions from DB "<<endl;
00449     */
00450   } 
00451 
00452     if(usePFPhotons_){
00453       //pfAlgo_->setPFPhotonRegWeights(ReaderLC_, ReaderGC_, ReaderRes_);
00454       pfAlgo_->setPFPhotonRegWeights(ReaderLCEB_,ReaderLCEE_,ReaderGCBarrel_,ReaderGCEndCapHighr9_, ReaderGCEndCapLowr9_, ReaderEcalRes_ );
00455     }
00456 }
00457 
00458 
00459 void 
00460 PFProducer::produce(Event& iEvent, 
00461                     const EventSetup& iSetup) {
00462   
00463   LogDebug("PFProducer")<<"START event: "
00464                         <<iEvent.id().event()
00465                         <<" in run "<<iEvent.id().run()<<endl;
00466   
00467 
00468   // Get The vertices from the event
00469   // and assign dynamic vertex parameters
00470   edm::Handle<reco::VertexCollection> vertices;
00471   bool gotVertices = iEvent.getByLabel(vertices_,vertices);
00472   if(!gotVertices) {
00473     ostringstream err;
00474     err<<"Cannot find vertices for this event.Continuing Without them ";
00475     LogError("PFProducer")<<err.str()<<endl;
00476   }
00477 
00478   //Assign the PFAlgo Parameters
00479   pfAlgo_->setPFVertexParameters(useVerticesForNeutral_,*vertices);
00480 
00481   // get the collection of blocks 
00482 
00483   Handle< reco::PFBlockCollection > blocks;
00484 
00485   LogDebug("PFProducer")<<"getting blocks"<<endl;
00486   bool found = iEvent.getByLabel( inputTagBlocks_, blocks );  
00487 
00488   if(!found ) {
00489 
00490     ostringstream err;
00491     err<<"cannot find blocks: "<<inputTagBlocks_;
00492     LogError("PFProducer")<<err.str()<<endl;
00493     
00494     throw cms::Exception( "MissingProduct", err.str());
00495   }
00496 
00497   // get the collection of muons 
00498 
00499   Handle< reco::MuonCollection > muons;
00500 
00501   if ( postMuonCleaning_ ) {
00502 
00503     LogDebug("PFProducer")<<"getting muons"<<endl;
00504     found = iEvent.getByLabel( inputTagMuons_, muons );  
00505 
00506     if(!found) {
00507       ostringstream err;
00508       err<<"cannot find muons: "<<inputTagMuons_;
00509       LogError("PFProducer")<<err.str()<<endl;
00510     
00511       throw cms::Exception( "MissingProduct", err.str());
00512     }
00513 
00514   }
00515 
00516   if (useEGammaElectrons_) {
00517     Handle < reco::GsfElectronCollection > egelectrons;
00518     
00519     LogDebug("PFProducer")<<" Reading e/gamma electrons activated "<<endl;
00520     found = iEvent.getByLabel( inputTagEgammaElectrons_, egelectrons );  
00521     
00522     if(!found) {
00523       ostringstream err;
00524       err<<"cannot find electrons: "<<inputTagEgammaElectrons_;
00525       LogError("PFProducer")<<err.str()<<endl;
00526     
00527       throw cms::Exception( "MissingProduct", err.str());
00528     }
00529     
00530     pfAlgo_->setEGElectronCollection(*egelectrons);
00531   }
00532 
00533   
00534   LogDebug("PFProducer")<<"particle flow is starting"<<endl;
00535 
00536   assert( blocks.isValid() );
00537 
00538   pfAlgo_->reconstructParticles( blocks );
00539 
00540   if(verbose_) {
00541     ostringstream  str;
00542     str<<(*pfAlgo_)<<endl;
00543     //    cout << (*pfAlgo_) << endl;
00544     LogInfo("PFProducer") <<str.str()<<endl;
00545   }  
00546 
00547 
00548   if ( postMuonCleaning_ )
00549     pfAlgo_->postMuonCleaning( muons, *vertices );
00550 
00551   // Florian 5/01/2011
00552   // Save the PFElectron Extra Collection First as to be able to create valid References  
00553   if(usePFElectrons_)   {  
00554     auto_ptr< reco::PFCandidateElectronExtraCollection >
00555       pOutputElectronCandidateExtraCollection( pfAlgo_->transferElectronExtra() ); 
00556 
00557     const edm::OrphanHandle<reco::PFCandidateElectronExtraCollection > electronExtraProd=
00558       iEvent.put(pOutputElectronCandidateExtraCollection,electronExtraOutputCol_);      
00559     pfAlgo_->setElectronExtraRef(electronExtraProd);
00560   }
00561 
00562   // Daniele 18/05/2011
00563   // Save the PFPhoton Extra Collection First as to be able to create valid References  
00564   if(usePFPhotons_)   {  
00565     auto_ptr< reco::PFCandidatePhotonExtraCollection >
00566       pOutputPhotonCandidateExtraCollection( pfAlgo_->transferPhotonExtra() ); 
00567 
00568     const edm::OrphanHandle<reco::PFCandidatePhotonExtraCollection > photonExtraProd=
00569       iEvent.put(pOutputPhotonCandidateExtraCollection,photonExtraOutputCol_);      
00570     pfAlgo_->setPhotonExtraRef(photonExtraProd);
00571   }
00572 
00573 
00574   // Save cosmic cleaned muon candidates
00575   auto_ptr< reco::PFCandidateCollection > 
00576     pCosmicsMuonCleanedCandidateCollection( pfAlgo_->transferCosmicsMuonCleanedCandidates() ); 
00577   // Save tracker/global cleaned muon candidates
00578   auto_ptr< reco::PFCandidateCollection > 
00579     pTrackerAndGlobalCleanedMuonCandidateCollection( pfAlgo_->transferCleanedTrackerAndGlobalMuonCandidates() ); 
00580   // Save fake cleaned muon candidates
00581   auto_ptr< reco::PFCandidateCollection > 
00582     pFakeCleanedMuonCandidateCollection( pfAlgo_->transferFakeMuonCleanedCandidates() ); 
00583   // Save punch-through cleaned muon candidates
00584   auto_ptr< reco::PFCandidateCollection > 
00585     pPunchThroughMuonCleanedCandidateCollection( pfAlgo_->transferPunchThroughMuonCleanedCandidates() ); 
00586   // Save punch-through cleaned neutral hadron candidates
00587   auto_ptr< reco::PFCandidateCollection > 
00588     pPunchThroughHadronCleanedCandidateCollection( pfAlgo_->transferPunchThroughHadronCleanedCandidates() ); 
00589   // Save added muon candidates
00590   auto_ptr< reco::PFCandidateCollection > 
00591     pAddedMuonCandidateCollection( pfAlgo_->transferAddedMuonCandidates() ); 
00592 
00593   // Check HF overcleaning
00594   reco::PFRecHitCollection hfCopy;
00595   for ( unsigned ihf=0; ihf<inputTagCleanedHF_.size(); ++ihf ) {
00596     Handle< reco::PFRecHitCollection > hfCleaned;
00597     bool foundHF = iEvent.getByLabel( inputTagCleanedHF_[ihf], hfCleaned );  
00598     if (!foundHF) continue;
00599     for ( unsigned jhf=0; jhf<(*hfCleaned).size(); ++jhf ) { 
00600       hfCopy.push_back( (*hfCleaned)[jhf] );
00601     }
00602   }
00603   pfAlgo_->checkCleaning( hfCopy );
00604 
00605   // Save recovered HF candidates
00606   auto_ptr< reco::PFCandidateCollection > 
00607     pCleanedCandidateCollection( pfAlgo_->transferCleanedCandidates() ); 
00608 
00609   
00610   // Save the final PFCandidate collection
00611   auto_ptr< reco::PFCandidateCollection > 
00612     pOutputCandidateCollection( pfAlgo_->transferCandidates() ); 
00613   
00614 
00615   
00616   LogDebug("PFProducer")<<"particle flow: putting products in the event"<<endl;
00617   if ( verbose_ ) std::cout <<"particle flow: putting products in the event. Here the full list"<<endl;
00618   int nC=0;
00619   for( reco::PFCandidateCollection::const_iterator  itCand =  (*pOutputCandidateCollection).begin(); itCand !=  (*pOutputCandidateCollection).end(); itCand++) {
00620     nC++;
00621       if (verbose_ ) std::cout << nC << ")" << (*itCand).particleId() << std::endl;
00622 
00623   }
00624 
00625   // Write in the event
00626   iEvent.put(pOutputCandidateCollection);
00627   iEvent.put(pCleanedCandidateCollection,"CleanedHF");
00628 
00629   if ( postMuonCleaning_ ) { 
00630     iEvent.put(pCosmicsMuonCleanedCandidateCollection,"CleanedCosmicsMuons");
00631     iEvent.put(pTrackerAndGlobalCleanedMuonCandidateCollection,"CleanedTrackerAndGlobalMuons");
00632     iEvent.put(pFakeCleanedMuonCandidateCollection,"CleanedFakeMuons");
00633     iEvent.put(pPunchThroughMuonCleanedCandidateCollection,"CleanedPunchThroughMuons");
00634     iEvent.put(pPunchThroughHadronCleanedCandidateCollection,"CleanedPunchThroughNeutralHadrons");
00635     iEvent.put(pAddedMuonCandidateCollection,"AddedMuonsAndHadrons");
00636   }
00637 
00638   if(usePFElectrons_)
00639     {
00640       auto_ptr< reco::PFCandidateCollection >  
00641         pOutputElectronCandidateCollection( pfAlgo_->transferElectronCandidates() ); 
00642       iEvent.put(pOutputElectronCandidateCollection,electronOutputCol_);
00643 
00644     }
00645 }
00646