diff --git a/Event/EventBookkeeperTools/CMakeLists.txt b/Event/EventBookkeeperTools/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..451e7b0f9626d9b116591e531e8a4754387f66a0 --- /dev/null +++ b/Event/EventBookkeeperTools/CMakeLists.txt @@ -0,0 +1,39 @@ +################################################################################ +# Package: EventBookkeeperTools +################################################################################ + +# Declare the package name: +atlas_subdir( EventBookkeeperTools ) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( PUBLIC + Control/AthToolSupport/AsgTools + Control/AthenaBaseComps + Control/AthenaKernel + Database/AthenaPOOL/AthenaPoolKernel + Event/xAOD/xAODCutFlow + GaudiKernel + PRIVATE + Control/SGTools + Control/StoreGate + Event/EventBookkeeperMetaData + Event/EventInfo + Event/xAOD/xAODEventInfo ) + +# External dependencies: +find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread ) + +# Component(s) in the package: +atlas_add_component( EventBookkeeperTools + src/*.cxx + Root/*.cxx + src/components/*.cxx + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} AsgTools AthenaBaseComps AthenaKernel xAODCutFlow GaudiKernel SGTools StoreGateLib SGtests EventBookkeeperMetaData EventInfo xAODEventInfo ) + +# Install files from the package: +atlas_install_headers( EventBookkeeperTools ) +atlas_install_python_modules( python/*.py ) +atlas_install_joboptions( share/*.py ) +atlas_install_scripts( share/PrintCutFlow.py ) + diff --git a/Event/EventBookkeeperTools/EventBookkeeperTools/BookkeeperTool.h b/Event/EventBookkeeperTools/EventBookkeeperTools/BookkeeperTool.h new file mode 100644 index 0000000000000000000000000000000000000000..40436dfb823132ca1c1144117c11334a6ce3c1c3 --- /dev/null +++ b/Event/EventBookkeeperTools/EventBookkeeperTools/BookkeeperTool.h @@ -0,0 +1,76 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef BOOKKEEPERTOOL_H +#define BOOKKEEPERTOOL_H + +/** @file BookkeeperTool.h + * @brief This file contains the class definition for the BookkeeperTool class. + * @author Peter van Gemmeren <gemmeren@anl.gov> + * $Id: BookkeeperTool.h 663679 2015-04-29 08:31:54Z krasznaa $ + **/ + +//#include "GaudiKernel/AlgTool.h" +#include "AthenaBaseComps/AthAlgTool.h" +#include "AsgTools/AsgMetadataTool.h" +#ifdef ASGTOOL_ATHENA +#include "AthenaPoolKernel/IMetaDataTool.h" +#endif // ASGTOOL_ATHENA +#include "GaudiKernel/IIncidentListener.h" +#include "GaudiKernel/ServiceHandle.h" +#include "AthenaKernel/ICutFlowSvc.h" + +#include "xAODCutFlow/CutBookkeeper.h" +#include "xAODCutFlow/CutBookkeeperContainer.h" +#include "xAODCutFlow/CutBookkeeperAuxContainer.h" + +#include <string> + +/** @class BookkeeperTool + * @brief This class provides an example for reading with a ISelectorTool to veto events on AttributeList. + **/ + + +class BookkeeperTool : public asg::AsgMetadataTool +#ifdef ASGTOOL_ATHENA + , public virtual ::IMetaDataTool +#endif // ASGTOOL_ATHENA +{ + ASG_TOOL_CLASS0(BookkeeperTool) +public: // Constructor and Destructor + /// Standard Service Constructor + BookkeeperTool(const std::string& name = "BookkeeperTool"); + /// Destructor + virtual ~BookkeeperTool(); + +public: + //void handle(const Incident& incident); + virtual StatusCode metaDataStop(); + virtual StatusCode beginInputFile(); + virtual StatusCode endInputFile(); + virtual StatusCode initialize(); + virtual StatusCode finalize(); + +private: + /// Update an existing (possibly empty) xAOD::CutBookkeeperContainer with + /// all the information from the container(s) form the input file + StatusCode updateCollFromInputStore( xAOD::CutBookkeeperContainer* coll, + const std::string &collName ); + + /// Helper class to update a container with information from another one + StatusCode updateContainer( xAOD::CutBookkeeperContainer* contToUpdate, + const xAOD::CutBookkeeperContainer* otherCont ); + + /// Pointer to cut flow svc + //ServiceHandle<ICutFlowSvc> m_cutflowsvc; + + /// The name of the completed, i.e., fully processed, CutBookkeeperContainer + std::string m_completeCollName; + + /// The name of the incomplete, i.e., not fully processed (e.g. failed job), CutBookkeeperContainer + std::string m_incompleteCollName; +}; + +#endif + diff --git a/Event/EventBookkeeperTools/EventBookkeeperTools/myCppFilterTest.h b/Event/EventBookkeeperTools/EventBookkeeperTools/myCppFilterTest.h index 66d7b3e7b555159fc85675a33f42e66dc6b68036..069b2e048edf4b922c986af81a00c3e986a66b05 100644 --- a/Event/EventBookkeeperTools/EventBookkeeperTools/myCppFilterTest.h +++ b/Event/EventBookkeeperTools/EventBookkeeperTools/myCppFilterTest.h @@ -20,6 +20,9 @@ #include "AthenaKernel/ICutFlowSvc.h" #include "GaudiKernel/ServiceHandle.h" +// Prevent checkreq warning. +#include "AthenaPoolKernel/IMetaDataTool.h" + //class StoreGateSvc; diff --git a/Event/EventBookkeeperTools/Root/BookkeeperTool.cxx b/Event/EventBookkeeperTools/Root/BookkeeperTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b36770f9c1af094621daff9af52a6bdef56813c5 --- /dev/null +++ b/Event/EventBookkeeperTools/Root/BookkeeperTool.cxx @@ -0,0 +1,383 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// Implementation file for class BookkeeperTool +// Authors: Joao Firmino da Costa <joao.costa@cern.ch> and David Cote <david.cote@cern.ch> +/////////////////////////////////////////////////////////////////// + +#include "EventBookkeeperTools/BookkeeperTool.h" + +// STL include +#include <algorithm> + +// #include "FillEBCFromFlat.h" + +#include "GaudiKernel/Incident.h" +#include "GaudiKernel/FileIncident.h" +#include "GaudiKernel/IIncidentSvc.h" +#include "AthenaKernel/errorcheck.h" +#include "AthenaBaseComps/AthCheckMacros.h" + + +BookkeeperTool::BookkeeperTool(const std::string& name) + : asg::AsgMetadataTool(name) +{ + declareProperty("OutputCollName", m_completeCollName="CutBookkeepers", + "The default name of the xAOD::CutBookkeeperContainer for fully processed files"); + declareProperty("OutputIncompleteCollName", m_incompleteCollName = "IncompleteCutBookkeepers", + "The default name of the xAOD::CutBookkeeperContainer for partially processed files"); +#ifdef ASGTOOL_ATHENA + declareInterface< ::IMetaDataTool >( this ); +#endif // ASGTOOL_ATHENA +} + + + +BookkeeperTool::~BookkeeperTool() +{ +} + + + +StatusCode +BookkeeperTool::initialize() +{ + ATH_MSG_DEBUG( "Initializing " << name() << " - package version " << PACKAGE_VERSION ); + ATH_MSG_DEBUG("OutputCollName = " << m_completeCollName); + ATH_MSG_DEBUG("OutputIncompleteCollName = " << m_incompleteCollName); + + return StatusCode::SUCCESS; +} + + +//__________________________________________________________________________ +StatusCode BookkeeperTool::beginInputFile() +{ + //OPENING NEW INPUT FILE + //Things to do: + // 1) note that a file is currently opened + // 2) Load CutBookkeepers from input file + // 2a) if incomplete from input, directly propagate to output + // 2b) if complete from input, wait for EndInputFile to decide what to do in output + + // Get the incomplete bookkeeper collection of the input metadata store + const xAOD::CutBookkeeperContainer* input_inc = 0; + StatusCode ssc = inputMetaStore()->retrieve( input_inc, m_incompleteCollName ); + if (ssc.isSuccess()) { + //if ( (inputMetaStore()->retrieve( input_inc, m_incompleteCollName )).isSuccess() ) { + // First make sure there is an incomplete container in the output store + if( !(outputMetaStore()->contains<xAOD::CutBookkeeperContainer>(m_incompleteCollName)) ) { + xAOD::CutBookkeeperContainer* inc = new xAOD::CutBookkeeperContainer(); + xAOD::CutBookkeeperAuxContainer* auxinc = new xAOD::CutBookkeeperAuxContainer(); + inc->setStore(auxinc); + ATH_CHECK(outputMetaStore()->record(inc,m_incompleteCollName)); + ATH_CHECK(outputMetaStore()->record(auxinc,m_incompleteCollName+"Aux.")); + } + // retrieve the incomplete output container + xAOD::CutBookkeeperContainer* incompleteBook(NULL); + ATH_CHECK(outputMetaStore()->retrieve( incompleteBook, m_incompleteCollName)); + // update incomplete output with any incomplete input + ATH_CHECK(this->updateContainer(incompleteBook,input_inc)); + ATH_MSG_DEBUG("Successfully merged input incomplete bookkeepers with output"); + } + else { + ATH_MSG_INFO("No incomplete bookkeepers in this file " << m_incompleteCollName); + } + + // Get the complete bookkeeper collection of the input metadata store + const xAOD::CutBookkeeperContainer* input_com = 0; + if ( (inputMetaStore()->retrieve( input_com, m_completeCollName )).isSuccess() ) { + // Check if a tmp is there. IT SHOULD NOT BE + //xAOD::CutBookkeeperContainer* incompleteBook(NULL); + if( !(outputMetaStore()->contains<xAOD::CutBookkeeperContainer>(m_completeCollName+"tmp")) ) { + // Now create the tmp container + xAOD::CutBookkeeperContainer* tmp = new xAOD::CutBookkeeperContainer(); + xAOD::CutBookkeeperAuxContainer* auxtmp = new xAOD::CutBookkeeperAuxContainer(); + tmp->setStore(auxtmp); + if (updateContainer(tmp,input_com).isSuccess()) { + ATH_CHECK(outputMetaStore()->record(tmp,m_completeCollName+"tmp")); + ATH_CHECK(outputMetaStore()->record(auxtmp,m_completeCollName+"tmpAux.")); + } + else { + ATH_MSG_WARNING("Could not update tmp container from input complete conatiner"); + } + } + else { + ATH_MSG_WARNING("tmp collection already exists"); + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("Successfully copied complete bookkeepers to temp container"); + } + + return StatusCode::SUCCESS; +} + + +StatusCode BookkeeperTool::endInputFile() +{ + //CLOSING INPUT FILE + //Things to do: + // Make sure complete container exists in output + if( !(outputMetaStore()->contains<xAOD::CutBookkeeperContainer>(m_completeCollName)) ) { + // Now create the complete container + xAOD::CutBookkeeperContainer* inc = new xAOD::CutBookkeeperContainer(); + xAOD::CutBookkeeperAuxContainer* auxinc = new xAOD::CutBookkeeperAuxContainer(); + inc->setStore(auxinc); + ATH_CHECK(outputMetaStore()->record(inc,m_completeCollName)); + ATH_CHECK(outputMetaStore()->record(auxinc,m_completeCollName+"Aux.")); + } + else { + ATH_MSG_WARNING("complete collection already exists"); + //return StatusCode::SUCCESS; + } + + // Get the complete bookkeeper collection of the output meta-data store + xAOD::CutBookkeeperContainer* completeBook(NULL); + if( !(outputMetaStore()->retrieve( completeBook, m_completeCollName) ).isSuccess() ) { + ATH_MSG_ERROR( "Could not get complete CutBookkeepers from output MetaDataStore" ); + return StatusCode::FAILURE; + } + + // Get the tmp bookkeeper from the input + const xAOD::CutBookkeeperContainer* tmpCompleteBook(NULL); + if( !(outputMetaStore()->retrieve( tmpCompleteBook, m_completeCollName+"tmp") ).isSuccess() ) { + ATH_MSG_WARNING( "Could not get tmp CutBookkeepers from output MetaDataStore" ); + } + else { + // update the complete output with the complete input + ATH_CHECK(this->updateContainer(completeBook,tmpCompleteBook)); + // remove the tmp container + const SG::IConstAuxStore* tmpCompleteBookAux = tmpCompleteBook->getConstStore(); + ATH_CHECK(outputMetaStore()->removeDataAndProxy(tmpCompleteBook)); + ATH_CHECK(outputMetaStore()->removeDataAndProxy(tmpCompleteBookAux)); + } + + return StatusCode::SUCCESS; +} + +StatusCode BookkeeperTool::metaDataStop() +{ + //TERMINATING THE JOB (EndRun) + //Things to do: + // 1) Create new incomplete CutBookkeepers if relevant + // 2) Print cut flow summary + // 3) Write root file if requested + // Make sure complete container exists in output + if( !(outputMetaStore()->contains<xAOD::CutBookkeeperContainer>(m_incompleteCollName)) ) { + // Now create the complete container + xAOD::CutBookkeeperContainer* coll = new xAOD::CutBookkeeperContainer(); + xAOD::CutBookkeeperAuxContainer* auxcoll = new xAOD::CutBookkeeperAuxContainer(); + coll->setStore(auxcoll); + ATH_CHECK(outputMetaStore()->record(coll,m_incompleteCollName)); + ATH_CHECK(outputMetaStore()->record(auxcoll,m_incompleteCollName+"Aux.")); + } + else { + ATH_MSG_WARNING("incomplete collection already exists"); + } + + // Get the complete bookkeeper collection of the output meta-data store + xAOD::CutBookkeeperContainer* incompleteBook(NULL); + if( !(outputMetaStore()->retrieve( incompleteBook, m_incompleteCollName) ).isSuccess() ) { + ATH_MSG_WARNING( "Could not get incomplete CutBookkeepers from output MetaDataStore" ); + } + + // Get the tmp bookkeeper from the input + const xAOD::CutBookkeeperContainer* tmpCompleteBook(NULL); + if( !(outputMetaStore()->retrieve( tmpCompleteBook, m_completeCollName+"tmp") ).isSuccess() ) { + ATH_MSG_WARNING( "Could not get tmp CutBookkeepers from output MetaDataStore for " << m_completeCollName+"tmp"); + } + else { + // update the complete output with the complete input + ATH_CHECK(this->updateContainer(incompleteBook,tmpCompleteBook)); + // remove the tmp container + const SG::IConstAuxStore* tmpCompleteBookAux = tmpCompleteBook->getConstStore(); + ATH_CHECK(outputMetaStore()->removeDataAndProxy(tmpCompleteBook)); + ATH_CHECK(outputMetaStore()->removeDataAndProxy(tmpCompleteBookAux)); + } + + return StatusCode::SUCCESS; +} + + +StatusCode +BookkeeperTool::finalize() +{ + ATH_MSG_DEBUG( "Finalizing " << name() << " - package version " << PACKAGE_VERSION ); + return StatusCode::SUCCESS; +} + + + +StatusCode +BookkeeperTool::updateCollFromInputStore(xAOD::CutBookkeeperContainer* coll, + const std::string &collName) +{ + ATH_MSG_DEBUG("calling updateCollFromInputStore(" << collName << ") with coll-size=" << coll->size() ); + + if ( inputMetaStore()->contains<xAOD::CutBookkeeperContainer>(collName) ) { + ATH_MSG_VERBOSE("Input MetaData contains type xAOD::CutBookkeeperContainer with name" << collName); + + // There can always only be a single object in the input store. As the store + // is connected to just a single input file. + const xAOD::CutBookkeeperContainer* tmpColl = 0; + ATH_CHECK( inputMetaStore()->retrieve( tmpColl, collName ) ); + + // Check that we succeeded: + if( ! tmpColl->hasStore() ) { + ATH_MSG_FATAL( "Object doesn't have an auxiliary store" ); + return StatusCode::FAILURE; + } + + //...and update coll with each list. + ATH_CHECK( this->updateContainer(coll, tmpColl) ); + } + else { + ATH_MSG_INFO( "Cannot find xAOD::CutBookkeeperContainer " + << "with name " << collName << " in the input file."); + } + return StatusCode::SUCCESS; +} + + + +StatusCode +BookkeeperTool::updateContainer( xAOD::CutBookkeeperContainer* contToUpdate, + const xAOD::CutBookkeeperContainer* otherCont ) { + ATH_MSG_DEBUG("calling updateContainer(...)" ); + ATH_MSG_DEBUG("Have container to update with size=" << contToUpdate->size() + << ", and other container with size=" << otherCont->size() ); + + // Create an vector of indices of all the newly transferred CutBookkeepers + std::vector< std::size_t > newEBKIndices; + // Loop through otherCont. + // If element already in contToUpdate, update event counts, otherwise create new element + for ( std::size_t i=0; i<otherCont->size(); ++i ) { + const xAOD::CutBookkeeper* otherEBK = otherCont->at(i); + ATH_MSG_VERBOSE("Looping through otherCont at index " << i); + ATH_MSG_VERBOSE("Have otherEBK with: name=" << otherEBK->name() + << ", cycle=" << otherEBK->cycle() + << ", nAcceptedEvents=" << otherEBK->nAcceptedEvents() + << ", inputStream=" << otherEBK->inputStream() ); + + + // Loop through the container to be updated (contToUpdate) and see if we find a match + bool foundEBKToUpdate(false); + for ( std::size_t j=0; j<contToUpdate->size(); ++j ) { + xAOD::CutBookkeeper* ebkToUpdate = contToUpdate->at(j); + // Check if they are identical, if so, update; else add otherEBK + if ( otherEBK->isEqualTo(ebkToUpdate) ) { + ebkToUpdate->setPayload( ebkToUpdate->payload() + otherEBK->payload() ); + foundEBKToUpdate = true; + break; + } + } // End: Inner loop over contToUpdate + if (!foundEBKToUpdate) { + xAOD::CutBookkeeper* newEBK = new xAOD::CutBookkeeper(); + if ( newEBK->usingPrivateStore() ) { newEBK->releasePrivateStore(); } + newEBK->makePrivateStore(otherEBK); + contToUpdate->push_back( newEBK ); + std::size_t ebIdx = newEBK->index(); + newEBKIndices.push_back(ebIdx); + } + } // End: Outer loop over contToUpdate + + // Now, we still need to fix the cross-referencing of the newly added CutBookkkeepers + for ( std::size_t i=0; i<newEBKIndices.size(); ++i ) { + std::size_t otherIndex = newEBKIndices.at(i); + xAOD::CutBookkeeper* ebkToModify = contToUpdate->at(otherIndex); + + // Parent check + if ( ebkToModify->hasParent() ) { + const xAOD::CutBookkeeper* oldParent = ebkToModify->parent(); + xAOD::CutBookkeeperContainer::iterator matchIter = std::find( contToUpdate->begin(), + contToUpdate->end(), + oldParent ); + // If we found it, we can modify + if ( matchIter != contToUpdate->end() ) { + ATH_MSG_VERBOSE("Updating ElementLink to parent"); + ebkToModify->setParent( *matchIter ); + } + // If we didn't find it, we need to add it + else { + ATH_MSG_VERBOSE("Adding new parent"); + xAOD::CutBookkeeper* newEBK = new xAOD::CutBookkeeper(); + if ( newEBK->usingPrivateStore() ) { newEBK->releasePrivateStore(); } + newEBK->makePrivateStore(oldParent); + contToUpdate->push_back( newEBK ); + ebkToModify->setParent( newEBK ); + } + } // Done fixing parent + + // Children check + for ( std::size_t oldIdx=0; oldIdx<ebkToModify->nChildren(); ++oldIdx ) { + const xAOD::CutBookkeeper* oldEBK = ebkToModify->child(oldIdx); + xAOD::CutBookkeeperContainer::iterator matchIter = std::find( contToUpdate->begin(), + contToUpdate->end(), + oldEBK ); + // If we found it, we can modify + if ( matchIter != contToUpdate->end() ) { + ATH_MSG_VERBOSE("Updating ElementLink to child"); + ebkToModify->addChild( *matchIter ); + } + // If we didn't find it, we need to add it + else { + ATH_MSG_VERBOSE("Adding new child"); + xAOD::CutBookkeeper* newEBK = new xAOD::CutBookkeeper(); + if ( newEBK->usingPrivateStore() ) { newEBK->releasePrivateStore(); } + newEBK->makePrivateStore(oldEBK); + contToUpdate->push_back( newEBK ); + ebkToModify->addChild( newEBK ); + } + } // Done fixing children + + // Used others check + for ( std::size_t oldIdx=0; oldIdx<ebkToModify->nUsedOthers(); ++oldIdx ) { + const xAOD::CutBookkeeper* oldEBK = ebkToModify->usedOther(oldIdx); + xAOD::CutBookkeeperContainer::iterator matchIter = std::find( contToUpdate->begin(), + contToUpdate->end(), + oldEBK ); + // If we found it, we can modify + if ( matchIter != contToUpdate->end() ) { + ATH_MSG_VERBOSE("Updating ElementLink to usedOther"); + ebkToModify->addUsedOther( *matchIter ); + } + // If we didn't find it, we need to add it + else { + ATH_MSG_VERBOSE("Adding new usedOther"); + xAOD::CutBookkeeper* newEBK = new xAOD::CutBookkeeper(); + if ( newEBK->usingPrivateStore() ) { newEBK->releasePrivateStore(); } + newEBK->makePrivateStore(oldEBK); + contToUpdate->push_back( newEBK ); + ebkToModify->addUsedOther( newEBK ); + } + } // Done fixing used others + + // Siblings check + for ( std::size_t oldIdx=0; oldIdx<ebkToModify->nSiblings(); ++oldIdx ) { + const xAOD::CutBookkeeper* oldEBK = ebkToModify->sibling(oldIdx); + xAOD::CutBookkeeperContainer::iterator matchIter = std::find( contToUpdate->begin(), + contToUpdate->end(), + oldEBK ); + // If we found it, we can modify + if ( matchIter != contToUpdate->end() ) { + ATH_MSG_VERBOSE("Updating ElementLink to sibling"); + ebkToModify->addSibling( *matchIter ); + } + // If we didn't find it, we need to add it + else { + ATH_MSG_VERBOSE("Adding new sibling"); + xAOD::CutBookkeeper* newEBK = new xAOD::CutBookkeeper(); + if ( newEBK->usingPrivateStore() ) { newEBK->releasePrivateStore(); } + newEBK->makePrivateStore(oldEBK); + contToUpdate->push_back( newEBK ); + ebkToModify->addSibling( newEBK ); + } + } // Done fixing siblings + } // Done fixing all cross references + return StatusCode::SUCCESS; +} + + diff --git a/Event/EventBookkeeperTools/cmt/requirements b/Event/EventBookkeeperTools/cmt/requirements index 800abb452b1e1f4d2609f9a325430a0751c5e75c..5b22fcd19028e83daeb93ea27061f03e256cd928 100644 --- a/Event/EventBookkeeperTools/cmt/requirements +++ b/Event/EventBookkeeperTools/cmt/requirements @@ -7,6 +7,9 @@ use AtlasPolicy AtlasPolicy-* use AthenaBaseComps AthenaBaseComps-* Control use AthenaKernel AthenaKernel-* Control use GaudiInterface GaudiInterface-* External +use AsgTools AsgTools-* Control/AthToolSupport +use xAODCutFlow xAODCutFlow-* Event/xAOD +use AthenaPoolKernel AthenaPoolKernel-* Database/AthenaPOOL #use AtlasBoost AtlasBoost-* External #use SampleHandler SampleHandler-* PhysicsAnalysis/D3PDTools @@ -18,13 +21,12 @@ use EventBookkeeperMetaData EventBookkeeperMetaData-* Event use EventInfo EventInfo-* Event use SGTools SGTools-* Control use StoreGate StoreGate-* Control -use xAODCutFlow xAODCutFlow-* Event/xAOD use xAODEventInfo xAODEventInfo-* Event/xAOD end_private -library EventBookkeeperTools *.cxx components/*.cxx -#library EventBookkeeperTools *.cxx ../Root/*.cxx components/*.cxx +#library EventBookkeeperTools *.cxx components/*.cxx +library EventBookkeeperTools *.cxx ../Root/*.cxx components/*.cxx branches src Root diff --git a/Event/EventBookkeeperTools/python/CutFlowHelpers.py b/Event/EventBookkeeperTools/python/CutFlowHelpers.py index 364f2bfc7ea31144281a930b67300c5f79a15f4f..c71361fa18812c53c217d5979ced30d091956aaa 100644 --- a/Event/EventBookkeeperTools/python/CutFlowHelpers.py +++ b/Event/EventBookkeeperTools/python/CutFlowHelpers.py @@ -59,7 +59,7 @@ def CreateCutFlowSvc( svcName="CutFlowSvc", athFile=None, seq=None, addAlgInPlac # Determine current input stream name inputStreamName = GetCurrentStreamName( msg=msg, athFile=athFile ) - msg.debug("CrateCutFlowSvc: Have inputStreamName = %s" % (inputStreamName) ) + msg.debug("CreateCutFlowSvc: Have inputStreamName = %s" % (inputStreamName) ) # Create the CutFlowSvc instance import AthenaCommon.CfgMgr as CfgMgr diff --git a/Event/EventBookkeeperTools/src/CutFlowSvc.cxx b/Event/EventBookkeeperTools/src/CutFlowSvc.cxx index 462d3c6132cbe065945d4c5cd17994503939d926..ae38cbfa5813dba6c93566ad819564e3c74a6dd0 100644 --- a/Event/EventBookkeeperTools/src/CutFlowSvc.cxx +++ b/Event/EventBookkeeperTools/src/CutFlowSvc.cxx @@ -59,8 +59,8 @@ CutFlowSvc::CutFlowSvc(const std::string& name, m_inputCompleteBookAuxTmp(0), m_fileCurrentlyOpened(false), m_ebkMap(), - m_alreadyCopiedEventBookkeepers(false), - m_alreadyDeterminedCycleNumber(false) + m_alreadyCopiedEventBookkeepers(false) + //m_alreadyDeterminedCycleNumber(false) { declareProperty("OutputCollName", m_completeCollName="CutBookkeepers", "The default name of the xAOD::CutBookkeeperContainer for fully processed files"); @@ -372,8 +372,8 @@ CutIdentifier CutFlowSvc::declareUsedOtherFilter( const std::string& name, // Otherwise, add the new one to the collection tmpEBK->setDescription( "Registered by origin filter" ); - originEBK->addUsedOther( tmpEBK ); completeBook->push_back( tmpEBK ); + originEBK->addUsedOther( tmpEBK ); // Fill the map m_ebkMap[cutID] = tmpEBK; @@ -434,19 +434,19 @@ CutFlowSvc::addEvent( CutIdentifier cutID, double weight) xAOD::CutBookkeeperContainer::iterator iterEnd = completeBook->end(); for ( ; iter != iterEnd; ++iter ) { xAOD::CutBookkeeper* ebk = *iter; - CutIdentifier cutID = ebk->uniqueIdentifier(); + CutIdentifier cutID2 = ebk->uniqueIdentifier(); ATH_MSG_VERBOSE( "addEvent: Have CutBookkeeper with" << " skimming cycle " << ebk->cycle() << " and input Stream name " << ebk->inputStream() << " and logic " << ebk->cutLogic() << " isTopFilter " << ebk->isTopFilter() - << " and cutID " << cutID + << " and cutID " << cutID2 << " and name " << ebk->name() ); if ( m_skimmingCycle == ebk->cycle() ) { if ( m_inputStream.value() == ebk->inputStream() ) { - CutIDMap_t::iterator mapIter = m_ebkMap.find(cutID); + CutIDMap_t::iterator mapIter = m_ebkMap.find(cutID2); ATH_MSG_DEBUG( "BeginInputFile: Have CutBookkeeper with" - << " cutID " << cutID + << " cutID " << cutID2 << " and name " << ebk->name() ); if ( mapIter != m_ebkMap.end() ) { // we found this CutBookkeeper in the existing map (*mapIter).second = ebk; @@ -673,7 +673,45 @@ CutFlowSvc::updateCollFromInputStore(xAOD::CutBookkeeperContainer* coll, } +namespace { + + +xAOD::CutBookkeeper* +resolveLink (const xAOD::CutBookkeeper* old, + xAOD::CutBookkeeperContainer& contToUpdate, + const xAOD::CutBookkeeperContainer& otherCont, + const std::vector<size_t>& otherIndices) +{ + { + xAOD::CutBookkeeperContainer::iterator matchIter = + std::find( contToUpdate.begin(), + contToUpdate.end(), + old ); + if (matchIter != contToUpdate.end()) + return *matchIter; + } + + { + xAOD::CutBookkeeperContainer::const_iterator matchIter = + std::find( otherCont.begin(), + otherCont.end(), + old ); + if (matchIter != contToUpdate.end()) { + size_t pos = matchIter - otherCont.begin(); + return contToUpdate[otherIndices[pos]]; + } + } + + // If we didn't find it, we need to add it + xAOD::CutBookkeeper* newEBK = new xAOD::CutBookkeeper(); + if ( newEBK->usingPrivateStore() ) { newEBK->releasePrivateStore(); } + newEBK->makePrivateStore(old); + contToUpdate.push_back( newEBK ); + return newEBK; +} + +} // anonymous namespace StatusCode @@ -683,8 +721,10 @@ CutFlowSvc::updateContainer( xAOD::CutBookkeeperContainer* contToUpdate, ATH_MSG_VERBOSE("Have container to update with size=" << contToUpdate->size() << ", and other container with size=" << otherCont->size() ); - // Create an vector of indices of all the newly transferred CutBookkeepers - std::vector< std::size_t > newEBKIndices; + size_t origSize = contToUpdate->size(); + + // Vector of indices in contToUpdate of elements in otherCont. + std::vector< std::size_t > otherIndices (otherCont->size()); // Loop through otherCont. // If element already in contToUpdate, update event counts, otherwise create new element for ( std::size_t i=0; i<otherCont->size(); ++i ) { @@ -703,6 +743,7 @@ CutFlowSvc::updateContainer( xAOD::CutBookkeeperContainer* contToUpdate, // Check if they are identical, if so, update; else add otherEBK if ( otherEBK->isEqualTo(ebkToUpdate) ) { ebkToUpdate->setPayload( ebkToUpdate->payload() + otherEBK->payload() ); + otherIndices[i] = j; foundEBKToUpdate = true; break; } @@ -713,102 +754,56 @@ CutFlowSvc::updateContainer( xAOD::CutBookkeeperContainer* contToUpdate, newEBK->makePrivateStore(otherEBK); contToUpdate->push_back( newEBK ); std::size_t ebIdx = newEBK->index(); - newEBKIndices.push_back(ebIdx); + otherIndices[i] = ebIdx; } } // End: Outer loop over contToUpdate // Now, we still need to fix the cross-referencing of the newly added CutBookkkeepers - for ( std::size_t i=0; i<newEBKIndices.size(); ++i ) { - std::size_t otherIndex = newEBKIndices.at(i); - xAOD::CutBookkeeper* ebkToModify = contToUpdate->at(otherIndex); + for ( std::size_t i=origSize; i<contToUpdate->size(); ++i ) { + xAOD::CutBookkeeper* ebkToModify = contToUpdate->at(i); // Parent check if ( ebkToModify->hasParent() ) { const xAOD::CutBookkeeper* oldParent = ebkToModify->parent(); - xAOD::CutBookkeeperContainer::iterator matchIter = std::find( contToUpdate->begin(), - contToUpdate->end(), - oldParent ); - // If we found it, we can modify - if ( matchIter != contToUpdate->end() ) { - ATH_MSG_VERBOSE("Updating ElementLink to parent"); - ebkToModify->setParent( *matchIter ); - } - // If we didn't find it, we need to add it - else { - ATH_MSG_VERBOSE("Adding new parent"); - xAOD::CutBookkeeper* newEBK = new xAOD::CutBookkeeper(); - if ( newEBK->usingPrivateStore() ) { newEBK->releasePrivateStore(); } - newEBK->makePrivateStore(oldParent); - contToUpdate->push_back( newEBK ); - ebkToModify->setParent( newEBK ); - } + const xAOD::CutBookkeeper* newParent = resolveLink (oldParent, + *contToUpdate, + *otherCont, + otherIndices); + ebkToModify->setParent (newParent); } // Done fixing parent // Children check + std::vector< xAOD::CutBookkeeper* > newChildren; for ( std::size_t oldIdx=0; oldIdx<ebkToModify->nChildren(); ++oldIdx ) { const xAOD::CutBookkeeper* oldEBK = ebkToModify->child(oldIdx); - xAOD::CutBookkeeperContainer::iterator matchIter = std::find( contToUpdate->begin(), - contToUpdate->end(), - oldEBK ); - // If we found it, we can modify - if ( matchIter != contToUpdate->end() ) { - ATH_MSG_VERBOSE("Updating ElementLink to child"); - ebkToModify->addChild( *matchIter ); - } - // If we didn't find it, we need to add it - else { - ATH_MSG_VERBOSE("Adding new child"); - xAOD::CutBookkeeper* newEBK = new xAOD::CutBookkeeper(); - if ( newEBK->usingPrivateStore() ) { newEBK->releasePrivateStore(); } - newEBK->makePrivateStore(oldEBK); - contToUpdate->push_back( newEBK ); - ebkToModify->addChild( newEBK ); - } + newChildren.push_back (resolveLink (oldEBK, + *contToUpdate, + *otherCont, + otherIndices)); } // Done fixing children + ebkToModify->setChildren (newChildren); // Used others check + std::vector< xAOD::CutBookkeeper* > newOthers; for ( std::size_t oldIdx=0; oldIdx<ebkToModify->nUsedOthers(); ++oldIdx ) { const xAOD::CutBookkeeper* oldEBK = ebkToModify->usedOther(oldIdx); - xAOD::CutBookkeeperContainer::iterator matchIter = std::find( contToUpdate->begin(), - contToUpdate->end(), - oldEBK ); - // If we found it, we can modify - if ( matchIter != contToUpdate->end() ) { - ATH_MSG_VERBOSE("Updating ElementLink to usedOther"); - ebkToModify->addUsedOther( *matchIter ); - } - // If we didn't find it, we need to add it - else { - ATH_MSG_VERBOSE("Adding new usedOther"); - xAOD::CutBookkeeper* newEBK = new xAOD::CutBookkeeper(); - if ( newEBK->usingPrivateStore() ) { newEBK->releasePrivateStore(); } - newEBK->makePrivateStore(oldEBK); - contToUpdate->push_back( newEBK ); - ebkToModify->addUsedOther( newEBK ); - } + newOthers.push_back (resolveLink (oldEBK, + *contToUpdate, + *otherCont, + otherIndices)); } // Done fixing used others + ebkToModify->setUsedOthers (newOthers); // Siblings check + std::vector< xAOD::CutBookkeeper* > newSiblings; for ( std::size_t oldIdx=0; oldIdx<ebkToModify->nSiblings(); ++oldIdx ) { const xAOD::CutBookkeeper* oldEBK = ebkToModify->sibling(oldIdx); - xAOD::CutBookkeeperContainer::iterator matchIter = std::find( contToUpdate->begin(), - contToUpdate->end(), - oldEBK ); - // If we found it, we can modify - if ( matchIter != contToUpdate->end() ) { - ATH_MSG_VERBOSE("Updating ElementLink to sibling"); - ebkToModify->addSibling( *matchIter ); - } - // If we didn't find it, we need to add it - else { - ATH_MSG_VERBOSE("Adding new sibling"); - xAOD::CutBookkeeper* newEBK = new xAOD::CutBookkeeper(); - if ( newEBK->usingPrivateStore() ) { newEBK->releasePrivateStore(); } - newEBK->makePrivateStore(oldEBK); - contToUpdate->push_back( newEBK ); - ebkToModify->addSibling( newEBK ); - } + newSiblings.push_back (resolveLink (oldEBK, + *contToUpdate, + *otherCont, + otherIndices)); } // Done fixing siblings + ebkToModify->setSiblings (newSiblings); } // Done fixing all cross references return StatusCode::SUCCESS; } diff --git a/Event/EventBookkeeperTools/src/CutFlowSvc.h b/Event/EventBookkeeperTools/src/CutFlowSvc.h index b123e438e0612a571f3ad782457a86bc7c5427c7..8aec81ea9d7fb43048364dbc359722ce9e3aa78e 100644 --- a/Event/EventBookkeeperTools/src/CutFlowSvc.h +++ b/Event/EventBookkeeperTools/src/CutFlowSvc.h @@ -217,7 +217,7 @@ private: bool m_alreadyCopiedEventBookkeepers; /// Internal flag to track if we have already determined the cycle number from the first input file - bool m_alreadyDeterminedCycleNumber; + //bool m_alreadyDeterminedCycleNumber; public: diff --git a/Event/EventBookkeeperTools/src/FillEBCFromFlat.cxx b/Event/EventBookkeeperTools/src/FillEBCFromFlat.cxx index 663c3567febc953bd7fc46650bca1874decaff18..1c130f6c004cc19f48c1f634d039ef4e8e266e62 100644 --- a/Event/EventBookkeeperTools/src/FillEBCFromFlat.cxx +++ b/Event/EventBookkeeperTools/src/FillEBCFromFlat.cxx @@ -21,36 +21,36 @@ void FillEBCFromFlat::initialise() { //std::cout << "FillEBCFromFlat::initialise()" << std::endl; - name = m_inputStore->retrieve<std::vector<std::string> >("CutFlowTree/name"); - inputstream = m_inputStore->retrieve<std::vector<std::string> >("CutFlowTree/inputstream"); - outputstream = m_inputStore->retrieve<std::vector<std::string> >("CutFlowTree/outputstream"); - description = m_inputStore->retrieve<std::vector<std::string> >("CutFlowTree/description"); - logic = m_inputStore->retrieve<std::vector<std::string> >("CutFlowTree/logic"); - nAcceptedEvents = m_inputStore->retrieve<std::vector<ULong_t> >("CutFlowTree/nAcceptedEvents"); - nWeightedAcceptedEvents = m_inputStore->retrieve<std::vector<Double_t> >("CutFlowTree/nWeightedAcceptedEvents"); - isComplete = m_inputStore->retrieve<std::vector<Int_t> >("CutFlowTree/isComplete"); - cycle = m_inputStore->retrieve<std::vector<Int_t> >("CutFlowTree/cycle"); - parentIndex = m_inputStore->retrieve<std::vector<Int_t> >("CutFlowTree/parentIndex"); - nbChildren = m_inputStore->retrieve<std::vector<Int_t> >("CutFlowTree/nbChildren"); - childrenIndices = m_inputStore->retrieve<std::vector< std::vector<UInt_t> > >("CutFlowTree/childrenIndices"); + m_name = m_inputStore->retrieve<std::vector<std::string> >("CutFlowTree/name"); + m_inputstream = m_inputStore->retrieve<std::vector<std::string> >("CutFlowTree/inputstream"); + m_outputstream = m_inputStore->retrieve<std::vector<std::string> >("CutFlowTree/outputstream"); + m_description = m_inputStore->retrieve<std::vector<std::string> >("CutFlowTree/description"); + m_logic = m_inputStore->retrieve<std::vector<std::string> >("CutFlowTree/logic"); + m_nAcceptedEvents = m_inputStore->retrieve<std::vector<ULong_t> >("CutFlowTree/nAcceptedEvents"); + m_nWeightedAcceptedEvents = m_inputStore->retrieve<std::vector<Double_t> >("CutFlowTree/nWeightedAcceptedEvents"); + m_isComplete = m_inputStore->retrieve<std::vector<Int_t> >("CutFlowTree/isComplete"); + m_cycle = m_inputStore->retrieve<std::vector<Int_t> >("CutFlowTree/cycle"); + m_parentIndex = m_inputStore->retrieve<std::vector<Int_t> >("CutFlowTree/parentIndex"); + m_nbChildren = m_inputStore->retrieve<std::vector<Int_t> >("CutFlowTree/nbChildren"); + m_childrenIndices = m_inputStore->retrieve<std::vector< std::vector<UInt_t> > >("CutFlowTree/childrenIndices"); } void FillEBCFromFlat::fill() { //std::cout << "FillEBCFromFlat::fill()" << std::endl; - unsigned int nCuts = name->size(); + unsigned int nCuts = m_name->size(); for (unsigned int i = 0; i < nCuts; ++i) { - if (isComplete->at(i) != m_wantIsComplete) continue; + if (m_isComplete->at(i) != m_wantIsComplete) continue; // Only add top level EventBookkeepers here - if (parentIndex->at(i) != -1) continue; + if (m_parentIndex->at(i) != -1) continue; EventBookkeeper *eb = newEventBookkeeper(i); m_coll->push_back(eb); - if (nbChildren->at(i) > 0) { + if (m_nbChildren->at(i) > 0) { addChildren(eb, i); } } @@ -58,16 +58,16 @@ void FillEBCFromFlat::fill() EventBookkeeper *FillEBCFromFlat::newEventBookkeeper(unsigned int index) const { - //std::cout << "FillEBCFromFlat::newEventBookkeeper(" << index << ") - " << name->at(index) << std::endl; - - EventBookkeeper *eb = new EventBookkeeper(name->at(index)); - eb->setInputStream(inputstream->at(index)); - eb->setOutputStream(outputstream->at(index)); - eb->setDescription(description->at(index)); - eb->setLogic(logic->at(index)); - eb->setNAcceptedEvents(nAcceptedEvents->at(index)); - eb->setNWeightedAcceptedEvents(nWeightedAcceptedEvents->at(index)); - eb->setCycle(cycle->at(index)); + //std::cout << "FillEBCFromFlat::newEventBookkeeper(" << index << ") - " << m_name->at(index) << std::endl; + + EventBookkeeper *eb = new EventBookkeeper(m_name->at(index)); + eb->setInputStream(m_inputstream->at(index)); + eb->setOutputStream(m_outputstream->at(index)); + eb->setDescription(m_description->at(index)); + eb->setLogic(m_logic->at(index)); + eb->setNAcceptedEvents(m_nAcceptedEvents->at(index)); + eb->setNWeightedAcceptedEvents(m_nWeightedAcceptedEvents->at(index)); + eb->setCycle(m_cycle->at(index)); return eb; } @@ -75,7 +75,7 @@ void FillEBCFromFlat::addChildren(EventBookkeeper *eb, unsigned int indexOfEb) c { //std::cout << "FillEBCFromFlat::addChildren(@" << eb << ", " << indexOfEb <<")" << std::endl; - for (std::vector<UInt_t>::const_iterator childIndex = childrenIndices->at(indexOfEb).begin(); childIndex != childrenIndices->at(indexOfEb).end(); ++childIndex) { + for (std::vector<UInt_t>::const_iterator childIndex = m_childrenIndices->at(indexOfEb).begin(); childIndex != m_childrenIndices->at(indexOfEb).end(); ++childIndex) { unsigned int corrChildIndex = (*childIndex) + m_offset; if (corrChildIndex == indexOfEb) { std::cout << "FillEBCFromFlat::addChildren() WARNING - corrChildIndex == indexOfEb == " << indexOfEb << std::endl; @@ -83,7 +83,7 @@ void FillEBCFromFlat::addChildren(EventBookkeeper *eb, unsigned int indexOfEb) c } EventBookkeeper *ebChild = newEventBookkeeper(corrChildIndex); - if (nbChildren->at(corrChildIndex) > 0) { + if (m_nbChildren->at(corrChildIndex) > 0) { addChildren(ebChild, corrChildIndex); } eb->AddChild(ebChild); diff --git a/Event/EventBookkeeperTools/src/FillEBCFromFlat.h b/Event/EventBookkeeperTools/src/FillEBCFromFlat.h index d948f4ab1ff6029898da83069a93d7245efc48c4..b8c5a275e5084498d6f3e497c2ba5866c4f8b354 100644 --- a/Event/EventBookkeeperTools/src/FillEBCFromFlat.h +++ b/Event/EventBookkeeperTools/src/FillEBCFromFlat.h @@ -37,18 +37,18 @@ class FillEBCFromFlat { unsigned int m_offset; - std::vector<std::string> *name; - std::vector<std::string> *inputstream; - std::vector<std::string> *outputstream; - std::vector<std::string> *description; - std::vector<std::string> *logic; - std::vector<ULong_t> *nAcceptedEvents; - std::vector<Double_t> *nWeightedAcceptedEvents; - std::vector<Int_t> *isComplete; - std::vector<Int_t> *cycle; - std::vector<Int_t> *parentIndex; - std::vector<Int_t> *nbChildren; - std::vector< std::vector<UInt_t> > *childrenIndices; + std::vector<std::string> *m_name; + std::vector<std::string> *m_inputstream; + std::vector<std::string> *m_outputstream; + std::vector<std::string> *m_description; + std::vector<std::string> *m_logic; + std::vector<ULong_t> *m_nAcceptedEvents; + std::vector<Double_t> *m_nWeightedAcceptedEvents; + std::vector<Int_t> *m_isComplete; + std::vector<Int_t> *m_cycle; + std::vector<Int_t> *m_parentIndex; + std::vector<Int_t> *m_nbChildren; + std::vector< std::vector<UInt_t> > *m_childrenIndices; }; #endif // FILL_EBC_FROM_FLAT_H diff --git a/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx b/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx index eb988163f00f1ef946a864c0b96095c7672b9a8b..383b21496955793eb2ad8fc3668f6eb39eee37b9 100644 --- a/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx +++ b/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx @@ -3,6 +3,7 @@ #include "EventBookkeeperTools/myCppFilterTest.h" #include "../SkimDecisionMultiFilter.h" #include "../CutFlowSvc.h" +#include "EventBookkeeperTools/BookkeeperTool.h" #include "../EventSelectorCounterTool.h" #include "../EventCounterAlg.h" @@ -10,6 +11,7 @@ DECLARE_ALGORITHM_FACTORY( myCppFilterTest ) DECLARE_ALGORITHM_FACTORY( SkimDecisionMultiFilter ) DECLARE_ALGORITHM_FACTORY( EventCounterAlg ) DECLARE_TOOL_FACTORY( EventSelectorCounterTool ) +DECLARE_TOOL_FACTORY( BookkeeperTool ) DECLARE_SERVICE_FACTORY( CutFlowSvc ) DECLARE_FACTORY_ENTRIES(EventBookkeeperTools) { @@ -17,5 +19,6 @@ DECLARE_FACTORY_ENTRIES(EventBookkeeperTools) { DECLARE_ALGORITHM( SkimDecisionMultiFilter ); DECLARE_ALGORITHM( EventCounterAlg ); DECLARE_ALGTOOL( EventSelectorCounterTool ); + DECLARE_ALGTOOL( BookkeeperTool ); DECLARE_SERVICE( CutFlowSvc ); } diff --git a/Event/EventBookkeeperTools/src/myCppFilterTest.cxx b/Event/EventBookkeeperTools/src/myCppFilterTest.cxx index 2cd9f7110e62da1575ae477161fc06c28e36b4e5..d2865df906cda093ef1e2c17ec2b0d3eae67269a 100644 --- a/Event/EventBookkeeperTools/src/myCppFilterTest.cxx +++ b/Event/EventBookkeeperTools/src/myCppFilterTest.cxx @@ -19,6 +19,9 @@ myCppFilterTest::myCppFilterTest(const std::string& name, ISvcLocator* pSvcLocator) : // ***************************************************** AthFilterAlgorithm(name, pSvcLocator), + m_filterCutID(), + m_cut1ID(), + m_cut2ID(), m_cut1(0), m_cut2(0) {