ATLAS Offline Software
Functions
D3PD::Version2 Namespace Reference

Private namespace for version 2 of the code generator code. More...

Functions

StatusCode writeD3PDObjectBase (const std::string &dir)
 This function can be used to create the D3PDReader::D3PDObjectBase class's source files. More...
 
StatusCode writeVarHandle (const std::string &dir)
 This function can be used to create the D3PDReader::VarHandle class's source files. More...
 
StatusCode writeVarProxy (const std::string &dir)
 This function can be used to create the D3PDReader::VarProxy class's source files. More...
 
StatusCode writeUserD3PDObject (const std::string &dir)
 This function can be used to create the D3PDReader::UserD3PDObject class's source files. More...
 
StatusCode writeD3PDReadStats (const std::string &dir)
 This function can be used to create the D3PDReader::D3PDReadStats class's source files. More...
 
StatusCode writeD3PDPerfStats (const std::string &dir)
 This function can be used to create the D3PDReader::D3PDPerfStats class's source files. More...
 
StatusCode writeUtils (const std::string &dir)
 This function can be used to create source files containing some utility functions. More...
 
StatusCode writeHeader (const std::string &classname, const std::string &dir, const ObjectMetadata &metadata)
 This function is used to create the header of the class describing a set of D3PD variables. More...
 
StatusCode writeSource (const std::string &classname, const std::string &dir, const ObjectMetadata &metadata)
 This function is used to generate the source file of a D3PDReader class. More...
 
StatusCode writeEventHeader (const std::string &classname, const std::string &dir, const std::set< ObjectMetadata > &metadata)
 Write the header of the main event class describing a D3PD tree. More...
 
StatusCode writeEventSource (const std::string &classname, const std::string &dir, const std::set< ObjectMetadata > &metadata)
 Write the source of the main event class describing a D3PD tree. More...
 

Detailed Description

Private namespace for version 2 of the code generator code.

   The code generator functions have now been separated completely
   from the D3PD code. This way it should be possible to generate
   the same kind of code from multiple input sources.
Author
Attila Krasznahorkay Attil.nosp@m.a.Kr.nosp@m.aszna.nosp@m.hork.nosp@m.ay@ce.nosp@m.rn.c.nosp@m.h
Revision
516932
Date
2012-09-10 11:29:08 +0200 (Mon, 10 Sep 2012)

Function Documentation

◆ writeD3PDObjectBase()

StatusCode D3PD::Version2::writeD3PDObjectBase ( const std::string &  dir)

This function can be used to create the D3PDReader::D3PDObjectBase class's source files.

Write the "D3PDObjectBase" source files into a given directory.

The created class is used as a base to all the main D3PDReader classes.

Parameters
dirDirectory name where the source file should be put
Returns
A StatusCode indicating whether the operation was successful

Definition at line 265 of file CodeGenerator_v2.cxx.

265  {
266 
267  // Construct the file names as they will be needed in a few places:
268  const std::string headerName = dir + "/" + D3PDOBJECTBASE_HEADER_NAME;
269 
270  // Only create the header if it doesn't exist:
271  struct stat fileInfo;
272  if( stat( headerName.c_str(), &fileInfo ) ) {
273 
274  // Let everyone know what we're doing:
275  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO,
276  "Version2::writeD3PDObjectBase" )
277  << "Generating file: " << headerName;
278 
279  // Open the header file (overwriting a possibly existing file):
280  std::ofstream header( headerName.c_str() );
281 
282  // Write the header file:
283  header << D3PDOBJECTBASE_HEADER << std::endl;
284  header.close();
285  }
286 
287  return StatusCode::SUCCESS;
288  }

◆ writeD3PDPerfStats()

StatusCode D3PD::Version2::writeD3PDPerfStats ( const std::string &  dir)

This function can be used to create the D3PDReader::D3PDPerfStats class's source files.

Write the "D3PDPerfStats" source files into a given directory.

The created class is collecting global performance statistics from ROOT during a D3PD analysis.

Parameters
dirDirectory name where the source files should be put
Returns
A StatusCode indicating whether the operation was successful

Definition at line 528 of file CodeGenerator_v2.cxx.

528  {
529 
530  // Construct the file names as they will be needed in a few places:
531  const std::string headerName = dir + "/" + D3PDPERFSTATS_HEADER_NAME;
532  const std::string cxxName = dir + "/" + D3PDPERFSTATS_CXX_NAME;
533 
534  // Only create the header if it doesn't exist:
535  struct stat fileInfo;
536  if( stat( headerName.c_str(), &fileInfo ) ) {
537 
538  // Let everyone know what we're doing:
539  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO,
540  "Version2::writeD3PDPerfStats" )
541  << "Generating file: " << headerName;
542 
543  // Open the header file (overwriting a possibly existing file):
544  std::ofstream header( headerName.c_str() );
545 
546  // Write the header file:
547  header << D3PDPERFSTATS_HEADER << std::endl;
548  header.close();
549  }
550 
551  // Only create the implementation if it doesn't exist:
552  if( stat( cxxName.c_str(), &fileInfo ) ) {
553 
554  // Let everyone know what we're doing:
555  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO,
556  "Version2::writeD3PDPerfStats" )
557  << "Generating file: " << cxxName;
558 
559  // Open the header file (overwriting a possibly existing file):
560  std::ofstream impl( cxxName.c_str() );
561 
562  // Write the header file:
563  impl << D3PDPERFSTATS_CXX << std::endl;
564  impl.close();
565  }
566 
567  return StatusCode::SUCCESS;
568  }

◆ writeD3PDReadStats()

StatusCode D3PD::Version2::writeD3PDReadStats ( const std::string &  dir)

This function can be used to create the D3PDReader::D3PDReadStats class's source files.

Write the "D3PDReadStats" source files into a given directory.

The created class is used in the D3PDReader code to keep track of the performance of an analysis.

Parameters
dirDirectory name where the source files should be put
Returns
A StatusCode indicating whether the operation was successful

Definition at line 478 of file CodeGenerator_v2.cxx.

478  {
479 
480  // Construct the file names as they will be needed in a few places:
481  const std::string headerName = dir + "/" + D3PDREADSTATS_HEADER_NAME;
482  const std::string cxxName = dir + "/" + D3PDREADSTATS_CXX_NAME;
483 
484  // Only create the header if it doesn't exist:
485  struct stat fileInfo;
486  if( stat( headerName.c_str(), &fileInfo ) ) {
487 
488  // Let everyone know what we're doing:
489  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO,
490  "Version2::writeD3PDReadStats" )
491  << "Generating file: " << headerName;
492 
493  // Open the header file (overwriting a possibly existing file):
494  std::ofstream header( headerName.c_str() );
495 
496  // Write the header file:
497  header << D3PDREADSTATS_HEADER << std::endl;
498  header.close();
499  }
500 
501  // Only create the implementation if it doesn't exist:
502  if( stat( cxxName.c_str(), &fileInfo ) ) {
503 
504  // Let everyone know what we're doing:
505  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO,
506  "Version2::writeD3PDReadStats" )
507  << "Generating file: " << cxxName;
508 
509  // Open the header file (overwriting a possibly existing file):
510  std::ofstream impl( cxxName.c_str() );
511 
512  // Write the header file:
513  impl << D3PDREADSTATS_CXX << std::endl;
514  impl.close();
515  }
516 
517  return StatusCode::SUCCESS;
518  }

◆ writeEventHeader()

StatusCode D3PD::Version2::writeEventHeader ( const std::string &  classname,
const std::string &  dir,
const std::set< ObjectMetadata > &  metadata 
)

Write the header of the main event class describing a D3PD tree.

Definition at line 1913 of file CodeGenerator_v2.cxx.

1914  {
1915 
1916  // Construct the file name:
1917  const std::string fileName = dir + "/" + classname + ".h";
1918 
1919  // If the file already exists, let's not overwrite it:
1920  struct stat fileInfo;
1921  if( ! stat( fileName.c_str(), &fileInfo ) ) return StatusCode::SUCCESS;
1922 
1923  // Let everyone know what we're doing:
1924  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "Version2::writeEventHeader" )
1925  << "Generating file: " << fileName;
1926 
1927  // Open the header file (overwriting a possibly existing file):
1928  std::ofstream header( fileName.c_str() );
1929 
1930  // Write a header for the file:
1931  header << CODE_COMMENT << std::endl;
1932  header << "#ifndef D3PDREADER_" << classname << "_H" << std::endl;
1933  header << "#define D3PDREADER_" << classname << "_H" << std::endl << std::endl;
1934 
1935  //
1936  // Construct the includes:
1937  //
1938  header << "// Local include(s):" << std::endl;
1939  header << "#include \"D3PDObjectBase.h\"" << std::endl;
1940  std::set< std::string > d3pd_reader_names;
1941  std::set< ObjectMetadata >::const_iterator meta_itr = metadata.begin();
1942  std::set< ObjectMetadata >::const_iterator meta_end = metadata.end();
1943  for( ; meta_itr != meta_end; ++meta_itr ) {
1944  // Check if we already included this class:
1946  d3pd_reader_names.insert( meta_itr->name() );
1947  if( ! ret.second ) continue;
1948  // If not, then:
1949  header << "#include \"" << meta_itr->name() << ".h\"" << std::endl;
1950  }
1951  header << std::endl;
1952 
1953  header << "namespace D3PDReader {" << std::endl << std::endl;
1954 
1955  //
1956  // Declare the event class:
1957  //
1958  header << " /**" << std::endl;
1959  header << " * Code generated by CodeGenerator_v2 on:" << std::endl;
1960  header << " * host = " << System::hostName() << std::endl;
1961  header << " * OS = " << System::osName() << " / " << System::osVersion()
1962  << std::endl;
1963  header << " * user = " << System::accountName() << std::endl;
1964  time_t rawtime = time( NULL );
1965  char buf[26];
1966  header << " * time = " << ctime_r( &rawtime, buf );
1967  header << " */" << std::endl;
1968  header << " class " << classname << " : public D3PDObjectBase {" << std::endl
1969  << std::endl;
1970  header << " public:" << std::endl;
1971 
1972  //
1973  // Declare the constructors:
1974  //
1975  header << " /// Default constructor, to be used when reading a D3PD" << std::endl;
1976  header << " " << classname << "();" << std::endl;
1977  header << " /// Constructor for only writing data" << std::endl;
1978  header << " " << classname << "( Bool_t onlyForWriting );" << std::endl
1979  << std::endl;
1980 
1981  //
1982  // Declare some functions:
1983  //
1984  header << " /// Get the currently configured prefix value" << std::endl;
1985  header << " virtual const char* GetPrefix() const;" << std::endl;
1986  header << " /// Set the prefix for the variables" << std::endl;
1987  header << " virtual void SetPrefix( const char* prefix );" << std::endl
1988  << std::endl;
1989 
1990  header << " /// Connect the object to an input TTree" << std::endl;
1991  header << " virtual void ReadFrom( ::TTree* tree );" << std::endl;
1992  header << " /// Connect the object to an output TTree" << std::endl;
1993  header << " virtual void WriteTo( ::TTree* tree );" << std::endl << std::endl;
1994 
1995  header << " /// Turn (selected) branches either on or off" << std::endl;
1996  header << " virtual void SetActive( ::Bool_t active = kTRUE," << std::endl;
1997  header << " const ::TString& pattern = \".*\" );"
1998  << std::endl;
1999  header << " /// Read in all the variables that we need to write out as well"
2000  << std::endl;
2001  header << " virtual void ReadAllActive();" << std::endl << std::endl;
2002  header << " /// Get the D3PD reading statistics" << std::endl;
2003  header << " virtual D3PDReadStats GetStatistics() const;" << std::endl
2004  << std::endl;
2005 
2006  header << " /// Switch the reader object to a new event" << std::endl;
2007  header << " void GetEntry( ::Long64_t entry );" << std::endl << std::endl;
2008 
2009  //
2010  // Declare each object:
2011  //
2012  header << " //" << std::endl;
2013  header << " // All the components of the D3PD:" << std::endl;
2014  header << " //" << std::endl;
2015  FOR_ALL_EVENT_VARIABLES( header << " " << meta_itr->name() << " " << varname
2016  << ";" << std::endl );
2017 
2018  // Declare the additional member variable(s):
2019  header << std::endl << " private:" << std::endl;
2020  header << " Long64_t fEntry; ///< Variable storing the current entry number"
2021  << std::endl;
2022  header << " Bool_t fFromInput; "
2023  << "///< Flag specifying if object is used for D3PD reading"
2024  << std::endl << std::endl;
2025 
2026  // Close the class definition:
2027  header << " ClassDef( " << classname << ", 0 )" << std::endl << std::endl;
2028  header << " }; // class " << classname << std::endl << std::endl;
2029  header << "} // namespace D3PDReader" << std::endl << std::endl;
2030  header << "#endif // D3PDREADER_" << classname << "_H" << std::endl;
2031 
2032  header.close();
2033 
2034  return StatusCode::SUCCESS;
2035  }

