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

Storing Generator Filter Information in NanoAOD #34169

Merged
merged 5 commits into from
Dec 11, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "FWCore/Framework/interface/stream/EDProducer.h"
#include "FWCore/Framework/interface/one/EDProducer.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Framework/interface/ConsumesCollector.h"
#include "DataFormats/Common/interface/View.h"
Expand Down Expand Up @@ -271,3 +272,134 @@ class FirstObjectSimpleFlatTableProducer : public SimpleFlatTableProducerBase<T,
return out;
}
};

template <typename T, typename TProd>
class SimpleFlatTableProducerBaseLumi : public edm::one::EDProducer<edm::EndLuminosityBlockProducer> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this module (template) need to be edm::one? Could it be edm::stream?

If it needs to stay edm::one for some reason, please use also edm::LuminosityBlockCache extension to tell the framework the the module can process events from multiple LuminosityBlocks concurrently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dear @makortel,

At the time of development I tried to use the edm::stream (as in SimpleFlatTableProducerBase) guided by the FWMultithreadedFrameworkStreamModuleInterface Twiki however, this resulted in a series of compilation errors that I was not able to resolve. Using edm::one solved the issues.

If you have any suggestions on how to make edm::stream work, I would be grateful.

Best,
Mateusz

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What kind of compilation errors did you get?

Copy link
Contributor Author

@mzarucki mzarucki Jun 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first one is: /afs/cern.ch/work/m/mzarucki/nanoAOD/CMSSW_12_0_0_pre3/src/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h:315:8: error: 'void SimpleFlatTableProducerBaseLumi<T, TProd>::endLuminosityBlockProduce(edm::LuminosityBlock&, const edm::EventSetup&) [with T = GenFilterInfo; TProd = GenFilterInfo]' marked 'final', but is not virtual

which can be solved by just removing the final specifier for the endLuminosityBlockProduce method.

A following compilation error is:

/cvmfs/cms.cern.ch/slc7_amd64_gcc900/cms/cmssw/CMSSW_12_0_0_pre3/src/FWCore/Framework/interface/stream/callAbilities.h:455:43: error: 'globalEndLuminosityBlockProduce' is not a member of 'LumiSingletonSimpleFlatTableProducer<GenFilterInfo>' 455 | T::globalEndLuminosityBlockProduce(Lumi, iES, iRC);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, after further thought stream module type actually wouldn't help. I was thinking we could use the "streams" to work around the thread-unsafety of StringObjectFunction and StringCutObjectSelector, but the LuminosityBlock transitions of stream modules are global (i.e. can occur concurrently).

So the best way to support "processing Events from multiple LuminosityBlocks concurrently" would be to use the edm::LuminosityBlockCache extension. Since you don't really need the cache, you could declare it as e.g. edm::LuminosityBlockCache<int> and in globalBeginLuminosityBlock() return nullptr.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dear @makortel,

Therefore, is edm:one fine to use for this module?

As suggested, I have added the edm:LuminosityBlockCache extension as follows:

class SimpleFlatTableProducerBaseLumi : public edm::one::EDProducer<edm::EndLuminosityBlockProducer, edm::LuminosityBlockCache<int>> {

I have also added the globalBeginLuminosityBlock method which returns nullptr.

Unfortunately, I get the following compilation errors:

