Skip to content

Tools belonging to Algorithms with multiple ToolHandles not configured correctly

If an Algorithm has multiple ToolHandle properties of the same type, configuring the tool with certain names causes the configuration not to appear in the final options.

Example

Take this configuration:

from Configurables import (
    Gaudi__Examples__FloatTool as FloatTool,
    Gaudi__Examples__THDoubleToolOwner as DoubleToolOwner,
)

tool1 = FloatTool(name="Gaudi::Examples::THDoubleToolOwner.Gaudi::Examples::FloatTool", OutputLevel=1)
reader = DoubleToolOwner(FloatTool1=tool1)

The FloatTool has been configured with a name that makes it a private tool of the owning algorithm. The owning algorithm is something that declares two handles to the same type:

ToolHandle<FloatTool> m_floatTool1{this, "FloatTool1", "Gaudi::Examples::FloatTool"};
ToolHandle<FloatTool> m_floatTool2{this, "FloatTool2", "Gaudi::Examples::FloatTool"};

Running the configuration — with gaudirun.py -o opts.py example.py — generates these options (the contents of opts.py):

{'Gaudi::Examples::THDoubleToolOwner': {'FloatTool1': 'Gaudi::Examples::FloatTool/Gaudi::Examples::FloatTool',
                                        'FloatTool2': 'Gaudi::Examples::FloatTool/Gaudi::Examples::FloatTool'}}

The custom configuration (OutputLevel=1) of the tool is missing! This is the problem.


Workarounds

Not setting the tool's name produces options like one would expect. This configuration:

from Configurables import (
    Gaudi__Examples__FloatTool as FloatTool,
    Gaudi__Examples__THDoubleToolOwner as DoubleToolOwner,
)

tool1 = FloatTool(OutputLevel=1)
reader = DoubleToolOwner(FloatTool1=tool1)

produces these options:

{'Gaudi::Examples::THDoubleToolOwner': {'FloatTool1': 'Gaudi::Examples::FloatTool/Gaudi::Examples::FloatTool',
                                        'FloatTool2': 'Gaudi::Examples::FloatTool/Gaudi::Examples::FloatTool'},
 'Gaudi::Examples::THDoubleToolOwner.Gaudi::Examples::FloatTool': {'OutputLevel': 1},
 'ToolSvc.Gaudi::Examples::FloatTool': {'OutputLevel': 1}}

Similarly, one can set the tool's name to something other than it's class name:

from Configurables import (
    Gaudi__Examples__FloatTool as FloatTool,
    Gaudi__Examples__THDoubleToolOwner as DoubleToolOwner,
)

tool1 = FloatTool(name="Gaudi::Examples::THDoubleToolOwner.Foo", OutputLevel=1)
reader = DoubleToolOwner(FloatTool1=tool1)

and this also produces expected options (although slightly more compact, because the public tool instance is not created):

{'Gaudi::Examples::THDoubleToolOwner': {'FloatTool1': 'Gaudi::Examples::FloatTool/Foo',
                                        'FloatTool2': 'Gaudi::Examples::FloatTool/Gaudi::Examples::FloatTool'},
 'Gaudi::Examples::THDoubleToolOwner.Foo': {'OutputLevel': 1}}

Algorithms with single tools

Algorithms that hold only a single tool of a given type do not have this problem:

from Configurables import (
    Gaudi__Examples__FloatTool as FloatTool,
    Gaudi__Examples__THDataConsumer as SingleToolOwner,
)

# Named as a private tool and using the tool's type
tool = FloatTool(name="Gaudi::Examples::THDataConsumer.Gaudi::Examples::FloatTool", OutputLevel=1)
reader = SingleToolOwner(FloatTool=tool)

produces these options:

{'Gaudi::Examples::THDataConsumer': {'FloatTool': 'Gaudi::Examples::FloatTool/Gaudi::Examples::FloatTool'},
 'Gaudi::Examples::THDataConsumer.Gaudi::Examples::FloatTool': {'OutputLevel': 1}}

Double tool declaration

The double-tool algorithm declares its properties as given above.

I can instead make each (default) tool name unique:

ToolHandle<FloatTool> m_floatTool1{this, "FloatTool1", "Gaudi::Examples::FloatTool/FloatTool1"};
ToolHandle<FloatTool> m_floatTool2{this, "FloatTool2", "Gaudi::Examples::FloatTool/FloatTool2"};

In this case, a configuration similar to that which produces the original wrong configuration now goes away, i.e. this configuration:

from Configurables import (
    Gaudi__Examples__FloatTool as FloatTool,
    Gaudi__Examples__THDoubleToolOwner as DoubleToolOwner,
)

tool1 = FloatTool(name="Gaudi::Examples::THDoubleToolOwner.Gaudi::Examples::FloatTool/FloatTool1", OutputLevel=1)
reader = DoubleToolOwner(FloatTool1=tool1)

produces these options:

{'Gaudi::Examples::THDoubleToolOwner': {'FloatTool1': 'Gaudi::Examples::FloatTool/Gaudi::Examples::FloatTool/FloatTool1',
                                        'FloatTool2': 'Gaudi::Examples::FloatTool/FloatTool2'},
 'Gaudi::Examples::THDoubleToolOwner.Gaudi::Examples::FloatTool/FloatTool1': {'OutputLevel': 1}}

Questions

  1. When there are multiple same-type ToolHandles with identical defualt names, should the configuration of the tool with its default name be ignored?
  2. Should the declaration of two same-type ToolHandle properties always have different default name, given the observed behaviour?
    • Or is this a sign of a bug in the Configurables logic somewhere?
    • Or a bug in the Algorithm/ToolHandle constructor?

/cc @nnolte

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information