◆ writeEventSource()

StatusCode D3PD::Version2::writeEventSource ( const std::string &  classname,
const std::string &  dir,
const std::set< ObjectMetadata > &  metadata 
)

Write the source of the main event class describing a D3PD tree.

Definition at line 2037 of file CodeGenerator_v2.cxx.

2038  {
2039 
2040  // Construct the file name:
2041  const std::string fileName = dir + "/" + classname + ".cxx";
2042 
2043  // If the file already exists, let's not overwrite it:
2044  struct stat fileInfo;
2045  if( ! stat( fileName.c_str(), &fileInfo ) ) return StatusCode::SUCCESS;
2046 
2047  // Let everyone know what we're doing:
2048  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "Version2::writeSource" )
2049  << "Generating file: " << fileName;
2050 
2051  // Open the header file (overwriting a possibly existing file):
2052  std::ofstream source( fileName.c_str() );
2053 
2054  // Add the common header to the file:
2055  source << CODE_COMMENT << std::endl << std::endl;
2056 
2057  // Include the class's header:
2058  source << "#include \"" << classname << ".h\"" << std::endl;
2059  source << "#include \"D3PDPerfStats.h\"" << std::endl << std::endl;
2060 
2061  source << "ClassImp( D3PDReader::" << classname << " )" << std::endl << std::endl;
2062 
2063  source << "namespace D3PDReader {" << std::endl << std::endl;
2064 
2065  //
2066  // Produce the (input) constructor:
2067  //
2068  source << " " << classname << "::" << classname << "()" << std::endl
2069  << " : D3PDObjectBase()," << std::endl;
2070  FOR_ALL_EVENT_VARIABLES( source << " " << varname << "( fEntry, \""
2071  << meta_itr->prefix() << "\" )," << std::endl );
2072  source << " fEntry( 0 )," << std::endl;
2073  source << " fFromInput( kTRUE ) {" << std::endl << std::endl;
2074  source << " }" << std::endl << std::endl;
2075 
2076  //
2077  // Produce the (output) constructor:
2078  //
2079  source << " " << classname << "::" << classname << "( Bool_t )" << std::endl
2080  << " : D3PDObjectBase()," << std::endl;
2081  FOR_ALL_EVENT_VARIABLES( source << " " << varname << "( \""
2082  << meta_itr->prefix() << "\" )," << std::endl );
2083  source << " fEntry( 0 )," << std::endl;
2084  source << " fFromInput( kFALSE ) {" << std::endl << std::endl;
2085  source << " }" << std::endl << std::endl;
2086 
2087  //
2088  // Produce the prefix handling functions:
2089  //
2090  source << " const char* " << classname << "::GetPrefix() const {" << std::endl
2091  << std::endl;
2092  source << " Warning( \"GetPrefix\", \"A prefix is not defined for this object\" );"
2093  << std::endl;
2094  source << " return \"\";" << std::endl;
2095  source << " }" << std::endl << std::endl;
2096 
2097  source << " void " << classname << "::SetPrefix( const char* ) {" << std::endl
2098  << std::endl;
2099  source << " Warning( \"SetPrefix\", \"A prefix is not defined for this object\" );"
2100  << std::endl;
2101  source << " return;" << std::endl;
2102  source << " }" << std::endl << std::endl;
2103 
2104  //
2105  // Produce the ReadFrom(...) function:
2106  //
2107  source << " void " << classname << "::ReadFrom( ::TTree* tree ) {" << std::endl
2108  << std::endl;
2109  source << " if( ! fFromInput ) {" << std::endl;
2110  source << " Error( \"ReadFrom\", \"Object can't read a D3PD. Use a different "
2111  << "constructor!\" );" << std::endl;
2112  source << " return;" << std::endl;
2113  source << " }" << std::endl << std::endl;
2114  FOR_ALL_EVENT_VARIABLES( source << " " << varname << ".ReadFrom( tree );"
2115  << std::endl );
2116  source << std::endl << " return;" << std::endl;
2117  source << " }" << std::endl << std::endl;
2118 
2119  //
2120  // Produce the WriteTo(...) function:
2121  //
2122  source << " void " << classname << "::WriteTo( ::TTree* tree ) {" << std::endl
2123  << std::endl;
2124  FOR_ALL_EVENT_VARIABLES( source << " " << varname << ".WriteTo( tree );"
2125  << std::endl );
2126  source << std::endl << " return;" << std::endl;
2127  source << " }" << std::endl << std::endl;
2128 
2129  //
2130  // Produce the SetActive(...) function:
2131  //
2132  source << " void " << classname << "::SetActive( ::Bool_t active, "
2133  << "const ::TString& pattern ) {" << std::endl << std::endl;
2134  FOR_ALL_EVENT_VARIABLES( source << " " << varname << ".SetActive( "
2135  << "active, pattern );" << std::endl );
2136  source << std::endl << " return;" << std::endl;
2137  source << " }" << std::endl << std::endl;
2138 
2139  //
2140  // Produce the ReadAllActive() function:
2141  //
2142  source << " void " << classname << "::ReadAllActive() {" << std::endl
2143  << std::endl;
2144  FOR_ALL_EVENT_VARIABLES( source << " " << varname << ".ReadAllActive();"
2145  << std::endl );
2146  source << std::endl << " return;" << std::endl;
2147  source << " }" << std::endl << std::endl;
2148 
2149  //
2150  // Produce the GetStatistics() function:
2151  //
2152  source << " D3PDReadStats " << classname << "::GetStatistics() const {"
2153  << std::endl << std::endl;
2154  source << " // The result object:" << std::endl;
2155  source << " D3PDReadStats result( D3PDPerfStats::Instance()->GetStats() );"
2156  << std::endl << std::endl;
2157  source << " // Collect the statistics from all constituents:" << std::endl;
2158  FOR_ALL_EVENT_VARIABLES( source << " result += " << varname
2159  << ".GetStatistics();" << std::endl );
2160  source << std::endl << " return result;" << std::endl;
2161  source << " }" << std::endl << std::endl;
2162 
2163  //
2164  // Produce the GetEntry(...) function:
2165  //
2166  source << " void " << classname << "::GetEntry( ::Long64_t entry ) {" << std::endl
2167  << std::endl;
2168  source << " fEntry = entry;" << std::endl;
2169  source << " return;" << std::endl;
2170  source << " }" << std::endl << std::endl;
2171 
2172  source << "} // namespace D3PDReader" << std::endl;
2173  source.close();
2174 
2175  return StatusCode::SUCCESS;
2176  }

◆ writeHeader()

StatusCode D3PD::Version2::writeHeader ( const std::string &  classname,
const std::string &  dir,
const ObjectMetadata metadata 
)

This function is used to create the header of the class describing a set of D3PD variables.

Write the header of the class(es) describing some D3PD variables.

When the source code is generated in an Athena job, the classes follow the organization of the D3PDMaker python configuration. But in standalone code generation mode any kind of variables can be grouped together.

Parameters
classnameThe name of the class to be generated
dirThe directory where the header file should be put
prefixThe common prefix of the variable names
varsA vector of the variable descriptions
isContainerA flag specifying whether an element proxy class should be generated
Returns
A StatusCode indicating whether the operation was successful

Definition at line 632 of file CodeGenerator_v2.cxx.

