From 3ac8d8509b2e0c4205a7d556e1145c99a65ba6c2 Mon Sep 17 00:00:00 2001 From: Sifu Luo Date: Fri, 11 Mar 2022 19:04:50 +0100 Subject: [PATCH 1/4] Make both ME1a and ME1b LCT (A/CLCT) sorted into ring 1. --- Validation/MuonCSCDigis/src/CSCStubMatcher.cc | 47 ++++++++++++------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/Validation/MuonCSCDigis/src/CSCStubMatcher.cc b/Validation/MuonCSCDigis/src/CSCStubMatcher.cc index 2bbe013a2b391..457ecc42eb3b4 100644 --- a/Validation/MuonCSCDigis/src/CSCStubMatcher.cc +++ b/Validation/MuonCSCDigis/src/CSCStubMatcher.cc @@ -141,6 +141,7 @@ void CSCStubMatcher::matchCLCTsToSimTrack(const CSCCLCTDigiCollection& clcts) { if (isME1a) ring = 1; CSCDetId ch_id2(ch_id.endcap(), ch_id.station(), ring, ch_id.chamber(), 0); + auto id2 = ch_id2.rawId(); // CLCTs should be sorted into the det of the CLCTs. const auto& clcts_in_det = clcts.get(ch_id2); @@ -156,7 +157,7 @@ void CSCStubMatcher::matchCLCTsToSimTrack(const CSCCLCTDigiCollection& clcts) { continue; // store all CLCTs in this chamber - chamber_to_clcts_all_[id].push_back(*c); + chamber_to_clcts_all_[id2].push_back(*c); // check that at least 3 comparator digis were matched! int nMatches = 0; @@ -190,13 +191,14 @@ void CSCStubMatcher::matchCLCTsToSimTrack(const CSCCLCTDigiCollection& clcts) { edm::LogInfo("CSCStubMatcher") << "clctGOOD"; // store matching CLCTs in this chamber - if (std::find(chamber_to_clcts_[id].begin(), chamber_to_clcts_[id].end(), *c) == chamber_to_clcts_[id].end()) { - chamber_to_clcts_[id].push_back(*c); + if (std::find(chamber_to_clcts_[id2].begin(), chamber_to_clcts_[id2].end(), *c) == chamber_to_clcts_[id2].end()) { + chamber_to_clcts_[id2].push_back(*c); } } - if (chamber_to_clcts_[id].size() > 2) { - edm::LogInfo("CSCStubMatcher") << "WARNING!!! too many CLCTs " << chamber_to_clcts_[id].size() << " in " << ch_id; - for (auto& c : chamber_to_clcts_[id]) + if (chamber_to_clcts_[id2].size() > 2) { + edm::LogInfo("CSCStubMatcher") << "WARNING!!! too many CLCTs " << chamber_to_clcts_[id2].size() << " in " + << ch_id2; + for (auto& c : chamber_to_clcts_[id2]) edm::LogInfo("CSCStubMatcher") << " " << c; } } @@ -220,8 +222,9 @@ void CSCStubMatcher::matchALCTsToSimTrack(const CSCALCTDigiCollection& alcts) { int ring = ch_id.ring(); if (ring == 4) - ring = 1; //use ME1b id to get CLCTs + ring = 1; //use ME1b id to get ALCTs CSCDetId ch_id2(ch_id.endcap(), ch_id.station(), ring, ch_id.chamber(), 0); + auto id2 = ch_id2.rawId(); // ALCTs should be sorted into the det of the ALCTs. const auto& alcts_in_det = alcts.get(ch_id2); for (auto a = alcts_in_det.first; a != alcts_in_det.second; ++a) { @@ -238,7 +241,7 @@ void CSCStubMatcher::matchALCTsToSimTrack(const CSCALCTDigiCollection& alcts) { int wg = a->getKeyWG() + 1; // as ALCT wiregroups numbers start from 0 // store all ALCTs in this chamber - chamber_to_alcts_all_[id].push_back(*a); + chamber_to_alcts_all_[id2].push_back(*a); // match by wiregroup with the digis if (digi_wgs.find(wg) == digi_wgs.end()) { @@ -248,13 +251,14 @@ void CSCStubMatcher::matchALCTsToSimTrack(const CSCALCTDigiCollection& alcts) { edm::LogInfo("CSCStubMatcher") << "alctGOOD"; // store matching ALCTs in this chamber - if (std::find(chamber_to_alcts_[id].begin(), chamber_to_alcts_[id].end(), *a) == chamber_to_alcts_[id].end()) { - chamber_to_alcts_[id].push_back(*a); + if (std::find(chamber_to_alcts_[id2].begin(), chamber_to_alcts_[id2].end(), *a) == chamber_to_alcts_[id2].end()) { + chamber_to_alcts_[id2].push_back(*a); } } - if (chamber_to_alcts_[id].size() > 2) { - edm::LogInfo("CSCStubMatcher") << "WARNING!!! too many ALCTs " << chamber_to_alcts_[id].size() << " in " << ch_id; - for (auto& a : chamber_to_alcts_[id]) + if (chamber_to_alcts_[id2].size() > 2) { + edm::LogInfo("CSCStubMatcher") << "WARNING!!! too many ALCTs " << chamber_to_alcts_[id2].size() << " in " + << ch_id; + for (auto& a : chamber_to_alcts_[id2]) edm::LogInfo("CSCStubMatcher") << " " << a; } } @@ -282,6 +286,7 @@ void CSCStubMatcher::matchLCTsToSimTrack(const CSCCorrelatedLCTDigiCollection& l if (ring == 4) ring = 1; CSCDetId ch_id2(ch_id.endcap(), ch_id.station(), ring, ch_id.chamber(), 0); + auto id2 = ch_id2.rawId(); // LCTs should be sorted into the det of the LCTs. const auto& lcts_in_det = lcts.get(ch_id2); @@ -377,8 +382,8 @@ void CSCStubMatcher::matchLCTsToSimTrack(const CSCCorrelatedLCTDigiCollection& l if (lct_matched) { if (verboseLCT_) edm::LogInfo("CSCStubMatcher") << "...was matched"; - if (std::find(chamber_to_lcts_[id].begin(), chamber_to_lcts_[id].end(), lct) == chamber_to_lcts_[id].end()) { - chamber_to_lcts_[id].emplace_back(lct); + if (std::find(chamber_to_lcts_[id2].begin(), chamber_to_lcts_[id2].end(), lct) == chamber_to_lcts_[id2].end()) { + chamber_to_lcts_[id2].emplace_back(lct); } } } // lct loop over @@ -643,9 +648,15 @@ GlobalPoint CSCStubMatcher::getGlobalPosition(unsigned int rawId, const CSCCorre CSCDetId cscId(rawId); CSCDetId keyId(cscId.endcap(), cscId.station(), cscId.ring(), cscId.chamber(), CSCConstants::KEY_CLCT_LAYER); float fractional_strip = lct.getFractionalStrip(); - // case ME1/a - if (cscId.station() == 1 and cscId.ring() == 4 and lct.getStrip() > CSCConstants::MAX_HALF_STRIP_ME1B) { - fractional_strip -= CSCConstants::NUM_STRIPS_ME1B; + // case ME1/1 + if (cscId.station() == 1 and (cscId.ring() == 4 || cscId.ring() == 1)) { + int ring = 1; // Default to ME1/b + if (lct.getStrip() > CSCConstants::MAX_HALF_STRIP_ME1B) { + ring = 4; // Change to ME1/a if the HalfStrip Number exceeds the range of ME1/b + fractional_strip -= CSCConstants::NUM_STRIPS_ME1B; + } + CSCDetId cscId_(cscId.endcap(), cscId.station(), ring, cscId.chamber(), cscId.layer()); + cscId = cscId_; } // regular cases const auto& chamber = cscGeometry_->chamber(cscId); From d02578ea5d1b8d3c95de48bd88f3192a9dccedfb Mon Sep 17 00:00:00 2001 From: mmusich Date: Fri, 11 Mar 2022 14:11:40 +0100 Subject: [PATCH 2/4] introduce real data unit test for pede --- .../test/BuildFile.xml | 5 + .../test/TestDriver.cpp | 2 + .../test/test_pede.py | 100 ++++++++++++++++++ .../test/test_pede.sh | 32 ++++++ 4 files changed, 139 insertions(+) create mode 100644 Alignment/MillePedeAlignmentAlgorithm/test/TestDriver.cpp create mode 100644 Alignment/MillePedeAlignmentAlgorithm/test/test_pede.py create mode 100755 Alignment/MillePedeAlignmentAlgorithm/test/test_pede.sh diff --git a/Alignment/MillePedeAlignmentAlgorithm/test/BuildFile.xml b/Alignment/MillePedeAlignmentAlgorithm/test/BuildFile.xml index b5cf58f8993be..a6d954d927ad8 100644 --- a/Alignment/MillePedeAlignmentAlgorithm/test/BuildFile.xml +++ b/Alignment/MillePedeAlignmentAlgorithm/test/BuildFile.xml @@ -5,3 +5,8 @@ + + + + + diff --git a/Alignment/MillePedeAlignmentAlgorithm/test/TestDriver.cpp b/Alignment/MillePedeAlignmentAlgorithm/test/TestDriver.cpp new file mode 100644 index 0000000000000..2f0e0c40064da --- /dev/null +++ b/Alignment/MillePedeAlignmentAlgorithm/test/TestDriver.cpp @@ -0,0 +1,2 @@ +#include "FWCore/Utilities/interface/TestHelper.h" +RUNTEST() diff --git a/Alignment/MillePedeAlignmentAlgorithm/test/test_pede.py b/Alignment/MillePedeAlignmentAlgorithm/test/test_pede.py new file mode 100644 index 0000000000000..262094bf569a5 --- /dev/null +++ b/Alignment/MillePedeAlignmentAlgorithm/test/test_pede.py @@ -0,0 +1,100 @@ +import FWCore.ParameterSet.Config as cms +process = cms.Process("Alignment") + +process.Tracer = cms.Service("Tracer") + +setupGlobaltag = "121X_mcRun3_2021_realistic_forpp900GeV_v6" +setupCollection = "ALCARECOTkAlCosmicsCosmicTF0T" +setupCosmicsDecoMode = True +setupCosmicsZeroTesla = False +setupPrimaryWidth = -1.0 +setupJson = "placeholder_json" +setupRunStartGeometry = 1 +setupAlgoMode = "pede" +setupMonitorFile = "millePedeMonitorISN.root" +setupBinaryFile = "milleBinaryISN.dat" +readFiles = cms.untracked.vstring() + +import Alignment.MillePedeAlignmentAlgorithm.alignmentsetup.GeneralSetup as generalSetup +generalSetup.setup(process, setupGlobaltag, setupCosmicsZeroTesla) + + +################################################################################ +# setup alignment producer +################################################################################ +import Alignment.MillePedeAlignmentAlgorithm.alignmentsetup.ConfigureAlignmentProducer as confAliProducer + +confAliProducer.setConfiguration(process, + collection = setupCollection, + mode = setupAlgoMode, + monitorFile = setupMonitorFile, + binaryFile = setupBinaryFile, + primaryWidth = setupPrimaryWidth, + cosmicsZeroTesla = setupCosmicsZeroTesla) + + +################################################################################ +# Overwrite some conditions in global tag +################################################################################ +import Alignment.MillePedeAlignmentAlgorithm.alignmentsetup.SetCondition as tagwriter + +################################################################################ +# insert Startgeometry +################################################################################ +# You can use tagwriter.setCondition() to overwrite conditions in globaltag + +################################################################################ +# insert Alignables +################################################################################ +process.AlignmentProducer.ParameterBuilder.parameterTypes = ["SelectorRigid,RigidBody"] + +################################################################################ +# Define the high-level structure alignables +################################################################################ +process.AlignmentProducer.ParameterBuilder.SelectorRigid = cms.PSet( + alignParams = cms.vstring( + "TrackerP1PXBHalfBarrel,111111", + "TrackerP1PXECHalfCylinder,111111", + "TrackerTIBHalfBarrel,111111", + "TrackerTOBHalfBarrel,rrrrrr", + "TrackerTIDEndcap,111111", + "TrackerTECEndcap,111111", + ) +) + +################################################################################ +# insert Pedesettings +################################################################################ +import Alignment.MillePedeAlignmentAlgorithm.alignmentsetup.helper as helper +helper.set_pede_option(process, "skipemptycons") + +################################################################################ +# Mille-procedure +################################################################################ +if setupAlgoMode == "mille": + import Alignment.MillePedeAlignmentAlgorithm.alignmentsetup.MilleSetup as mille + mille.setup(process, + input_files = readFiles, + collection = setupCollection, + json_file = setupJson, + cosmics_zero_tesla = setupCosmicsZeroTesla, + cosmics_deco_mode = setupCosmicsDecoMode) + +################################################################################ +# Pede-procedure +################################################################################ +else: + merge_binary_files = [ + 'milleBinary001.dat', + 'milleBinary002.dat', + 'milleBinary003.dat'] + merge_tree_files = [ + 'treeFile001.root', + 'treeFile002.root', + 'treeFile003.root'] + + import Alignment.MillePedeAlignmentAlgorithm.alignmentsetup.PedeSetup as pede + pede.setup(process, + binary_files = merge_binary_files, + tree_files = merge_tree_files, + run_start_geometry = setupRunStartGeometry) diff --git a/Alignment/MillePedeAlignmentAlgorithm/test/test_pede.sh b/Alignment/MillePedeAlignmentAlgorithm/test/test_pede.sh new file mode 100755 index 0000000000000..3683ba50ce54e --- /dev/null +++ b/Alignment/MillePedeAlignmentAlgorithm/test/test_pede.sh @@ -0,0 +1,32 @@ +#!/bin/bash +function die { echo $1: status $2; exit $2; } + +if [ "${SCRAM_TEST_NAME}" != "" ] ; then + mkdir ${SCRAM_TEST_NAME} + cd ${SCRAM_TEST_NAME} +fi + +if test -f "milleBinary00*"; then + echo "cleaning the local test area" + rm -fr milleBinary00* + rm -fr pedeSteer* +fi + +pwd +echo " testing Aligment/MillePedeAlignmentAlgorithm" + +REMOTE="/store/group/alca_global/tkal_millepede_tests/" +TESTPACKAGE="test_pede_package.tar" +COMMMAND=`xrdfs cms-xrd-global.cern.ch locate ${REMOTE}${TESTPACKAGE}` +STATUS=$? +echo "xrdfs command status = "$STATUS +if [ $STATUS -eq 0 ]; then + echo "Using file ${TESTPACKAGE}. Running in ${LOCAL_TEST_DIR}." + xrdcp root://cms-xrd-global.cern.ch/${REMOTE}${TESTPACKAGE} ${LOCAL_TEST_DIR} + tar -xvf ${LOCAL_TEST_DIR}/${TESTPACKAGE} + gunzip milleBinary00* + (cmsRun ${LOCAL_TEST_DIR}/test_pede.py) || die 'failed running test_pede.py' $? + echo -e "\n MillePede Exit Status: "`cat millepede.end` +else + die "SKIPPING test, file ${TESTPACKAGE} not found" 0 +fi From d30ceca26a0dcad887a8d0e050f31cdba1b013b1 Mon Sep 17 00:00:00 2001 From: Tamas Date: Sun, 13 Mar 2022 22:07:51 +0100 Subject: [PATCH 3/4] Bugfix for Strips O2O --- CondTools/SiStrip/scripts/o2oRun_SiStripDAQ.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CondTools/SiStrip/scripts/o2oRun_SiStripDAQ.py b/CondTools/SiStrip/scripts/o2oRun_SiStripDAQ.py index 5f27fe812f36d..a85a758e4f21c 100755 --- a/CondTools/SiStrip/scripts/o2oRun_SiStripDAQ.py +++ b/CondTools/SiStrip/scripts/o2oRun_SiStripDAQ.py @@ -50,7 +50,7 @@ def run(args): for jobname in processes: status[jobname] = {'job':None, 'upload':None, 'fast':None, 'changed':None} p = processes[jobname] - log = p.communicate()[0] + log = p.communicate()[0].decode() logging.debug('=== log from o2o run ===\n%s' % log) if p.returncode == 0: logging.info('Job for %s finished successfully!' % jobname) @@ -86,7 +86,7 @@ def summary(args, is_ok, status, logfile): send_to=args.mail_to, send_from=args.mail_from) # send the detailed log - with open(logfile, 'rb') as log: + with open(logfile, 'r') as log: helper.send_mail(subject='%sNew O2O Log, IOV: %s' % (debugLabel, args.since), message=log.read(), send_to=args.mail_log_to, From a3ca1c4482a4a9b16e1499d8b4f953617e1db0a5 Mon Sep 17 00:00:00 2001 From: Kaya Tatar Date: Thu, 17 Mar 2022 15:10:10 +0100 Subject: [PATCH 4/4] Fix GED electron/photon PF association in run2 heavy-ion miniAOD --- .../PatAlgos/python/slimming/slimming_cff.py | 1 + .../python/reducedEgamma_cfi.py | 11 +++++ .../plugins/HiBadParticleCleaner.cc | 41 +++++++++++++++++-- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/PhysicsTools/PatAlgos/python/slimming/slimming_cff.py b/PhysicsTools/PatAlgos/python/slimming/slimming_cff.py index 306efa71e690e..eb3c4932d67e6 100644 --- a/PhysicsTools/PatAlgos/python/slimming/slimming_cff.py +++ b/PhysicsTools/PatAlgos/python/slimming/slimming_cff.py @@ -92,6 +92,7 @@ from Configuration.ProcessModifiers.run2_miniAOD_pp_on_AA_103X_cff import run2_miniAOD_pp_on_AA_103X run2_miniAOD_pp_on_AA_103X.toReplaceWith(slimmingTask,cms.Task(primaryVertexAssociationCleaned,slimmingTask.copy())) run2_miniAOD_pp_on_AA_103X.toReplaceWith(slimmingTask,cms.Task(primaryVertexWithBSAssociationCleaned,slimmingTask.copy())) +run2_miniAOD_pp_on_AA_103X.toReplaceWith(slimmingTask,cms.Task(pfEGammaToCandidateRemapperCleaned,slimmingTask.copy())) from RecoHI.HiTracking.miniAODVertexRecovery_cff import offlinePrimaryVerticesRecovery, offlineSlimmedPrimaryVerticesRecovery pp_on_AA.toReplaceWith( diff --git a/RecoEgamma/EgammaPhotonProducers/python/reducedEgamma_cfi.py b/RecoEgamma/EgammaPhotonProducers/python/reducedEgamma_cfi.py index 7c6964e437e9e..6a320d7815f65 100644 --- a/RecoEgamma/EgammaPhotonProducers/python/reducedEgamma_cfi.py +++ b/RecoEgamma/EgammaPhotonProducers/python/reducedEgamma_cfi.py @@ -104,3 +104,14 @@ hiPhotonIsolationMapInput = "photonIsolationHIProducerppGED", hiPhotonIsolationMapOutput = "photonIsolationHIProducerppGED" ) + +from RecoHI.HiJetAlgos.HiBadParticleCleaner_cfi import cleanedParticleFlow +from CommonTools.ParticleFlow.pfEGammaToCandidateRemapper_cfi import pfEGammaToCandidateRemapper as pfEGammaToCandidateRemapperCleaned +pfEGammaToCandidateRemapperCleaned.pf2pf = cms.InputTag("cleanedParticleFlow") + +from Configuration.ProcessModifiers.run2_miniAOD_pp_on_AA_103X_cff import run2_miniAOD_pp_on_AA_103X +run2_miniAOD_pp_on_AA_103X.toModify( + reducedEgamma, + photonsPFValMap = cms.InputTag("pfEGammaToCandidateRemapperCleaned:photons"), + gsfElectronsPFValMap = cms.InputTag("pfEGammaToCandidateRemapperCleaned:electrons") +) diff --git a/RecoHI/HiJetAlgos/plugins/HiBadParticleCleaner.cc b/RecoHI/HiJetAlgos/plugins/HiBadParticleCleaner.cc index 7b8cce25d0795..19c1c61706ae6 100644 --- a/RecoHI/HiJetAlgos/plugins/HiBadParticleCleaner.cc +++ b/RecoHI/HiJetAlgos/plugins/HiBadParticleCleaner.cc @@ -66,6 +66,7 @@ HiBadParticleCleaner::HiBadParticleCleaner(const edm::ParameterSet& iConfig) produces(); produces(); produces("removed"); + produces>(); } // @@ -91,7 +92,11 @@ void HiBadParticleCleaner::produce(edm::StreamID, edm::Event& iEvent, const edm: bool foundBadCandidate = false; + int n = pfCandidates->size(); + std::vector oldToNew(n); + int iPF = -1; for (const reco::PFCandidate& pfCandidate : *pfCandidates) { + iPF++; if (pfCandidate.particleId() == reco::PFCandidate::ParticleType::mu) // muon cleaning { if (pfCandidate.pt() > minMuonPt_) { @@ -128,6 +133,7 @@ void HiBadParticleCleaner::produce(edm::StreamID, edm::Event& iEvent, const edm: if (sig3d > maxSigLoose_) { pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); foundBadCandidate = true; continue; } @@ -135,12 +141,14 @@ void HiBadParticleCleaner::produce(edm::StreamID, edm::Event& iEvent, const edm: if (track->pt() < pfCandidate.pt() / 1.5 || track->pt() > pfCandidate.pt() * 1.5) { foundBadCandidate = true; pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); continue; } if (track->originalAlgo() == reco::TrackBase::muonSeededStepOutIn && track->hitPattern().trackerLayersWithMeasurement() < minTrackerLayersForMuonTight_) { foundBadCandidate = true; pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); continue; } } @@ -156,6 +164,7 @@ void HiBadParticleCleaner::produce(edm::StreamID, edm::Event& iEvent, const edm: if ((nHits < minTrackNHits_ && nPixelHits < minPixelNHits_) || nHits == 3) { foundBadCandidate = true; pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); continue; } @@ -176,12 +185,14 @@ void HiBadParticleCleaner::produce(edm::StreamID, edm::Event& iEvent, const edm: if (sig3d > maxSigLoose_) { foundBadCandidate = true; pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); continue; } if (sig3d > maxSigTight_ && nHits < minTrackNHits_) { foundBadCandidate = true; pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); continue; } @@ -192,12 +203,14 @@ void HiBadParticleCleaner::produce(edm::StreamID, edm::Event& iEvent, const edm: if (sig3d > maxSigLoose_) { foundBadCandidate = true; pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); continue; } if (nHits < minTrackNHits_) { foundBadCandidate = true; pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); continue; } } @@ -208,18 +221,21 @@ void HiBadParticleCleaner::produce(edm::StreamID, edm::Event& iEvent, const edm: if (sig3d > maxSigTight_) { foundBadCandidate = true; pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); continue; } if (nHits < minTrackNHits_) { foundBadCandidate = true; pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); continue; } if (nPixelHits < minPixelNHits_) { foundBadCandidate = true; pBadCandidateCollection->push_back(pfCandidate); + oldToNew[iPF] = -1*(pBadCandidateCollection->size()); continue; } } @@ -227,15 +243,34 @@ void HiBadParticleCleaner::produce(edm::StreamID, edm::Event& iEvent, const edm: } pOutputCandidateCollection->push_back(pfCandidate); - + oldToNew[iPF] = (pOutputCandidateCollection->size()); } // end loop over pf candidates bool pass = !foundBadCandidate; - iEvent.put(std::move(pOutputCandidateCollection)); - iEvent.put(std::move(pBadCandidateCollection), "removed"); + edm::OrphanHandle> newpf = iEvent.put(std::move(pOutputCandidateCollection)); + edm::OrphanHandle> badpf = iEvent.put(std::move(pBadCandidateCollection), "removed"); iEvent.put(std::make_unique(pass)); + + std::unique_ptr> pf2pf(new edm::ValueMap()); + edm::ValueMap::Filler filler(*pf2pf); + + std::vector refs; + refs.reserve(n); + + // old to new + for (iPF = 0; iPF < n; ++iPF) { + if (oldToNew[iPF] > 0) { + refs.push_back(reco::PFCandidateRef(newpf, oldToNew[iPF] - 1)); + } else { + refs.push_back(reco::PFCandidateRef(badpf, -oldToNew[iPF] - 1)); + } + } + filler.insert(pfCandidates, refs.begin(), refs.end()); + + filler.fill(); + iEvent.put(std::move(pf2pf)); } //define this as a plug-in