 from /afs/cern.ch/work/m/mzarucki/nanoAOD/CMSSW_12_0_0_pre3/src/PhysicsTools/NanoAOD/plugins/SimpleFlatTableProducerPlugins.cc:1:
/cvmfs/cms.cern.ch/slc7_amd64_gcc900/external/gcc/9.3.0/include/c++/9.3.0/bits/unique_ptr.h: In instantiation of 'typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = LumiSingletonSimpleFlatTableProducer<GenFilterInfo>; _Args = {const edm::ParameterSet&}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<LumiSingletonSimpleFlatTableProducer<GenFilterInfo>, std::default_delete<LumiSingletonSimpleFlatTableProducer<GenFilterInfo> > >]':
/cvmfs/cms.cern.ch/slc7_amd64_gcc900/cms/cmssw/CMSSW_12_0_0_pre3/src/FWCore/Framework/src/MakeModuleHelper.h:39:40:   required from 'static std::unique_ptr<_Tp> edm::MakeModuleHelper<Base>::makeModule(const edm::ParameterSet&) [with T = LumiSingletonSimpleFlatTableProducer<GenFilterInfo>; Base = edm::one::EDProducerBase]'
/cvmfs/cms.cern.ch/slc7_amd64_gcc900/cms/cmssw/CMSSW_12_0_0_pre3/src/FWCore/Framework/src/WorkerMaker.h:83:107:   required from 'std::shared_ptr<edm::maker::ModuleHolder> edm::WorkerMaker<T>::makeModule(const edm::ParameterSet&) const [with T = LumiSingletonSimpleFlatTableProducer<GenFilterInfo>]'
/cvmfs/cms.cern.ch/slc7_amd64_gcc900/cms/cmssw/CMSSW_12_0_0_pre3/src/FWCore/Framework/src/WorkerMaker.h:77:40:   required from here
/cvmfs/cms.cern.ch/slc7_amd64_gcc900/external/gcc/9.3.0/include/c++/9.3.0/bits/unique_ptr.h:857:30: error: invalid new-expression of abstract class type 'LumiSingletonSimpleFlatTableProducer<GenFilterInfo>'
  857 |     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Is there something obvious that I might be missing here?

Best regards,
Mateusz

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of LuminosityBlockCache requires overriding also void SimpleFlatTableProducerBaseLumi::globalEndLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override {}.
(sorry for not mentioning it earlier)
https://twiki.cern.ch/twiki/bin/view/CMSPublic/FWMultithreadedFrameworkOneModuleInterface#edm_LuminosityBlockCacheT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification!

I have made the discussed updates to support processing events from multiple LuminosityBlocks concurrently in a4a7f44

I would be grateful if you could have a look whether this is what you were expecting.

Cheers,
Mateusz

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be grateful if you could have a look whether this is what you were expecting.

Yes, it looks good now. Thanks!

public:
SimpleFlatTableProducerBaseLumi(edm::ParameterSet const &params)
: name_(params.getParameter<std::string>("name")),
doc_(params.existsAs<std::string>("doc") ? params.getParameter<std::string>("doc") : ""),
extension_(params.existsAs<bool>("extension") ? params.getParameter<bool>("extension") : false),
skipNonExistingSrc_(
params.existsAs<bool>("skipNonExistingSrc") ? params.getParameter<bool>("skipNonExistingSrc") : false),
src_(skipNonExistingSrc_ ? mayConsume<TProd>(params.getParameter<edm::InputTag>("src"))
mzarucki marked this conversation as resolved.
Show resolved Hide resolved
: consumes<TProd,edm::InLumi>(params.getParameter<edm::InputTag>("src"))) {
edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
const std::string &type = varPSet.getParameter<std::string>("type");
if (type == "int")
vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
else if (type == "float")
vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
else if (type == "uint8")
vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
else if (type == "bool")
vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
else
throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
}

produces<nanoaod::FlatTable,edm::Transition::EndLuminosityBlock>();
}

~SimpleFlatTableProducerBaseLumi() override {}

// this is to be overriden by the child class
virtual std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &iLumi,
const edm::Handle<TProd> &prod) const = 0;

void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
// do nothing
}

void endLuminosityBlockProduce(edm::LuminosityBlock& iLumi, const edm::EventSetup &iSetup) final {
edm::Handle<TProd> src;
iLumi.getByToken(src_, src);

std::unique_ptr<nanoaod::FlatTable> out = fillTable(iLumi, src);
out->setDoc(doc_);

iLumi.put(std::move(out));
}

protected:
const std::string name_;
const std::string doc_;
const bool extension_;
const bool skipNonExistingSrc_;
const edm::EDGetTokenT<TProd> src_;

class VariableBase {
mzarucki marked this conversation as resolved.
Show resolved Hide resolved
public:
VariableBase(const std::string &aname, const edm::ParameterSet &cfg)
: name_(aname),
doc_(cfg.getParameter<std::string>("doc")),
precision_(cfg.existsAs<int>("precision") ? cfg.getParameter<int>("precision")
: (cfg.existsAs<std::string>("precision") ? -2 : -1)) {}
virtual ~VariableBase() {}
const std::string &name() const { return name_; }

protected:
std::string name_, doc_;
int precision_;
};

class Variable : public VariableBase {
public:
Variable(const std::string &aname, const edm::ParameterSet &cfg) : VariableBase(aname, cfg) {}
virtual void fill(std::vector<const T *> selobjs, nanoaod::FlatTable &out) const = 0;
mzarucki marked this conversation as resolved.
Show resolved Hide resolved
};