634  {
635 
636  // Construct the file name:
637  const std::string fileName = dir + "/" + classname + ".h";
638 
639  // If the file already exists, let's not overwrite it:
640  struct stat fileInfo;
641  if( ! stat( fileName.c_str(), &fileInfo ) ) return StatusCode::SUCCESS;
642 
643  // Let everyone know what we're doing:
644  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "Version2::writeHeader" )
645  << "Generating file: " << fileName;
646 
647  // Open the header file (overwriting a possibly existing file):
648  std::ofstream header( fileName.c_str() );
649 
650  // Write a header for the file:
651  header << CODE_COMMENT << std::endl;
652  header << "#ifndef D3PDREADER_" << classname << "_H" << std::endl;
653  header << "#define D3PDREADER_" << classname << "_H" << std::endl
654  << std::endl;
655 
656  // The STL map is always needed:
657  header << "// STL include(s):" << std::endl;
658  header << "#include <map>" << std::endl;
659 
660  // Include some other STL headers if they're needed:
661  addSTLHeader( header, "vector", metadata );
662  addSTLHeader( header, "string", metadata );
663  header << std::endl;
664 
665  // ROOT include(s):
666  header << "// ROOT include(s):" << std::endl;
667  header << "#include <TObject.h>" << std::endl;
668  header << "#include <TString.h>" << std::endl << std::endl;
669 
670  // Local include(s):
671  header << "#include \"" << D3PDOBJECTBASE_HEADER_NAME << "\""
672  << std::endl;
673  header << "#include \"" << D3PDREADSTATS_HEADER_NAME << "\""
674  << std::endl;
675  header << "#include \"" << VARHANDLE_HEADER_NAME << "\"" << std::endl;
676  if( metadata.container() ) {
677  header << "#include \"" << VARPROXY_HEADER_NAME << "\""
678  << std::endl;
679  }
680  header << "#include \"" << USERD3PDOBJECT_HEADER_NAME << "\""
681  << std::endl;
682  header << std::endl;
683 
684  // Forward declaration(s):
685  header << "class TTree;" << std::endl << std::endl;
686 
687  // Declare the namespace:
688  header << "namespace D3PDReader {" << std::endl << std::endl;
689 
690  //
691  // Declare the proxy class:
692  //
693  if( metadata.container() ) {
694 
695  // Forward declare the reader class:
696  header << " // Forward declaration(s):" << std::endl;
697  header << " class " << classname << ";" << std::endl << std::endl;
698 
699  // Declare the proxy class:
700  header << " /**" << std::endl;
701  header << " * Code generated by CodeGenerator_v2 on:"
702  << std::endl;
703  header << " * host = " << System::hostName() << std::endl;
704  header << " * OS = " << System::osName() << " / "
705  << System::osVersion() << std::endl;
706  header << " * user = " << System::accountName() << std::endl;
707  const time_t rawtime = time( NULL );
708  char buf[26];
709  header << " * time = " << ctime_r( &rawtime, buf );
710  header << " */" << std::endl;
711  header << " class " << classname << "Element : "
712  << "public UserD3PDObjectElement {" << std::endl
713  << std::endl;
714  header << " friend class " << classname << ";" << std::endl
715  << std::endl;
716  header << " protected:" << std::endl;
717 
718  // Create the constructor:
719  header << " /// Constructor only visible to " << classname
720  << std::endl;
721  header << " " << classname << "Element( size_t index, const "
722  << classname << "& parent );" << std::endl << std::endl;
723 
724  // Create the copy constructor:
725  header << " public:" << std::endl;
726  header << " /// Copy constructor" << std::endl;
727  header << " " << classname << "Element( const " << classname
728  << "Element& parent );" << std::endl << std::endl;
729 
730  // Create the generic accessor functions:
731  header << " /// Parent object of this proxy object"
732  << std::endl;
733  header << " const " << classname << "* GetParent() const;"
734  << std::endl;
735  header << " /// Index of the object inside its container"
736  << std::endl;
737  header << " size_t GetIndex() const;" << std::endl
738  << std::endl;
739 
740  // Create the member variable(s):
741  std::map< std::string, int > variableCounter;
742  std::set< ObjectMetadata::Variable >::const_iterator itr =
743  metadata.variables().begin();
744  std::set< ObjectMetadata::Variable >::const_iterator end =
745  metadata.variables().end();
746  for( ; itr != end; ++itr ) {
747  // Ignore the container size variable:
748  if( ( itr->name() == "n" ) || ( itr->name() == "N" ) ) continue;
749 
750  bool ok = true;
751  const std::string type =
752  vectorTemplateArgument( itr->type(), ok );
753  if( ! ok ) {
754  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR,
755  "Version2::writeHeader" )
756  << "Unexpected variable type encountered for "
757  << "container dumper: " << itr->type();
758  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR,
759  "Version2::writeHeader" )
760  << "Variable name: " << itr->name();
761  return StatusCode::FAILURE;
762  }
763  if( itr->doc() != "" ) {
764  header << " /// " << itr->doc() << std::endl;
765  }
766  if( variableCounter.find( itr->name() ) ==
767  variableCounter.end() ) {
768  header << " VarProxy< " << type << " > "
769  << variableName( itr->name() ) << ";" << std::endl;
770  variableCounter[ itr->name() ] = 1;
771  } else {
772  header << " VarProxy< " << type << " > "
773  << variableName( itr->name() )
774  << variableCounter[ itr->name() ] << ";" << std::endl;
775  variableCounter[ itr->name() ]++;
776  }
777  }
778  header << std::endl;
779 
780  // Create the private variable(s):
781  header << " private:" << std::endl;
782  header << " /// Reference to the parent of this object"
783  << std::endl;
784  header << " const " << classname << "* fParent;" << std::endl;
785  header << " /// The index of this object inside the parent "
786  << "container" << std::endl;
787  header << " size_t fIndex;" << std::endl << std::endl;
788 
789  // Close the class definition:
790  header << " ClassDef( " << classname << "Element, 0 )"
791  << std::endl
792  << std::endl;
793  header << " }; // class " << classname << "Element" << std::endl
794  << std::endl;
795  }
796 
797  //
798  // Declare the reader class itself:
799  //
800  header << " /**" << std::endl;
801  header << " * Code generated by CodeGenerator_v2 on:" << std::endl;
802  header << " * host = " << System::hostName() << std::endl;
803  header << " * OS = " << System::osName() << " / "
804  << System::osVersion() << std::endl;
805  header << " * user = " << System::accountName() << std::endl;
806  const time_t rawtime = time( NULL );
807  char buf[26];
808  header << " * time = " << ctime_r( &rawtime, buf );
809  header << " */" << std::endl;
810  header << " class " << classname << " : "
811  << "public UserD3PDObject {" << std::endl << std::endl;
812  header << " public:" << std::endl;
813 
814  //
815  // Declare the constructor(s)/destructor:
816  //
817  header << " /// Constructor used when reading from a TTree"
818  << std::endl;
819  header << " " << classname
820  << "( const ::Long64_t& master, const char* prefix = \""
821  << metadata.prefix() << "\" );" << std::endl;
822  header << " /// Constructor when the object is only used for "
823  << "writing data out" << std::endl;
824  header << " " << classname << "( const char* prefix = \""
825  << metadata.prefix() << "\" );" << std::endl;
826  if( metadata.container() ) {
827  header << " /// Destructor" << std::endl;
828  header << " ~" << classname << "();" << std::endl;
829  }
830  header << std::endl;
831 
832  //
833  // Declare some functions:
834  //
835  header << " /// Get the currently configured prefix value"
836  << std::endl;
837  header << " virtual const char* GetPrefix() const;" << std::endl;
838  header << " /// Set the prefix for the variables" << std::endl;
839  header << " virtual void SetPrefix( const char* prefix );"
840  << std::endl << std::endl;
841 
842  header << " /// Connect the object to an input TTree"
843  << std::endl;
844  header << " virtual void ReadFrom( ::TTree* tree );" << std::endl;
845  header << " /// Connect the object to an output TTree"
846  << std::endl;
847  header << " virtual void WriteTo( ::TTree* tree );" << std::endl
848  << std::endl;
849 
850  header << " /// Turn (selected) branches either on or off"
851  << std::endl;
852  header << " virtual void SetActive( ::Bool_t active = kTRUE,"
853  << std::endl;
854  header << " const ::TString& pattern = "
855  << "\".*\" );" << std::endl;
856  header << " /// Read in all the variables that we need to write "
857  << "out as well" << std::endl;
858  header << " virtual void ReadAllActive();" << std::endl
859  << std::endl;
860 
861  header << " /// Get the D3PD reading statistics" << std::endl;
862  header << " virtual D3PDReadStats GetStatistics() const;"
863  << std::endl << std::endl;
864 
865  header << " /// Set the contents of the object according to "
866  << "another object" << std::endl;
867  header << " " << classname << "& Set( const " << classname
868  << "& parent );" << std::endl << std::endl;
869 
870  if( metadata.container() ) {
871  header << " /// Clear the container. Useful when writing new "
872  << "branches." << std::endl;
873  header << " void Clear( Option_t* option = \"\" );"
874  << std::endl;
875  header << " /// Add one element to an output collection"
876  << std::endl;
877  header << " " << classname << "& Add( const " << classname
878  << "Element& el );" << std::endl << std::endl;
879  header << " /// Access a proxy class describing one element of"
880  << " the container" << std::endl;
881  header << " " << classname << "Element& operator[]( size_t "
882  << "index );" << std::endl;
883  header << " /// Access a proxy class describing one element of"
884  << " the container (constant version)" << std::endl;
885  header << " const " << classname << "Element& operator[]( "
886  << "size_t index ) const;" << std::endl;
887  header << " /// Add one element to an output collection"
888  << std::endl;
889  header << " " << classname << "& operator+=( const "
890  << classname << "Element& el );" << std::endl << std::endl;
891  }
892 
893  //
894  // Declare each variable responsible for reading a branch:
895  //
896  std::map< std::string, int > variableCounter;
897  std::set< ObjectMetadata::Variable >::const_iterator itr =
898  metadata.variables().begin();
899  std::set< ObjectMetadata::Variable >::const_iterator end =
900  metadata.variables().end();
901  for( ; itr != end; ++itr ) {
902  if( itr->doc() != "" ) {
903  header << " /// " << itr->doc() << std::endl;
904  }
905  if( variableCounter.find( itr->name() ) == variableCounter.end() ) {
906  header << " VarHandle< " << itr->type()
907  << ( itr->primitive() ? "" : "*" ) << " > "
908  << variableName( itr->name() ) << ";" << std::endl;
909  variableCounter[ itr->name() ] = 1;
910  } else {
911  header << " VarHandle< " << itr->type()
912  << ( itr->primitive() ? "" : "*" ) << " > "
913  << variableName( itr->name() )
914  << variableCounter[ itr->name() ] << ";" << std::endl;
915  variableCounter[ itr->name() ]++;
916  }
917  }
918 
919  // Declare the private functions/members:
920  header << std::endl << " private:" << std::endl;
921  header << " /// Function used internally to access the variables"
922  << std::endl;
923  header << " VarHandleBase* GetVarHandle( const char* name );"
924  << std::endl;
925  header << " /// Function setting up all the VarHandle members"
926  << std::endl;
927  header << " void SetVarHandles( const ::Long64_t* master );"
928  << std::endl << std::endl;
929 
930  // Declare the additional member variable(s):
931  if( metadata.container() ) {
932  header << " mutable std::vector< " << classname << "Element* >"
933  << " fProxies; ///< Internal list of proxy objects"
934  << std::endl;
935  }
936  header << " std::map< ::TString, VarHandleBase* > fHandles; "
937  << "///< Book-keeper of the VarHandle members" << std::endl;
938  header << " const ::Bool_t fFromInput; "
939  << "///< Flag specifying if object is used for D3PD reading"
940  << std::endl;
941  header << " ::TString fPrefix; ///< Prefix to the branch names"
942  << std::endl << std::endl;
943 
944  // Close the class definition:
945  header << " ClassDef( " << classname << ", 0 )" << std::endl
946  << std::endl;
947  header << " }; // class " << classname << std::endl << std::endl;
948  header << "} // namespace D3PDReader" << std::endl << std::endl;
949  header << "#endif // D3PDREADER_" << classname << "_H" << std::endl;
950 
951  header.close();
952 
953  return StatusCode::SUCCESS;
954  }

