This function is used to generate the source file of a D3PDReader class.
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 =
"";
1644 ObjectMetadata::Variable
var;
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;