diff --git a/otsdaq-mu2e-trigger/TablePlugins/TriggerConfigTable.h b/otsdaq-mu2e-trigger/TablePlugins/TriggerConfigTable.h index 0ada074..d40d716 100644 --- a/otsdaq-mu2e-trigger/TablePlugins/TriggerConfigTable.h +++ b/otsdaq-mu2e-trigger/TablePlugins/TriggerConfigTable.h @@ -10,19 +10,20 @@ namespace ots { +// clang-format off class TriggerConfigTable : public TableBase { public: TriggerConfigTable(void); virtual ~TriggerConfigTable(void); - // Methods - void init(ConfigurationManager* configManager); - void createTriggerMenuFiles(std::ofstream& EpilogFclFile, - std::string& EpilogDir, - std::string& TrigPath, - ots::ConfigurationTree ConfTree); - std::string GetModuleNameFromPath(std::string& TrigPath); + //Methods + void init (ConfigurationManager* configManager) override; + void initPrereqsForARTDAQ (const ConfigurationManager* configManager) override; + + std::mutex prereqsGeneratedMutex_; + bool prereqsGenerated_ = false; }; +// clang-format on } // namespace ots #endif diff --git a/otsdaq-mu2e-trigger/TablePlugins/TriggerConfigTable_table.cc b/otsdaq-mu2e-trigger/TablePlugins/TriggerConfigTable_table.cc index 2ef6063..32814ce 100644 --- a/otsdaq-mu2e-trigger/TablePlugins/TriggerConfigTable_table.cc +++ b/otsdaq-mu2e-trigger/TablePlugins/TriggerConfigTable_table.cc @@ -1,7 +1,7 @@ #include "otsdaq-mu2e-trigger/TablePlugins/TriggerConfigTable.h" #include "otsdaq/ConfigurationInterface/ConfigurationManager.h" #include "otsdaq/Macros/TablePluginMacros.h" -// #include "otsdaq/tools/otsdaq_load_json_document.cc" +//#include "otsdaq/tools/otsdaq_load_json_document.cc" #include #include //for mkdir @@ -14,7 +14,7 @@ using namespace ots; #define ARTDAQ_FCL_PATH std::string(getenv("OTS_SCRATCH")) + "/TriggerConfigurations/" #define ARTDAQ_FILE_PREAMBLE "boardReader" -// helpers +//helpers #define OUT out << tabStr << commentStr #define PUSHTAB tabStr += "\t" #define POPTAB tabStr.resize(tabStr.size() - 1) @@ -25,14 +25,14 @@ using namespace ots; TriggerConfigTable::TriggerConfigTable(void) : TableBase("TriggerConfigTable") { ////////////////////////////////////////////////////////////////////// - // WARNING: the names used in C++ MUST match the Table INFO // + //WARNING: the names used in C++ MUST match the Table INFO // ////////////////////////////////////////////////////////////////////// __COUTS__(10) << "[TriggerConfigTable::TriggerConfigTable] Initializing the " "TriggerConfigTable plugin..." << __E__; // exit(0); __COUTS__(10) << StringMacros::stackTrace() << __E__; -} // end constructor +} //end constructor //======================================================================================================================== TriggerConfigTable::~TriggerConfigTable(void) {} @@ -40,13 +40,40 @@ TriggerConfigTable::~TriggerConfigTable(void) {} //======================================================================================================================== void TriggerConfigTable::init(ConfigurationManager* configManager) { + __COUTS__(10) << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << __E__; + __COUTS__(10) << configManager->__SELF_NODE__ << __E__; + isFirstAppInContext_ = configManager->isOwnerFirstAppInContext(); __COUTV__(isFirstAppInContext_); if(!isFirstAppInContext_) return; +} //end init() - // make directory just in case +//======================================================================================================================== +void TriggerConfigTable::initPrereqsForARTDAQ(const ConfigurationManager* configManager) +{ + __COUTS__(50) << "initPrereqsForARTDAQ()" << __E__; + __COUTS__(51) << StringMacros::stackTrace() << __E__; + + bool needToGenerate = false; + //lock for scope to check if need to generate in this thread + std::lock_guard lock(prereqsGeneratedMutex_); + if(!prereqsGenerated_) + needToGenerate = true; + + + if(!needToGenerate) //then wait for generation + { + __COUTS__(10) << "initPrereqsForARTDAQ() already generated!" << __E__; + return; //done! + } + + __COUTS__(10) << "initPrereqsForARTDAQ() generating!" << __E__; + __COUTS__(11) << StringMacros::stackTrace() << __E__; + + + //make directory just in case mkdir((ARTDAQ_FCL_PATH).c_str(), 0755); std::string trigEpilogsDir; @@ -54,267 +81,81 @@ void TriggerConfigTable::init(ConfigurationManager* configManager) trigEpilogsDir = ARTDAQ_FCL_PATH + fcl_dir; mkdir(trigEpilogsDir.c_str(), 0755); - __COUTS__(10) << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << std::endl; - __COUTS__(10) << configManager->__SELF_NODE__ << std::endl; - auto childrenMap = configManager->__SELF_NODE__.getChildren(); + __COUTS__(10) << "children map size" << childrenMap.size() << __E__; - // now download from MONGO-Db the trigger table to be used - std::string getTableFromMongoDb = "otsdaq_load_json_document "; + if(childrenMap.empty()) + { + __SS__ << "There is no record in the table '" << configManager->__SELF_NODE__.getTableName() + << "' - the first record is required to define the Trigger Menu document and tag!" << __E__; + __SS_THROW__; + } + + auto& topLevelPair = childrenMap.at(0); + __COUTS__(10) << "Main table name '" << topLevelPair.first << "'" << __E__; + + //now download from MONGO-Db the trigger table to be used std::string triggerTableName = - " " + - childrenMap[0].second.getNode("TriggerDocName").getValue(); //" testTriggerDoc "; + topLevelPair.second.getNode("TriggerDocName").getValue(); //" testTriggerDoc "; std::string triggerTableVersion = - " " + childrenMap[0].second.getNode("TriggerConfigTag").getValue() + " "; - std::string outputFileName = ARTDAQ_FCL_PATH + "trigger_table.json"; + topLevelPair.second.getNode("TriggerConfigTag").getValue(); //" 6 "; + std::string outputFileName = ARTDAQ_FCL_PATH + "/physMenu.json"; + + //sanitize values for system call + for(size_t c = 0; c < triggerTableName.size(); ++c) + if(!((triggerTableName[c] >= 'a' && triggerTableName[c] <= 'z') || + (triggerTableName[c] >= 'A' && triggerTableName[c] <= 'Z') || + (triggerTableName[c] >= '0' && triggerTableName[c] <= '9') || + triggerTableName[c] == '_' || triggerTableName[c] == '-')) + { + __SS__ << "Illegal character found in triggerTableName '" << triggerTableName + << "' ... only alpha-numeric, dashes, and underscores allowed." + << __E__; + __SS_THROW__; + } + + for(size_t c = 0; c < triggerTableVersion.size(); ++c) + if(!((triggerTableVersion[c] >= '0' && triggerTableVersion[c] <= '9'))) + { + __SS__ << "Illegal character found in triggerTableVersion '" + << triggerTableVersion << "' ... only numeric characters allowed." + << __E__; + __SS_THROW__; + } - __COUTS__(10) << "printing children content" << __E__; - __COUTS__(10) << "TriggerDocName : " << triggerTableName << __E__; - __COUTS__(10) << "TriggerConfigTag: " << triggerTableVersion << __E__; + std::string getTableFromMongoDb = "otsdaq_load_json_document "; + getTableFromMongoDb += + triggerTableName + " " + triggerTableVersion + " " + outputFileName; + __COUTS__(10) << "otsdaq_load_json command: " << getTableFromMongoDb << __E__; - getTableFromMongoDb += triggerTableName + triggerTableVersion + outputFileName; - system(getTableFromMongoDb.c_str()); + std::string laodJsonResult = StringMacros::exec(getTableFromMongoDb.c_str()); + __COUTVS__(10, laodJsonResult.size()); + __COUT_MULTI__(10, laodJsonResult); - __COUTS__(10) << StringMacros::stackTrace() << __E__; - std::string command = "generateMenuFromJSON.py"; - std::string menuFile = - " -mf " + outputFileName; //"mu2e_trig_config/data/physMenu.json"; - std::string output = " -o " + trigEpilogsDir; - std::string evtMode = " -evtMode all"; + std::string menuFile = " -mf " + outputFileName; + std::string output = " -o " + trigEpilogsDir; + std::string evtMode = " -evtMode all"; + std::string command = + "python generateMenuFromJSON.py"; command += menuFile + output + evtMode; - system(command.c_str()); - - // //create the fcl file - // std::ofstream triggerFclFile, epilogFclFile, subEpilogFclFile, - // allPathsFile; std::string fclFileName, skelethonName, allPathsFileName; - // std::string epilogName; - // //skelethon to clone - // // skelethonName = Form("%s/main.fcl", (ARTDAQ_FCL_PATH).c_str()); - // skelethonName = ARTDAQ_FCL_PATH + "/main.fcl" ; - // //file to be edited - // // fclFileName = Form("%s/runTriggerExample.fcl", - // (ARTDAQ_FCL_PATH).c_str()); fclFileName = - // ARTDAQ_FCL_PATH+"/runTriggerExample.fcl"; - - // //file that will house all the includes necessary to run the trigger paths - // allPathsFileName = trigEpilogsDir+ "/allPaths.fcl"; - - // std::ifstream mainFclFile; - // mainFclFile .open(skelethonName); - // triggerFclFile.open(fclFileName); - // allPathsFile .open(allPathsFileName); - - // std::string line; - // while (std::getline(mainFclFile, line, '\n') ) triggerFclFile << line << - // '\n'; - - // //we need to append the line where include the fcl that will contain all - // the trigger paths triggerFclFile << "#include - // \"Trigger_epilogs/allPaths.fcl\""<<__E__; - - // __COUTS__(10) << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << std::endl; - // __COUTS__(10) << configManager->__SELF_NODE__ << std::endl; - - // auto childrenMap = configManager->__SELF_NODE__.getChildren(); - // __COUTS__(10) <<"printing children content"<<__E__; - // __COUTS__(10) <<"children map size"< list_of_pathIDs; - - // for (auto &triggerPathPair : triggerPaths) - // { - // __COUTS__(10) << "internal LOOP" << __E__; - // __COUTS__(10) << "Trigger Path '" << triggerPathPair.first << "'" << - //__E__; - // __COUTS__(10) << "Trigger Name '" << - // triggerPathPair.second.getNode("TriggerName").getValue() << "'" << __E__; - - // std::string trigger_status = - // triggerPathPair.second.getNode("Status").getValue(); if - // (trigger_status == "Off"){ - // __COUTS__(10) << "Trigger status is Off" << __E__; - // continue; - // } - // ots::ConfigurationTree singlePath = - // triggerPathPair.second.getNode("LinkToTriggerTable"); - // __COUTS__(10) << "singlePath : " << singlePath << __E__; - // __COUTS__(10) << "singlePath.isDisconnected : " << - // singlePath.isDisconnected() << __E__; - // // __COUTS__(10) << "singlePath.getNode : " << - // StringMacros::vectorToString(singlePath.getChildrenNames()) << __E__; - // // __COUTS__(10) << "singlePath.getConfigurationManager " << - // singlePath.getConfigurationManager() << __E__; - // // __COUTS__(10) << - //"singlePath.getConfigurationManager()->getTableByName " << - // singlePath.getConfigurationManager()->getTableByName("TriggerParameterTable") - //<< __E__; - - // std::string triggerType = - // triggerPathPair.second.getNode("TriggerType").getValue(); - // int pathID = triggerPathPair.second.getNode("PathID").getValue(); - - // __COUTS__(10) << "Trigger Type '" << triggerType << "'" << __E__; - - // //create the fcl housing the trigger-path configurations - // epilogName = trigEpilogsDir + "/" + triggerPathPair.first + ".fcl"; - // allPathsFile << "#include \"Trigger_epilogs/" << - // triggerPathPair.first<<".fcl\"" << __E__; - // //we need to append the line where we instantiate the given - // TriggerPath - // // allPathsFile << "art.physics." << triggerPathPair.first << - //"_trigger : [ @sequence::Trigger.paths."<< triggerPathPair.first<< " ]\n" - //<< __E__; - // // allPathsFile << "art.physics." << triggerPathPair.first << - //"_trigger : [ makeSD, CaloDigiMaker, @sequence::Trigger.paths."<< - // triggerPathPair.first<< " ]\n" << __E__; - // //allPathsFile << "art.physics." << triggerPathPair.first << - //"_trigger : [ dtcEventVerifier, artFragFromDTCEvents, makeSD, - //@sequence::Trigger.paths."<< triggerPathPair.first<< " ]" << __E__; - // allPathsFile << "art.physics." << triggerPathPair.first << "_trigger - //: [ artFragFromDTCEvents, makeSD, @sequence::Trigger.paths."<< - // triggerPathPair.first<< " ]" << __E__; allPathsFile << - //"art.physics.trigger_paths["<< pathID <<"] : " << triggerPathPair.first << - //"_trigger \n"<< __E__; - - // epilogFclFile.open(epilogName.c_str()); - - // //check if the pathID is already usd by another trigger chain - // for (auto & id : list_of_pathIDs){ - // if (id == pathID){ - // __SS__ << "Attempt to use twice the same PathID : "<< pathID << - // std::endl; - // __COUT_ERR__ << ss.str() << std::endl; - // __SS_THROW__; - // } - // } - - // //create the directory that will house all the epilogs of a given - // triggerPath std::string singlePathEpilogsDir, - // singlePathPairFclName; - // // singlePathEpilogsDir = "%sTrigger_epilogs/%s", - //(ARTDAQ_FCL_PATH).c_str(), triggerPathPair.first.c_str()); - // singlePathEpilogsDir = ARTDAQ_FCL_PATH + "Trigger_epilogs/" + - // triggerPathPair.first; mkdir(singlePathEpilogsDir.c_str(), 0755); - // __COUTS__(10) << "single path epilogs dir " << singlePathEpilogsDir - //<< __E__; - - // //set the general prescale factor at the beginning of the path - // createPrescaleEpilog (epilogFclFile, singlePathEpilogsDir, - // triggerPathPair.first, triggerPathPair.second); //singlePath); - - // if (triggerType == "TrackSeed") - // { - // //to set up the Tracking filters we need to loop over the children - // of the corresponding node createTrackingFiltersEpilog - // (epilogFclFile, singlePathEpilogsDir, triggerPathPair.first, singlePath); - // } - // else if (triggerType == "Helix") - // { - // singlePath.getNode("LinkToDigiFilterParameterTable"); - // createHelixFiltersEpilog (epilogFclFile, singlePathEpilogsDir, - // triggerPathPair.first, singlePath); - // } - // else if (triggerType == "DigiCount") - // { - // createDigiCountFiltersEpilog (epilogFclFile, - // singlePathEpilogsDir, triggerPathPair.first, singlePath); - // } - - // __COUTS__(10) <<" closing epilogFclFile" <<__E__; - - // epilogFclFile.close(); - // __COUTS__(10) << "epilogFclFile closed... " << __E__; - - // ++counter; - // __COUTS__(10) <<"counter = " << counter <<", map-size = " << - // children_map_size <<__E__; - // // if (counter == children_map_size-2) break; - // }//end loop over triggerPathPair - - // __COUTS__(10) <<" end of main LOOP" <<__E__; - - // }//end loop over topLevelPair - - // __COUTS__(10) << "loop completed closed... " << __E__; - - // triggerFclFile.close(); - // __COUTS__(10) << "triggerFclFile closed... " << __E__; -} - -//---------------------------------------------------------------------------------------------------- -// this function creates a string usde to set the module names in a given -// trigPath -//---------------------------------------------------------------------------------------------------- -std::string TriggerConfigTable::GetModuleNameFromPath(std::string& TrigPath) -{ - std::string del("_"); - std::string name(TrigPath); - std::string newName = ""; - __COUTS__(10) << "TrigPath = " << TrigPath << __E__; - - auto pos = name.find(del); - if(pos == std::string::npos) + __COUTS__(10) << "generateMenuFromJSON command: " << command << __E__; + std::string genMenuResult = StringMacros::exec(command.c_str()); + __COUTVS__(10, genMenuResult.size()); + __COUT_MULTI__(10, genMenuResult); + if(1 || genMenuResult == "") { - newName = name; + command = + "python $OTSDAQ_DIR/python/generateMenuFromJSON.py"; + command += menuFile + output + evtMode; + __COUTS__(10) << "generateMenuFromJSON command tk2: " << command << __E__; + genMenuResult = StringMacros::exec(command.c_str()); + __COUTVS__(10, genMenuResult.size()); + __COUT_MULTI__(10, genMenuResult); } - else - { - newName = name.substr(0, pos); - name.erase(0, pos + del.length()); - __COUTS__(10) << "newName = " << newName << ", name = " << name << __E__; - // while(name.length() >0) - do - { - auto pos = name.find(del); - std::string token = name.substr(0, pos); - if((pos == std::string::npos) && (name.length() > 0)) - { - token = name; - name = ""; - } - if((newName != "") && - (token.find("timing") == - std::string::npos)) // convert to upper case the first letter - { - token[0] = token[0] - 32; - newName += token; - } - name.erase(0, pos + del.length()); - __COUTS__(10) << "[while ] newName = " << newName << ", name = " << name - << __E__; - - } while(name.length() > 0); // name.find(del) != std::string::npos); - } - return newName; -} + prereqsGenerated_ = true; +} //end initPrereqsForARTDAQ() DEFINE_OTS_TABLE(TriggerConfigTable)