Project

General

Profile

Upcoming feature

Feature #9079: Conditional configuration

As described in Feature #8773-3, there are cases when the allowed configuration should depend on the value of an upstream parameter. For example, consider the two configurations:

# Configuration 1
myVolume : {
   shape : sphere
   centerPosition : [ 0., 0., 0. ] # mm
   radius : 10. # mm
}

#Configuration 2
myVolume : {
   shape : box
   centerPosition : [ 0., 0., 0.  ] # mm
   halfLengths    : [ 5., 5., 10. ] # mm
}

For the first configuration, radius is a required parameter whereas for the second, halfLengths is a required parameter. With current versions of fhicl-cpp, the C++ source code could look like this:

auto const shape = pset.get<string>("shape");
auto const cp    = pset.get<std::array<double,3>>("centerPosition");

if ( shape == "sphere" )
  make_sphere( cp, pset.get<double>("radius") );
else if ( shape == "box" )
  make_box( cp, pset.get<std::array<double,3>>("halfLengths") );

Such a setup is not possible with the fhiclcpp-typed system, unless defaults are specified for radius and halfLengths. This is clearly undesirable. We intend to have functionality so that users could declare something similar to:

struct MyVolume {
  Atom<string> shape { Name("shape") };
  Sequence<double,3> centerPosition { Name("centerPosition") };

  Atom<double>       radius      { Name("radius")     , If( shape() == "sphere" ) };
  Sequence<double,3> halfLengths { Name("halfLengths"), If( shape() == "box"    ) };
}

Table<MyVolume> myVolume { Name("myVolume") };

The exact syntax and behavior under various conditions need to be discussed.