1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#include "FWCore/Framework/interface/maker/ModuleMaker.h"
#include "FWCore/Framework/interface/SignallingProductRegistryFiller.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/Registry.h"
#include "DataFormats/Provenance/interface/ModuleDescription.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/ConvertException.h"
#include "FWCore/Utilities/interface/Exception.h"
#include "FWCore/Utilities/interface/EDMException.h"
#include "FWCore/Utilities/interface/thread_safety_macros.h"
#include <sstream>
#include <exception>
namespace edm {
ModuleMakerBase::~ModuleMakerBase() {}
ModuleDescription ModuleMakerBase::createModuleDescription(MakeModuleParams const& p) const {
ParameterSet const& conf = *p.pset_;
ModuleDescription md(conf.id(),
conf.getParameter<std::string>("@module_type"),
conf.getParameter<std::string>("@module_label"),
p.processConfiguration_.get(),
ModuleDescription::getUniqueID());
return md;
}
void ModuleMakerBase::throwValidationException(MakeModuleParams const& p, cms::Exception& iException) const {
ParameterSet const& conf = *p.pset_;
std::string moduleName = conf.getParameter<std::string>("@module_type");
std::string moduleLabel = conf.getParameter<std::string>("@module_label");
std::ostringstream ost;
ost << "Validating configuration of module: class=" << moduleName << " label='" << moduleLabel << "'";
iException.addContext(ost.str());
throw;
}
void ModuleMakerBase::throwConfigurationException(ModuleDescription const& md, cms::Exception& iException) const {
std::ostringstream ost;
ost << "Constructing module: class=" << md.moduleName() << " label='" << md.moduleLabel() << "'";
iException.addContext(ost.str());
throw;
}
void ModuleMakerBase::validateEDMType(std::string const& edmType, MakeModuleParams const& p) const {
std::string expected = p.pset_->getParameter<std::string>("@module_edm_type");
if (edmType != expected) {
throw Exception(errors::Configuration)
<< "The base type in the python configuration is " << expected << ", but the base type\n"
<< "for the module's C++ class is " << edmType << ". "
<< "Please fix the configuration.\n"
<< "It must use the same base type as the C++ class.\n";
}
}
std::shared_ptr<maker::ModuleHolder> ModuleMakerBase::makeModule(
MakeModuleParams const& p,
signalslot::Signal<void(ModuleDescription const&)>& pre,
signalslot::Signal<void(ModuleDescription const&)>& post) const {
// Add process_name for SwitchProducer
if (p.pset_->getParameter<std::string>("@module_type") == "SwitchProducer") {
p.pset_->addUntrackedParameter("@process_name", p.processConfiguration_->processName());
}
ConfigurationDescriptions descriptions(baseType(), p.pset_->getParameter<std::string>("@module_type"));
fillDescriptions(descriptions);
try {
convertException::wrap([&]() {
descriptions.validate(*p.pset_, p.pset_->getParameter<std::string>("@module_label"));
validateEDMType(baseType(), p);
});
} catch (cms::Exception& iException) {
throwValidationException(p, iException);
}
p.pset_->registerIt();
//Need to be certain top level untracked parameters are stored in
// the registry even if another PSet already exists in the
// registry from a previous process
//NOTE: a better implementation would be to change ParameterSet::registerIt
// but that would require rebuilding much more code so will be done at
// a later date.
edm::pset::Registry::instance()->insertMapped(*(p.pset_), true);
ModuleDescription md = createModuleDescription(p);
std::shared_ptr<maker::ModuleHolder> module;
bool postCalled = false;
try {
convertException::wrap([&]() {
pre(md);
module = makeModule(*(p.pset_));
module->finishModuleInitialization(md, *p.preallocate_, p.reg_);
// if exception then post will be called in the catch block
postCalled = true;
post(md);
});
} catch (cms::Exception& iException) {
if (!postCalled) {
CMS_SA_ALLOW try { post(md); } catch (...) {
// If post throws an exception ignore it because we are already handling another exception
}
}
throwConfigurationException(md, iException);
}
return module;
}
} // namespace edm
|