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 __COUT__ << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << std::endl;
00046 __COUT__ << 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 __COUT__ << "Path for this reader config is " <<
00080 readerContext->contextUID_ << "/" <<
00081 readerContext->applications_[0].applicationUID_ << "/" <<
00082 readerConfigNode.getValueAsString() <<
00083 std::endl;
00084
00085 __COUT__ << "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 __COUT_ERR__ << ss.str();
00094 __COUT__ << "Path for this reader config is " <<
00095 readerContext->contextUID_ << "/" <<
00096 readerContext->applications_[0].applicationUID_ << "/X" << std::endl;
00097 __COUT_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(ViewColumnInfo::COL_NAME_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 __COUT__ << "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 __COUT__ << "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 __COUT__ << "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(ViewColumnInfo::COL_NAME_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(ViewColumnInfo::COL_NAME_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 try
00366 {
00367 auto destinations = destinationsGroup.getChildren();
00368 for(auto &destination:destinations)
00369 {
00370 unsigned int destinationRank =
00371 contextConfig->getARTDAQAppRank(
00372 destination.second.getNode("destinationARTDAQContextLink").getValue());
00373 OUT << destination.second.getNode("destinationKey").getValue() <<
00374 ": {" <<
00375 " transferPluginType: " <<
00376 destination.second.getNode("transferPluginType").getValue() <<
00377 " destination_rank: " <<
00378 destinationRank <<
00379 " max_fragment_size_words: " <<
00380 destination.second.getNode("ARTDAQGlobalConfigurationLink/maxFragmentSizeWords").getValue<unsigned int>() <<
00381 "}\n";
00382 }
00383 }
00384 catch(const std::runtime_error& e)
00385 {
00386 __SS__ << "Are the DAQ destinations valid? Error occurred looking for Board Reader DAQ sources for UID '" <<
00387 boardReaderNode.getValue() << "': " << e.what() << std::endl;
00388 __COUT_ERR__ << ss.str() << std::endl;
00389 throw std::runtime_error(ss.str());
00390 }
00391 }
00392 POPTAB;
00393 OUT << "}\n\n";
00394
00395 POPTAB;
00396 OUT << "}\n\n";
00397
00398
00399 OUT << "metrics: {\n";
00400
00401 PUSHTAB;
00402 auto metricsGroup = boardReaderNode.getNode("daqMetricsLink");
00403 if(!metricsGroup.isDisconnected())
00404 {
00405 auto metrics = metricsGroup.getChildren();
00406
00407 for(auto &metric:metrics)
00408 {
00409 if(!metric.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
00410 PUSHCOMMENT;
00411
00412 OUT << metric.second.getNode("metricKey").getValue() <<
00413 ": {\n";
00414 PUSHTAB;
00415
00416 OUT << "metricPluginType: " <<
00417 metric.second.getNode("metricPluginType").getValue()
00418 << "\n";
00419 OUT << "level: " <<
00420 metric.second.getNode("metricLevel").getValue()
00421 << "\n";
00422
00423 auto metricParametersGroup = metric.second.getNode("metricParametersLink");
00424 if(!metricParametersGroup.isDisconnected())
00425 {
00426 auto metricParameters = metricParametersGroup.getChildren();
00427 for(auto &metricParameter:metricParameters)
00428 {
00429 if(!metricParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
00430 PUSHCOMMENT;
00431
00432 OUT << metricParameter.second.getNode("metricParameterKey").getValue() <<
00433 ": " <<
00434 metricParameter.second.getNode("metricParameterValue").getValue()
00435 << "\n";
00436
00437 if(!metricParameter.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
00438 POPCOMMENT;
00439
00440 }
00441 }
00442 POPTAB;
00443 OUT << "}\n\n";
00444
00445 if(!metric.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>())
00446 POPCOMMENT;
00447 }
00448 }
00449 POPTAB;
00450 OUT << "}\n\n";
00451
00452 POPTAB;
00453 OUT << "}\n\n";
00454
00455
00456 out.close();
00457 }
00458
00459 DEFINE_OTS_CONFIGURATION(ARTDAQBoardReaderConfiguration)