File indexing completed on 2023-03-17 11:21:11
0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0004 #include "CommonTools/ParticleFlow/interface/PFClusterWidthAlgo.h"
0005 #include "RecoEcal/EgammaCoreTools/interface/Mustache.h"
0006 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0007 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateElectronExtra.h"
0008 #include "DataFormats/EgammaReco/interface/PreshowerCluster.h"
0009 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
0010 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
0011 #include "DataFormats/EgammaCandidates/interface/GsfElectronCore.h"
0012 #include "DataFormats/ParticleFlowReco/interface/PFBlockElement.h"
0013 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementGsfTrack.h"
0014 #include "FWCore/Framework/interface/stream/EDProducer.h"
0015 #include "FWCore/Framework/interface/MakerMacros.h"
0016 #include "DataFormats/Common/interface/ValueMap.h"
0017 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
0018 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
0019 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
0020 #include "CondFormats/EcalObjects/interface/EcalMustacheSCParameters.h"
0021 #include "CondFormats/DataRecord/interface/EcalMustacheSCParametersRcd.h"
0022
0023 class DetId;
0024 namespace edm {
0025 class EventSetup;
0026 }
0027
0028 class PFElectronTranslator : public edm::stream::EDProducer<> {
0029 public:
0030 explicit PFElectronTranslator(const edm::ParameterSet&);
0031 ~PFElectronTranslator() override;
0032
0033 void produce(edm::Event&, const edm::EventSetup&) override;
0034
0035 typedef std::vector<edm::Handle<edm::ValueMap<double>>> IsolationValueMaps;
0036
0037 private:
0038
0039 bool fetchCandidateCollection(edm::Handle<reco::PFCandidateCollection>& c,
0040 const edm::InputTag& tag,
0041 const edm::Event& iEvent) const;
0042
0043 void fetchGsfCollection(edm::Handle<reco::GsfTrackCollection>& c,
0044 const edm::InputTag& tag,
0045 const edm::Event& iEvent) const;
0046
0047
0048
0049 void createBasicCluster(const reco::PFBlockElement&,
0050 reco::BasicClusterCollection& basicClusters,
0051 std::vector<const reco::PFCluster*>&,
0052 const reco::PFCandidate& coCandidate) const;
0053
0054 void createPreshowerCluster(const reco::PFBlockElement& PFBE,
0055 reco::PreshowerClusterCollection& preshowerClusters,
0056 unsigned plane) const;
0057
0058
0059 void createSuperClusters(const reco::PFCandidateCollection&, reco::SuperClusterCollection& superClusters) const;
0060
0061
0062 void createGsfElectronCores(reco::GsfElectronCoreCollection&) const;
0063
0064
0065 void createBasicClusterPtrs(const edm::OrphanHandle<reco::BasicClusterCollection>& basicClustersHandle);
0066
0067
0068 void createPreshowerClusterPtrs(const edm::OrphanHandle<reco::PreshowerClusterCollection>& preshowerClustersHandle);
0069
0070
0071 void createSuperClusterGsfMapRefs(const edm::OrphanHandle<reco::SuperClusterCollection>& superClustersHandle);
0072
0073
0074 void createGsfElectronCoreRefs(const edm::OrphanHandle<reco::GsfElectronCoreCollection>& gsfElectronCoreHandle);
0075
0076
0077 void createGsfElectrons(const reco::PFCandidateCollection&,
0078 const IsolationValueMaps& isolationValues,
0079 reco::GsfElectronCollection&);
0080
0081
0082 void fillMVAValueMap(edm::Event& iEvent, edm::ValueMap<float>::Filler& filler);
0083 void fillValueMap(edm::Event& iEvent, edm::ValueMap<float>::Filler& filler) const;
0084 void fillSCRefValueMap(edm::Event& iEvent, edm::ValueMap<reco::SuperClusterRef>::Filler& filler) const;
0085 void getAmbiguousGsfTracks(const reco::PFBlockElement& PFBE, std::vector<reco::GsfTrackRef>&) const;
0086
0087 const reco::PFCandidate& correspondingDaughterCandidate(const reco::PFCandidate& cand,
0088 const reco::PFBlockElement& pfbe) const;
0089
0090 private:
0091 edm::InputTag inputTagPFCandidates_;
0092 edm::InputTag inputTagPFCandidateElectrons_;
0093 edm::InputTag inputTagGSFTracks_;
0094 std::vector<edm::InputTag> inputTagIsoVals_;
0095 std::string PFBasicClusterCollection_;
0096 std::string PFPreshowerClusterCollection_;
0097 std::string PFSuperClusterCollection_;
0098 std::string PFMVAValueMap_;
0099 std::string PFSCValueMap_;
0100 std::string GsfElectronCoreCollection_;
0101 std::string GsfElectronCollection_;
0102 double MVACut_;
0103 bool checkStatusFlag_;
0104
0105
0106
0107 std::vector<reco::GsfTrackRef> GsfTrackRef_;
0108
0109 std::vector<reco::CandidatePtr> CandidatePtr_;
0110
0111 std::vector<reco::TrackRef> kfTrackRef_;
0112
0113 std::vector<std::vector<reco::GsfTrackRef>> ambiguousGsfTracks_;
0114
0115 std::vector<reco::BasicClusterCollection> basicClusters_;
0116
0117 std::vector<std::vector<const reco::PFCluster*>> pfClusters_;
0118
0119 std::vector<reco::PreshowerClusterCollection> preshowerClusters_;
0120
0121 std::vector<reco::SuperClusterCollection> superClusters_;
0122
0123 std::vector<reco::CaloClusterPtrVector> basicClusterPtr_;
0124
0125 std::vector<reco::CaloClusterPtrVector> preshowerClusterPtr_;
0126
0127 std::vector<reco::GsfElectronCoreRef> gsfElectronCoreRefs_;
0128
0129 std::vector<int> gsfPFCandidateIndex_;
0130
0131 std::map<reco::GsfTrackRef, reco::SuperClusterRef> scMap_;
0132 std::map<reco::GsfTrackRef, float> gsfMvaMap_;
0133
0134
0135 edm::ESGetToken<EcalMustacheSCParameters, EcalMustacheSCParametersRcd> ecalMustacheSCParametersToken_;
0136 const EcalMustacheSCParameters* mustacheSCParams_;
0137
0138 bool emptyIsOk_;
0139 };
0140
0141 DEFINE_FWK_MODULE(PFElectronTranslator);
0142
0143 PFElectronTranslator::PFElectronTranslator(const edm::ParameterSet& iConfig) {
0144 inputTagPFCandidates_ = iConfig.getParameter<edm::InputTag>("PFCandidate");
0145 inputTagPFCandidateElectrons_ = iConfig.getParameter<edm::InputTag>("PFCandidateElectron");
0146 inputTagGSFTracks_ = iConfig.getParameter<edm::InputTag>("GSFTracks");
0147
0148 bool useIsolationValues = iConfig.getParameter<bool>("useIsolationValues");
0149 if (useIsolationValues) {
0150 if (!iConfig.exists("isolationValues"))
0151 throw cms::Exception("PFElectronTranslator|InternalError") << "Missing ParameterSet isolationValues";
0152 else {
0153 edm::ParameterSet isoVals = iConfig.getParameter<edm::ParameterSet>("isolationValues");
0154 inputTagIsoVals_.push_back(isoVals.getParameter<edm::InputTag>("pfSumChargedHadronPt"));
0155 inputTagIsoVals_.push_back(isoVals.getParameter<edm::InputTag>("pfSumPhotonEt"));
0156 inputTagIsoVals_.push_back(isoVals.getParameter<edm::InputTag>("pfSumNeutralHadronEt"));
0157 inputTagIsoVals_.push_back(isoVals.getParameter<edm::InputTag>("pfSumPUPt"));
0158 }
0159 }
0160
0161 PFBasicClusterCollection_ = iConfig.getParameter<std::string>("PFBasicClusters");
0162 PFPreshowerClusterCollection_ = iConfig.getParameter<std::string>("PFPreshowerClusters");
0163 PFSuperClusterCollection_ = iConfig.getParameter<std::string>("PFSuperClusters");
0164 GsfElectronCoreCollection_ = iConfig.getParameter<std::string>("PFGsfElectronCore");
0165 GsfElectronCollection_ = iConfig.getParameter<std::string>("PFGsfElectron");
0166
0167 PFMVAValueMap_ = iConfig.getParameter<std::string>("ElectronMVA");
0168 PFSCValueMap_ = iConfig.getParameter<std::string>("ElectronSC");
0169 MVACut_ = (iConfig.getParameter<edm::ParameterSet>("MVACutBlock")).getParameter<double>("MVACut");
0170 checkStatusFlag_ = iConfig.getParameter<bool>("CheckStatusFlag");
0171
0172 if (iConfig.exists("emptyIsOk"))
0173 emptyIsOk_ = iConfig.getParameter<bool>("emptyIsOk");
0174 else
0175 emptyIsOk_ = false;
0176
0177 ecalMustacheSCParametersToken_ = esConsumes<EcalMustacheSCParameters, EcalMustacheSCParametersRcd>();
0178
0179 produces<reco::BasicClusterCollection>(PFBasicClusterCollection_);
0180 produces<reco::PreshowerClusterCollection>(PFPreshowerClusterCollection_);
0181 produces<reco::SuperClusterCollection>(PFSuperClusterCollection_);
0182 produces<reco::GsfElectronCoreCollection>(GsfElectronCoreCollection_);
0183 produces<reco::GsfElectronCollection>(GsfElectronCollection_);
0184 produces<edm::ValueMap<float>>(PFMVAValueMap_);
0185 produces<edm::ValueMap<reco::SuperClusterRef>>(PFSCValueMap_);
0186 }
0187
0188 PFElectronTranslator::~PFElectronTranslator() {}
0189
0190 void PFElectronTranslator::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0191 mustacheSCParams_ = &iSetup.getData(ecalMustacheSCParametersToken_);
0192
0193 auto gsfElectronCores_p = std::make_unique<reco::GsfElectronCoreCollection>();
0194
0195 auto gsfElectrons_p = std::make_unique<reco::GsfElectronCollection>();
0196
0197 auto superClusters_p = std::make_unique<reco::SuperClusterCollection>();
0198
0199 auto basicClusters_p = std::make_unique<reco::BasicClusterCollection>();
0200
0201 auto psClusters_p = std::make_unique<reco::PreshowerClusterCollection>();
0202
0203 auto mvaMap_p = std::make_unique<edm::ValueMap<float>>();
0204 edm::ValueMap<float>::Filler mvaFiller(*mvaMap_p);
0205
0206 auto scMap_p = std::make_unique<edm::ValueMap<reco::SuperClusterRef>>();
0207 edm::ValueMap<reco::SuperClusterRef>::Filler scRefFiller(*scMap_p);
0208
0209 edm::Handle<reco::PFCandidateCollection> pfCandidates;
0210 bool status = fetchCandidateCollection(pfCandidates, inputTagPFCandidates_, iEvent);
0211
0212 IsolationValueMaps isolationValues(inputTagIsoVals_.size());
0213 for (size_t j = 0; j < inputTagIsoVals_.size(); ++j) {
0214 iEvent.getByLabel(inputTagIsoVals_[j], isolationValues[j]);
0215 }
0216
0217
0218 GsfTrackRef_.clear();
0219 CandidatePtr_.clear();
0220 ambiguousGsfTracks_.clear();
0221 kfTrackRef_.clear();
0222 basicClusters_.clear();
0223 pfClusters_.clear();
0224 preshowerClusters_.clear();
0225 superClusters_.clear();
0226 basicClusterPtr_.clear();
0227 preshowerClusterPtr_.clear();
0228 gsfPFCandidateIndex_.clear();
0229 gsfElectronCoreRefs_.clear();
0230 scMap_.clear();
0231
0232
0233
0234
0235
0236
0237 unsigned ncand = (status) ? pfCandidates->size() : 0;
0238 unsigned iGSF = 0;
0239 for (unsigned i = 0; i < ncand; ++i) {
0240 const reco::PFCandidate& cand = (*pfCandidates)[i];
0241 if (cand.particleId() != reco::PFCandidate::e)
0242 continue;
0243 if (cand.gsfTrackRef().isNull())
0244 continue;
0245
0246
0247 if (cand.mva_e_pi() < MVACut_)
0248 continue;
0249
0250
0251 if (checkStatusFlag_ && !cand.electronExtraRef()->electronStatus(reco::PFCandidateElectronExtra::Selected)) {
0252 continue;
0253 }
0254
0255 GsfTrackRef_.push_back(cand.gsfTrackRef());
0256 kfTrackRef_.push_back(cand.trackRef());
0257 gsfPFCandidateIndex_.push_back(i);
0258
0259 reco::PFCandidatePtr ptrToPFElectron(pfCandidates, i);
0260
0261 CandidatePtr_.push_back(ptrToPFElectron);
0262
0263 basicClusters_.push_back(reco::BasicClusterCollection());
0264 pfClusters_.push_back(std::vector<const reco::PFCluster*>());
0265 preshowerClusters_.push_back(reco::PreshowerClusterCollection());
0266 ambiguousGsfTracks_.push_back(std::vector<reco::GsfTrackRef>());
0267
0268 for (unsigned iele = 0; iele < cand.elementsInBlocks().size(); ++iele) {
0269
0270 reco::PFBlockRef blockRef = cand.elementsInBlocks()[iele].first;
0271
0272 unsigned elementIndex = cand.elementsInBlocks()[iele].second;
0273
0274 if (blockRef.isNull())
0275 continue;
0276
0277
0278 const edm::OwnVector<reco::PFBlockElement>& elements = (*blockRef).elements();
0279
0280 const reco::PFBlockElement& pfbe(elements[elementIndex]);
0281
0282 if (pfbe.type() == reco::PFBlockElement::ECAL) {
0283
0284
0285
0286
0287 createBasicCluster(pfbe, basicClusters_[iGSF], pfClusters_[iGSF], correspondingDaughterCandidate(cand, pfbe));
0288 }
0289 if (pfbe.type() == reco::PFBlockElement::PS1) {
0290 createPreshowerCluster(pfbe, preshowerClusters_[iGSF], 1);
0291 }
0292 if (pfbe.type() == reco::PFBlockElement::PS2) {
0293 createPreshowerCluster(pfbe, preshowerClusters_[iGSF], 2);
0294 }
0295 if (pfbe.type() == reco::PFBlockElement::GSF) {
0296 getAmbiguousGsfTracks(pfbe, ambiguousGsfTracks_[iGSF]);
0297 }
0298
0299 }
0300
0301
0302 basicClusters_p->insert(basicClusters_p->end(), basicClusters_[iGSF].begin(), basicClusters_[iGSF].end());
0303
0304 psClusters_p->insert(psClusters_p->end(), preshowerClusters_[iGSF].begin(), preshowerClusters_[iGSF].end());
0305
0306 ++iGSF;
0307 }
0308
0309
0310
0311 const edm::OrphanHandle<reco::BasicClusterCollection> bcRefProd =
0312 iEvent.put(std::move(basicClusters_p), PFBasicClusterCollection_);
0313
0314
0315 const edm::OrphanHandle<reco::PreshowerClusterCollection> psRefProd =
0316 iEvent.put(std::move(psClusters_p), PFPreshowerClusterCollection_);
0317
0318
0319 createBasicClusterPtrs(bcRefProd);
0320
0321 createPreshowerClusterPtrs(psRefProd);
0322
0323
0324 if (status)
0325 createSuperClusters(*pfCandidates, *superClusters_p);
0326
0327
0328 const edm::OrphanHandle<reco::SuperClusterCollection> scRefProd =
0329 iEvent.put(std::move(superClusters_p), PFSuperClusterCollection_);
0330
0331 createSuperClusterGsfMapRefs(scRefProd);
0332
0333
0334 createGsfElectronCores(*gsfElectronCores_p);
0335
0336 const edm::OrphanHandle<reco::GsfElectronCoreCollection> gsfElectronCoreRefProd =
0337 iEvent.put(std::move(gsfElectronCores_p), GsfElectronCoreCollection_);
0338
0339
0340 createGsfElectronCoreRefs(gsfElectronCoreRefProd);
0341
0342
0343 createGsfElectrons(*pfCandidates, isolationValues, *gsfElectrons_p);
0344 iEvent.put(std::move(gsfElectrons_p), GsfElectronCollection_);
0345
0346 fillMVAValueMap(iEvent, mvaFiller);
0347 mvaFiller.fill();
0348
0349 fillSCRefValueMap(iEvent, scRefFiller);
0350 scRefFiller.fill();
0351
0352
0353 iEvent.put(std::move(mvaMap_p), PFMVAValueMap_);
0354
0355 iEvent.put(std::move(scMap_p), PFSCValueMap_);
0356 }
0357
0358 bool PFElectronTranslator::fetchCandidateCollection(edm::Handle<reco::PFCandidateCollection>& c,
0359 const edm::InputTag& tag,
0360 const edm::Event& iEvent) const {
0361 bool found = iEvent.getByLabel(tag, c);
0362
0363 if (!found && !emptyIsOk_) {
0364 std::ostringstream err;
0365 err << " cannot get PFCandidates: " << tag << std::endl;
0366 edm::LogError("PFElectronTranslator") << err.str();
0367 }
0368 return found;
0369 }
0370
0371 void PFElectronTranslator::fetchGsfCollection(edm::Handle<reco::GsfTrackCollection>& c,
0372 const edm::InputTag& tag,
0373 const edm::Event& iEvent) const {
0374 bool found = iEvent.getByLabel(tag, c);
0375
0376 if (!found) {
0377 std::ostringstream err;
0378 err << " cannot get GSFTracks: " << tag << std::endl;
0379 edm::LogError("PFElectronTranslator") << err.str();
0380 throw cms::Exception("MissingProduct", err.str());
0381 }
0382 }
0383
0384
0385
0386
0387 void PFElectronTranslator::createBasicCluster(const reco::PFBlockElement& PFBE,
0388 reco::BasicClusterCollection& basicClusters,
0389 std::vector<const reco::PFCluster*>& pfClusters,
0390 const reco::PFCandidate& coCandidate) const {
0391 const reco::PFClusterRef& myPFClusterRef = PFBE.clusterRef();
0392 if (myPFClusterRef.isNull())
0393 return;
0394
0395 const reco::PFCluster& myPFCluster(*myPFClusterRef);
0396 pfClusters.push_back(&myPFCluster);
0397
0398
0399
0400
0401 basicClusters.push_back(reco::CaloCluster(
0402
0403 coCandidate.rawEcalEnergy(),
0404 myPFCluster.position(),
0405 myPFCluster.caloID(),
0406 myPFCluster.hitsAndFractions(),
0407 myPFCluster.algo(),
0408 myPFCluster.seed()));
0409 }
0410
0411 void PFElectronTranslator::createPreshowerCluster(const reco::PFBlockElement& PFBE,
0412 reco::PreshowerClusterCollection& preshowerClusters,
0413 unsigned plane) const {
0414 const reco::PFClusterRef& myPFClusterRef = PFBE.clusterRef();
0415 preshowerClusters.push_back(reco::PreshowerCluster(
0416 myPFClusterRef->energy(), myPFClusterRef->position(), myPFClusterRef->hitsAndFractions(), plane));
0417 }
0418
0419 void PFElectronTranslator::createBasicClusterPtrs(
0420 const edm::OrphanHandle<reco::BasicClusterCollection>& basicClustersHandle) {
0421 unsigned size = GsfTrackRef_.size();
0422 unsigned basicClusterCounter = 0;
0423 basicClusterPtr_.resize(size);
0424
0425 for (unsigned iGSF = 0; iGSF < size; ++iGSF)
0426 {
0427 unsigned nbc = basicClusters_[iGSF].size();
0428 for (unsigned ibc = 0; ibc < nbc; ++ibc)
0429 {
0430
0431 reco::CaloClusterPtr bcPtr(basicClustersHandle, basicClusterCounter);
0432 basicClusterPtr_[iGSF].push_back(bcPtr);
0433 ++basicClusterCounter;
0434 }
0435 }
0436 }
0437
0438 void PFElectronTranslator::createPreshowerClusterPtrs(
0439 const edm::OrphanHandle<reco::PreshowerClusterCollection>& preshowerClustersHandle) {
0440 unsigned size = GsfTrackRef_.size();
0441 unsigned psClusterCounter = 0;
0442 preshowerClusterPtr_.resize(size);
0443
0444 for (unsigned iGSF = 0; iGSF < size; ++iGSF)
0445 {
0446 unsigned nbc = preshowerClusters_[iGSF].size();
0447 for (unsigned ibc = 0; ibc < nbc; ++ibc)
0448 {
0449
0450 reco::CaloClusterPtr psPtr(preshowerClustersHandle, psClusterCounter);
0451 preshowerClusterPtr_[iGSF].push_back(psPtr);
0452 ++psClusterCounter;
0453 }
0454 }
0455 }
0456
0457 void PFElectronTranslator::createSuperClusterGsfMapRefs(
0458 const edm::OrphanHandle<reco::SuperClusterCollection>& superClustersHandle) {
0459 unsigned size = GsfTrackRef_.size();
0460
0461 for (unsigned iGSF = 0; iGSF < size; ++iGSF)
0462 {
0463 edm::Ref<reco::SuperClusterCollection> scRef(superClustersHandle, iGSF);
0464 scMap_[GsfTrackRef_[iGSF]] = scRef;
0465 }
0466 }
0467
0468 void PFElectronTranslator::fillMVAValueMap(edm::Event& iEvent, edm::ValueMap<float>::Filler& filler) {
0469 gsfMvaMap_.clear();
0470 edm::Handle<reco::PFCandidateCollection> pfCandidates;
0471 bool status = fetchCandidateCollection(pfCandidates, inputTagPFCandidateElectrons_, iEvent);
0472
0473 unsigned ncand = (status) ? pfCandidates->size() : 0;
0474 for (unsigned i = 0; i < ncand; ++i) {
0475 const reco::PFCandidate& cand = (*pfCandidates)[i];
0476 if (cand.particleId() != reco::PFCandidate::e)
0477 continue;
0478 if (cand.gsfTrackRef().isNull())
0479 continue;
0480
0481 gsfMvaMap_[cand.gsfTrackRef()] = cand.mva_e_pi();
0482 }
0483
0484 edm::Handle<reco::GsfTrackCollection> gsfTracks;
0485 fetchGsfCollection(gsfTracks, inputTagGSFTracks_, iEvent);
0486 unsigned ngsf = gsfTracks->size();
0487 std::vector<float> values;
0488 for (unsigned igsf = 0; igsf < ngsf; ++igsf) {
0489 reco::GsfTrackRef theTrackRef(gsfTracks, igsf);
0490 std::map<reco::GsfTrackRef, float>::const_iterator itcheck = gsfMvaMap_.find(theTrackRef);
0491 if (itcheck == gsfMvaMap_.end()) {
0492
0493 values.push_back(-99.);
0494
0495 } else {
0496
0497 values.push_back(itcheck->second);
0498 }
0499 }
0500 filler.insert(gsfTracks, values.begin(), values.end());
0501 }
0502
0503 void PFElectronTranslator::fillSCRefValueMap(edm::Event& iEvent,
0504 edm::ValueMap<reco::SuperClusterRef>::Filler& filler) const {
0505 edm::Handle<reco::GsfTrackCollection> gsfTracks;
0506 fetchGsfCollection(gsfTracks, inputTagGSFTracks_, iEvent);
0507 unsigned ngsf = gsfTracks->size();
0508 std::vector<reco::SuperClusterRef> values;
0509 for (unsigned igsf = 0; igsf < ngsf; ++igsf) {
0510 reco::GsfTrackRef theTrackRef(gsfTracks, igsf);
0511 std::map<reco::GsfTrackRef, reco::SuperClusterRef>::const_iterator itcheck = scMap_.find(theTrackRef);
0512 if (itcheck == scMap_.end()) {
0513
0514 values.push_back(reco::SuperClusterRef());
0515 } else {
0516 values.push_back(itcheck->second);
0517 }
0518 }
0519 filler.insert(gsfTracks, values.begin(), values.end());
0520 }
0521
0522 void PFElectronTranslator::createSuperClusters(const reco::PFCandidateCollection& pfCand,
0523 reco::SuperClusterCollection& superClusters) const {
0524 unsigned nGSF = GsfTrackRef_.size();
0525 for (unsigned iGSF = 0; iGSF < nGSF; ++iGSF) {
0526
0527 double sclusterE = 0;
0528 double posX = 0.;
0529 double posY = 0.;
0530 double posZ = 0.;
0531
0532 unsigned nbasics = basicClusters_[iGSF].size();
0533 for (unsigned ibc = 0; ibc < nbasics; ++ibc) {
0534 double e = basicClusters_[iGSF][ibc].energy();
0535 sclusterE += e;
0536 posX += e * basicClusters_[iGSF][ibc].position().X();
0537 posY += e * basicClusters_[iGSF][ibc].position().Y();
0538 posZ += e * basicClusters_[iGSF][ibc].position().Z();
0539 }
0540 posX /= sclusterE;
0541 posY /= sclusterE;
0542 posZ /= sclusterE;
0543
0544 if (pfCand[gsfPFCandidateIndex_[iGSF]].gsfTrackRef() != GsfTrackRef_[iGSF]) {
0545 edm::LogError("PFElectronTranslator") << " Major problem in PFElectron Translator" << std::endl;
0546 }
0547
0548
0549 PFClusterWidthAlgo pfwidth(pfClusters_[iGSF]);
0550
0551 double correctedEnergy = pfCand[gsfPFCandidateIndex_[iGSF]].ecalEnergy();
0552 reco::SuperCluster mySuperCluster(correctedEnergy, math::XYZPoint(posX, posY, posZ));
0553
0554 if (nbasics) {
0555
0556
0557
0558 mySuperCluster.setSeed(basicClusterPtr_[iGSF][0]);
0559 } else {
0560
0561
0562
0563
0564
0565 mySuperCluster.setSeed(reco::CaloClusterPtr());
0566 }
0567
0568
0569 for (unsigned ibc = 0; ibc < nbasics; ++ibc) {
0570 mySuperCluster.addCluster(basicClusterPtr_[iGSF][ibc]);
0571
0572 const std::vector<std::pair<DetId, float>>& v1 = basicClusters_[iGSF][ibc].hitsAndFractions();
0573
0574 for (std::vector<std::pair<DetId, float>>::const_iterator diIt = v1.begin(); diIt != v1.end(); ++diIt) {
0575
0576 mySuperCluster.addHitAndFraction(diIt->first, diIt->second);
0577 }
0578 }
0579
0580 unsigned nps = preshowerClusterPtr_[iGSF].size();
0581 for (unsigned ips = 0; ips < nps; ++ips) {
0582 mySuperCluster.addPreshowerCluster(preshowerClusterPtr_[iGSF][ips]);
0583 }
0584
0585
0586 mySuperCluster.setPreshowerEnergy(pfCand[gsfPFCandidateIndex_[iGSF]].pS1Energy() +
0587 pfCand[gsfPFCandidateIndex_[iGSF]].pS2Energy());
0588
0589
0590 mySuperCluster.setEtaWidth(pfwidth.pflowEtaWidth());
0591 mySuperCluster.setPhiWidth(pfwidth.pflowPhiWidth());
0592
0593 mySuperCluster.rawEnergy();
0594 superClusters.push_back(mySuperCluster);
0595 }
0596 }
0597
0598 const reco::PFCandidate& PFElectronTranslator::correspondingDaughterCandidate(const reco::PFCandidate& cand,
0599 const reco::PFBlockElement& pfbe) const {
0600 unsigned refindex = pfbe.index();
0601
0602 reco::PFCandidate::const_iterator myDaughterCandidate = cand.begin();
0603 reco::PFCandidate::const_iterator itend = cand.end();
0604
0605 for (; myDaughterCandidate != itend; ++myDaughterCandidate) {
0606 const reco::PFCandidate* myPFCandidate = (const reco::PFCandidate*)&*myDaughterCandidate;
0607 if (myPFCandidate->elementsInBlocks().size() != 1) {
0608
0609 return cand;
0610 }
0611 if (myPFCandidate->elementsInBlocks()[0].second == refindex) {
0612
0613 return *myPFCandidate;
0614 }
0615 }
0616 return cand;
0617 }
0618
0619 void PFElectronTranslator::createGsfElectronCores(reco::GsfElectronCoreCollection& gsfElectronCores) const {
0620 unsigned nGSF = GsfTrackRef_.size();
0621 for (unsigned iGSF = 0; iGSF < nGSF; ++iGSF) {
0622 reco::GsfElectronCore myElectronCore(GsfTrackRef_[iGSF]);
0623 myElectronCore.setCtfTrack(kfTrackRef_[iGSF], -1.);
0624 std::map<reco::GsfTrackRef, reco::SuperClusterRef>::const_iterator itcheck = scMap_.find(GsfTrackRef_[iGSF]);
0625 if (itcheck != scMap_.end())
0626 myElectronCore.setParentSuperCluster(itcheck->second);
0627 gsfElectronCores.push_back(myElectronCore);
0628 }
0629 }
0630
0631 void PFElectronTranslator::createGsfElectronCoreRefs(
0632 const edm::OrphanHandle<reco::GsfElectronCoreCollection>& gsfElectronCoreHandle) {
0633 unsigned size = GsfTrackRef_.size();
0634
0635 for (unsigned iGSF = 0; iGSF < size; ++iGSF)
0636 {
0637 edm::Ref<reco::GsfElectronCoreCollection> elecCoreRef(gsfElectronCoreHandle, iGSF);
0638 gsfElectronCoreRefs_.push_back(elecCoreRef);
0639 }
0640 }
0641
0642 void PFElectronTranslator::getAmbiguousGsfTracks(const reco::PFBlockElement& PFBE,
0643 std::vector<reco::GsfTrackRef>& tracks) const {
0644 const reco::PFBlockElementGsfTrack* GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(&PFBE);
0645 if (GsfEl == nullptr)
0646 return;
0647 const std::vector<reco::GsfPFRecTrackRef>& ambPFRecTracks(GsfEl->GsftrackRefPF()->convBremGsfPFRecTrackRef());
0648 unsigned ntracks = ambPFRecTracks.size();
0649 for (unsigned it = 0; it < ntracks; ++it) {
0650 tracks.push_back(ambPFRecTracks[it]->gsfTrackRef());
0651 }
0652 }
0653
0654 void PFElectronTranslator::createGsfElectrons(const reco::PFCandidateCollection& pfcand,
0655 const IsolationValueMaps& isolationValues,
0656 reco::GsfElectronCollection& gsfelectrons) {
0657 unsigned size = GsfTrackRef_.size();
0658
0659 for (unsigned iGSF = 0; iGSF < size; ++iGSF)
0660 {
0661 const reco::PFCandidate& pfCandidate(pfcand[gsfPFCandidateIndex_[iGSF]]);
0662
0663 reco::GsfElectron myElectron(gsfElectronCoreRefs_[iGSF]);
0664
0665 myElectron.setP4(reco::GsfElectron::P4_PFLOW_COMBINATION, pfCandidate.p4(), pfCandidate.deltaP(), true);
0666
0667
0668 reco::GsfElectron::MvaInput myMvaInput;
0669 myMvaInput.earlyBrem = pfCandidate.electronExtraRef()->mvaVariable(reco::PFCandidateElectronExtra::MVA_FirstBrem);
0670 myMvaInput.lateBrem = pfCandidate.electronExtraRef()->mvaVariable(reco::PFCandidateElectronExtra::MVA_LateBrem);
0671 myMvaInput.deltaEta =
0672 pfCandidate.electronExtraRef()->mvaVariable(reco::PFCandidateElectronExtra::MVA_DeltaEtaTrackCluster);
0673 myMvaInput.sigmaEtaEta = pfCandidate.electronExtraRef()->sigmaEtaEta();
0674 myMvaInput.hadEnergy = pfCandidate.electronExtraRef()->hadEnergy();
0675
0676
0677 reco::Mustache myMustache(mustacheSCParams_);
0678 myMustache.MustacheID(
0679 *(myElectron.parentSuperCluster()), myMvaInput.nClusterOutsideMustache, myMvaInput.etOutsideMustache);
0680
0681 myElectron.setMvaInput(myMvaInput);
0682
0683
0684 reco::GsfElectron::MvaOutput myMvaOutput;
0685 myMvaOutput.status = pfCandidate.electronExtraRef()->electronStatus();
0686 myMvaOutput.mva_e_pi = pfCandidate.mva_e_pi();
0687 myElectron.setMvaOutput(myMvaOutput);
0688
0689
0690 unsigned ntracks = ambiguousGsfTracks_[iGSF].size();
0691 for (unsigned it = 0; it < ntracks; ++it) {
0692 myElectron.addAmbiguousGsfTrack(ambiguousGsfTracks_[iGSF][it]);
0693 }
0694
0695
0696 if (!isolationValues.empty()) {
0697 reco::GsfElectron::PflowIsolationVariables myPFIso;
0698 myPFIso.sumChargedHadronPt = (*isolationValues[0])[CandidatePtr_[iGSF]];
0699 myPFIso.sumPhotonEt = (*isolationValues[1])[CandidatePtr_[iGSF]];
0700 myPFIso.sumNeutralHadronEt = (*isolationValues[2])[CandidatePtr_[iGSF]];
0701 myPFIso.sumPUPt = (*isolationValues[3])[CandidatePtr_[iGSF]];
0702 myElectron.setPfIsolationVariables(myPFIso);
0703 }
0704
0705 gsfelectrons.push_back(myElectron);
0706 }
0707 }