◆ writeSource()

StatusCode D3PD::Version2::writeSource ( const std::string &  classname,
const std::string &  dir,
const ObjectMetadata metadata 
)

This function is used to generate the source file of a D3PDReader class.

Write the source of the class(es) describing some D3PD variables.

Parameters
classnameThe name of the class to be generated
dirThe directory where the header file should be put
varsA vector of the variable descriptions
isContainerA flag specifying whether an element proxy class should be generated
Returns
A StatusCode indicating whether the operation was successful

Definition at line 967 of file CodeGenerator_v2.cxx.

969  {
970 
971  // Construct the file name:
972  const std::string fileName = dir + "/" + classname + ".cxx";
973 
974  // If the file already exists, let's not overwrite it:
975  struct stat fileInfo;
976  if( ! stat( fileName.c_str(), &fileInfo ) ) return StatusCode::SUCCESS;
977 
978  // Let everyone know what we're doing:
979  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "Version2::writeSource" )
980  << "Generating file: " << fileName;
981 
982  // Open the header file (overwriting a possibly existing file):
983  std::ofstream source( fileName.c_str() );
984 
985  // Add the common header to the file:
986  source << CODE_COMMENT << std::endl << std::endl;
987 
988  if( metadata.container() ) {
989  source << "#include <limits>" << std::endl;
990  source << "#include <stdexcept>" << std::endl << std::endl;
991  }
992 
993  // Extra ROOT include(s):
994  source << "#include <TPRegexp.h>" << std::endl;
995  source << "#include <TList.h>" << std::endl;
996  source << "#include <TDataMember.h>" << std::endl << std::endl;
997 
998  // Include the class's header:
999  source << "#include \"" << classname << ".h\"" << std::endl
1000  << std::endl;
1001 
1002  if( metadata.container() ) {
1003  source << "ClassImp( D3PDReader::" << classname << "Element )"
1004  << std::endl;
1005  }
1006  source << "ClassImp( D3PDReader::" << classname << " )" << std::endl
1007  << std::endl;
1008 
1009  source << "namespace D3PDReader {" << std::endl << std::endl;
1010 
1011  if( metadata.container() ) {
1012  //
1013  // Produce the constructor of the proxy class:
1014  //
1015  const std::string spacer( ( 2 * classname.size() ) + 21, ' ' );
1016  source << " /**" << std::endl;
1017  source << " * This constructor can be used to create new proxy "
1018  << "objects from scratch." << std::endl;
1019  source << " * Since the constructor of such an object is quite "
1020  << "complicated and" << std::endl;
1021  source << " * error prone, it is only visible to the parent "
1022  << "class " << classname << "." << std::endl;
1023  source << " */" << std::endl;
1024  source << " " << classname << "Element::" << classname
1025  << "Element( size_t index, const " << classname
1026  << "& parent )" << std::endl;
1027  source << " : UserD3PDObjectElement( index, parent )";
1028  std::map< std::string, int > variableCounter;
1029  std::set< ObjectMetadata::Variable >::const_iterator itr =
1030  metadata.variables().begin();
1031  std::set< ObjectMetadata::Variable >::const_iterator end =
1032  metadata.variables().end();
1033  for( ; itr != end; ++itr ) {
1034  // Ignore the container size variable:
1035  if( ( itr->name() == "n" ) || ( itr->name() == "N" ) ) continue;
1036 
1037  source << "," << std::endl;
1038  if( variableCounter.find( itr->name() ) ==
1039  variableCounter.end() ) {
1040  source << " " << variableName( itr->name() )
1041  << "( parent." << variableName( itr->name() )
1042  << ", index )";
1043  variableCounter[ itr->name() ] = 1;
1044  } else {
1045  source << " " << variableName( itr->name() )
1046  << variableCounter[ itr->name() ]
1047  << "( parent." << variableName( itr->name() )
1048  << variableCounter[ itr->name() ] << ", index )";
1049  variableCounter[ itr->name() ]++;
1050  }
1051  }
1052  source << "," << std::endl;
1053  source << " fParent( &parent ), fIndex( index ) {"
1054  << std::endl << std::endl;
1055  source << " }" << std::endl << std::endl;
1056 
1057  //
1058  // Produce the copy-constructor of the proxy class:
1059  //
1060  source << " /**" << std::endl;
1061  source << " * This constructor is useful for creating copies of "
1062  << "proxy objects." << std::endl;
1063  source << " * Such objects are fairly cheap to copy, so the user"
1064  << " is allowed to have" << std::endl;
1065  source << " * his/her containers of them inside an analysis "
1066  << "code. (To select and" << std::endl;
1067  source << " * sort objects according to some criteria for "
1068  << "instance.)" << std::endl;
1069  source << " *" << std::endl;
1070  source << " * @param parent The proxy object that should be "
1071  << "copied" << std::endl;
1072  source << " */" << std::endl;
1073  source << " " << classname << "Element::" << classname
1074  << "Element( const " << classname << "Element& parent )"
1075  << std::endl;
1076  source << " : UserD3PDObjectElement( parent )";
1077  variableCounter.clear();
1078  itr = metadata.variables().begin();
1079  end = metadata.variables().end();
1080  for( ; itr != end; ++itr ) {
1081  // Ignore the container size variable:
1082  if( ( itr->name() == "n" ) || ( itr->name() == "N" ) ) continue;
1083 
1084  source << "," << std::endl;
1085  if( variableCounter.find( itr->name() ) ==
1086  variableCounter.end() ) {
1087  source << " " << variableName( itr->name() )
1088  << "( parent." << variableName( itr->name() )
1089  << " )";
1090  variableCounter[ itr->name() ] = 1;
1091  } else {
1092  source << " " << variableName( itr->name() )
1093  << variableCounter[ itr->name() ]
1094  << "( parent." << variableName( itr->name() )
1095  << variableCounter[ itr->name() ] << " )";
1096  variableCounter[ itr->name() ]++;
1097  }
1098  }
1099  source << "," << std::endl;
1100  source << " fParent( parent.fParent ), "
1101  << "fIndex( parent.fIndex ) {" << std::endl << std::endl;
1102  source << " }" << std::endl << std::endl;
1103 
1104  //
1105  // Produce the GetParent() function of the proxy class:
1106  //
1107  source << " /**" << std::endl;
1108  source << " * This function can be used to access the parent "
1109  << "object of this" << std::endl;
1110  source << " * proxy object. It can come in handy when optimizing"
1111  << " an analysis code." << std::endl;
1112  source << " *" << std::endl;
1113  source << " * @returns A reference to this object's parent"
1114  << std::endl;
1115  source << " */" << std::endl;
1116  source << " const " << classname << "* " << classname
1117  << "Element::GetParent() const {" << std::endl << std::endl;
1118  source << " return fParent;" << std::endl;
1119  source << " }" << std::endl << std::endl;
1120 
1121  //
1122  // Produce the GetIndex() function of the proxy class:
1123  //
1124  source << " /**" << std::endl;
1125  source << " * This function can be used to access the index of "
1126  << "this proxy object" << std::endl;
1127  source << " * inside the parent container. It can come in handy "
1128  << "when optimizing an" << std::endl;
1129  source << " * analysis code." << std::endl;
1130  source << " *" << std::endl;
1131  source << " * @returns The index of the proxy in the object's "
1132  << "parent" << std::endl;
1133  source << " */" << std::endl;
1134  source << " size_t " << classname << "Element::GetIndex() const {"
1135  << std::endl << std::endl;
1136  source << " return fIndex;" << std::endl;
1137  source << " }" << std::endl << std::endl;
1138  }
1139 
1140  //
1141  // Produce the (input) constructor:
1142  //
1143  source << " /**" << std::endl;
1144  source << " * This constructor should be used when the object will "
1145  << "be used to read" << std::endl;
1146  source << " * variables from an existing ntuple. The object will "
1147  << "also be able to" << std::endl;
1148  source << " * output variables, but it will also need to read them "
1149  << "from somewhere." << std::endl;
1150  source << " *" << std::endl;
1151  source << " * @param master Reference to the variable holding the "
1152  << "current " << "event number" << std::endl;
1153  source << " * @param prefix Prefix of the variables in the D3PD"
1154  << std::endl;
1155  source << " */" << std::endl;
1156  source << " " << classname << "::" << classname
1157  << "( const ::Long64_t& master, const char* prefix )"
1158  << std::endl;
1159  source << " : UserD3PDObject( master, prefix ),"
1160  << std::endl;
1161  source << " fHandles()," << std::endl;
1162  source << " fFromInput( kTRUE )," << std::endl;
1163  source << " fPrefix( prefix ) {" << std::endl << std::endl;
1164  source << " SetVarHandles( &master );" << std::endl;
1165  source << " }" << std::endl << std::endl;
1166 
1167  //
1168  // Produce the (output) constructor:
1169  //
1170  source << " /**" << std::endl;
1171  source << " * This constructor can be used when the object will "
1172  << "only have to output" << std::endl;
1173  source << " * (and temporarily store) new information into an "
1174  << "output ntuple. For" << std::endl;
1175  source << " * instance when one wants to create a selected/modified"
1176  << " list of information." << std::endl;
1177  source << " *" << std::endl;
1178  source << " * @param prefix Prefix of the variables in the D3PD"
1179  << std::endl;
1180  source << " */" << std::endl;
1181  source << " " << classname << "::" << classname
1182  << "( const char* prefix )" << std::endl;
1183  source << " : UserD3PDObject( prefix ),"
1184  << std::endl;
1185  source << " fHandles()," << std::endl;
1186  source << " fFromInput( kFALSE )," << std::endl;
1187  source << " fPrefix( prefix ) {" << std::endl << std::endl;
1188  source << " SetVarHandles( 0 );" << std::endl;
1189  source << " }" << std::endl << std::endl;
1190 
1191  //
1192  // Produce the destructor:
1193  //
1194  if( metadata.container() ) {
1195  source << " /**" << std::endl;
1196  source << " * The destructor needs to delete all the allocated "
1197  << "objects." << std::endl;
1198  source << " */" << std::endl;
1199  source << " " << classname << "::~" << classname << "() {"
1200  << std::endl
1201  << std::endl;
1202  source << " for( size_t i = 0; i < fProxies.size(); ++i ) {"
1203  << std::endl;
1204  source << " delete fProxies[ i ];" << std::endl;
1205  source << " }" << std::endl;
1206  source << " }" << std::endl << std::endl;
1207  }
1208 
1209  //
1210  // Produce the prefix handling function(s):
1211  //
1212  source << " /**" << std::endl;
1213  source << " * @returns The branch name prefix used by the object"
1214  << std::endl;
1215  source << " */" << std::endl;
1216  source << " const char* " << classname << "::GetPrefix() const {"
1217  << std::endl << std::endl;
1218  source << " return fPrefix;" << std::endl;
1219  source << " }" << std::endl << std::endl;
1220 
1221  source << " /**" << std::endl;
1222  source << " * @param prefix The prefix that should be used for the "
1223  << "variables" << std::endl;
1224  source << " */" << std::endl;
1225  source << " void " << classname << "::SetPrefix( const char* prefix "
1226  << ") {" << std::endl << std::endl;
1227  source << " // Call the base class's function:" << std::endl;
1228  source << " UserD3PDObject::SetPrefix( prefix );" << std::endl
1229  << std::endl;
1230  source << " // Remember the prefix:" << std::endl;
1231  source << " fPrefix = prefix;" << std::endl << std::endl;
1232  source << " // Set all the variable names:" << std::endl;
1233  source << " std::map< TString, VarHandleBase* >::const_iterator "
1234  << "itr = fHandles.begin();" << std::endl;
1235  source << " std::map< TString, VarHandleBase* >::const_iterator "
1236  << "end = fHandles.end();" << std::endl;
1237  source << " for( ; itr != end; ++itr ) {" << std::endl;
1238  source << " itr->second->SetName( ::TString( prefix ) + "
1239  << "itr->first );" << std::endl;
1240  source << " }" << std::endl << std::endl;
1241  source << " return;" << std::endl;
1242  source << " }" << std::endl << std::endl;
1243 
1244  //
1245  // Produce the ReadFrom(...) function:
1246  //
1247  source << " /**" << std::endl;
1248  source << " * This function should be called every time a new TFile"
1249  << " is opened" << std::endl;
1250  source << " * by your analysis code." << std::endl;
1251  source << " *" << std::endl;
1252  source << " * @param tree Pointer to the TTree with the variables"
1253  << std::endl;
1254  source << " */" << std::endl;
1255  source << " void " << classname << "::ReadFrom( TTree* tree ) {"
1256  << std::endl << std::endl;
1257  source << " // Check if the object will be able to read from the "
1258  << "TTree:" << std::endl;
1259  source << " if( ! fFromInput ) {" << std::endl;
1260  source << " Error( \"ReadFrom\", \"The object was not created "
1261  << "with the correct\" );" << std::endl;
1262  source << " Error( \"ReadFrom\", \"constructor to read data "
1263  << "from a D3PD!\" );" << std::endl;
1264  source << " return;" << std::endl;
1265  source << " }" << std::endl << std::endl;
1266  source << " // Call the base class's function:" << std::endl;
1267  source << " UserD3PDObject::ReadFrom( tree );" << std::endl
1268  << std::endl;
1269  source << " // Call ReadFrom(...) on all the variables:"
1270  << std::endl;
1271  source << " std::map< TString, VarHandleBase* >::const_iterator "
1272  << "itr = fHandles.begin();" << std::endl;
1273  source << " std::map< TString, VarHandleBase* >::const_iterator "
1274  << "end = fHandles.end();" << std::endl;
1275  source << " for( ; itr != end; ++itr ) {" << std::endl;
1276  source << " itr->second->ReadFrom( tree );" << std::endl;
1277  source << " }" << std::endl << std::endl;
1278  source << " return;" << std::endl;
1279  source << " }" << std::endl << std::endl;
1280 
1281  //
1282  // Produce the WriteTo(...) function:
1283  //
1284  source << " /**" << std::endl;
1285  source << " * This function can be called to connect the active "
1286  << "variables of the object" << std::endl;
1287  source << " * to an output TTree. It can be called multiple times, "
1288  << "then the variables" << std::endl;
1289  source << " * will be written to multiple TTrees." << std::endl;
1290  source << " *" << std::endl;
1291  source << " * @param tree Pointer to the TTree where the variables "
1292  << "should be written" << std::endl;
1293  source << " */" << std::endl;
1294  source << " void " << classname << "::WriteTo( TTree* tree ) {"
1295  << std::endl << std::endl;
1296  source << " // Call the base class's function:" << std::endl;
1297  source << " UserD3PDObject::WriteTo( tree );" << std::endl
1298  << std::endl;
1299  source << " // Call WriteTo(...) on all the variables:"
1300  << std::endl;
1301  source << " std::map< TString, VarHandleBase* >::const_iterator "
1302  << "itr = fHandles.begin();" << std::endl;
1303  source << " std::map< TString, VarHandleBase* >::const_iterator "
1304  << "end = fHandles.end();" << std::endl;
1305  source << " for( ; itr != end; ++itr ) {" << std::endl;
1306  source << " itr->second->WriteTo( tree );" << std::endl;
1307  source << " }" << std::endl << std::endl;
1308  source << " return;" << std::endl;
1309  source << " }" << std::endl << std::endl;
1310 
1311  //
1312  // Produce the SetActive(...) function:
1313  //
1314  source << " /**" << std::endl;
1315  source << " * This is a convenience function for turning the "
1316  << "branches active or" << std::endl;
1317  source << " * inactive conveniently. If the parameter is set to "
1318  << "<code>kTRUE</code>" << std::endl;
1319  source << " * then the branches available from the input which "
1320  << "match the given" << std::endl;
1321  source << " * pattern are turned active."
1322  << std::endl;
1323  source << " * When it's set to <code>kFALSE</code> then all the "
1324  << "variables matching" << std::endl;
1325  source << " * the pattern are turned inactive." << std::endl;
1326  source << " *" << std::endl;
1327  source << " * @param active Flag behaving as explained above"
1328  << std::endl;
1329  source << " * @param pattern Regular expression specifying which "
1330  << "branches to modify" << std::endl;
1331  source << " */" << std::endl;
1332  source << " void " << classname << "::SetActive( ::Bool_t active, "
1333  << "const ::TString& pattern ) {" << std::endl
1334  << std::endl;
1335  source << " // Call the base class's function:" << std::endl;
1336  source << " UserD3PDObject::SetActive( active, pattern );"
1337  << std::endl << std::endl;
1338  source << " ::TPRegexp re( pattern );" << std::endl << std::endl;
1339  source << " std::map< TString, VarHandleBase* >::const_iterator "
1340  << "itr = fHandles.begin();" << std::endl;
1341  source << " std::map< TString, VarHandleBase* >::const_iterator "
1342  << "end = fHandles.end();" << std::endl;
1343  source << " for( ; itr != end; ++itr ) {" << std::endl;
1344  source << " if( ! re.Match( fPrefix + itr->first ) ) continue;"
1345  << std::endl;
1346  source << " if( active ) {" << std::endl;
1347  source << " if( itr->second->IsAvailable() ) "
1348  << "itr->second->SetActive( active );" << std::endl;
1349  source << " } else {" << std::endl;
1350  source << " itr->second->SetActive( active );" << std::endl;
1351  source << " }" << std::endl;
1352  source << " }" << std::endl << std::endl;
1353  source << " return;" << std::endl;
1354  source << " }" << std::endl << std::endl;
1355 
1356  //
1357  // Produce the ReadAllActive(...) function:
1358  //
1359  source << " /**" << std::endl;
1360  source << " * This function can be used to read in all the branches"
1361  << " from the input" << std::endl;
1362  source << " * TTree which are set active for writing out. This can "
1363  << "simplify writing" << std::endl;
1364  source << " * event selector codes immensely. Remember to set the "
1365  << "desired variable" << std::endl;
1366  source << " * active before calling this function." << std::endl;
1367  source << " */" << std::endl;
1368  source << " void " << classname << "::ReadAllActive() {" << std::endl
1369  << std::endl;
1370  source << " // Check if it makes sense to call this function:"
1371  << std::endl;
1372  source << " if( ! fFromInput ) {" << std::endl;
1373  source << " static ::Bool_t wPrinted = kFALSE;" << std::endl;
1374  source << " if( ! wPrinted ) {" << std::endl;
1375  source << " Warning( \"ReadAllActive\", "
1376  << "\"Function only meaningful when used on objects\" );"
1377  << std::endl;
1378  source << " Warning( \"ReadAllActive\", "
1379  << "\"which are used to read information from a D3PD\" );"
1380  << std::endl;
1381  source << " wPrinted = kTRUE;" << std::endl;
1382  source << " }" << std::endl;
1383  source << " }" << std::endl << std::endl;
1384  source << " // Call the base class's function:" << std::endl;
1385  source << " UserD3PDObject::ReadAllActive();" << std::endl
1386  << std::endl;
1387  source << " // Read in the current entry for each active "
1388  << "variable:" << std::endl;
1389  source << " std::map< TString, VarHandleBase* >::const_iterator "
1390  << "itr = fHandles.begin();" << std::endl;
1391  source << " std::map< TString, VarHandleBase* >::const_iterator "
1392  << "end = fHandles.end();" << std::endl;
1393  source << " for( ; itr != end; ++itr ) {" << std::endl;
1394  source << " if( ! itr->second->IsActive() ) continue;"
1395  << std::endl;
1396  source << " itr->second->ReadCurrentEntry();" << std::endl;
1397  source << " }" << std::endl << std::endl;
1398  source << " return;" << std::endl;
1399  source << " }" << std::endl << std::endl;
1400 
1401  //
1402  // Produce the GetStatistics() function:
1403  //
1404  source << " /**" << std::endl;
1405  source << " * This function can be used to get information about "
1406  << "the access" << std::endl;
1407  source << " * pattern/statistics of the job. It should be called "
1408  << "at the end of" << std::endl;
1409  source << " * an analysis job to get the information about the "
1410  << "performance of the" << std::endl;
1411  source << " * analysis." << std::endl;
1412  source << " *" << std::endl;
1413  source << " * @returns An object describing the D3PD access "
1414  << "statistics" << std::endl;
1415  source << " */" << std::endl;
1416  source << " D3PDReadStats " << classname
1417  << "::GetStatistics() const {" << std::endl << std::endl;
1418  source << " // The result object:" << std::endl;
1419  source << " D3PDReadStats result = "
1420  << "UserD3PDObject::GetStatistics();" << std::endl << std::endl;
1421  source << " // Add the statistics from each variable to the "
1422  << "result:" << std::endl;
1423  source << " std::map< ::TString, VarHandleBase* >::const_iterator"
1424  << " itr = fHandles.begin();" << std::endl;
1425  source << " std::map< ::TString, VarHandleBase* >::const_iterator"
1426  << " end = fHandles.end();" << std::endl;
1427  source << " for( ; itr != end; ++itr ) {" << std::endl;
1428  source << " result.AddVariable( itr->second->GetStatistics() );"
1429  << std::endl;
1430  source << " }" << std::endl << std::endl;
1431  source << " return result;" << std::endl;
1432  source << " }" << std::endl << std::endl;
1433 
1434  //
1435  // Produce the Set function:
1436  //
1437  source << " /**" << std::endl;
1438  source << " * This function can be used to copy the contents of the"
1439  << " entire object" << std::endl;
1440  source << " * for a given event. This can be useful for instance "
1441  << "when the user" << std::endl;
1442  source << " * wants to copy all information to an output file, and "
1443  << "modify it a bit," << std::endl;
1444  source << " * and only then write it out." << std::endl;
1445  source << " *" << std::endl;
1446  source << " * @param parent The object to copy the information from"
1447  << std::endl;
1448  source << " * @returns This same object, for convenience reasons"
1449  << std::endl;
1450  source << " */" << std::endl;
1451  source << " " << classname << "& " << classname << "::Set( const "
1452  << classname << "& parent ) {" << std::endl << std::endl;
1453  source << " // Check if this function can be used on the object:"
1454  << std::endl;
1455  source << " if( fFromInput ) {" << std::endl;
1456  source << " Error( \"Set\", "
1457  << "\"Objects used for reading a D3PD can't be modified!\" );"
1458  << std::endl;
1459  source << " return *this;" << std::endl;
1460  source << " }" << std::endl << std::endl;
1461  source << " // Call the base class's function:" << std::endl;
1462  source << " UserD3PDObject::Set( parent );" << std::endl
1463  << std::endl;
1464  std::map< std::string, int > variableCounter;
1465  std::set< ObjectMetadata::Variable >::const_iterator itr =
1466  metadata.variables().begin();
1467  std::set< ObjectMetadata::Variable >::const_iterator end =
1468  metadata.variables().end();
1469  for( ; itr != end; ++itr ) {
1470  std::string postfix = "";
1471  if( variableCounter.find( itr->name() ) == variableCounter.end() ) {
1472  variableCounter[ itr->name() ] = 1;
1473  } else {
1474  postfix =
1475  std::to_string( variableCounter[ itr->name() ] );
1476  variableCounter[ itr->name() ]++;
1477  }
1478  source << " if( parent." << variableName( itr->name() )
1479  << postfix << ".IsAvailable() && "
1480  << variableName( itr->name() ) << postfix
1481  << ".IsActive() ) {" << std::endl;
1482  if( itr->primitive() ) {
1483  source << " " << variableName( itr->name() ) << postfix
1484  << "() = parent." << variableName( itr->name() )
1485  << postfix << "();" << std::endl;
1486  } else {
1487  source << " *( " << variableName( itr->name() )
1488  << postfix << "() ) = *( parent."
1489  << variableName( itr->name() ) << postfix
1490  << "() );" << std::endl;
1491  }
1492  source << " } else {" << std::endl;
1493  if( itr->primitive() ) {
1494  source << " " << variableName( itr->name() )
1495  << postfix << "() = 0;" << std::endl;
1496  } else {
1497  source << " " << variableName( itr->name() )
1498  << postfix << "()->clear();" << std::endl;
1499  }
1500  source << " }" << std::endl;
1501  }
1502  source << std::endl << " return *this;" << std::endl;
1503  source << " }" << std::endl << std::endl;
1504 
1505  if( metadata.container() ) {
1506  //
1507  // Produce the Clear function:
1508  //
1509  source << " /**" << std::endl;
1510  source << " * This function makes it easier to clear out the "
1511  << "object completely." << std::endl;
1512  source << " * It cleares all the vector variables, and sets the "
1513  << "element number" << std::endl;
1514  source << " * variable to 0. Very useful when performing object "
1515  << "selection." << std::endl;
1516  source << " * The option argument is not used at the moment for "
1517  << "anything." << std::endl;
1518  source << " * It's only there because the <code>Clear</code> "
1519  << "function defined in" << std::endl;
1520  source << " * TObject has this parameter as well." << std::endl;
1521  source << " *" << std::endl;
1522  source << " * @param option Ignored at the moment" << std::endl;
1523  source << " */" << std::endl;
1524  source << " void " << classname << "::Clear( Option_t* opt ) {"
1525  << std::endl << std::endl;
1526  source << " // Check if this function can be used on the "
1527  << "object:" << std::endl;
1528  source << " if( fFromInput ) {" << std::endl;
1529  source << " Error( \"Clear\", "
1530  << "\"Objects used for reading a D3PD can't be cleared!\" );"
1531  << std::endl;
1532  source << " return;" << std::endl;
1533  source << " }" << std::endl << std::endl;
1534  source << " // Call the base class's function:" << std::endl;
1535  source << " UserD3PDObject::Clear( opt );" << std::endl
1536  << std::endl;
1537  source << " // Clear each variable:" << std::endl;
1538  source << " std::map< ::TString, VarHandleBase* >::const_iterator"
1539  << " itr = fHandles.begin();" << std::endl;
1540  source << " std::map< ::TString, VarHandleBase* >::const_iterator"
1541  << " end = fHandles.end();" << std::endl;
1542  source << " for( ; itr != end; ++itr ) {" << std::endl;
1543  source << " itr->second->Clear();" << std::endl;
1544  source << " }" << std::endl << std::endl;
1545  source << " return;" << std::endl;
1546  source << " }" << std::endl << std::endl;
1547 
1548  //
1549  // Produce the Add function:
1550  //
1551  source << " /**" << std::endl;
1552  source << " * This function can be used to easily add an "
1553  << "'element' describing one" << std::endl;
1554  source << " * object to an output collection. Comes in very "
1555  << "handy when performing" << std::endl;
1556  source << " * object selection." << std::endl;
1557  source << " *" << std::endl;
1558  source << " * Note that variables which are not available from "
1559  << "the input, will be" << std::endl;
1560  source << " * filled with dummy values." << std::endl;
1561  source << " *" << std::endl;
1562  source << " * @param el The 'element' that should be added to "
1563  << "the collection" << std::endl;
1564  source << " */" << std::endl;
1565  source << " " << classname << "& " << classname << "::Add( const "
1566  << classname << "Element& el ) {" << std::endl << std::endl;
1567  source << " // Check if this function can be used on the "
1568  << "object:" << std::endl;
1569  source << " if( fFromInput ) {" << std::endl;
1570  source << " Error( \"Add\", \"Objects used for reading a "
1571  << "D3PD can't be modified!\" );" << std::endl;
1572  source << " return *this;" << std::endl;
1573  source << " }" << std::endl << std::endl;
1574  source << " // Call the base class's function:" << std::endl;
1575  source << " UserD3PDObject::Add( el );" << std::endl
1576  << std::endl;
1577  variableCounter.clear();
1578  itr = metadata.variables().begin();
1579  end = metadata.variables().end();
1580  for( ; itr != end; ++itr ) {
1581  // Treat the size variable in a special way:
1582  if( itr->name() == "n" ) {
1583  source << " ++( n() );" << std::endl;
1584  continue;
1585  }
1586  if( itr->name() == "N" ) {
1587  source << " ++( N() );" << std::endl;
1588  continue;
1589  }
1590 
1591  // Construct a possible post-fix for the variable name:
1592  std::string postfix = "";
1593  if( variableCounter.find( itr->name() ) ==
1594  variableCounter.end() ) {
1595  variableCounter[ itr->name() ] = 1;
1596  } else {
1597  postfix =
1598  std::to_string( variableCounter[ itr->name() ] );
1599  variableCounter[ itr->name() ]++;
1600  }
1601 
1602  source << " if( el." << variableName( itr->name() )
1603  << postfix << ".IsAvailable() && "
1604  << variableName( itr->name() ) << postfix
1605  << ".IsActive() ) {" << std::endl;
1606  source << " " << variableName( itr->name() ) << postfix
1607  << "()->push_back( el." << variableName( itr->name() )
1608  << postfix << "() );" << std::endl;
1609  source << " } else {" << std::endl;
1610 
1611  // Extract the type of the variable we're dealing with:
1612  bool ok = true;
1613  const std::string type =
1614  vectorTemplateArgument( itr->type(), ok );
1615  if( ! ok ) {
1616  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR,
1617  "Version2::writeSource" )
1618  << "Unexpected variable type encountered for "
1619  << "container dumper: " << itr->type();
1620  return StatusCode::FAILURE;
1621  }
1622 
1623  // Primitive and complex types have to be treated differently if
1624  // they don't exist in the input:
1625  source << " " << variableName( itr->name() )
1626  << postfix << "()->push_back( ";
1627  if( isPrimitive( type ) ) {
1628  source << "std::numeric_limits< " << type << " >::min()";
1629  } else {
1630  source << type << "()";
1631  }
1632  source << " );" << std::endl;
1633  source << " }" << std::endl;
1634  }
1635  source << " return *this;" << std::endl;
1636  source << " }" << std::endl << std::endl;
1637 
1638  //
1639  // Try to find the size variable's name:
1640  //
1641  static const int NSIZEVARS = 2;
1642  static const char* const SIZEVARS[ NSIZEVARS ] = { "n", "N" };
1643  std::string sizeVariable = "";
1644  ObjectMetadata::Variable var;
1645  for( int i = 0; i < NSIZEVARS; ++i ) {
1646  var.setName( SIZEVARS[ i ] );
1647  if( metadata.variables().find( var ) !=
1648  metadata.variables().end() ) {
1649  sizeVariable = var.name() + "()";
1650  break;
1651  }
1652  }
1653 
1654  //
1655  // Produce the [] operators:
1656  //
1657  source << " /**" << std::endl;
1658  source << " * This operator can be used to get access to one "
1659  << "element in the" << std::endl;
1660  source << " * collection. This element can then be passed around"
1661  << " between parts" << std::endl;
1662  source << " * of the analysis code easily." << std::endl;
1663  source << " *" << std::endl;
1664  source << " * This version is useful when modifying the variable"
1665  << " contents through" << std::endl;
1666  source << " * the proxy objects." << std::endl;
1667  source << " *" << std::endl;
1668  source << " * @param index Index of the element inside the "
1669  << "collection" << std::endl;
1670  source << " */" << std::endl;
1671  source << " " << classname << "Element& " << classname
1672  << "::operator[]( size_t index ) {" << std::endl
1673  << std::endl;
1674  source << " // Check whether the index makes sense:"
1675  << std::endl;
1676  source << " if( index >= static_cast< size_t >( "
1677  << ( sizeVariable == "" ? "1000000" : sizeVariable )
1678  << " ) ) {" << std::endl;
1679  source << " Fatal( \"operator[]\", \"Proxy with index %i"
1680  << " requested\", static_cast< int >( index ) );"
1681  << std::endl;
1682  source << " // The previous should've stopped the code "
1683  << "already," << std::endl;
1684  source << " // but let's go for sure..." << std::endl;
1685  source << " throw std::runtime_error( \"Too large proxy "
1686  << "index\" );" << std::endl;
1687  source << " }" << std::endl << std::endl;
1688  source << " // Make sure that the proxy exists:" << std::endl;
1689  source << " while( fProxies.size() <= index ) {" << std::endl;
1690  source << " fProxies.push_back( new " << classname
1691  << "Element( fProxies.size(), *this ) );" << std::endl;
1692  source << " }" << std::endl;
1693  source << " return *fProxies[ index ];" << std::endl;
1694  source << " }" << std::endl << std::endl;
1695 
1696  source << " /**" << std::endl;
1697  source << " * This operator can be used to get access to one "
1698  << "element in the" << std::endl;
1699  source << " * collection. This element can then be passed around"
1700  << " between parts" << std::endl;
1701  source << " * of the analysis code easily." << std::endl;
1702  source << " *" << std::endl;
1703  source << " * This version is useful when only reading the "
1704  << "variables." << std::endl;
1705  source << " *" << std::endl;
1706  source << " * @param index Index of the element inside the "
1707  << "collection" << std::endl;
1708  source << " */" << std::endl;
1709  source << " const " << classname << "Element& " << classname
1710  << "::operator[]( size_t index ) const {" << std::endl
1711  << std::endl;
1712  source << " // Check whether the index makes sense:"
1713  << std::endl;
1714  source << " if( index >= static_cast< size_t >( "
1715  << ( sizeVariable == "" ? "1000000" : sizeVariable )
1716  << " ) ) {" << std::endl;
1717  source << " Fatal( \"operator[]\", \"Proxy with index %i"
1718  << " requested\", static_cast< int >( index ) );"
1719  << std::endl;
1720  source << " // The previous should've stopped the code "
1721  << "already," << std::endl;
1722  source << " // but let's go for sure..." << std::endl;
1723  source << " throw std::runtime_error( \"Too large proxy "
1724  << "index\" );" << std::endl;
1725  source << " }" << std::endl << std::endl;
1726  source << " // Make sure that the proxy exists:" << std::endl;
1727  source << " while( fProxies.size() <= index ) {" << std::endl;
1728  source << " fProxies.push_back( new " << classname
1729  << "Element( fProxies.size(), *this ) );" << std::endl;
1730  source << " }" << std::endl;
1731  source << " return *fProxies[ index ];" << std::endl;
1732  source << " }" << std::endl << std::endl;
1733 
1734  //
1735  // Produce the += operator:
1736  //
1737  source << " /**" << std::endl;
1738  source << " * A convenience operator for adding an 'element' to "
1739  << "this collection." << std::endl;
1740  source << " *" << std::endl;
1741  source << " * @see Add" << std::endl;
1742  source << " * @param el The 'element' that should be added to "
1743  << "the collection" << std::endl;
1744  source << " */" << std::endl;
1745  source << " " << classname << "& " << classname
1746  << "::operator+=( const " << classname << "Element& el ) {"
1747  << std::endl << std::endl;
1748  source << " return this->Add( el );" << std::endl;
1749  source << " }" << std::endl << std::endl;
1750  }
1751 
1752  //
1753  // Produce the GetVarHandle(...) function:
1754  //
1755  source << " /**" << std::endl;
1756  source << " * This function is used internally to access VarHandle "
1757  << "members" << std::endl;
1758  source << " * by name. This is necessary to push some setup from "
1759  << "compile time" << std::endl;
1760  source << " * to run time. It may sound weird, but it makes a lot "
1761  << "of sense for large" << std::endl;
1762  source << " * classes." << std::endl;
1763  source << " *" << std::endl;
1764  source << " * @param name The name of the C++ variable (not of the "
1765  << "branch)" << std::endl;
1766  source << " * @returns A pointer to the VarHandle object"
1767  << std::endl;
1768  source << " */" << std::endl;
1769  source << " VarHandleBase* " << classname
1770  << "::GetVarHandle( const char* name ) {" << std::endl
1771  << std::endl;
1772  variableCounter.clear();
1773  itr = metadata.variables().begin();
1774  end = metadata.variables().end();
1775  for( ; itr != end; ++itr ) {
1776  // Construct a possible post-fix for the variable name:
1777  std::string postfix = "";
1778  if( variableCounter.find( itr->name() ) ==
1779  variableCounter.end() ) {
1780  variableCounter[ itr->name() ] = 1;
1781  } else {
1782  postfix =
1783  std::to_string( variableCounter[ itr->name() ] );
1784  variableCounter[ itr->name() ]++;
1785  }
1786  if( itr == metadata.variables().begin() ) {
1787  source << " if( ! ::strcmp( name, \""
1788  << variableName( itr->name() ) << postfix << "\" ) ) {"
1789  << std::endl;
1790  } else {
1791  source << " else if( ! ::strcmp( name, \""
1792  << variableName( itr->name() ) << postfix << "\" ) ) {"
1793  << std::endl;
1794  }
1795  source << " return &" << variableName( itr->name() )
1796  << postfix << ";" << std::endl;
1797  source << " }" << std::endl;
1798  }
1799  source << std::endl << " Error( \"GetVarHandle\", \"Variable \\\"%s"
1800  << "\\\" unknown\", name );" << std::endl;
1801  source << " return 0;" << std::endl;
1802  source << " }" << std::endl << std::endl;
1803 
1804  //
1805  // Produce the SetVarHandles(...) function:
1806  //
1807  source << " /**" << std::endl;
1808  source << " * This function is used internally to set up all the "
1809  << "VarHandle members" << std::endl;
1810  source << " * of the class. It speeds up compilation *a lot* to do "
1811  << "this at run-time" << std::endl;
1812  source << " * like this, instead of putting a lot of lines of code "
1813  << "operating on" << std::endl;
1814  source << " * the std::map member." << std::endl;
1815  source << " *" << std::endl;
1816  source << " * @param master Pointer to the master index, or a null "
1817  << "pointer" << std::endl;
1818  source << " */" << std::endl;
1819  source << " void " << classname << "::SetVarHandles( const "
1820  << "::Long64_t* master ) {" << std::endl << std::endl;
1821  source << " // Create a list of variable-branch name pairs:"
1822  << std::endl;
1823  source << " static const Int_t NVARNAMES = "
1824  << metadata.variables().size() << ";" << std::endl;
1825  source << " static const char* VARNAMES[ NVARNAMES ][ 2 ] = {"
1826  << std::endl;
1827  variableCounter.clear();
1828  itr = metadata.variables().begin();
1829  end = metadata.variables().end();
1830  for( ; itr != end; ++itr ) {
1831  // Construct a possible post-fix for the variable name:
1832  std::string postfix = "";
1833  if( variableCounter.find( itr->name() ) ==
1834  variableCounter.end() ) {
1835  variableCounter[ itr->name() ] = 1;
1836  } else {
1837  postfix =
1838  std::to_string( variableCounter[ itr->name() ] );
1839  variableCounter[ itr->name() ]++;
1840  }
1841  // Add the names:
1842  source << " { \"" << variableName( itr->name() ) << postfix
1843  << "\", \"" << variableName( itr->name() ) << "\" }";
1844  if( ++itr != end ) {
1845  source << ",";
1846  }
1847  --itr;
1848  source << std::endl;
1849  }
1850  source << " };" << std::endl << std::endl;
1851  source << " // Set up the fHandles map using this list:"
1852  << std::endl;
1853  source << " for( Int_t i = 0; i < NVARNAMES; ++i ) {"
1854  << std::endl;
1855  source << " VarHandleBase* vh = "
1856  << "GetVarHandle( VARNAMES[ i ][ 0 ] );" << std::endl;
1857  source << " vh->SetName( fPrefix + VARNAMES[ i ][ 1 ] );"
1858  << std::endl;
1859  source << " vh->SetMaster( master );" << std::endl;
1860  source << " fHandles[ VARNAMES[ i ][ 0 ] ] = vh;" << std::endl;
1861  source << " }" << std::endl << std::endl;
1862 
1863  /*
1864  source << " // Access the class's dictionary:" << std::endl;
1865  source << " ::TClass* cl = IsA();" << std::endl;
1866  source << " // Get a list of all members:" << std::endl;
1867  source << " ::TList* members = cl->GetListOfDataMembers();"
1868  << std::endl;
1869  source << " // Set up all the VarHandle members:" << std::endl;
1870  source << " for( ::Int_t i = 0; i < members->GetSize(); ++i ) {"
1871  << std::endl;
1872  source << " // Check that it's a VarHandle:" << std::endl;
1873  source << " ::TDataMember* m = dynamic_cast< ::TDataMember* >("
1874  << " members->At( i ) );" << std::endl;
1875  source << " if( ! m ) {" << std::endl;
1876  source << " Fatal( \"SetVarHandles\", \"Found a wrong "
1877  << "data member\" );" << std::endl;
1878  source << " continue;" << std::endl;
1879  source << " }" << std::endl;
1880  source << " const ::TString type = m->GetTypeName();"
1881  << std::endl;
1882  source << " if( ! type.BeginsWith( \"D3PDReader::VarHandle<\" "
1883  << ") ) {" << std::endl;
1884  source << " continue;" << std::endl;
1885  source << " }" << std::endl;
1886  source << " // If it is, let's set it up:" << std::endl;
1887  source << " VarHandleBase* vh = GetVarHandle( m->GetName() );"
1888  << std::endl;
1889  source << " fHandles[ m->GetName() ] = vh;" << std::endl;
1890  source << " }" << std::endl << std::endl;
1891  source << " // Now configure all variables in a second loop:"
1892  << std::endl;
1893  source << " std::map< TString, VarHandleBase* >::const_iterator "
1894  << "itr = fHandles.begin();" << std::endl;
1895  source << " std::map< TString, VarHandleBase* >::const_iterator "
1896  << "end = fHandles.end();" << std::endl;
1897  source << " for( ; itr != end; ++itr ) {" << std::endl;
1898  source << " itr->second->SetName( fPrefix + itr->first );"
1899  << std::endl;
1900  source << " itr->second->SetMaster( master );" << std::endl;
1901  source << " }" << std::endl << std::endl;
1902  */
1903  source << " return;" << std::endl;
1904  source << " }" << std::endl << std::endl;
1905 
1906  source << "} // namespace D3PDReader" << std::endl;
1907 
1908  source.close();
1909 
1910  return StatusCode::SUCCESS;
1911  }

