Project

General

Profile

Fhiclcpp types in detail » History » Version 21

« Previous - Version 21/56 (diff) - Next » - Current version
Kyle Knoepfel, 09/14/2015 04:32 PM


fhiclcpp types in detail


Parameter constructors

General rules

For each of the fhiclcpp types, the following rules apply:
  • The Name argument is required.
  • If there is more than one argument, the Name argument must be first in the list.
  • If there are three arguments, the relative order of the Comment argument and default-value argument is not important.
    Atom<int> val { Name("val"), Comment("Some parameter"), 9 }; // is equivalent to
    Atom<int> val { Name("val"), 9, Comment("Some parameter") };
    
  • The Table<T> parameter does not support a default value.

Atom<T>

Atom<int> var { Name("var") };
Atom<int> var { Name("var"), 9 };
Atom<int> var { Name("var"), Comment("A parameter description") };
Atom<int> var { Name("var"), Comment("A parameter description"), 9 };

Sequence<T>

This class template is used for unbounded sequences. See the two caveats below.

Sequence<int> seq { Name("seq") };
Sequence<int> seq { Name("seq"), Comment("A sequence") };
Sequence<int> seq { Name("seq"), Sequence<int>{ 4, 5, 6, 7 } };
Sequence<int> seq { Name("seq"), { 4, 5, 6, 7 } };
Sequence<int> seq { Name("seq"), Comment("A sequence"), Sequence<int>{ 4, 5, 6, 7 } };
Sequence<int> seq { Name("seq"), Comment("A sequence"), { 4, 5, 6, 7 } };

Sequence<T>::make_empty()

Due to the implementation details of the unbounded sequence, the following:

Sequence<int> seq { Name("seq"), Sequence<int>{} }; // Don't do this.

does not represent an empty sequence. If you would like an empty sequence as a default value, use the following:

Sequence<int> seq { Name("seq"), Sequence<int>::make_empty() };

Precaution regarding narrowing conversions and std::initializer_list objects

The following configuration will trigger a compilation warning:

Sequence<int> seq1 { Name("seq1"), Sequence<int>{ 1, 2.4e-4 } };
Sequence<int> seq2 { Name("seq2"), { 1, 2.4e-4 } };

that looks similar to this:

warning: narrowing conversion of ‘2.4000000000000001e-4’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]

For build systems that convert compile-time warnings to errors, this will result in a build failure. The warning results from the nature of an std::initializer_list object, signified by '{1, 2.4e-4}', which is used to initialize the sequence objects. For std::initializer_list objects, narrowing conversions are not allowed--that is, converting a double to an int is an example of narrowing that results in loss of information. This is the most likely example of where you may find a narrowing conversion.

Sequence<T,std::size_t>

This class template is used for sequences of a specific length, known at compile time.

Sequence<int,3u> seq { Name("seq") };
Sequence<int,3u> seq { Name("seq"), Comment("A sequence") };
Sequence<int,3u> seq { Name("seq"), Sequence<int,3u>{ 4, 5, 6 } };
Sequence<int,3u> seq { Name("seq"), { 4, 5, 6 } };
Sequence<int,3u> seq { Name("seq"), Comment("A sequence"), Sequence<int,3u>{ 4, 5, 6 } };
Sequence<int,3u> seq { Name("seq"), Comment("A sequence"), { 4, 5, 6 } };

The warning regarding narrowing conversions above applies for bounded sequences as well.

Tuple<T...>

Tuple<string,bool> tuple { Name("tuple") };
Tuple<string,bool> tuple { Name("tuple"), Comment("A tuple") };
Tuple<string,bool> tuple { Name("tuple"), Tuple<string,bool>{"explicit?", true} };
Tuple<string,bool> tuple { Name("tuple"), {"compact?", true } };
Tuple<string,bool> tuple { Name("tuple"), Comment("A tuple"), Tuple<string,bool>{ "Particle physics is neat.", true } };
Tuple<string,bool> tuple { Name("tuple"), Comment("A tuple"), { "This is false", false } };

Table<T>

Table<T> config { Name("config") };
Table<T> config { Name("config"), Comment("This describes the table") };

Return types

