ATLAS Offline Software
SysCopyHandle.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /// @author Nils Krumnack
6 
7 
8 //
9 // includes
10 //
11 
12 #include <AsgMessaging/MessageCheck.h>
13 #include <SystematicsHandles/CopyHelpers.h>
14 
15 //
16 // method implementations
17 //
18 
19 namespace CP
20 {
21  template<typename T> template<typename T2> SysCopyHandle<T> ::
22  SysCopyHandle (T2 *owner, const std::string& propertyName,
23  const std::string& propertyValue,
24  const std::string& propertyDescription)
25  : AsgMessagingForward (owner), m_inputName (propertyValue)
26  , m_evtStoreGetter ([owner] () {return &*owner->evtStore();})
27  {
28  owner->declareProperty (propertyName, m_inputName, propertyDescription);
29  owner->declareProperty (propertyName + "Out", m_outputName, "the (optional) name of the copy we create of " + propertyName);
30  }
31 
32  template<typename T> template<typename T2> SysCopyHandle<T> ::
33  SysCopyHandle (const std::string &inputName, const std::string &outputName, T2 *owner)
34  : AsgMessagingForward (owner), m_inputName(inputName), m_outputName(outputName)
35  , m_evtStoreGetter ([owner] () {return &*owner->evtStore();})
36  {}
37 
38 
39 
40  template<typename T> bool SysCopyHandle<T> ::
41  empty () const noexcept
42  {
43  return m_inputName.empty();
44  }
45 
46 
47 
48  template<typename T> SysCopyHandle<T> ::
49  operator bool () const noexcept
50  {
51  return !m_inputName.empty();
52  }
53 
54 
55 
56  template<typename T> std::string SysCopyHandle<T> ::
57  getNamePattern () const
58  {
59  if (!m_outputName.empty())
60  return m_outputName;
61  else
62  return m_inputName;
63  }
64 
65 
66 
67  template<typename T> StatusCode SysCopyHandle<T> ::
68  initialize (SysListHandle& sysListHandle)
69  {
70  if (!m_outputName.empty())
71  ANA_CHECK (sysListHandle.service().registerCopy (m_inputName, m_outputName));
72  return sysListHandle.addHandle (*this);
73  }
74 
75 
76 
77  template<typename T> StatusCode SysCopyHandle<T> ::
78  initialize (SysListHandle& sysListHandle, SG::AllowEmptyEnum)
79  {
80  if (!empty())
81  return initialize (sysListHandle);
82  else
83  return StatusCode::SUCCESS;
84  }
85 
86 
87 
88  template<typename T> ::StatusCode SysCopyHandle<T> ::
89  getCopy (T*& object, const CP::SystematicSet& sys) const
90  {
91  auto cache = m_nameCache.find (sys);
92  if (cache == m_nameCache.end())
93  {
94  if (m_nameCache.empty())
95  throw std::logic_error ("uninitialized SysCopyHandle (" + m_inputName + ")");
96  else
97  throw std::logic_error ("unsupported systematic in SysCopyHandle (" + m_inputName + "): (" + sys.name() + ")");
98  }
99  assert (m_evtStore);
100  if (std::get<1>(cache->second).empty())
101  {
102  // if no output name is configured, act like an update handle
103  // (or read handle if const qualified)
104  return m_evtStore->retrieve (object, std::get<0>(cache->second));
105  } else
106  {
107  // if an output name is configured, retrieve the input object as
108  // a const object, (shallow) copy it, record the copy and return
109  // it.
110 
111  const T *inputObject = nullptr;
112  if (m_evtStore->retrieve (inputObject, std::get<0>(cache->second)).isFailure())
113  return StatusCode::FAILURE;
114 
115  // using an intermediate, since in the const version we can't
116  // pass in our argument pointer
117  std::remove_const_t<T> *tmpObject = nullptr;
118  if (detail::ShallowCopy<std::remove_const_t<T>>::getCopy
119  (msg(), *m_evtStore, tmpObject, inputObject,
120  std::get<1>(cache->second), std::get<2>(cache->second)).isFailure())
121  return StatusCode::FAILURE;
122  object = tmpObject;
123  return StatusCode::SUCCESS;
124  }
125  }
126 
127 
128 
129  template<typename T> CP::SystematicSet SysCopyHandle<T> ::
130  getInputAffecting (const ISystematicsSvc& svc) const
131  {
132  return svc.getObjectSystematics (m_inputName);
133  }
134 
135 
136 
137  template<typename T> StatusCode SysCopyHandle<T> ::
138  fillSystematics (const ISystematicsSvc& svc,
139  const CP::SystematicSet& fullAffecting,
140  const std::vector<CP::SystematicSet>& sysList)
141  {
142  const CP::SystematicSet affecting = svc.getObjectSystematics (m_inputName);
143 
144  for (auto& sys : sysList)
145  {
146  CP::SystematicSet inputSys;
147  ANA_CHECK (SystematicSet::filterForAffectingSystematics (sys, affecting, inputSys));
148  std::string inputName;
149  ANA_CHECK (svc.makeSystematicsName (inputName, m_inputName, inputSys));
150  m_nameCache.emplace (sys, std::make_tuple (inputName, "", ""));
151  }
152 
153  if (!m_outputName.empty())
154  {
155  ANA_MSG_DEBUG ("SysCopyHandle: " << m_inputName << " make copy " << m_outputName);
156  ANA_CHECK (svc.setObjectSystematics (m_outputName, fullAffecting));
157  for (auto& sys : sysList)
158  {
159  std::string outputName;
160  ANA_CHECK (svc.makeSystematicsName (outputName, m_outputName, sys));
161  auto& cache = m_nameCache[sys];
162  std::get<1>(cache) = outputName;
163  std::get<2>(cache) = outputName+"Aux.";
164  ANA_MSG_DEBUG ("SysCopyHandle: " << std::get<0>(cache) << " -> " << std::get<1>(cache) << " (" << sys.name() << ")");
165  }
166  }
167  if (!m_evtStore)
168  m_evtStore = m_evtStoreGetter();
169  return StatusCode::SUCCESS;
170  }
171 }