CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/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   
00283 
00284   // Set muon and fake track parameters
00285   pfAlgo_->setPFMuonAndFakeParameters(iConfig);
00286   
00287   //Post cleaning of the HF
00288   bool postHFCleaning
00289     = iConfig.getParameter<bool>("postHFCleaning");
00290   double minHFCleaningPt 
00291     = iConfig.getParameter<double>("minHFCleaningPt");
00292   double minSignificance
00293     = iConfig.getParameter<double>("minSignificance");
00294   double maxSignificance
00295     = iConfig.getParameter<double>("maxSignificance");
00296   double minSignificanceReduction
00297     = iConfig.getParameter<double>("minSignificanceReduction");
00298   double maxDeltaPhiPt
00299     = iConfig.getParameter<double>("maxDeltaPhiPt");
00300   double minDeltaMet
00301     = iConfig.getParameter<double>("minDeltaMet");
00302 
00303   // Set post HF cleaning muon parameters
00304   pfAlgo_->setPostHFCleaningParameters(postHFCleaning,
00305                                        minHFCleaningPt,
00306                                        minSignificance,
00307                                        maxSignificance,
00308                                        minSignificanceReduction,
00309                                        maxDeltaPhiPt,
00310                                        minDeltaMet);
00311 
00312   // Input tags for HF cleaned rechits
00313   inputTagCleanedHF_ 
00314     = iConfig.getParameter< std::vector<edm::InputTag> >("cleanedHF");
00315 
00316   //MIKE: Vertex Parameters
00317   vertices_ = iConfig.getParameter<edm::InputTag>("vertexCollection");
00318   useVerticesForNeutral_ = iConfig.getParameter<bool>("useVerticesForNeutral");
00319 
00320   // Use HO clusters and links in the PF reconstruction
00321   useHO_= iConfig.getParameter<bool>("useHO");
00322   pfAlgo_->setHOTag(useHO_);
00323 
00324   verbose_ = 
00325     iConfig.getUntrackedParameter<bool>("verbose",false);
00326 
00327   bool debug_ = 
00328     iConfig.getUntrackedParameter<bool>("debug",false);
00329 
00330   pfAlgo_->setDebug( debug_ );
00331 
00332 }
00333 
00334 
00335 
00336 PFProducer::~PFProducer() {}
00337 
00338 void 
00339 PFProducer::beginRun(const edm::Run & run, 
00340                      const edm::EventSetup & es) 
00341 {
00342 
00343 
00344   /*
00345   static map<string, PerformanceResult::ResultType> functType;
00346 
00347   functType["PFfa_BARREL"] = PerformanceResult::PFfa_BARREL;
00348   functType["PFfa_ENDCAP"] = PerformanceResult::PFfa_ENDCAP;
00349   functType["PFfb_BARREL"] = PerformanceResult::PFfb_BARREL;
00350   functType["PFfb_ENDCAP"] = PerformanceResult::PFfb_ENDCAP;
00351   functType["PFfc_BARREL"] = PerformanceResult::PFfc_BARREL;
00352   functType["PFfc_ENDCAP"] = PerformanceResult::PFfc_ENDCAP;
00353   functType["PFfaEta_BARREL"] = PerformanceResult::PFfaEta_BARREL;
00354   functType["PFfaEta_ENDCAP"] = PerformanceResult::PFfaEta_ENDCAP;
00355   functType["PFfbEta_BARREL"] = PerformanceResult::PFfbEta_BARREL;
00356   functType["PFfbEta_ENDCAP"] = PerformanceResult::PFfbEta_ENDCAP;
00357   */
00358 
00359   if ( useCalibrationsFromDB_ ) { 
00360   // Read the PFCalibration functions from the global tags.
00361     edm::ESHandle<PerformancePayload> perfH;
00362     es.get<PFCalibrationRcd>().get(perfH);
00363     
00364     const PerformancePayloadFromTFormula *pfCalibrations = static_cast< const PerformancePayloadFromTFormula *>(perfH.product());
00365     
00366     pfAlgo_->thePFEnergyCalibration()->setCalibrationFunctions(pfCalibrations);
00367   }
00368   
00369   /*
00370   for(vector<string>::const_iterator name = fToRead.begin(); name != fToRead.end(); ++name) {    
00371     
00372     cout << "Function: " << *name << endl;
00373     PerformanceResult::ResultType fType = functType[*name];
00374     pfCalibrations->printFormula(fType);
00375     
00376     // evaluate it @ 10 GeV
00377     float energy = 10.;
00378     
00379     BinningPointByMap point;
00380     point.insert(BinningVariables::JetEt, energy);
00381     
00382     if(pfCalibrations->isInPayload(fType, point)) {
00383       float value = pfCalibrations->getResult(fType, point);
00384       cout << "   Energy before:: " << energy << " after: " << value << endl;
00385     } else cout <<  "outside limits!" << endl;
00386     
00387   }
00388   */
00389   
00390   if(useRegressionFromDB_) {
00391     edm::ESHandle<GBRForest> readerPFLCEB;
00392     edm::ESHandle<GBRForest> readerPFLCEE;    
00393     edm::ESHandle<GBRForest> readerPFGCEB;
00394     edm::ESHandle<GBRForest> readerPFGCEEHR9;
00395     edm::ESHandle<GBRForest> readerPFGCEELR9;
00396     edm::ESHandle<GBRForest> readerPFRes;
00397     es.get<GBRWrapperRcd>().get("PFLCorrectionBar",readerPFLCEB);
00398     ReaderLCEB_=readerPFLCEB.product();
00399     es.get<GBRWrapperRcd>().get("PFLCorrectionEnd",readerPFLCEE);
00400     ReaderLCEE_=readerPFLCEE.product();
00401     es.get<GBRWrapperRcd>().get("PFGCorrectionBar",readerPFGCEB);       
00402     ReaderGCBarrel_=readerPFGCEB.product();
00403     es.get<GBRWrapperRcd>().get("PFGCorrectionEndHighR9",readerPFGCEEHR9);
00404     ReaderGCEndCapHighr9_=readerPFGCEEHR9.product();
00405     es.get<GBRWrapperRcd>().get("PFGCorrectionEndLowR9",readerPFGCEELR9);
00406     ReaderGCEndCapLowr9_=readerPFGCEELR9.product();
00407     es.get<GBRWrapperRcd>().get("PFEcalResolution",readerPFRes);
00408     ReaderEcalRes_=readerPFRes.product();
00409     
00410     /*
00411     LogDebug("PFProducer")<<"setting regressions from DB "<<endl;
00412     */
00413   } 
00414 
00415     if(usePFPhotons_){
00416       //pfAlgo_->setPFPhotonRegWeights(ReaderLC_, ReaderGC_, ReaderRes_);
00417       pfAlgo_->setPFPhotonRegWeights(ReaderLCEB_,ReaderLCEE_,ReaderGCBarrel_,ReaderGCEndCapHighr9_, ReaderGCEndCapLowr9_, ReaderEcalRes_ );
00418     }
00419 }
00420 
00421 
00422 void 
00423 PFProducer::produce(Event& iEvent, 
00424                     const EventSetup& iSetup) {
00425   
00426   LogDebug("PFProducer")<<"START event: "
00427                         <<iEvent.id().event()
00428                         <<" in run "<<iEvent.id().run()<<endl;
00429   
00430 
00431   // Get The vertices from the event
00432   // and assign dynamic vertex parameters
00433   edm::Handle<reco::VertexCollection> vertices;
00434   bool gotVertices = iEvent.getByLabel(vertices_,vertices);
00435   if(!gotVertices) {
00436     ostringstream err;
00437     err<<"Cannot find vertices for this event.Continuing Without them ";
00438     LogError("PFProducer")<<err.str()<<endl;
00439   }
00440 
00441   //Assign the PFAlgo Parameters
00442   pfAlgo_->setPFVertexParameters(useVerticesForNeutral_,vertices.product());
00443 
00444   // get the collection of blocks 
00445 
00446   Handle< reco::PFBlockCollection > blocks;
00447 
00448   LogDebug("PFProducer")<<"getting blocks"<<endl;
00449   bool found = iEvent.getByLabel( inputTagBlocks_, blocks );  
00450 
00451   if(!found ) {
00452 
00453     ostringstream err;
00454     err<<"cannot find blocks: "<<inputTagBlocks_;
00455     LogError("PFProducer")<<err.str()<<endl;
00456     
00457     throw cms::Exception( "MissingProduct", err.str());
00458   }
00459 
00460   // get the collection of muons 
00461 
00462   Handle< reco::MuonCollection > muons;
00463 
00464   if ( postMuonCleaning_ ) {
00465 
00466     LogDebug("PFProducer")<<"getting muons"<<endl;
00467     found = iEvent.getByLabel( inputTagMuons_, muons );  
00468     pfAlgo_->setMuonHandle(muons);
00469     if(!found) {
00470       ostringstream err;
00471       err<<"cannot find muons: "<<inputTagMuons_;
00472       LogError("PFProducer")<<err.str()<<endl;
00473     
00474       throw cms::Exception( "MissingProduct", err.str());
00475 
00476     }
00477 
00478   }
00479 
00480   if (useEGammaElectrons_) {
00481     Handle < reco::GsfElectronCollection > egelectrons;
00482     
00483     LogDebug("PFProducer")<<" Reading e/gamma electrons activated "<<endl;
00484     found = iEvent.getByLabel( inputTagEgammaElectrons_, egelectrons );  
00485     
00486     if(!found) {
00487       ostringstream err;
00488       err<<"cannot find electrons: "<<inputTagEgammaElectrons_;
00489       LogError("PFProducer")<<err.str()<<endl;
00490     
00491       throw cms::Exception( "MissingProduct", err.str());
00492     }
00493     
00494     pfAlgo_->setEGElectronCollection(*egelectrons);
00495   }
00496 
00497   
00498   LogDebug("PFProducer")<<"particle flow is starting"<<endl;
00499 
00500   assert( blocks.isValid() );
00501 
00502   pfAlgo_->reconstructParticles( blocks );
00503   
00504   if(verbose_) {
00505     ostringstream  str;
00506     str<<(*pfAlgo_)<<endl;
00507     //    cout << (*pfAlgo_) << endl;
00508     LogInfo("PFProducer") <<str.str()<<endl;
00509   }  
00510 
00511 
00512   // Florian 5/01/2011
00513   // Save the PFElectron Extra Collection First as to be able to create valid References  
00514   if(usePFElectrons_)   {  
00515     auto_ptr< reco::PFCandidateElectronExtraCollection >
00516       pOutputElectronCandidateExtraCollection( pfAlgo_->transferElectronExtra() ); 
00517 
00518     const edm::OrphanHandle<reco::PFCandidateElectronExtraCollection > electronExtraProd=
00519       iEvent.put(pOutputElectronCandidateExtraCollection,electronExtraOutputCol_);      
00520     pfAlgo_->setElectronExtraRef(electronExtraProd);
00521   }
00522 
00523   // Daniele 18/05/2011
00524   // Save the PFPhoton Extra Collection First as to be able to create valid References  
00525   if(usePFPhotons_)   {  
00526     auto_ptr< reco::PFCandidatePhotonExtraCollection >
00527       pOutputPhotonCandidateExtraCollection( pfAlgo_->transferPhotonExtra() ); 
00528 
00529     const edm::OrphanHandle<reco::PFCandidatePhotonExtraCollection > photonExtraProd=
00530       iEvent.put(pOutputPhotonCandidateExtraCollection,photonExtraOutputCol_);      
00531     pfAlgo_->setPhotonExtraRef(photonExtraProd);
00532   }
00533 
00534 
00535    // Save cosmic cleaned muon candidates
00536     auto_ptr< reco::PFCandidateCollection > 
00537       pCosmicsMuonCleanedCandidateCollection( pfAlgo_->getPFMuonAlgo()->transferCleanedCosmicCandidates() ); 
00538     // Save tracker/global cleaned muon candidates
00539     auto_ptr< reco::PFCandidateCollection > 
00540       pTrackerAndGlobalCleanedMuonCandidateCollection( pfAlgo_->getPFMuonAlgo()->transferCleanedTrackerAndGlobalCandidates() ); 
00541     // Save fake cleaned muon candidates
00542     auto_ptr< reco::PFCandidateCollection > 
00543       pFakeCleanedMuonCandidateCollection( pfAlgo_->getPFMuonAlgo()->transferCleanedFakeCandidates() ); 
00544     // Save punch-through cleaned muon candidates
00545     auto_ptr< reco::PFCandidateCollection > 
00546       pPunchThroughMuonCleanedCandidateCollection( pfAlgo_->getPFMuonAlgo()->transferPunchThroughCleanedMuonCandidates() ); 
00547     // Save punch-through cleaned neutral hadron candidates
00548     auto_ptr< reco::PFCandidateCollection > 
00549       pPunchThroughHadronCleanedCandidateCollection( pfAlgo_->getPFMuonAlgo()->transferPunchThroughCleanedHadronCandidates() ); 
00550     // Save added muon candidates
00551     auto_ptr< reco::PFCandidateCollection > 
00552       pAddedMuonCandidateCollection( pfAlgo_->getPFMuonAlgo()->transferAddedMuonCandidates() ); 
00553 
00554   // Check HF overcleaning
00555   reco::PFRecHitCollection hfCopy;
00556   for ( unsigned ihf=0; ihf<inputTagCleanedHF_.size(); ++ihf ) {
00557     Handle< reco::PFRecHitCollection > hfCleaned;
00558     bool foundHF = iEvent.getByLabel( inputTagCleanedHF_[ihf], hfCleaned );  
00559     if (!foundHF) continue;
00560     for ( unsigned jhf=0; jhf<(*hfCleaned).size(); ++jhf ) { 
00561       hfCopy.push_back( (*hfCleaned)[jhf] );
00562     }
00563   }
00564   pfAlgo_->checkCleaning( hfCopy );
00565 
00566   // Save recovered HF candidates
00567   auto_ptr< reco::PFCandidateCollection > 
00568     pCleanedCandidateCollection( pfAlgo_->transferCleanedCandidates() ); 
00569 
00570   
00571   // Save the final PFCandidate collection
00572   auto_ptr< reco::PFCandidateCollection > 
00573     pOutputCandidateCollection( pfAlgo_->transferCandidates() ); 
00574   
00575 
00576   
00577   LogDebug("PFProducer")<<"particle flow: putting products in the event"<<endl;
00578   if ( verbose_ ) std::cout <<"particle flow: putting products in the event. Here the full list"<<endl;
00579   int nC=0;
00580   for( reco::PFCandidateCollection::const_iterator  itCand =  (*pOutputCandidateCollection).begin(); itCand !=  (*pOutputCandidateCollection).end(); itCand++) {
00581     nC++;
00582       if (verbose_ ) std::cout << nC << ")" << (*itCand).particleId() << std::endl;
00583 
00584   }
00585 
00586 
00587 
00588   // Write in the event
00589   iEvent.put(pOutputCandidateCollection);
00590   iEvent.put(pCleanedCandidateCollection,"CleanedHF");
00591 
00592     if ( postMuonCleaning_ ) { 
00593       iEvent.put(pCosmicsMuonCleanedCandidateCollection,"CleanedCosmicsMuons");
00594       iEvent.put(pTrackerAndGlobalCleanedMuonCandidateCollection,"CleanedTrackerAndGlobalMuons");
00595       iEvent.put(pFakeCleanedMuonCandidateCollection,"CleanedFakeMuons");
00596       iEvent.put(pPunchThroughMuonCleanedCandidateCollection,"CleanedPunchThroughMuons");
00597       iEvent.put(pPunchThroughHadronCleanedCandidateCollection,"CleanedPunchThroughNeutralHadrons");
00598       iEvent.put(pAddedMuonCandidateCollection,"AddedMuonsAndHadrons");
00599     }
00600 
00601   if(usePFElectrons_)
00602     {
00603       auto_ptr< reco::PFCandidateCollection >  
00604         pOutputElectronCandidateCollection( pfAlgo_->transferElectronCandidates() ); 
00605       iEvent.put(pOutputElectronCandidateCollection,electronOutputCol_);
00606 
00607     }
00608 }
00609