Commit ae8cb4d3 authored by Attila Krasznahorkay's avatar Attila Krasznahorkay
Browse files

Created CP::xAODWriterAlg, and the StandaloneAnalysisAlgorithms package.

Since the algorithm needs more detailed access to the internals of EventLoop / xAODRootAccess than what EL::AnaAlgorithm provides, it seemed best to just put it into a separate package.
Had to make the algorithm a friend of xAOD::TEvent.


Former-commit-id: b251b04119103ac93a7104c20845446254e1a79b
parent 87307920
......@@ -43,6 +43,9 @@ namespace xAODPrivate {
class THolderBucket;
class TLoader;
}
namespace CP {
class xAODWriterAlg;
}
namespace xAOD {
......@@ -83,6 +86,7 @@ namespace xAOD {
friend class xAOD::TTreeMgr;
friend class xAODPrivate::THolderBucket;
friend class xAODPrivate::TLoader;
friend class CP::xAODWriterAlg;
public:
/// Auxiliary store "mode"
......
# Set the name of the package:
atlas_subdir( StandaloneAnalysisAlgorithms )
# Check that this is a standalone release:
if( NOT XAOD_STANDALONE )
message( WARNING "This package is only meant for standalone releases" )
return()
endif()
# Set the package's dependencies:
atlas_depends_on_subdirs(
PUBLIC
Control/xAODRootAccess
PhysicsAnalysis/Algorithms/SystematicsHandles
PhysicsAnalysis/D3PDTools/AnaAlgorithm
PRIVATE
Control/AthContainers
PhysicsAnalysis/D3PDTools/EventLoop )
# External(s):
find_package( ROOT COMPONENTS Core RIO )
# Set up the main library:
atlas_add_library( StandaloneAnalysisAlgorithmsLib
StandaloneAnalysisAlgorithms/*.h Root/*.cxx
PUBLIC_HEADERS StandaloneAnalysisAlgorithms
LINK_LIBRARIES xAODRootAccess AnaAlgorithmLib
PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} AthContainers EventLoop )
# Set up a dictionary:
atlas_add_dictionary( StandaloneAnalysisAlgorithmsDict
StandaloneAnalysisAlgorithms/StandaloneAnalysisAlgorithmsDict.h
StandaloneAnalysisAlgorithms/selection.xml
LINK_LIBRARIES StandaloneAnalysisAlgorithmsLib )
# Standalone Analysis Algorithms
This package collects code/algorithms that are only relevant for standalone
analysis releases. So they wouldn't need to be compiled in Athena based
releases.
Current algorithm(s) in the package:
- [CP::xAODWriterAlg](StandaloneAnalysisAlgorithms/xAODWriterAlg.h):
Algorithm for writing mini-xAOD files as the output of analysis jobs.
//
// Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
//
// System include(s):
#include <regex>
// ROOT include(s):
#include <TClass.h>
#include <TFile.h>
// Core include(s):
#include "AthContainers/normalizedTypeinfoName.h"
#include "EventLoop/Worker.h"
#include "SystematicsHandles/Helpers.h"
// Local include(s):
#include "StandaloneAnalysisAlgorithms/xAODWriterAlg.h"
namespace CP {
xAODWriterAlg::xAODWriterAlg( const std::string& name, ISvcLocator* svcLoc )
: EL::AnaAlgorithm( name, svcLoc ) {
// Declare the algorithm's properties.
declareProperty( "OutputStreamName", m_outputStreamName = "ANALYSIS",
"Stream name of the output file to use" );
declareProperty( "ItemList", m_itemList,
"Objects to write to the output file" );
declareProperty( "BasketSize", m_basketSize = 32000,
"(Starter) Basket size for the created branches" );
declareProperty( "SplitLevel", m_splitLevel = 0,
"Split level for the created branches" );
}
StatusCode xAODWriterAlg::initialize() {
// Set up the systematics list.
ATH_CHECK( m_systematicsList.initialize() );
// Access the file of the output stream.
TFile* ofile = wk()->getOutputFile( m_outputStreamName );
if( ! ofile ) {
ATH_MSG_FATAL( "Couldn't access output file for stream \""
<< m_outputStreamName << "\"" );
return StatusCode::FAILURE;
}
// Write to this output file.
ANA_CHECK( m_event.writeTo( ofile ) );
// Reset the internal flag(s).
m_itemListInitialized = false;
// Return gracefully.
return StatusCode::SUCCESS;
}
StatusCode xAODWriterAlg::execute() {
// If this is the first event, figure out which objects can actually be
// written out.
if( ! m_itemListInitialized ) {
ANA_CHECK( setup() );
m_itemListInitialized = true;
}
// Write all objects to the output file.
xAOD::TEvent* event = evtStore()->event();
for( const Item& item : m_writtenItemList ) {
// Get the object. See the description in @c xAOD::TEvent::retrieve
// (the const version) for an explanation of this implementation.
static const bool SILENT = true;
static const bool METADATA = false;
const void* obj = event->getOutputObject( item.name, *( item.type ),
METADATA );
if( ! obj ) {
obj = event->getInputObject( item.name, *( item.type ), SILENT,
METADATA );
} else {
event->getInputObject( item.name, *( item.type ), SILENT,
METADATA );
}
// Check that we succeeded.
if( ! obj ) {
ATH_MSG_FATAL( "Couldn't retrieve object \"" << item.name << "\"" );
return StatusCode::FAILURE;
}
// Record it to the output for the current event.
ANA_CHECK( m_event.record( const_cast< void* >( obj ),
SG::normalizedTypeinfoName( *( item.type ) ),
item.name, m_basketSize, m_splitLevel ) );
}
// Write the event.
if( m_event.fill() <= 0 ) {
ATH_MSG_FATAL( "There was an error writing out the event" );
return StatusCode::FAILURE;
}
// Return gracefully.
return StatusCode::SUCCESS;
}
StatusCode xAODWriterAlg::finalize() {
// Access the file of the output stream.
TFile* ofile = wk()->getOutputFile( m_outputStreamName );
if( ! ofile ) {
ATH_MSG_FATAL( "Couldn't access output file for stream \""
<< m_outputStreamName << "\"" );
return StatusCode::FAILURE;
}
// Finish writing to this output file.
ANA_CHECK( m_event.finishWritingTo( ofile ) );
// Return gracefully.
return StatusCode::SUCCESS;
}
StatusCode xAODWriterAlg::setup() {
// Loop over all of the declared items.
for( const std::string& stringItem : m_itemList ) {
// Interpret the item string.
static const std::regex itemRegex( "([^#]+)#([^\\.]+\\.?)(.*)" );
std::smatch itemMatch;
if( ! std::regex_match( stringItem, itemMatch, itemRegex ) ) {
ATH_MSG_FATAL( "Item \"" << stringItem
<< "\" is not of the form: \"Type#Name\"" );
return StatusCode::FAILURE;
}
ATH_MSG_VERBOSE( "Found item: " << itemMatch[ 1 ] << "#"
<< itemMatch[ 2 ] << itemMatch[ 3 ] );
// Consider all systematics. Not usin CP::SysListHandle::foreach, to
// be able to exit the for-loop early if necessary.
auto sysVector = m_systematicsList.systematicsVector();
for( const auto& sys : sysVector ) {
// Event store key for the object under consideration.
const std::string key = makeSystematicsName( itemMatch[ 2 ], sys );
// Whether or not the object will be available, as long as
// variable selection rules were set up for it, let xAOD::TEvent
// know about them.
if( itemMatch[ 3 ] != "" ) {
ATH_MSG_DEBUG( "Calling setAuxItemList( \"" << key << "\""
<< ", \"" << itemMatch[ 3 ]
<< "\" )" );
m_event.setAuxItemList( key, itemMatch[ 3 ] );
}
// Construct an Item object.
Item item;
item.name = key;
TClass* cl = TClass::GetClass( itemMatch[ 1 ].str().c_str() );
if( ! cl ) {
ATH_MSG_FATAL( "Type \"" << itemMatch[ 1 ] << "\" not found" );
return StatusCode::FAILURE;
}
item.type = cl->GetTypeInfo();
if( ! item.type ) {
ATH_MSG_FATAL( "No compiled dictionary found for \""
<< itemMatch[ 1 ] << "\"" );
return StatusCode::FAILURE;
}
// Check if the item is available.
static const bool SILENT = true;
static const bool METADATA = false;
xAOD::TEvent* event = evtStore()->event();
if( event->getOutputObject( item.name, *( item.type ), METADATA ) ||
event->getInputObject( item.name, *( item.type ), SILENT,
METADATA ) ) {
m_writtenItemList.push_back( item );
ATH_MSG_DEBUG( "Scheduling \"" << itemMatch[ 1 ] << "#"
<< key << "\" for writing" );
}
// If there was no %SYS% pattern in the object name, stop the loop
// over the systematics now.
if( key == itemMatch[ 2 ] ) {
break;
}
}
}
// Return gracefully.
return StatusCode::SUCCESS;
}
} // namespace CP
// Dear emacs, this is -*- c++ -*-
//
// Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
//
#ifndef STANDALONEANALYSISALGORITHMS_STANDALONEANALYSISALGORITHMSDICT_H
#define STANDALONEANALYSISALGORITHMS_STANDALONEANALYSISALGORITHMSDICT_H
// Local include(s):
#include "StandaloneAnalysisAlgorithms/xAODWriterAlg.h"
#endif // STANDALONEANALYSISALGORITHMS_STANDALONEANALYSISALGORITHMSDICT_H
<!-- Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration -->
<lcgdict>
<!-- Algorithm(s): -->
<class name="CP::xAODWriterAlg" />
</lcgdict>
// Dear emacs, this is -*- c++ -*-
//
// Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
//
#ifndef STANDALONEANALYSISALGORITHMS_XAODWRITERALG_H
#define STANDALONEANALYSISALGORITHMS_XAODWRITERALG_H
// System include(s):
#include <string>
#include <vector>
#include <typeinfo>
// Core include(s):
#include "AnaAlgorithm/AnaAlgorithm.h"
#include "SystematicsHandles/SysListHandle.h"
#include "xAODRootAccess/TEvent.h"
namespace CP {
/// Algorithm writing an xAOD output file
///
/// This algorithm is meant to be used to write mini-xAOD output files from
/// analysis jobs. Similar to how such a file could be written using an
/// Athena job.
///
/// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
///
class xAODWriterAlg final : public EL::AnaAlgorithm {
public:
/// Algorithm constructor
xAODWriterAlg( const std::string& name, ISvcLocator* svcLoc );
/// @name Function(s) inherited from @c EL::AnaAlgorithm
/// @{
/// Function initialising the algorithm
StatusCode initialize() override;
/// Function executing the algorithm
StatusCode execute() override;
/// Function finalising the algorithm
StatusCode finalize() override;
/// @}
private:
/// Function setting up the algorithm while processing the first event
StatusCode setup();
/// @name Algorithm properties
/// @{
/// Name of the output stream to write to
std::string m_outputStreamName;
/// Item list to write to the output file
std::vector< std::string > m_itemList;
/// (Starter) Basket size for the created branches
int m_basketSize;
/// Split level for the created branches
int m_splitLevel;
/// @}
/// Helper struct
struct Item {
/// Name of the written object
std::string name;
/// Type of the written object
const std::type_info* type;
}; // struct Item
/// Object to write the output file with
xAOD::TEvent m_event;
/// Internal flag
bool m_itemListInitialized = false;
/// Item list being written after the first event
std::vector< Item > m_writtenItemList;
/// The systematic list to consider during execution
SysListHandle m_systematicsList{ this };
}; // class xAODWriterAlg
} // namespace CP
#endif // STANDALONEANALYSISALGORITHMS_XAODWRITERALG_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment