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/PFElectronTranslator.h"
00006 #include "RecoParticleFlow/PFClusterTools/interface/PFClusterWidthAlgo.h"
00007 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00008 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
00009 #include "DataFormats/EgammaReco/interface/PreshowerCluster.h"
00010 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
00011 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00012 #include "DataFormats/ParticleFlowReco/interface/PFBlockElement.h"
00013 #include "DataFormats/ParticleFlowReco/interface/PFBlockFwd.h"
00014 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00015
00016
00017 PFElectronTranslator::PFElectronTranslator(const edm::ParameterSet & iConfig) {
00018 inputTagPFCandidates_
00019 = iConfig.getParameter<edm::InputTag>("PFCandidate");
00020 inputTagGSFTracks_
00021 = iConfig.getParameter<edm::InputTag>("GSFTracks");
00022
00023 PFBasicClusterCollection_ = iConfig.getParameter<std::string>("PFBasicClusters");
00024 PFPreshowerClusterCollection_ = iConfig.getParameter<std::string>("PFPreshowerClusters");
00025 PFSuperClusterCollection_ = iConfig.getParameter<std::string>("PFSuperClusters");
00026 PFMVAValueMap_ = iConfig.getParameter<std::string>("ElectronMVA");
00027 PFSCValueMap_ = iConfig.getParameter<std::string>("ElectronSC");
00028 MVACut_ = (iConfig.getParameter<edm::ParameterSet>("MVACutBlock")).getParameter<double>("MVACut");
00029
00030 produces<reco::BasicClusterCollection>(PFBasicClusterCollection_);
00031 produces<reco::PreshowerClusterCollection>(PFPreshowerClusterCollection_);
00032 produces<reco::SuperClusterCollection>(PFSuperClusterCollection_);
00033 produces<edm::ValueMap<float> >(PFMVAValueMap_);
00034 produces<edm::ValueMap<reco::SuperClusterRef> >(PFSCValueMap_);
00035 }
00036
00037 PFElectronTranslator::~PFElectronTranslator() {}
00038
00039 void PFElectronTranslator::beginRun(edm::Run& run,const edm::EventSetup & es) {}
00040
00041 void PFElectronTranslator::produce(edm::Event& iEvent,
00042 const edm::EventSetup& iSetup) {
00043
00044 std::auto_ptr<reco::SuperClusterCollection>
00045 superClusters_p(new reco::SuperClusterCollection);
00046
00047 std::auto_ptr<reco::BasicClusterCollection>
00048 basicClusters_p(new reco::BasicClusterCollection);
00049
00050 std::auto_ptr<reco::PreshowerClusterCollection>
00051 psClusters_p(new reco::PreshowerClusterCollection);
00052
00053 std::auto_ptr<edm::ValueMap<float> > mvaMap_p(new edm::ValueMap<float>());
00054 edm::ValueMap<float>::Filler mvaFiller(*mvaMap_p);
00055
00056 std::auto_ptr<edm::ValueMap<reco::SuperClusterRef> >
00057 scMap_p(new edm::ValueMap<reco::SuperClusterRef>());
00058 edm::ValueMap<reco::SuperClusterRef>::Filler scRefFiller(*scMap_p);
00059
00060
00061 edm::Handle<reco::PFCandidateCollection> pfCandidates;
00062 bool status=fetchCandidateCollection(pfCandidates,
00063 inputTagPFCandidates_,
00064 iEvent );
00065
00066
00067 GsfTrackRef_.clear();
00068 basicClusters_.clear();
00069 pfClusters_.clear();
00070 preshowerClusters_.clear();
00071 superClusters_.clear();
00072 basicClusterPtr_.clear();
00073 preshowerClusterPtr_.clear();
00074 gsfPFCandidateIndex_.clear();
00075 scMap_.clear();
00076 gsfMvaMap_.clear();
00077
00078
00079
00080
00081
00082
00083 unsigned ncand=(status)?pfCandidates->size():0;
00084 unsigned iGSF=0;
00085 for( unsigned i=0; i<ncand; ++i ) {
00086
00087 const reco::PFCandidate& cand = (*pfCandidates)[i];
00088 if(cand.particleId()!=reco::PFCandidate::e) continue;
00089 if(cand.gsfTrackRef().isNull()) continue;
00090
00091
00092 gsfMvaMap_[cand.gsfTrackRef()]=cand.mva_e_pi();
00093 if(cand.mva_e_pi()<MVACut_) continue;
00094
00095 GsfTrackRef_.push_back(cand.gsfTrackRef());
00096 gsfPFCandidateIndex_.push_back(i);
00097
00098 basicClusters_.push_back(reco::BasicClusterCollection());
00099 pfClusters_.push_back(std::vector<const reco::PFCluster *>());
00100 preshowerClusters_.push_back(reco::PreshowerClusterCollection());
00101
00102 for(unsigned iele=0; iele<cand.elementsInBlocks().size(); ++iele) {
00103
00104 reco::PFBlockRef blockRef = cand.elementsInBlocks()[iele].first;
00105
00106 unsigned elementIndex = cand.elementsInBlocks()[iele].second;
00107
00108 if(blockRef.isNull()) continue;
00109
00110
00111 const edm::OwnVector< reco::PFBlockElement >& elements = (*blockRef).elements();
00112
00113 const reco::PFBlockElement & pfbe (elements[elementIndex]);
00114
00115 if(pfbe.type()==reco::PFBlockElement::ECAL)
00116 {
00117
00118
00119
00120
00121 createBasicCluster(pfbe,basicClusters_[iGSF],pfClusters_[iGSF],correspondingDaughterCandidate(cand,pfbe));
00122 }
00123 if(pfbe.type()==reco::PFBlockElement::PS1)
00124 {
00125 createPreshowerCluster(pfbe,preshowerClusters_[iGSF],1);
00126 }
00127 if(pfbe.type()==reco::PFBlockElement::PS2)
00128 {
00129 createPreshowerCluster(pfbe,preshowerClusters_[iGSF],2);
00130 }
00131
00132 }
00133
00134
00135 basicClusters_p->insert(basicClusters_p->end(),basicClusters_[iGSF].begin(), basicClusters_[iGSF].end());
00136
00137 psClusters_p->insert(psClusters_p->end(),preshowerClusters_[iGSF].begin(),preshowerClusters_[iGSF].end());
00138
00139 ++iGSF;
00140 }
00141
00142
00143
00144
00145 const edm::OrphanHandle<reco::BasicClusterCollection> bcRefProd =
00146 iEvent.put(basicClusters_p,PFBasicClusterCollection_);
00147
00148
00149 const edm::OrphanHandle<reco::PreshowerClusterCollection> psRefProd =
00150 iEvent.put(psClusters_p,PFPreshowerClusterCollection_);
00151
00152
00153 createBasicClusterPtrs(bcRefProd);
00154
00155 createPreshowerClusterPtrs(psRefProd);
00156
00157
00158 if(status) createSuperClusters(*pfCandidates,*superClusters_p);
00159
00160
00161 const edm::OrphanHandle<reco::SuperClusterCollection> scRefProd = iEvent.put(superClusters_p,PFSuperClusterCollection_);
00162
00163 createSuperClusterGsfMapRefs(scRefProd);
00164
00165
00166 fillMVAValueMap(iEvent,mvaFiller);
00167 mvaFiller.fill();
00168
00169 fillSCRefValueMap(iEvent,scRefFiller);
00170 scRefFiller.fill();
00171
00172
00173 iEvent.put(mvaMap_p,PFMVAValueMap_);
00174
00175 iEvent.put(scMap_p,PFSCValueMap_);
00176 }
00177
00178
00179
00180 bool PFElectronTranslator::fetchCandidateCollection(edm::Handle<reco::PFCandidateCollection>& c,
00181 const edm::InputTag& tag,
00182 const edm::Event& iEvent) const {
00183 bool found = iEvent.getByLabel(tag, c);
00184
00185 if(!found)
00186 {
00187 std::ostringstream err;
00188 err<<" cannot get PFCandidates: "
00189 <<tag<<std::endl;
00190 edm::LogError("PFElectronTranslator")<<err.str();
00191 }
00192 return found;
00193
00194 }
00195
00196 void PFElectronTranslator::fetchGsfCollection(edm::Handle<reco::GsfTrackCollection>& c,
00197 const edm::InputTag& tag,
00198 const edm::Event& iEvent) const {
00199 bool found = iEvent.getByLabel(tag, c);
00200
00201 if(!found ) {
00202 std::ostringstream err;
00203 err<<" cannot get GSFTracks: "
00204 <<tag<<std::endl;
00205 edm::LogError("PFElectronTranslator")<<err.str();
00206 throw cms::Exception( "MissingProduct", err.str());
00207 }
00208 }
00209
00210
00211
00212
00213 void PFElectronTranslator::createBasicCluster(const reco::PFBlockElement & PFBE,
00214 reco::BasicClusterCollection & basicClusters,
00215 std::vector<const reco::PFCluster *> & pfClusters,
00216 const reco::PFCandidate & coCandidate) const
00217 {
00218 reco::PFClusterRef myPFClusterRef= PFBE.clusterRef();
00219 if(myPFClusterRef.isNull()) return;
00220
00221 const reco::PFCluster & myPFCluster (*myPFClusterRef);
00222 pfClusters.push_back(&myPFCluster);
00223
00224
00225
00226
00227 basicClusters.push_back(reco::CaloCluster(coCandidate.rawEcalEnergy(),
00228 myPFCluster.position(),
00229 myPFCluster.caloID(),
00230 myPFCluster.hitsAndFractions(),
00231 myPFCluster.algo(),
00232 myPFCluster.seed()));
00233 }
00234
00235
00236 void PFElectronTranslator::createPreshowerCluster(const reco::PFBlockElement & PFBE, reco::PreshowerClusterCollection& preshowerClusters,unsigned plane) const
00237 {
00238 reco::PFClusterRef myPFClusterRef= PFBE.clusterRef();
00239 preshowerClusters.push_back(reco::PreshowerCluster(myPFClusterRef->energy(),myPFClusterRef->position(),
00240 myPFClusterRef->hitsAndFractions(),plane));
00241 }
00242
00243 void PFElectronTranslator::createBasicClusterPtrs(const edm::OrphanHandle<reco::BasicClusterCollection> & basicClustersHandle )
00244 {
00245 unsigned size=GsfTrackRef_.size();
00246 unsigned basicClusterCounter=0;
00247 basicClusterPtr_.resize(size);
00248
00249 for(unsigned iGSF=0;iGSF<size;++iGSF)
00250 {
00251 unsigned nbc=basicClusters_[iGSF].size();
00252 for(unsigned ibc=0;ibc<nbc;++ibc)
00253 {
00254
00255 reco::CaloClusterPtr bcPtr(basicClustersHandle,basicClusterCounter);
00256 basicClusterPtr_[iGSF].push_back(bcPtr);
00257 ++basicClusterCounter;
00258 }
00259 }
00260 }
00261
00262 void PFElectronTranslator::createPreshowerClusterPtrs(const edm::OrphanHandle<reco::PreshowerClusterCollection> & preshowerClustersHandle )
00263 {
00264 unsigned size=GsfTrackRef_.size();
00265 unsigned psClusterCounter=0;
00266 preshowerClusterPtr_.resize(size);
00267
00268 for(unsigned iGSF=0;iGSF<size;++iGSF)
00269 {
00270 unsigned nbc=preshowerClusters_[iGSF].size();
00271 for(unsigned ibc=0;ibc<nbc;++ibc)
00272 {
00273
00274 reco::CaloClusterPtr psPtr(preshowerClustersHandle,psClusterCounter);
00275 preshowerClusterPtr_[iGSF].push_back(psPtr);
00276 ++psClusterCounter;
00277 }
00278 }
00279 }
00280
00281 void PFElectronTranslator::createSuperClusterGsfMapRefs(const edm::OrphanHandle<reco::SuperClusterCollection> & superClustersHandle )
00282 {
00283 unsigned size=GsfTrackRef_.size();
00284
00285 for(unsigned iGSF=0;iGSF<size;++iGSF)
00286 {
00287 edm::Ref<reco::SuperClusterCollection> scRef(superClustersHandle,iGSF);
00288 scMap_[GsfTrackRef_[iGSF]]=scRef;
00289 }
00290 }
00291
00292
00293 void PFElectronTranslator::fillMVAValueMap(edm::Event& iEvent, edm::ValueMap<float>::Filler & filler) const
00294 {
00295 edm::Handle<reco::GsfTrackCollection> gsfTracks;
00296 fetchGsfCollection(gsfTracks,
00297 inputTagGSFTracks_,
00298 iEvent);
00299 unsigned ngsf=gsfTracks->size();
00300 std::vector<float> values;
00301 for(unsigned igsf=0;igsf<ngsf;++igsf)
00302 {
00303 reco::GsfTrackRef theTrackRef(gsfTracks, igsf);
00304 std::map<reco::GsfTrackRef,float>::const_iterator itcheck=gsfMvaMap_.find(theTrackRef);
00305 if(itcheck==gsfMvaMap_.end())
00306 {
00307
00308 values.push_back(-99.);
00309
00310 }
00311 else
00312 {
00313 values.push_back(itcheck->second);
00314 }
00315 }
00316 filler.insert(gsfTracks,values.begin(),values.end());
00317 }
00318
00319
00320 void PFElectronTranslator::fillSCRefValueMap(edm::Event& iEvent,
00321 edm::ValueMap<reco::SuperClusterRef>::Filler & filler) const
00322 {
00323 edm::Handle<reco::GsfTrackCollection> gsfTracks;
00324 fetchGsfCollection(gsfTracks,
00325 inputTagGSFTracks_,
00326 iEvent);
00327 unsigned ngsf=gsfTracks->size();
00328 std::vector<reco::SuperClusterRef> values;
00329 for(unsigned igsf=0;igsf<ngsf;++igsf)
00330 {
00331 reco::GsfTrackRef theTrackRef(gsfTracks, igsf);
00332 std::map<reco::GsfTrackRef,reco::SuperClusterRef>::const_iterator itcheck=scMap_.find(theTrackRef);
00333 if(itcheck==scMap_.end())
00334 {
00335
00336 values.push_back(reco::SuperClusterRef());
00337 }
00338 else
00339 {
00340 values.push_back(itcheck->second);
00341 }
00342 }
00343 filler.insert(gsfTracks,values.begin(),values.end());
00344 }
00345
00346
00347 void PFElectronTranslator::createSuperClusters(const reco::PFCandidateCollection & pfCand,
00348 reco::SuperClusterCollection &superClusters) const
00349 {
00350 unsigned nGSF=GsfTrackRef_.size();
00351 for(unsigned iGSF=0;iGSF<nGSF;++iGSF)
00352 {
00353
00354
00355 double sclusterE=0;
00356 double posX=0.;
00357 double posY=0.;
00358 double posZ=0.;
00359
00360 unsigned nbasics=basicClusters_[iGSF].size();
00361 for(unsigned ibc=0;ibc<nbasics;++ibc)
00362 {
00363 double e = basicClusters_[iGSF][ibc].energy();
00364 sclusterE += e;
00365 posX += e * basicClusters_[iGSF][ibc].position().X();
00366 posY += e * basicClusters_[iGSF][ibc].position().Y();
00367 posZ += e * basicClusters_[iGSF][ibc].position().Z();
00368 }
00369 posX /=sclusterE;
00370 posY /=sclusterE;
00371 posZ /=sclusterE;
00372
00373 if(pfCand[gsfPFCandidateIndex_[iGSF]].gsfTrackRef()!=GsfTrackRef_[iGSF])
00374 {
00375 edm::LogError("PFElectronTranslator") << " Major problem in PFElectron Translator" << std::endl;
00376 }
00377
00378
00379 PFClusterWidthAlgo pfwidth(pfClusters_[iGSF]);
00380
00381 double correctedEnergy=pfCand[gsfPFCandidateIndex_[iGSF]].ecalEnergy();
00382 reco::SuperCluster mySuperCluster(correctedEnergy,math::XYZPoint(posX,posY,posZ));
00383
00384 if(nbasics)
00385 {
00386
00387
00388
00389 mySuperCluster.setSeed(basicClusterPtr_[iGSF][0]);
00390 }
00391 else
00392 {
00393
00394
00395
00396
00397
00398 mySuperCluster.setSeed(reco::CaloClusterPtr());
00399 }
00400
00401
00402 for(unsigned ibc=0;ibc<nbasics;++ibc)
00403 {
00404 mySuperCluster.addCluster(basicClusterPtr_[iGSF][ibc]);
00405
00406 const std::vector< std::pair<DetId, float> > & v1 = basicClusters_[iGSF][ibc].hitsAndFractions();
00407
00408 for( std::vector< std::pair<DetId, float> >::const_iterator diIt = v1.begin();
00409 diIt != v1.end();
00410 ++diIt ) {
00411
00412 mySuperCluster.addHitAndFraction(diIt->first,diIt->second);
00413 }
00414 }
00415
00416 unsigned nps=preshowerClusterPtr_[iGSF].size();
00417 for(unsigned ips=0;ips<nps;++ips)
00418 {
00419 mySuperCluster.addPreshowerCluster(preshowerClusterPtr_[iGSF][ips]);
00420 }
00421
00422
00423
00424 mySuperCluster.setPreshowerEnergy(pfCand[gsfPFCandidateIndex_[iGSF]].pS1Energy()+
00425 pfCand[gsfPFCandidateIndex_[iGSF]].pS2Energy());
00426
00427
00428 mySuperCluster.setEtaWidth(pfwidth.pflowEtaWidth());
00429 mySuperCluster.setPhiWidth(pfwidth.pflowPhiWidth());
00430
00431 mySuperCluster.rawEnergy();
00432 superClusters.push_back(mySuperCluster);
00433 }
00434 }
00435
00436
00437 const reco::PFCandidate & PFElectronTranslator::correspondingDaughterCandidate(const reco::PFCandidate & cand, const reco::PFBlockElement & pfbe) const
00438 {
00439 unsigned refindex=pfbe.index();
00440
00441 reco::PFCandidate::const_iterator myDaughterCandidate=cand.begin();
00442 reco::PFCandidate::const_iterator itend=cand.end();
00443
00444 for(;myDaughterCandidate!=itend;++myDaughterCandidate)
00445 {
00446 const reco::PFCandidate * myPFCandidate = (const reco::PFCandidate*)&*myDaughterCandidate;
00447 if(myPFCandidate->elementsInBlocks().size()!=1)
00448 {
00449
00450 return cand;
00451 }
00452 if(myPFCandidate->elementsInBlocks()[0].second==refindex)
00453 {
00454
00455 return *myPFCandidate;
00456 }
00457 }
00458 return cand;
00459 }
00460