ATLAS Offline Software
Loading...
Searching...
No Matches
SGInputLoader.cxx
Go to the documentation of this file.
1
2
3/*
4 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
5*/
6
7// SGInputLoader.cxx
8// Implementation file for class SGInputLoader
10
11#include "SGInputLoader.h"
12
13// FrameWork includes
14#include "Gaudi/Property.h"
18
20
21//---------------------------------------------------------------------------------
22
23
24namespace
25{
26 struct DataObjIDSorter {
27 bool operator()( const DataObjID* a, const DataObjID* b ) { return a->fullKey() < b->fullKey(); }
28 };
29
30 // Sort a DataObjIDColl in a well-defined, reproducible manner.
31 // Used for making debugging dumps.
32 std::vector<const DataObjID*> sortedDataObjIDColl( const DataObjIDColl& coll )
33 {
34 std::vector<const DataObjID*> v;
35 v.reserve( coll.size() );
36 for ( const DataObjID& id : coll ) v.push_back( &id );
37 std::sort( v.begin(), v.end(), DataObjIDSorter() );
38 return v;
39 }
40}
41
42//---------------------------------------------------------------------------------
43
44SGInputLoader::SGInputLoader( const std::string& name,
45 ISvcLocator* pSvcLocator ) :
46 ::AthAlgorithm( name, pSvcLocator )
47{
48 //
49 // Property declaration
50 //
51 declareProperty( "Load", m_load, "create Output data dependencies for these objects")
52 ->declareUpdateHandler(&SGInputLoader::loader, this);
53
54}
55
56//---------------------------------------------------------------------------------
57
60
61//---------------------------------------------------------------------------------
62
63StatusCode
65{
66 ATH_MSG_VERBOSE ("Initializing " << name() << "...");
67
68 StatusCode sc(StatusCode::SUCCESS);
69
70 if (m_load.size() > 0) {
71 std::ostringstream str;
72 str << "Will explicitly preload the following DataObjects:";
73 for (auto &e : m_load) {
74 str << "\n + " << e;
75 if (e.key().empty()) {
76 sc = StatusCode::FAILURE;
77 str << " ERROR: empty key is not allowed!";
78 }
79 }
80 ATH_MSG_INFO(str.str());
81 }
82
83 return sc;
84}
85
86//---------------------------------------------------------------------------------
87
88StatusCode
90{
91 ATH_MSG_INFO ("Finalizing " << name() << "...");
92
93 return StatusCode::SUCCESS;
94}
95
96//---------------------------------------------------------------------------------
97
98StatusCode
99SGInputLoader::execute(const EventContext& /*ctx*/)
100{
101 StatusCode sc(StatusCode::SUCCESS);
102
103 ATH_MSG_DEBUG ("Executing " << name() << "...");
104
105 // add objects automatically added by the Scheduler
106 if (m_first) {
107 if (m_loadProxies.value()) {
108 for (DataObjID obj : outputDataObjs() ) {
109 // Strip any decoration name.
110 std::string::size_type ppos = obj.key().find ('.');
111 if (ppos < obj.key().size()-1) {
112 //obj.updateKey (obj.key().substr (0, ppos));
113 // commented out line above, to keep decoration on key so can distinguish undeclared decorations from undeclared objects
114 // undeclared objects will be an error, undeclared decorations will just be a warning
115 // TODO: restore the above modification (and make all transient proxies an error in loadObj, not just non-decorations) when all decorations are declared
116 }
117 m_load.emplace (std::move(obj));
118 }
119 }
120
121 // check if objects are not in EventStore
122 DataObjIDColl toLoad;
123 for (const DataObjID* obj : sortedDataObjIDColl (m_load)) {
124 // don't load anything that is in the ExtraOutputs list, which is used for objects created e.g. by the eventloopmgr
125 if( extraOutputDeps().count(*obj) ) {
126 ATH_MSG_DEBUG(obj->key() << " is in ExtraOutputs and will not be loaded");
127 continue;
128 } else if(std::string::size_type ppos = obj->key().find ('.'); ppos < obj->key().size()-1) {
129 // see if the object that the decoration is on is declared as extra output. Will assume the extra output
130 // will also provide such a decoration
131 DataObjID objcopy(*obj);
132 objcopy.updateKey(obj->key().substr (0, ppos));
133 if( extraOutputDeps().count(objcopy) ) {
134 ATH_MSG_DEBUG(obj->key() << "'s object/container is in ExtraOutputs and will not be loaded");
135 continue;
136 }
137 }
138 SG::VarHandleKey vhk(obj->clid(),obj->key(),Gaudi::DataHandle::Writer);
140 toLoad.emplace(*obj);
141 }
143 ATH_MSG_ERROR("Unresolved conditions dependency: "
144 << *obj);
145 return StatusCode::FAILURE;
146 }
147 else {
148 ATH_MSG_DEBUG("Will not auto-load proxy for non-EventStore object: "
149 << *obj);
150 }
151 }
152 m_load = std::move(toLoad);
153
154 m_first = false;
155 }
156
157 bool b = loadObjs( m_load );
158
159 if (m_dump.value()) {
161 }
162
163 if (m_preLoad.value()) {
164 SG::ReadHandle<DataHeader> eventDataHeader(m_dataHeaderKey.value(), evtStore()->name());
165 if (!eventDataHeader.isValid()) {
166 ATH_MSG_ERROR("Cannot retrieve DataHeader from StoreGate: " << m_dataHeaderKey);
167 return StatusCode::FAILURE;
168 }
169 for (const auto& element : *eventDataHeader) {
170 SG::DataProxy* dp = evtStore()->proxy(element.getPrimaryClassID(), element.getKey());
171 if (dp != 0 && dp->isValid()) {
172 if (nullptr == dp->accessData()) {
173 ATH_MSG_WARNING("unable to load proxy for " << element.getKey());
174 }
175 }
176 }
177 }
178
179 if (m_failEvt.value() && !b) {
180 ATH_MSG_ERROR("autoload of objects failed. aborting event processing");
181 sc = StatusCode::FAILURE;
182 }
183
184 return sc;
185}
186
187//---------------------------------------------------------------------------------
188
189void
190SGInputLoader::loader(Gaudi::Details::PropertyBase& p ) {
191
192 ATH_MSG_DEBUG("Adding to outputs: " << p.toString());
193
194 DataObjIDColl toLoad;
195
196 for (auto obj : m_load) {
197 // add an explicit storename as needed
198 SG::VarHandleKey vhk(obj.clid(),obj.key(),Gaudi::DataHandle::Writer);
199 obj.updateKey( vhk.objKey() );
200 toLoad.emplace(obj);
201 if(!outputDataObjs().count(obj)) { addDependency(obj,Gaudi::DataHandle::Writer); }
202 }
203 m_load = std::move(toLoad);
204
205}
206
207//---------------------------------------------------------------------------------
208
209bool
210SGInputLoader::loadObjs(const DataObjIDColl& objs) const {
211
212 bool ok = true;
213
214 for (auto &obj: objs) {
215
216 std::string::size_type ppos = obj.key().substr(0,obj.key().size()-1).find('.');
217
218 // use the parsing built into the VarHandleKey to get the correct
219 // StoreGate key
220 SG::VarHandleKey vhk(obj.clid(),obj.key().substr(0,ppos),Gaudi::DataHandle::Reader);
221
222 ATH_MSG_DEBUG("trying to load " << obj << " sgkey: " << vhk.key() );
223
224 SG::DataProxy* dp = evtStore()->proxy(obj.clid(), vhk.key());
225 if (dp != 0) {
226 ATH_MSG_DEBUG(" found proxy for " << obj);
227 if (dp->provider() == 0 && extraOutputDeps().find(obj)==extraOutputDeps().end()) {
228 if(ppos==std::string::npos) {
229 ATH_MSG_ERROR(" obj " << obj << " has no provider, and is only Transient - indicative of a missing output declaration" );
230 ok =false;
231 } else { // just warning for now for potentially undeclared decorations, instead of error, because too many cases to fix
232 ATH_MSG_WARNING(" decoration " << obj << " has no provider, and is only Transient - either a decoration output declaration is missing, or a ReadDecorHandleKey is being used to read a non-decoration" );
233 }
234 }
235 } else {
236 ok = false;
237 if (m_failEvt.value()) {
238 ATH_MSG_ERROR("unable to find proxy for " << obj);
239 } else {
240 ATH_MSG_WARNING("unable to find proxy for " << obj);
241 }
242 }
243 }
244
245 return ok;
246
247}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Helpers for checking error return status codes and reporting errors.
This file contains the class definition for the DataHeader and DataHeaderElement classes.
static Double_t a
static Double_t sc
void operator()(T1)
A property holding a SG store/key/clid from which a VarHandle is made.
size_t size() const
Number of registered mappings.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
virtual const DataObjIDColl & extraOutputDeps() const override
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
SGInputLoader()
Default constructor:
virtual ~SGInputLoader()
Gaudi::Property< bool > m_failEvt
void loader(Gaudi::Details::PropertyBase &)
bool loadObjs(const DataObjIDColl &objs) const
Gaudi::Property< bool > m_dump
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
Gaudi::Property< bool > m_loadProxies
Gaudi::Property< std::string > m_dataHeaderKey
DataObjIDColl m_load
Properties.
virtual StatusCode finalize() override
Gaudi::Property< bool > m_preLoad
virtual StatusCode initialize() override
virtual bool isValid() override final
Can the handle be successfully dereferenced?
A property holding a SG store/key/clid from which a VarHandle is made.
const std::string & key() const
Return the StoreGate ID for the referenced object.
const ServiceHandle< IProxyDict > & storeHandle() const
Return handle to the referenced store.
@ EVENT_STORE
Definition StoreID.h:26
@ CONDITION_STORE
Definition StoreID.h:28
static StoreID::type findStoreID(const std::string &storeName)
Definition StoreID.cxx:21
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:140
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:148
-event-from-file
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.