00001 #include "otsdaq-core/ConfigurationPluginDataFormats/ARTDAQBoardReaderConfiguration.h"
00002 #include "otsdaq-core/Macros/ConfigurationPluginMacros.h"
00003 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
00004 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
00005
00006 #include <iostream>
00007 #include <fstream>
00008 #include <stdio.h>
00009 #include <sys/stat.h>
00010
00011 using namespace ots;
00012
00013
00014 #define ARTDAQ_FCL_PATH std::string(getenv("USER_DATA")) + "/"+ "ARTDAQConfigurations/"
00015 #define ARTDAQ_FILE_PREAMBLE "boardReader"
00016
00017
00018 #define OUT out << tabStr << commentStr
00019 #define PUSHTAB tabStr += "\t"
00020 #define POPTAB tabStr.resize(tabStr.size()-1)
00021 #define PUSHCOMMENT commentStr += "# "
00022 #define POPCOMMENT commentStr.resize(commentStr.size()-2)
00023
00024
00025
00026 ARTDAQBoardReaderConfiguration::ARTDAQBoardReaderConfiguration(void)
00027 : ConfigurationBase("ARTDAQBoardReaderConfiguration")
00028 {
00030
00032
00033 }
00034
00035
00036 ARTDAQBoardReaderConfiguration::~ARTDAQBoardReaderConfiguration(void)
00037 {}
00038
00039
00040 void ARTDAQBoardReaderConfiguration::init(ConfigurationManager* configManager)
00041 {
00042
00043 mkdir((ARTDAQ_FCL_PATH).c_str(), 0755);
00044
00045 __MOUT__ << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << std::endl;
00046 __MOUT__ << configManager->__SELF_NODE__ << std::endl;
00047
00048 const XDAQContextConfiguration *contextConfig = configManager->__GET_CONFIG__(XDAQContextConfiguration);
00049
00050
00051
00052
00053
00054
00055
00056
00057
00060
00061
00062
00063 std::vector<const XDAQContextConfiguration::XDAQContext *> readerContexts =
00064 contextConfig->getBoardReaderContexts();
00065
00066
00067
00068
00069
00070
00071
00072 for(auto &readerContext: readerContexts)
00073 {
00074 try
00075 {
00076 ConfigurationTree readerConfigNode = contextConfig->getSupervisorConfigNode(configManager,
00077 readerContext->contextUID_, readerContext->applications_[0].applicationUID_);
00078
00079 __MOUT__ << "Path for this reader config is " <<
00080 readerContext->contextUID_ << "/" <<
00081 readerContext->applications_[0].applicationUID_ << "/" <<
00082 readerConfigNode.getValueAsString() <<
00083 std::endl;
00084
00085 __MOUT__ << "Checking that this reader supervisor node is DataManager-like." << std::endl;
00086
00087 readerConfigNode.getNode("LinkToDataManagerConfiguration").getChildren();
00088 }
00089 catch(const std::runtime_error& e)
00090 {
00091 __SS__ << "artdaq Board Readers must be instantiated as a Consumer within a DataManager configuration. Error found while checking for LinkToDataManagerConfiguration: " <<
00092 e.what() << std::endl;
00093 __MOUT_ERR__ << ss.str();
00094 __MOUT__ << "Path for this reader config is " <<
00095 readerContext->contextUID_ << "/" <<
00096 readerContext->applications_[0].applicationUID_ << "/X" << std::endl;
00097 __MOUT_ERR__ << "This board reader will likely not get instantiated properly! Proceeding anyway with fcl generation." << std::endl;
00098
00099
00100
00101 }
00102
00103
00104
00105
00106
00107 }
00108
00109
00110
00111 auto childrenMap = configManager->__SELF_NODE__.getChildren();
00112 std::string appUID, buffUID, consumerUID;
00113
00114 for(auto &child:childrenMap)
00115 if(child.second.getNode("Status").getValue<bool>())
00116 {
00117 outputFHICL(child.second, contextConfig);
00118 }
00119 }
00120
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 std::string ARTDAQBoardReaderConfiguration::getFHICLFilename(const ConfigurationTree &boardReaderNode)
00132 {
00133 __MOUT__ << "ARTDAQ BoardReader UID: " << boardReaderNode.getValue() << std::endl;
00134 std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
00135 std::string uid = boardReaderNode.getValue();
00136 for(unsigned int i=0;i<uid.size();++i)
00137 if((uid[i] >= 'a' && uid[i] <= 'z') ||
00138 (uid[i] >= 'A' && uid[i] <= 'Z') ||
00139 (uid[i] >= '0' && uid[i] <= '9'))
00140 filename += uid[i];
00141
00142 filename += ".fcl";
00143
00144 __MOUT__ << "fcl: " << filename << std::endl;
00145
00146 return filename;
00147 }
00148
00149
00150 void ARTDAQBoardReaderConfiguration::outputFHICL(const ConfigurationTree &boardReaderNode,
00151 const XDAQContextConfiguration *contextConfig)
00152 {
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 std::string filename = getFHICLFilename(boardReaderNode);
00247
00249
00250 std::fstream out;
00251
00252 std::string tabStr = "";
00253 std::string commentStr = "";
00254
00255 out.open(filename, std::fstream::out | std::fstream::trunc);
00256 if(out.fail())
00257 {
00258 __SS__ << "Failed to open ARTDAQ Builder fcl file: " << filename << std::endl;
00259 throw std::runtime_error(ss.str());
00260 }
00261
00262
00263 try
00264 {
00265 if(boardReaderNode.isDisconnected())
00266 {
00267
00268 OUT << "{}\n\n";
00269 out.close();
00270 return;
00271 }
00272 }
00273 catch(const std::runtime_error)
00274 {
00275 __MOUT__ << "Ignoring error, assume this a valid UID node." << std::endl;
00276
00277
00278 }
00279
00280
00281
00282 OUT << "daq: {\n";
00283
00284
00285 PUSHTAB;
00286 OUT << "fragment_receiver: {\n";
00287
00288 PUSHTAB;
00289 {
00290
00291 OUT << "generator" <<
00292 ": " <<
00293 boardReaderNode.getNode("daqGeneratorPluginType").getValue()<<
00294 ("\t #daq generator plug-in type") <<
00295 "\n";
00296 OUT << "fragment_type" <<
00297 ": " <<
00298 boardReaderNode.getNode("daqGeneratorFragmentType").getValue() <<
00299 ("\t #generator data fragment type") <<
00300 "\n\n";
00301
00302
00303 auto parametersLink = boardReaderNode.getNode("daqParametersLink");
00304 if(!parametersLink.isDisconnected())
00305 {
00306
00307 auto parameters = parametersLink.getChildren();
00308 for(auto ¶meter:parameters)
00309 {
00310 if(!parameter.second.getNode("Status").getValue<bool>())
00311 PUSHCOMMENT;
00312
00313
00314
00315
00316
00317
00318
00319 auto comment = parameter.second.getNode("CommentDescription");
00320 OUT << parameter.second.getNode("daqParameterKey").getValue() <<
00321 ": " <<
00322 parameter.second.getNode("daqParameterValue").getValue()
00323 <<
00324 (comment.isDefaultValue()?"":("\t # " + comment.getValue())) <<
00325 "\n";
00326
00327 if(!parameter.second.getNode("Status").getValue<bool>())
00328 POPCOMMENT;
00329 }
00330 }
00331 OUT << "\n";
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 OUT << "destinations: {\n";
00360
00361 PUSHTAB;
00362 auto destinationsGroup = boardReaderNode.getNode("daqDestinationsLink");
00363 if(!destinationsGroup.isDisconnected())
00364 {
00365 auto destinations = destinationsGroup.getChildren();
00366 for(auto &destination:destinations)
00367 {
00368 unsigned int destinationRank =
00369 contextConfig->getARTDAQAppRank(
00370 destination.second.getNode("destinationARTDAQContextLink").getValue());
00371 OUT << destination.second.getNode("destinationKey").getValue() <<
00372 ": {" <<
00373 " transferPluginType: " <<
00374 destination.second.getNode("transferPluginType").getValue() <<
00375 " destination_rank: " <<
00376 destinationRank <<
00377 " max_fragment_size_words: " <<
00378 destination.second.getNode("ARTDAQGlobalConfigurationLink/maxFragmentSizeWords").getValue<unsigned int>() <<
00379 "}\n";
00380 }
00381 }
00382 POPTAB;
00383 OUT << "}\n\n";
00384
00385 POPTAB;
00386 OUT << "}\n\n";
00387
00388
00389 OUT << "metrics: {\n";
00390
00391 PUSHTAB;
00392 auto metricsGroup = boardReaderNode.getNode("daqMetricsLink");
00393 if(!metricsGroup.isDisconnected())
00394 {
00395 auto metrics = metricsGroup.getChildren();
00396
00397 for(auto &metric:metrics)
00398 {
00399 if(!metric.second.getNode("Status").getValue<bool>())
00400 PUSHCOMMENT;
00401
00402 OUT << metric.second.getNode("metricKey").getValue() <<
00403 ": {\n";
00404 PUSHTAB;
00405
00406 OUT << "metricPluginType: " <<
00407 metric.second.getNode("metricPluginType").getValue()
00408 << "\n";
00409 OUT << "level: " <<
00410 metric.second.getNode("metricLevel").getValue()
00411 << "\n";
00412
00413 auto metricParametersGroup = metric.second.getNode("metricParametersLink");
00414 if(!metricParametersGroup.isDisconnected())
00415 {
00416 auto metricParameters = metricParametersGroup.getChildren();
00417 for(auto &metricParameter:metricParameters)
00418 {
00419 if(!metricParameter.second.getNode("Status").getValue<bool>())
00420 PUSHCOMMENT;
00421
00422 OUT << metricParameter.second.getNode("metricParameterKey").getValue() <<
00423 ": " <<
00424 metricParameter.second.getNode("metricParameterValue").getValue()
00425 << "\n";
00426
00427 if(!metricParameter.second.getNode("Status").getValue<bool>())
00428 POPCOMMENT;
00429
00430 }
00431 }
00432 POPTAB;
00433 OUT << "}\n\n";
00434
00435 if(!metric.second.getNode("Status").getValue<bool>())
00436 POPCOMMENT;
00437 }
00438 }
00439 POPTAB;
00440 OUT << "}\n\n";
00441
00442 POPTAB;
00443 OUT << "}\n\n";
00444
00445
00446 out.close();
00447 }
00448
00449 DEFINE_OTS_CONFIGURATION(ARTDAQBoardReaderConfiguration)