18 #include "GaudiKernel/System.h"
30 static const char*
const CODE_COMMENT =
31 "// Dear emacs, this is -*- c++ -*-\n"
32 "// -------------------------------------------------------------\n"
33 "// Code produced by D3PDMakerReader\n"
35 "// author: Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>\n"
36 "// -------------------------------------------------------------";
39 #define FOR_ALL_EVENT_VARIABLES(EXP) { \
40 std::set< ObjectMetadata >::const_iterator meta_itr = \
42 std::set< ObjectMetadata >::const_iterator meta_end = \
44 std::set< std::string > varnames; \
45 for( ; meta_itr != meta_end; ++meta_itr ) { \
46 const std::string varname = \
47 eventVariableName( meta_itr->prefix(), \
50 varnames.insert( varname ); \
71 std::string vectorTemplateArgument(
const std::string&
type,
80 if(
result.starts_with(
"std::vector<" ) ) {
81 result.replace( 0, 12,
"" );
82 }
else if(
result.starts_with(
"vector<" ) ) {
83 result.replace( 0, 7,
"" );
96 for(
size_t i = 0;
i <
result.size(); ++
i ) {
112 return result.substr( 0,
i - 1 );
137 void addSTLHeader( std::ostream&
out,
const char*
name,
141 bool header_needed =
false;
142 std::set< D3PD::ObjectMetadata::Variable >::const_iterator itr =
144 std::set< D3PD::ObjectMetadata::Variable >::const_iterator
end =
146 for( ; itr !=
end; ++itr ) {
147 if( itr->type().find(
name ) != std::string::npos ) {
148 header_needed =
true;
154 if( header_needed ) {
155 out <<
"#include <" <<
name <<
">" << std::endl;
158 out <<
"using std::" <<
name <<
";" << std::endl;
173 std::string variableName(
const std::string&
varname ) {
178 std::string::size_type
i = 0;
179 while( (
i =
result.find(
":" ) ) != std::string::npos ) {
182 while( (
i =
result.find(
" " ) ) != std::string::npos ) {
188 if( isdigit(
result[ 0 ] ) ) {
212 std::string eventVariableName(
const std::string&
prefix,
213 const std::string& objectName,
214 const std::set< std::string >& varnames ) {
227 if( varnames.find(
result ) == varnames.end() ) {
231 for(
int i = 0; ; ++
i ) {
232 std::ostringstream
name;
233 name <<
result <<
"_" <<
static_cast< char >(
'a' +
i );
234 if( varnames.find(
name.str() ) == varnames.end() ) {
243 if(
result.find(
"D3PDObject" ) ==
result.size() - 10 ) {
268 const std::string headerName =
dir +
"/" + D3PDOBJECTBASE_HEADER_NAME;
271 struct stat fileInfo;
272 if(
stat( headerName.c_str(), &fileInfo ) ) {
276 "Version2::writeD3PDObjectBase" )
277 <<
"Generating file: " << headerName;
280 std::ofstream
header( headerName.c_str() );
283 header << D3PDOBJECTBASE_HEADER << std::endl;
287 return StatusCode::SUCCESS;
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;
306 struct stat fileInfo;
307 if(
stat( headerName.c_str(), &fileInfo ) ) {
311 "Version2::writeVarHandle" )
312 <<
"Generating file: " << headerName;
315 std::ofstream
header( headerName.c_str() );
318 header << VARHANDLE_HEADER << std::endl;
323 if(
stat( implName.c_str(), &fileInfo ) ) {
327 <<
"Generating file: " << implName;
330 std::ofstream
impl( implName.c_str() );
333 impl << VARHANDLE_IMPL << std::endl;
338 if(
stat( sourceName.c_str(), &fileInfo ) ) {
342 <<
"Generating file: " << sourceName;
345 std::ofstream
source( sourceName.c_str() );
348 source << VARHANDLE_CXX << std::endl;
352 return StatusCode::SUCCESS;
366 const std::string headerName =
dir +
"/" + VARPROXY_HEADER_NAME;
367 const std::string implName =
dir +
"/" + VARPROXY_IMPL_NAME;
370 struct stat fileInfo;
371 if(
stat( headerName.c_str(), &fileInfo ) ) {
375 <<
"Generating file: " << headerName;
378 std::ofstream
header( headerName.c_str() );
381 header << VARPROXY_HEADER << std::endl;
386 if(
stat( implName.c_str(), &fileInfo ) ) {
390 <<
"Generating file: " << implName;
393 std::ofstream
impl( implName.c_str() );
396 impl << VARPROXY_IMPL << std::endl;
400 return StatusCode::SUCCESS;
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;
419 struct stat fileInfo;
420 if(
stat( headerName.c_str(), &fileInfo ) ) {
424 "Version2::writeUserD3PDObject" )
425 <<
"Generating file: " << headerName;
428 std::ofstream
header( headerName.c_str() );
431 header << USERD3PDOBJECT_HEADER << std::endl;
436 if(
stat( implName.c_str(), &fileInfo ) ) {
440 "Version2::writeUserD3PDObject" )
441 <<
"Generating file: " << implName;
444 std::ofstream
impl( implName.c_str() );
447 impl << USERD3PDOBJECT_IMPL << std::endl;
452 if(
stat( sourceName.c_str(), &fileInfo ) ) {
456 "Version2::writeUserD3PDObject" )
457 <<
"Generating file: " << sourceName;
460 std::ofstream
source( sourceName.c_str() );
463 source << USERD3PDOBJECT_CXX << std::endl;
467 return StatusCode::SUCCESS;
481 const std::string headerName =
dir +
"/" + D3PDREADSTATS_HEADER_NAME;
482 const std::string cxxName =
dir +
"/" + D3PDREADSTATS_CXX_NAME;
485 struct stat fileInfo;
486 if(
stat( headerName.c_str(), &fileInfo ) ) {
490 "Version2::writeD3PDReadStats" )
491 <<
"Generating file: " << headerName;
494 std::ofstream
header( headerName.c_str() );
497 header << D3PDREADSTATS_HEADER << std::endl;
502 if(
stat( cxxName.c_str(), &fileInfo ) ) {
506 "Version2::writeD3PDReadStats" )
507 <<
"Generating file: " << cxxName;
510 std::ofstream
impl( cxxName.c_str() );
513 impl << D3PDREADSTATS_CXX << std::endl;
517 return StatusCode::SUCCESS;
531 const std::string headerName =
dir +
"/" + D3PDPERFSTATS_HEADER_NAME;
532 const std::string cxxName =
dir +
"/" + D3PDPERFSTATS_CXX_NAME;
535 struct stat fileInfo;
536 if(
stat( headerName.c_str(), &fileInfo ) ) {
540 "Version2::writeD3PDPerfStats" )
541 <<
"Generating file: " << headerName;
544 std::ofstream
header( headerName.c_str() );
547 header << D3PDPERFSTATS_HEADER << std::endl;
552 if(
stat( cxxName.c_str(), &fileInfo ) ) {
556 "Version2::writeD3PDPerfStats" )
557 <<
"Generating file: " << cxxName;
560 std::ofstream
impl( cxxName.c_str() );
563 impl << D3PDPERFSTATS_CXX << std::endl;
567 return StatusCode::SUCCESS;
580 const std::string headerName =
dir +
"/" + UTILS_HEADER_NAME;
581 const std::string cxxName =
dir +
"/" + UTILS_CXX_NAME;
584 struct stat fileInfo;
585 if(
stat( headerName.c_str(), &fileInfo ) ) {
589 <<
"Generating file: " << headerName;
592 std::ofstream
header( headerName.c_str() );
595 header << UTILS_HEADER << std::endl;
600 if(
stat( cxxName.c_str(), &fileInfo ) ) {
604 <<
"Generating file: " << cxxName;
607 std::ofstream
impl( cxxName.c_str() );
610 impl << UTILS_CXX << std::endl;
614 return StatusCode::SUCCESS;
633 const std::string&
dir,
637 const std::string
fileName =
dir +
"/" + classname +
".h";
640 struct stat fileInfo;
641 if( !
stat(
fileName.c_str(), &fileInfo ) )
return StatusCode::SUCCESS;
651 header << CODE_COMMENT << std::endl;
652 header <<
"#ifndef D3PDREADER_" << classname <<
"_H" << std::endl;
653 header <<
"#define D3PDREADER_" << classname <<
"_H" << std::endl
657 header <<
"// STL include(s):" << std::endl;
658 header <<
"#include <map>" << std::endl;
666 header <<
"// ROOT include(s):" << std::endl;
667 header <<
"#include <TObject.h>" << std::endl;
668 header <<
"#include <TString.h>" << std::endl << std::endl;
671 header <<
"#include \"" << D3PDOBJECTBASE_HEADER_NAME <<
"\""
673 header <<
"#include \"" << D3PDREADSTATS_HEADER_NAME <<
"\""
675 header <<
"#include \"" << VARHANDLE_HEADER_NAME <<
"\"" << std::endl;
677 header <<
"#include \"" << VARPROXY_HEADER_NAME <<
"\""
680 header <<
"#include \"" << USERD3PDOBJECT_HEADER_NAME <<
"\""
685 header <<
"class TTree;" << std::endl << std::endl;
688 header <<
"namespace D3PDReader {" << std::endl << std::endl;
696 header <<
" // Forward declaration(s):" << std::endl;
697 header <<
" class " << classname <<
";" << std::endl << std::endl;
700 header <<
" /**" << std::endl;
701 header <<
" * Code generated by CodeGenerator_v2 on:"
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 );
709 header <<
" * time = " << ctime_r( &rawtime, buf );
710 header <<
" */" << std::endl;
711 header <<
" class " << classname <<
"Element : "
712 <<
"public UserD3PDObjectElement {" << std::endl
714 header <<
" friend class " << classname <<
";" << std::endl
716 header <<
" protected:" << std::endl;
719 header <<
" /// Constructor only visible to " << classname
721 header <<
" " << classname <<
"Element( size_t index, const "
722 << classname <<
"& parent );" << std::endl << std::endl;
725 header <<
" public:" << std::endl;
726 header <<
" /// Copy constructor" << std::endl;
727 header <<
" " << classname <<
"Element( const " << classname
728 <<
"Element& parent );" << std::endl << std::endl;
731 header <<
" /// Parent object of this proxy object"
733 header <<
" const " << classname <<
"* GetParent() const;"
735 header <<
" /// Index of the object inside its container"
737 header <<
" size_t GetIndex() const;" << std::endl
741 std::map< std::string, int > variableCounter;
742 std::set< ObjectMetadata::Variable >::const_iterator itr =
744 std::set< ObjectMetadata::Variable >::const_iterator
end =
746 for( ; itr !=
end; ++itr ) {
748 if( ( itr->name() ==
"n" ) || ( itr->name() ==
"N" ) )
continue;
751 const std::string
type =
752 vectorTemplateArgument( itr->type(), ok );
755 "Version2::writeHeader" )
756 <<
"Unexpected variable type encountered for "
757 <<
"container dumper: " << itr->type();
759 "Version2::writeHeader" )
760 <<
"Variable name: " << itr->name();
761 return StatusCode::FAILURE;
763 if( itr->doc() !=
"" ) {
764 header <<
" /// " << itr->doc() << std::endl;
766 if( variableCounter.find( itr->name() ) ==
767 variableCounter.end() ) {
769 << variableName( itr->name() ) <<
";" << std::endl;
770 variableCounter[ itr->name() ] = 1;
773 << variableName( itr->name() )
774 << variableCounter[ itr->name() ] <<
";" << std::endl;
775 variableCounter[ itr->name() ]++;
781 header <<
" private:" << std::endl;
782 header <<
" /// Reference to the parent of this object"
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;
790 header <<
" ClassDef( " << classname <<
"Element, 0 )"
793 header <<
" }; // class " << classname <<
"Element" << std::endl
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 );
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;
817 header <<
" /// Constructor used when reading from a TTree"
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;
827 header <<
" /// Destructor" << std::endl;
828 header <<
" ~" << classname <<
"();" << std::endl;
835 header <<
" /// Get the currently configured prefix value"
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;
842 header <<
" /// Connect the object to an input TTree"
844 header <<
" virtual void ReadFrom( ::TTree* tree );" << std::endl;
845 header <<
" /// Connect the object to an output TTree"
847 header <<
" virtual void WriteTo( ::TTree* tree );" << std::endl
850 header <<
" /// Turn (selected) branches either on or off"
852 header <<
" virtual void SetActive( ::Bool_t active = kTRUE,"
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
861 header <<
" /// Get the D3PD reading statistics" << std::endl;
862 header <<
" virtual D3PDReadStats GetStatistics() const;"
863 << std::endl << std::endl;
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;
871 header <<
" /// Clear the container. Useful when writing new "
872 <<
"branches." << std::endl;
873 header <<
" void Clear( Option_t* option = \"\" );"
875 header <<
" /// Add one element to an output collection"
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"
889 header <<
" " << classname <<
"& operator+=( const "
890 << classname <<
"Element& el );" << std::endl << std::endl;
896 std::map< std::string, int > variableCounter;
897 std::set< ObjectMetadata::Variable >::const_iterator itr =
899 std::set< ObjectMetadata::Variable >::const_iterator
end =
901 for( ; itr !=
end; ++itr ) {
902 if( itr->doc() !=
"" ) {
903 header <<
" /// " << itr->doc() << std::endl;
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;
911 header <<
" VarHandle< " << itr->type()
912 << ( itr->primitive() ?
"" :
"*" ) <<
" > "
913 << variableName( itr->name() )
914 << variableCounter[ itr->name() ] <<
";" << std::endl;
915 variableCounter[ itr->name() ]++;
920 header << std::endl <<
" private:" << std::endl;
921 header <<
" /// Function used internally to access the variables"
923 header <<
" VarHandleBase* GetVarHandle( const char* name );"
925 header <<
" /// Function setting up all the VarHandle members"
927 header <<
" void SetVarHandles( const ::Long64_t* master );"
928 << std::endl << std::endl;
932 header <<
" mutable std::vector< " << classname <<
"Element* >"
933 <<
" fProxies; ///< Internal list of proxy objects"
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"
941 header <<
" ::TString fPrefix; ///< Prefix to the branch names"
942 << std::endl << std::endl;
945 header <<
" ClassDef( " << classname <<
", 0 )" << 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;
953 return StatusCode::SUCCESS;
968 const std::string&
dir,
972 const std::string
fileName =
dir +
"/" + classname +
".cxx";
975 struct stat fileInfo;
976 if( !
stat(
fileName.c_str(), &fileInfo ) )
return StatusCode::SUCCESS;
986 source << CODE_COMMENT << std::endl << std::endl;
989 source <<
"#include <limits>" << std::endl;
990 source <<
"#include <stdexcept>" << std::endl << std::endl;
994 source <<
"#include <TPRegexp.h>" << std::endl;
995 source <<
"#include <TList.h>" << std::endl;
996 source <<
"#include <TDataMember.h>" << std::endl << std::endl;
999 source <<
"#include \"" << classname <<
".h\"" << std::endl
1003 source <<
"ClassImp( D3PDReader::" << classname <<
"Element )"
1006 source <<
"ClassImp( D3PDReader::" << classname <<
" )" << std::endl
1009 source <<
"namespace D3PDReader {" << std::endl << std::endl;
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 =
1031 std::set< ObjectMetadata::Variable >::const_iterator
end =
1033 for( ; itr !=
end; ++itr ) {
1035 if( ( itr->name() ==
"n" ) || ( itr->name() ==
"N" ) )
continue;
1037 source <<
"," << std::endl;
1038 if( variableCounter.find( itr->name() ) ==
1039 variableCounter.end() ) {
1040 source <<
" " << variableName( itr->name() )
1041 <<
"( parent." << variableName( itr->name() )
1043 variableCounter[ itr->name() ] = 1;
1045 source <<
" " << variableName( itr->name() )
1046 << variableCounter[ itr->name() ]
1047 <<
"( parent." << variableName( itr->name() )
1048 << variableCounter[ itr->name() ] <<
", index )";
1049 variableCounter[ itr->name() ]++;
1052 source <<
"," << std::endl;
1053 source <<
" fParent( &parent ), fIndex( index ) {"
1054 << std::endl << std::endl;
1055 source <<
" }" << std::endl << std::endl;
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 )"
1076 source <<
" : UserD3PDObjectElement( parent )";
1077 variableCounter.clear();
1078 itr =
metadata.variables().begin();
1080 for( ; itr !=
end; ++itr ) {
1082 if( ( itr->name() ==
"n" ) || ( itr->name() ==
"N" ) )
continue;
1084 source <<
"," << std::endl;
1085 if( variableCounter.find( itr->name() ) ==
1086 variableCounter.end() ) {
1087 source <<
" " << variableName( itr->name() )
1088 <<
"( parent." << variableName( itr->name() )
1090 variableCounter[ itr->name() ] = 1;
1092 source <<
" " << variableName( itr->name() )
1093 << variableCounter[ itr->name() ]
1094 <<
"( parent." << variableName( itr->name() )
1095 << variableCounter[ itr->name() ] <<
" )";
1096 variableCounter[ itr->name() ]++;
1099 source <<
"," << std::endl;
1100 source <<
" fParent( parent.fParent ), "
1101 <<
"fIndex( parent.fIndex ) {" << std::endl << std::endl;
1102 source <<
" }" << std::endl << std::endl;
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"
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;
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;
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"
1155 source <<
" */" << std::endl;
1156 source <<
" " << classname <<
"::" << classname
1157 <<
"( const ::Long64_t& master, const char* prefix )"
1159 source <<
" : UserD3PDObject( master, prefix ),"
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;
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"
1180 source <<
" */" << std::endl;
1181 source <<
" " << classname <<
"::" << classname
1182 <<
"( const char* prefix )" << std::endl;
1183 source <<
" : UserD3PDObject( prefix ),"
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;
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 <<
"() {"
1202 source <<
" for( size_t i = 0; i < fProxies.size(); ++i ) {"
1204 source <<
" delete fProxies[ i ];" << std::endl;
1205 source <<
" }" << std::endl;
1206 source <<
" }" << std::endl << std::endl;
1212 source <<
" /**" << std::endl;
1213 source <<
" * @returns The branch name prefix used by the object"
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;
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
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;
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"
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
1269 source <<
" // Call ReadFrom(...) on all the variables:"
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;
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
1299 source <<
" // Call WriteTo(...) on all the variables:"
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;
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."
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"
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
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;"
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;
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
1370 source <<
" // Check if it makes sense to call this function:"
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\" );"
1378 source <<
" Warning( \"ReadAllActive\", "
1379 <<
"\"which are used to read information from a D3PD\" );"
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
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;"
1396 source <<
" itr->second->ReadCurrentEntry();" << std::endl;
1397 source <<
" }" << std::endl << std::endl;
1398 source <<
" return;" << std::endl;
1399 source <<
" }" << std::endl << std::endl;
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() );"
1430 source <<
" }" << std::endl << std::endl;
1431 source <<
" return result;" << std::endl;
1432 source <<
" }" << std::endl << std::endl;
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"
1448 source <<
" * @returns This same object, for convenience reasons"
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:"
1455 source <<
" if( fFromInput ) {" << std::endl;
1456 source <<
" Error( \"Set\", "
1457 <<
"\"Objects used for reading a D3PD can't be modified!\" );"
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
1464 std::map< std::string, int > variableCounter;
1465 std::set< ObjectMetadata::Variable >::const_iterator itr =
1467 std::set< ObjectMetadata::Variable >::const_iterator
end =
1469 for( ; itr !=
end; ++itr ) {
1470 std::string postfix =
"";
1471 if( variableCounter.find( itr->name() ) == variableCounter.end() ) {
1472 variableCounter[ itr->name() ] = 1;
1476 variableCounter[ itr->name() ]++;
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;
1487 source <<
" *( " << variableName( itr->name() )
1488 << postfix <<
"() ) = *( parent."
1489 << variableName( itr->name() ) << postfix
1490 <<
"() );" << std::endl;
1492 source <<
" } else {" << std::endl;
1493 if( itr->primitive() ) {
1494 source <<
" " << variableName( itr->name() )
1495 << postfix <<
"() = 0;" << std::endl;
1497 source <<
" " << variableName( itr->name() )
1498 << postfix <<
"()->clear();" << std::endl;
1500 source <<
" }" << std::endl;
1502 source << std::endl <<
" return *this;" << std::endl;
1503 source <<
" }" << std::endl << std::endl;
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!\" );"
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
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;
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
1577 variableCounter.clear();
1578 itr =
metadata.variables().begin();
1580 for( ; itr !=
end; ++itr ) {
1582 if( itr->name() ==
"n" ) {
1583 source <<
" ++( n() );" << std::endl;
1586 if( itr->name() ==
"N" ) {
1587 source <<
" ++( N() );" << std::endl;
1592 std::string postfix =
"";
1593 if( variableCounter.find( itr->name() ) ==
1594 variableCounter.end() ) {
1595 variableCounter[ itr->name() ] = 1;
1599 variableCounter[ itr->name() ]++;
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;
1613 const std::string
type =
1614 vectorTemplateArgument( itr->type(), ok );
1617 "Version2::writeSource" )
1618 <<
"Unexpected variable type encountered for "
1619 <<
"container dumper: " << itr->type();
1620 return StatusCode::FAILURE;
1625 source <<
" " << variableName( itr->name() )
1626 << postfix <<
"()->push_back( ";
1628 source <<
"std::numeric_limits< " <<
type <<
" >::min()";
1632 source <<
" );" << std::endl;
1633 source <<
" }" << std::endl;
1635 source <<
" return *this;" << std::endl;
1636 source <<
" }" << std::endl << std::endl;
1641 static const int NSIZEVARS = 2;
1642 static const char*
const SIZEVARS[ NSIZEVARS ] = {
"n",
"N" };
1643 std::string sizeVariable =
"";
1645 for(
int i = 0;
i < NSIZEVARS; ++
i ) {
1646 var.setName( SIZEVARS[
i ] );
1649 sizeVariable =
var.name() +
"()";
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
1674 source <<
" // Check whether the index makes sense:"
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 ) );"
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;
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
1712 source <<
" // Check whether the index makes sense:"
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 ) );"
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;
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;
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"
1768 source <<
" */" << std::endl;
1769 source <<
" VarHandleBase* " << classname
1770 <<
"::GetVarHandle( const char* name ) {" << std::endl
1772 variableCounter.clear();
1773 itr =
metadata.variables().begin();
1775 for( ; itr !=
end; ++itr ) {
1777 std::string postfix =
"";
1778 if( variableCounter.find( itr->name() ) ==
1779 variableCounter.end() ) {
1780 variableCounter[ itr->name() ] = 1;
1784 variableCounter[ itr->name() ]++;
1786 if( itr ==
metadata.variables().begin() ) {
1787 source <<
" if( ! ::strcmp( name, \""
1788 << variableName( itr->name() ) << postfix <<
"\" ) ) {"
1791 source <<
" else if( ! ::strcmp( name, \""
1792 << variableName( itr->name() ) << postfix <<
"\" ) ) {"
1795 source <<
" return &" << variableName( itr->name() )
1796 << postfix <<
";" << std::endl;
1797 source <<
" }" << std::endl;
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;
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:"
1823 source <<
" static const Int_t NVARNAMES = "
1824 <<
metadata.variables().size() <<
";" << std::endl;
1825 source <<
" static const char* VARNAMES[ NVARNAMES ][ 2 ] = {"
1827 variableCounter.clear();
1828 itr =
metadata.variables().begin();
1830 for( ; itr !=
end; ++itr ) {
1832 std::string postfix =
"";
1833 if( variableCounter.find( itr->name() ) ==
1834 variableCounter.end() ) {
1835 variableCounter[ itr->name() ] = 1;
1839 variableCounter[ itr->name() ]++;
1842 source <<
" { \"" << variableName( itr->name() ) << postfix
1843 <<
"\", \"" << variableName( itr->name() ) <<
"\" }";
1844 if( ++itr !=
end ) {
1850 source <<
" };" << std::endl << std::endl;
1851 source <<
" // Set up the fHandles map using this list:"
1853 source <<
" for( Int_t i = 0; i < NVARNAMES; ++i ) {"
1855 source <<
" VarHandleBase* vh = "
1856 <<
"GetVarHandle( VARNAMES[ i ][ 0 ] );" << std::endl;
1857 source <<
" vh->SetName( fPrefix + VARNAMES[ i ][ 1 ] );"
1859 source <<
" vh->SetMaster( master );" << std::endl;
1860 source <<
" fHandles[ VARNAMES[ i ][ 0 ] ] = vh;" << std::endl;
1861 source <<
" }" << std::endl << std::endl;
1903 source <<
" return;" << std::endl;
1904 source <<
" }" << std::endl << std::endl;
1906 source <<
"} // namespace D3PDReader" << std::endl;
1910 return StatusCode::SUCCESS;
1914 const std::set< ObjectMetadata >&
metadata ) {
1917 const std::string
fileName =
dir +
"/" + classname +
".h";
1920 struct stat fileInfo;
1921 if( !
stat(
fileName.c_str(), &fileInfo ) )
return StatusCode::SUCCESS;
1925 <<
"Generating file: " <<
fileName;
1931 header << CODE_COMMENT << std::endl;
1932 header <<
"#ifndef D3PDREADER_" << classname <<
"_H" << std::endl;
1933 header <<
"#define D3PDREADER_" << classname <<
"_H" << std::endl << std::endl;
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 ) {
1946 d3pd_reader_names.insert( meta_itr->name() );
1947 if( ! ret.second )
continue;
1949 header <<
"#include \"" << meta_itr->name() <<
".h\"" << std::endl;
1953 header <<
"namespace D3PDReader {" << std::endl << std::endl;
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()
1963 header <<
" * user = " << System::accountName() << std::endl;
1964 time_t rawtime =
time( NULL );
1966 header <<
" * time = " << ctime_r( &rawtime, buf );
1967 header <<
" */" << std::endl;
1968 header <<
" class " << classname <<
" : public D3PDObjectBase {" << std::endl
1970 header <<
" public:" << std::endl;
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
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
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;
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 = \".*\" );"
1999 header <<
" /// Read in all the variables that we need to write out as well"
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
2006 header <<
" /// Switch the reader object to a new event" << std::endl;
2007 header <<
" void GetEntry( ::Long64_t entry );" << std::endl << std::endl;
2012 header <<
" //" << std::endl;
2013 header <<
" // All the components of the D3PD:" << std::endl;
2014 header <<
" //" << std::endl;
2016 <<
";" << std::endl );
2019 header << std::endl <<
" private:" << std::endl;
2020 header <<
" Long64_t fEntry; ///< Variable storing the current entry number"
2022 header <<
" Bool_t fFromInput; "
2023 <<
"///< Flag specifying if object is used for D3PD reading"
2024 << std::endl << std::endl;
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;
2034 return StatusCode::SUCCESS;
2038 const std::set< ObjectMetadata >&
metadata ) {
2041 const std::string
fileName =
dir +
"/" + classname +
".cxx";
2044 struct stat fileInfo;
2045 if( !
stat(
fileName.c_str(), &fileInfo ) )
return StatusCode::SUCCESS;
2049 <<
"Generating file: " <<
fileName;
2055 source << CODE_COMMENT << std::endl << std::endl;
2058 source <<
"#include \"" << classname <<
".h\"" << std::endl;
2059 source <<
"#include \"D3PDPerfStats.h\"" << std::endl << std::endl;
2061 source <<
"ClassImp( D3PDReader::" << classname <<
" )" << std::endl << std::endl;
2063 source <<
"namespace D3PDReader {" << std::endl << std::endl;
2068 source <<
" " << classname <<
"::" << classname <<
"()" << std::endl
2069 <<
" : D3PDObjectBase()," << std::endl;
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;
2079 source <<
" " << classname <<
"::" << classname <<
"( Bool_t )" << std::endl
2080 <<
" : D3PDObjectBase()," << std::endl;
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;
2090 source <<
" const char* " << classname <<
"::GetPrefix() const {" << std::endl
2092 source <<
" Warning( \"GetPrefix\", \"A prefix is not defined for this object\" );"
2094 source <<
" return \"\";" << std::endl;
2095 source <<
" }" << std::endl << std::endl;
2097 source <<
" void " << classname <<
"::SetPrefix( const char* ) {" << std::endl
2099 source <<
" Warning( \"SetPrefix\", \"A prefix is not defined for this object\" );"
2101 source <<
" return;" << std::endl;
2102 source <<
" }" << std::endl << std::endl;
2107 source <<
" void " << classname <<
"::ReadFrom( ::TTree* tree ) {" << 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;
2116 source << std::endl <<
" return;" << std::endl;
2117 source <<
" }" << std::endl << std::endl;
2122 source <<
" void " << classname <<
"::WriteTo( ::TTree* tree ) {" << std::endl
2126 source << std::endl <<
" return;" << std::endl;
2127 source <<
" }" << std::endl << std::endl;
2132 source <<
" void " << classname <<
"::SetActive( ::Bool_t active, "
2133 <<
"const ::TString& pattern ) {" << std::endl << std::endl;
2135 <<
"active, pattern );" << std::endl );
2136 source << std::endl <<
" return;" << std::endl;
2137 source <<
" }" << std::endl << std::endl;
2142 source <<
" void " << classname <<
"::ReadAllActive() {" << std::endl
2146 source << std::endl <<
" return;" << std::endl;
2147 source <<
" }" << std::endl << std::endl;
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;
2159 <<
".GetStatistics();" << std::endl );
2160 source << std::endl <<
" return result;" << std::endl;
2161 source <<
" }" << std::endl << std::endl;
2166 source <<
" void " << classname <<
"::GetEntry( ::Long64_t entry ) {" << std::endl
2168 source <<
" fEntry = entry;" << std::endl;
2169 source <<
" return;" << std::endl;
2170 source <<
" }" << std::endl << std::endl;
2172 source <<
"} // namespace D3PDReader" << std::endl;
2175 return StatusCode::SUCCESS;