template <typename StringFunctor, typename ValType>
class FuncVariable : public Variable {
public:
FuncVariable(const std::string &aname, const edm::ParameterSet &cfg)
: Variable(aname, cfg),
func_(cfg.getParameter<std::string>("expr"), true),
precisionFunc_(cfg.existsAs<std::string>("precision") ? cfg.getParameter<std::string>("precision") : "23",
true) {}
~FuncVariable() override {}
void fill(std::vector<const T *> selobjs, nanoaod::FlatTable &out) const override {
std::vector<ValType> vals(selobjs.size());
for (unsigned int i = 0, n = vals.size(); i < n; ++i) {
if constexpr (std::is_same<ValType, float>()) {
if (this->precision_ == -2) {
vals[i] =
MiniFloatConverter::reduceMantissaToNbitsRounding(func_(*selobjs[i]), precisionFunc_(*selobjs[i]));
} else {
vals[i] = func_(*selobjs[i]);
}
} else {
vals[i] = func_(*selobjs[i]);
}
}
out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
}

protected:
StringFunctor func_;
StringFunctor precisionFunc_;
};
typedef FuncVariable<StringObjectFunction<T>, int> IntVar;
typedef FuncVariable<StringObjectFunction<T>, float> FloatVar;
typedef FuncVariable<StringObjectFunction<T>, uint8_t> UInt8Var;
typedef FuncVariable<StringCutObjectSelector<T>, bool> BoolVar;
std::vector<std::unique_ptr<Variable>> vars_;
};

template <typename T>
class LumiSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBaseLumi<T, T> {
public:
LumiSingletonSimpleFlatTableProducer(edm::ParameterSet const &params) : SimpleFlatTableProducerBaseLumi<T, T>(params) {}

~LumiSingletonSimpleFlatTableProducer() override {}

std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &, const edm::Handle<T> &prod) const override {
auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
std::vector<const T *> selobjs(1, prod.product());
for (const auto &var : this->vars_)
var->fill(selobjs, *out);
return out;
}
};
94 changes: 94 additions & 0 deletions PhysicsTools/NanoAOD/plugins/LumiOutputBranches.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include "PhysicsTools/NanoAOD/plugins/LumiOutputBranches.h"

#include <iostream>

namespace {
std::string makeBranchName(const std::string &baseName, const std::string &leafName) {
return baseName.empty() ? leafName : (leafName.empty() ? baseName : baseName + "_" + leafName);
}
} // namespace

void LumiOutputBranches::defineBranchesFromFirstEvent(const nanoaod::FlatTable &tab) {
m_baseName = tab.name();
for (size_t i = 0; i < tab.nColumns(); i++) {
const std::string &var = tab.columnName(i);
switch (tab.columnType(i)) {
case nanoaod::FlatTable::ColumnType::Float:
m_floatBranches.emplace_back(var, tab.columnDoc(i), "F");
break;
case nanoaod::FlatTable::ColumnType::Int:
m_intBranches.emplace_back(var, tab.columnDoc(i), "I");
break;
case nanoaod::FlatTable::ColumnType::UInt8:
m_uint8Branches.emplace_back(var, tab.columnDoc(i), "b");
break;
case nanoaod::FlatTable::ColumnType::Bool:
m_uint8Branches.emplace_back(var, tab.columnDoc(i), "O");
break;
default:
throw cms::Exception("LogicError", "Unsupported type");
}
}
}

void LumiOutputBranches::branch(TTree &tree) {
if (!m_singleton) {
if (m_extension == IsExtension) {
m_counterBranch = tree.FindBranch(("n" + m_baseName).c_str());
if (!m_counterBranch) {
throw cms::Exception("LogicError",
"Trying to save an extension table for " + m_baseName +
" before having saved the corresponding main table\n");
}
} else {
if (tree.FindBranch(("n" + m_baseName).c_str()) != nullptr) {
throw cms::Exception("LogicError", "Trying to save multiple main tables for " + m_baseName + "\n");
}
m_counterBranch = tree.Branch(("n" + m_baseName).c_str(), &m_counter, ("n" + m_baseName + "/i").c_str());
m_counterBranch->SetTitle(m_doc.c_str());
}
}
std::string varsize = m_singleton ? "" : "[n" + m_baseName + "]";
for (std::vector<NamedBranchPtr> *branches : {&m_floatBranches, &m_intBranches, &m_uint8Branches}) {
for (auto &pair : *branches) {
std::string branchName = makeBranchName(m_baseName, pair.name);
pair.branch =
tree.Branch(branchName.c_str(), (void *)nullptr, (branchName + varsize + "/" + pair.rootTypeCode).c_str());
pair.branch->SetTitle(pair.title.c_str());
}
}
}

