ATLAS Offline Software
Loading...
Searching...
No Matches
CondInputLoader.cxx
Go to the documentation of this file.
1
2
3/*
4 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
5*/
6
7// CondInputLoader.cxx
8// Implementation file for class CondInputLoader
10
11#include "CondInputLoader.h"
12
13// FrameWork includes
14#include "Gaudi/Property.h"
15#include "GaudiKernel/IClassIDSvc.h"
26
29#include "ICondSvcSetupDone.h"
30
31#include "TClass.h"
32
33
34namespace
35{
36 struct DataObjIDSorter {
37 bool operator()( const DataObjID* a, const DataObjID* b ) { return a->fullKey() < b->fullKey(); }
38 };
39
40 // Sort a DataObjIDColl in a well-defined, reproducible manner.
41 // Used for making debugging dumps.
42 std::vector<const DataObjID*> sortedDataObjIDColl( const DataObjIDColl& coll )
43 {
44 std::vector<const DataObjID*> v;
45 v.reserve( coll.size() );
46 for ( const DataObjID& id : coll ) v.push_back( &id );
47 std::sort( v.begin(), v.end(), DataObjIDSorter() );
48 return v;
49 }
50}
51
53// Public methods:
55
56// Constructors
58CondInputLoader::CondInputLoader( const std::string& name,
59 ISvcLocator* pSvcLocator ) :
60 ::AthReentrantAlgorithm( name, pSvcLocator ),
61 m_condStore("StoreGateSvc/ConditionStore", name),
62 m_condSvc("CondSvc",name),
63 m_IOVSvc("IOVSvc",name),
64 m_IOVDbSvc("IOVDbSvc",name),
65 m_clidSvc("ClassIDSvc",name),
66 m_rcuSvc("Athena::RCUSvc",name)
67{
68 //
69 // Property declaration
70 //
71 auto props = getProperties();
72 for( Gaudi::Details::PropertyBase* prop : props ) {
73 if (prop->name() == "ExtraOutputs" || prop->name() == "ExtraInputs") {
74 prop->declareUpdateHandler
76 }
77 }
78}
79
80//-----------------------------------------------------------------------------
81
82// Athena Algorithm's Hooks
84StatusCode
86{
87 ATH_MSG_INFO ("Initializing " << name() << "...");
88
89 ATH_CHECK( m_condSvc.retrieve() );
90 ATH_CHECK( m_condStore.retrieve() );
91 ATH_CHECK( m_clidSvc.retrieve() );
92 ATH_CHECK( m_rcuSvc.retrieve() );
93 ATH_CHECK( m_dictLoader.retrieve() );
94 ATH_CHECK( m_tpCnvSvc.retrieve() );
95
96 // Trigger read of IOV database
97 ServiceHandle<IIOVSvc> ivs("IOVSvc",name());
98 ATH_CHECK( ivs.retrieve() );
99
100 // Update the SG keys if different from Folder Names
101 ATH_CHECK( m_IOVDbSvc.retrieve() );
102 std::vector<std::string> keys = m_IOVDbSvc->getKeyList();
104 DataObjIDColl handles_to_load;
105
106 for (const std::string& key : keys) {
107 if( m_IOVDbSvc->getKeyInfo(key, info) ) {
108 m_keyFolderMap[key] = info.folderName;
109 } else {
110 ATH_MSG_WARNING("unable to retrieve keyInfo for " << key );
111 }
112 }
113
114 // We can get warnings later if we don't get this defined first.
115 TClass::GetClass ("coral::AttributeList", true, false);
116
117 for (const auto& itr : m_keyFolderMap) { //loop over keys of IOVDbSvc
118 for (auto id : m_load) {
119 if (id.key() == itr.second) {//CondInputLoader deals with this folder
120 if (itr.second != itr.first) {
121 ATH_MSG_DEBUG(" mapping folder " << id.key() << " to SGkey "
122 << itr.first);
123 id.updateKey( itr.first );
124 }//end if folder-name doesn't match SG key
125
126 SG::VarHandleKey vhk(id.clid(),id.key(),Gaudi::DataHandle::Writer,
128 handles_to_load.emplace(vhk.fullKey());
129
130 // Loading root dictionaries in a multithreaded environment
131 // is unreliable.
132 // So try to be sure all dictionaries are loaded now.
133 RootType rt = loadDict (id.clid());
134
135 // Special case for LArConditionsSubset classes.
136 if (rt.Class()) {
137 size_t nbases = rt.BaseSize();
138 std::string pat = "LArConditionsContainer<";
139 for (size_t ibase = 0; ibase < nbases; ++ibase) {
140 std::string basename = rt.BaseAt(ibase).Name();
141 if (basename.starts_with( pat)) {
142 std::string subset = "LArConditionsSubset<" + basename.substr (pat.size(), std::string::npos);
143 loadDict (subset);
144 loadDict ("LArConditionsSubset_p1");
145 }
146 }
147 }
148
149 break; //quit loop over m_load
150 } // end if CondInputLoader deals with this folder
151 }//end loop over m_load
152 }//end loop over m_keyFolderMap
153
154 m_load = handles_to_load;
155 m_handlesToCreate = handles_to_load;
156
157 // Add in all the base classes known to StoreGate, in case a handle
158 // is read via its base class. These will be added to the output deps,
159 // and also registered with the CondSvc, as the scheduler needs this
160 // info.
161
162 std::ostringstream ost;
163 ost << "Adding base classes:";
164 for (auto &e : sortedDataObjIDColl (handles_to_load)) {
165 // ignore empty keys
166 if (e->key().empty()) continue;
167
168 ost << "\n + " << *e << " ->";
169 CLID clid = e->clid();
170 const SG::BaseInfoBase* bib = SG::BaseInfoBase::find( clid );
171 if ( ! bib ) {
172 ost << " no bases";
173 } else {
174 for (CLID clid2 : bib->get_bases()) {
175 if (clid2 != clid) {
176 std::string base("UNKNOWN");
177 m_clidSvc->getTypeNameOfID(clid2,base).ignore();
178 ost << " " << base << " (" << clid2 << ")";
179 SG::VarHandleKey vhk(clid2,e->key(),Gaudi::DataHandle::Writer,
181 m_load.value().emplace(vhk.fullKey());
182 // Again, make sure all needed dictionaries are loaded.
183 m_dictLoader->load_type (clid2, true);
184 }
185 }
186 }
187 }
188 ATH_MSG_INFO(ost.str());
189
190
191 // Update the properties, set the ExtraOutputs for Alg deps
192 const Gaudi::Details::PropertyBase &p = getProperty("Load");
193
194 ATH_MSG_DEBUG("setting prop ExtraOutputs to " << p.toString());
195 if (!setProperty("ExtraOutputs", p).isSuccess()) {
196 ATH_MSG_ERROR("failed setting property ExtraOutputs");
197 return StatusCode::FAILURE;
198 }
199
200 StatusCode sc(StatusCode::SUCCESS);
201 std::ostringstream str;
202 str << "Will create WriteCondHandle dependencies for the following DataObjects:";
203 for (auto &e : sortedDataObjIDColl(m_load)) {
204 str << "\n + " << *e;
205 if (e->key().empty()) {
206 sc = StatusCode::FAILURE;
207 str << " ERROR: empty key is not allowed!";
208 } else {
209 SG::VarHandleKey vhk(e->clid(),e->key(),Gaudi::DataHandle::Writer,
211 if (m_condSvc->regHandle(this, vhk).isFailure()) {
212 ATH_MSG_ERROR("Unable to register WriteCondHandle " << vhk.fullKey());
213 sc = StatusCode::FAILURE;
214 }
215 ATH_MSG_DEBUG("Ignoring proxy: " << vhk.key());
216 m_IOVSvc->ignoreProxy(vhk.fullKey().clid(), vhk.key());
217 }
218 }
219 ATH_MSG_INFO(str.str());
220
221 return sc;
222}
223
224//-----------------------------------------------------------------------------
225
226StatusCode
228{
229 ATH_MSG_INFO ("Finalizing " << name() << "...");
230
231 return StatusCode::SUCCESS;
232}
233
234//-----------------------------------------------------------------------------
235
236StatusCode
238{
239 //
240 // now create the CondCont<T>. This has to be done after initialize(),
241 // as we need to make sure that all Condition Objects have been instantiated
242 // so as to fill the static condition obj registry via REGISTER_CC
243 //
244 // we use a VHK to store the info instead of a DataObjIDColl, as this saves
245 // us the trouble of stripping out the storename from the key later.
246 //
247
248 m_vhk.clear(); // in case of multiple start transitions
249
250 bool fail(false);
251 for (const DataObjID* ditr : sortedDataObjIDColl (m_handlesToCreate)) {
252 SG::VarHandleKey vhk(ditr->clid(),ditr->key(),Gaudi::DataHandle::Writer);
253 if ( ! m_condStore->contains<CondContBase>( vhk.key() ) ){
254 std::string tp("UNKNOWN");
255 if (m_clidSvc->getTypeNameOfID(ditr->clid(),tp).isFailure()) {
256 ATH_MSG_WARNING("unable to convert clid " << ditr->clid() << " to a classname."
257 << "This is a BAD sign, but will try to continue");
258 }
260 CondContainer::CondContFactory::Instance().Create( *m_rcuSvc, ditr->clid(), ditr->key() );
261 if (cb == 0) {
262 // try to force a load of libraries using ROOT
263 (void)TClass::GetClass (tp.c_str());
264 cb =
265 CondContainer::CondContFactory::Instance().Create( *m_rcuSvc, ditr->clid(), ditr->key() );
266 }
267 if (cb == 0) {
268 ATH_MSG_ERROR("failed to create CondCont<" << tp
269 << "> clid=" << ditr->clid()
270 << " : no factory found");
271 fail = true;
272 } else {
273 ATH_MSG_INFO("created CondCont<" << tp << "> with key '"
274 << ditr->key() << "'");
275 if (m_condStore->recordObject(cb, vhk.key(), true, false) == nullptr) {
276 ATH_MSG_ERROR("while creating a CondContBase for "
277 << vhk.fullKey());
278 fail = true;
279 } else {
280 m_vhk.emplace_back(std::move(vhk));
281 }
282 }
283 } else {
284 m_vhk.emplace_back(std::move(vhk));
285 }
286 }
287
288 if (fail && m_abort) {
289 ATH_MSG_FATAL("Unable to setup some of the requested CondCont<T>. "
290 << "Aborting");
291 return StatusCode::FAILURE;
292 }
293
294 // Let the conditions service know that we've finished creating
295 // conditions containers.
296 ServiceHandle<ICondSvcSetupDone> condSvcDone ("CondSvc", name());
297 ATH_CHECK( condSvcDone.retrieve() );
298 ATH_CHECK( condSvcDone->setupDone() );
299
300 return StatusCode::SUCCESS;
301
302}
303
304
305//-----------------------------------------------------------------------------
306
307StatusCode
308CondInputLoader::execute(const EventContext& ctx) const
309{
310 ATH_MSG_DEBUG ("Executing " << name() << "...");
311
312 EventIDBase now;
313 if (!ctx.valid()) {
314 ATH_MSG_WARNING("EventContext not valid! This should not happen!");
315 const xAOD::EventInfo* thisEventInfo;
316 if(evtStore()->retrieve(thisEventInfo)!=StatusCode::SUCCESS) {
317 ATH_MSG_ERROR("Unable to get Event Info");
318 return StatusCode::FAILURE;
319 }
320 now.set_run_number(thisEventInfo->runNumber());
321 now.set_event_number(thisEventInfo->eventNumber());
322 now.set_lumi_block(thisEventInfo->lumiBlock());
323 now.set_time_stamp(thisEventInfo->timeStamp());
324 now.set_time_stamp_ns_offset(thisEventInfo->timeStampNSOffset());
325 }
326 else {
327 now.set_run_number(ctx.eventID().run_number());
328 now.set_event_number(ctx.eventID().event_number());
329 now.set_lumi_block(ctx.eventID().lumi_block());
330 now.set_time_stamp(ctx.eventID().time_stamp());
331 now.set_time_stamp_ns_offset(ctx.eventID().time_stamp_ns_offset());
332 }
333
334 EventIDBase now_event = now;
335 now.set_event_number (EventIDBase::UNDEFEVT);
336
337 // For a MC event, the run number we need to use to look up the conditions
338 // may be different from that of the event itself. Override the run
339 // number with the conditions run number from the event context,
340 // if it is defined.
341 EventIDBase::number_type conditionsRun =
343 if (conditionsRun != EventIDBase::UNDEFNUM) {
344 now.set_run_number (conditionsRun);
345 }
346
347 StatusCode sc(StatusCode::SUCCESS);
348 std::string tag;
349 for (auto &vhk: m_vhk) {
350 ATH_MSG_DEBUG( "handling id: " << vhk.fullKey() << " key: " << vhk.key() );
351
352 CondContBase* ccb(0);
353 if (! m_condStore->retrieve(ccb, vhk.key()).isSuccess()) {
354 ATH_MSG_ERROR( "unable to get CondContBase* for " << vhk.fullKey()
355 << " from ConditionStore" );
356 sc = StatusCode::FAILURE;
357 continue;
358 }
359
360 if (ccb->valid(now)) {
361 ATH_MSG_DEBUG( " CondObj " << vhk.fullKey() << " is still valid at " << now_event );
362 continue;
363 }
364
365 const std::string& dbKey = m_keyFolderMap.at(vhk.key());
366 if (m_IOVSvc->createCondObj( ccb, vhk.fullKey(), now ).isFailure()) {
367 ATH_MSG_ERROR("unable to create Cond object for " << vhk.fullKey() << " dbKey: "
368 << dbKey);
369 sc = StatusCode::FAILURE;
370 continue;
371 }
372 }
373
374 if (m_dumpCondStore) {
375 ATH_MSG_DEBUG(m_condStore->dump());
376 }
377
378 if (m_dumpCondSvc) {
379 std::ostringstream ost;
380 m_condSvc->dump(ost);
381 ATH_MSG_DEBUG(ost.str());
382 }
383 return sc;
384}
385
386//-----------------------------------------------------------------------------
387
388// need to override the handling of the DataObjIDs that's done by
389// AthAlgorithm, so we don't inject the name of the Default Store
390void
391CondInputLoader::extraDeps_update_handler( Gaudi::Details::PropertyBase& /*ExtraDeps*/ )
392{
393 // do nothing
394}
395
396//-----------------------------------------------------------------------------
397
398RootType CondInputLoader::loadDict (const std::string& name)
399{
400 // First try to load the persistent class dictionary.
401 std::unique_ptr<ITPCnvBase> tpcnv = m_tpCnvSvc->t2p_cnv_unique (name);
402 if (tpcnv) {
403 RootType rtp = m_dictLoader->load_type (tpcnv->persistentTInfo());
404 if (rtp.Class()) {
405 return rtp;
406 }
407 }
408
409 // Otherwise try to load the dictionary for the class itself.
410 return m_dictLoader->load_type (name);
411}
412
413
415{
416 std::string name;
417 if (m_clidSvc->getTypeNameOfID (clid, name).isSuccess()) {
418 return loadDict (name);
419 }
420 return RootType();
421}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Provide an interface for finding inheritance information at run time.
Helpers for checking error return status codes and reporting errors.
uint32_t CLID
The Class ID type.
Interface to tell CondSvc to cache conditions containers.
Abstract interface to IOVDbSvc to access IOVRange and tag information.
Validity Range object.
Basic time unit for IOVSvc.
static Double_t a
static Double_t sc
void setProperty(columnar::PythonToolHandle &self, const std::string &key, nb::object value)
TTypeAdapter RootType
Definition RootType.h:211
Handle class for reading from StoreGate.
Run a MT piece of code with an alternate root error handler.
An algorithm that can be simultaneously executed in multiple threads.
EventIDBase::number_type conditionsRun() const
Base class for all conditions containers.
Definition CondCont.h:140
virtual bool valid(const EventIDBase &t) const =0
Test to see if a given IOV time is mapped in the container.
SG::DataObjectSharedPtr< DataObject > Create(Athena::IRCUSvc &rcusvc, const CLID &clid, const std::string &key) const
static CondContFactory & Instance()
virtual StatusCode initialize() override
std::vector< SG::VarHandleKey > m_vhk
CondInputLoader(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
ServiceHandle< IIOVSvc > m_IOVSvc
ServiceHandle< IDictLoaderSvc > m_dictLoader
Gaudi::Property< bool > m_abort
std::map< std::string, std::string > m_keyFolderMap
virtual StatusCode start() override
ServiceHandle< IClassIDSvc > m_clidSvc
ServiceHandle< IIOVDbSvc > m_IOVDbSvc
ServiceHandle< ICondSvc > m_condSvc
virtual StatusCode finalize() override
DataObjIDColl m_handlesToCreate
ServiceHandle< Athena::IRCUSvc > m_rcuSvc
void extraDeps_update_handler(Gaudi::Details::PropertyBase &)
Gaudi::Property< bool > m_dumpCondSvc
Gaudi::Property< DataObjIDColl > m_load
Containers.
virtual StatusCode execute(const EventContext &ctx) const override
Gaudi::Property< bool > m_dumpCondStore
ServiceHandle< ITPCnvSvc > m_tpCnvSvc
RootType loadDict(CLID clid)
ServiceHandle< StoreGateSvc > m_condStore
The non-template portion of the BaseInfo implementation.
static const BaseInfoBase * find(CLID clid)
Find the BaseInfoBase instance for clid.
Definition BaseInfo.cxx:570
const std::vector< CLID > & get_bases() const
Return the class IDs of all known bases of T (that have class IDs).
Definition BaseInfo.cxx:304
A property holding a SG store/key/clid from which a VarHandle is made.
CLID clid() const
Return the class ID for the referenced object.
const std::string & key() const
Return the StoreGate ID for the referenced object.
@ CONDITION_STORE
Definition StoreID.h:28
static const std::string & storeName(const StoreID::type &s)
Definition StoreID.cxx:77
std::string Name() const
Definition RootType.cxx:361
TBaseAdapter BaseAt(size_t nth) const
Definition RootType.cxx:778
TClass * Class() const
Definition RootType.h:183
size_t BaseSize() const
Definition RootType.cxx:754
uint32_t lumiBlock() const
The current event's luminosity block number.
uint32_t timeStamp() const
POSIX time in seconds from 1970. January 1st.
uint32_t runNumber() const
The current event's run number.
uint32_t timeStampNSOffset() const
Nanosecond time offset wrt. the time stamp.
uint64_t eventNumber() const
The current event's event number.
std::string base
Definition hcg.cxx:81
const ExtendedEventContext & getExtendedEventContext(const EventContext &ctx)
Retrieve an extended context from a context object.
CxxUtils::RefCountedPtr< T > DataObjectSharedPtr
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
EventInfo_v1 EventInfo
Definition of the latest event info version.
Filled by IIOVDbSvc::getKeyInfo.
Definition IIOVDbSvc.h:44
std::string basename(std::string name)
Definition utils.cxx:207