ATLAS Offline Software
Loading...
Searching...
No Matches
AthAnalysisHelper.h
Go to the documentation of this file.
1
2
3/*
4 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5*/
6
7// AthAnalysisHelper.h
8// Header file for class AthAnalysisHelper
9// Methods that are useful for athena-based analysis will go here
10// Author: W.Buttinger<will@cern.ch>
12
13#ifndef ATHANALYSISBASECOMPS_ATHANALYSISHELPER_H
14#define ATHANALYSISBASECOMPS_ATHANALYSISHELPER_H 1
15
17#include "GaudiKernel/ServiceHandle.h"
18
19#include "Gaudi/Interfaces/IOptionsSvc.h"
20#include "GaudiKernel/IToolSvc.h"
21
23
24#include "GaudiKernel/AlgTool.h"
25#include "GaudiKernel/Algorithm.h"
26
28
29#include "GaudiKernel/IAppMgrUI.h"
30
31
32#include "GaudiKernel/ToolHandle.h"
33
34#include <type_traits>
35#include "TFile.h"
36
37class AthAnalysisHelper { //thought about being a namespace but went for static methods instead, in case I want private data members in future
38
39public:
40 AthAnalysisHelper(); //need a constructor to link the dictionary library with the implementation library
41
42 static const std::string UNDEFINED; //used in getProperty
43
45 static IAppMgrUI* initGaudi(const char* options = "");
46
47
50 template<typename W> static StatusCode addPropertyToCatalogue( const std::string& name , const std::string& property, const W& value, bool override=true) {
51 ServiceHandle<Gaudi::Interfaces::IOptionsSvc> joSvc("JobOptionsSvc","AthAnalysisHelper");
52 if(joSvc.retrieve().isFailure()) return StatusCode::FAILURE;
53 if(!override) {
54 //check if property already defined. If so, then print a warning and return failure
55 std::string pValue = getProperty( name, property );
56 if( pValue != UNDEFINED) {
57 std::cout << "WARNING: " << name << "." << property << " already defined as " << pValue << " ... ignoring " << Gaudi::Utils::toString ( value ) << std::endl;
58 return StatusCode::FAILURE;
59 }
60 }
61
62 if constexpr (std::is_convertible<W, std::string>::value) {
63 // If value is already convertible to a string, don't use toString().
64 // Otherwise, toString() will add quotes around the string,
65 // which confuses things further on.
66 // (These quotes used to be removed by the old
67 // IJobOptionsSvc::addPropertyToCatalogue interface, but IOptionsSvc::set
68 // doesn't do that.)
69 joSvc->set( name+"."+property , std::string (value) );
70 }
71 else {
72 joSvc->set( name+"."+property , Gaudi::Utils::toString ( value ) );
73 }
74 return StatusCode::SUCCESS;
75 }
76
77
78 //alias for above
79 template<typename W> static StatusCode setProperty( const std::string& name , const std::string& property, const W& value, bool override=true) {
80 return addPropertyToCatalogue(name,property,value,override);
81 }
82
89 static StatusCode setProperty( const std::string& name , const std::string& property, const std::string& value, bool override=true) {
90 return addPropertyToCatalogue( name, property, value, override );
91 } //set a property for a client in the catalogue
92
93
105
106 template<class W, typename = typename std::enable_if<!std::is_base_of<GaudiHandleBase,W>::value &&
107 !std::is_base_of<GaudiHandleArrayBase,W>::value>::type>
108 static StatusCode setProperty(const GaudiHandleBase& toolHandle, const std::string& property, const W& value, bool override=true) {
109 if(toolHandle.empty()) {
110 std::cout << "ERROR: Empty toolHandle passed to AthAnalysisHelper::setProperty" << std::endl;
111 return StatusCode::FAILURE;
112 }
113 std::string fullName = toolHandle.parentName() + "." + toolHandle.name();
114 std::string thePropertyName(property);
115 //if the property contains any "." then strip the last bit as the property name
116 std::string::size_type dotLocation = thePropertyName.find_last_of('.');
117 if(dotLocation != std::string::npos) {
118 fullName += "." + thePropertyName.substr(0,dotLocation);
119 thePropertyName = thePropertyName.substr(dotLocation+1,thePropertyName.length()-dotLocation);
120 }
121 //check if the tool already exists, if so then we are too late!!
122 if( toolExists( fullName ) ) {
123 std::cout << "ERROR: Cannot setProperty on a tool that is already initialized" << std::endl;
124 return StatusCode::FAILURE;
125 }
126 //tool not existing, ok so add property to catalogue
127 return addPropertyToCatalogue(fullName, thePropertyName, value, override);
128 }
129
131 static StatusCode setProperty(const GaudiHandleBase& toolHandle, const std::string& property, const GaudiHandleBase& value, bool override=true) {
132 std::string subToolName(value.name());
133 size_t start_pos = subToolName.find(toolHandle.name()+".");
134 if(start_pos!=std::string::npos) { subToolName.replace( start_pos, toolHandle.name().length()+1, "" ); }
135 std::string typeAndName = value.type(); if(!subToolName.empty()) typeAndName += "/"+subToolName;
136 return setProperty( toolHandle, property, typeAndName, override );
137 }
138 static StatusCode setProperty(const GaudiHandleBase& toolHandle, const std::string& property, const GaudiHandleArrayBase& value, bool override=true) {
139 return setProperty( toolHandle, property, value.typesAndNames(), override );
140 }
141
143 template<typename W> static StatusCode setProperty(IAlgTool* tool, const std::string& property, const W& value) {
144 AlgTool* algtool = dynamic_cast<AlgTool*>(tool);
145 if(!algtool) {
146 std::cout << "ERROR: Tool is not an algtool. Cannot AthAnalysisHelper::setProperty on it" << std::endl;
147 return StatusCode::FAILURE;
148 }
149 return algtool->setProperty(property, value);
150 }
151
153 template<typename W> static StatusCode setProperty(IAlgorithm* alg, const std::string& property, const W& value) {
154 Gaudi::Algorithm* theAlg = dynamic_cast<Gaudi::Algorithm*>(alg);
155 if(!theAlg) {
156 std::cout << "ERROR: alg is not an Algorithm. Cannot AthAnalysisHelper::setProperty on it" << std::endl;
157 return StatusCode::FAILURE;
158 }
159 return theAlg->setProperty(property, value);
160 }
161
162 template<typename T> static std::string toString(const T& value) { return Gaudi::Utils::toString( value ); }
163 static std::string toString(const std::string& value) { return value; } //gaudi's toString puts extra quote marks around things like "['b']" .. should probably stop that..
164 static std::string toString(const char* value) { return value; } //gaudi's toString puts extra quote marks around things like "['b']" .. should probably stop that..
165
166
168 template<typename T, typename W> static StatusCode setProperty(const ServiceHandle<T>& serviceHandle, const std::string& property, const W& value) {
169 if(serviceHandle.isSet()) {
170 return dynamic_cast<Service&>(*serviceHandle).setProperty(property,toString ( value ));
171 }
172 std::string fullName = serviceHandle.name();
173 std::string thePropertyName(property);
174 //if the property contains any "." then strip the last bit as the property name
175 std::string::size_type dotLocation = thePropertyName.find_last_of('.');
176 if(dotLocation != std::string::npos) {
177 fullName += "." + thePropertyName.substr(0,dotLocation);
178 thePropertyName = thePropertyName.substr(dotLocation+1,thePropertyName.length()-dotLocation);
179 }
180
181 //check if the service already exists
182 if(Gaudi::svcLocator()->existsService(serviceHandle.name())) {
183 //set property on the service directly
184 return dynamic_cast<Service&>(*serviceHandle).setProperty(property,toString ( value ));
185 }
186
187 //service not existing, ok so add property to catalogue
188 return addPropertyToCatalogue(fullName, thePropertyName, value);
189 }
190
204 template<typename W> static W* createTool(const std::string& typeAndName, INamedInterface* parent = 0) {
205 std::string type = typeAndName; std::string name = typeAndName;
206 std::string::size_type pos = type.find('/');
207 if(pos!=std::string::npos) {
208 type.resize (pos);
209 name = name.substr(pos+1,name.length());
210 }
211 if(parent==0) {
212 //use ToolSvc as parent
213 parent = Gaudi::svcLocator()->service( "ToolSvc" );
214 }
215 IAlgTool *algtool = AlgTool::Factory::create(type,type,name,parent).release();
216 algtool->addRef(); //important to increment the reference count so that Gaudi Garbage collection wont delete alg ahead of time
217 W* out = dynamic_cast<W*>(algtool);
218 if(!out) {
219 std::cout << "ERROR: Tool of type " << type << " does not implement the interface " << System::typeinfoName(typeid(W)) << std::endl;
220 delete algtool;
221 return 0;
222 }
223 return out;
224 }
225 static IAlgTool* createTool(const std::string& typeAndName, INamedInterface* parent = 0) {
226 return createTool<IAlgTool>(typeAndName,parent);
227 }
228
229
230 //equivalent method for creating an algorithm ... always returns an IAlgorithm though, so not templated
231 static IAlgorithm* createAlgorithm(const std::string& typeAndName) {
232 std::string type = typeAndName; std::string name = typeAndName;
233 std::string::size_type pos = type.find('/');
234 if(pos!=std::string::npos) {
235 type.resize (pos);
236 name = name.substr(pos+1,name.length());
237 }
238 IAlgorithm* out = Algorithm::Factory::create(type,name,Gaudi::svcLocator()).release();
239 out->addRef(); //important to increment the reference count so that Gaudi Garbage collection wont delete alg ahead of time
240 return out;
241 }
242
243
245 static bool toolExists( const std::string& fullName );
246 static bool toolExists(const GaudiHandleBase& toolHandle) { return toolExists( toolHandle.parentName() + "." + toolHandle.name() ); }
247
248
254 static std::string retrieveMetadata(const std::string& folder, const std::string& key, const ServiceHandle<StoreGateSvc>& inputMetaStore) {
255 std::string out("");
256 StatusCode result = retrieveMetadata(folder,key,out,inputMetaStore);
257 if(result.isFailure()) { std::cout << "ERROR: Could not retrieve IOVMetadata with folder " << folder << " and key " << key << std::endl; }
258 return out;
259 }
260 static std::string retrieveMetadata(const std::string& folder, const std::string& key, ServiceHandle<StoreGateSvc>& inputMetaStore) {
261 std::string out("");
262 StatusCode result = retrieveMetadata(folder,key,out,inputMetaStore);
263 if(result.isFailure()) { std::cout << "ERROR: Could not retrieve IOVMetadata with folder " << folder << " and key " << key << std::endl; }
264 return out;
265 }
266
267
270 template<typename T> static StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out) {
271 ServiceHandle<StoreGateSvc> inputMetaStore("StoreGateSvc/InputMetaDataStore", "AthAnalysisHelper");
272 if(inputMetaStore.retrieve().isFailure()) return StatusCode::FAILURE; //must remember to release
273 StatusCode result = retrieveMetadata(folder,key,out,inputMetaStore);
274 if(inputMetaStore.release().isFailure()) return StatusCode::FAILURE;
275 return result;
276 }
277
278
279
281 template<typename T> static StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out, const ServiceHandle<StoreGateSvc>& inputMetaStore) {
282 const IOVMetaDataContainer* cont = 0;
283 if( inputMetaStore->retrieve(cont,folder).isFailure()) return StatusCode::FAILURE;
284
285 //payload is a collection of condattrlistcollections
286 //only look a the first one, assuming it exists, and within that only look at the first channel;
287 if(cont->payloadContainer()->size()>0 && cont->payloadContainer()->at(0)->size()>0) {
288 //just try to retrieve the requested key from the attributelist - we will let it throw the coral::AttributeListException (inherits from std::exception) if it fails
289 //if the typeName is std::string, we will try to use the gaudi parsers to parse it
290 //otherwise we try to do a straight assignment
291 try {
292 const coral::Attribute& attr = cont->payloadContainer()->at(0)->attributeList(cont->payloadContainer()->at(0)->chanNum(0))[key];
293
294 if(attr.specification().typeName()=="string") {
295 if(Gaudi::Parsers::parse(out,attr.data<std::string>()).isFailure()) return StatusCode::FAILURE;
296 } else { //do a straight conversion, and just hope its ok (FIXME: should probably do a check of typeid(T) vs typeName)
297 out = attr.data<T>();
298 }
299 } catch(...) {
300 //anything that goes wrong is taken to be a failure
301 return StatusCode::FAILURE;
302 }
303
304 return StatusCode::SUCCESS;
305 }
306 return StatusCode::FAILURE;
307 }
308
311 template<typename T> static StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out, const ServiceHandle<StoreGateSvc>& inputMetaStore, const IOVTime& time, int channel=-1) {
312 const IOVMetaDataContainer* cont = 0;
313 if( inputMetaStore->retrieve(cont,folder).isFailure()) return StatusCode::FAILURE;
314
315 //payload is a collection of condattrlistcollections
316 //have to find first one that the time lies in
317 auto cond = cont->payloadContainer()->find(time);
318 if(cond == cont->payloadContainer()->end()) { return StatusCode::FAILURE; }
319
320 //get the first channel number, if required
321 if(channel<0) channel = (*cond)->chanNum(0);
322
323 //get the channel pair.. checks if it exists...
324 auto attrlist = (*cond)->chanAttrListPair(channel);
325 if(attrlist == (*cond)->end()) { return StatusCode::FAILURE; }
326
327
328 //just try to retrieve the requested key from the attributelist - we will let it throw the coral::AttributeListException (inherits from std::exception) if it fails
329 //if the typeName is std::string, we will try to use the gaudi parsers to parse it
330 //otherwise we try to do a straight assignment
331 try {
332 const coral::Attribute& attr = attrlist->second[key];
333 if(attr.specification().typeName()=="string") {
334 if(Gaudi::Parsers::parse(out,attr.data<std::string>()).isFailure()) return StatusCode::FAILURE;
335 } else { //do a straight conversion, and just hope its ok (FIXME: should probably do a check of typeid(T) vs typeName)
336 out = attr.data<T>();
337 }
338 }
339 catch(...) {
340 return StatusCode::FAILURE;
341 }
342
343 return StatusCode::SUCCESS;
344 }
345
346 template<typename T> static StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out, const IOVTime& time, int channel=-1) {
347 ServiceHandle<StoreGateSvc> inputMetaStore("StoreGateSvc/InputMetaDataStore", "AthAnalysisHelper");
348 if(inputMetaStore.retrieve().isFailure()) return StatusCode::FAILURE; //must remember to release
349 StatusCode result = retrieveMetadata(folder,key,out,inputMetaStore,time,channel);
350 if(inputMetaStore.release().isFailure()) return StatusCode::FAILURE;
351 return result;
352 }
353
354
362 static void dumpJobOptionProperties(const std::string& client="");
363 inline static void dumpProperties(const std::string& client="") { dumpJobOptionProperties(client); } //list properties of client present in catalogue
364
368 static std::string getProperty(const std::string& client, const std::string& property); //get property of client present in catalogue, or return AAH::UNDEFINED
369
370
373 static void printAuxElement(const SG::AuxElement& ae);
374 static void dumpProperties(const SG::AuxElement& ae) { printAuxElement(ae); } //list properties of an xAOD object
375
376
378 //these aren't necessarily the same as what is in the JobOptionsSvc
379 static void dumpProperties(const IProperty& component); //list properties of an existing component (may not match what is in the catalogue)
380
381
382 template<typename T> static void dumpProperties(const GaudiHandle<T>& handle) {
383 if(!handle.isSet()) {std::cout << "Please retrieve handle before dumping properties" << std::endl; return;}
384 return dumpProperties(dynamic_cast<const IProperty&>(*handle));
385 }
386
387
388
389 //Obtain TFile pointer to THistSvc's output file with the given streamName
390 static TFile* getOutputFile(const std::string& streamName);
391
392
393}; //AthAnalysisHelper class
394
395
396class AAH : public AthAnalysisHelper {
397public:
399
400 // Add some explicit specializations for easier calling from job options.
401 static StatusCode setProperty (const GaudiHandleBase& toolHandle, const std::string& property, const int& value, bool override = true)
402 { return AthAnalysisHelper::setProperty (toolHandle, property, value, override); }
403 static StatusCode setProperty (const GaudiHandleBase& toolHandle, const std::string& property, const double& value, bool override = true)
404 { return AthAnalysisHelper::setProperty (toolHandle, property, value, override); }
405 static StatusCode setProperty (const GaudiHandleBase& toolHandle, const std::string& property, const std::string& value, bool override = true)
406 { return AthAnalysisHelper::setProperty (toolHandle, property, value, override); }
407
408};
409
410
411
412#endif
Base class for elements of a container that can have aux data.
This class is a container for conditions data.
static StatusCode setProperty(const GaudiHandleBase &toolHandle, const std::string &property, const int &value, bool override=true)
static StatusCode setProperty(const GaudiHandleBase &toolHandle, const std::string &property, const std::string &value, bool override=true)
static StatusCode setProperty(const GaudiHandleBase &toolHandle, const std::string &property, const double &value, bool override=true)
static void printAuxElement(const SG::AuxElement &ae)
Print the aux variables of an xAOD object (aux element) An alternative to this method is the 'xAOD::d...
static void dumpProperties(const std::string &client="")
static TFile * getOutputFile(const std::string &streamName)
static StatusCode setProperty(const GaudiHandleBase &toolHandle, const std::string &property, const GaudiHandleArrayBase &value, bool override=true)
static std::string getProperty(const std::string &client, const std::string &property)
Check catalogue for property of specified client returns AAH::UNDEFINED in case of no property value ...
static std::string toString(const std::string &value)
static void dumpJobOptionProperties(const std::string &client="")
Dump the properties from joboptionsvc of clients with names beginning with given string.
static std::string toString(const T &value)
static StatusCode retrieveMetadata(const std::string &folder, const std::string &key, T &out, const ServiceHandle< StoreGateSvc > &inputMetaStore, const IOVTime &time, int channel=-1)
retrieve metadata, for a specified IOVTime and a specific channel, unless the channel is -1,...
static StatusCode setProperty(IAlgTool *tool, const std::string &property, const W &value)
setProperty on any tool, even when initialized
static IAlgorithm * createAlgorithm(const std::string &typeAndName)
static StatusCode setProperty(const ServiceHandle< T > &serviceHandle, const std::string &property, const W &value)
setProperty for services ... will allow setProperty on already-existing services
static bool toolExists(const std::string &fullName)
check if tool already exists. FullName = Parent.Name
static bool toolExists(const GaudiHandleBase &toolHandle)
static IAppMgrUI * initGaudi(const char *options="")
initGaudi method starts the gaudi ApplicationMgr ready for working with all the components
static const std::string UNDEFINED
static void dumpProperties(const GaudiHandle< T > &handle)
static StatusCode retrieveMetadata(const std::string &folder, const std::string &key, T &out, const IOVTime &time, int channel=-1)
static std::string retrieveMetadata(const std::string &folder, const std::string &key, const ServiceHandle< StoreGateSvc > &inputMetaStore)
method that always returns as a string you can use from, e.g, pyROOT with evt = ROOT....
static W * createTool(const std::string &typeAndName, INamedInterface *parent=0)
Create a tool using the gaudi factory methods.
static StatusCode setProperty(const std::string &name, const std::string &property, const W &value, bool override=true)
static StatusCode setProperty(IAlgorithm *alg, const std::string &property, const W &value)
setProperty on an alg, even when initialized
static IAlgTool * createTool(const std::string &typeAndName, INamedInterface *parent=0)
static std::string retrieveMetadata(const std::string &folder, const std::string &key, ServiceHandle< StoreGateSvc > &inputMetaStore)
static StatusCode setProperty(const std::string &name, const std::string &property, const std::string &value, bool override=true)
non-template method, for use in joboptions current usage would be: ... usual joboptions ....
static void dumpProperties(const SG::AuxElement &ae)
static StatusCode retrieveMetadata(const std::string &folder, const std::string &key, T &out, const ServiceHandle< StoreGateSvc > &inputMetaStore)
implemenation where you pass it a particular store instead
static StatusCode setProperty(const GaudiHandleBase &toolHandle, const std::string &property, const GaudiHandleBase &value, bool override=true)
Partial template specialization for ToolHandles and ToolHandleArrays ... strips parent name from tool...
static StatusCode setProperty(const GaudiHandleBase &toolHandle, const std::string &property, const W &value, bool override=true)
helper method for setting a property on a tool before retrieving it uses the toolhandle to work out w...
static StatusCode addPropertyToCatalogue(const std::string &name, const std::string &property, const W &value, bool override=true)
helper method for adding a property to the JobOptionsSvc to list all the properties in the catalogue,...
static std::string toString(const char *value)
static StatusCode retrieveMetadata(const std::string &folder, const std::string &key, T &out)
retrieve metadata from the input metadata storegate.
const AttributeList & attributeList(ChanNum chanNum) const
attribute list for a given channel number
ChanNum chanNum(unsigned int index) const
channel number for index: (index = 0 to size-1)
size_type size() const
number of Chan/AttributeList pairs
This class is a container for conditions data.
const IOVPayloadContainer * payloadContainer() const
Access to payload container.
size_type size() const
size of payload vector
const_iterator end() const
End of payload vector.
const_iterator find(const IOVTime &time) const
find the first payload that has a IOVRange which includes the
CondAttrListCollection * at(unsigned int i) const
Element access.
Basic time unit for IOVSvc.
Definition IOVTime.h:33
Base class for elements of a container that can have aux data.
Definition AuxElement.h:483
StatusCode parse(std::tuple< Tup... > &tup, const Gaudi::Parsers::InputData &input)