The Gaudi Framework
v39r0 (5b8b5eda)
Writer.h
Go to the documentation of this file.
1
/***********************************************************************************\
2
* (c) Copyright 2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3
* *
4
* This software is distributed under the terms of the Apache version 2 licence, *
5
* copied verbatim in the file "LICENSE". *
6
* *
7
* In applying this licence, CERN does not waive the privileges and immunities *
8
* granted to it by virtue of its status as an Intergovernmental Organization *
9
* or submit itself to any jurisdiction. *
10
\***********************************************************************************/
11
#pragma once
12
13
#include <
Gaudi/Algorithm.h
>
14
#include <
Gaudi/Functional/Consumer.h
>
15
#include <
Gaudi/Interfaces/IFileSvc.h
>
16
#include <
Gaudi/details/BranchWrapper.h
>
17
#include <
GaudiKernel/StdArrayAsProperty.h
>
18
#include <TFile.h>
19
#include <TTree.h>
20
#include <fmt/format.h>
21
#include <gsl/pointers>
22
#include <gsl/span>
23
#include <mutex>
24
#include <numeric>
25
#include <tuple>
26
#include <utility>
27
28
namespace
Gaudi::NTuple
{
29
35
template
<
typename
Signature>
36
struct
WriterMixin
{
37
WriterMixin
() = 0;
// This function has to be implemented with this speialization:
38
// WriterMixin<std::tuple<OUTPUTs...>( const INPUTs&... )>
39
};
40
50
template
<
typename
... OUTPUTs,
typename
... INPUTs>
51
struct
WriterMixin
<
std
::tuple<OUTPUTs...>( const INPUTs&... )> {
52
TTree* m_tree =
nullptr
;
// Pointer to the TTree being written to
53
std::array
<
std::string
,
sizeof
...( OUTPUTs )> m_branchNames;
// Names of the branches to be created
54
mutable
std::vector<details::BranchWrapper>
m_branchWrappers{};
// Container for BranchWrapper objects
55
61
virtual
std::tuple
<OUTPUTs...>
transform
(
const
INPUTs&... inputs )
const
= 0;
62
63
// Initialize the TTree and creates branches
64
void
initTree
(
const
std::shared_ptr<TFile>
& file,
const
gsl::span<
std::string
,
sizeof
...( OUTPUTs )> branchNames,
65
const
Gaudi::Algorithm
& algRef ) {
66
file->cd();
67
m_tree = std::make_unique<TTree>(
"WriterTree"
,
"Tree of Writer Algorithm"
).release();
68
m_branchWrappers.reserve( m_branchWrappers.size() +
sizeof
...( OUTPUTs ) );
69
createBranchesForOutputs( branchNames, std::make_index_sequence<
sizeof
...( OUTPUTs )>{}, algRef );
70
}
71
72
// Create branches in the TTree based on the provided names and output data types
73
template
<
std::size_t
... Is>
74
void
createBranchesForOutputs
(
const
gsl::span<
std::string
,
sizeof
...( OUTPUTs )> branchNames,
75
const
std::index_sequence<Is...>,
const
Gaudi::Algorithm
& algRef )
const
{
76
( ..., m_branchWrappers.emplace_back(
77
m_tree,
System::typeinfoName
(
typeid
( std::tuple_element_t<Is,
std::tuple<OUTPUTs...>
> ) ),
78
branchNames[Is],
""
, algRef ) );
79
}
80
81
// Fill the TTree with transformed data from the input
82
void
fillTree
(
const
INPUTs&... inputs )
const
{
83
auto
transformedData = transform( inputs... );
84
std::apply(
85
[&](
const
auto
&... elems ) {
86
size_t
index
= 0;
87
( ..., m_branchWrappers[
index
++].setDataPtr(
const_cast<
void
*
>
(
static_cast<
const
void
*
>
( &elems ) ) ) );
88
},
89
transformedData );
90
m_tree->Fill();
91
}
92
93
// Write the TTree to the associated ROOT file
94
void
writeTree
(
const
std::shared_ptr<TFile>
& file,
const
Gaudi::Algorithm
& algRef ) {
95
file->cd();
96
if
( m_tree->Write() <= 0 ) {
97
throw
GaudiException
(
"Failed to write TTree to ROOT file."
, algRef.
name
(),
StatusCode::FAILURE
);
98
}
99
m_tree =
nullptr
;
100
algRef.info() <<
"TTree written to TFile."
<<
endmsg
;
101
}
102
103
virtual
~WriterMixin
() =
default
;
104
};
105
111
template
<
typename
Signature,
typename
Traits_ = Gaudi::Functional::Traits::BaseClass_t<Gaudi::Algorithm>>
112
struct
Writer
{
113
Writer
() = 0;
// If you wish to not provide any transformation for your data, please use the NTuple::GenericWriter
114
// algorithm
115
};
116
125
template
<
typename
... OUTPUTs,
typename
... INPUTs,
typename
Traits_>
126
struct
Writer
<
std
::tuple<OUTPUTs...>( const INPUTs&... ), Traits_>
127
:
Gaudi::Functional::Consumer
<void( const INPUTs&... ), Traits_>,
128
WriterMixin
<std::tuple<OUTPUTs...>( const INPUTs&... )> {
129
using
Consumer_t
=
Gaudi::Functional::Consumer
<void(
const
INPUTs&... ), Traits_>;
130
using
Consumer_t::Consumer_t;
131
132
Gaudi::Property<std::string>
m_fileId{
this
,
"OutputFile"
,
"NTuple"
,
"Identifier for the TFile to write to."
};
133
Gaudi::Property
<
std::array
<
std::string
,
sizeof
...( OUTPUTs )>> m_branchNames{
134
this
,
"BranchNames"
, {},
"Names of the tree branches."
};
// Names for the tree branches
135
std::shared_ptr<TFile>
m_file =
nullptr
;
// Pointer to the ROOT file
136
Gaudi::Interfaces::IFileSvc
*
m_fileSvc
;
137
mutable
std::mutex
m_mtx
;
// Mutex for thread-safe operations
138
139
// Initialize the algorithm, set up the ROOT file and a TTree branch for each input location
140
virtual
StatusCode
initialize
()
override
{
141
return
Consumer_t::initialize().
andThen
( [
this
]() {
142
m_fileSvc = this->
template
service<Gaudi::Interfaces::IFileSvc>(
"FileSvc"
);
143
if
( !m_fileSvc ) {
144
this->error() <<
"Failed to retrieve FileSvc."
<<
endmsg
;
145
return
StatusCode::FAILURE
;
146
}
147
148
m_file = m_fileSvc->
getFile
( m_fileId );
149
if
( !m_file ) {
150
this->error() <<
"Failed to retrieve TFile."
<<
endmsg
;
151
return
StatusCode::FAILURE
;
152
}
153
154
this->initTree( m_file, m_branchNames.value(), *
this
);
155
156
return
StatusCode::SUCCESS
;
157
} );
158
}
159
160
// Execute the algorithm for each event, retrieving data from the event store and writing it to the TTree
161
void
operator()
(
const
INPUTs&...
args
)
const override
{
162
std::lock_guard<std::mutex>
lock( m_mtx );
163
this->fillTree(
args
... );
164
}
165
166
// Finalize the algorithm by writing the TTree to the file and closing it
167
virtual
StatusCode
finalize
()
override
{
168
this->writeTree( m_file, *
this
);
169
return
Consumer_t::finalize();
170
}
171
};
172
}
// namespace Gaudi::NTuple
Gaudi::NTuple::Writer< std::tuple< OUTPUTs... >(const INPUTs &...), Traits_ >::m_fileSvc
Gaudi::Interfaces::IFileSvc * m_fileSvc
Definition:
Writer.h:136
std::string
STL class.
std::shared_ptr< TFile >
StatusCode::andThen
StatusCode andThen(F &&f, ARGS &&... args) const
Chain code blocks making the execution conditional a success result.
Definition:
StatusCode.h:163
Gaudi::Algorithm::name
const std::string & name() const override
The identifying name of the algorithm object.
Definition:
Algorithm.cpp:528
Gaudi::NTuple::Writer< std::tuple< OUTPUTs... >(const INPUTs &...), Traits_ >::initialize
virtual StatusCode initialize() override
Definition:
Writer.h:140
std::vector
STL class.
StdArrayAsProperty.h
GaudiException
Definition:
GaudiException.h:31
std::lock_guard
STL class.
Gaudi::NTuple::WriterMixin::WriterMixin
WriterMixin()=0
std::tuple
Gaudi::NTuple::WriterMixin< std::tuple< OUTPUTs... >(const INPUTs &...)>::~WriterMixin
virtual ~WriterMixin()=default
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition:
System.cpp:315
Gaudi::NTuple::WriterMixin< std::tuple< OUTPUTs... >(const INPUTs &...)>::writeTree
void writeTree(const std::shared_ptr< TFile > &file, const Gaudi::Algorithm &algRef)
Definition:
Writer.h:94
Gaudi::Functional::details::Consumer
Definition:
Consumer.h:23
Gaudi::NTuple::Writer< std::tuple< OUTPUTs... >(const INPUTs &...), Traits_ >::operator()
void operator()(const INPUTs &... args) const override
Definition:
Writer.h:161
StatusCode
Definition:
StatusCode.h:65
Consumer.h
IFileSvc.h
Gaudi::Algorithm
Base class from which all concrete algorithm classes should be derived.
Definition:
Algorithm.h:90
Gaudi::NTuple
Definition:
Writer.h:28
std::array
STL class.
Algorithm.h
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition:
MsgStream.h:203
Gaudi::NTuple::Writer< std::tuple< OUTPUTs... >(const INPUTs &...), Traits_ >::m_mtx
std::mutex m_mtx
Definition:
Writer.h:137
Gaudi::NTuple::Writer::Writer
Writer()=0
Gaudi::NTuple::WriterMixin< std::tuple< OUTPUTs... >(const INPUTs &...)>::initTree
void initTree(const std::shared_ptr< TFile > &file, const gsl::span< std::string, sizeof...(OUTPUTs)> branchNames, const Gaudi::Algorithm &algRef)
Definition:
Writer.h:64
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition:
StatusCode.h:100
gaudirun.args
args
Definition:
gaudirun.py:336
Gaudi::NTuple::Writer< std::tuple< OUTPUTs... >(const INPUTs &...), Traits_ >::finalize
virtual StatusCode finalize() override
Definition:
Writer.h:167
BranchWrapper.h
std
STL namespace.
Gaudi::NTuple::WriterMixin< std::tuple< OUTPUTs... >(const INPUTs &...)>::createBranchesForOutputs
void createBranchesForOutputs(const gsl::span< std::string, sizeof...(OUTPUTs)> branchNames, const std::index_sequence< Is... >, const Gaudi::Algorithm &algRef) const
Definition:
Writer.h:74
Gaudi::Interfaces::IFileSvc::getFile
virtual std::shared_ptr< TFile > getFile(const std::string &identifier)=0
std::mutex
STL class.
Gaudi::NTuple::WriterMixin
Base template for NTuple::WriterMixin. Actual specializations of this template provide the functional...
Definition:
Writer.h:36
std::size_t
Gaudi::NTuple::WriterMixin< std::tuple< OUTPUTs... >(const INPUTs &...)>::transform
virtual std::tuple< OUTPUTs... > transform(const INPUTs &... inputs) const =0
Transform input data to the desired output format.
Gaudi::Interfaces::IFileSvc
Interface for a component that manages file access within Gaudi applications.
Definition:
IFileSvc.h:27
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition:
StatusCode.h:101
Gaudi::NTuple::WriterMixin< std::tuple< OUTPUTs... >(const INPUTs &...)>::fillTree
void fillTree(const INPUTs &... inputs) const
Definition:
Writer.h:82
Gaudi::NTuple::Writer
Base template for NTuple::Writer. Actual specializations of this template provide the functionality.
Definition:
Writer.h:112
Gaudi::Property< std::string >
Gaudi::ParticleProperties::index
size_t index(const Gaudi::ParticleProperty *property, const Gaudi::Interfaces::IParticlePropertySvc *service)
helper utility for mapping of Gaudi::ParticleProperty object into non-negative integral sequential id...
Definition:
IParticlePropertySvc.cpp:39
GaudiUtils
include
Gaudi
NTuple
Writer.h
Generated on Mon Sep 23 2024 11:49:36 for The Gaudi Framework by
1.8.18