ATLAS Offline Software
Loading...
Searching...
No Matches
AnaToolHandle.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7
8
9//
10// includes
11//
12
15#include <mutex>
16
17#include "AsgTools/ToolStore.h"
18
19#ifdef XAOD_STANDALONE
20#include <TInterpreter.h>
21#include <TROOT.h>
22#include <regex>
23#else
24#include <GaudiKernel/AlgTool.h>
26#include <GaudiKernel/IToolSvc.h>
27#include "Gaudi/Interfaces/IOptionsSvc.h"
28#endif
29
30//
31// method implementations
32//
33
34namespace asg
35{
36 namespace detail
37 {
38 AnaToolShare ::
39 AnaToolShare (const ToolHandle<interfaceType_t>& val_th,
40 std::shared_ptr<void> val_cleanup,
41 std::vector<std::function<StatusCode ()>>&& extraInit)
42 : m_th (val_th), m_extraInit (std::move (extraInit)), m_cleanup (std::move (val_cleanup))
43 {
44 assert (!m_th.empty());
45 }
46
47
48
49 ToolHandle<interfaceType_t>& AnaToolShare ::
50 th ()
51 {
52 assert (!m_th.empty());
53 return m_th;
54 }
55
56
57
58 AnaToolShareList& AnaToolShareList ::
59 singleton () noexcept
60 {
61 static AnaToolShareList result ATLAS_THREAD_SAFE;
62 return result;
63 }
64
65
66
67 std::shared_ptr<AnaToolShare> AnaToolShareList ::
68 getShare (const std::string& name) const
69 {
70 lock_t lock (m_mutex);
71 auto iter = m_shared.find (name);
72 if (iter == m_shared.end())
73 return std::shared_ptr<AnaToolShare> ();
74 return iter->second.lock();
75 }
76
77
78
79 std::shared_ptr<AnaToolShare> AnaToolShareList ::
80 setShare (const std::string& name,
81 std::unique_ptr<AnaToolShare> val_share)
82 {
83 lock_t lock (m_mutex);
84 std::shared_ptr<AnaToolShare> result = getShare (name);
85 if (result != nullptr)
86 return result;
87 result.reset (val_share.release ());
88 m_shared[name] = result;
89 return result;
90 }
91
92
93
94 StatusCode AnaToolShareList ::
95 makeShare (const std::string& name,
96 const AsgToolConfig& config,
97 std::vector<std::function<StatusCode ()>>&& extraInit,
98 std::shared_ptr<AnaToolShare>& result)
99 {
100 lock_t lock (m_mutex);
101 using namespace msgToolHandle;
102
103 auto& share = m_shared[name];
104 auto res_result = share.lock();
105 if (res_result != nullptr)
106 {
107 result = std::move(res_result);
108 return StatusCode::SUCCESS;
109 }
110 ToolHandle<interfaceType_t> th;
111 std::shared_ptr<void> cleanup;
112 for (auto& init : extraInit)
113 ANA_CHECK (init());
114 ANA_CHECK (config.makeTool (th, cleanup, true));
115 ANA_MSG_DEBUG ("made shared tool with " << extraInit.size() << " inits for TH: " << th);
116 res_result.reset (new AnaToolShare (th, std::move(cleanup), std::move (extraInit)));
117#ifndef XAOD_STANDALONE
118 if (!th.empty())
119 {
120 th->release ();
121 }
122#endif
123 assert (share.lock() == nullptr);
124 share = res_result;
125 result = std::move(res_result);
126 return StatusCode::SUCCESS;
127 }
128 }
129}
130
131//
132// legacy code
133//
134
135#ifdef XAOD_STANDALONE
136
137namespace asg
138{
139 namespace detail
140 {
141 StatusCode makeToolRootCore (const std::string& type,
142 const std::string& name,
143 AsgTool*& tool)
144 {
145 using namespace msgToolHandle;
146
147 std::regex typeExpr ("[A-Za-z_][A-Za-z0-9_]*(::[A-Za-z_][A-Za-z0-9_]*)*");
148 if (!std::regex_match (type, typeExpr))
149 {
150 ANA_MSG_ERROR ("type \"" << type << "\" does not match format expression");
151 return StatusCode::FAILURE;
152 }
153 std::regex nameExpr ("[A-Za-z_][A-Za-z0-9_]*((\\.|::)[A-Za-z_][A-Za-z0-9_]*)*(@[0-9]+)?");
154 if (!std::regex_match (name, nameExpr))
155 {
156 ANA_MSG_ERROR ("name \"" << name << "\" does not match format expression");
157 return StatusCode::FAILURE;
158 }
159
160 // Load the ROOT dictionary. Apparently that is needed in some
161 // cases to make the line below work, i.e. some dictionaries
162 // work, other dictionaries fail.
163 for (const char *typeName : {"asg::AsgTool", type.c_str()})
164 {
165 TClass* toolClass = TClass::GetClass (typeName);
166 if(!toolClass){
167 ANA_MSG_ERROR("Unable to load class dictionary for type " << type);
168 return StatusCode::FAILURE;
169 }
170 }
171
172 ANA_MSG_DEBUG ("Creating tool of type " << type);
173 tool = (AsgTool*) (gInterpreter->Calc(("dynamic_cast<asg::AsgTool*>(new " + type + " (\"" + name + "\"))").c_str()));
174 if (tool == nullptr)
175 {
176 ANA_MSG_ERROR ("failed to create tool of type " << type);
177 ANA_MSG_ERROR ("make sure you created a dictionary for your tool");
178 return StatusCode::FAILURE;
179 }
180
181 ANA_MSG_DEBUG ("Created tool of type " << type);
182
183 return StatusCode::SUCCESS;
184 }
185 }
186}
187
188#else
189
190namespace asg
191{
192 namespace detail
193 {
194 StatusCode hasPropertiesInCatalogue( const std::string& toolName ) {
195 ServiceHandle<Gaudi::Interfaces::IOptionsSvc> svc("JobOptionsSvc","AnaToolHandle");
196 if( svc.retrieve().isFailure() ) return StatusCode::FAILURE;
197 auto props = svc->items(std::regex("^" + toolName + "\\."));
198 StatusCode out = StatusCode::FAILURE;
199 for (auto& prop : svc->items())
200 {
201 if (std::get<0>(prop).substr (0, toolName.size()) == toolName &&
202 std::get<0>(prop)[toolName.size()] == '.')
203 out = StatusCode::SUCCESS;
204 }
205 svc.release().ignore();
206 //delete props;
207 return out;
208 }
209
210 StatusCode addPropertyToCatalogue( const std::string& toolName, const std::string& propertyName, const std::string& propertyValue ) {
211//std::cout << "Adding " << toolName << " ." << propertyName << " = " << propertyValue << std::endl;
212 ServiceHandle<Gaudi::Interfaces::IOptionsSvc> joSvc("JobOptionsSvc","AnaToolHandle");
213 //check if propertyName contains '.' . If it does, then assume settng a property of a private tool, so adjust toolname
214 joSvc->set( toolName + "." + propertyName, propertyValue );
215 if(joSvc.release().isFailure()) return StatusCode::FAILURE;
216 return StatusCode::SUCCESS;
217 }
218
219
220
221 StatusCode removePropertyFromCatalogue( const std::string& toolName, const std::string& propertyName ) {
222 ServiceHandle<Gaudi::Interfaces::IOptionsSvc> joSvc("JobOptionsSvc","AnaToolHandle");
223 //check if propertyName contains '.' . If it does, then assume settng a property of a private tool, so adjust toolname
224 std::string theToolName = toolName; std::string thePropertyName=propertyName;
225 std::string::size_type dotLocation = thePropertyName.find_last_of('.');
226 if(dotLocation != std::string::npos) {
227 theToolName = toolName + "." + thePropertyName.substr(0,dotLocation);
228 thePropertyName = thePropertyName.substr(dotLocation+1,thePropertyName.length()-dotLocation);
229 }
230 joSvc->pop( theToolName + "." + thePropertyName );
231 if(joSvc.release().isFailure()) return StatusCode::FAILURE;
232 return StatusCode::SUCCESS;
233 }
234 StatusCode toolExists( const std::string& fullName, interfaceType_t*& tool ) {
235 ServiceHandle<IToolSvc> toolSvc("ToolSvc","AnaToolHandle");
236 toolSvc.retrieve().ignore();
237 auto tools = toolSvc->getTools();
238 StatusCode out(StatusCode::FAILURE);
239 for(auto atool : tools) {
240 if(atool && atool->name() == fullName) {out=StatusCode::SUCCESS;tool=atool;break;}
241 }
242 toolSvc.release().ignore();
243 return out;
244 }
245
246 StatusCode factoryExists( const std::string& type ) {
247 using Gaudi::PluginService::Details::Registry;
248 Registry &reg = Registry::instance();
249 if(reg.getInfo(type).library=="unknown") return StatusCode::FAILURE;
250 return StatusCode::SUCCESS;
251 }
252
253 StatusCode copyPropertiesInCatalogue( const std::string& fromTool, const std::string& toTool ) {
254 using namespace msgToolHandle;
255 //this method copies any properties assigned to 'fromTool' to 'toTool'
256 //purpose of this is because python joboptions will set joboptions properties using the name of the handle
257 //but we would like the name of the property (in declareProperty) to be used for anatoolhandles instead, in the case of private tools
258//std::cout << "copy : " << fromTool << " -> " << toTool << std::endl;
259 if(fromTool == toTool) return StatusCode::SUCCESS; //nothing to do
260
261 ServiceHandle<Gaudi::Interfaces::IOptionsSvc> joSvc("JobOptionsSvc","AnaToolHandle");
262 auto fromProps = joSvc->items(std::regex ("^" + fromTool));
263 for(auto& prop : fromProps) {
264 std::get<0>(prop).replace (0, fromTool.size(), toTool);
265 joSvc->set( std::get<0>(prop) , std::get<1>(prop) );
266 }
267 if(joSvc.release().isFailure()) return StatusCode::FAILURE;
268 return StatusCode::SUCCESS;
269 }
270
271
272 StatusCode readToolConfig (AsgToolConfig& config, const std::string& toolName) {
273 using namespace msgToolHandle;
274 //this method copies any properties assigned to tool with 'toolName' to 'config'
275 ServiceHandle<Gaudi::Interfaces::IOptionsSvc> joSvc("JobOptionsSvc","AnaToolHandle");
276 decltype(auto) fromProps = joSvc->items(std::regex ("^" + toolName));
277 for(const auto& prop : fromProps) {
278 if (std::get<0>(prop) == toolName)
279 {
280 config.setTypeAndName (std::get<1>(prop));
281 } else
282 {
283 config.setPropertyFromString (std::get<0>(prop).substr (toolName.size()+1) , std::get<1>(prop));
284 }
285 }
286 ANA_CHECK (joSvc.release());
287 return StatusCode::SUCCESS;
288 }
289 }
290}
291#endif
macros for messaging and checking status codes
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
#define ANA_MSG_DEBUG(xmsg)
Macro printing debug messages.
#define ANA_CHECK(EXP)
check whether the given expression was successful
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
an object that can create a AsgTool
::StatusCode StatusCode
StatusCode definition for legacy code.
std::lock_guard< std::mutex > lock_t
StatusCode toolExists(const std::string &fullName, interfaceType_t *&tool)
StatusCode readToolConfig(AsgToolConfig &config, const std::string &toolName)
StatusCode removePropertyFromCatalogue(const std::string &toolName, const std::string &propertyName)
StatusCode addPropertyToCatalogue(const std::string &toolName, const std::string &propertyName, const std::string &propertyValue)
StatusCode copyPropertiesInCatalogue(const std::string &fromTool, const std::string &toTool)
StatusCode factoryExists(const std::string &type)
StatusCode hasPropertiesInCatalogue(const std::string &toolName)
IAlgTool interfaceType_t
init(v_theApp, v_rootStream=None)
Definition PyKernel.py:45