◆ writeUserD3PDObject()

StatusCode D3PD::Version2::writeUserD3PDObject ( const std::string &  dir)

This function can be used to create the D3PDReader::UserD3PDObject class's source files.

Write the UserD3PDObject source files into a given directory.

The created class is used throughout the D3PDReader code to create/access user variables.

Parameters
dirDirectory name where the source files should be put
Returns
A StatusCode indicating whether the operation was successful

Definition at line 411 of file CodeGenerator_v2.cxx.

411  {
412 
413  // Construct the file names as they will be needed in a few places:
414  const std::string headerName = dir + "/" + USERD3PDOBJECT_HEADER_NAME;
415  const std::string implName = dir + "/" + USERD3PDOBJECT_IMPL_NAME;
416  const std::string sourceName = dir + "/" + USERD3PDOBJECT_CXX_NAME;
417 
418  // Only create the header if it doesn't exist:
419  struct stat fileInfo;
420  if( stat( headerName.c_str(), &fileInfo ) ) {
421 
422  // Let everyone know what we're doing:
423  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO,
424  "Version2::writeUserD3PDObject" )
425  << "Generating file: " << headerName;
426 
427  // Open the header file (overwriting a possibly existing file):
428  std::ofstream header( headerName.c_str() );
429 
430  // Write the header file:
431  header << USERD3PDOBJECT_HEADER << std::endl;
432  header.close();
433  }
434 
435  // Only create the implementation if it doesn't exist:
436  if( stat( implName.c_str(), &fileInfo ) ) {
437 
438  // Let everyone know what we're doing:
439  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO,
440  "Version2::writeUserD3PDObject" )
441  << "Generating file: " << implName;
442 
443  // Open the header file (overwriting a possibly existing file):
444  std::ofstream impl( implName.c_str() );
445 
446  // Write the header file:
447  impl << USERD3PDOBJECT_IMPL << std::endl;
448  impl.close();
449  }
450 
451  // Only create the source if it doesn't exist:
452  if( stat( sourceName.c_str(), &fileInfo ) ) {
453 
454  // Let everyone know what we're doing:
455  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO,
456  "Version2::writeUserD3PDObject" )
457  << "Generating file: " << sourceName;
458 
459  // Open the header file (overwriting a possibly existing file):
460  std::ofstream source( sourceName.c_str() );
461 
462  // Write the header file:
463  source << USERD3PDOBJECT_CXX << std::endl;
464  source.close();
465  }
466 
467  return StatusCode::SUCCESS;
468  }

