Forked from
atlas / athena
125355 commits behind the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CondInputLoader.cxx 11.75 KiB
///////////////////////// -*- C++ -*- /////////////////////////////
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
// CondInputLoader.cxx
// Implementation file for class CondInputLoader
///////////////////////////////////////////////////////////////////
#include "CondInputLoader.h"
// FrameWork includes
#include "GaudiKernel/Property.h"
#include "GaudiKernel/IClassIDSvc.h"
#include "StoreGate/ReadHandle.h"
#include "AthenaKernel/errorcheck.h"
#include "AthenaKernel/IOVTime.h"
#include "AthenaKernel/IOVRange.h"
#include "AthenaKernel/IIOVDbSvc.h"
#include "AthenaKernel/IIOVSvc.h"
#include "StoreGate/CondHandleKey.h"
#include "AthenaKernel/CondContMaker.h"
#include "xAODEventInfo/EventInfo.h"
#include "SGTools/BaseInfo.h"
#include "TClass.h"
///////////////////////////////////////////////////////////////////
// Public methods:
///////////////////////////////////////////////////////////////////
// Constructors
////////////////
CondInputLoader::CondInputLoader( const std::string& name,
ISvcLocator* pSvcLocator ) :
::AthAlgorithm( name, pSvcLocator ),
m_condStore("StoreGateSvc/ConditionStore", name),
m_condSvc("CondSvc",name),
m_IOVSvc("IOVSvc",name),
m_clidSvc("ClassIDSvc",name)
{
//
// Property declaration
//
auto props = getProperties();
for( Property* prop : props ) {
if (prop->name() == "ExtraOutputs" || prop->name() == "ExtraInputs") {
prop->declareUpdateHandler
(&CondInputLoader::extraDeps_update_handler, this);
}
}
declareProperty( "Load", m_load);
//->declareUpdateHandler(&CondInputLoader::loader, this);
}
// Destructor
///////////////
CondInputLoader::~CondInputLoader()
{}
//-----------------------------------------------------------------------------
// Athena Algorithm's Hooks
////////////////////////////
StatusCode
CondInputLoader::initialize()
{
ATH_MSG_INFO ("Initializing " << name() << "...");
ATH_CHECK( m_condSvc.retrieve() );
ATH_CHECK( m_condStore.retrieve() );
ATH_CHECK( m_clidSvc.retrieve() );
// Trigger read of IOV database
ServiceHandle<IIOVSvc> ivs("IOVSvc",name());
ATH_CHECK( ivs.retrieve() );
// Update the SG keys if different from Folder Names
ServiceHandle<IIOVDbSvc> idb("IOVDbSvc",name());
ATH_CHECK( idb.retrieve() );
std::vector<std::string> keys = idb->getKeyList();
std::string folderName, tg;
IOVRange range;
bool retrieved;
unsigned long long br;
float rt;
DataObjIDColl handles_to_load;
std::map<std::string,std::string> folderKeyMap;
for (auto key : keys) {
if (idb->getKeyInfo(key, folderName, tg, range, retrieved, br, rt)) {
folderKeyMap[folderName] = key;
m_keyFolderMap[key] = folderName;
} else {
ATH_MSG_WARNING("unable to retrieve keyInfo for " << key );
}
}
std::map<std::string,std::string>::const_iterator itr;
for (auto id : m_load) {
itr = folderKeyMap.find(id.key());
if (itr != folderKeyMap.end() && id.key() != itr->second) {
ATH_MSG_DEBUG(" mapping folder " << id.key() << " to SGkey "
<< itr->second);
id.updateKey( itr->second );
// } else {
// ATH_MSG_DEBUG(" not remapping folder " << id.key());
}
if (id.key() == "") {
ATH_MSG_INFO("ignoring blank key for " << id );
continue;
}
SG::VarHandleKey vhk(id.clid(),id.key(),Gaudi::DataHandle::Writer,
StoreID::storeName(StoreID::CONDITION_STORE));
handles_to_load.emplace(vhk.fullKey());
}
// for (auto key : keys) {
// if (idb->getKeyInfo(key, folderName, tg, range, retrieved, br, rt)) {
// ATH_MSG_VERBOSE("folder: " << folderName << " key: " << key);
// for (auto id : m_load) {
// if (id.key() == folderName) {
// ATH_MSG_DEBUG(" mapping folder " << folderName << " to SGkey " << key );
// id.updateKey( key );
// handles_to_load.insert(id);
// m_keyFolderMap[key] = folderName;
// break;
// }
// }
// } else {
// ATH_MSG_WARNING("unable to retrieve keyInfo for " << key );
// }
// }
m_load = handles_to_load;
m_handlesToCreate = handles_to_load;
// Add in all the base classes known to StoreGate, in case a handle
// is read via its base class. These will be added to the output deps,
// and also registered with the CondSvc, as the scheduler needs this
// info.
std::ostringstream ost;
ost << "Adding base classes:";
for (auto &e : handles_to_load) {
// ignore empty keys
if (e.key() == "") continue;
ost << "\n + " << e << " ->";
CLID clid = e.clid();
const SG::BaseInfoBase* bib = SG::BaseInfoBase::find( clid );
if ( ! bib ) {
ost << " no bases";
} else {
for (CLID clid2 : bib->get_bases()) {
if (clid2 != clid) {
std::string base("UNKNOWN");
m_clidSvc->getTypeNameOfID(clid2,base).ignore();
ost << " " << base << " (" << clid2 << ")";
SG::VarHandleKey vhk(clid2,e.key(),Gaudi::DataHandle::Writer,
StoreID::storeName(StoreID::CONDITION_STORE));
m_load.emplace(vhk.fullKey());
}
}
}
}
ATH_MSG_INFO(ost.str());
// Update the properties, set the ExtraOutputs for Alg deps
const Property &p = getProperty("Load");
ATH_MSG_DEBUG("setting prop ExtraOutputs to " << p.toString());
if (!setProperty("ExtraOutputs", p).isSuccess()) {
ATH_MSG_ERROR("failed setting property ExtraOutputs");
return StatusCode::FAILURE;
}
StatusCode sc(StatusCode::SUCCESS);
std::ostringstream str;
str << "Will create WriteCondHandle dependencies for the following DataObjects:";
for (auto &e : m_load) {
str << "\n + " << e;
if (e.key() == "") {
sc = StatusCode::FAILURE;
str << " ERROR: empty key is not allowed!";
} else {
SG::VarHandleKey vhk(e.clid(),e.key(),Gaudi::DataHandle::Writer,
StoreID::storeName(StoreID::CONDITION_STORE));
if (m_condSvc->regHandle(this, vhk).isFailure()) {
ATH_MSG_ERROR("Unable to register WriteCondHandle " << vhk.fullKey());
sc = StatusCode::FAILURE;
}
ATH_MSG_DEBUG("Ignoring proxy: " << vhk.key());
m_IOVSvc->ignoreProxy(vhk.fullKey().clid(), vhk.key());
}
}
ATH_MSG_INFO(str.str());
return sc;
}
//-----------------------------------------------------------------------------
StatusCode
CondInputLoader::finalize()
{
ATH_MSG_INFO ("Finalizing " << name() << "...");
return StatusCode::SUCCESS;
}
//-----------------------------------------------------------------------------
StatusCode
CondInputLoader::start()
{
//
// now create the CondCont<T>. This has to be done after initialize(),
// as we need to make sure that all Condition Objects have been instantiated
// so as to fill the static condition obj registry via REGISTER_CC
//
// we use a VHK to store the info instead of a DataObjIDColl, as this saves
// us the trouble of stripping out the storename from the key later.
//
DataObjIDColl::iterator ditr;
bool fail(false);
for (ditr = m_handlesToCreate.begin(); ditr != m_handlesToCreate.end(); ++ditr) {
SG::VarHandleKey vhk(ditr->clid(),ditr->key(),Gaudi::DataHandle::Writer);
if ( ! m_condStore->contains<CondContBase>( vhk.key() ) ){
std::string tp("UNKNOWN");
if (m_clidSvc->getTypeNameOfID(ditr->clid(),tp).isFailure()) {
ATH_MSG_WARNING("unable to convert clid " << ditr->clid() << " to a classname."
<< "This is a BAD sign, but will try to continue");
}
CondContBase* cb =
CondContainer::CondContFactory::Instance().Create( ditr->clid(), ditr->key() );
if (cb == 0) {
// try to force a load of libraries using ROOT
(void)TClass::GetClass (tp.c_str());
cb =
CondContainer::CondContFactory::Instance().Create( ditr->clid(), ditr->key() );
}
if (cb == 0) {
ATH_MSG_ERROR("failed to create CondCont<" << tp
<< "> clid=" << ditr->clid()
<< " : no factory found");
fail = true;
} else {
ATH_MSG_INFO("created CondCont<" << tp << "> with key '"
<< ditr->key() << "'");
if (m_condStore->record(cb, vhk.key()).isFailure()) {
ATH_MSG_ERROR("while creating a CondContBase for "
<< vhk.fullKey());
fail = true;
} else {
m_vhk.push_back(vhk);
}
}
} else {
m_vhk.push_back(vhk);
}
}
if (fail && m_abort) {
ATH_MSG_FATAL("Unable to setup some of the requested CondCont<T>. "
<< "Aborting");
return StatusCode::FAILURE;
}
return StatusCode::SUCCESS;
}
//-----------------------------------------------------------------------------
StatusCode
CondInputLoader::execute()
{
ATH_MSG_DEBUG ("Executing " << name() << "...");
EventIDBase now;
if (!getContext().valid()) {
ATH_MSG_WARNING("EventContext not valid! This should not happen!");
const xAOD::EventInfo* thisEventInfo;
if(evtStore()->retrieve(thisEventInfo)!=StatusCode::SUCCESS) {
ATH_MSG_ERROR("Unable to get Event Info");
return StatusCode::FAILURE;
}
now.set_run_number(thisEventInfo->runNumber());
now.set_event_number(thisEventInfo->eventNumber());
now.set_lumi_block(thisEventInfo->lumiBlock());
now.set_time_stamp(thisEventInfo->timeStamp());
now.set_time_stamp_ns_offset(thisEventInfo->timeStampNSOffset());
}
else {
now.set_run_number(getContext().eventID().run_number());
now.set_event_number(getContext().eventID().event_number());
now.set_lumi_block(getContext().eventID().lumi_block());
now.set_time_stamp(getContext().eventID().time_stamp());
now.set_time_stamp_ns_offset(getContext().eventID().time_stamp_ns_offset());
}
EventIDBase now_event = now;
now.set_event_number (EventIDBase::UNDEFEVT);
// For a MC event, the run number we need to use to look up the conditions
// may be different from that of the event itself. Override the run
// number with the conditions run number from the event context,
// if it is defined.
EventIDBase::number_type conditionsRun =
getContext().template getExtension<Atlas::ExtendedEventContext>()->conditionsRun();
if (conditionsRun != EventIDBase::UNDEFNUM) {
now.set_run_number (conditionsRun);
}
IOVTime t(now.run_number(), now.lumi_block(), now.time_stamp());
StatusCode sc(StatusCode::SUCCESS);
std::string tag;
for (auto &vhk: m_vhk) {
ATH_MSG_DEBUG( "handling id: " << vhk.fullKey() << " key: " << vhk.key() );
CondContBase* ccb(0);
if (! m_condStore->retrieve(ccb, vhk.key()).isSuccess()) {
ATH_MSG_ERROR( "unable to get CondContBase* for " << vhk.fullKey()
<< " from ConditionStore" );
sc = StatusCode::FAILURE;
continue;
}
if (ccb->valid(now)) {
ATH_MSG_INFO( " CondObj " << vhk.fullKey() << " is still valid at " << now_event );
evtStore()->addedNewTransObject(vhk.fullKey().clid(), vhk.key());
continue;
}
std::string dbKey = m_keyFolderMap[vhk.key()];
if (m_IOVSvc->createCondObj( ccb, vhk.fullKey(), now ).isFailure()) {
ATH_MSG_ERROR("unable to create Cond object for " << vhk.fullKey() << " dbKey: "
<< dbKey);
sc = StatusCode::FAILURE;
continue;
} else {
evtStore()->addedNewTransObject(vhk.fullKey().clid(), vhk.key());
}
}
if (m_dumpEvt) {
ATH_MSG_DEBUG(m_condStore->dump());
}
return sc;
}
//-----------------------------------------------------------------------------
// need to override the handling of the DataObjIDs that's done by
// AthAlgorithm, so we don't inject the name of the Default Store
void
CondInputLoader::extraDeps_update_handler( Property& /*ExtraDeps*/ )
{
// do nothing
}