ATLAS Offline Software
ToolWithConstants.icc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
3  */
4 /**
5  * @file CaloUtils/ToolWithConstants.icc
6  * @author scott snyder <snyder@bnl.gov>
7  * @date Apr, 2020
8  * @brief Hold constants for a tool.
9  */
10 
11 
12 namespace CaloUtils {
13 
14 
15 /**
16  * @brief Declare a constant with no default.
17  * @param owner The owning @c ToolWithConstants.
18  * @param name Name of the constant.
19  * @param doc Documentation string.
20  */
21 template <class T>
22 template <class OWNER>
23 ToolConstant<T>::ToolConstant (OWNER* owner,
24  const std::string& name,
25  const std::string& doc /*= ""*/)
26  : m_prop (name, doc, owner->m_impl),
27  m_toolVersion (owner->toolVersion())
28 {
29  owner->declareProperty (m_prop);
30  owner->m_impl.addConstant (this);
31  m_prop.template setOwnerType<OWNER>();
32 }
33 
34 
35 /**
36  * @brief Declare a constant with no default.
37  * @param owner The owning @c ToolWithConstants.
38  * @param name Name of the constant.
39  * @param doc Documentation string.
40  *
41  * (Needed in addition to the previous signature in order to avoid ambiguities;
42  * otherwise, if a char* is given for the third argument, it would
43  * match the following signature instead of the previous one.)
44  */
45 template <class T>
46 template <class OWNER>
47 ToolConstant<T>::ToolConstant (OWNER* owner,
48  const std::string& name,
49  const char* doc)
50  : ToolConstant (owner, name, std::string(doc))
51 {
52 }
53 
54 
55 /**
56  * @brief Declare a constant with a default.
57  * @param owner The owning @c ToolWithConstants.
58  * @param name Name of the constant.
59  * @param deflt Default value.
60  * @param doc Documentation string.
61  *
62  * Only possible for arithmetic types, not @c Array<N>.
63  */
64 template <class T>
65 template <class OWNER,
66  typename U /*= T*/,
67  typename /*= std::enable_if_t<std::is_arithmetic_v<U> >*/ >
68 ToolConstant<T>::ToolConstant (OWNER* owner,
69  const std::string& name,
70  const T& deflt,
71  const std::string& doc /*= ""*/)
72  : m_prop (name, doc, owner->m_impl, deflt),
73  m_toolVersion (owner->toolVersion())
74 {
75  owner->declareProperty (m_prop);
76  owner->m_impl.addConstant (this);
77  m_prop.template setOwnerType<OWNER>();
78 }
79 
80 
81 /**
82  * @brief Retrieve the value of a constant.
83  * @param c Context for accessing condtions (as returned from context()).
84  */
85 template <class T>
86 T ToolConstant<T>::operator() (const Context& c) const
87 {
88  // If it's been set from JO, just return the value.
89  if (m_prop.m_setFromJO) {
90  return static_cast<T> (m_prop);
91  }
92 
93  // Check for a setting from COOL.
94  if (c.m_constants) {
95  // Verify version.
96  if (c.m_constants->version() > m_toolVersion) {
97  throw ExcBadToolConstantVersion (m_prop.m_impl.m_toolName,
98  m_prop.name(),
99  m_toolVersion,
100  c.m_constants->version());
101  }
102 
103  // Convert form the Arrayrep stored in COOL.
104  const CxxUtils::Arrayrep& rep =
105  c.m_constants->getrep (m_prop.m_impl.m_toolName,
106  m_prop.m_impl.m_prefix + m_prop.name());
107 
108  T ret;
109  CxxUtils::fromArrayrep (rep, ret);
110  return ret;
111  }
112 
113  // If we have a default value, return it.
114  if (m_prop.m_hasDefault) {
115  return static_cast<T> (m_prop);
116  }
117 
118  // Otherwise it's an error.
119  throw CaloUtils::ExcConstantNotSet (m_prop.m_impl.m_toolName, m_prop.name());
120 }
121 
122 
123 /**
124  * @brief Retrieve the value of a constant.
125  *
126  * This variant may only be used if the constant was initialized via JO.
127  */
128 template <class T>
129 inline
130 T ToolConstant<T>::operator()() const
131 {
132  if (!m_prop.m_setFromJO) {
133  CaloUtils::throwExcBadContextlessRetrieve (m_prop.m_impl.m_toolName, m_prop.name());
134  }
135  return static_cast<T> (m_prop);
136 }
137 
138 
139 /**
140  * @brief Return the name of this constant.
141  */
142 template <class T>
143 std::string ToolConstant<T>::name() const
144 {
145  return m_prop.name();
146 }
147 
148 
149 /**
150  * @brief Was this constant set through job options?
151  */
152 template <class T>
153 bool ToolConstant<T>::setFromJO() const
154 {
155  return m_prop.m_setFromJO;
156 }
157 
158 
159 /**
160  * @brief Constructor, no default value.
161  * @param name Constant name.
162  * @param doc Documentation string.
163  * @param impl Internal implementation object.
164  */
165 template <class T>
166 ToolConstant<T>::CProperty::CProperty (const std::string& name,
167  const std::string& doc,
168  ToolWithConstantsImpl& impl)
169  : Gaudi::Property<T> (name, T(), doc),
170  m_impl (impl),
171  m_hasDefault (false)
172 {
173 }
174 
175 
176 /**
177  * @brief Constructor, with default value.
178  * @param name Constant name.
179  * @param doc Documentation string.
180  * @param impl Internal implementation object.
181  * @param deflt Default value.
182  */
183 template <class T>
184 ToolConstant<T>::CProperty::CProperty (const std::string& name,
185  const std::string& doc,
186  ToolWithConstantsImpl& impl,
187  const T& deflt)
188  : Gaudi::Property<T> (name, deflt, doc),
189  m_impl (impl),
190  m_hasDefault (true)
191 {
192  // Install the default value in our internal constats representation.
193  CaloRec::Arrayrep rep;
194  rep.m_data.push_back (deflt);
195  m_impl.m_constants.setrep (this->name(), std::move (rep));
196 }
197 
198 
199 /**
200  * @brief Return the value of this property as a string.
201  */
202 template <class T>
203 std::string ToolConstant<T>::CProperty::toString() const
204 {
205  // Do this in terms of toStream().
206  std::ostringstream ss;
207  toStream (ss);
208  return ss.str();
209 }
210 
211 
212 /**
213  * @brief Print the value of this property to a stream.
214  * @param out Stream to which to print.
215  */
216 template <class T>
217 void ToolConstant<T>::CProperty::toStream( std::ostream& out ) const
218 {
219  out << static_cast<T> (*this);
220 }
221 
222 
223 /**
224  * @brief Initialize this property's value from a string.
225  * @param value String from which to initialize.
226  */
227 template <class T>
228 StatusCode ToolConstant<T>::CProperty::fromString( const std::string& value )
229 {
230  // A given constant should not be set from JO more than once.
231  if (m_setFromJO) {
232  throw ExcConstantReset (m_impl.m_toolName, this->name());
233  }
234 
235  // Convert from string and save as the value of the property.
236  CaloRec::Arrayrep rep (value, m_impl.m_toolName);
237  m_impl.m_constants.setrep (this->name(), rep);
238  T val;
239  CxxUtils::fromArrayrep (m_impl.m_constants.getrep (m_impl.m_toolName,
240  this->name()), val);
241  *this = val;
242 
243  // Remember that this property was set from JO.
244  m_setFromJO = true;
245  return StatusCode::SUCCESS;
246 }
247 
248 
249 //***************************************************************************
250 
251 
252 
253 /**
254  * @brief Initialize method. Derived classes must call this.
255  */
256 template <class BASE>
257  ATH_TWC_REQUIRES
258 StatusCode ToolWithConstants<BASE>::initialize()
259 {
260  ATH_CHECK( m_impl.initialize() );
261  ATH_CHECK( BASE::initialize() );
262  return StatusCode::SUCCESS;
263 }
264 
265 
266 /**
267  * @brief Create a @c Context object.
268  *
269  * This can then be passed to @c Constant::operator().
270  */
271 template <class BASE>
272  ATH_TWC_REQUIRES
273 inline
274 typename ToolWithConstants<BASE>::Context
275 ToolWithConstants<BASE>::context (const EventContext& ctx) const
276 {
277  return m_impl.context (ctx);
278 }
279 
280 
281 /**
282  * @brief Dump method (for debugging)
283  * @param stream Ostream to which to write.
284  * @param name Name to go in output
285  * @param ctx Event context.
286  */
287 template <class BASE>
288  ATH_TWC_REQUIRES
289 void ToolWithConstants<BASE>::writeConstants (std::ostream& stream,
290  const std::string& name,
291  const EventContext& ctx) const
292 {
293  m_impl.writeConstants (stream, name, ctx);
294 }
295 
296 
297 /**
298  * @brief Merge our constants into @c out with the proper prefix.
299  * @param[out] out Object to receive our constants.
300  * @param ctx Event context.
301  */
302 template <class BASE>
303  ATH_TWC_REQUIRES
304 StatusCode
305 ToolWithConstants<BASE>::mergeConstants (CaloRec::ToolConstants& out,
306  const EventContext& ctx) const
307 {
308  Context myctx = context (ctx);
309  return m_impl.mergeConstants (toolType(),
310  toolVersion(),
311  myctx,
312  m_isdummy (myctx),
313  out);
314 }
315 
316 
317 /**
318  * @brief Return the version number for this tool.
319  *
320  * A saved set of constants includes both the C++ class name and
321  * a version number. The idea is that the version number can
322  * be bumped whenever there's a backwards-incompatible change;
323  * this gives some protection against trying to use an old version
324  * of a tool with an incompatible newer set of constants.
325  *
326  * If you want a tool to have a version number, override this method.
327  * Otherwise, it will default to a version number of 0.
328  */
329 template <class BASE>
330  ATH_TWC_REQUIRES
331 int ToolWithConstants<BASE>::toolVersion() const
332 {
333  return 0;
334 }
335 
336 
337 /**
338  * @brief Return the name of the type of this tool.
339  *
340  * A saved set of constants includes both the C++ class name and
341  * a version number. Normally, the class name is taken from the
342  * Gaudi type() method, but that may be changed by overriding
343  * this method. This can be used, for example, when there are
344  * tools with distinct C++ classes but which are yet similar enough
345  * to combine together.
346  */
347 template <class BASE>
348  ATH_TWC_REQUIRES
349 const std::string& ToolWithConstants<BASE>::toolType() const
350 {
351  return this->type();
352 }
353 
354 
355 } // namespace CaloUtils