ATLAS Offline Software
Loading...
Searching...
No Matches
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/AthenaDependencyHelpers.h>
14#include <SystematicsHandles/CopyHelpers.h>
15
16//
17// method implementations
18//
19
20namespace CP
21{
22 template<typename T> template<typename T2> SysCopyHandle<T> ::
23 SysCopyHandle (T2 *owner, const std::string& propertyName,
24 const std::string& propertyValue,
25 const std::string& propertyDescription)
26 : SysCopyHandle (propertyValue, "", owner)
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 owner->declareProperty (propertyName + "Type", m_typeName,
31 "an explicit type name for output dependencies");
32 }
33
34 template<typename T> template<typename T2> SysCopyHandle<T> ::
35 SysCopyHandle (const std::string &inputName, const std::string &outputName, T2 *owner)
36 : AsgMessagingForward (owner), m_inputName(inputName), m_outputName(outputName)
37 , m_evtStoreGetter ([owner] () {return &*owner->evtStore();})
38 {
39#ifndef XAOD_STANDALONE
40 m_addAlgDependency = [owner](const DataObjID& id, Gaudi::DataHandle::Mode mode) {
41 owner->addDependency(id, mode);
42 };
43#endif
44 }
45
46
47
48 template<typename T> bool SysCopyHandle<T> ::
49 empty () const noexcept
50 {
51 return m_inputName.empty();
52 }
53
54
55
56 template<typename T> SysCopyHandle<T> ::
57 operator bool () const noexcept
58 {
59 return !m_inputName.empty();
60 }
61
62
63
64 template<typename T> std::string SysCopyHandle<T> ::
65 getNamePattern () const
66 {
67 if (!m_outputName.empty())
68 return m_outputName;
69 else
70 return m_inputName;
71 }
72
73
74
75 template<typename T> StatusCode SysCopyHandle<T> ::
76 initialize (SysListHandle& sysListHandle)
77 {
78 if (!m_outputName.empty())
79 ANA_CHECK (sysListHandle.service().registerCopy (m_inputName, m_outputName));
80 return sysListHandle.addHandle (*this);
81 }
82
83
84
85 template<typename T> StatusCode SysCopyHandle<T> ::
86 initialize (SysListHandle& sysListHandle, SG::AllowEmptyEnum)
87 {
88 if (!empty())
89 return initialize (sysListHandle);
90 else
91 return StatusCode::SUCCESS;
92 }
93
94
95
96 template<typename T> ::StatusCode SysCopyHandle<T> ::
97 getCopy (T*& object, const CP::SystematicSet& sys) const
98 {
99 auto cache = m_nameCache.find (sys);
100 if (cache == m_nameCache.end())
101 {
102 if (m_nameCache.empty())
103 throw std::logic_error ("uninitialized SysCopyHandle (" + m_inputName + ")");
104 else
105 throw std::logic_error ("unsupported systematic in SysCopyHandle (" + m_inputName + "): (" + sys.name() + ")");
106 }
107 assert (m_evtStore);
108 if (std::get<1>(cache->second).empty())
109 {
110 // if no output name is configured, act like an update handle
111 // (or read handle if const qualified)
112 return m_evtStore->retrieve (object, std::get<0>(cache->second));
113 } else
114 {
115 // if an output name is configured, retrieve the input object as
116 // a const object, (shallow) copy it, record the copy and return
117 // it.
118
119 const T *inputObject = nullptr;
120 if (m_evtStore->retrieve (inputObject, std::get<0>(cache->second)).isFailure())
121 return StatusCode::FAILURE;
122
123 // using an intermediate, since in the const version we can't
124 // pass in our argument pointer
125 std::remove_const_t<T> *tmpObject = nullptr;
126 if (detail::ShallowCopy<std::remove_const_t<T>>::getCopy
127 (msg(), *m_evtStore, tmpObject, inputObject,
128 std::get<1>(cache->second), std::get<2>(cache->second)).isFailure())
129 return StatusCode::FAILURE;
130 object = tmpObject;
131 return StatusCode::SUCCESS;
132 }
133 }
134
135
136
137 template<typename T> CP::SystematicSet SysCopyHandle<T> ::
138 getInputAffecting (const ISystematicsSvc& svc) const
139 {
140 return svc.getObjectSystematics (m_inputName);
141 }
142
143
144
145 template<typename T> StatusCode SysCopyHandle<T> ::
146 fillSystematics (const ISystematicsSvc& svc,
147 const CP::SystematicSet& fullAffecting,
148 const std::vector<CP::SystematicSet>& sysList)
149 {
150 const CP::SystematicSet affecting = svc.getObjectSystematics (m_inputName);
151
152 for (auto& sys : sysList)
153 {
154 CP::SystematicSet inputSys;
155 ANA_CHECK (SystematicSet::filterForAffectingSystematics (sys, affecting, inputSys));
156 std::string inputName;
157 ANA_CHECK (svc.makeSystematicsName (inputName, m_inputName, inputSys));
158 m_nameCache.emplace (sys, std::make_tuple (inputName, "", ""));
159 }
160
161 if (!m_outputName.empty())
162 {
163 ANA_MSG_DEBUG ("SysCopyHandle: " << m_inputName << " make copy " << m_outputName);
164 ANA_CHECK (svc.setObjectSystematics (m_outputName, fullAffecting));
165 for (auto& sys : sysList)
166 {
167 std::string outputName;
168 ANA_CHECK (svc.makeSystematicsName (outputName, m_outputName, sys));
169 auto& cache = m_nameCache[sys];
170 std::get<1>(cache) = outputName;
171 std::get<2>(cache) = outputName+"Aux.";
172 ANA_MSG_DEBUG ("SysCopyHandle: " << std::get<0>(cache) << " -> " << std::get<1>(cache) << " (" << sys.name() << ")");
173 }
174 }
175 if (!m_evtStore)
176 m_evtStore = m_evtStoreGetter();
177
178#ifndef XAOD_STANDALONE
179 ANA_CHECK (addDecorationDependency(svc, "", false));
180 if (!m_outputName.empty())
181 {
182 const CLID clidRead = detail::getClidForDependency<std::remove_const_t<T>>("", "deco", false);
183 const CLID clidWrite = detail::getClidForDependency<std::remove_const_t<T>>(m_typeName, "deco", true);
184 for (const auto& decoName : svc.getObjectDecorations(m_inputName))
185 {
186 ANA_CHECK (detail::addSysDependency(msg(), svc, m_addAlgDependency, clidRead, m_inputName, Gaudi::DataHandle::Reader, decoName, false));
187 ANA_CHECK (detail::addSysDependency(msg(), svc, m_addAlgDependency, clidWrite, m_outputName, Gaudi::DataHandle::Writer, decoName, true));
188 }
189 }
190#endif
191
192 return StatusCode::SUCCESS;
193 }
194
195
196
197 template<typename T> StatusCode SysCopyHandle<T> ::
198 addDecorationDependency (const ISystematicsSvc& svc, const std::string& decoName, bool decoWrite)
199 {
200#ifdef XAOD_STANDALONE
201 (void) svc;
202 (void) decoName;
203 (void) decoWrite;
204 return StatusCode::SUCCESS;
205#else
206 const CLID clidRead = detail::getClidForDependency<std::remove_const_t<T>>("", decoName, decoWrite);
207 const CLID clidWrite = detail::getClidForDependency<std::remove_const_t<T>>(m_typeName, decoName, decoWrite);
208
209 // if no output name is given, we act like an update or read handle on the input name
210 if (m_outputName.empty())
211 {
212 if (!std::is_const_v<T>)
213 ANA_MSG_INFO ("SysCopyHandle acting as update handle for " << m_inputName << " this likely won't work in AthenaMT");
214
215 // Both const (read) and non-const (update) use Reader mode for dependencies
216 ANA_CHECK (detail::addSysDependency(msg(), svc, m_addAlgDependency, clidRead, m_inputName, Gaudi::DataHandle::Reader, decoName, decoWrite));
217 return StatusCode::SUCCESS;
218 }
219
220 // otherwise we read the input name and write the output name
221
222 // if this is for reading a decoration, we only declare it for the
223 // input
224 if (decoName.empty() || decoWrite == false)
225 {
226 ANA_CHECK (detail::addSysDependency(msg(), svc, m_addAlgDependency, clidRead, m_inputName, Gaudi::DataHandle::Reader, decoName, decoWrite));
227 }
228
229 // if this is for adding a decoration, we only declare it for the
230 // output
231 if (decoName.empty() || decoWrite == true)
232 {
233 ANA_CHECK (detail::addSysDependency(msg(), svc, m_addAlgDependency, clidWrite, m_outputName, Gaudi::DataHandle::Writer, decoName, decoWrite));
234 }
235 return StatusCode::SUCCESS;
236#endif
237 }
238}