File indexing completed on 2024-04-06 12:23:52
0001 #include <string>
0002
0003 #include "DataFormats/Candidate/interface/Candidate.h"
0004 #include "DataFormats/Common/interface/Association.h"
0005 #include "DataFormats/Common/interface/ValueMap.h"
0006 #include "DataFormats/Common/interface/View.h"
0007 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0008 #include "DataFormats/MuonReco/interface/Muon.h"
0009 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0010 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0011 #include "DataFormats/PatCandidates/interface/HcalDepthEnergyFractions.h"
0012 #include "DataFormats/PatCandidates/interface/Jet.h"
0013 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0014 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
0015 #include "DataFormats/VertexReco/interface/Vertex.h"
0016 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0017 #include "FWCore/Framework/interface/ESHandle.h"
0018 #include "FWCore/Framework/interface/Event.h"
0019 #include "FWCore/Framework/interface/EventSetup.h"
0020 #include "FWCore/Framework/interface/Frameworkfwd.h"
0021 #include "FWCore/Framework/interface/global/EDProducer.h"
0022 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0023 #include "FWCore/Utilities/interface/Exception.h"
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 namespace pat {
0036
0037 const static int qualityMap[8] = {1, 0, 1, 1, 4, 4, 5, 6};
0038
0039 class PATPackedCandidateProducer : public edm::global::EDProducer<> {
0040 public:
0041 explicit PATPackedCandidateProducer(const edm::ParameterSet &);
0042 ~PATPackedCandidateProducer() override;
0043
0044 void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override;
0045
0046
0047 static bool candsOrdering(pat::PackedCandidate const &i, pat::PackedCandidate const &j) {
0048 if (std::abs(i.charge()) == std::abs(j.charge())) {
0049 if (i.charge() != 0) {
0050 if (i.hasTrackDetails() and !j.hasTrackDetails())
0051 return true;
0052 if (!i.hasTrackDetails() and j.hasTrackDetails())
0053 return false;
0054 if (i.covarianceSchema() > j.covarianceSchema())
0055 return true;
0056 if (i.covarianceSchema() < j.covarianceSchema())
0057 return false;
0058 }
0059 if (i.vertexRef() == j.vertexRef())
0060 return i.eta() > j.eta();
0061 else
0062 return i.vertexRef().key() < j.vertexRef().key();
0063 }
0064 return std::abs(i.charge()) > std::abs(j.charge());
0065 }
0066
0067 template <typename T>
0068 static std::vector<size_t> sort_indexes(const std::vector<T> &v) {
0069 std::vector<size_t> idx(v.size());
0070 for (size_t i = 0; i != idx.size(); ++i)
0071 idx[i] = i;
0072 std::sort(idx.begin(), idx.end(), [&v](size_t i1, size_t i2) { return candsOrdering(v[i1], v[i2]); });
0073 return idx;
0074 }
0075
0076 private:
0077
0078
0079
0080 const bool usePuppi_;
0081
0082 const edm::EDGetTokenT<reco::PFCandidateCollection> Cands_;
0083 const edm::EDGetTokenT<reco::VertexCollection> PVs_;
0084 const edm::EDGetTokenT<edm::Association<reco::VertexCollection>> PVAsso_;
0085 const edm::EDGetTokenT<edm::ValueMap<int>> PVAssoQuality_;
0086 const edm::EDGetTokenT<reco::VertexCollection> PVOrigs_;
0087 const edm::EDGetTokenT<reco::TrackCollection> TKOrigs_;
0088 const edm::EDGetTokenT<edm::ValueMap<float>> PuppiWeight_;
0089 const edm::EDGetTokenT<edm::ValueMap<float>> PuppiWeightNoLep_;
0090 std::vector<edm::EDGetTokenT<edm::View<reco::Candidate>>> SVWhiteLists_;
0091 const bool storeChargedHadronIsolation_;
0092 const edm::EDGetTokenT<edm::ValueMap<bool>> ChargedHadronIsolation_;
0093
0094 const double minPtForChargedHadronProperties_;
0095 const double minPtForTrackProperties_;
0096 const double minPtForLowQualityTrackProperties_;
0097 const int covarianceVersion_;
0098 const std::vector<int> covariancePackingSchemas_;
0099
0100 const std::vector<int> pfCandidateTypesForHcalDepth_;
0101 const bool storeHcalDepthEndcapOnly_;
0102
0103 const bool storeTiming_;
0104 const bool timeFromValueMap_;
0105 const edm::EDGetTokenT<edm::ValueMap<float>> t0Map_;
0106 const edm::EDGetTokenT<edm::ValueMap<float>> t0ErrMap_;
0107
0108
0109 float calcDxy(float dx, float dy, float phi) const { return -dx * std::sin(phi) + dy * std::cos(phi); }
0110 float calcDz(reco::Candidate::Point p, reco::Candidate::Point v, const reco::Candidate &c) const {
0111 return p.Z() - v.Z() - ((p.X() - v.X()) * c.px() + (p.Y() - v.Y()) * c.py()) * c.pz() / (c.pt() * c.pt());
0112 }
0113 };
0114 }
0115
0116 pat::PATPackedCandidateProducer::PATPackedCandidateProducer(const edm::ParameterSet &iConfig)
0117 : usePuppi_(!iConfig.getParameter<edm::InputTag>("PuppiSrc").encode().empty() ||
0118 !iConfig.getParameter<edm::InputTag>("PuppiNoLepSrc").encode().empty()),
0119 Cands_(consumes<reco::PFCandidateCollection>(iConfig.getParameter<edm::InputTag>("inputCollection"))),
0120 PVs_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("inputVertices"))),
0121 PVAsso_(
0122 consumes<edm::Association<reco::VertexCollection>>(iConfig.getParameter<edm::InputTag>("vertexAssociator"))),
0123 PVAssoQuality_(consumes<edm::ValueMap<int>>(iConfig.getParameter<edm::InputTag>("vertexAssociator"))),
0124 PVOrigs_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("originalVertices"))),
0125 TKOrigs_(consumes<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("originalTracks"))),
0126 PuppiWeight_(usePuppi_ ? consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("PuppiSrc"))
0127 : edm::EDGetTokenT<edm::ValueMap<float>>()),
0128 PuppiWeightNoLep_(usePuppi_ ? consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("PuppiNoLepSrc"))
0129 : edm::EDGetTokenT<edm::ValueMap<float>>()),
0130 storeChargedHadronIsolation_(!iConfig.getParameter<edm::InputTag>("chargedHadronIsolation").encode().empty()),
0131 ChargedHadronIsolation_(
0132 consumes<edm::ValueMap<bool>>(iConfig.getParameter<edm::InputTag>("chargedHadronIsolation"))),
0133 minPtForChargedHadronProperties_(iConfig.getParameter<double>("minPtForChargedHadronProperties")),
0134 minPtForTrackProperties_(iConfig.getParameter<double>("minPtForTrackProperties")),
0135 minPtForLowQualityTrackProperties_(iConfig.getParameter<double>("minPtForLowQualityTrackProperties")),
0136 covarianceVersion_(iConfig.getParameter<int>("covarianceVersion")),
0137 covariancePackingSchemas_(iConfig.getParameter<std::vector<int>>("covariancePackingSchemas")),
0138 pfCandidateTypesForHcalDepth_(iConfig.getParameter<std::vector<int>>("pfCandidateTypesForHcalDepth")),
0139 storeHcalDepthEndcapOnly_(iConfig.getParameter<bool>("storeHcalDepthEndcapOnly")),
0140 storeTiming_(iConfig.getParameter<bool>("storeTiming")),
0141 timeFromValueMap_(!iConfig.getParameter<edm::InputTag>("timeMap").encode().empty() &&
0142 !iConfig.getParameter<edm::InputTag>("timeMapErr").encode().empty()),
0143 t0Map_(timeFromValueMap_ ? consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("timeMap"))
0144 : edm::EDGetTokenT<edm::ValueMap<float>>()),
0145 t0ErrMap_(timeFromValueMap_ ? consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("timeMapErr"))
0146 : edm::EDGetTokenT<edm::ValueMap<float>>()) {
0147 std::vector<edm::InputTag> sv_tags =
0148 iConfig.getParameter<std::vector<edm::InputTag>>("secondaryVerticesForWhiteList");
0149 for (const auto &itag : sv_tags) {
0150 SVWhiteLists_.push_back(consumes<edm::View<reco::Candidate>>(itag));
0151 }
0152
0153 produces<std::vector<pat::PackedCandidate>>();
0154 produces<edm::Association<pat::PackedCandidateCollection>>();
0155 produces<edm::Association<reco::PFCandidateCollection>>();
0156
0157 if (not pfCandidateTypesForHcalDepth_.empty())
0158 produces<edm::ValueMap<pat::HcalDepthEnergyFractions>>("hcalDepthEnergyFractions");
0159 }
0160
0161 pat::PATPackedCandidateProducer::~PATPackedCandidateProducer() {}
0162
0163 void pat::PATPackedCandidateProducer::produce(edm::StreamID, edm::Event &iEvent, const edm::EventSetup &iSetup) const {
0164 edm::Handle<reco::PFCandidateCollection> cands;
0165 iEvent.getByToken(Cands_, cands);
0166
0167 edm::Handle<edm::ValueMap<float>> puppiWeight;
0168 edm::Handle<edm::ValueMap<float>> puppiWeightNoLep;
0169 if (usePuppi_) {
0170 iEvent.getByToken(PuppiWeight_, puppiWeight);
0171 iEvent.getByToken(PuppiWeightNoLep_, puppiWeightNoLep);
0172 }
0173
0174 edm::Handle<reco::VertexCollection> PVOrigs;
0175 iEvent.getByToken(PVOrigs_, PVOrigs);
0176
0177 edm::Handle<edm::Association<reco::VertexCollection>> assoHandle;
0178 iEvent.getByToken(PVAsso_, assoHandle);
0179 edm::Handle<edm::ValueMap<int>> assoQualityHandle;
0180 iEvent.getByToken(PVAssoQuality_, assoQualityHandle);
0181 const edm::Association<reco::VertexCollection> &associatedPV = *(assoHandle.product());
0182 const edm::ValueMap<int> &associationQuality = *(assoQualityHandle.product());
0183
0184 edm::Handle<edm::ValueMap<bool>> chargedHadronIsolationHandle;
0185 if (storeChargedHadronIsolation_)
0186 iEvent.getByToken(ChargedHadronIsolation_, chargedHadronIsolationHandle);
0187
0188 std::set<unsigned int> whiteList;
0189 std::set<reco::TrackRef> whiteListTk;
0190 for (auto itoken : SVWhiteLists_) {
0191 edm::Handle<edm::View<reco::Candidate>> svWhiteListHandle;
0192 iEvent.getByToken(itoken, svWhiteListHandle);
0193 const edm::View<reco::Candidate> &svWhiteList = *(svWhiteListHandle.product());
0194 for (unsigned int i = 0; i < svWhiteList.size(); i++) {
0195
0196 for (unsigned int j = 0; j < svWhiteList[i].numberOfSourceCandidatePtrs(); j++) {
0197 const edm::Ptr<reco::Candidate> &c = svWhiteList[i].sourceCandidatePtr(j);
0198 if (c.id() == cands.id())
0199 whiteList.insert(c.key());
0200 }
0201
0202 for (auto dau = svWhiteList[i].begin(); dau != svWhiteList[i].end(); dau++) {
0203 const reco::RecoChargedCandidate *chCand = dynamic_cast<const reco::RecoChargedCandidate *>(&(*dau));
0204 if (chCand != nullptr) {
0205 whiteListTk.insert(chCand->track());
0206 }
0207 }
0208 }
0209 }
0210
0211 edm::Handle<edm::ValueMap<float>> t0Map;
0212 edm::Handle<edm::ValueMap<float>> t0ErrMap;
0213 if (timeFromValueMap_) {
0214 iEvent.getByToken(t0Map_, t0Map);
0215 iEvent.getByToken(t0ErrMap_, t0ErrMap);
0216 }
0217
0218 edm::Handle<reco::VertexCollection> PVs;
0219 iEvent.getByToken(PVs_, PVs);
0220 reco::VertexRef PV(PVs.id());
0221 reco::VertexRefProd PVRefProd(PVs);
0222 math::XYZPoint PVpos;
0223
0224 std::vector<pat::HcalDepthEnergyFractions> hcalDepthEnergyFractions;
0225 hcalDepthEnergyFractions.reserve(cands->size());
0226 std::vector<pat::HcalDepthEnergyFractions> hcalDepthEnergyFractions_Ordered;
0227 hcalDepthEnergyFractions_Ordered.reserve(cands->size());
0228
0229 edm::Handle<reco::TrackCollection> TKOrigs;
0230 iEvent.getByToken(TKOrigs_, TKOrigs);
0231 auto outPtrP = std::make_unique<std::vector<pat::PackedCandidate>>();
0232 std::vector<int> mapping(cands->size());
0233 std::vector<int> mappingReverse(cands->size());
0234 std::vector<int> mappingTk(TKOrigs->size(), -1);
0235
0236 for (unsigned int ic = 0, nc = cands->size(); ic < nc; ++ic) {
0237 const reco::PFCandidate &cand = (*cands)[ic];
0238 const reco::Track *ctrack = nullptr;
0239 if ((abs(cand.pdgId()) == 11 || cand.pdgId() == 22) && cand.gsfTrackRef().isNonnull()) {
0240 ctrack = &*cand.gsfTrackRef();
0241 } else if (cand.trackRef().isNonnull()) {
0242 ctrack = &*cand.trackRef();
0243 }
0244 if (ctrack) {
0245 float dist = 1e99;
0246 int pvi = -1;
0247 for (size_t ii = 0; ii < PVs->size(); ii++) {
0248 float dz = std::abs(ctrack->dz(((*PVs)[ii]).position()));
0249 if (dz < dist) {
0250 pvi = ii;
0251 dist = dz;
0252 }
0253 }
0254 PV = reco::VertexRef(PVs, pvi);
0255 math::XYZPoint vtx = cand.vertex();
0256 pat::PackedCandidate::LostInnerHits lostHits = pat::PackedCandidate::noLostInnerHits;
0257 const reco::VertexRef &PVOrig = associatedPV[reco::CandidatePtr(cands, ic)];
0258 if (PVOrig.isNonnull())
0259 PV = reco::VertexRef(PVs,
0260 PVOrig.key());
0261 int quality = associationQuality[reco::CandidatePtr(cands, ic)];
0262
0263
0264
0265
0266
0267
0268
0269 vtx = ctrack->referencePoint();
0270 float ptTrk = ctrack->pt();
0271 float etaAtVtx = ctrack->eta();
0272 float phiAtVtx = ctrack->phi();
0273
0274 int nlost = ctrack->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS);
0275 if (nlost == 0) {
0276 if (ctrack->hitPattern().hasValidHitInPixelLayer(PixelSubdetector::SubDetector::PixelBarrel, 1)) {
0277 lostHits = pat::PackedCandidate::validHitInFirstPixelBarrelLayer;
0278 }
0279 } else {
0280 lostHits = (nlost == 1 ? pat::PackedCandidate::oneLostInnerHit : pat::PackedCandidate::moreLostInnerHits);
0281 }
0282
0283 outPtrP->push_back(
0284 pat::PackedCandidate(cand.polarP4(), vtx, ptTrk, etaAtVtx, phiAtVtx, cand.pdgId(), PVRefProd, PV.key()));
0285 outPtrP->back().setAssociationQuality(pat::PackedCandidate::PVAssociationQuality(qualityMap[quality]));
0286 outPtrP->back().setCovarianceVersion(covarianceVersion_);
0287 if (cand.trackRef().isNonnull() && PVOrig.isNonnull() && PVOrig->trackWeight(cand.trackRef()) > 0.5 &&
0288 quality == 7) {
0289 outPtrP->back().setAssociationQuality(pat::PackedCandidate::UsedInFitTight);
0290 }
0291
0292 outPtrP->back().setLostInnerHits(lostHits);
0293 if (outPtrP->back().pt() > minPtForTrackProperties_ || outPtrP->back().ptTrk() > minPtForTrackProperties_ ||
0294 whiteList.find(ic) != whiteList.end() ||
0295 (cand.trackRef().isNonnull() && whiteListTk.find(cand.trackRef()) != whiteListTk.end())) {
0296 outPtrP->back().setTrkAlgo(static_cast<uint8_t>(ctrack->algo()), static_cast<uint8_t>(ctrack->originalAlgo()));
0297 outPtrP->back().setFirstHit(ctrack->hitPattern().getHitPattern(reco::HitPattern::TRACK_HITS, 0));
0298 if (abs(outPtrP->back().pdgId()) == 22) {
0299 outPtrP->back().setTrackProperties(*ctrack, covariancePackingSchemas_[4], covarianceVersion_);
0300 } else {
0301 if (ctrack->hitPattern().numberOfValidPixelHits() > 0) {
0302 outPtrP->back().setTrackProperties(*ctrack,
0303 covariancePackingSchemas_[0],
0304 covarianceVersion_);
0305 } else {
0306 outPtrP->back().setTrackProperties(*ctrack, covariancePackingSchemas_[1], covarianceVersion_);
0307 }
0308 }
0309
0310 } else {
0311 if (outPtrP->back().pt() > minPtForLowQualityTrackProperties_) {
0312 if (ctrack->hitPattern().numberOfValidPixelHits() > 0)
0313 outPtrP->back().setTrackProperties(*ctrack,
0314 covariancePackingSchemas_[2],
0315 covarianceVersion_);
0316 else
0317 outPtrP->back().setTrackProperties(*ctrack,
0318 covariancePackingSchemas_[3],
0319 covarianceVersion_);
0320 }
0321 }
0322
0323
0324 outPtrP->back().setTrackHighPurity(cand.trackRef().isNonnull() &&
0325 cand.trackRef()->quality(reco::Track::highPurity));
0326 if (cand.muonRef().isNonnull()) {
0327 outPtrP->back().setMuonID(cand.muonRef()->isStandAloneMuon(), cand.muonRef()->isGlobalMuon());
0328 }
0329 } else {
0330 if (!PVs->empty()) {
0331 PV = reco::VertexRef(PVs, 0);
0332 PVpos = PV->position();
0333 }
0334
0335 outPtrP->push_back(pat::PackedCandidate(
0336 cand.polarP4(), PVpos, cand.pt(), cand.eta(), cand.phi(), cand.pdgId(), PVRefProd, PV.key()));
0337 outPtrP->back().setAssociationQuality(
0338 pat::PackedCandidate::PVAssociationQuality(pat::PackedCandidate::UsedInFitTight));
0339 }
0340
0341
0342
0343 bool isIsolatedChargedHadron = false;
0344 if (storeChargedHadronIsolation_) {
0345 const edm::ValueMap<bool> &chargedHadronIsolation = *(chargedHadronIsolationHandle.product());
0346 isIsolatedChargedHadron =
0347 ((cand.pt() > minPtForChargedHadronProperties_) && (chargedHadronIsolation[reco::PFCandidateRef(cands, ic)]));
0348 outPtrP->back().setIsIsolatedChargedHadron(isIsolatedChargedHadron);
0349 }
0350
0351 if (abs(cand.pdgId()) == 1 || abs(cand.pdgId()) == 130) {
0352 outPtrP->back().setHcalFraction(cand.hcalEnergy() / (cand.ecalEnergy() + cand.hcalEnergy()));
0353 } else if ((cand.charge() || abs(cand.pdgId()) == 22) && cand.pt() > 0.5) {
0354 outPtrP->back().setHcalFraction(cand.hcalEnergy() / (cand.ecalEnergy() + cand.hcalEnergy()));
0355 outPtrP->back().setCaloFraction((cand.hcalEnergy() + cand.ecalEnergy()) / cand.energy());
0356 } else {
0357 outPtrP->back().setHcalFraction(0);
0358 outPtrP->back().setCaloFraction(0);
0359 }
0360
0361 if (isIsolatedChargedHadron) {
0362 outPtrP->back().setRawCaloFraction((cand.rawEcalEnergy() + cand.rawHcalEnergy()) / cand.energy());
0363 outPtrP->back().setRawHcalFraction(cand.rawHcalEnergy() / (cand.rawEcalEnergy() + cand.rawHcalEnergy()));
0364 } else {
0365 outPtrP->back().setRawCaloFraction(0);
0366 outPtrP->back().setRawHcalFraction(0);
0367 }
0368
0369 std::vector<float> dummyVector;
0370 dummyVector.clear();
0371 pat::HcalDepthEnergyFractions hcalDepthEFrac(dummyVector);
0372
0373
0374 if (std::find(pfCandidateTypesForHcalDepth_.begin(), pfCandidateTypesForHcalDepth_.end(), abs(cand.pdgId())) !=
0375 pfCandidateTypesForHcalDepth_.end()) {
0376 if (!storeHcalDepthEndcapOnly_ ||
0377 fabs(outPtrP->back().eta()) > 1.3) {
0378
0379
0380 std::vector<float> hcalDepthEnergyFractionTmp(cand.hcalDepthEnergyFractions().begin(),
0381 cand.hcalDepthEnergyFractions().end());
0382 hcalDepthEFrac.reset(hcalDepthEnergyFractionTmp);
0383 }
0384 }
0385 hcalDepthEnergyFractions.push_back(hcalDepthEFrac);
0386
0387
0388
0389 if (cand.particleId() == reco::PFCandidate::e ||
0390 (cand.particleId() == reco::PFCandidate::gamma && cand.mva_nothing_gamma() > 0.)) {
0391 outPtrP->back().setGoodEgamma();
0392 }
0393
0394 if (usePuppi_) {
0395 reco::PFCandidateRef pkref(cands, ic);
0396
0397 float puppiWeightVal = (*puppiWeight)[pkref];
0398 float puppiWeightNoLepVal = (*puppiWeightNoLep)[pkref];
0399 outPtrP->back().setPuppiWeight(puppiWeightVal, puppiWeightNoLepVal);
0400 }
0401
0402 if (storeTiming_) {
0403 if (timeFromValueMap_) {
0404 if (cand.trackRef().isNonnull()) {
0405 auto t0 = (*t0Map)[cand.trackRef()];
0406 auto t0Err = (*t0ErrMap)[cand.trackRef()];
0407 outPtrP->back().setTime(t0, t0Err);
0408 }
0409 } else {
0410 if (cand.isTimeValid()) {
0411 outPtrP->back().setTime(cand.time(), cand.timeError());
0412 }
0413 }
0414 }
0415
0416 mapping[ic] = ic;
0417 if (cand.trackRef().isNonnull() && cand.trackRef().id() == TKOrigs.id()) {
0418 mappingTk[cand.trackRef().key()] = ic;
0419 }
0420 }
0421
0422 auto outPtrPSorted = std::make_unique<std::vector<pat::PackedCandidate>>();
0423 std::vector<size_t> order = sort_indexes(*outPtrP);
0424 std::vector<size_t> reverseOrder(order.size());
0425 for (size_t i = 0, nc = cands->size(); i < nc; i++) {
0426 outPtrPSorted->push_back((*outPtrP)[order[i]]);
0427 reverseOrder[order[i]] = i;
0428 mappingReverse[order[i]] = i;
0429 hcalDepthEnergyFractions_Ordered.push_back(hcalDepthEnergyFractions[order[i]]);
0430 }
0431
0432
0433 for (size_t i = 0, ntk = mappingTk.size(); i < ntk; i++) {
0434 if (mappingTk[i] >= 0)
0435 mappingTk[i] = reverseOrder[mappingTk[i]];
0436 }
0437
0438 edm::OrphanHandle<pat::PackedCandidateCollection> oh = iEvent.put(std::move(outPtrPSorted));
0439
0440
0441 auto pf2pc = std::make_unique<edm::Association<pat::PackedCandidateCollection>>(oh);
0442 auto pc2pf = std::make_unique<edm::Association<reco::PFCandidateCollection>>(cands);
0443 edm::Association<pat::PackedCandidateCollection>::Filler pf2pcFiller(*pf2pc);
0444 edm::Association<reco::PFCandidateCollection>::Filler pc2pfFiller(*pc2pf);
0445 pf2pcFiller.insert(cands, mappingReverse.begin(), mappingReverse.end());
0446 pc2pfFiller.insert(oh, order.begin(), order.end());
0447
0448 pf2pcFiller.insert(TKOrigs, mappingTk.begin(), mappingTk.end());
0449
0450 pf2pcFiller.fill();
0451 pc2pfFiller.fill();
0452 iEvent.put(std::move(pf2pc));
0453 iEvent.put(std::move(pc2pf));
0454
0455
0456 auto hcalDepthEnergyFractionsV = std::make_unique<edm::ValueMap<HcalDepthEnergyFractions>>();
0457 edm::ValueMap<HcalDepthEnergyFractions>::Filler fillerHcalDepthEnergyFractions(*hcalDepthEnergyFractionsV);
0458 fillerHcalDepthEnergyFractions.insert(
0459 cands, hcalDepthEnergyFractions_Ordered.begin(), hcalDepthEnergyFractions_Ordered.end());
0460 fillerHcalDepthEnergyFractions.fill();
0461
0462 if (not pfCandidateTypesForHcalDepth_.empty())
0463 iEvent.put(std::move(hcalDepthEnergyFractionsV), "hcalDepthEnergyFractions");
0464 }
0465
0466 using pat::PATPackedCandidateProducer;
0467 #include "FWCore/Framework/interface/MakerMacros.h"
0468 DEFINE_FWK_MODULE(PATPackedCandidateProducer);