void LumiOutputBranches::fill(const edm::LuminosityBlockForOutput &iLumi, TTree &tree, bool extensions) {
if (m_extension != DontKnowYetIfMainOrExtension) {
if (extensions != m_extension)
return; // do nothing, wait to be called with the proper flag
}

edm::Handle<nanoaod::FlatTable> handle;
iLumi.getByToken(m_token, handle);
const nanoaod::FlatTable &tab = *handle;
m_counter = tab.size();
m_singleton = tab.singleton();
if (!m_branchesBooked) {
m_extension = tab.extension() ? IsExtension : IsMain;
if (extensions != m_extension)
return; // do nothing, wait to be called with the proper flag
defineBranchesFromFirstEvent(tab);
m_doc = tab.doc();
m_branchesBooked = true;
branch(tree);
}
if (!m_singleton && m_extension == IsExtension) {
if (m_counter != *reinterpret_cast<UInt_t *>(m_counterBranch->GetAddress())) {
throw cms::Exception("LogicError",
"Mismatch in number of entries between extension and main table for " + tab.name());
}
}
for (auto &pair : m_floatBranches)
fillColumn<float>(pair, tab);
for (auto &pair : m_intBranches)
fillColumn<int>(pair, tab);
for (auto &pair : m_uint8Branches)
fillColumn<uint8_t>(pair, tab);
}
58 changes: 58 additions & 0 deletions PhysicsTools/NanoAOD/plugins/LumiOutputBranches.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef PhysicsTools_NanoAOD_LumiOutputBranches_h
#define PhysicsTools_NanoAOD_LumiOutputBranches_h

#include <string>
#include <vector>
#include <TTree.h>
#include "FWCore/Framework/interface/LuminosityBlockForOutput.h"
#include "DataFormats/NanoAOD/interface/FlatTable.h"
#include "DataFormats/Provenance/interface/BranchDescription.h"
#include "FWCore/Utilities/interface/EDGetToken.h"

class LumiOutputBranches {
public:
LumiOutputBranches(const edm::BranchDescription *desc, const edm::EDGetToken &token)
: m_token(token), m_extension(DontKnowYetIfMainOrExtension), m_branchesBooked(false) {
if (desc->className() != "nanoaod::FlatTable")
throw cms::Exception("Configuration", "NanoAODOutputModule can only write out nanoaod::FlatTable objects");
}

void defineBranchesFromFirstEvent(const nanoaod::FlatTable &tab);
void branch(TTree &tree);

/// Fill the current table, if extensions == table.extension().
/// This parameter is used so that the fill is called first for non-extensions and then for extensions
void fill(const edm::LuminosityBlockForOutput &iLumi, TTree &tree, bool extensions);

private:
edm::EDGetToken m_token;
std::string m_baseName;
bool m_singleton;
enum { IsMain = 0, IsExtension = 1, DontKnowYetIfMainOrExtension = 2 } m_extension;
std::string m_doc;
UInt_t m_counter;
struct NamedBranchPtr {
std::string name, title, rootTypeCode;
TBranch *branch;
NamedBranchPtr(const std::string &aname,
const std::string &atitle,
const std::string &rootType,
TBranch *branchptr = nullptr)
: name(aname), title(atitle), rootTypeCode(rootType), branch(branchptr) {}
};
TBranch *m_counterBranch;
std::vector<NamedBranchPtr> m_floatBranches;
std::vector<NamedBranchPtr> m_intBranches;
std::vector<NamedBranchPtr> m_uint8Branches;
bool m_branchesBooked;

template <typename T>
void fillColumn(NamedBranchPtr &pair, const nanoaod::FlatTable &tab) {
int idx = tab.columnIndex(pair.name);
if (idx == -1)
throw cms::Exception("LogicError", "Missing column in input for " + m_baseName + "_" + pair.name);
pair.branch->SetAddress(const_cast<T *>(&tab.columnData<T>(idx).front())); // SetAddress should take a const * !
}
};

