24#include <TInterpreter.h>
29#include "Gaudi/Interfaces/IOptionsSvc.h"
30#include <GaudiKernel/ServiceHandle.h>
48 std::string makeArrayName (
const std::string& name, std::size_t index)
50 return name +
"@" + std::to_string (index);
56 AsgComponentConfig (
const std::string& val_typeAndName)
63 bool AsgComponentConfig ::
64 empty ()
const noexcept
73 const std::string& AsgComponentConfig ::
74 type ()
const noexcept
81 void AsgComponentConfig ::
82 setType (
const std::string& val_type)
89 const std::string& AsgComponentConfig ::
90 name ()
const noexcept
97 void AsgComponentConfig ::
98 setName (
const std::string& val_name)
105 std::string AsgComponentConfig ::
115 void AsgComponentConfig ::
116 setTypeAndName (
const std::string& val_typeAndName)
118 const auto split = val_typeAndName.find (
'/');
119 if (
split == std::string::npos)
132 void AsgComponentConfig ::
133 setPropertyFromString (
const std::string&
name,
134 const std::string& value)
137 if (
split == std::string::npos)
143 subtool.config->setPropertyFromString (subtool.name, value);
149 StatusCode AsgComponentConfig ::
150 createPrivateTool (
const std::string&
name,
151 const std::string& toolType)
158 std::string AsgComponentConfig ::
159 createPrivateToolInArray (
const std::string&
name,
160 const std::string& toolType)
167 StatusCode AsgComponentConfig ::
168 addPrivateTool (
const std::string&
name,
171 using namespace msgComponentConfig;
174 if (
split == std::string::npos)
178 return StatusCode::SUCCESS;
182 return subtool.config->addPrivateTool (subtool.name, std::move (toolConfig));
188 std::string AsgComponentConfig ::
189 addPrivateToolInArray (
const std::string&
name,
192 using namespace msgComponentConfig;
195 if (
split == std::string::npos)
198 auto myname = makeArrayName (
name, arrayData.size());
201 arrayData.push_back (myname);
206 return subtool.prefix + subtool.config
207 ->addPrivateToolInArray (subtool.name, std::move (toolConfig));
213 StatusCode AsgComponentConfig ::
214 checkTypeName (
bool nestedNames)
const
216 using namespace msgComponentConfig;
218 std::regex typeExpr (
"[A-Za-z_][A-Za-z0-9_]*(::[A-Za-z_][A-Za-z0-9_]*)*");
219 if (!std::regex_match (
m_type, typeExpr))
222 return StatusCode::FAILURE;
226 nameExpr = std::regex (
"[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*(@[0-9]+)?");
228 nameExpr = std::regex (
"[A-Za-z_][A-Za-z0-9_]*(@[0-9]+)?");
229 if (!std::regex_match (
m_name, nameExpr))
232 return StatusCode::FAILURE;
234 return StatusCode::SUCCESS;
240 accessSubtool (
const std::string&
name, std::size_t
split)
245 throw std::runtime_error (
"trying to access unknown private tool: " +
name.substr (0,
split));
246 result.config = &(subtool->second.m_config);
247 result.prefix =
name.substr (0,
split + 1);
254#ifdef XAOD_STANDALONE
257 std::string convert_boost_format_to_std_format(
const std::string& s) {
259 out = std::regex_replace(out, std::regex(
"\\{"),
"{{");
260 out = std::regex_replace(out, std::regex(
"\\}"),
"}}");
262 out = std::regex_replace(out, std::regex(
"%[0-9]+%"),
"{}");
278 constexpr bool noDictionaryFactories =
false;
280 StatusCode createComponent (std::unique_ptr<AsgComponent>& component,
281 const std::string&
type,
282 const std::string& name,
283 const std::string& newCommand)
285 using namespace msgComponentConfig;
287 const auto *factory = getComponentFactory (
type);
291 component = (*factory) (name);
292 if (component ==
nullptr)
295 return StatusCode::FAILURE;
297 return StatusCode::SUCCESS;
300 if (noDictionaryFactories)
302 ANA_MSG_ERROR (
"no component factory for type " << type <<
" (dictionary factories disabled)");
303 return StatusCode::FAILURE;
306 ANA_MSG_DEBUG (
"using dictionary as factory for type " << type);
311 TClass* componentClass = TClass::GetClass (
type.c_str());
314 ATH_MSG_ERROR (
"Unable to load class dictionary for type " << type);
315 return StatusCode::FAILURE;
317 std::string
fmt = convert_boost_format_to_std_format(newCommand);
318 std::string
cmd = std::vformat(
fmt, std::make_format_args(type, name));
319 std::string expr = std::format(
"dynamic_cast<asg::AsgComponent*>({})", cmd);
320 AsgComponent *
comp =
reinterpret_cast<AsgComponent*
>(gInterpreter->Calc(expr.c_str()));
323 ANA_MSG_ERROR (
"failed to create component of type " << type);
324 ANA_MSG_ERROR (
"make sure you created a dictionary for your component");
325 return StatusCode::FAILURE;
327 component.reset (comp);
329 return StatusCode::SUCCESS;
336 makeComponentExpert<AsgComponent> (std::unique_ptr<AsgComponent>& component,
337 const std::string& newCommand,
338 bool nestedNames, std::string prefix)
const
340 using namespace msgComponentConfig;
346 if (!createComponent (component, m_type, name, newCommand).isSuccess())
347 return StatusCode::FAILURE;
349 for (
auto& toolInfo : m_privateTools)
351 ToolHandle<AsgTool>
th (toolInfo.first, component.get());
352 std::shared_ptr<void> mycleanup;
355 ANA_MSG_ERROR (
"failed to create subtool \"" << toolInfo.first <<
"\" on component \"" << component->name() <<
"\"");
356 return StatusCode::FAILURE;
358 component->addCleanup (mycleanup);
359 if (toolInfo.second.m_propName.empty())
361 if (component->setProperty (toolInfo.first,
th->name()).isFailure())
363 ANA_MSG_ERROR (
"failed to set ToolHandle property \"" << toolInfo.first <<
"\" on component \"" << component->name() <<
"\"");
364 return StatusCode::FAILURE;
369 for (
const auto& toolArray : m_toolArrays)
371 std::vector<std::string> valueArray;
372 for (
const auto& tool : toolArray.second)
373 valueArray.emplace_back (component->name() +
"." + tool);
374 std::string valueString;
375 ANA_CHECK (asg::detail::GetCastStringHelper<std::vector<std::string>>
::get (valueArray, valueString));
376 ANA_CHECK (component->setProperty (toolArray.first, valueString));
379 for (
auto& property : m_propertyValues)
381 ANA_CHECK (component->setProperty (property.first, property.second));
385 return StatusCode::SUCCESS;
394 StatusCode AsgComponentConfig ::
395 configureComponentExpert (
const std::string& prefix,
396 bool nestedNames)
const
398 using namespace msgComponentConfig;
407 ANA_CHECK (tool.second.m_config.configureComponentExpert (prefix +
m_name +
".",
true));
408 if (tool.second.m_propName.empty())
410 std::string toolPath = prefix +
m_name +
"." + tool.first;
411 joSvc->set (toolPath, tool.second.m_config.typeAndName());
417 std::vector<std::string> valueArray;
418 for (
const auto& tool : toolArray.second)
423 ANA_MSG_ERROR (
"Couldn't find private tool with name \"" << tool <<
"\"");
425 return StatusCode::FAILURE;
427 valueArray.push_back (toolConfig->second.m_config.typeAndName());
429 std::string valueString = Gaudi::Utils::toString (valueArray);
430 std::string propertyPath = prefix +
m_name +
"." + toolArray.first;
431 joSvc->set (propertyPath, valueString);
436 std::string propertyPath = prefix +
m_name +
"." +
property.first;
437 joSvc->set (propertyPath, property.second);
440 return StatusCode::SUCCESS;
std::string addPrivateToolInArray(const std::string &name, AsgComponentConfig toolConfig)
the array version of addPrivateTool
std::string m_type
the value of type
std::map< std::string, std::string > m_propertyValues
the map of property values
std::map< std::string, details::AsgComponentPrivateToolConfig > m_privateTools
the map of (private) tools to create
const std::string & name() const noexcept
the name of the component
void setType(const std::string &val_type)
set the value of type
void setTypeAndName(const std::string &val_typeAndName)
set type and name at the same time
AsgComponentConfig()=default
standard constructor
StatusCode checkTypeName(bool nestedNames) const
check that the type and name members have the correct format
AccessSubtoolData accessSubtool(const std::string &name, std::size_t split)
StatusCode addPrivateTool(const std::string &name, AsgComponentConfig toolConfig)
add a private tool from the given configuration
std::string m_name
the value of name
void setName(const std::string &val_name)
set the value of name
std::map< std::string, std::vector< std::string > > m_toolArrays
the map of (private) tool handle arrays to manage, and the tools they contain
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
std::vector< std::string > split(const std::string &s, const std::string &t=":")
std::string m_name
The primary name part of this expression.
::StatusCode StatusCode
StatusCode definition for legacy code.