◆ writeUtils()

StatusCode D3PD::Version2::writeUtils ( const std::string &  dir)

This function can be used to create source files containing some utility functions.

Write the "Utils" source files into a given directory.

Parameters
dirDirectory name where the source files should be put
Returns
A StatusCode indicating whether the operation was successful

Definition at line 577 of file CodeGenerator_v2.cxx.

577  {
578 
579  // Construct the file names as they will be needed in a few places:
580  const std::string headerName = dir + "/" + UTILS_HEADER_NAME;
581  const std::string cxxName = dir + "/" + UTILS_CXX_NAME;
582 
583  // Only create the header if it doesn't exist:
584  struct stat fileInfo;
585  if( stat( headerName.c_str(), &fileInfo ) ) {
586 
587  // Let everyone know what we're doing:
588  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "Version2::writeUtils" )
589  << "Generating file: " << headerName;
590 
591  // Open the header file (overwriting a possibly existing file):
592  std::ofstream header( headerName.c_str() );
593 
594  // Write the header file:
595  header << UTILS_HEADER << std::endl;
596  header.close();
597  }
598 
599  // Only create the implementation if it doesn't exist:
600  if( stat( cxxName.c_str(), &fileInfo ) ) {
601 
602  // Let everyone know what we're doing:
603  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "Version2::writeUtils" )
604  << "Generating file: " << cxxName;
605 
606  // Open the header file (overwriting a possibly existing file):
607  std::ofstream impl( cxxName.c_str() );
608 
609  // Write the header file:
610  impl << UTILS_CXX << std::endl;
611  impl.close();
612  }
613 
614  return StatusCode::SUCCESS;
615  }

