GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GResponseCache.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GResponseCache.cpp - Response cache class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2020 by Juergen Knoedlseder *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 /**
22  * @file GResponseCache.cpp
23  * @brief Response cache class implementation
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <cstring> // memcpy
32 #include "GTools.hpp"
33 #include "GResponseCache.hpp"
34 #include "GInstDir.hpp"
35 
36 /* __ Method name definitions ____________________________________________ */
37 
38 /* __ Macros _____________________________________________________________ */
39 
40 /* __ Coding definitions _________________________________________________ */
41 
42 /* __ Debug definitions __________________________________________________ */
43 
44 
45 /*==========================================================================
46  = =
47  = Constructors/destructors =
48  = =
49  ==========================================================================*/
50 
51 /***********************************************************************//**
52  * @brief Void constructor
53  ***************************************************************************/
55 {
56  // Initialise class members
57  init_members();
58 
59  // Return
60  return;
61 }
62 
63 
64 /***********************************************************************//**
65  * @brief Copy constructor
66  *
67  * @param[in] cache Response cache.
68  ***************************************************************************/
70 {
71  // Initialise class members
72  init_members();
73 
74  // Copy members
75  copy_members(cache);
76 
77  // Return
78  return;
79 }
80 
81 
82 /***********************************************************************//**
83  * @brief Destructor
84  ***************************************************************************/
86 {
87  // Free members
88  free_members();
89 
90  // Return
91  return;
92 }
93 
94 
95 /*==========================================================================
96  = =
97  = Operators =
98  = =
99  ==========================================================================*/
100 
101 /***********************************************************************//**
102  * @brief Assignment operator
103  *
104  * @param[in] cache Response cache.
105  * @return Response cache.
106  ***************************************************************************/
108 {
109  // Execute only if object is not identical
110  if (this != &cache) {
111 
112  // Free members
113  free_members();
114 
115  // Initialise private members
116  init_members();
117 
118  // Copy members
119  copy_members(cache);
120 
121  } // endif: object was not identical
122 
123  // Return this object
124  return *this;
125 }
126 
127 
128 /*==========================================================================
129  = =
130  = Public methods =
131  = =
132  ==========================================================================*/
133 
134 /***********************************************************************//**
135  * @brief Clear response cache
136  ***************************************************************************/
138 {
139  // Free members
140  free_members();
141 
142  // Initialise private members
143  init_members();
144 
145  // Return
146  return;
147 }
148 
149 
150 /***********************************************************************//**
151  * @brief Return number of elements in cache
152  *
153  * @return Number of elements in cache
154  *
155  * Returns the number of elements in the response cache.
156  ***************************************************************************/
157 int GResponseCache::size(void) const
158 {
159  // Initialize size
160  int size = 0;
161 
162  // Compute size
163  for (GResponseCacheName::const_iterator it_name = m_cache.begin();
164  it_name != m_cache.end(); ++it_name) {
165  for (GResponseCacheEnergy::const_iterator it_energy =
166  it_name->second.begin();
167  it_energy != it_name->second.end(); ++it_energy) {
168  size += it_energy->second.size();
169  }
170  }
171 
172  // Return size
173  return size;
174 }
175 
176 
177 /***********************************************************************//**
178  * @brief Return number of energies in cache
179  *
180  * @return Number of energies in cache
181  *
182  * Returns the number of energies in the response cache.
183  ***************************************************************************/
185 {
186  // Initialize number of energies
187  int nenergies = 0;
188 
189  // Compute number of elements
190  for (GResponseCacheName::const_iterator it_name = m_cache.begin();
191  it_name != m_cache.end(); ++it_name) {
192  for (GResponseCacheEnergy::const_iterator it_energy =
193  it_name->second.begin();
194  it_energy != it_name->second.end(); ++it_energy) {
195  nenergies += it_energy->second.size();
196  }
197  }
198 
199  // Return number of energies
200  return nenergies;
201 }
202 
203 
204 /***********************************************************************//**
205  * @brief Set cache value
206  *
207  * @param[in] name Cache name.
208  * @param[in] ereco Reconstructed energy.
209  * @param[in] etrue True energy.
210  * @param[in] value Cache value.
211  *
212  * Set cache value for a given @p name, reconstructed energy @p ereco, and
213  * true energy @p etrue.
214  ***************************************************************************/
215 void GResponseCache::set(const std::string& name,
216  const GEnergy& ereco,
217  const GEnergy& etrue,
218  const double& value)
219 {
220  // Get energy identifier
221  u_int64_t energy = hash(ereco, etrue);
222 
223  // Set cache value
224  m_cache[name][energy][0] = value;
225 
226  // Return
227  return;
228 }
229 
230 
231 /***********************************************************************//**
232  * @brief Set cache value
233  *
234  * @param[in] name Cache name.
235  * @param[in] dir Instrument direction.
236  * @param[in] ereco Reconstructed energy.
237  * @param[in] etrue True energy.
238  * @param[in] value Cache value.
239  *
240  * Set cache value for a given @p name, instrument direction @p dir,
241  * reconstructed energy @p ereco, and true energy @p etrue.
242  ***************************************************************************/
243 void GResponseCache::set(const std::string& name,
244  const GInstDir& dir,
245  const GEnergy& ereco,
246  const GEnergy& etrue,
247  const double& value)
248 {
249  // Get energy and direction identifier
250  u_int64_t energy = hash(ereco, etrue);
251  u_int64_t instdir = dir.hash();
252 
253  // Set cache value
254  m_cache[name][energy][instdir] = value;
255 
256  // Return
257  return;
258 }
259 
260 
261 /***********************************************************************//**
262  * @brief Check if cache contains a value for specific parameters
263  *
264  * @param[in] name Cache name.
265  * @param[in] ereco Reconstructed energy.
266  * @param[in] etrue True energy.
267  * @param[out] value Pointer to cached value (only if found).
268  * @return True if cached value was found, otherwise false.
269  *
270  * Check if the cache contains a value for a given @p name, reconstructed
271  * energy @p ereco, and true energy @p etrue.
272  *
273  * If the @p value pointer argument is not NULL, the method will return the
274  * cached value through this argument in case that the value exists.
275  ***************************************************************************/
276 bool GResponseCache::contains(const std::string& name,
277  const GEnergy& ereco,
278  const GEnergy& etrue,
279  double* value) const
280 {
281  // Initialise containment flag
282  bool contains = false;
283 
284  // Get energy identifier
285  u_int64_t energy = hash(ereco, etrue);
286  u_int64_t instdir = 0;
287 
288  // Search for name in cache
289  GResponseCacheName::const_iterator it_name = m_cache.find(name);
290  if (it_name != m_cache.end()) {
291 
292  // Search for energy in cache
293  GResponseCacheEnergy::const_iterator it_energy =
294  it_name->second.find(energy);
295  if (it_energy != it_name->second.end()) {
296 
297  // Search for direction in cache
298  GResponseCacheDir::const_iterator it_dir =
299  it_energy->second.find(instdir);
300  if (it_dir != it_energy->second.end()) {
301  contains = true;
302  if (value != NULL) {
303  *value = it_dir->second;
304  }
305  } // endif: direction found
306 
307  } // endif: energy found
308 
309  } // endif: name found
310 
311  // Return containment flag
312  return contains;
313 }
314 
315 
316 /***********************************************************************//**
317  * @brief Check if cache contains a value for specific parameters
318  *
319  * @param[in] name Cache name.
320  * @param[in] dir Instrument direction.
321  * @param[in] ereco Reconstructed energy.
322  * @param[in] etrue True energy.
323  * @param[out] value Pointer to cached value (only if found).
324  * @return True if cached value was found, otherwise false.
325  *
326  * Check if the cache contains a value for a given @p name, instrument
327  * direction @p dir, reconstructed energy @p ereco, and true energy @p etrue.
328  *
329  * If the @p value pointer argument is not NULL, the method will return the
330  * cached value through this argument in case that the value exists.
331  ***************************************************************************/
332 bool GResponseCache::contains(const std::string& name,
333  const GInstDir& dir,
334  const GEnergy& ereco,
335  const GEnergy& etrue,
336  double* value) const
337 {
338  // Initialise containment flag
339  bool contains = false;
340 
341  // Get energy identifier
342  u_int64_t energy = hash(ereco, etrue);
343  u_int64_t instdir = dir.hash();
344 
345  // Search for name in cache
346  GResponseCacheName::const_iterator it_name = m_cache.find(name);
347  if (it_name != m_cache.end()) {
348 
349  // Search for energy in cache
350  GResponseCacheEnergy::const_iterator it_energy =
351  it_name->second.find(energy);
352  if (it_energy != it_name->second.end()) {
353 
354  // Search for direction in cache
355  GResponseCacheDir::const_iterator it_dir =
356  it_energy->second.find(instdir);
357  if (it_dir != it_energy->second.end()) {
358  contains = true;
359  if (value != NULL) {
360  *value = it_dir->second;
361  }
362  } // endif: direction found
363 
364  } // endif: energy found
365 
366  } // endif: name found
367 
368  // Return containment flag
369  return contains;
370 }
371 
372 
373 /***********************************************************************//**
374  * @brief Clone response cache
375  *
376  * @return Pointer to deep copy of response cache.
377  ***************************************************************************/
379 {
380  return new GResponseCache(*this);
381 }
382 
383 
384 /***********************************************************************//**
385  * @brief Print response cache
386  *
387  * @param[in] chatter Chattiness.
388  * @return String containing response cache information.
389  ***************************************************************************/
390 std::string GResponseCache::print(const GChatter& chatter) const
391 {
392  // Initialise result string
393  std::string result;
394 
395  // Continue only if chatter is not silent
396  if (chatter != SILENT) {
397 
398  // Append header
399  result.append("=== GResponseCache ===");
400 
401  // Append total cache size
402  result.append("\n"+gammalib::parformat("Number of cached values"));
403  result.append(gammalib::str(size()));
404 
405  // Append information
406  for (GResponseCacheName::const_iterator it_name = m_cache.begin();
407  it_name != m_cache.end(); ++it_name) {
408 
409  // Append name
410  result.append("\n"+gammalib::parformat("Name")+it_name->first);
411 
412  // Compute number of sky directions and energies
413  int ndirs = 0;
414  int nenergies = 0;
415  for (GResponseCacheEnergy::const_iterator it_energy =
416  it_name->second.begin();
417  it_energy != it_name->second.end(); ++it_energy) {
418  nenergies++;
419  for (GResponseCacheDir::const_iterator it_dir =
420  it_energy->second.begin();
421  it_dir != it_energy->second.end(); ++it_dir) {
422  ndirs++;
423  }
424  }
425 
426  // Append number of reconstructed and true energies
427  result.append("\n"+gammalib::parformat("Number of energies"));
428  result.append(gammalib::str(nenergies));
429  result.append("\n"+gammalib::parformat("Number of directions"));
430  result.append(gammalib::str(ndirs));
431 
432  } // endfor: looped over names
433 
434  } // endif: chatter was not silent
435 
436  // Return result
437  return result;
438 }
439 
440 
441 /*==========================================================================
442  = =
443  = Private methods =
444  = =
445  ==========================================================================*/
446 
447 /***********************************************************************//**
448  * @brief Initialise class members
449  ***************************************************************************/
451 {
452  // Initialise members
453  m_cache.clear();
454 
455  // Return
456  return;
457 }
458 
459 
460 /***********************************************************************//**
461  * @brief Copy class members
462  *
463  * @param[in] cache Response cache.
464  ***************************************************************************/
466 {
467  // Copy members
468  m_cache = cache.m_cache;
469 
470  // Return
471  return;
472 }
473 
474 
475 /***********************************************************************//**
476  * @brief Delete class members
477  ***************************************************************************/
479 {
480  // Return
481  return;
482 }
483 
484 
485 /***********************************************************************//**
486  * @brief Encode reconstructued and true energy into hash value
487  *
488  * @param[in] ereco Reconstructed energy.
489  * @param[in] etrue True energy.
490  * @return Encoded reconstructued and true energy
491  *
492  * Encodes the reconstructued and true energy in a 64 Bit unsigned integer
493  * value. The energy are converted into single precision floating point
494  * values and mapped on a 64 Bit unsigned integer value. This provides unique
495  * hash values for all instruments up to the precision of floating point
496  * singles.
497  ***************************************************************************/
498 u_int64_t GResponseCache::hash(const GEnergy& ereco,
499  const GEnergy& etrue) const
500 {
501  // Allocate static array to store the two energies as floats
502  static float buffer[2];
503 
504  // Store the two energies as floats
505  buffer[0] = float(ereco.MeV());
506  buffer[1] = float(etrue.MeV());
507 
508  // Map the floats to an unsigned 64 Bit integer
509  u_int64_t hash; std::memcpy(&hash, &buffer, sizeof hash);
510 
511  // Return encoded value
512  return hash;
513 }
Abstract instrument direction base class definition.
void free_members(void)
Delete class members.
void init_members(void)
Initialise class members.
GResponseCache & operator=(const GResponseCache &cache)
Assignment operator.
GResponseCache(void)
Void constructor.
double MeV(void) const
Return energy in MeV.
Definition: GEnergy.cpp:321
Gammalib tools definition.
void copy_members(const GResponseCache &cache)
Copy class members.
int size(void) const
Return number of elements in cache.
u_int64_t hash(const GEnergy &ereco, const GEnergy &etrue) const
Encode reconstructued and true energy into hash value.
Abstract instrument direction base class.
Definition: GInstDir.hpp:51
Response cache class definition.
virtual ~GResponseCache(void)
Destructor.
virtual u_int64_t hash(void) const =0
GChatter
Definition: GTypemaps.hpp:33
GResponseCacheName m_cache
int nenergies(void) const
Return number of energies in cache.
GResponseCache * clone(void) const
Clone response cache.
void clear(void)
Clear response cache.
bool contains(const std::string &name, const GEnergy &ereco, const GEnergy &etrue, double *value=NULL) const
Check if cache contains a value for specific parameters.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
Response cache class.
void set(const std::string &name, const GEnergy &ereco, const GEnergy &etrue, const double &value)
Set cache value.
std::string print(const GChatter &chatter=NORMAL) const
Print response cache.
Class that handles energies in a unit independent way.
Definition: GEnergy.hpp:48
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489