ATLAS Offline Software
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 
19 static 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 
28 static const char* const CODE_NAMESPACE = "D3PDReader";
29 
30 namespace D3PD {
31 
33 
34  }
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
D3PD::ObjectMetadata::variables
const std::set< Variable > & variables() const
Function for accessing all the variables of the D3PDObject.
Definition: ObjectMetadata.cxx:577
D3PD::RootReaderD3PD_v1::RootReaderD3PD_v1
RootReaderD3PD_v1()
Quite empty constructor.
Definition: RootReaderD3PD_v1.cxx:32
header
Definition: hcg.cxx:526
D3PD::RootReaderD3PDBase::m_metadata
ObjectMetadata m_metadata
Object holding the information about the variables.
Definition: RootReaderD3PDBase.h:84
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
D3PD::RootReaderD3PD_v1::writeSource
StatusCode writeSource(const std::string &classname, const std::string &dir) const
Function creatig the D3PDReader C++ source.
Definition: RootReaderD3PD_v1.cxx:178
D3PD::RootReaderD3PD_v1::writeHeader
StatusCode writeHeader(const std::string &classname, const std::string &dir) const
Function creating the D3PDReader C++ header.
Definition: RootReaderD3PD_v1.cxx:56
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
D3PD
Block filler tool for noisy FEB information.
Definition: CaloCellDetailsFillerTool.cxx:29
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
beamspotman.dir
string dir
Definition: beamspotman.py:623
REPORT_MESSAGE_WITH_CONTEXT
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:345
errorcheck.h
Helpers for checking error return status codes and reporting errors.
D3PD::ObjectMetadata::prefix
const std::string & prefix() const
Get the prefix given to variables in this D3PDObject.
Definition: ObjectMetadata.cxx:219
D3PD::RootReaderD3PDBase::addSTLHeader
void addSTLHeader(std::ostream &out, const char *name) const
Function adding STL include statements to the header when needed.
Definition: RootReaderD3PDBase.cxx:167
copySelective.source
string source
Definition: copySelective.py:32
RootReaderD3PD_v1.h
makeTOC.header
header
Definition: makeTOC.py:28
D3PD::RootReaderD3PD_v1::createReader
StatusCode createReader(const std::string &classname, const std::string &dir="./") const
Function creating the D3PDReader C++ code.
Definition: RootReaderD3PD_v1.cxx:44