This function is used to generate the source file of a D3PDReader class.
969 {
970
971
972 const std::string fileName = dir + "/" + classname + ".cxx";
973
974
975 struct stat fileInfo;
976 if( ! stat( fileName.c_str(), &fileInfo ) ) return StatusCode::SUCCESS;
977
978
980 << "Generating file: " << fileName;
981
982
983 std::ofstream source( fileName.c_str() );
984
985
987
988 if( metadata.container() ) {
989 source << "#include <limits>" << std::endl;
990 source << "#include <stdexcept>" << std::endl << std::endl;
991 }
992
993
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
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
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
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
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();
1080 for( ; itr !=
end; ++itr ) {
1081
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
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
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
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
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
1193
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
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
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
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
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
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
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
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 =
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;
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
1506
1507
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
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();
1580 for( ; itr !=
end; ++itr ) {
1581
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
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
1612 bool ok = true;
1613 const std::string
type =
1614 vectorTemplateArgument( itr->type(), ok );
1615 if( ! ok ) {
1617 "Version2::writeSource" )
1618 << "Unexpected variable type encountered for "
1619 << "container dumper: " << itr->type();
1620 return StatusCode::FAILURE;
1621 }
1622
1623
1624
1625 source <<
" " << variableName( itr->name() )
1626 << postfix << "()->push_back( ";
1628 source <<
"std::numeric_limits< " <<
type <<
" >::min()";
1629 } else {
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
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 ) !=
1649 sizeVariable =
var.name() +
"()";
1650 break;
1651 }
1652 }
1653
1654
1655
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
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
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();
1775 for( ; itr !=
end; ++itr ) {
1776
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
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();
1830 for( ; itr !=
end; ++itr ) {
1831
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
1842 source <<
" { \"" << variableName( itr->name() ) << postfix
1843 << "\", \"" << variableName( itr->name() ) << "\" }";
1844 if( ++itr != end ) {
1846 }
1847 --itr;
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
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903 source <<
" return;" << std::endl;
1904 source <<
" }" << std::endl << std::endl;
1905
1906 source <<
"} // namespace D3PDReader" << std::endl;
1907
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...