Parameterizing a factory
Last updated on 2026-07-10 | Edit this page
Estimated time: 5 minutes
Overview
Questions
- How do I give a factory configurable parameters?
- How do I override those parameters from a generator or the command line?
- How do I access services such as geometry from a factory?
Objectives
- Learn how to set parameters on a factory.
- Learn how to override factories via a generator.
- Learn how to override factories via the command line.
- Learn how to access services from a factory.
Setting parameters on a factory
Parameters are also handled using registered members. JOmniFactory
provides a Parameter class template which can hold its own
value, but in EICrecon we prefer to use Config structs. Thus
JOmniFactory provides ParameterRef, which stores a
reference into the Config object.
CPP
ParameterRef<double> m_samplingFraction {this, "samplingFraction", config().sampFrac};
ParameterRef<std::string> m_energyWeight {this, "energyWeight", config().energyWeight};
Parameters are fetched immediately before Configure() is
called, so you may access them from any of the callbacks like so:
CPP
void Process(int32_t run_number, uint64_t event_number) {
logger()->debug( "Event {}: samplingFraction = {}", event_number, m_samplingFraction() );
}
Because we are using ParameterRefs, we can also access the field the ref points to directly:
Config objects
We create a plain-old struct to hold our parameters. For now this config struct can live in the same header file as our factory, although eventually it should belong with the algorithm instead.
By passing it in to the JOmniFactory base class, we can make it
automatically available via the config() method.
Overriding parameters via a generator
If you use a Config object for your parameters, you can pass it in directly to the factory generator:
Overriding parameters via the command line
We can override parameters on the command line like so:
Accessing services from a factory
Services are singletons that provide access to resources such as
loggers, geometry, magnetic field maps, etc. Services need to be
thread-safe because they are shared by different threads. The most
relevant service right now is DD4hep_service. You obtain a
service using a registered member like this:
Oftentimes we want to retrieve a resource from a Service and refresh
it whenever the run number changes. OmniFactory provides
Resource for this purpose.
Exercise
- Give your factory a Config struct.
- Give your Config struct some parameters.
- Experiment with overriding parameter values in the generator and on the command line.
Add a struct with a couple of fields (for example a
double threshold) and pass it as the second template
argument to JOmniFactory. Register
ParameterRef members pointing at those fields. You can then
set them in the generator with brace-initialization
({.threshold = 6.1}) or on the command line with
-P<prefix>:threshold=12.0; the command-line value
takes precedence.
- Parameters are registered members; in EICrecon we back them with a
Config struct via
ParameterRef. - Pass the Config type as the second
JOmniFactorytemplate argument to make it available throughconfig(). - Override parameters in the generator with brace-initialization, or
on the command line with
-P<prefix>:<name>=<value>. - Access shared resources (geometry, fields) through thread-safe
Servicemembers.