diff --git a/Control/AthAnalysisBaseComps/AthAnalysisBaseComps/AthAnalysisAlgorithm.h b/Control/AthAnalysisBaseComps/AthAnalysisBaseComps/AthAnalysisAlgorithm.h index f9724833d35e87d8440c311d87c10c78c7032c1d..f654f8256959527d68d26e1d89762427937b785b 100644 --- a/Control/AthAnalysisBaseComps/AthAnalysisBaseComps/AthAnalysisAlgorithm.h +++ b/Control/AthAnalysisBaseComps/AthAnalysisBaseComps/AthAnalysisAlgorithm.h @@ -35,6 +35,9 @@ class AthAnalysisAlgorithm : public ::AthHistogramAlgorithm, virtual public IIncidentListener { public: + /// Constructor taking just a name + AthAnalysisAlgorithm(const std::string& name); + /// Constructor with parameters: AthAnalysisAlgorithm(const std::string& name, ISvcLocator* pSvcLocator, @@ -56,7 +59,11 @@ class AthAnalysisAlgorithm : public ::AthHistogramAlgorithm, virtual public IInc /// Function initialising the tool in the correct way in Athena virtual StatusCode sysInitialize() override; /// override to do firstEvent method +#ifndef GAUDI_SYSEXECUTE_WITHCONTEXT virtual StatusCode sysExecute() override; +#else + virtual StatusCode sysExecute(const EventContext&) override; +#endif /// Helper function to access IOVMetaDataContainer information helped in the MetaDataStore template<typename T> StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out) { @@ -80,8 +87,8 @@ class AthAnalysisAlgorithm : public ::AthHistogramAlgorithm, virtual public IInc } protected: - /// @name Callback functions helping in metadata reading - /// @{ + void updateEvtStore(Property& prop); + /// Function receiving incidents from IncidentSvc/TEvent /// Experts can override but they should ensure they add @@ -104,6 +111,8 @@ class AthAnalysisAlgorithm : public ::AthHistogramAlgorithm, virtual public IInc /// user can read event information with evtStore() virtual StatusCode firstExecute(); + /// Function returning the TFile pointer of the currently open file of the + /// given EventSelector (in athena jobs this defaults to "EventSelector") virtual TFile* currentFile(const char* evtSelName="EventSelector") final; private: diff --git a/Control/AthAnalysisBaseComps/AthAnalysisBaseComps/AthAnalysisHelper.h b/Control/AthAnalysisBaseComps/AthAnalysisBaseComps/AthAnalysisHelper.h index 3c77ac977df1b4b741aacb1a5d59a84f4d5af668..0e728e74e8f5fed9a356f22f8fba6165bcb71183 100644 --- a/Control/AthAnalysisBaseComps/AthAnalysisBaseComps/AthAnalysisHelper.h +++ b/Control/AthAnalysisBaseComps/AthAnalysisBaseComps/AthAnalysisHelper.h @@ -241,12 +241,18 @@ public: //just try to retrieve the requested key from the attributelist - we will let it throw the coral::AttributeListException (inherits from std::exception) if it fails //if the typeName is std::string, we will try to use the gaudi parsers to parse it //otherwise we try to do a straight assignment - const coral::Attribute& attr = cont->payloadContainer()->at(0)->attributeList(cont->payloadContainer()->at(0)->chanNum(0))[key]; - if(attr.specification().typeName()=="string") { - if(Gaudi::Parsers::parse(out,attr.data<std::string>()).isFailure()) return StatusCode::FAILURE; - } else { //do a straight conversion, and just hope its ok (FIXME: should probably do a check of typeid(T) vs typeName) - out = attr.data<T>(); - } + try { + const coral::Attribute& attr = cont->payloadContainer()->at(0)->attributeList(cont->payloadContainer()->at(0)->chanNum(0))[key]; + + if(attr.specification().typeName()=="string") { + if(Gaudi::Parsers::parse(out,attr.data<std::string>()).isFailure()) return StatusCode::FAILURE; + } else { //do a straight conversion, and just hope its ok (FIXME: should probably do a check of typeid(T) vs typeName) + out = attr.data<T>(); + } + } catch(...) { + //anything that goes wrong is taken to be a failure + return StatusCode::FAILURE; + } return StatusCode::SUCCESS; } @@ -275,11 +281,16 @@ public: //just try to retrieve the requested key from the attributelist - we will let it throw the coral::AttributeListException (inherits from std::exception) if it fails //if the typeName is std::string, we will try to use the gaudi parsers to parse it //otherwise we try to do a straight assignment - const coral::Attribute& attr = attrlist->second[key]; - if(attr.specification().typeName()=="string") { - if(Gaudi::Parsers::parse(out,attr.data<std::string>()).isFailure()) return StatusCode::FAILURE; - } else { //do a straight conversion, and just hope its ok (FIXME: should probably do a check of typeid(T) vs typeName) - out = attr.data<T>(); + try { + const coral::Attribute& attr = attrlist->second[key]; + if(attr.specification().typeName()=="string") { + if(Gaudi::Parsers::parse(out,attr.data<std::string>()).isFailure()) return StatusCode::FAILURE; + } else { //do a straight conversion, and just hope its ok (FIXME: should probably do a check of typeid(T) vs typeName) + out = attr.data<T>(); + } + } + catch(...) { + return StatusCode::FAILURE; } return StatusCode::SUCCESS; diff --git a/Control/AthAnalysisBaseComps/src/AthAnalysisAlgorithm.cxx b/Control/AthAnalysisBaseComps/src/AthAnalysisAlgorithm.cxx index 1ff044d88c885749cc2d642a65f034a28e12b92b..4451def6da8046c53e13e9a3a4e22bffcf5c728f 100644 --- a/Control/AthAnalysisBaseComps/src/AthAnalysisAlgorithm.cxx +++ b/Control/AthAnalysisBaseComps/src/AthAnalysisAlgorithm.cxx @@ -15,6 +15,14 @@ #include "TROOT.h" +AthAnalysisAlgorithm::AthAnalysisAlgorithm( const std::string& name ) : AthAnalysisAlgorithm( name, Gaudi::svcLocator() ) { + //we assume this constructor is used outside of the framework + //therefore we must increment the ref count so that + //any SmartIF doesn't "release" the alg and therefore delete it + addRef(); + +} + AthAnalysisAlgorithm::AthAnalysisAlgorithm( const std::string& name, ISvcLocator* pSvcLocator, const std::string& ) : @@ -23,10 +31,22 @@ AthAnalysisAlgorithm::AthAnalysisAlgorithm( const std::string& name, m_outputMetaStore( "StoreGateSvc/MetaDataStore", name ) { + //declare an update handler for the EvtStore property, to reset the ServiceHandle + for(auto prop : getProperties()) { + if(prop->name() != "EvtStore") continue; + prop->declareUpdateHandler(&AthAnalysisAlgorithm::updateEvtStore, this ); + break; + } + } AthAnalysisAlgorithm::~AthAnalysisAlgorithm() { } +void AthAnalysisAlgorithm::updateEvtStore(Property& prop) { + evtStore().release().ignore(); + evtStore().setTypeAndName(prop.toString()); +} + ServiceHandle<StoreGateSvc>& AthAnalysisAlgorithm::inputMetaStore() const { return m_inputMetaStore; @@ -59,6 +79,7 @@ StatusCode AthAnalysisAlgorithm::sysInitialize() { return StatusCode::SUCCESS; } +#ifndef GAUDI_SYSEXECUTE_WITHCONTEXT StatusCode AthAnalysisAlgorithm::sysExecute() { if(!m_doneFirstEvent) { m_doneFirstEvent=true; @@ -69,6 +90,18 @@ StatusCode AthAnalysisAlgorithm::sysExecute() { } return AthHistogramAlgorithm::sysExecute(); } +#else +StatusCode AthAnalysisAlgorithm::sysExecute(const EventContext& ctx) { + if(!m_doneFirstEvent) { + m_doneFirstEvent=true; + if( firstExecute().isFailure() ) { + ATH_MSG_FATAL("Failure in firstEvent method"); + return StatusCode::FAILURE; + } + } + return AthHistogramAlgorithm::sysExecute(ctx); +} +#endif void AthAnalysisAlgorithm::handle( const Incident& inc ) { @@ -138,14 +171,27 @@ TFile* AthAnalysisAlgorithm::currentFile(const char* evtSelName) { if(m_currentFile) return m_currentFile; //get the EventSelector so we can get it's list of input files + //dont get it with a ServiceHandle, because that invokes initialize, can get into init loop + + IProperty* evtSelector = 0; + if(service(evtSelName,evtSelector,false).isFailure()) { + ATH_MSG_ERROR("currentFile(): Couldn't find the service: " << evtSelName);return 0; + } + //SmartIF<IProperty> evtSelector(mysel); + /* ServiceHandle<IProperty> evtSelector(evtSelName,name()); if(evtSelector.retrieve().isFailure()) { - ATH_MSG_ERROR("Couldn't find the service: " << evtSelName);return 0; + ATH_MSG_ERROR("currentFile(): Couldn't find the service: " << evtSelName);return 0; + }*/ + + StringArrayProperty inputCollectionsName; + try { + //get the list of input files - use this to determine which open file is the current input file + inputCollectionsName = dynamic_cast<const StringArrayProperty&>(evtSelector->getProperty("InputCollections")); + } catch(...) { + ATH_MSG_ERROR("currentFile(): Couldn't load InputCollections property of " << evtSelName); return 0; } - - //get the list of input files - use this to determine which open file is the current input file - const StringArrayProperty& inputCollectionsName = dynamic_cast<const StringArrayProperty&>(evtSelector->getProperty("InputCollections")); ATH_MSG_VERBOSE("nOpenFile=" << gROOT->GetListOfFiles()->GetSize() << ". nFilesInInputCollection=" << inputCollectionsName.value().size()); if(msgLvl(MSG::VERBOSE)) { for(int i=0;i<gROOT->GetListOfFiles()->GetSize();i++) { @@ -212,7 +258,7 @@ TFile* AthAnalysisAlgorithm::currentFile(const char* evtSelName) { } } } - ATH_MSG_ERROR("Could not find the current file!"); + ATH_MSG_ERROR("currentFile(): Could not find the current file!"); return 0; //something went wrong :-( }