ATLAS Offline Software
SystematicsCache.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 
8 #ifndef PAT_INTERFACES__SYSTEMATICS_CACHE_H
9 #define PAT_INTERFACES__SYSTEMATICS_CACHE_H
10 
16 #include <functional>
17 #include <mutex>
18 #include <tbb/concurrent_unordered_map.h>
19 
20 namespace CP
21 {
82 
83  template<typename CalibData>
85  {
88 
89  public:
90 
92 
93  template<typename T2>
94  SystematicsCache (T2 *val_parent);
95 
98  void initialize (CP::SystematicSet val_affectingSystematics,
99  std::function<StatusCode (const CP::SystematicSet& sys, CalibData& result)> val_calc) noexcept;
100 
103 
104 
110 
111 
115 
116 
120 
121 
124 
125  private:
126 
129 
133 
135  mutable tbb::concurrent_unordered_map<CP::SystematicSet,std::shared_ptr<const CalibData>,SystematicSetHash> m_cache ATLAS_THREAD_SAFE;
136 
141  mutable std::mutex m_calcMutex;
142  };
143 
144 
145 
148 
151  SystematicsCache (T2 *val_parent)
152  : AsgMessagingForward (val_parent)
153  {}
154 
155 
156 
157  template<typename CalibData> void SystematicsCache<CalibData> ::
158  initialize (CP::SystematicSet val_affectingSystematics,
159  std::function<StatusCode (const CP::SystematicSet& sys, CalibData& result)> val_calc) noexcept
160  {
161  m_calc = std::move (val_calc);
162  m_affectingSystematics = std::move (val_affectingSystematics);
163  m_cache.clear ();
164  }
165 
166 
167 
168  template<typename CalibData>
170  affectingSystematics () const noexcept
171  {
172  return m_affectingSystematics;
173  }
174 
175 
176 
177  template<typename CalibData>
180  {
181  // this is not technically correct, but what a lot of people do
183  }
184 
185 
186 
187  template<typename CalibData>
189  get (const CP::SystematicSet& sys, const CalibData*& result) const
190  {
191  // fast-path, check if we already calculated this
192  auto iter = m_cache.find (sys);
193  if (ATH_LIKELY (iter != m_cache.end())) //[[likely]], removed until C++20 support
194  {
195  result = iter->second.get();
196  return StatusCode::SUCCESS;
197  }
198 
199  // create a lock to prevent the concurrent (or duplicate)
200  // execution of the \ref m_calc function. if that function is
201  // thread-safe this lock is not strictly necessary. however,
202  // given that it is hard to enforce that the function is indeed
203  // thread-safe and there are essentially no performance gains to
204  // be had, this seems safer (unless \ref m_calc acquires mutexes
205  // in a way that causes a dead-lock).
206  std::lock_guard<std::mutex> lock (m_calcMutex);
207 
208  // check if another thread already calculated this value while we
209  // acquired the lock
210  iter = m_cache.find (sys);
211  if (iter != m_cache.end())
212  {
213  result = iter->second.get();
214  return StatusCode::SUCCESS;
215  }
216 
217  // we will only ever calculate the systematics for our set of
218  // affecting systematics, any systematics that are not affecting
219  // us will be ignored
220  CP::SystematicSet mysys;
222 
223  std::shared_ptr<const CalibData> mycalib;
224  {
225  // check if our affecting systematics are known already
226  auto iter = m_cache.find (mysys);
227  if (iter != m_cache.end())
228  mycalib = iter->second;
229  else
230  {
231  // this will now actually calculate the systematics. note
232  // that if this fails, nothing gets cached, but we should also
233  // be aborting
234  auto value = std::make_shared<CalibData> ();
235  ANA_CHECK (m_calc (mysys, *value));
236 
237  // store for the affecting systematic
238  auto emplace_result = m_cache.emplace (mysys, value);
239  mycalib = emplace_result.first->second;
240  }
241  }
242 
243  // store for user requested systematics as well, which may or may
244  // not be the same as the affecting systematics, but if it is
245  // already there, this will do nothing.
246  m_cache.emplace (sys, mycalib);
247  result = mycalib.get();
248  return StatusCode::SUCCESS;
249  }
250 
251 
252 
253  template<typename CalibData>
256  {
257  auto emplace_result = m_cache.emplace (sys, std::make_shared<CalibData> (std::move (value)));
258  if (emplace_result.second == false)
259  {
260  ANA_MSG_ERROR ("failed to add systematic, already present: " << sys.name());
261  return StatusCode::FAILURE;
262  }
263 
264  for (const auto& var : sys)
266 
267  return StatusCode::SUCCESS;
268  }
269 
270 
271 
272  template<typename CalibData>
274  add (const SystematicVariation& variation, CalibData value)
275  {
277  sys.insert (variation);
278  return add (sys, std::move (value));
279  }
280 }
281 
282 #endif
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
get_generator_info.result
result
Definition: get_generator_info.py:21
asg::AsgMessagingForward
base class to forward messages to another class
Definition: AsgMessagingForward.h:29
CP::SystematicsCache::initialize
void initialize(CP::SystematicSet val_affectingSystematics, std::function< StatusCode(const CP::SystematicSet &sys, CalibData &result)> val_calc) noexcept
initialize with the list of affecting systematics and a function to calculate the calibration data fo...
Definition: SystematicsCache.h:158
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
CP::SystematicSetHash
SystematicSet hash function for general use.
Definition: SystematicSet.h:175
SystematicSet.h
taskman.template
dictionary template
Definition: taskman.py:317
CP::SystematicSet
Class to wrap a set of SystematicVariations.
Definition: SystematicSet.h:31
AsgMessagingForward.h
ANA_MSG_ERROR
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:294
athena.value
value
Definition: athena.py:122
ANA_CHECK
#define ANA_CHECK(EXP)
check whether the given expression was successful
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:324
const
bool const RAWDATA *ch2 const
Definition: LArRodBlockPhysicsV0.cxx:562
CP::SystematicVariation
Definition: SystematicVariation.h:47
CP
Select isolated Photons, Electrons and Muons.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:48
mapkey::sys
@ sys
Definition: TElectronEfficiencyCorrectionTool.cxx:42
asg::AsgMessagingForward::msg
MsgStream & msg() const
The standard message stream.
Definition: AsgMessagingForward.cxx:24
CP::SystematicsCache::isAffectedBySystematic
bool isAffectedBySystematic(const SystematicVariation &systematic) const
whether we are affected by the given systematic variation
Definition: SystematicsCache.h:179
AthUnlikelyMacros.h
CalibData
Definition: ZDCNLCalibration.h:35
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
CP::SystematicsCache::m_calc
std::function< StatusCode(const CP::SystematicSet &sys, CalibData &result)> m_calc
the function to calculate the calibration data for a given systematics
Definition: SystematicsCache.h:132
CP::SystematicSet::end
const_iterator end() const
description: const iterator to the end of the set
Definition: SystematicSet.h:59
asg::AsgMessagingForward::AsgMessagingForward
AsgMessagingForward(T *owner)
forwarding constructor
Definition: AsgMessagingForward.h:83
CP::SystematicSet::insert
void insert(const SystematicVariation &systematic)
description: insert a systematic into the set
Definition: SystematicSet.cxx:88
private
#define private
Definition: DetDescrConditionsDict_dict_fixes.cxx:13
CP::SystematicsCache::m_calcMutex
std::mutex m_calcMutex
a mutex to protext against concurrent execution of m_calc
Definition: SystematicsCache.h:141
python.Dumpers.typename
def typename(t)
Definition: Dumpers.py:194
CP::SystematicsCache::ATLAS_THREAD_SAFE
tbb::concurrent_unordered_map< CP::SystematicSet, std::shared_ptr< const CalibData >, SystematicSetHash > m_cache ATLAS_THREAD_SAFE
the cache of previously calculated calibration data
Definition: SystematicsCache.h:135
CP::SystematicsCache::SystematicsCache
SystematicsCache(T2 *val_parent)
Definition: SystematicsCache.h:151
CP::SystematicSet::find
iterator find(const SystematicVariation &sys) const
description: find an element in the set
Definition: SystematicSet.h:63
ATH_LIKELY
#define ATH_LIKELY(x)
Definition: AthUnlikelyMacros.h:16
CP::SystematicsCache
helper class to cache systematics varied calibration constants inside a ISystematicsTool or IRentrant...
Definition: SystematicsCache.h:85
CP::SystematicsCache::m_affectingSystematics
CP::SystematicSet m_affectingSystematics
the list of affecting systematics
Definition: SystematicsCache.h:128
CP::SystematicsCache::affectingSystematics
const CP::SystematicSet & affectingSystematics() const noexcept
the list of affecting systematics
Definition: SystematicsCache.h:170
CP::SystematicsCache::add
StatusCode add(const CP::SystematicSet &sys, CalibData value)
add an individual systematic variation
Definition: SystematicsCache.h:255
checker_macros.h
Define macros for attributes used to control the static checker.
CP::SystematicsCache::get
StatusCode get(const CP::SystematicSet &sys, const CalibData *&result) const
get the pointer to the cached calibration data for the given systematic, calculating it if necessary
Definition: SystematicsCache.h:189
CP::SystematicSet::filterForAffectingSystematics
static StatusCode filterForAffectingSystematics(const SystematicSet &systConfig, const SystematicSet &affectingSystematics, SystematicSet &filteredSystematics)
description: filter the systematics for the affected systematics returns: success guarantee: strong f...
Definition: SystematicSet.cxx:213