#endif
10 changes: 10 additions & 0 deletions PhysicsTools/NanoAOD/plugins/NanoAODOutputModule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "DataFormats/NanoAOD/interface/FlatTable.h"
#include "DataFormats/NanoAOD/interface/UniqueString.h"
#include "PhysicsTools/NanoAOD/plugins/TableOutputBranches.h"
#include "PhysicsTools/NanoAOD/plugins/LumiOutputBranches.h"
#include "PhysicsTools/NanoAOD/plugins/TriggerOutputBranches.h"
#include "PhysicsTools/NanoAOD/plugins/EventStringOutputBranches.h"
#include "PhysicsTools/NanoAOD/plugins/SummaryTableOutputBranches.h"
Expand Down Expand Up @@ -128,6 +129,7 @@ class NanoAODOutputModule : public edm::one::OutputModule<> {

std::vector<SummaryTableOutputBranches> m_runTables;
std::vector<SummaryTableOutputBranches> m_lumiTables;
std::vector<LumiOutputBranches> m_lumiTables2;
std::vector<TableOutputBranches> m_runFlatTables;

std::vector<std::pair<std::string, edm::EDGetToken>> m_nanoMetadata;
Expand Down Expand Up @@ -231,6 +233,11 @@ void NanoAODOutputModule::writeLuminosityBlock(edm::LuminosityBlockForOutput con

for (auto& t : m_lumiTables)
t.fill(iLumi, *m_lumiTree);

for (unsigned int extensions = 0; extensions <= 1; ++extensions) {
for (auto& t : m_lumiTables2)
t.fill(iLumi, *m_lumiTree, extensions);
}

tbb::this_task_arena::isolate([&] { m_lumiTree->Fill(); });

Expand Down Expand Up @@ -301,6 +308,7 @@ void NanoAODOutputModule::openFile(edm::FileBlock const&) {
m_evstrings.clear();
m_runTables.clear();
m_lumiTables.clear();
m_lumiTables2.clear();
m_runFlatTables.clear();
const auto& keeps = keptProducts();
for (const auto& keep : keeps[edm::InEvent]) {
Expand All @@ -320,6 +328,8 @@ void NanoAODOutputModule::openFile(edm::FileBlock const&) {
m_lumiTables.push_back(SummaryTableOutputBranches(keep.first, keep.second));
else if (keep.first->className() == "nanoaod::UniqueString" && keep.first->moduleLabel() == "nanoMetadata")
m_nanoMetadata.emplace_back(keep.first->productInstanceName(), keep.second);
else if (keep.first->className() == "nanoaod::FlatTable")
m_lumiTables2.push_back(LumiOutputBranches(keep.first, keep.second));
else
throw cms::Exception(
"Configuration",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ typedef SimpleFlatTableProducer<reco::Candidate> SimpleCandidateFlatTableProduce
#include "SimDataFormats/GeneratorProducts/interface/GenEventInfoProduct.h"
typedef EventSingletonSimpleFlatTableProducer<GenEventInfoProduct> SimpleGenEventFlatTableProducer;

#include "SimDataFormats/GeneratorProducts/interface/GenFilterInfo.h"
typedef LumiSingletonSimpleFlatTableProducer<GenFilterInfo> SimpleGenFilterFlatTableProducerLumi;

#include "SimDataFormats/HTXS/interface/HiggsTemplateCrossSections.h"
typedef EventSingletonSimpleFlatTableProducer<HTXS::HiggsClassification> SimpleHTXSFlatTableProducer;

Expand All @@ -21,7 +24,8 @@ typedef EventSingletonSimpleFlatTableProducer<math::XYZPointF> SimpleXYZPointFla
#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(SimpleCandidateFlatTableProducer);
DEFINE_FWK_MODULE(SimpleGenEventFlatTableProducer);
DEFINE_FWK_MODULE(SimpleGenFilterFlatTableProducerLumi);
DEFINE_FWK_MODULE(SimpleHTXSFlatTableProducer);
DEFINE_FWK_MODULE(SimpleProtonTrackFlatTableProducer);
DEFINE_FWK_MODULE(SimpleLocalTrackFlatTableProducer);
DEFINE_FWK_MODULE(SimpleXYZPointFlatTableProducer);
DEFINE_FWK_MODULE(SimpleXYZPointFlatTableProducer);
17 changes: 16 additions & 1 deletion PhysicsTools/NanoAOD/python/globals_cff.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,20 @@
),
)

genFilterTable = cms.EDProducer("SimpleGenFilterFlatTableProducerLumi",
src = cms.InputTag("genFilterEfficiencyProducer"),
cut = cms.string(""),
name= cms.string("GenFilter"),
doc = cms.string("Generator filter information"),
singleton = cms.bool(True),
extension = cms.bool(False),
variables = cms.PSet(
numEventsTotal = Var("numEventsTotal()", int, doc="generator filter: total number of events", precision=6),
numEventsPassed = Var("numEventsPassed()", int, doc="generator filter: passed number of events", precision=6),
filterEfficiency = Var("filterEfficiency()", float, doc="generator filter: efficiency", precision=14),
filterEfficiencyError = Var("filterEfficiencyError()", float, doc="generator filter: efficiency error", precision=14),
),
)

globalTables = cms.Sequence(rhoTable)
globalTablesMC = cms.Sequence(puTable+genTable)
globalTablesMC = cms.Sequence(puTable+genTable+genFilterTable)