◆ writeVarHandle()

StatusCode D3PD::Version2::writeVarHandle ( const std::string &  dir)

This function can be used to create the D3PDReader::VarHandle class's source files.

Write the "VarHandle" source files into a given directory.

The created class is used throughout the D3PDReader code to access the branches of the TTrees.

Parameters
dirDirectory name where the source files should be put
Returns
A StatusCode indicating whether the operation was successful

Definition at line 298 of file CodeGenerator_v2.cxx.

298  {
299 
300  // Construct the file names as they will be needed in a few places:
301  const std::string headerName = dir + "/" + VARHANDLE_HEADER_NAME;
302  const std::string implName = dir + "/" + VARHANDLE_IMPL_NAME;
303  const std::string sourceName = dir + "/" + VARHANDLE_CXX_NAME;
304 
305  // Only create the header if it doesn't exist:
306  struct stat fileInfo;
307  if( stat( headerName.c_str(), &fileInfo ) ) {
308 
309  // Let everyone know what we're doing:
310  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO,
311  "Version2::writeVarHandle" )
312  << "Generating file: " << headerName;
313 
314  // Open the header file (overwriting a possibly existing file):
315  std::ofstream header( headerName.c_str() );
316 
317  // Write the header file:
318  header << VARHANDLE_HEADER << std::endl;
319  header.close();
320  }
321 
322  // Only create the implementation if it doesn't exist:
323  if( stat( implName.c_str(), &fileInfo ) ) {
324 
325  // Let everyone know what we're doing:
326  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "Version2::writeVarHandle" )
327  << "Generating file: " << implName;
328 
329  // Open the header file (overwriting a possibly existing file):
330  std::ofstream impl( implName.c_str() );
331 
332  // Write the header file:
333  impl << VARHANDLE_IMPL << std::endl;
334  impl.close();
335  }
336 
337  // Only create the source if it doesn't exist:
338  if( stat( sourceName.c_str(), &fileInfo ) ) {
339 
340  // Let everyone know what we're doing:
341  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "Version2::writeVarHandle" )
342  << "Generating file: " << sourceName;
343 
344  // Open the header file (overwriting a possibly existing file):
345  std::ofstream source( sourceName.c_str() );
346 
347  // Write the header file:
348  source << VARHANDLE_CXX << std::endl;
349  source.close();
350  }
351 
352  return StatusCode::SUCCESS;
353  }

