ATLAS Offline Software
Loading...
Searching...
No Matches
RootReaderD3PD_v1.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6// STL/system include(s):
7#include <iostream>
8#include <fstream>
9#include <ctime>
10
11// Gaudi/Athena include(s):
12#include "GaudiKernel/System.h"
14
15// Local include(s):
16#include "RootReaderD3PD_v1.h"
17
19static const char* const CODE_COMMENT =
20 "// Dear emacs, this is -*- c++ -*-\n"
21 "// -------------------------------------------------------------\n"
22 "// Code produced by D3PDMakerReader\n"
23 "//\n"
24 "// author: Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>\n"
25 "// -------------------------------------------------------------";
26
28static const char* const CODE_NAMESPACE = "D3PDReader";
29
30namespace D3PD {
31
35
44 StatusCode RootReaderD3PD_v1::createReader( const std::string& classname,
45 const std::string& dir ) const {
46
47 //
48 // Create the source files:
49 //
50 CHECK( writeHeader( classname, dir ) );
51 CHECK( writeSource( classname, dir ) );
52
53 return StatusCode::SUCCESS;
54 }
55
56 StatusCode RootReaderD3PD_v1::writeHeader( const std::string& classname,
57 const std::string& dir ) const {
58
59 // Let everyone know what we're doing:
60 REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "RootReaderD3PD_v1" )
61 << "Generating file: " << dir << "/" << classname << ".h";
62
63 // Open the header file (overwriting a possibly existing file):
64 std::fstream header( ( dir + "/" + classname + ".h" ).c_str(),
65 std::fstream::out | std::fstream::trunc );
66
67 // Write a header for the file:
68 header << CODE_COMMENT << std::endl;
69 header << "#ifndef D3PDREADER_" << classname << "_H" << std::endl;
70 header << "#define D3PDREADER_" << classname << "_H" << std::endl << std::endl;
71
72 // Include some STL headers if they're needed:
73 addSTLHeader( header, "vector" );
74 addSTLHeader( header, "map" );
75 addSTLHeader( header, "string" );
76 header << std::endl;
77
78 // ROOT include(s):
79 header << "#include <TNamed.h>" << std::endl;
80 header << "#include <TString.h>" << std::endl << std::endl;
81
82 // Forward declaration(s):
83 header << "class TTree;" << std::endl;
84 header << "class TBranch;" << std::endl << std::endl;
85
86 //
87 // Declare the class itself:
88 //
89 header << "namespace " << CODE_NAMESPACE << " {" << std::endl << std::endl;
90 header << " /**" << std::endl;
91 header << " * Code generated by RootD3PDReader_v1 on:" << std::endl;
92 header << " * host = " << System::hostName() << std::endl;
93 header << " * OS = " << System::osName() << " / " << System::osVersion()
94 << std::endl;
95 header << " * user = " << System::accountName() << std::endl;
96 time_t rawtime = time( NULL );
97 char buf[26];
98 header << " * time = " << ctime_r( &rawtime, buf );
99 header << " */" << std::endl;
100 header << " class " << classname << " : public TNamed {" << std::endl << std::endl;
101 header << " public:" << std::endl;
102
103 //
104 // Declare the constructor:
105 //
106 header << " /// Constructor specifying the needed parameters" << std::endl;
107 header << " " << classname << "( Long64_t* master, const char* prefix = \""
108 << m_metadata.prefix() << "\" );" << std::endl << std::endl;
109
110 //
111 // Declare some functions:
112 //
113 header << " /// Get the currently configured prefix value" << std::endl;
114 header << " const char* getPrefix() const;" << std::endl;
115 header << " /// Set the prefix to the ntuple variables" << std::endl;
116 header << " void setPrefix( const char* prefix );" << std::endl << std::endl;
117 header << " /// Connect the object to a new TTree" << std::endl;
118 header << " void connect( TTree* tree );" << std::endl << std::endl;
119
120 //
121 // Declare the variable accessor function(s):
122 //
123 std::set< D3PD::ObjectMetadata::Variable >::const_iterator itr =
124 m_metadata.variables().begin();
125 std::set< D3PD::ObjectMetadata::Variable >::const_iterator end =
126 m_metadata.variables().end();
127 for( ; itr != end; ++itr ) {
128 if( itr->doc() != "" ) {
129 header << " /// " << itr->doc() << std::endl;
130 }
131 header << " " << itr->type()
132 << ( itr->primitive() ? " " : "* " ) << itr->name() << "();"
133 << std::endl;
134 }
135
136 header << std::endl << " private:" << std::endl;
137
138 //
139 // Declare the member variable(s):
140 //
141 header << " // Variables used in the TTree reading:" << std::endl;
142 itr = m_metadata.variables().begin();
143 end = m_metadata.variables().end();
144 for( ; itr != end; ++itr ) {
145 header << " " << itr->type()
146 << ( itr->primitive() ? "" : "*" ) << " m_"
147 << itr->name() << ";" << std::endl;
148 }
149
150 header << std::endl;
151
152 //
153 // Declare the branch(es):
154 //
155 header << " // TBranch variables used in the TTree reading:" << std::endl;
156 itr = m_metadata.variables().begin();
157 end = m_metadata.variables().end();
158 for( ; itr != end; ++itr ) {
159 header << " ::TBranch* m_b_" << itr->name() << "; //!" << std::endl;
160 }
161
162 // Declare the additional member variable(s):
163 header << std::endl << " ::TTree* m_tree;" << std::endl;
164 header << " Long64_t* m_master;" << std::endl;
165 header << " ::TString m_prefix;" << std::endl << std::endl;
166
167 // Close the class definition:
168 header << " ClassDef( " << classname << ", 0 )" << std::endl << std::endl;
169 header << " }; // class " << classname << std::endl << std::endl;
170 header << "} // namespace " << CODE_NAMESPACE << std::endl << std::endl;
171 header << "#endif // D3PDREADER_" << classname << "_H" << std::endl;
172
173 header.close();
174
175 return StatusCode::SUCCESS;
176 }
177
178 StatusCode RootReaderD3PD_v1::writeSource( const std::string& classname,
179 const std::string& dir ) const {
180
181 // Let everyone know what we're doing:
182 REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "RootReaderD3PD_v1" )
183 << "Generating file: " << dir << "/" << classname << ".cxx";
184
185 // Open the header file (overwriting a possibly existing file):
186 std::fstream source( ( dir + "/" + classname + ".cxx" ).c_str(),
187 std::fstream::out | std::fstream::trunc );
188
189 // Add the common header to the file:
190 source << CODE_COMMENT << std::endl << std::endl;
191
192 // Add the necessary ROOT include(s):
193 source << "#include <TTree.h>" << std::endl;
194 source << "#include <TBranch.h>" << std::endl << std::endl;
195
196 // Include the class's header:
197 source << "#include \"" << classname << ".h\"" << std::endl << std::endl;
198
199 source << "ClassImp( D3PDReader::" << classname << " )" << std::endl << std::endl;
200
201 source << "namespace " << CODE_NAMESPACE << " {" << std::endl << std::endl;
202
203 //
204 // Produce the constructor:
205 //
206 source << " /**" << std::endl;
207 source << " * @param master Pointer to the variable holding the current "
208 << "event number" << std::endl;
209 source << " * @param prefix Prefix of the variables in the D3PD" << std::endl;
210 source << " */" << std::endl;
211 source << " " << classname << "::" << classname
212 << "( Long64_t* master, const char* prefix )" << std::endl;
213 source << " : TNamed( \"" << classname << "\", \"D3PDReader class\" ),"
214 << std::endl;
215 std::set< D3PD::ObjectMetadata::Variable >::const_iterator itr =
216 m_metadata.variables().begin();
217 std::set< D3PD::ObjectMetadata::Variable >::const_iterator end =
218 m_metadata.variables().end();
219 for( ; itr != end; ++itr ) {
220 if( itr->primitive() ) continue;
221 source << " m_" << itr->name() << "( 0 )," << std::endl;
222 }
223 itr = m_metadata.variables().begin();
224 end = m_metadata.variables().end();
225 for( ; itr != end; ++itr ) {
226 source << " m_b_" << itr->name() << "( 0 )," << std::endl;
227 }
228 source << " m_tree( 0 ), m_master( master )," << std::endl;
229 source << " m_prefix( prefix ) {" << std::endl << std::endl;
230 source << " }" << std::endl << std::endl;
231
232 //
233 // Produce the prefix handling functions:
234 //
235 source << " const char* " << classname << "::getPrefix() const {" << std::endl
236 << std::endl;
237 source << " return m_prefix;" << std::endl;
238 source << " }" << std::endl << std::endl;
239 source << " void " << classname << "::setPrefix( const char* prefix ) {"
240 << std::endl << std::endl;
241 source << " m_prefix = prefix;" << std::endl;
242 source << " return;" << std::endl;
243 source << " }" << std::endl << std::endl;
244
245 //
246 // Produce the connect(...) function:
247 //
248 source << " /**" << std::endl;
249 source << " * This function should be called every time a new TFile is opened"
250 << std::endl;
251 source << " * by your analysis code." << std::endl;
252 source << " *" << std::endl;
253 source << " * @param tree Pointer to the TTree with the variables" << std::endl;
254 source << " */" << std::endl;
255 source << " void " << classname << "::connect( TTree* tree ) {" << std::endl
256 << std::endl;
257 itr = m_metadata.variables().begin();
258 end = m_metadata.variables().end();
259 for( ; itr != end; ++itr ) {
260 if( ! itr->primitive() ) {
261 source << " if( m_" << itr->name() << " ) delete m_" << itr->name()
262 << ";" << std::endl;
263 source << " m_" << itr->name() << " = 0;" << std::endl;
264 }
265 source << " m_b_" << itr->name() << " = 0;" << std::endl << std::endl;
266 }
267 source << " m_tree = tree;" << std::endl << std::endl;
268 source << " return;" << std::endl;
269 source << " }" << std::endl << std::endl;
270
271 //
272 // Produce the accessor functions:
273 //
274 itr = m_metadata.variables().begin();
275 end = m_metadata.variables().end();
276 for( ; itr != end; ++itr ) {
277 source << " " << itr->type() << ( itr->primitive() ? " " : "* " )
278 << classname << "::" << itr->name()
279 << "() {" << std::endl << std::endl;
280 source << " if( ! m_b_" << itr->name() << " ) {" << std::endl;
281 source << " if( ! m_tree ) {" << std::endl;
282 source << " Error( \"Connect\", \"Object not connected yet!\" );"
283 << std::endl;
284 source << " return 0;" << std::endl;
285 source << " }" << std::endl;
286 source << " if( ! m_tree->GetBranch( m_prefix + \"" << itr->name()
287 << "\" ) ) {" << std::endl;
288 source << " Error( \"Connect\", "
289 << "\"The following variable doesn't exist: %s\", "
290 << "( m_prefix + \"" << itr->name() << "\" ).Data() );" << std::endl;
291 source << " return 0;" << std::endl;
292 source << " }" << std::endl;
293 source << " m_tree->SetBranchAddress( m_prefix + \"" << itr->name()
294 << "\", &m_" << itr->name() << ", &m_b_" << itr->name() << " );"
295 << std::endl;
296 source << " }" << std::endl;
297 source << " if( *m_master != m_b_" << itr->name() << "->GetReadEntry() ) {"
298 << std::endl;
299 source << " m_b_" << itr->name() << "->GetEntry( *m_master );"
300 << std::endl;
301 source << " }" << std::endl;
302 source << " return m_" << itr->name() << ";" << std::endl;
303 source << " }" << std::endl << std::endl;
304 }
305
306 source << "} // namespace " << CODE_NAMESPACE << std::endl;
307
308 source.close();
309
310 return StatusCode::SUCCESS;
311 }
312
313} // namespace D3PD
static const char *const CODE_COMMENT
A little header for all the generated source files.
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.
#define CHECK(...)
Evaluate an expression and check for errors.
static const char *const CODE_NAMESPACE
Namespace into which all the code should be put.
void addSTLHeader(std::ostream &out, const char *name) const
Function adding STL include statements to the header when needed.
ObjectMetadata m_metadata
Object holding the information about the variables.
StatusCode writeHeader(const std::string &classname, const std::string &dir) const
Function creating the D3PDReader C++ header.
StatusCode createReader(const std::string &classname, const std::string &dir="./") const
Function creating the D3PDReader C++ code.
RootReaderD3PD_v1()
Quite empty constructor.
StatusCode writeSource(const std::string &classname, const std::string &dir) const
Function creatig the D3PDReader C++ source.
Block filler tool for noisy FEB information.