Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merger producer with Duplicate Removal Backport from CMSSW_11 #30424

Merged
merged 1 commit into from Jun 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions CommonTools/CandAlgos/plugins/CandFwdPtrMerger.cc
@@ -0,0 +1,21 @@
/* \class CandFwdPtrMerger
*
* Producer of merged Candidate forward pointer collection
*
* \author: Lauren Hay
*
*/
#include "FWCore/Framework/interface/MakerMacros.h"
#include "CommonTools/UtilAlgos/interface/UniqueMerger.h"
#include "DataFormats/Candidate/interface/Candidate.h"
#include "DataFormats/PatCandidates/interface/PackedCandidate.h"
#include "DataFormats/PatCandidates/interface/PackedGenParticle.h"
#include "DataFormats/Common/interface/FwdPtr.h"

typedef UniqueMerger<std::vector<edm::FwdPtr<reco::Candidate>>> CandFwdPtrMerger;
typedef UniqueMerger<std::vector<edm::FwdPtr<pat::PackedCandidate>>> PackedCandidateFwdPtrMerger;
typedef UniqueMerger<std::vector<edm::FwdPtr<pat::PackedGenParticle>>> PackedGenParticleFwdPtrMerger;

DEFINE_FWK_MODULE(CandFwdPtrMerger);
DEFINE_FWK_MODULE(PackedCandidateFwdPtrMerger);
DEFINE_FWK_MODULE(PackedGenParticleFwdPtrMerger);
21 changes: 21 additions & 0 deletions CommonTools/CandAlgos/plugins/CandPtrMerger.cc
@@ -0,0 +1,21 @@
/* \class CandPtrMerger
*
* Producer of merged Candidate forward pointer collection
*
* \author: Lauren Hay
*
*/
#include "FWCore/Framework/interface/MakerMacros.h"
#include "CommonTools/UtilAlgos/interface/UniqueMerger.h"
#include "DataFormats/Candidate/interface/Candidate.h"
#include "DataFormats/PatCandidates/interface/PackedCandidate.h"
#include "DataFormats/PatCandidates/interface/PackedGenParticle.h"
#include "DataFormats/Common/interface/Ptr.h"

typedef UniqueMerger<std::vector<edm::Ptr<reco::Candidate>>> CandPtrMerger;
typedef UniqueMerger<std::vector<edm::Ptr<pat::PackedCandidate>>> PackedCandidatePtrMerger;
typedef UniqueMerger<std::vector<edm::Ptr<pat::PackedGenParticle>>> PackedGenParticlePtrMerger;

DEFINE_FWK_MODULE(CandPtrMerger);
DEFINE_FWK_MODULE(PackedCandidatePtrMerger);
DEFINE_FWK_MODULE(PackedGenParticlePtrMerger);
87 changes: 87 additions & 0 deletions CommonTools/UtilAlgos/interface/UniqueMerger.h
@@ -0,0 +1,87 @@
#ifndef UtilAlgos_UniqueMerger_h
#define UtilAlgos_UniqueMerger_h
/** \class UniqueMerger
*
* Merges an arbitrary number of collections
* into a single collection, without duplicates. Based on logic from Merger.h.
* This class template differs from Merger.h in that it uses a set instead of std::vector.
* This requires the OutputCollection type to be sortable,
* which allows us to search for elements downstream efficiently.
*
* Template parameters:
* - C : collection type
* - P : policy class that specifies how objects
* in the collection are are cloned
*
* \author Lauren Hay
*
* \version $Revision: 1.2 $
*
*
*/

#include "FWCore/Framework/interface/global/EDProducer.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/transform.h"
#include "FWCore/Utilities/interface/InputTag.h"
#include "DataFormats/Common/interface/CloneTrait.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include <vector>

template <typename InputCollection,
typename OutputCollection = InputCollection,
typename P = typename edm::clonehelper::CloneTrait<InputCollection>::type>
class UniqueMerger : public edm::global::EDProducer<> {
public:
typedef std::set<typename OutputCollection::value_type> set_type;
/// constructor from parameter set
explicit UniqueMerger(const edm::ParameterSet&);
/// destructor
~UniqueMerger() override;

private:
/// process an event
void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
/// vector of strings
typedef std::vector<edm::EDGetTokenT<InputCollection> > vtoken;
/// labels of the collections to be merged
vtoken srcToken_;
/// choose whether to skip null/invalid pointers
bool skipNulls_;
/// choose whether to warn when skipping pointers
bool warnOnSkip_;
};

template <typename InputCollection, typename OutputCollection, typename P>
UniqueMerger<InputCollection, OutputCollection, P>::UniqueMerger(const edm::ParameterSet& par)
: srcToken_(edm::vector_transform(par.template getParameter<std::vector<edm::InputTag> >("src"),
[this](edm::InputTag const& tag) { return consumes<InputCollection>(tag); })),
skipNulls_(par.getParameter<bool>("skipNulls")),
warnOnSkip_(par.getParameter<bool>("warnOnSkip")) {
produces<OutputCollection>();
}

template <typename InputCollection, typename OutputCollection, typename P>
UniqueMerger<InputCollection, OutputCollection, P>::~UniqueMerger() {}

template <typename InputCollection, typename OutputCollection, typename P>
void UniqueMerger<InputCollection, OutputCollection, P>::produce(edm::StreamID,
edm::Event& evt,
const edm::EventSetup&) const {
set_type coll_set;
for (auto const& s : srcToken_) {
for (auto const& c : evt.get(s)) {
if (!skipNulls_ || (c.isNonnull() && c.isAvailable())) {
coll_set.emplace(P::clone(c));
} else if (warnOnSkip_) {
edm::LogWarning("InvalidPointer") << "Found an invalid pointer. Will not merge to collection.";
}
}
}
std::unique_ptr<OutputCollection> coll(new OutputCollection(coll_set.size()));
std::copy(coll_set.begin(), coll_set.end(), coll->begin());
evt.put(std::move(coll));
}

#endif