diff --git a/MQ/monitor/CMakeLists.txt b/MQ/monitor/CMakeLists.txt index b4832fbd67b5bcadd92d3de53436a61ed15abb56..e8366b2b7f979524e6d2fb91149a75f44f9f0e19 100644 --- a/MQ/monitor/CMakeLists.txt +++ b/MQ/monitor/CMakeLists.txt @@ -3,6 +3,8 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/startMQSamplerT0Monitor2020.sh.in ${C configure_file(${CMAKE_CURRENT_SOURCE_DIR}/startMQSamplerTofMonitor2020.sh.in ${CMAKE_BINARY_DIR}/bin/MQ/topologies/startMQSamplerTofMonitor2020.sh) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/startMQSamplerT0Monitor2021.sh.in ${CMAKE_BINARY_DIR}/bin/MQ/topologies/startMQSamplerT0Monitor2021.sh) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/startMQSamplerTofMonitor2021.sh.in ${CMAKE_BINARY_DIR}/bin/MQ/topologies/startMQSamplerTofMonitor2021.sh) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/startMQSamplerPsdMonitor2021.sh.in ${CMAKE_BINARY_DIR}/bin/MQ/topologies/startMQSamplerPsdMonitor2021.sh) + set(INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} @@ -14,8 +16,11 @@ set(INCLUDE_DIRECTORIES ${CBMROOT_SOURCE_DIR}/fles/flestools ${CBMDATA_DIR} ${CBMDATA_DIR}/tof + ${CBMDATA_DIR}/psd ${CBMDATA_DIR}/raw ${CBMBASE_DIR} + + ${CBMDETECTORBASE_DIR}/psd ) Set(SYSTEM_INCLUDE_DIRECTORIES @@ -107,3 +112,24 @@ set(DEPENDENCIES #GENERATE_LIBRARY() GENERATE_EXECUTABLE() +set(EXE_NAME PsdMonitorMcbm2018) +set(SRCS CbmDeviceMonitorPsd.cxx runMonitorPsd.cxx) + +set(DEPENDENCIES + ${DEPENDENCIES} + ${FAIR_LIBS} + ${BOOST_LIBS} + fles_ipc + CbmFlibMcbm2018 + CbmFlibFlesTools + CbmBase + CbmData + Core + RIO + Net + Hist + RHTTP +) +#GENERATE_LIBRARY() +GENERATE_EXECUTABLE() + diff --git a/MQ/monitor/CbmDeviceMonitorPsd.cxx b/MQ/monitor/CbmDeviceMonitorPsd.cxx new file mode 100644 index 0000000000000000000000000000000000000000..697bb62dd9304edcbd4638302ab094dba9d679f7 --- /dev/null +++ b/MQ/monitor/CbmDeviceMonitorPsd.cxx @@ -0,0 +1,339 @@ +/** + * CbmDeviceMonitorPsd.cxx + * + * @since 2021-02-17 + * @author N. Karpushkin + * @comment based on CbmDeviceMonitorT0 by F. Uhlig + */ + +#include "CbmDeviceMonitorPsd.h" + +#include "CbmFlesCanvasTools.h" +#include "CbmMQDefs.h" +#include "CbmMcbm2018MonitorAlgoPsd.h" + +#include "StorableTimeslice.hpp" + +#include "FairMQLogger.h" +#include "FairMQProgOptions.h" // device->fConfig +#include "FairParGenericSet.h" + +#include "TCanvas.h" +#include "TFile.h" +#include "TH1.h" +#include "TList.h" +#include "TNamed.h" + +#include "BoostSerializer.h" +#include <boost/archive/binary_iarchive.hpp> +#include <boost/serialization/utility.hpp> + +#include <array> +#include <iomanip> +#include <stdexcept> +#include <string> + +#include "RootSerializer.h" +struct InitTaskError : std::runtime_error { + using std::runtime_error::runtime_error; +}; + +using namespace std; + +CbmDeviceMonitorPsd::CbmDeviceMonitorPsd() + : fbIgnoreOverlapMs {false} + , fsChannelNameDataInput {"psdcomponent"} + , fsChannelNameHistosInput {"histogram-in"} + , fsChannelNameHistosConfig {"histo-conf"} + , fsChannelNameCanvasConfig {"canvas-conf"} + , fuPublishFreqTs {100} + , fdMinPublishTime {0.5} + , fdMaxPublishTime {5.0} + , fuHistoryHistoSize {3600} + , fviHistoChargeArgs(3, 0) + , fviHistoAmplArgs(3, 0) + , fviHistoZLArgs(3, 0) + , fsAllowedChannels {fsChannelNameDataInput} + , fParCList {nullptr} + , fulNumMessages {0} + , fulTsCounter {0} + , fLastPublishTime {std::chrono::system_clock::now()} + , fMonitorAlgo {new CbmMcbm2018MonitorAlgoPsd()} + , fArrayHisto {} + , fvpsHistosFolder {} + , fvpsCanvasConfig {} +{ +} + +void CbmDeviceMonitorPsd::InitTask() +try { + /// Read options from executable + LOG(info) << "Init options for CbmMqStarHistoServer."; + fbIgnoreOverlapMs = fConfig->GetValue<bool>("IgnOverMs"); + fbMonitorMode = fConfig->GetValue<bool>("MonitorMode"); + fbMonitorChanMode = fConfig->GetValue<bool>("MonitorChanMode"); + fbMonitorWfmMode = fConfig->GetValue<bool>("MonitorWfmMode"); + fbMonitorFitMode = fConfig->GetValue<bool>("MonitorFitMode"); + fuHistoryHistoSize = fConfig->GetValue<uint32_t>("HistEvoSz"); + fviHistoChargeArgs = fConfig->GetValue<std::vector<int>>("HistChrgArgs"); + fviHistoAmplArgs = fConfig->GetValue<std::vector<int>>("HistAmplArgs"); + fviHistoZLArgs = fConfig->GetValue<std::vector<int>>("HistZlArgs"); + fuPublishFreqTs = fConfig->GetValue<uint32_t>("PubFreqTs"); + fdMinPublishTime = fConfig->GetValue<double_t>("PubTimeMin"); + fdMaxPublishTime = fConfig->GetValue<double_t>("PubTimeMax"); + fsChannelNameDataInput = fConfig->GetValue<std::string>("TsNameIn"); + fsChannelNameHistosInput = fConfig->GetValue<std::string>("ChNameIn"); + fsChannelNameHistosConfig = fConfig->GetValue<std::string>("ChNameHistCfg"); + fsChannelNameCanvasConfig = fConfig->GetValue<std::string>("ChNameCanvCfg"); + fsAllowedChannels[0] = fsChannelNameDataInput; + + LOG(info) << "Histograms publication frequency in TS: " << fuPublishFreqTs; + LOG(info) << "Histograms publication min. interval in s: " << fdMinPublishTime; + LOG(info) << "Histograms publication max. interval in s: " << fdMaxPublishTime; + + // Get the information about created channels from the device + // Check if the defined channels from the topology (by name) + // are in the list of channels which are possible/allowed + // for the device + // The idea is to check at initilization if the devices are + // properly connected. For the time beeing this is done with a + // nameing convention. It is not avoided that someone sends other + // data on this channel. + //logger::SetLogLevel("INFO"); + + int noChannel = fChannels.size(); + LOG(info) << "Number of defined channels: " << noChannel; + for (auto const& entry : fChannels) { + LOG(info) << "Channel name: " << entry.first; + if (std::string::npos != entry.first.find(fsChannelNameDataInput)) { + if (!IsChannelNameAllowed(entry.first)) throw InitTaskError("Channel name does not match."); + OnData(entry.first, &CbmDeviceMonitorPsd::HandleData); + } // if( entry.first.find( "ts" ) + } // for( auto const &entry : fChannels ) + InitContainers(); +} +catch (InitTaskError& e) { + LOG(error) << e.what(); + // Wrapper defined in CbmMQDefs.h to support different FairMQ versions + cbm::mq::ChangeState(this, cbm::mq::Transition::ErrorFound); +} + +bool CbmDeviceMonitorPsd::IsChannelNameAllowed(std::string channelName) +{ + for (auto const& entry : fsAllowedChannels) { + std::size_t pos1 = channelName.find(entry); + if (pos1 != std::string::npos) { + const vector<std::string>::const_iterator pos = + std::find(fsAllowedChannels.begin(), fsAllowedChannels.end(), entry); + const vector<std::string>::size_type idx = pos - fsAllowedChannels.begin(); + LOG(info) << "Found " << entry << " in " << channelName; + LOG(info) << "Channel name " << channelName << " found in list of allowed channel names at position " << idx; + return true; + } // if (pos1!=std::string::npos) + } // for(auto const &entry : fsAllowedChannels) + LOG(info) << "Channel name " << channelName << " not found in list of allowed channel names."; + LOG(error) << "Stop device."; + return false; +} + +Bool_t CbmDeviceMonitorPsd::InitContainers() +{ + LOG(info) << "Init parameter containers for CbmDeviceMonitorPsd."; + + fParCList = fMonitorAlgo->GetParList(); + + for (int iparC = 0; iparC < fParCList->GetEntries(); iparC++) { + FairParGenericSet* tempObj = (FairParGenericSet*) (fParCList->At(iparC)); + fParCList->Remove(tempObj); + std::string paramName {tempObj->GetName()}; + // NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place). + // Should only be used for small data because of the cost of an additional copy + + // Her must come the proper Runid + std::string message = paramName + ",111"; + LOG(info) << "Requesting parameter container " << paramName << ", sending message: " << message; + + FairMQMessagePtr req(NewSimpleMessage(message)); + FairMQMessagePtr rep(NewMessage()); + + FairParGenericSet* newObj = nullptr; + + if (Send(req, "parameters") > 0) { + if (Receive(rep, "parameters") >= 0) { + if (rep->GetSize() != 0) { + CbmMQTMessage tmsg(rep->GetData(), rep->GetSize()); + newObj = static_cast<FairParGenericSet*>(tmsg.ReadObject(tmsg.GetClass())); + LOG(info) << "Received unpack parameter from the server:"; + newObj->print(); + } + else { + LOG(error) << "Received empty reply. Parameter not available"; + } // if (rep->GetSize() != 0) + } // if (Receive(rep, "parameters") >= 0) + } // if (Send(req, "parameters") > 0) + fParCList->AddAt(newObj, iparC); + delete tempObj; + } // for ( int iparC = 0; iparC < fParCList->GetEntries(); iparC++ ) + + /// Need to add accessors for all options + fMonitorAlgo->SetIgnoreOverlapMs(fbIgnoreOverlapMs); + fMonitorAlgo->SetMonitorMode(fbMonitorMode); + fMonitorAlgo->SetMonitorChanMode(fbMonitorChanMode); + fMonitorAlgo->SetMonitorWfmMode(fbMonitorWfmMode); + fMonitorAlgo->SetMonitorFitMode(fbMonitorFitMode); + fMonitorAlgo->SetHistoryHistoSize(fuHistoryHistoSize); + fMonitorAlgo->SetChargeHistoArgs(fviHistoChargeArgs); + fMonitorAlgo->SetAmplHistoArgs(fviHistoAmplArgs); + fMonitorAlgo->SetZLHistoArgs(fviHistoZLArgs); + //fMonitorAlgo->AddMsComponentToList(0, 0x80); + + Bool_t initOK = fMonitorAlgo->InitContainers(); + + // Bool_t initOK = fMonitorAlgo->ReInitContainers(); + + /// Histos creation and obtain pointer on them + /// Trigger histo creation on all associated algos + initOK &= fMonitorAlgo->CreateHistograms(); + + /// Obtain vector of pointers on each histo from the algo (+ optionally desired folder) + std::vector<std::pair<TNamed*, std::string>> vHistos = fMonitorAlgo->GetHistoVector(); + /// Obtain vector of pointers on each canvas from the algo (+ optionally desired folder) + std::vector<std::pair<TCanvas*, std::string>> vCanvases = fMonitorAlgo->GetCanvasVector(); + + /// Add pointers to each histo in the histo array + /// Create histo config vector + /// ===> Use an std::vector< std::pair< std::string, std::string > > with < Histo name, Folder > + /// and send it through a separate channel using the BoostSerializer + for (UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto) { + // LOG(info) << "Registering " << vHistos[ uHisto ].first->GetName() + // << " in " << vHistos[ uHisto ].second.data() + // ; + fArrayHisto.Add(vHistos[uHisto].first); + std::pair<std::string, std::string> psHistoConfig(vHistos[uHisto].first->GetName(), vHistos[uHisto].second); + fvpsHistosFolder.push_back(psHistoConfig); + + /// Serialize the vector of histo config into a single MQ message + FairMQMessagePtr messageHist(NewMessage()); + Serialize<BoostSerializer<std::pair<std::string, std::string>>>(*messageHist, psHistoConfig); + + /// Send message to the common histogram config messages queue + if (Send(messageHist, fsChannelNameHistosConfig) < 0) { + LOG(error) << "Problem sending histo config"; + return false; + } // if( Send( messageHist, fsChannelNameHistosConfig ) < 0 ) + + LOG(info) << "Config of hist " << psHistoConfig.first.data() << " in folder " << psHistoConfig.second.data(); + } // for( UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto ) + + /// Create canvas config vector + /// ===> Use an std::vector< std::pair< std::string, std::string > > with < Canvas name, config > + /// and send it through a separate channel using the BoostSerializer + for (UInt_t uCanv = 0; uCanv < vCanvases.size(); ++uCanv) { + // LOG(info) << "Registering " << vCanvases[ uCanv ].first->GetName() + // << " in " << vCanvases[ uCanv ].second.data(); + std::string sCanvName = (vCanvases[uCanv].first)->GetName(); + std::string sCanvConf = GenerateCanvasConfigString(vCanvases[uCanv].first); + + std::pair<std::string, std::string> psCanvConfig(sCanvName, sCanvConf); + + fvpsCanvasConfig.push_back(psCanvConfig); + + /// Serialize the vector of canvas config into a single MQ message + FairMQMessagePtr messageCan(NewMessage()); + Serialize<BoostSerializer<std::pair<std::string, std::string>>>(*messageCan, psCanvConfig); + + /// Send message to the common canvas config messages queue + if (Send(messageCan, fsChannelNameCanvasConfig) < 0) { + LOG(error) << "Problem sending canvas config"; + return false; + } // if( Send( messageCan, fsChannelNameCanvasConfig ) < 0 ) + + LOG(info) << "Config string of Canvas " << psCanvConfig.first.data() << " is " << psCanvConfig.second.data(); + } // for( UInt_t uCanv = 0; uCanv < vCanvases.size(); ++uCanv ) + + return initOK; +} + + +// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0) +bool CbmDeviceMonitorPsd::HandleData(FairMQMessagePtr& msg, int /*index*/) +{ + fulNumMessages++; + LOG(debug) << "Received message number " << fulNumMessages << " with size " << msg->GetSize(); + + if (0 == fulNumMessages % 10000) LOG(info) << "Received " << fulNumMessages << " messages"; + + std::string msgStr(static_cast<char*>(msg->GetData()), msg->GetSize()); + std::istringstream iss(msgStr); + boost::archive::binary_iarchive inputArchive(iss); + + /// Create an empty TS and fill it with the incoming message + fles::StorableTimeslice component {0}; + inputArchive >> component; + + /// Process the Timeslice + DoUnpack(component, 0); + + /// Send histograms each 100 time slices. Should be each ~1s + /// Use also runtime checker to trigger sending after M s if + /// processing too slow or delay sending if processing too fast + std::chrono::system_clock::time_point currentTime = std::chrono::system_clock::now(); + std::chrono::duration<double_t> elapsedSeconds = currentTime - fLastPublishTime; + if ((fdMaxPublishTime < elapsedSeconds.count()) + || (0 == fulNumMessages % fuPublishFreqTs && fdMinPublishTime < elapsedSeconds.count())) { + SendHistograms(); + fLastPublishTime = std::chrono::system_clock::now(); + } // if( ( fdMaxPublishTime < elapsedSeconds.count() ) || ( 0 == fulNumMessages % fuPublishFreqTs && fdMinPublishTime < elapsedSeconds.count() ) ) + + return true; +} + +bool CbmDeviceMonitorPsd::SendHistograms() +{ + /// Serialize the array of histos into a single MQ message + FairMQMessagePtr message(NewMessage()); + Serialize<RootSerializer>(*message, &fArrayHisto); + + /// Send message to the common histogram messages queue + if (Send(message, fsChannelNameHistosInput) < 0) { + LOG(error) << "Problem sending data"; + return false; + } // if( Send( message, fsChannelNameHistosInput ) < 0 ) + + /// Reset the histograms after sending them (but do not reset the time) + fMonitorAlgo->ResetHistograms(kFALSE); + + return true; +} + + +CbmDeviceMonitorPsd::~CbmDeviceMonitorPsd() {} + +Bool_t CbmDeviceMonitorPsd::DoUnpack(const fles::Timeslice& ts, size_t /*component*/) +{ + + if (kFALSE == fbComponentsAddedToList) { + for (uint32_t uCompIdx = 0; uCompIdx < ts.num_components(); ++uCompIdx) { + if (kusSysId == ts.descriptor(uCompIdx, 0).sys_id) { + fMonitorAlgo->AddMsComponentToList(uCompIdx, kusSysId); + } // if( kusSysId == ts.descriptor( uCompIdx, 0 ).sys_id ) + } // for( uint32_t uComp = 0; uComp < ts.num_components(); ++uComp ) + fbComponentsAddedToList = kTRUE; + } // if( kFALSE == fbComponentsAddedToList ) + + if (kFALSE == fMonitorAlgo->ProcessTs(ts)) { + LOG(error) << "Failed processing TS " << ts.index() << " in unpacker algorithm class"; + return kTRUE; + } // if( kFALSE == fMonitorAlgo->ProcessTs( ts ) ) + + /// Clear the digis vector in case it was filled + fMonitorAlgo->ClearVector(); + + if (0 == fulTsCounter % 10000) LOG(info) << "Processed " << fulTsCounter << "TS"; + fulTsCounter++; + + return kTRUE; +} + + +void CbmDeviceMonitorPsd::Finish() {} diff --git a/MQ/monitor/CbmDeviceMonitorPsd.h b/MQ/monitor/CbmDeviceMonitorPsd.h new file mode 100644 index 0000000000000000000000000000000000000000..44c28213ccfb4ebed4420c679248ca1491f79ef6 --- /dev/null +++ b/MQ/monitor/CbmDeviceMonitorPsd.h @@ -0,0 +1,101 @@ +/** + * CbmDeviceMonitorPsd.h + * + * @since 2021-02-17 + * @author N. Karpushkin + * @comment based on CbmDeviceMonitorT0 by F. Uhlig + */ + +#ifndef CBMDEVICEMONITORPSD_H_ +#define CBMDEVICEMONITORPSD_H_ + +#include "Timeslice.hpp" + +#include "FairMQDevice.h" + +#include "Rtypes.h" +#include "TMessage.h" +#include "TObjArray.h" + +#include <chrono> +#include <map> +#include <vector> + +class TList; +class CbmMcbm2018MonitorAlgoPsd; + +class CbmDeviceMonitorPsd : public FairMQDevice { +public: + CbmDeviceMonitorPsd(); + virtual ~CbmDeviceMonitorPsd(); + +protected: + virtual void InitTask(); + bool HandleData(FairMQMessagePtr&, int); + +private: + /// Constants + static const uint16_t kusSysId = 0x80; + Bool_t fbComponentsAddedToList = kFALSE; + + /// Control flags + Bool_t fbMonitorMode; //! Switch ON the filling of a minimal set of histograms + Bool_t fbIgnoreOverlapMs; //! Ignore Overlap Ms: all fuOverlapMsNb MS at the end of timeslice + Bool_t fbMonitorChanMode; //! Switch ON the filling channelwise histograms + Bool_t fbMonitorWfmMode; //! Switch ON the filling waveforms histograms + Bool_t fbMonitorFitMode; //! Switch ON the filling waveform fitting histograms + Bool_t fbDebugMonitorMode; //! Switch ON the filling of a additional set of histograms + + /// User settings parameters + std::string fsChannelNameDataInput; + std::string fsChannelNameHistosInput; + std::string fsChannelNameHistosConfig; + std::string fsChannelNameCanvasConfig; + uint32_t fuPublishFreqTs; + double_t fdMinPublishTime; + double_t fdMaxPublishTime; + + UInt_t fuHistoryHistoSize; + std::vector<Int_t> fviHistoChargeArgs; /** Charge histogram arguments in adc counts **/ + std::vector<Int_t> fviHistoAmplArgs; /** Amplitude histogram arguments in adc counts **/ + std::vector<Int_t> fviHistoZLArgs; /** ZeroLevel histogram arguments in adc counts **/ + + + /// List of MQ channels names + std::vector<std::string> fsAllowedChannels; + + /// Parameters management + TList* fParCList; + + /// Statistics & first TS rejection + uint64_t fulNumMessages; + uint64_t fulTsCounter; + std::chrono::system_clock::time_point fLastPublishTime; + + /// Processing algo + CbmMcbm2018MonitorAlgoPsd* fMonitorAlgo; + + /// Array of histograms to send to the histogram server + TObjArray fArrayHisto; + /// Vector of string pairs with ( HistoName, FolderPath ) to send to the histogram server + std::vector<std::pair<std::string, std::string>> fvpsHistosFolder; + /// Vector of string pairs with ( CanvasName, CanvasConfig ) to send to the histogram server + /// Format of Can config is "NbPadX(U);NbPadY(U);ConfigPad1(s);....;ConfigPadXY(s)" + /// Format of Pad config is "GrixX(b),GridY(b),LogX(b),LogY(b),LogZ(b),HistoName(s),DrawOptions(s)" + std::vector<std::pair<std::string, std::string>> fvpsCanvasConfig; + + bool IsChannelNameAllowed(std::string channelName); + Bool_t InitContainers(); + Bool_t DoUnpack(const fles::Timeslice& ts, size_t component); + void Finish(); + bool SendHistograms(); +}; + +// special class to expose protected TMessage constructor +class CbmMQTMessage : public TMessage { +public: + CbmMQTMessage(void* buf, Int_t len) : TMessage(buf, len) { ResetBit(kIsOwner); } +}; + + +#endif /* CBMDEVICEMONITORPSD_H_ */ diff --git a/MQ/monitor/runMonitorPsd.cxx b/MQ/monitor/runMonitorPsd.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1b304ecf358ea3f47ecd5b1c1761b51db61bf20c --- /dev/null +++ b/MQ/monitor/runMonitorPsd.cxx @@ -0,0 +1,38 @@ +#include "CbmDeviceMonitorPsd.h" + +#include <iomanip> +#include <string> + +#include "runFairMQDevice.h" + +namespace bpo = boost::program_options; +using namespace std; + +void addCustomOptions(bpo::options_description& options) +{ + options.add_options()("IgnOverMs", bpo::value<bool>()->default_value(true), "Ignore overlap MS if true"); + options.add_options()("MonitorMode", bpo::value<bool>()->default_value(true), "Monitor mode ON/OFF"); + options.add_options()("MonitorChanMode", bpo::value<bool>()->default_value(false), "Monitor channelwise mode ON/OFF"); + options.add_options()("MonitorWfmMode", bpo::value<bool>()->default_value(false), "Monitor waveform mode ON/OFF"); + options.add_options()("MonitorFitMode", bpo::value<bool>()->default_value(false), "Monitor fit waveform mode ON/OFF"); + options.add_options()("HistEvoSz", bpo::value<uint32_t>()->default_value(1800), + "Size of evolution histos in seconds"); + options.add_options()("HistChrgArgs", bpo::value<vector<int>>()->multitoken(), "Charge histos arguments"); + options.add_options()("HistAmplArgs", bpo::value<vector<int>>()->multitoken(), "Ampl histos arguments"); + options.add_options()("HistZlArgs", bpo::value<vector<int>>()->multitoken(), "ZL histos arguments"); + options.add_options()("PubFreqTs", bpo::value<uint32_t>()->default_value(100), "Histo publishing frequency in TS"); + options.add_options()("PubTimeMin", bpo::value<double_t>()->default_value(1.0), + "Minimal time between two publishing"); + options.add_options()("PubTimeMax", bpo::value<double_t>()->default_value(10.0), + "Maximal time between two publishing"); + options.add_options()("TsNameIn", bpo::value<std::string>()->default_value("psdcomponent"), + "MQ channel name for TS data"); + options.add_options()("ChNameIn", bpo::value<std::string>()->default_value("histogram-in"), + "MQ channel name for histos"); + options.add_options()("ChNameHistCfg", bpo::value<std::string>()->default_value("histo-conf"), + "MQ channel name for histos config"); + options.add_options()("ChNameCanvCfg", bpo::value<std::string>()->default_value("canvas-conf"), + "MQ channel name for canvases config"); +} + +FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/) { return new CbmDeviceMonitorPsd(); } diff --git a/MQ/monitor/startMQSamplerPsdMonitor2021.sh.in b/MQ/monitor/startMQSamplerPsdMonitor2021.sh.in new file mode 100644 index 0000000000000000000000000000000000000000..02d5551fb0e5e9e069f4b812322172d9d2cecee6 --- /dev/null +++ b/MQ/monitor/startMQSamplerPsdMonitor2021.sh.in @@ -0,0 +1,111 @@ +#!/bin/bash +$SIMPATH/bin/fairmq-shmmonitor --cleanup + +if [ $# -ge 1 ]; then + _nbmoni=$1 + + if [ $# -ge 4 ]; then + _filename="" + _dirname="" + _hostname=$4 + elif [ $# -ge 2 ]; then + _filename=$2 + _hostname="" + if [ $# -eq 3 ]; then + _dirname=$3 + else + _dirname="" + fi + else + echo 'Starting connection to local stream' + echo ' for other usages, please supply at least a filename.' + echo 'Possible usages are:' + echo 'startMQSamplerPsdMonitor2021.sh' + echo 'startMQSamplerPsdMonitor2021.sh <Nb Monitor processes>' + echo 'startMQSamplerPsdMonitor2021.sh <Nb Monitor processes> <full filename pattern list>' + echo 'startMQSamplerPsdMonitor2021.sh <Nb Monitor processes> <filename pattern> <folder_path>' + echo 'startMQSamplerPsdMonitor2021.sh <Nb Monitor processes> "" "" <hostname(s) list>' + _filename="" + _dirname="" + _hostname="localhost" + fi +else + echo 'Starting connection to local stream with 1 monitor process' + echo ' for other usages, please supply at least a filename.' + echo 'Possible usages are:' + echo 'startMQSamplerPsdMonitor2021.sh' + echo 'startMQSamplerPsdMonitor2021.sh <Nb Monitor processes>' + echo 'startMQSamplerPsdMonitor2021.sh <Nb Monitor processes> <full filename pattern list>' + echo 'startMQSamplerPsdMonitor2021.sh <Nb Monitor processes> <filename pattern> <folder_path>' + echo 'startMQSamplerPsdMonitor2021.sh <Nb Monitor processes> "" "" <hostname(s) list>' + _filename="" + _dirname="" + _hostname="localhost" + _nbmoni=1 +fi + +_paramfile=/mnt/scratch/users/ploizeau/mcbm2020/cbmroot_pal/macro/beamtime/mcbm2020/mPsdPar.par +##_paramfile=$VMCWORKDIR/macro/beamtime/mcbm2021/mPsdPar.par + +SAMPLER="MultiTsaSampler" +SAMPLER+=" --id sampler1" +SAMPLER+=" --max-timeslices 0" +SAMPLER+=" --severity info" +#SAMPLER+=" --flib-port 10" +if [ "$_hostname" != "" ]; then + SAMPLER+=" --flib-host $_hostname" +elif [ "$_filename" != "" ]; then + SAMPLER+=" --filename $_filename" + if [ "$_dirname" != "" ]; then + SAMPLER+=" --dirname $_dirname" + fi +fi +SAMPLER+=" --high-water-mark 1000" +SAMPLER+=" --send-ts-per-sysid 1" +SAMPLER+=" --channel-config name=psdcomponent,type=push,method=bind,address=tcp://127.0.0.1:11555" +SAMPLER+=" --transport shmem" +#SAMPLER+=" --transport zeromq" +#SAMPLER+=" --transport nanomsg" +xterm -l -geometry 80x23+0+0 -hold -e @CMAKE_BINARY_DIR@/bin/MQ/source/$SAMPLER & + +_iMoni=0 +((_oubfreqts = $_nbmoni*100 )) +while (( _iMoni < _nbmoni )); do + (( _yOffset=100*_iMoni )) + (( _iMoni += 1 )) + MONITOR="PsdMonitorMcbm2018" + + MONITOR+=" --id mon$_iMoni" + MONITOR+=" --severity info" + MONITOR+=" --HistEvoSz 600" + MONITOR+=" --HistChrgArgs 500 0 5000" + MONITOR+=" --HistAmplArgs 100 0 500" + MONITOR+=" --HistZlArgs 100 0 5000" + MONITOR+=" --PubFreqTs $_oubfreqts" + MONITOR+=" --channel-config name=psdcomponent,type=pull,method=connect,address=tcp://127.0.0.1:11555" + MONITOR+=" --transport shmem" + #MONITOR+=" --transport zeromq" + #MONITOR+=" --transport nanomsg" + MONITOR+=" --channel-config name=parameters,type=req,method=connect,transport=zeromq,address=tcp://127.0.0.1:11005,rateLogging=0" + MONITOR+=" --channel-config name=histogram-in,type=pub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11666" + MONITOR+=" --channel-config name=histo-conf,type=pub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11667" + MONITOR+=" --channel-config name=canvas-conf,type=pub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11668" + xterm -l -geometry 80x23+500+$_yOffset -hold -e @CMAKE_BINARY_DIR@/bin/MQ/monitor/$MONITOR & +done + +PARAMETERSERVER="parmq-server" +PARAMETERSERVER+=" --id parmq-server" +PARAMETERSERVER+=" --severity info" +PARAMETERSERVER+=" --channel-name parameters" +PARAMETERSERVER+=" --channel-config name=parameters,type=rep,method=bind,transport=zeromq,address=tcp://127.0.0.1:11005,rateLogging=0" +PARAMETERSERVER+=" --first-input-name $_paramfile" +PARAMETERSERVER+=" --first-input-type ASCII" +PARAMETERSERVER+=" --libs-to-load=libCbmFlibMcbm2018" # doesn't work due to runtime problem +xterm -geometry 80x23+1000+0 -hold -e @CMAKE_BINARY_DIR@/bin/MQ/parmq/$PARAMETERSERVER & + +HISTSERVER="MqHistoServer" +HISTSERVER+=" --id server1" +HISTSERVER+=" --channel-config name=histogram-in,type=sub,method=bind,transport=zeromq,address=tcp://127.0.0.1:11666" +HISTSERVER+=" --channel-config name=histo-conf,type=sub,method=bind,transport=zeromq,address=tcp://127.0.0.1:11667" +HISTSERVER+=" --channel-config name=canvas-conf,type=sub,method=bind,transport=zeromq,address=tcp://127.0.0.1:11668" +xterm -geometry 800x230+1500+0 -hold -e @CMAKE_BINARY_DIR@/bin/MQ/histogramServer/$HISTSERVER & diff --git a/MQ/source/CbmMQTsaMultiSampler.h b/MQ/source/CbmMQTsaMultiSampler.h index b4e5523a58ba68a34f87589e0dd026a6471285af..2fc353313826fca849ff4242aba350598d05ede1 100644 --- a/MQ/source/CbmMQTsaMultiSampler.h +++ b/MQ/source/CbmMQTsaMultiSampler.h @@ -103,17 +103,17 @@ private: // TODO: Up to now we have three disconnected vectors which is very // error prone. Find a better solution - std::vector<std::string> fAllowedChannels = {"stscomponent", "richcomponent", "trdcomponent", - "muchcomponent", "tofcomponent", "t0component"}; - // std::vector<int> fSysId = {16, 48, 64, 96, 144, 80}; - std::vector<int> fSysId = {0x10, 0x30, 0x40, 0x50, 0x60, 0x90}; + std::vector<std::string> fAllowedChannels = {"stscomponent", "richcomponent", "trdcomponent", "muchcomponent", + "tofcomponent", "t0component", "psdcomponent"}; + // std::vector<int> fSysId = {16, 48, 64, 96, 144, 80}; + std::vector<int> fSysId = {0x10, 0x30, 0x40, 0x50, 0x60, 0x90, 0x80}; - std::vector<int> fComponentsToSend = {0, 0, 0, 0, 0, 0}; - std::vector<std::vector<std::string>> fChannelsToSend = {{}, {}, {}, {}, {}, {}}; + std::vector<int> fComponentsToSend = {0, 0, 0, 0, 0, 0, 0}; + std::vector<std::vector<std::string>> fChannelsToSend = {{}, {}, {}, {}, {}, {}, {}}; bool fbListCompPerSysIdReady = false; - std::vector<std::vector<uint32_t>> fvvCompPerSysId = {{}, {}, {}, {}, {}, {}}; + std::vector<std::vector<uint32_t>> fvvCompPerSysId = {{}, {}, {}, {}, {}, {}, {}}; bool fbListCompPerChannelReady = false; std::vector<std::string> fvChannelsToSend = {};