Configuration validation and description¶
- Table of contents
- Configuration validation and description
- Validation and description use in user code
- Validation and description use in art-provided facilities
Validation and description use in user code¶
Guidelines for defining the configuration¶
The documentation for defining an allowed configuration is given here. Here, we will consider how the configuration should be defined in different contexts.
Configurations in header files¶
If your configuration needs to be used in multiple places, you can place the configuration in a header file. However, you should not invoke a using
directive (e.g. using namespace fhicl
). Rather, you must qualify the types with their fhiclcpp
namespace:
namespace yours {
struct MyConfig {
fhicl::Atom<int> threshold { fhicl::Name("threshold") };
fhicl::Atom<std::string> tagLabel { fhicl::Name("tagLabel") };
fhicl::Sequence<int,3u> offset { fhicl::Name("offset") };
};
}
For lengthy configurations, it is safe to include type/template aliases within the configuration definition:
namespace yours {
struct MyConfig {
// aliases (these are NOT 'using' directives)
using Name = fhicl::Name;
template<typename T>
using Atom = fhicl::Atom<T>;
template<typename T, std::size_t SZ>
using Sequence = fhicl::Sequence<T,SZ>;
// configuration
Atom<int> threshold { Name("threshold") };
Atom<std::string> tagLabel { Name("tagLabel") };
Sequence<int,3u> offset { Name("offset") };
// etc.
};
}
Configurations local to the plugin¶
For configurations that do not need to be shared with other files, they should be placed in an anonymous namespace local to the source file:
// MyModule_module.cc
namespace {
using namespace fhicl;
struct MyConfig {
Atom<int> threshold { Name("threshold") };
Atom<std::string> tagLabel { Name("tagLabel") };
Sequence<int,3u> offset { Name("offset") };
};
}
namespace experiment {
class MyModule : public art::EDAnalyzer { ... };
}
DEFINE_ART_MODULE(experiment::MyModule);
By placing the configuration in an anonymous namespace, this ensures that the MyConfig
definition is local to the library corresponding to this source file. If the MyConfig
definition is placed inside of the experiment
namespace, and if another module places a different MyConfig
struct
definition in the experiment
namespace, then the library-loading system will likely not invoke the correct definition for each module.
art
-provided and -injected parameters¶
Provided parameters¶
For all modules, a required FHiCL parameter is module_type
, followed by a string of characters corresponding to prefix
of the dynamic library prefix_module.so
. Because of this requirement, art
provides the parameter declaration for the user, and the user does not have to specify a declaration like:
Atom<string> module_type { Name("module_type") }; // Not required
If the user does specify such a parameter, the program will execute correctly, although the description will specify 'module_type'
twice in the printout.
Injected parameters¶
The art
executable injects various parameters into the fhicl::ParameterSet
object, depending on the context. For example, the post-processed configuration corresponding to:
label: { module_type: MyModule }
will be
label: { module_type : MyModule module_label: "label" # inserted by 'art' }
The user is not required to specify these injected parameters in his/her configuration. In general, the parameters are not even accessible unless one interacts with the fhicl::ParameterSet
object itself via a call to pset.get<std::string>("module_label")
.
Since the injected parameters are meant to be internal to art
, we do not explicitly list each of them here.
Enabling configuration validation¶
For the following cases, all validation is enabled by declaring a constructor that receives a Table
argument instead of a ParameterSet
one. The validation will be performed just prior to module/service construction. If there is a configuration error, the following type of message will be sent to STDOUT, and the program will terminate.
---- Configuration BEGIN ==================================================================================================== !! The following modules have been misconfigured: !! ---------------------------------------------------------------------------------------------------- Module label: m1a module_type : IntProducer Missing parameters: - ivalue : <int> Unsupported parameters: + ivalu [ ./test_simple_01.fcl:50 ] ==================================================================================================== ---- Configuration END
In this case, a user attempted to supply a value for ivalue
, but misspelled the parameter.
For all modules, the appropriate Table
class templates are provided automatically by the corresponding producer, filter, or analyzer header file.
Producers¶
#include "art/Framework/Core/EDProducer.h"
// ... hopefully in a namespace ...
struct Config { ... }; // fhicl-cpp parameter declarations
class MyProducer : public art::EDProducer {
explicit MyProducer(art::EDProducer::Table<Config> const& config);
};
Filters¶
#include "art/Framework/Core/EDFilter.h"
// ... hopefully in a namespace ...
struct Config { ... }; // fhicl-cpp parameter declarations
class MyFilter : public art::EDFilter {
explicit MyFilter(art::EDFilter::Table<Config> const& config);
};
Analyzers¶
#include "art/Framework/Core/EDAnalyzer.h"
// ... hopefully in a namespace ...
struct Config { ... }; // fhicl-cpp parameter declarations
class MyAnalyzer : public art::EDAnalyzer {
explicit MyAnalyzer(art::EDAnalyzer::Table<Config> const& config);
};
Results producers (validation/description supported as of art 2.11.00)¶
#include "art/Framework/Core/ResultsProducer.h"
// ... hopefully in a namespace ...
struct Config { ... }; // fhicl-cpp parameter declarations
class MyAnalyzer : public art::ResultsProducer {
explicit MyAnalyzer(art::ResultsProducer::Table<Config> const& config);
};
Services¶
For services, the relevant table must be explicitly #include
d.
#include "art/Framework/Services/Registry/ServiceTable.h"
// ... hopefully in a namespace ...
struct Config { ... }; // fhicl-cpp parameter declarations
class MyService {
explicit MyService(art::ServiceTable<Config> const& config,
art::ActivityRegistry& aReg);
};
Ignoring keys during validation¶
As described here, specific keys can be ignored during validation if a suitable type is supplied. For example:
struct KeysToIgnore {
std::set<std::string> operator()()
{
return {"myTable1", "mySequence", "myTable2.mySequence"};
}
};
indicates to the validation system that myTable1
(and its members), mySequence
and myTable2.mySequence
are permitted to be present, in addition to the supported configuration. To make use of this feature, provide the KeysToIgnore
type as an additional template argument to any of the art
-provided tables:
art::EDProducer::Table<T> |
= Replaced by => | art::EDProducer::Table<T, KeysToIgnore> |
art::EDFilter::Table<T> |
art::EDFilter::Table<T, KeysToIgnore> |
|
art::EDAnalyzer::Table<T> |
art::EDAnalyzer::Table<T, KeysToIgnore> |
|
art::ResultsProducer::Table<T> |
art::ResultsProducer::Table<T, KeysToIgnore> |
|
art::ServiceTable<T> |
art::ServiceTable<T, KeysToIgnore> |
The KeysToIgnore
type must contain an operator()()
function that returns an std::set<std::string>
object.
N.B. Supplying a KeysToIgnore
type yields different behavior than the (Optional)DelegatedParameter
class, which is explained here.
Required configuration validation for users¶
An unintentional consequence of enabling configuration validation for art
-provided modules (see below) is that users who provide a detail class to art::ProvenanceDumper
must provide a configuration struct
named Config
. For example:
class PDDetail {
// The configuration here MUST be called 'Config'
struct Config : art::ProvenanceDumperConfig {
fhicl::Atom<bool> flag { fhicl::Name("flag"), false };
fhicl::Atom<int> num { fhicl::Name("num"), 2 };
};
explicit PDDetail(art::OutputModule::Table<Config> const & ps)
: flag_{ps().flag()}
, num_{ps().num()}
{}
// ...
}
The inheritance from art::ProvenanceDumperConfig
is, strictly speaking, not necessary. The constructor for the detail class is permitted to receive the fhicl::Parameter const& pset
argument, although there is not much benefit in doing so since configuration validation must be enabled anyway. It is permitted to have an empty Config
struct
if no FHiCL parameters are used in the detail class.
A fix has been committed so that configuration validation will not be required for ProvenanceDumper
detail classes. This will be included with a future art
release.
Enabling description printouts¶
Enabling configuration description requires introducing the Parameters
typedef
or type alias. For an analyzer,
class MyAnalyzer : public art::EDAnalyzer {
// The following type alias is necessary to provide
// a description of the allowed configuration
using Parameters = art::EDAnalyzer::Table<MyConfig>;
MyAnalyzer( Parameters const& config ) : ... {}
};
The presence of the type alias allows the description-printing system to find the relevant configuration. No other steps are necessary. As an example, for the IntProducer
module referenced above and an additional module called IntTestAnalyzer
, the following descriptions are printed:
[knoepfel@woof build-art-prof]$ art --print-description IntProducer IntTestAnalyzer ==================================================================================================== module_type : IntProducer (or "test/Integration/IntProducer") provider: user type : producer source : /home/knoepfel/art/test/Integration/IntProducer_module.cc library : /home/knoepfel/scratch/build-art-prof/lib/libtest_Integration_IntProducer_module.so Allowed configuration --------------------- module_label: { module_type: IntProducer errorOnFailureToPut: true # default ivalue: <int> branchType: 0 # default } ==================================================================================================== module_type : IntTestAnalyzer (or "test/Integration/IntTestAnalyzer") provider: user type : analyzer source : /home/knoepfel/art/test/Integration/IntTestAnalyzer_module.cc library : /home/knoepfel/scratch/build-art-prof/lib/libtest_Integration_IntTestAnalyzer_module.so Allowed configuration --------------------- [ None provided ] ====================================================================================================
Note that for modules that have not provided a Parameters
type alias/typedef
, no configuration can be provided.
Validation and description use in art
-provided facilities¶
As agreed to by the art
stakeholders, art
enables configuration validation and description for art
-provided facilities.
Modules¶
All art
-provided modules (e.g. RootOutput
, RandomNumberSaver
, etc.) enable configuration validation and description.
Services¶
As of art 2.08, all art
-provided services (e.g. TimeTracker
, message
, etc.) enable configuration validation and description.
Sources¶
The EmptyEvent
and RootInput
sources also use configuration validation. The EmptyEvent
source allows an optional configuration-specified plugin called timestampPlugin
, for which configuration validation and description are not yet supported. The configuration validation and description system is also not yet supported for detail arguments ('T'
) to the art::Source<T>
template.
Other plugins¶
There are other plugins that are recognized by art
's library manager system. If you have need of enabling configuration validation and description for them, please contact artists@fnal.gov.