ATLAS Offline Software
Loading...
Searching...
No Matches
xAODWriterAlg.cxx
Go to the documentation of this file.
1//
2// Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3//
4
5// System include(s):
6#include <regex>
7
8// ROOT include(s):
9#include <TClass.h>
10#include <TFile.h>
11
12// Core include(s):
14#include "EventLoop/Worker.h"
16
17
18// Local include(s):
20
21namespace CP {
22
24
25 // Make sure that the xAOD::TEvent object managed by EventLoop is the
26 // "active" one.
27 evtStore()->event()->setActive();
28
29 // Set up the systematics list.
30 ATH_CHECK( m_systematicsList.initialize() );
31
32 // Access the file of the output stream.
33 TFile* ofile = wk()->getOutputFile( m_outputStreamName );
34 if( ! ofile ) {
35 ATH_MSG_FATAL( "Couldn't access output file for stream \""
36 << m_outputStreamName << "\"" );
37 return StatusCode::FAILURE;
38 }
39
40 // Write to this output file.
41 m_event = std::make_unique<xAOD::TEvent>();
42 ANA_CHECK( m_event->writeTo( ofile ) );
43
44 // Reset the internal flag(s).
46
47 // Return gracefully.
48 return StatusCode::SUCCESS;
49 }
50
52
53 // If this is the first event, figure out which objects can actually be
54 // written out.
55 if( ! m_itemListInitialized ) {
56 ANA_CHECK( setup() );
58 }
59
60 // Write all objects to the output file.
61 xAOD::TEvent* event = dynamic_cast<xAOD::TEvent*>(evtStore()->event());
62 if (event == nullptr) {
63 ATH_MSG_FATAL( "event pointer is not of TEvent type - writing is not yet implemented for RNTuple" );
64 return StatusCode::FAILURE;
65 }
66 for( const Item& item : m_writtenItemList ) {
67
68 // Get the object. See the description in @c xAOD::TEvent::retrieve
69 // (the const version) for an explanation of this implementation.
70 static const bool SILENT = true;
71 static const bool METADATA = false;
72 const void* obj = event->getOutputObject( item.name, *( item.type ),
73 METADATA );
74 if( ! obj ) {
75 obj = event->getInputObject( item.name, *( item.type ), SILENT,
76 METADATA );
77 } else {
78 event->getInputObject( item.name, *( item.type ), SILENT,
79 METADATA );
80 }
81
82 // Check that we succeeded.
83 if( ! obj ) {
84 ATH_MSG_FATAL( "Couldn't retrieve object \"" << item.name << "\"" );
85 return StatusCode::FAILURE;
86 }
87
88 // Record it to the output for the current event.
89 static constexpr bool OVERWRITE = false;
90 static constexpr bool IS_OWNER = true;
91 ANA_CHECK( m_event->record( const_cast< void* >( obj ), item.typeName,
92 item.name, OVERWRITE, METADATA, IS_OWNER ) );
93 }
94
95 // Write the event.
96 if( m_event->fill() <= 0 ) {
97 ATH_MSG_FATAL( "There was an error writing out the event" );
98 return StatusCode::FAILURE;
99 }
100
101 // Return gracefully.
102 return StatusCode::SUCCESS;
103 }
104
106
107 // Access the file of the output stream.
108 TFile* ofile = wk()->getOutputFile( m_outputStreamName );
109 if( ! ofile ) {
110 ATH_MSG_FATAL( "Couldn't access output file for stream \""
111 << m_outputStreamName << "\"" );
112 return StatusCode::FAILURE;
113 }
114
115 // Finish writing to this output file.
116 ANA_CHECK( m_event->finishWritingTo( ofile ) );
117
118 // Return gracefully.
119 return StatusCode::SUCCESS;
120 }
121
122 StatusCode xAODWriterAlg::setup() {
123
124 // Loop over all of the declared items.
125 for( const std::string& stringItem : m_itemList ) {
126
127 // Interpret the item string.
128 static const std::regex itemRegex( "([^#]+)#([^\\.]+\\.?)(.*)" );
129 std::smatch itemMatch;
130 if( ! std::regex_match( stringItem, itemMatch, itemRegex ) ) {
131 ATH_MSG_FATAL( "Item \"" << stringItem
132 << "\" is not of the form: \"Type#Name\"" );
133 return StatusCode::FAILURE;
134 }
135 ATH_MSG_VERBOSE( "Found item: " << itemMatch[ 1 ] << "#"
136 << itemMatch[ 2 ] << itemMatch[ 3 ] );
137
138 // Consider all systematics. Not usin CP::SysListHandle::foreach, to
139 // be able to exit the for-loop early if necessary.
140 auto sysVector = m_systematicsList.systematicsVector();
141 for( const auto& sys : sysVector ) {
142
143 // Event store key for the object under consideration.
144 std::string key;
145 ANA_CHECK (m_systematicsList.service().makeSystematicsName( key, itemMatch[ 2 ], sys ));
146
147 // Whether or not the object will be available, as long as
148 // variable selection rules were set up for it, let xAOD::TEvent
149 // know about them.
150 if( itemMatch[ 3 ] != "" ) {
151 ATH_MSG_DEBUG( "Calling setAuxItemList( \"" << key << "\""
152 << ", \"" << itemMatch[ 3 ]
153 << "\" )" );
154 m_event->setAuxItemList( key, itemMatch[ 3 ] );
155 }
156
157 // Construct an Item object.
158 Item item;
159 item.name = key;
160 TClass* cl = TClass::GetClass( itemMatch[ 1 ].str().c_str() );
161 if( ! cl ) {
162 ATH_MSG_FATAL( "Type \"" << itemMatch[ 1 ] << "\" not found" );
163 return StatusCode::FAILURE;
164 }
165 item.type = cl->GetTypeInfo();
166 if( ! item.type ) {
167 ATH_MSG_FATAL( "No compiled dictionary found for \""
168 << itemMatch[ 1 ] << "\"" );
169 return StatusCode::FAILURE;
170 }
171 item.typeName = SG::normalizedTypeinfoName( *( item.type ) );
172
173 // Check if the item is available.
174 static const bool SILENT = true;
175 static const bool METADATA = false;
176 xAOD::TEvent* event = dynamic_cast<xAOD::TEvent*>(evtStore()->event());
177 if (event == nullptr) {
178 ATH_MSG_FATAL( "event pointer is not of TEvent type - writing is not yet implemented for RNTuple" );
179 return StatusCode::FAILURE;
180 }
181 if( event->getOutputObject( item.name, *( item.type ), METADATA ) ||
182 event->getInputObject( item.name, *( item.type ), SILENT,
183 METADATA ) ) {
184 m_writtenItemList.push_back( item );
185 ATH_MSG_DEBUG( "Scheduling \"" << itemMatch[ 1 ] << "#"
186 << key << "\" for writing" );
187 }
188
189 // If there was no %SYS% pattern in the object name, stop the loop
190 // over the systematics now.
191 if( key == itemMatch[ 2 ] ) {
192 break;
193 }
194 }
195 }
196
197 // Return gracefully.
198 return StatusCode::SUCCESS;
199 }
200
201} // namespace CP
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
#define ANA_CHECK(EXP)
check whether the given expression was successful
bool m_itemListInitialized
Internal flag.
StatusCode setup()
Function setting up the algorithm while processing the first event.
std::unique_ptr< xAOD::TEvent > m_event
Object to write the output file with.
StatusCode finalize() override
Function finalising the algorithm.
std::vector< Item > m_writtenItemList
Item list being written after the first event.
StatusCode execute() override
Function executing the algorithm.
Gaudi::Property< std::vector< std::string > > m_itemList
Item list to write to the output file.
SysListHandle m_systematicsList
The systematic list to consider during execution.
Gaudi::Property< std::string > m_outputStreamName
Name of the output stream to write to.
StatusCode initialize() override
Function initialising the algorithm.
Tool for accessing xAOD files outside of Athena.
Select isolated Photons, Electrons and Muons.
@ SILENT
don't print anything and return success
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
std::string name
Name of the written object.
const std::type_info * type
Type of the written object.
std::string typeName
Type name of the written object.