ATLAS Offline Software
AnaToolHandle.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 
8 
9 //
10 // includes
11 //
12 
13 #include <AsgTools/AnaToolHandle.h>
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 
34 namespace 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 = 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, 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 = res_result;
126  return StatusCode::SUCCESS;
127  }
128  }
129 }
130 
131 //
132 // legacy code
133 //
134 
135 #ifdef XAOD_STANDALONE
136 
137 namespace 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 
190 namespace 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
get_generator_info.result
result
Definition: get_generator_info.py:21
asg::interfaceType_t
IAlgTool interfaceType_t
Definition: AnaToolHandle.h:31
WriteCellNoiseToCool.fullName
fullName
Definition: WriteCellNoiseToCool.py:461
asg::detail::removePropertyFromCatalogue
StatusCode removePropertyFromCatalogue(const std::string &toolName, const std::string &propertyName)
Definition: AnaToolHandle.cxx:221
asg
Definition: DataHandleTestTool.h:28
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
ANA_MSG_ERROR
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:294
detail
Definition: extract_histogram_tag.cxx:14
ANA_CHECK
#define ANA_CHECK(EXP)
check whether the given expression was successful
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:324
asg::detail::toolExists
StatusCode toolExists(const std::string &fullName, interfaceType_t *&tool)
Definition: AnaToolHandle.cxx:234
python.DomainsRegistry.reg
reg
globals -----------------------------------------------------------------—
Definition: DomainsRegistry.py:343
FPEAudit::lock_t
std::lock_guard< std::mutex > lock_t
Definition: FPEAuditor.cxx:44
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
python.TriggerHandler.th
th
Definition: TriggerHandler.py:296
asg::AsgToolConfig
an object that can create a AsgTool
Definition: AsgToolConfig.h:22
run.atool
atool
Definition: run.py:56
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
MessageCheck.h
macros for messaging and checking status codes
asg::detail::readToolConfig
StatusCode readToolConfig(AsgToolConfig &config, const std::string &toolName)
Definition: AnaToolHandle.cxx:272
Handler::svc
AthROOTErrorHandlerSvc * svc
Definition: AthROOTErrorHandlerSvc.cxx:10
AnaToolHandle.h
tools
Definition: DataQuality/ZLumiScripts/python/tools/__init__.py:1
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:453
python.PyKernel.init
def init(v_theApp, v_rootStream=None)
Definition: PyKernel.py:45
asg::detail::hasPropertiesInCatalogue
StatusCode hasPropertiesInCatalogue(const std::string &toolName)
Definition: AnaToolHandle.cxx:194
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
asg::detail::addPropertyToCatalogue
StatusCode addPropertyToCatalogue(const std::string &toolName, const std::string &propertyName, const std::string &propertyValue)
Definition: AnaToolHandle.cxx:210
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
asg::detail::factoryExists
StatusCode factoryExists(const std::string &type)
Definition: AnaToolHandle.cxx:246
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
ToolStore.h
checker_macros.h
Define macros for attributes used to control the static checker.
asg::detail::copyPropertiesInCatalogue
StatusCode copyPropertiesInCatalogue(const std::string &fromTool, const std::string &toTool)
Definition: AnaToolHandle.cxx:253
ServiceHandle< Gaudi::Interfaces::IOptionsSvc >
ANA_MSG_DEBUG
#define ANA_MSG_DEBUG(xmsg)
Macro printing debug messages.
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:288