Commit e68966ad authored by Will Buttinger's avatar Will Buttinger Committed by Graeme Stewart
Browse files

'addPropertyToCatalogue method' (AthAnalysisBaseComps-00-00-18)

	* AthAnalysisHelper: methods for creating and setting properties on algorithms
	* Tagging as AthAnalysisBaseComps-00-00-16
	* made ToolSvc the default parent for created tools
	* Tagging as AthAnalysisBaseComps-00-00-17
	* One more helper method for adding properties to catalogue
	* Tagging as AthAnalysisBaseComps-00-00-18

2016-05-08 Will Buttinger <Will@cern.ch>
      * AthAnalysisHelper: printAuxElement method for printing content of an aux element
      * Tagging as AthAnalysisBaseComps-00-00-15

2016-05-03 Will Buttinger <will@cern.ch>
      * AthAnalysisHelper: Use const references instead of r-value references.
                           Added specialization of setProperty for toolHandles + arrays
      * Tagging as AthAnalysisBaseComps-00-00-14

2016-04-07 Will Buttinger <will@cern.ch>
        * AthAnalysisHelper: createTool method for simplifying call to gaudi factory,
                             corresponding setProperty method for bare tools
                             setProperty method for services too
...
(Long ChangeLog diff - truncated)
parent 1120304d
......@@ -6,7 +6,7 @@
// AthAnalysisAlgorithm.h
// Header file for class AthAnalysisAlgorithm
// Inherits from AthAlgorithm but adds beginInputFile incident listener
// Inherits from AthHistogramAlgorithm but adds beginInputFile incident listener
// and includes a retrieveMetadata method for easy metadata access
// Author: W.Buttinger<will@cern.ch>
///////////////////////////////////////////////////////////////////
......@@ -18,19 +18,21 @@
*
* Same as AthAlgorithm but adds a beginInputFile method and handle method for incident listening
* Also adds a retrieveMetadata method for easy metadata retrieval from InputMetaDataStore (method not IOV Safe though!)
*
* Update Feb 2016: Made inherit from AthHistogramAlgorithm, since that has nice histogram booking features
* @author Will Buttinger
* @date 2015
*/
#include "AthenaBaseComps/AthAlgorithm.h"
#include "AthenaBaseComps/AthHistogramAlgorithm.h"
#include "GaudiKernel/ToolHandle.h" //included under assumption you'll want to use some tools!
#include "GaudiKernel/IIncidentSvc.h"
#include "AthAnalysisBaseComps/AthAnalysisHelper.h"
#include "TFile.h"
class AthAnalysisAlgorithm : public ::AthAlgorithm, virtual public IIncidentListener {
class AthAnalysisAlgorithm : public ::AthHistogramAlgorithm, virtual public IIncidentListener {
public:
/// Constructor with parameters:
......@@ -55,7 +57,25 @@ class AthAnalysisAlgorithm : public ::AthAlgorithm, virtual public IIncidentList
virtual StatusCode sysInitialize();
/// 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) { return AthAnalysisHelper::retrieveMetadata(folder,key,out,inputMetaStore()); }
template<typename T> StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out) {
try {
return AthAnalysisHelper::retrieveMetadata(folder,key,out,inputMetaStore());
} catch(std::exception& e) {
ATH_MSG_WARNING(e.what());
return StatusCode::FAILURE;
}
}
/// Helper function to access IOVMetaDataContainer information held in InputMetaDataStore, but will check IOVTime. Also can give a channel (leave as -1 to take first available)
/// IOVTime(runNumber, eventNumber) is a valid constructor for example
template<typename T> StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out, IOVTime time, int channel=-1) {
try {
return AthAnalysisHelper::retrieveMetadata(folder,key,out,inputMetaStore(),time,channel);
} catch(std::exception& e) {
ATH_MSG_WARNING(e.what());
return StatusCode::FAILURE;
}
}
protected:
/// @name Callback functions helping in metadata reading
......@@ -67,6 +87,7 @@ class AthAnalysisAlgorithm : public ::AthAlgorithm, virtual public IIncidentList
/// Function called when a new input file is opened
virtual StatusCode beginInputFile();
virtual TFile* currentFile(const char* evtSelName="EventSelector") final;
private:
/// Object accessing the input metadata store
......@@ -74,6 +95,7 @@ class AthAnalysisAlgorithm : public ::AthAlgorithm, virtual public IIncidentList
/// Object accessing the output metadata store
mutable ServiceHandle< StoreGateSvc > m_outputMetaStore;
TFile* m_currentFile = 0; //used to cache the current file
};
......
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef ATHANALYSISBASECOMPSDICT_H
#define ATHANALYSISBASECOMPSDICT_H
#include "AthAnalysisBaseComps/AthAnalysisHelper.h"
#endif
\ No newline at end of file
......@@ -16,14 +16,182 @@
#include "StoreGate/StoreGateSvc.h"
#include "GaudiKernel/ServiceHandle.h"
#include "GaudiKernel/IJobOptionsSvc.h"
#include "GaudiKernel/IToolSvc.h"
#include "IOVDbDataModel/IOVMetaDataContainer.h"
#include "GaudiKernel/AlgTool.h"
#include "GaudiKernel/Algorithm.h"
#include "AthContainers/AuxElement.h"
class AthAnalysisHelper { //thought about being a namespace but went for static methods instead, in case I want private data members in future
public:
AthAnalysisHelper(); //need a constructor to link the dictionary library with the implementation library
///helper method for adding a property to the JobOptionsSvc
///to list all the properties in the catalogue, do: AthAnalysisHelper::dumpJobOptionProperties()
template<typename W> static StatusCode addPropertyToCatalogue( const std::string& name , const std::string& property, const W& value) {
ServiceHandle<IJobOptionsSvc> joSvc("JobOptionsSvc","AthAnalysisHelper");
if(joSvc.retrieve().isFailure()) return StatusCode::FAILURE;
StatusCode result = joSvc->addPropertyToCatalogue( name , StringProperty( property , Gaudi::Utils::toString ( value ) ) );
if(joSvc.release().isFailure()) return StatusCode::FAILURE;
return result;
}
///helper method for setting a property on a tool before retrieving it
///uses the toolhandle to work out what to register the joboptionsvc
///Usage examples:
/// ToolHandle<IMyTool> tool("MyTool/toolName");
/// CHECK( AthAnalysisHelper::setProperty( tool, "IntegerProperty", 5) );
/// CHECK( AthAnalysisHelper::setProperty( tool, "StringProperty", "hello") );
/// CHECK( AthAnalysisHelper::setProperty( tool, "StringArrayProperty", std::vector<std::string>({"a","b","c"}) ) );
/// CHECK( AthAnalysisHelper::setProperty( tool, "PublicToolHandleProperty", anotherToolHandle) );
/// CHECK( AthAnalysisHelper::setProperty( tool, "PrivateToolHandleName.SubToolIntegerProperty", 4) );
///The last example assumes the 'MyTool' class has declared a ToolHandle("SubTool/PrivateToolHandleName",this)
///and 'SubTool' class has an integer property called 'SubToolIntegerProperty' declared
template<typename T, typename W> static StatusCode setProperty(const ToolHandle<T>& toolHandle, const std::string& property, const W& value) {
if(toolHandle.isSet()) {
std::cout << "ERROR: Cannot setProperty on a tool that is already initialized" << std::endl;
return StatusCode::FAILURE;
}
std::string fullName = toolHandle.parentName() + "." + toolHandle.name();
std::string thePropertyName(property);
//if the property contains any "." then strip the last bit as the property name
std::string::size_type dotLocation = thePropertyName.find_last_of('.');
if(dotLocation != std::string::npos) {
fullName += "." + thePropertyName.substr(0,dotLocation);
thePropertyName = thePropertyName.substr(dotLocation+1,thePropertyName.length()-dotLocation);
}
//check if the tool already exists, if so then we are too late!!
ServiceHandle<IToolSvc> toolSvc("ToolSvc","AthAnalysisHelper");
if(toolSvc.retrieve().isFailure()) return StatusCode::FAILURE;
auto existingTools = toolSvc->getInstances();
for(auto& toolName : existingTools) {
if(fullName==toolName) {
std::cout << "ERROR: Cannot setProperty on a tool that is already initialized" << std::endl;
return StatusCode::FAILURE;
}
}
if(toolSvc.release().isFailure()) return StatusCode::FAILURE;
//tool not existing, ok so add property to catalogue
ServiceHandle<IJobOptionsSvc> joSvc("JobOptionsSvc","AthAnalysisHelper");
if(joSvc.retrieve().isFailure()) return StatusCode::FAILURE;
StatusCode result = joSvc->addPropertyToCatalogue(fullName , StringProperty( thePropertyName, Gaudi::Utils::toString ( value ) ) );
if(joSvc.release().isFailure()) return StatusCode::FAILURE;
return result;
}
///Partial template specialization for ToolHandles and ToolHandleArrays ... strips parent name from tool name, for setting private handles on
template<typename T, typename W> static StatusCode setProperty(const ToolHandle<T>& toolHandle, const std::string& property, const ToolHandle<W>& value) {
std::string subToolName(value.name());
size_t start_pos = subToolName.find(toolHandle.name()+".");
if(start_pos!=std::string::npos) { subToolName.replace( start_pos, toolHandle.name().length()+1, "" ); }
std::string typeAndName = value.type(); if(!subToolName.empty()) typeAndName += "/"+subToolName;
return setProperty( toolHandle, property, typeAndName );
}
template<typename T, typename W> static StatusCode setProperty(const ToolHandle<T>& toolHandle, const std::string& property, const ToolHandleArray<W>& value) {
return setProperty( toolHandle, property, value.typesAndNames() );
}
///setProperty on any tool, even when initialized
template<typename W> static StatusCode setProperty(IAlgTool* tool, const std::string& property, const W& value) {
AlgTool* algtool = dynamic_cast<AlgTool*>(tool);
if(!algtool) {
std::cout << "ERROR: Tool is not an algtool. Cannot AthAnalysisHelper::setProperty on it" << std::endl;
return StatusCode::FAILURE;
}
return algtool->setProperty(property, value);
}
///setProperty on an alg, even when initialized
template<typename W> static StatusCode setProperty(IAlgorithm* alg, const std::string& property, const W& value) {
Algorithm* theAlg = dynamic_cast<Algorithm*>(alg);
if(!theAlg) {
std::cout << "ERROR: alg is not an Algorithm. Cannot AthAnalysisHelper::setProperty on it" << std::endl;
return StatusCode::FAILURE;
}
return theAlg->setProperty(property, value);
}
///setProperty for services ... will allow setProperty on already-existing services
template<typename T, typename W> static StatusCode setProperty(const ServiceHandle<T>& serviceHandle, const std::string& property, const W& value) {
if(serviceHandle.isSet()) {
return dynamic_cast<Service&>(*serviceHandle).setProperty(property,Gaudi::Utils::toString ( value ));
}
std::string fullName = serviceHandle.name();
std::string thePropertyName(property);
//if the property contains any "." then strip the last bit as the property name
std::string::size_type dotLocation = thePropertyName.find_last_of('.');
if(dotLocation != std::string::npos) {
fullName += "." + thePropertyName.substr(0,dotLocation);
thePropertyName = thePropertyName.substr(dotLocation+1,thePropertyName.length()-dotLocation);
}
//check if the service already exists
if(Gaudi::svcLocator()->existsService(serviceHandle.name())) {
//set property on the service directly
return dynamic_cast<Service&>(*serviceHandle).setProperty(property,Gaudi::Utils::toString ( value ));
}
//service not existing, ok so add property to catalogue
ServiceHandle<IJobOptionsSvc> joSvc("JobOptionsSvc","AthAnalysisHelper");
if(joSvc.retrieve().isFailure()) return StatusCode::FAILURE;
StatusCode result = joSvc->addPropertyToCatalogue(fullName , StringProperty( thePropertyName, Gaudi::Utils::toString ( value ) ) );
if(joSvc.release().isFailure()) return StatusCode::FAILURE;
return result;
}
///Create a tool using the gaudi factory methods. This creates tools that wont be known to the ToolSvc
///User is responsible for deleting the tool
///Parent is optional, allows your created tool to inherit OutputLevel properties from the parent
///If not parent specified, the ToolSvc will be used as the parent
///Please Note: The preferred method of creating tools is with a ToolHandle
///Usage:
/// IMyTool* tool = AthAnalysisHelper::createTool<IMyTool>("ToolType/ToolName");
/// CHECK( AthAnalysisHelper::setProperty( tool, "Property", value ) );
/// CHECK( tool->initialize() );
///Preferred:
/// ToolHandle<IMyTool> tool("ToolType/ToolName");
/// CHECK( AthAnalysisHelper::setProperty( tool, "Property", value ) );
/// CHECK( tool.retrieve() );
template<typename W> static W* createTool(const std::string& typeAndName, INamedInterface* parent = 0) {
std::string type = typeAndName; std::string name = typeAndName;
if(type.find("/")!=std::string::npos) { type = type.substr(0,type.find("/")); name = name.substr(name.find("/")+1,name.length()); }
if(parent==0) {
//use ToolSvc as parent
parent = Gaudi::svcLocator()->service( "ToolSvc" );
}
IAlgTool* m_algtool = AlgTool::Factory::create(type,type,name,parent);
W* out = dynamic_cast<W*>(m_algtool);
if(!out && m_algtool) {
std::cout << "ERROR: Tool of type " << type << " does not implement the interface " << System::typeinfoName(typeid(W)) << std::endl;
delete m_algtool;
return 0;
}
return out;
}
static IAlgTool* createTool(const std::string& typeAndName, INamedInterface* parent = 0) {
return createTool<IAlgTool>(typeAndName,parent);
}
//equivalent method for creating an algorithm ... always returns an IAlgorithm though, so not templated
static IAlgorithm* createAlgorithm(const std::string& typeAndName) {
std::string type = typeAndName; std::string name = typeAndName;
if(type.find("/")!=std::string::npos) { type = type.substr(0,type.find("/")); name = name.substr(name.find("/")+1,name.length()); }
return Algorithm::Factory::create(type,name,Gaudi::svcLocator());
}
///retrieve metadata from the input metadata storegate. Use checkMetaSG.py to see the 'folder' and 'key' values available
template<typename T> static StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out) {
///always takes the first CondAttrListCollection (aka IOV) and the first channel number present in that IOV
template<typename T> static StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out) throw(std::exception) {
ServiceHandle<StoreGateSvc> inputMetaStore("StoreGateSvc/InputMetaDataStore", "AthAnalysisHelper");
if(inputMetaStore.retrieve().isFailure()) return StatusCode::FAILURE; //must remember to release
StatusCode result = retrieveMetadata(folder,key,out,inputMetaStore);
......@@ -34,14 +202,14 @@ public:
///implemenation where you pass it a particular store instead
template<typename T> static StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out, ServiceHandle<StoreGateSvc> inputMetaStore) {
template<typename T> static StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out, ServiceHandle<StoreGateSvc>& inputMetaStore) throw(std::exception) {
const IOVMetaDataContainer* cont = 0;
if( inputMetaStore->retrieve(cont,folder).isFailure()) return StatusCode::FAILURE;
//payload is a collection of condattrlistcollections
//only look a the first one, assuming it exists, and within that only look at the first channel;
if(cont->payloadContainer()->size()>0 && cont->payloadContainer()->at(0)->size()>0) {
//just try to retrieve the requested key from the attributelist - we will let it throw the AttributeListException if it fails
//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];
......@@ -56,12 +224,65 @@ public:
return StatusCode::FAILURE;
}
///retrieve metadata, for a specified IOVTime and a specific channel, unless the channel is -1, in which case we take the first available channel
///channels have to be unsigned int, so can use -1 to signal 'take whatever first channel is (it isn't always 0)'
template<typename T> static StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out, ServiceHandle<StoreGateSvc>& inputMetaStore, const IOVTime& time, int channel=-1) throw(std::exception) {
const IOVMetaDataContainer* cont = 0;
if( inputMetaStore->retrieve(cont,folder).isFailure()) return StatusCode::FAILURE;
//payload is a collection of condattrlistcollections
//have to find first one that the time lies in
auto cond = cont->payloadContainer()->find(time);
if(cond == cont->payloadContainer()->end()) { return StatusCode::FAILURE; }
//get the first channel number, if required
if(channel<0) channel = (*cond)->chanNum(0);
//get the channel pair.. checks if it exists...
auto attrlist = (*cond)->chanAttrListPair(channel);
if(attrlist == (*cond)->end()) { return StatusCode::FAILURE; }
//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>();
}
return StatusCode::SUCCESS;
}
template<typename T> static StatusCode retrieveMetadata(const std::string& folder, const std::string& key, T& out, IOVTime time, int channel=-1) throw(std::exception) {
ServiceHandle<StoreGateSvc> inputMetaStore("StoreGateSvc/InputMetaDataStore", "AthAnalysisHelper");
if(inputMetaStore.retrieve().isFailure()) return StatusCode::FAILURE; //must remember to release
StatusCode result = retrieveMetadata(folder,key,out,inputMetaStore,time,channel);
if(inputMetaStore.release().isFailure()) return StatusCode::FAILURE;
return result;
}
///Dump the properties from joboptionsvc of clients with names beginning with given string. If string is blank, will print all clients
///Example usage:
///athena -i myJobOptions.py
///athena> theApp.setup()
///athena> import ROOT
///athena> ROOT.AthAnalysisHelper.dumpJobOptionProperties()
///This will display all the joboption properties declared at the start of your job
static void dumpJobOptionProperties(const std::string& client="");
///Print the aux variables of an xAOD object (aux element)
static void printAuxElement(const SG::AuxElement& ae);
}; //AthAnalysisHelper class
#endif
\ No newline at end of file
#endif
<lcgdict>
<class name="AthAnalysisHelper" />
</lcgdict>
......@@ -9,14 +9,26 @@ atlas_subdir( AthAnalysisBaseComps )
atlas_depends_on_subdirs( PUBLIC
Control/AthenaBaseComps
Control/StoreGate
Control/AthContainers
Database/IOVDbDataModel
GaudiKernel )
# External dependencies:
find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
# Component(s) in the package:
atlas_add_library( AthAnalysisBaseComps
src/*.cxx
PUBLIC_HEADERS AthAnalysisBaseComps
LINK_LIBRARIES AthenaBaseComps IOVDbDataModel GaudiKernel StoreGateLib SGtests )
PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
LINK_LIBRARIES AthenaBaseComps IOVDbDataModel GaudiKernel StoreGateLib SGtests AthContainers
PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} )
atlas_add_dictionary( AthAnalysisBaseCompsDict
AthAnalysisBaseComps/AthAnalysisBaseCompsDict.h
AthAnalysisBaseComps/selection.xml
INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaBaseComps StoreGateLib SGtests IOVDbDataModel GaudiKernel AthAnalysisBaseComps AthContainers )
# Install files from the package:
atlas_install_joboptions( share/*.py )
......
......@@ -13,6 +13,10 @@ use AthenaBaseComps AthenaBaseComps-* Control
use IOVDbDataModel IOVDbDataModel-* Database
use AtlasROOT AtlasROOT-* External
use AthContainers AthContainers-* Control
## put here your package dependencies...
##
......@@ -26,4 +30,8 @@ apply_pattern installed_library
apply_pattern declare_joboptions files="*.py"
private
use AtlasReflex AtlasReflex-* External -no_auto_imports
apply_pattern lcgdict dict=AthAnalysisBaseComps selectionfile=selection.xml headerfiles="../AthAnalysisBaseComps/AthAnalysisBaseCompsDict.h"
end_private
include.block ("RecExCommon/ContainerRemapping.py")
from AthenaCommon.AppMgr import ServiceMgr
# Instantiate the address remapping service:
if not hasattr( ServiceMgr, "AddressRemappingSvc" ):
ServiceMgr += CfgMgr.AddressRemappingSvc()
pass
if not hasattr( ServiceMgr, "ProxyProviderSvc" ):
ServiceMgr += CfgMgr.ProxyProviderSvc()
pass
ServiceMgr.ProxyProviderSvc.ProviderNames += [ "AddressRemappingSvc" ]
# Declare the name conversion rules:
ServiceMgr.AddressRemappingSvc.TypeKeyOverwriteMaps += [
"xAOD::ElectronContainer#ElectronCollection->"
"xAOD::ElectronContainer#Electrons",
"xAOD::ElectronAuxContainer#ElectronCollectionAux.->"
"xAOD::ElectronAuxContainer#ElectronsAux.",
"xAOD::ElectronContainer#FwdElectrons->"
"xAOD::ElectronContainer#ForwardElectrons",
"xAOD::ElectronAuxContainer#FwdElectronsAux.->"
"xAOD::ElectronAuxContainer#ForwardElectronsAux.",
"xAOD::PhotonContainer#PhotonCollection->"
"xAOD::PhotonContainer#Photons",
"xAOD::PhotonAuxContainer#PhotonCollectionAux.->"
"xAOD::PhotonAuxContainer#PhotonsAux.",
"xAOD::CaloClusterContainer#egClusterCollection->"
"xAOD::CaloClusterContainer#egammaClusters",
"xAOD::CaloClusterAuxContainer#egClusterCollectionAux.->"
"xAOD::CaloClusterAuxContainer#egammaClustersAux.",
"xAOD::CaloClusterContainer#LArClusterEMFrwd->"
"xAOD::CaloClusterContainer#ForwardElectronClusters",
"xAOD::CaloClusterAuxContainer#LArClusterEMFrwdAux.->"
"xAOD::CaloClusterAuxContainer#ForwardElectronClustersAux.",
"xAOD::TrackParticleContainer#InDetTrackParticlesForward->"
"xAOD::TrackParticleContainer#InDetForwardTrackParticles",
"xAOD::TrackParticleAuxContainer#InDetTrackParticlesForwardAux.->"
"xAOD::TrackParticleAuxContainer#InDetForwardTrackParticlesAux.",
"xAOD::TrackParticleContainer#InDetTrackParticlesLowBeta->"
"xAOD::TrackParticleContainer#InDetLowBetaTrackParticles",
"xAOD::TrackParticleAuxContainer#InDetTrackParticlesLowBetaAux.->"
"xAOD::TrackParticleAuxContainer#InDetLowBetaTrackParticlesAux.",
"xAOD::TauJetContainer#TauRecContainer->"
"xAOD::TauJetContainer#TauJets",
"xAOD::TauJetAuxContainer#TauRecContainerAux.->"
"xAOD::TauJetAuxContainer#TauJetsAux.",
"xAOD::CaloClusterContainer#TauPi0ClusterContainer->"
"xAOD::CaloClusterContainer#TauPi0Clusters",
"xAOD::CaloClusterAuxContainer#TauPi0ClusterContainerAux.->"
"xAOD::CaloClusterAuxContainer#TauPi0ClustersAux.",
"xAOD::VertexContainer#TauSecondaryVertexContainer->"
"xAOD::VertexContainer#TauSecondaryVertices",
"xAOD::VertexAuxContainer#TauSecondaryVertexContainerAux.->"
"xAOD::VertexAuxContainer#TauSecondaryVerticesAux.",
"xAOD::PFOContainer#TauShotPFOContainer->"
"xAOD::PFOContainer#TauShotParticleFlowObjects",
"xAOD::PFOAuxContainer#TauShotPFOContainerAux.->"
"xAOD::PFOAuxContainer#TauShotParticleFlowObjectsAux.",
"xAOD::PFOContainer#TauPi0ChargedPFOContainer->"
"xAOD::PFOContainer#TauChargedParticleFlowObjects",
"xAOD::PFOAuxContainer#TauPi0ChargedPFOContainerAux.->"
"xAOD::PFOAuxContainer#TauChargedParticleFlowObjectsAux.",
"xAOD::PFOContainer#TauPi0NeutralPFOContainer->"
"xAOD::PFOContainer#TauNeutralParticleFlowObjects",
"xAOD::PFOAuxContainer#TauPi0NeutralPFOContainerAux.->"
"xAOD::PFOAuxContainer#TauNeutralParticleFlowObjectsAux.",
"xAOD::PFOContainer#chargedJetETMissPFO_eflowRec->"
"xAOD::PFOContainer#JetETMissChargedParticleFlowObjects",
"xAOD::PFOAuxContainer#chargedJetETMissPFO_eflowRecAux.->"
"xAOD::PFOAuxContainer#JetETMissChargedParticleFlowObjectsAux.",
"xAOD::PFOContainer#neutralJetETMissPFO_eflowRec->"
"xAOD::PFOContainer#JetETMissNeutralParticleFlowObjects",
"xAOD::PFOAuxContainer#neutralJetETMissPFO_eflowRecAux.->"
"xAOD::PFOAuxContainer#JetETMissNeutralParticleFlowObjectsAux.",
"xAOD::CaloClusterContainer#CaloCalTopoCluster->"
"xAOD::CaloClusterContainer#CaloCalTopoClusters",
"xAOD::CaloClusterAuxContainer#CaloCalTopoClusterAux.->"
"xAOD::CaloClusterAuxContainer#CaloCalTopoClustersAux.",
"xAOD::TruthEventContainer#TruthEvent->"
"xAOD::TruthEventContainer#TruthEvents",
"xAOD::TruthEventAuxContainer#TruthEventAux.->"
"xAOD::TruthEventAuxContainer#TruthEventsAux.",
"xAOD::TruthParticleContainer#TruthParticle->"
"xAOD::TruthParticleContainer#TruthParticles",
"xAOD::TruthParticleAuxContainer#TruthParticleAux.->"
"xAOD::TruthParticleAuxContainer#TruthParticlesAux.",
"xAOD::TruthVertexContainer#TruthVertex->"
"xAOD::TruthVertexContainer#TruthVertices",
"xAOD::TruthVertexAuxContainer#TruthVertexAux.->"
"xAOD::TruthVertexAuxContainer#TruthVerticesAux."
]
svcMgr.AddressRemappingSvc.OutputLevel=WARNING #make quiet all the silly INFO printout
svcMgr.AddressRemappingSvc.SkipBadRemappings=True #for DxAOD running .. shouldn't harm in xAOD running either though
......@@ -13,10 +13,12 @@
#include "AthAnalysisBaseComps/AthAnalysisAlgorithm.h"
#include "TROOT.h"
AthAnalysisAlgorithm::AthAnalysisAlgorithm( const std::string& name,
ISvcLocator* pSvcLocator,
const std::string& version ) :
AthAlgorithm(name,pSvcLocator,version),
const std::string& ) :
AthHistogramAlgorithm(name,pSvcLocator),
m_inputMetaStore( "StoreGateSvc/InputMetaDataStore", name ),
m_outputMetaStore( "StoreGateSvc/MetaDataStore", name )
{
......@@ -46,7 +48,7 @@ StatusCode AthAnalysisAlgorithm::sysInitialize() {
incSvc->addListener( this, IncidentType::BeginInputFile, 0, true );
// Let the base class do its thing:
ATH_CHECK( AthAlgorithm::sysInitialize() );
ATH_CHECK( AthHistogramAlgorithm::sysInitialize() );
// Return gracefully:
return StatusCode::SUCCESS;
......@@ -59,6 +61,7 @@ void AthAnalysisAlgorithm::handle( const Incident& inc ) {
// Call the appropriate member function:
if( inc.type() == IncidentType::BeginInputFile ) {
m_currentFile=0;
if( beginInputFile().isFailure() ) {
ATH_MSG_FATAL( "Failed to call beginInputFile()" );
throw std::runtime_error( "Couldn't call beginInputFile()" );
......@@ -79,3 +82,83 @@ StatusCode AthAnalysisAlgorithm::beginInputFile() {
}
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
ServiceHandle<IProperty> evtSelector(evtSelName,name());
if(evtSelector.retrieve().isFailure()) {
ATH_MSG_ERROR("Couldn't find the service: " << evtSelName);return 0;
}
//get the list of input files - use this to determine which open file is the current input file
const StringArrayProperty& m_inputCollectionsName = dynamic_cast<const StringArrayProperty&>(evtSelector->getProperty("InputCollections"));
ATH_MSG_VERBOSE("nOpenFile=" << gROOT->GetListOfFiles()->GetSize() << ". nFilesInInputCollection=" << m_inputCollectionsName.value().size());
if(msgLvl(MSG::VERBOSE)) {
for(int i=0;i<gROOT->GetListOfFiles()->GetSize();i++) {
ATH_MSG_VERBOSE("Open file: " << gROOT->GetListOfFiles()->At(i)->GetName());
}
}
//look through list of files and find the one from the input collection that is currently open
for(int i=0;i<gROOT->GetListOfFiles()->GetSize();i++) {
TFile *g = (TFile*)gROOT->GetListOfFiles()->At(i);
//see if this file is in the input file list
//strip everything except stuff either side of last /
TString s(g->GetName());
TObjArray* tokens = s.Tokenize("/");
TObjString* lastToken = dynamic_cast<TObjString*>(tokens->Last());
TString sToCompare("");
bool shortComparison(false);
if(tokens->GetEntries()>1) {
TString beforeSlash((dynamic_cast<TObjString*>(tokens->At(tokens->GetEntries()-2)))->GetString