The Gaudi Framework
v38r2 (5b3c9e4d)
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/details/BranchWrapper.h
>
16
#include <
GaudiKernel/StdArrayAsProperty.h
>
17
#include <TFile.h>
18
#include <TTree.h>
19
#include <fmt/format.h>
20
#include <gsl/pointers>
21
#include <gsl/span>
22
#include <mutex>
23
#include <numeric>
24
#include <tuple>
25
#include <utility>
26
27
namespace
Gaudi::NTuple
{
28
34
template
<
typename
Signature>
35
struct
WriterMixin
{
36
WriterMixin
() = 0;
// This function has to be implemented with this speialization:
37
// WriterMixin<std::tuple<OUTPUTs...>( const INPUTs&... )>
38
};
39
49
template
<
typename
... OUTPUTs,
typename
... INPUTs>
50
struct
WriterMixin
<
std
::tuple<OUTPUTs...>( const INPUTs&... )> {
51
TTree* m_tree =
nullptr
;
// Pointer to the TTree being written to
52
std::array
<
std::string
,
sizeof
...( OUTPUTs )> m_branchNames;
// Names of the branches to be created
53
mutable
std::vector<details::BranchWrapper>
m_branchWrappers{};
// Container for BranchWrapper objects
54
60
virtual
std::tuple
<OUTPUTs...>
transform
(
const
INPUTs&... inputs )
const
= 0;
61
62
// Initialize the TTree and creates branches
63
void
initTree
(
const
std::unique_ptr<TFile>
& file,
const
gsl::span<
std::string
,
sizeof
...( OUTPUTs )> branchNames,
64
const
Gaudi::Algorithm
& algRef ) {
65
file->cd();
66
m_tree = std::make_unique<TTree>(
"WriterTree"
,
"Tree of Writer Algorithm"
).
release
();
67
if
( !m_tree ) {
68
throw
GaudiException
(
"Failed to create TTree. Ensure sufficient resources and permissions."
, algRef.
name
(),
69
StatusCode::FAILURE
);
70
}
71
m_branchWrappers.reserve( m_branchWrappers.size() +
sizeof
...( OUTPUTs ) );
72
createBranchesForOutputs( branchNames, std::make_index_sequence<
sizeof
...( OUTPUTs )>{}, algRef );
73
}
74
75
// Create branches in the TTree based on the provided names and output data types
76
template
<
std::size_t
... Is>
77
void
createBranchesForOutputs
(
const
gsl::span<
std::string
,
sizeof
...( OUTPUTs )> branchNames,
78
const
std::index_sequence<Is...>,
const
Gaudi::Algorithm
& algRef )
const
{
79
( ...,
80
m_branchWrappers.emplace_back(
81
m_tree,
System::typeinfoName
(
typeid
(
typename
std::tuple_element<Is,
std::tuple<OUTPUTs...>
>::
type
) ),
82
branchNames[Is],
""
, algRef ) );
83
}
84
85
// Fill the TTree with transformed data from the input
86
void
fillTree
(
const
INPUTs&... inputs )
const
{
87
auto
transformedData = transform( inputs... );
88
std::apply(
89
[&](
const
auto
&... elems ) {
90
size_t
index
= 0;
91
( ..., m_branchWrappers[
index
++].setDataPtr(
const_cast<
void
*
>
(
static_cast<
const
void
*
>
( &elems ) ) ) );
92
},
93
transformedData );
94
m_tree->Fill();
95
}
96
97
// Write the TTree to the associated ROOT file
98
void
writeTree
(
const
std::unique_ptr<TFile>
& file,
const
Gaudi::Algorithm
& algRef ) {
99
file->cd();
100
if
( m_tree->Write() <= 0 ) {
101
throw
GaudiException
(
"Failed to write TTree to ROOT file."
, algRef.
name
(),
StatusCode::FAILURE
);
102
}
103
m_tree =
nullptr
;
104
algRef.info() <<
"TTree written to TFile."
<<
endmsg
;
105
}
106
107
virtual
~WriterMixin
() =
default
;
108
};
109
115
template
<
typename
Signature,
typename
Traits_ = Gaudi::Functional::Traits::BaseClass_t<Gaudi::Algorithm>>
116
struct
Writer
{
117
Writer
() = 0;
// If you wish to not provide any transformation for your data, please use the NTuple::GenericWriter
118
// algorithm
119
};
120
129
template
<
typename
... OUTPUTs,
typename
... INPUTs,
typename
Traits_>
130
struct
Writer
<
std
::tuple<OUTPUTs...>( const INPUTs&... ), Traits_>
131
:
Gaudi::Functional::Consumer
<void( const INPUTs&... ), Traits_>,
132
WriterMixin
<std::tuple<OUTPUTs...>( const INPUTs&... )> {
133
using
Consumer_t
=
Gaudi::Functional::Consumer
<void(
const
INPUTs&... ), Traits_>;
134
using
Consumer_t::Consumer_t;
135
136
Gaudi::Property<std::string>
m_filename{
this
,
"TreeFilename"
,
"ntuple_writer_ts_tree.root"
,
137
"Filename for the TTree."
};
// Filename for the TTree
138
Gaudi::Property
<
std::array
<
std::string
,
sizeof
...( OUTPUTs )>> m_branchNames{
139
this
,
"BranchNames"
, {},
"Names of the tree branches."
};
// Names for the tree branches
140
std::unique_ptr<TFile>
m_file =
nullptr
;
// Pointer to the ROOT file
141
mutable
std::mutex
m_mtx
;
// Mutex for thread-safe operations
142
143
// Initialize the algorithm, set up the ROOT file and a TTree branch for each input location
144
virtual
StatusCode
initialize
()
override
{
145
return
Consumer_t::initialize().
andThen
( [
this
]() {
146
m_file = std::make_unique<TFile>( m_filename.value().c_str(),
"RECREATE"
);
147
if
( !m_file || m_file->IsZombie() ) {
148
throw
GaudiException
(
149
fmt::format
(
"Failed to open file '{}'. Check file path and permissions."
, m_filename.value() ),
150
this->name(),
StatusCode::FAILURE
);
151
}
152
153
this->initTree( m_file, m_branchNames.value(), *
this
);
154
155
return
StatusCode::SUCCESS
;
156
} );
157
}
158
159
// Execute the algorithm for each event, retrieving data from the event store and writing it to the TTree
160
void
operator()
(
const
INPUTs&...
args
)
const override
{
161
std::lock_guard<std::mutex>
lock( m_mtx );
162
this->fillTree(
args
... );
163
}
164
165
// Finalize the algorithm by writing the TTree to the file and closing it
166
virtual
StatusCode
finalize
()
override
{
167
this->writeTree( m_file, *
this
);
168
return
Consumer_t::finalize();
169
}
170
};
171
}
// namespace Gaudi::NTuple
std::string
STL class.
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:144
std::vector
STL class.
StdArrayAsProperty.h
GaudiException
Definition:
GaudiException.h:31
std::lock_guard
STL class.
std::unique_ptr::release
T release(T... args)
Gaudi::NTuple::WriterMixin::WriterMixin
WriterMixin()=0
std::tuple
Gaudi::NTuple::WriterMixin< std::tuple< OUTPUTs... >(const INPUTs &...)>::writeTree
void writeTree(const std::unique_ptr< TFile > &file, const Gaudi::Algorithm &algRef)
Definition:
Writer.h:98
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:313
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:160
Gaudi::NTuple::WriterMixin< std::tuple< OUTPUTs... >(const INPUTs &...)>::initTree
void initTree(const std::unique_ptr< TFile > &file, const gsl::span< std::string, sizeof...(OUTPUTs)> branchNames, const Gaudi::Algorithm &algRef)
Definition:
Writer.h:63
StatusCode
Definition:
StatusCode.h:65
Gaudi::Algorithm
Base class from which all concrete algorithm classes should be derived.
Definition:
Algorithm.h:90
Gaudi::NTuple
Definition:
Writer.h:27
std::array
STL class.
Algorithm.h
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition:
MsgStream.cpp:119
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:141
Gaudi::NTuple::Writer::Writer
Writer()=0
gaudirun.type
type
Definition:
gaudirun.py:160
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:166
Consumer.h
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:77
std::mutex
STL class.
Gaudi::NTuple::WriterMixin
Base template for NTuple::WriterMixin. Actual specializations of this template provide the functional...
Definition:
Writer.h:35
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.
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:86
Gaudi::NTuple::Writer
Base template for NTuple::Writer. Actual specializations of this template provide the functionality.
Definition:
Writer.h:116
std::unique_ptr< TFile >
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 Thu May 16 2024 12:46:15 for The Gaudi Framework by
1.8.18