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

Convert ObjectViewCleaner from legacy producer to stream producer #17596

Merged
merged 2 commits into from Mar 17, 2017
Merged
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
259 changes: 116 additions & 143 deletions Validation/RecoTau/plugins/ObjectViewCleaner.cc
@@ -1,183 +1,158 @@
/*****************************************************************************
* Project: CMS detector at the CERN
*
* Package: PhysicsTools/TagAndProbe
*
*
* Authors:
*
* Kalanand Mishra, Fermilab - kalanand@fnal.gov
* Package: Validation/RecoTau
*
* Description:
* - Cleans a given object collection of other
* - Cleans a given object collection of other
* cross-object candidates using deltaR-matching.
* - For example: can clean a muon collection by
* - For example: can clean a muon collection by
* removing all jets in the muon collection.
* - Saves collection of the reference vectors of cleaned objects.
* History:
* Generalized the existing CandViewCleaner
*
* 2010 FNAL
*****************************************************************************/
////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////
#include "FWCore/Framework/interface/EDProducer.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/EDGetToken.h"
#include "FWCore/Utilities/interface/InputTag.h"

#include "DataFormats/Common/interface/View.h"
#include "DataFormats/Math/interface/deltaR.h"
#include "CommonTools/Utils/interface/StringCutObjectSelector.h"

#include "DataFormats/Candidate/interface/Candidate.h"
#include "DataFormats/Candidate/interface/CandidateFwd.h"
#include "DataFormats/MuonReco/interface/Muon.h"
#include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
#include "DataFormats/Common/interface/View.h"
#include "DataFormats/EgammaCandidates/interface/Electron.h"
#include "DataFormats/JetReco/interface/Jet.h"
#include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
#include "DataFormats/EgammaCandidates/interface/Photon.h"
#include "DataFormats/JetReco/interface/Jet.h"
#include "DataFormats/Math/interface/deltaR.h"
#include "DataFormats/MuonReco/interface/Muon.h"
#include "DataFormats/TrackReco/interface/Track.h"

#include "CommonTools/Utils/interface/StringCutObjectSelector.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/Framework/interface/stream/EDProducer.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/MakerMacros.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/EDGetToken.h"
#include "FWCore/Utilities/interface/InputTag.h"

#include <memory>
#include <vector>
#include <sstream>
#include <vector>

////////////////////////////////////////////////////////////////////////////////
// class definition
////////////////////////////////////////////////////////////////////////////////
template<typename T>
class ObjectViewCleaner : public edm::EDProducer
{
public:
// construction/destruction
ObjectViewCleaner(const edm::ParameterSet& iConfig);
virtual ~ObjectViewCleaner();

// member functions
void produce(edm::Event& iEvent,const edm::EventSetup& iSetup) override;
void endJob() override;

private:
// member data
edm::EDGetTokenT<edm::View<T> > srcCands_;
std::vector<edm::EDGetTokenT<edm::View<reco::Candidate> > > srcObjects_;
double deltaRMin_;

std::string moduleLabel_;
StringCutObjectSelector<T,true> objKeepCut_; // lazy parsing, to allow cutting on variables not in reco::Candidate class
StringCutObjectSelector<reco::Candidate,true> objRemoveCut_; // lazy parsing, to allow cutting on variables

unsigned int nObjectsTot_;
unsigned int nObjectsClean_;
};


