The Gaudi Framework  master (37c0b60a)
PropertyAlg.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 // Include files
12 #include <GaudiKernel/DataObject.h>
15 #include <GaudiKernel/MsgStream.h>
16 #include <GaudiKernel/SmartIF.h>
17 #include <sstream>
18 
20 
21 #include "PropertyAlg.h"
22 
23 namespace {
24  // idea coming from The art of computer programming by Knuth
25  constexpr bool essentiallyEqual( double const a, double const b ) {
26  return std::abs( a - b ) <= std::min( std::abs( a ), std::abs( b ) ) * std::numeric_limits<double>::epsilon();
27  }
28 } // namespace
29 
30 // Read Handler
31 //------------------------------------------------------------------------------
33  // do not print messages if we are created in genconf
34  const std::string cmd = System::cmdLineArgs()[0];
35  if ( cmd.find( "genconf" ) != std::string::npos ) return;
36 
37  info() << "Read handler called for property: " << p << endmsg;
38 }
39 
40 // Update Handler
41 //------------------------------------------------------------------------------
43  // avoid the readHandler (which writes to the _same_ MsgStream!) from writing
44  // something in the middle of the printout of this message...
46  os << p;
47  info() << "Update handler called for property: " << os.str() << endmsg;
48 }
49 
50 // Constructor
51 //------------------------------------------------------------------------------
53  //------------------------------------------------------------------------------
54  // Associate read and update handlers
55 
56  p_double.declareUpdateHandler( &PropertyAlg::updateHandler, this );
57  p_double.declareReadHandler( &PropertyAlg::readHandler, this );
58 
59  {
60  // do not print messages if we are created in genconf
61  const std::string cmd = System::cmdLineArgs()[0];
62  if ( cmd.find( "genconf" ) != std::string::npos ) return;
63  }
64 
65  info() << "Before Initialization......" << endmsg;
66 
67  info() << "Int = " << m_int.value() << endmsg;
68  info() << "Int64 = " << m_int64.value() << endmsg;
69  info() << "UInt64 = " << m_uint64.value() << endmsg;
70  info() << "Double = " << m_double.value() << endmsg;
71  info() << "String = " << m_string.value() << endmsg;
72  info() << "Bool = " << m_bool.value() << endmsg;
73  info() << "IntArray = " << m_intarray.value() << endmsg;
74  info() << "Int64Array = " << m_int64array.value() << endmsg;
75  info() << "UInt64Array = " << m_uint64array.value() << endmsg;
76  info() << "DoubleArray = " << m_doublearray.value() << endmsg;
77  info() << "StringArray = " << m_stringarray.value() << endmsg;
78  info() << "BoolArray = " << m_boolarray.value() << endmsg;
79  info() << "EmptyArray = " << m_emptyarray.value() << endmsg;
80  info() << "IntPairArray = " << u_intpairarray.value() << endmsg;
81  info() << "DoublePairArray = " << u_doublepairarray.value() << endmsg;
82  info() << "IntSet = " << m_intset.value() << endmsg;
83  info() << "StringSet = " << m_stringset.value() << endmsg;
84  info() << "FloatUnorderedSet = " << m_floatuset.value() << endmsg;
85 
86  info() << "PInt = " << p_int << endmsg;
88  os << p_double; // avoid read handler from printing _during_ info()!
89  info() << "PDouble = " << os.str() << endmsg;
90  info() << "PString = " << p_string << endmsg;
91  info() << "PBool = " << p_bool << endmsg;
92  info() << "PIntArray = " << p_intarray << endmsg;
93  info() << "PDoubleArray = " << p_doublearray << endmsg;
94  info() << "PStringArray = " << p_stringarray << endmsg;
95  info() << "PBoolArray = " << p_boolarray << endmsg;
96 }
97 
98 //------------------------------------------------------------------------------
100  //------------------------------------------------------------------------------
101 
102  //
103  // Checking the JobOptions interface. Be able to set the properties
104  //
105  info() << "After Initialization having read the JobOptions file..." << endmsg;
106 
107  info() << "Int = " << m_int.value() << endmsg;
108  info() << "Int64 = " << m_int64.value() << endmsg;
109  info() << "UInt64 = " << m_uint64.value() << endmsg;
110  info() << "Double = " << m_double.value() << endmsg;
111  info() << "String = " << m_string.value() << endmsg;
112  info() << "Bool = " << m_bool.value() << endmsg;
113  info() << "IntArray = " << m_intarray.value() << endmsg;
114  info() << "Int64Array = " << m_int64array.value() << endmsg;
115  info() << "UInt64Array = " << m_uint64array.value() << endmsg;
116  info() << "DoubleArray = " << m_doublearray.value() << endmsg;
117  info() << "StringArray = " << m_stringarray.value() << endmsg;
118  info() << "BoolArray = " << m_boolarray.value() << endmsg;
119  info() << "EmptyArray = " << m_emptyarray.value() << endmsg;
120  info() << "IntPairArray = " << u_intpairarray.value() << endmsg;
121  info() << "DoublePairArray = " << u_doublepairarray.value() << endmsg;
122  info() << "IntSet = " << m_intset.value() << endmsg;
123  info() << "StringSet = " << m_stringset.value() << endmsg;
124  info() << "FloatUnorderedSet = " << m_floatuset.value() << endmsg;
125  info() << "StringMap = " << m_strmap << endmsg;
126 
127  info() << "PInt = " << p_int << endmsg;
129  os << p_double; // avoid read handler from printing _during_ info()!
130  info() << "PDouble = " << os.str() << endmsg;
131  info() << "PString = " << p_string << endmsg;
132  info() << "PBool = " << p_bool << endmsg;
133  info() << "PIntArray = " << p_intarray << endmsg;
134  info() << "PDoubleArray = " << p_doublearray << endmsg;
135  info() << "PStringArray = " << p_stringarray << endmsg;
136  info() << "PBoolArray = " << p_boolarray << endmsg;
137  //
138  // Checking units
139  //
140  auto& doublearrayunits = u_doublearrayunits.value();
141  auto& doublearray = u_doublearray.value();
142  for ( unsigned int i = 0; i < doublearrayunits.size(); i++ ) {
143 
144  if ( !essentiallyEqual( doublearrayunits[i], doublearray[i] ) ) {
145  error() << format( "DoubleArrayWithUnits[%d] = %g and should be %g", i, doublearrayunits[i], doublearray[i] )
146  << endmsg;
147  } else {
148  info() << format( "DoubleArrayWithUnits[%d] = %g", i, doublearrayunits[i] ) << endmsg;
149  }
150  }
151 
152  //
153  // Checking the Property Verifier
154  //
155  info() << "===============Checking Property Verifier ===============" << endmsg;
156 
157  info() << "Playing with PropertyVerifiers..." << endmsg;
158 
159  p_int.verifier().setBounds( 0, 200 );
160  p_int = 155;
161  // info() << "PInt= " << p_int << " [should be 155, bounds are " <<
162  // p_int.verifier().lower() << ", " <<
163  // p_int.verifier().upper() << " ]" << endmsg;
164  info() << format( "PInt= %d [should be 155, bounds are %d, %d]", (int)p_int, (int)p_int.verifier().lower(),
165  (int)p_int.verifier().upper() )
166  << endmsg;
167  try {
168  p_int = 255;
169  } catch ( ... ) { info() << "Got an exception when setting a value outside bounds" << endmsg; }
170  info() << "PInt= " << p_int << " [should be 155]" << endmsg;
171 
172  //
173  // Checking the Property CallBacks
174  //
175  info() << "===============Checking Property CallBaks ===============" << endmsg;
176 
177  double d;
178  info() << "Accessing PDouble ... " << endmsg;
179  d = p_double;
180 
181  info() << "Value obtained is: " << d << endmsg;
182 
183  info() << "Updating PDouble ... " << endmsg;
184  p_double = 999.;
185 
186  //
187  // Checking Accessing Properties by string
188  //
189 
190  info() << "==========Checking Accesing Properties by string=========" << endmsg;
191 
192  auto appmgr = serviceLocator()->as<IProperty>();
193  // StatusCode sc = serviceLocator()->service("ApplicationMgr", appmgr);
194  if ( !appmgr ) {
195  error() << "Unable to locate the ApplicationMgr" << endmsg;
196  } else {
197  std::string value( "empty" );
198  appmgr->getProperty( "ExtSvc", value ).ignore();
199  info() << " Got property ApplicationMgr.ExtSvc = " << value << ";" << endmsg;
200 
201  appmgr->setPropertyRepr( "ExtSvc", "[\"EvtDataSvc/EventDataSvc\", \"DetDataSvc/DetectorDataSvc\"]" ).ignore();
202  info() << " Set property ApplicationMgr.ExtSvc = "
203  << " [\"EvtDataSvc/EventDataSvc\", \"DetDataSvc/DetectorDataSvc\"]"
204  << ";" << endmsg;
205  appmgr->getProperty( "ExtSvc", value ).ignore();
206  info() << " Got property ApplicationMgr.ExtSvc = " << value << ";" << endmsg;
207 
208  appmgr->setPropertyRepr( "ExtSvc", "[ 'EventDataSvc', 'DetectorDataSvc']" ).ignore();
209  info() << " Set property ApplicationMgr.ExtSvc = "
210  << " [ 'EventDataSvc', 'DetectorDataSvc']"
211  << ";" << endmsg;
212  appmgr->getProperty( "ExtSvc", value ).ignore();
213  info() << " Got property ApplicationMgr.ExtSvc = " << value << ";" << endmsg;
214  }
215  // Testing setting bool
217  std::make_tuple( "true", true ), std::make_tuple( "false", false ), std::make_tuple( "True", true ),
218  std::make_tuple( "False", false ), std::make_tuple( "TRUE", true ), std::make_tuple( "FALSE", false ),
219  std::make_tuple( "T", true ), // not expected to work
220  std::make_tuple( "F", false ), // not expected to work
221  std::make_tuple( "10", true ), // not expected to work
222  };
224  for ( auto& c : cases ) {
225  p_bool = m_bool = !std::get<1>( c );
226  try {
227  sc = setPropertyRepr( "PBool", std::get<0>( c ) );
228  } catch ( ... ) { sc = StatusCode::FAILURE; }
229  if ( !sc || ( p_bool != std::get<1>( c ) ) ) {
230  error() << "PBool can not be set to " << std::get<0>( c ) << endmsg;
231  }
232  try {
233  sc = setPropertyRepr( "Bool", std::get<0>( c ) );
234  } catch ( ... ) { sc = StatusCode::FAILURE; }
235  if ( !sc || ( m_bool != std::get<1>( c ) ) ) { error() << "Bool can not be set to " << std::get<0>( c ) << endmsg; }
236  }
237 
238  // Testing the control of the output level directly from MessageSvc
239  MsgStream newlog( msgSvc(), "MsgTest" );
240  newlog << MSG::VERBOSE << "This should be printed if threshold is VERBOSE" << endmsg;
241  newlog << MSG::DEBUG << "This should be printed if threshold is DEBUG" << endmsg;
242  newlog << MSG::INFO << "This should be printed if threshold is INFO" << endmsg;
243  newlog << MSG::WARNING << "This should be printed if threshold is WARNING" << endmsg;
244  newlog << MSG::ERROR << "This should be printed if threshold is ERROR" << endmsg;
245  newlog << MSG::FATAL << "This should be printed if threshold is FATAL" << endmsg;
246  newlog << MSG::ALWAYS << "This should be printed ALWAYS" << endmsg;
247 
248  // Testing access to the JobOptions catalogue
249  auto& opts = serviceLocator()->getOptsSvc();
250 
251  // Dump of the catalogue
252  info() << "=================================================" << endmsg;
254  auto opt_items = opts.items(); // this copy is just to hide differences between gcc and clang outputs
255  ostream_joiner( info() << "Dump of the property catalogue:\n", opt_items, '\n',
256  []( MsgStream& os, const auto& item ) -> MsgStream& {
257  return os << std::get<0>( item ) << ": " << std::get<1>( item );
258  } )
259  << endmsg;
260  info() << "=================================================" << endmsg;
261 
262  // Change an option of my own....
263  opts.set( name() + '.' + "PInt", "154" );
264  info() << "PInt= " << p_int << " [should be 154]" << endmsg;
265 
266  auto orig_policy =
268  try {
269  info() << "Try to assign invalid value to DoubleArray" << endmsg;
270  opts.set( name() + '.' + "DoubleArray", "{\"12.12\", \"13.13\"}" );
271  } catch ( const GaudiException& exc ) { error() << "got exception: " << exc.what() << endmsg; }
272 
273  try {
274  info() << "Try to assign invalid value to StringMap" << endmsg;
275  opts.set( name() + '.' + "StringMap", "{\"one\", {\"une\", \"eins\"}}" );
276  } catch ( const GaudiException& exc ) { error() << "got exception: " << exc.what() << endmsg; }
277 
279 
280  info() << "DoubleArray = " << m_doublearray.value() << endmsg;
281  info() << "=================================================" << endmsg;
282  return StatusCode::SUCCESS;
283 }
284 
285 //------------------------------------------------------------------------------
287  //------------------------------------------------------------------------------
288  info() << "executing...." << endmsg;
289  return StatusCode::SUCCESS;
290 }
291 
292 //------------------------------------------------------------------------------
294  //------------------------------------------------------------------------------
295  info() << "finalizing...." << endmsg;
296  return StatusCode::SUCCESS;
297 }
298 
299 // Static Factory declaration
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
Gaudi::Details::PropertyBase
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: PropertyBase.h:35
PropertyAlg::m_doublearray
Gaudi::Property< std::vector< double > > m_doublearray
Definition: PropertyAlg.h:56
std::make_tuple
T make_tuple(T... args)
PropertyAlg::m_emptyarray
Gaudi::Property< std::vector< double > > m_emptyarray
Definition: PropertyAlg.h:59
PropertyAlg::initialize
StatusCode initialize() override
Three mandatory member functions of any algorithm.
Definition: PropertyAlg.cpp:99
PropertyAlg.h
PropertyAlg::m_stringarray
Gaudi::Property< std::vector< std::string > > m_stringarray
Definition: PropertyAlg.h:57
std::string
STL class.
PropertyAlg::p_stringarray
Gaudi::Property< std::vector< std::string > > p_stringarray
Definition: PropertyAlg.h:80
Gaudi::Algorithm::name
const std::string & name() const override
The identifying name of the algorithm object.
Definition: Algorithm.cpp:526
PropertyAlg::m_strmap
Gaudi::Property< std::map< std::string, std::string > > m_strmap
Definition: PropertyAlg.h:70
MSG::INFO
@ INFO
Definition: IMessageSvc.h:25
PropertyAlg::p_double
Gaudi::PropertyWithReadHandler< double > p_double
Definition: PropertyAlg.h:73
std::vector
STL class.
std::string::find
T find(T... args)
ISvcLocator
Definition: ISvcLocator.h:46
GaudiException
Definition: GaudiException.h:31
Algorithm
Alias for backward compatibility.
Definition: Algorithm.h:58
PropertyAlg::p_bool
Gaudi::Property< bool > p_bool
Definition: PropertyAlg.h:76
PropertyAlg::u_intpairarray
Gaudi::Property< std::vector< std::pair< int, int > > > u_intpairarray
Definition: PropertyAlg.h:63
Gaudi::Algorithm::serviceLocator
SmartIF< ISvcLocator > & serviceLocator() const override
The standard service locator.
Definition: Algorithm.cpp:570
MSG::WARNING
@ WARNING
Definition: IMessageSvc.h:25
PropertyAlg::PropertyAlg
PropertyAlg(const std::string &name, ISvcLocator *pSvcLocator)
Constructor of this form must be provided.
Definition: PropertyAlg.cpp:52
std::abs
Gaudi::ParticleID abs(const Gaudi::ParticleID &p)
Return the absolute value for a PID.
Definition: ParticleID.h:191
gaudirun.c
c
Definition: gaudirun.py:525
PropertyAlg::readHandler
void readHandler(Gaudi::Details::PropertyBase &)
Callbacks for properties.
Definition: PropertyAlg.cpp:32
PropertyAlg::p_doublearray
Gaudi::Property< std::vector< double > > p_doublearray
Definition: PropertyAlg.h:79
PropertyAlg::m_intset
Gaudi::Property< std::set< int > > m_intset
Definition: PropertyAlg.h:66
PropertyAlg::m_int64array
Gaudi::Property< std::vector< long long > > m_int64array
Definition: PropertyAlg.h:54
PropertyAlg::m_stringset
Gaudi::Property< std::set< std::string > > m_stringset
Definition: PropertyAlg.h:67
IDataProviderSvc.h
AvalancheSchedulerErrorTest.msgSvc
msgSvc
Definition: AvalancheSchedulerErrorTest.py:80
IProperty
Definition: IProperty.h:33
PropertyAlg::p_string
Gaudi::Property< std::string > p_string
Definition: PropertyAlg.h:75
SmartIF.h
PropertyAlg::m_uint64
Gaudi::Property< unsigned long long > m_uint64
Definition: PropertyAlg.h:48
PropertyAlg::p_boolarray
Gaudi::Property< std::vector< bool > > p_boolarray
Definition: PropertyAlg.h:81
StatusCode
Definition: StatusCode.h:65
gaudirun.opts
opts
Definition: gaudirun.py:336
PropertyHolder< CommonMessaging< implements< IAlgorithm, IDataHandleHolder, IProperty, IStateful > > >::setPropertyRepr
StatusCode setPropertyRepr(const std::string &n, const std::string &r) override
set the property from name and value string representation
Definition: PropertyHolder.h:177
Gaudi::Property::value
const ValueType & value() const
Definition: Property.h:237
PropertyAlg::m_intarray
Gaudi::Property< std::vector< int > > m_intarray
Definition: PropertyAlg.h:53
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
MsgStream
Definition: MsgStream.h:33
PropertyAlg::u_doublearrayunits
Gaudi::Property< std::vector< double > > u_doublearrayunits
Definition: PropertyAlg.h:60
MSG::FATAL
@ FATAL
Definition: IMessageSvc.h:25
std::numeric_limits::epsilon
T epsilon(T... args)
Gaudi::Details::Property::setParsingErrorPolicy
ParsingErrorPolicy setParsingErrorPolicy(ParsingErrorPolicy p)
Definition: Property.cpp:523
PropertyAlg::u_doublepairarray
Gaudi::Property< std::vector< std::pair< double, double > > > u_doublepairarray
Definition: PropertyAlg.h:64
PropertyAlg::m_floatuset
Gaudi::Property< std::unordered_set< float > > m_floatuset
Definition: PropertyAlg.h:68
PropertyAlg::m_string
Gaudi::Property< std::string > m_string
Definition: PropertyAlg.h:50
std::min
T min(T... args)
SmartIF::as
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Definition: SmartIF.h:117
std::ostringstream
STL class.
PropertyAlg::p_int
Gaudi::CheckedProperty< int > p_int
Definition: PropertyAlg.h:72
PropertyAlg::m_uint64array
Gaudi::Property< std::vector< unsigned long long > > m_uint64array
Definition: PropertyAlg.h:55
MSG::VERBOSE
@ VERBOSE
Definition: IMessageSvc.h:25
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
DataObject.h
IChronoStatSvc.h
PropertyAlg::execute
StatusCode execute() override
Definition: PropertyAlg.cpp:286
MSG::ALWAYS
@ ALWAYS
Definition: IMessageSvc.h:25
PropertyAlg::m_bool
Gaudi::Property< bool > m_bool
Definition: PropertyAlg.h:51
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
System::cmdLineArgs
GAUDI_API const std::vector< std::string > cmdLineArgs()
Command line arguments including executable name as arg[0] as vector of strings.
Definition: System.cpp:365
PropertyAlg::updateHandler
void updateHandler(Gaudi::Details::PropertyBase &)
Definition: PropertyAlg.cpp:42
MSG::ERROR
@ ERROR
Definition: IMessageSvc.h:25
PropertyAlg::m_boolarray
Gaudi::Property< std::vector< bool > > m_boolarray
Definition: PropertyAlg.h:58
PropertyAlg::m_double
Gaudi::Property< double > m_double
Definition: PropertyAlg.h:49
PropertyAlg::p_intarray
Gaudi::Property< std::vector< int > > p_intarray
Definition: PropertyAlg.h:78
std::ostringstream::str
T str(T... args)
SerializeSTL.h
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
PropertyAlg::finalize
StatusCode finalize() override
Definition: PropertyAlg.cpp:293
PropertyAlg
Definition: PropertyAlg.h:29
Gaudi::Details::Property::ParsingErrorPolicy::Exception
@ Exception
PropertyAlg::m_int64
Gaudi::Property< long long > m_int64
Definition: PropertyAlg.h:47
PropertyAlg::m_int
Gaudi::Property< int > m_int
These data members are used in the execution of this algorithm They are set in the initialization pha...
Definition: PropertyAlg.h:46
PropertyAlg::u_doublearray
Gaudi::Property< std::vector< double > > u_doublearray
Definition: PropertyAlg.h:61
GaudiException::what
const char * what() const override
method from std::exception
Definition: GaudiException.h:110
MsgStream.h
GaudiUtils::details::ostream_joiner
Stream & ostream_joiner(Stream &os, Iterator first, Iterator last, Separator sep, OutputElement output=OutputElement{})
Definition: SerializeSTL.h:75