ATLAS Offline Software
Loading...
Searching...
No Matches
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.
StatusCode writeVarHandle (const std::string &dir)
 This function can be used to create the D3PDReader::VarHandle class's source files.
StatusCode writeVarProxy (const std::string &dir)
 This function can be used to create the D3PDReader::VarProxy class's source files.
StatusCode writeUserD3PDObject (const std::string &dir)
 This function can be used to create the D3PDReader::UserD3PDObject class's source files.
StatusCode writeD3PDReadStats (const std::string &dir)
 This function can be used to create the D3PDReader::D3PDReadStats class's source files.
StatusCode writeD3PDPerfStats (const std::string &dir)
 This function can be used to create the D3PDReader::D3PDPerfStats class's source files.
StatusCode writeUtils (const std::string &dir)
 This function can be used to create source files containing some utility functions.
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.
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.
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.
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.

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:
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 }
static const char *const D3PDOBJECTBASE_HEADER
static const char *const D3PDOBJECTBASE_HEADER_NAME
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.

◆ 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:
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:
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 }
static const char *const D3PDPERFSTATS_HEADER_NAME
static const char *const D3PDPERFSTATS_HEADER
static const char *const D3PDPERFSTATS_CXX
static const char *const D3PDPERFSTATS_CXX_NAME

◆ 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:
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:
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 }
static const char *const D3PDREADSTATS_HEADER_NAME
static const char *const D3PDREADSTATS_CXX
static const char *const D3PDREADSTATS_CXX_NAME
static const char *const D3PDREADSTATS_HEADER

◆ 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:
1945 std::pair< std::set< std::string >::iterator, bool > ret =
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 }
#define FOR_ALL_EVENT_VARIABLES(EXP)
A convenience macro used in the event class generation.
static const char *const CODE_COMMENT
A little header for all the generated source files.

◆ 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 }
static const char *const VARPROXY_HEADER_NAME
static const char *const USERD3PDOBJECT_HEADER_NAME
static const char *const VARHANDLE_HEADER_NAME
time(flags, cells_name, *args, **kw)

◆ 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 }
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...
const std::string spacer
Definition spacer.h:27

◆ 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:
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:
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:
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 }
static const char *const USERD3PDOBJECT_CXX_NAME
static const char *const USERD3PDOBJECT_IMPL
static const char *const USERD3PDOBJECT_IMPL_NAME
static const char *const USERD3PDOBJECT_HEADER
static const char *const USERD3PDOBJECT_CXX

◆ 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 }
static const char *const UTILS_HEADER
static const char *const UTILS_CXX_NAME
static const char *const UTILS_HEADER_NAME
static const char *const UTILS_CXX

◆ 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:
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 }
static const char *const VARHANDLE_IMPL_NAME
static const char *const VARHANDLE_IMPL
static const char *const VARHANDLE_HEADER
static const char *const VARHANDLE_CXX
static const char *const VARHANDLE_CXX_NAME

◆ 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 }
static const char *const VARPROXY_IMPL
static const char *const VARPROXY_IMPL_NAME
static const char *const VARPROXY_HEADER