using namespace std;
namespace {

// Job-level data
struct Counters {
explicit Counters(std::string const& label) : moduleLabel{label} {}
std::string const moduleLabel;
mutable std::atomic<std::size_t> nObjectsTot {};
mutable std::atomic<std::size_t> nObjectsClean {};
};

////////////////////////////////////////////////////////////////////////////////
// construction/destruction
////////////////////////////////////////////////////////////////////////////////
template <typename T>
class ObjectViewCleaner : public edm::stream::EDProducer<edm::GlobalCache<Counters>> {
public:

//______________________________________________________________________________
template<typename T>
ObjectViewCleaner<T>::ObjectViewCleaner(const edm::ParameterSet& iConfig)
: srcCands_ (consumes<edm::View<T> >(iConfig.getParameter<edm::InputTag> ("srcObject")))
, srcObjects_ ()
, deltaRMin_ (iConfig.getParameter<double> ("deltaRMin"))
, moduleLabel_(iConfig.getParameter<string> ("@module_label"))
, objKeepCut_(iConfig.existsAs<std::string>("srcObjectSelection") ? iConfig.getParameter<std::string>("srcObjectSelection") : "", true)
,objRemoveCut_(iConfig.existsAs<std::string>("srcObjectsToRemoveSelection") ? iConfig.getParameter<std::string>("srcObjectsToRemoveSelection") : "", true)
, nObjectsTot_(0)
, nObjectsClean_(0)
{
produces<edm::RefToBaseVector<T> >();
std::vector<edm::InputTag> srcTags = iConfig.getParameter<vector<edm::InputTag> >("srcObjectsToRemove");
srcObjects_.reserve(srcTags.size());
for (auto const& tag : srcTags) {
srcObjects_.emplace_back(consumes<edm::View<reco::Candidate> >(tag));
}
}
explicit ObjectViewCleaner(edm::ParameterSet const&, Counters const*);

void produce(edm::Event&, edm::EventSetup const&) override;
static auto initializeGlobalCache(edm::ParameterSet const& iConfig)
{
return std::make_unique<Counters>(iConfig.getParameter<std::string>("@module_label"));
}
static void globalEndJob(Counters const*);

private:

//______________________________________________________________________________
template<typename T>
ObjectViewCleaner<T>::~ObjectViewCleaner()
{

}
// member data
edm::EDGetTokenT<edm::View<T>> srcCands_;
std::vector<edm::EDGetTokenT<edm::View<reco::Candidate>>> srcObjectsToRemove_;
double deltaRMin_;
StringCutObjectSelector<T,true> objKeepCut_; // lazy parsing, to allow cutting on variables not in reco::Candidate class
StringCutObjectSelector<reco::Candidate,true> objRemoveCut_; // lazy parsing, to allow cutting on variables

auto tagsToTokens(std::vector<edm::InputTag> const&) -> decltype(srcObjectsToRemove_);
bool isIsolated(edm::Event const&, T const&) const;

};

////////////////////////////////////////////////////////////////////////////////
// implementation of member functions
////////////////////////////////////////////////////////////////////////////////
using namespace std;

//______________________________________________________________________________
template<typename T>
void ObjectViewCleaner<T>::produce(edm::Event& iEvent,const edm::EventSetup& iSetup)
{
unique_ptr<edm::RefToBaseVector<T> >
cleanObjects(new edm::RefToBaseVector<T >());

edm::Handle<edm::View<T> > candidates;
iEvent.getByToken(srcCands_,candidates);

bool* isClean = new bool[candidates->size()];
for (unsigned int iObject=0;iObject<candidates->size();iObject++) isClean[iObject] = true;

for (auto const& object : srcObjects_) {
edm::Handle<edm::View<reco::Candidate> > objects;
iEvent.getByToken(object,objects);

for (unsigned int iObject=0;iObject<candidates->size();iObject++) {
const T& candidate = candidates->at(iObject);
if (!objKeepCut_(candidate)) isClean[iObject] = false;

for (unsigned int iObj=0;iObj<objects->size();iObj++) {
const reco::Candidate& obj = objects->at(iObj);
template<typename T>
ObjectViewCleaner<T>::ObjectViewCleaner(edm::ParameterSet const& iConfig, Counters const*)
: srcCands_{consumes<edm::View<T>>(iConfig.getParameter<edm::InputTag>("srcObject"))}
, srcObjectsToRemove_{tagsToTokens(iConfig.getParameter<vector<edm::InputTag>>("srcObjectsToRemove"))}
, deltaRMin_{iConfig.getParameter<double>("deltaRMin")}
, objKeepCut_{iConfig.existsAs<std::string>("srcObjectSelection") ? iConfig.getParameter<std::string>("srcObjectSelection") : "", true}
, objRemoveCut_{iConfig.existsAs<std::string>("srcObjectsToRemoveSelection") ? iConfig.getParameter<std::string>("srcObjectsToRemoveSelection") : "", true}
{
produces<edm::RefToBaseVector<T>>();
}

//______________________________________________________________________________
template <typename T>
void ObjectViewCleaner<T>::produce(edm::Event& iEvent, edm::EventSetup const&)
{
edm::Handle<edm::View<T>> candidates;
iEvent.getByToken(srcCands_,candidates);
globalCache()->nObjectsTot += candidates->size();

auto cleanObjects = std::make_unique<edm::RefToBaseVector<T>>();
for (unsigned int iCand {}; iCand < candidates->size(); ++iCand) {
auto const& candidate = candidates->at(iCand);
if (objKeepCut_(candidate) && isIsolated(iEvent, candidate)) {
cleanObjects->push_back(candidates->refAt(iCand));
}
}
globalCache()->nObjectsClean += cleanObjects->size();

iEvent.put(std::move(cleanObjects));
}

//______________________________________________________________________________
template <typename T>
void ObjectViewCleaner<T>::globalEndJob(Counters const* counters)
{
ostringstream oss;
oss << "nObjectsTot=" << counters->nObjectsTot << " nObjectsClean=" << counters->nObjectsClean
<< " fObjectsClean=" << 100*(counters->nObjectsClean/static_cast<double>(counters->nObjectsTot)) << "%\n";
edm::LogInfo("ObjectViewCleaner") << "++++++++++++++++++++++++++++++++++++++++++++++++++\n"
<< counters->moduleLabel << "(ObjectViewCleaner) SUMMARY:\n"
<< oss.str() << '\n'
<< "++++++++++++++++++++++++++++++++++++++++++++++++++";
}

//______________________________________________________________________________
template <typename T>
bool ObjectViewCleaner<T>::isIsolated(edm::Event const& iEvent, T const& candidate) const
{
for (auto const& srcObject : srcObjectsToRemove_) {
edm::Handle<edm::View<reco::Candidate>> objects;
iEvent.getByToken(srcObject, objects);

for (unsigned int iObj {}; iObj < objects->size() ; ++iObj) {
auto const& obj = objects->at(iObj);
if (!objRemoveCut_(obj)) continue;

double deltaR = reco::deltaR(candidate,obj);
if (deltaR<deltaRMin_) isClean[iObject] = false;
if (reco::deltaR(candidate,obj) < deltaRMin_) {
return false;
}
}
}
return true;
};

//______________________________________________________________________________
template <typename T>
auto ObjectViewCleaner<T>::tagsToTokens(std::vector<edm::InputTag> const& tags) -> decltype(srcObjectsToRemove_)
{
std::vector<edm::EDGetTokenT<edm::View<reco::Candidate>>> result;
std::transform(std::cbegin(tags), std::cend(tags), std::back_inserter(result),
[this](auto const& tag) { return this->consumes<edm::View<reco::Candidate>>(tag); });
return result;
}

for (unsigned int iObject=0;iObject<candidates->size();iObject++)
if (isClean[iObject]) cleanObjects->push_back(candidates->refAt(iObject));

nObjectsTot_ +=candidates->size();
nObjectsClean_+=cleanObjects->size();

delete [] isClean;
iEvent.put(std::move(cleanObjects));
}


//______________________________________________________________________________
template<typename T>
void ObjectViewCleaner<T>::endJob()
{
stringstream ss;
ss<<"nObjectsTot="<<nObjectsTot_<<" nObjectsClean="<<nObjectsClean_
<<" fObjectsClean="<<100.*(nObjectsClean_/(double)nObjectsTot_)<<"%\n";
edm::LogInfo("ObjectViewCleaner")<<"++++++++++++++++++++++++++++++++++++++++++++++++++"
<<"\n"<<moduleLabel_<<"(ObjectViewCleaner) SUMMARY:\n"<<ss.str()
<<"++++++++++++++++++++++++++++++++++++++++++++++++++";
}

} // anonymous namespace

////////////////////////////////////////////////////////////////////////////////
// plugin definition
// plugin definitions
////////////////////////////////////////////////////////////////////////////////


typedef ObjectViewCleaner<reco::Candidate> TauValCandViewCleaner;
typedef ObjectViewCleaner<reco::Jet> TauValJetViewCleaner;
typedef ObjectViewCleaner<reco::Muon> TauValMuonViewCleaner;
Expand All @@ -186,12 +161,10 @@ typedef ObjectViewCleaner<reco::Electron> TauValElectronViewCleaner;
typedef ObjectViewCleaner<reco::Photon> TauValPhotonViewCleaner;
typedef ObjectViewCleaner<reco::Track> TauValTrackViewCleaner;

#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(TauValCandViewCleaner);
DEFINE_FWK_MODULE(TauValJetViewCleaner);
DEFINE_FWK_MODULE(TauValMuonViewCleaner);
DEFINE_FWK_MODULE(TauValGsfElectronViewCleaner);
DEFINE_FWK_MODULE(TauValElectronViewCleaner);
DEFINE_FWK_MODULE(TauValPhotonViewCleaner);
DEFINE_FWK_MODULE(TauValTrackViewCleaner);