◆ writeVarProxy()

StatusCode D3PD::Version2::writeVarProxy ( const std::string &  dir)

This function can be used to create the D3PDReader::VarProxy class's source files.

Write the "VarProxy" source files into a given direcory.

The created class is used in the D3PDReader code to construct classes representing one element in a container.

Parameters
dirDirectory name where the source files should be put
Returns
A StatusCode indicating whether the operation was successful

Definition at line 363 of file CodeGenerator_v2.cxx.

363  {
364 
365  // Construct the file names as they will be needed in a few places:
366  const std::string headerName = dir + "/" + VARPROXY_HEADER_NAME;
367  const std::string implName = dir + "/" + VARPROXY_IMPL_NAME;
368 
369  // Only create the header if it doesn't exist:
370  struct stat fileInfo;
371  if( stat( headerName.c_str(), &fileInfo ) ) {
372 
373  // Let everyone know what we're doing:
374  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "Version2::writeVarProxy" )
375  << "Generating file: " << headerName;
376 
377  // Open the header file (overwriting a possibly existing file):
378  std::ofstream header( headerName.c_str() );
379 
380  // Write the header file:
381  header << VARPROXY_HEADER << std::endl;
382  header.close();
383  }
384 
385  // Only create the implementation if it doesn't exist:
386  if( stat( implName.c_str(), &fileInfo ) ) {
387 
388  // Let everyone know what we're doing:
389  REPORT_MESSAGE_WITH_CONTEXT( MSG::INFO, "Version2::writeVarProxy" )
390  << "Generating file: " << implName;
391 
392  // Open the header file (overwriting a possibly existing file):
393  std::ofstream impl( implName.c_str() );
394 
395  // Write the header file:
396  impl << VARPROXY_IMPL << std::endl;
397  impl.close();
398  }
399 
400  return StatusCode::SUCCESS;
401  }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
header
Definition: hcg.cxx:526
FOR_ALL_EVENT_VARIABLES
#define FOR_ALL_EVENT_VARIABLES(EXP)
A convenience macro used in the event class generation.
Definition: CodeGenerator_v2.cxx:39
D3PD::isPrimitive
bool isPrimitive(const std::string &type)
This function is used in the code generator to determine from a type name if it's a primitive type or...
Definition: isPrimitive.cxx:24
spacer
const std::string spacer
Definition: spacer.h:24
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
python.checkMetadata.metadata
metadata
Definition: checkMetadata.py:175
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
lumiFormat.i
int i
Definition: lumiFormat.py:92
python.DecayParser.buf
buf
print ("=> [%s]"cmd)
Definition: DecayParser.py:27
ret
T ret(T t)
Definition: rootspy.cxx:260
beamspotman.stat
stat
Definition: beamspotman.py:266
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
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
findIdxOfMinimum::impl
ATH_ALWAYS_INLINE int32_t impl(const float *distancesIn, int n)
Definition: GSFFindIndexOfMinimum.h:359
impl
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:46
LArG4AODNtuplePlotter.varname
def varname(hname)
Definition: LArG4AODNtuplePlotter.py:37
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
makeTOC.header
header
Definition: makeTOC.py:28