fhiclcpp parameter Function call Return type
Simple fhiclcpp parameters
Atom<std::string> label; label() std::string const&
Sequence<int> counts; counts() std::vector<int>
counts(1) int
Sequence<double, 3u> point; point() std::array<double, 3u>
point(0) double
Tuple<std::string, double> assoc; assoc() std::tuple<std::string, double>
assoc.get<0>() std::string
assoc.get<double>() double
Table<Config> config; config() Config const&
Nested fhiclcpp parameters
Sequence< Sequence<int> > datasets; datasets() std::vector< std::vector<int> >
datasets(17) std::vector<int>
Sequence< Sequence<int>, 2u > twoDatasets; twoDatasets() std::array< std::vector<int>, 2u >
twoDatasets(1) std::vector<int>
Sequence< Sequence<int, 2u> > intPairs; intPairs() std::vector< std::array<int, 2u> >
intPairs(42) std::array<int, 2u>
Sequence< Tuple<std::string, int, bool> > triplets; triplets() std::vector< std::tuple<std::string, int, bool> >
triplets(3) std::tuple<std::string, int, bool>
Sequence< Table<Config> > manyConfigTables; manyConfigTables() std::vector< Config >
manyConfigTables(6) Config const&
Tuple< std::string, Table<Config> > configAssoc; configAssoc() std::tuple< std::string, Config >
configAssoc.get<0>() std::string
configAssoc.get<std::string>() std::string
configAssoc.get<1>() Config
configAssoc.get< Table<Config> >() Config
Tuple< Tuple<std::string,bool>, Sequence<int> > awkward; awkward() std::tuple< std::tuple<std::string, bool>, std::vector<int> >
awkward.get<0>() std::tuple<std::string,bool>
awkward.get<1>() std::vector<int>

Additional functions for Table<T>

The Table template offers a few extra functions that the user can call:

fhicl::ParameterSet const& get_PSet() const;

void print_allowed_configuration(std::ostream& os,
                                 std::string const& tab = std::string(3,' ') ) const;

// Expert-level functions
void validate_ParameterSet(fhicl::ParameterSet const& pset,
                           std::set<std::string> const& keysToIgnore = {} );

void set_PSet( fhicl::ParameterSet const& pset );

get_PSet

A call to this function returns a const reference to the ParameterSet object that was used to fill the values of the individual Table members. This is helpful for users who need to interact with the ParameterSet object itself.

print_allowed_configuration

For any Table<Config> object, print_allowed_configuration will fill a user-supplied std::ostream object with the allowed configuration as defined by the Config struct. The optional second argument specifies the number of spaces per indentation. The default is 3 spaces but is, of course, user-configurable.

validate_ParameterSet (expert)

This function is intended for experts who need to validate the pset object themselves. The keysToIgnore variable represents a set of keys for which the validation step will ignore. The validation function will ignore any nested keys as well--i.e. if a user specifies an ignorable key as table1, the (e.g.) table1.someAtom key would be ignored in addition to just the table1 name. An indexed parameter (e.g.) seq[1] is considered a nested parameter of its parent seq. Providing or not providing the ignorable key in a configuration will lead to no error upon validation of the ParameterSet.

set_PSet (expert)

Common parameter accessors

Each of the fhiclcpp types has the following accessors:

std::string key()            const;
std::string comment()        const;
bool        has_default()    const;
par_type    parameter_type() const;

To call these functions, the difference in syntax is crucial:

Atom<int> val { Name("val") };

auto key1 = val.key();   //   correct
auto key2 = val().key(); // ! compile-time ERROR - 'val()' is an int, which has no accessor called 'key()' 

key()

A call to key() returns the full key, including all enclosing tables. For example, consider a module that is designed to allow the following configuration:

pset: {
  list: [ { particle: electron },
          { particle: muon } ]
}
For a suitably declared set of fhiclcpp parameters, the returned key corresponding to "muon" would be pset.list[1].particle.

N.B. The returned value is different than the relative name that is supplied in the Name("val") argument to the fhiclcpp parameter constructor.

[ The following three functions are used primarily by the validation/description system. Although they are not likely to be directly helpful for the user, the user is still permitted to call them. ]

comment()

Returns the comment supplied as the string literal in (e.g.) Comment("Here is the comment"). If no Comment argument is provided in the fhiclcpp parameter constructor, a call to this function returns an empty string.

has_default()

Returns true or false depending on whether the user supplied a default value for the parameter.

parameter_type()

Returns an enumeration value based on the parameter type:

enum class par_type {
  ATOM,        // Atom<T>
  TABLE,       // Table<T>
  SEQ_VECTOR,  // Sequence<T>
  SEQ_ARRAY,   // Sequence<T,std::size_t>
  TUPLE,       // Tuple<T...>
  NTYPES       // Signifies invalid parameter 
};