From d08c3ba454c6f383ce89a4d55dccb1df7404cd0a Mon Sep 17 00:00:00 2001 From: Dominik Smith <smith@th.physik.uni-frankfurt.de> Date: Thu, 18 Mar 2021 15:41:18 +0100 Subject: [PATCH] Added files for BuildRawEvents FairMQ device. Updated CMakeLists.txt to include them. --- MQ/mcbm/CMakeLists.txt | 31 ++ MQ/mcbm/CbmDeviceBuildRawEvents.cxx | 552 ++++++++++++++++++++++++++++ MQ/mcbm/CbmDeviceBuildRawEvents.h | 135 +++++++ MQ/mcbm/runBuildRawEvents.cxx | 48 +++ MQ/mcbm/startMQBuildRawEvents.sh.in | 264 +++++++++++++ 5 files changed, 1030 insertions(+) create mode 100644 MQ/mcbm/CbmDeviceBuildRawEvents.cxx create mode 100644 MQ/mcbm/CbmDeviceBuildRawEvents.h create mode 100644 MQ/mcbm/runBuildRawEvents.cxx create mode 100755 MQ/mcbm/startMQBuildRawEvents.sh.in diff --git a/MQ/mcbm/CMakeLists.txt b/MQ/mcbm/CMakeLists.txt index 3d0afdd0c4..99efb48b99 100644 --- a/MQ/mcbm/CMakeLists.txt +++ b/MQ/mcbm/CMakeLists.txt @@ -1,5 +1,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/startMQMcbmPulserMonitor2020.sh.in ${CMAKE_BINARY_DIR}/bin/MQ/topologies/startMQMcbmPulserMonitor2020.sh) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/startMQMcbmEvtBuilderWin2020.sh.in ${CMAKE_BINARY_DIR}/bin/MQ/topologies/startMQMcbmEvtBuilderWin2020.sh) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/startMQBuildRawEvents.sh.in ${CMAKE_BINARY_DIR}/bin/MQ/topologies/startMQBuildRawEvents.sh) set(INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} @@ -10,6 +11,7 @@ set(INCLUDE_DIRECTORIES ${CBMROOT_SOURCE_DIR}/fles/mcbm2018/dataformat ${CBMROOT_SOURCE_DIR}/fles/mcbm2018/commonMQ ${CBMROOT_SOURCE_DIR}/fles/flestools + ${CBMROOT_SOURCE_DIR}/reco/eventbuilder/digis ${CBMDATA_DIR} ${CBMDATA_DIR}/global ${CBMDATA_DIR}/raw @@ -45,6 +47,7 @@ include_directories(SYSTEM ${SYSTEM_INCLUDE_DIRECTORIES}) set(LINK_DIRECTORIES ${ROOT_LIBRARY_DIR} ${FAIRROOT_LIBRARY_DIR} + ${KFParticle_LIB_DIR} ${FAIRMQ_LIBRARY_DIR} ${Boost_LIBRARY_DIRS} ) @@ -116,6 +119,34 @@ set(DEPENDENCIES #GENERATE_LIBRARY() GENERATE_EXECUTABLE() +set(EXE_NAME BuildRawEvents) +set(SRCS CbmDeviceBuildRawEvents.cxx runBuildRawEvents.cxx) + +set(DEPENDENCIES + ${DEPENDENCIES} + ${FAIR_LIBS} + ${BOOST_LIBS} + fles_ipc + KFParticle + CbmFlibMcbm2018 + CbmFlibFlesTools + CbmEventBuilder + KF + L1 + CbmBase + CbmData + CbmTofBase + CbmSimBase + Core + RIO + Net + Hist + RHTTP +) +#GENERATE_LIBRARY() +GENERATE_EXECUTABLE() + + set(EXE_NAME McbmEventBuilderWin) set(SRCS CbmDeviceMcbmEventBuilderWin.cxx runMcbmEvtBuilderWin.cxx) diff --git a/MQ/mcbm/CbmDeviceBuildRawEvents.cxx b/MQ/mcbm/CbmDeviceBuildRawEvents.cxx new file mode 100644 index 0000000000..60d075eb86 --- /dev/null +++ b/MQ/mcbm/CbmDeviceBuildRawEvents.cxx @@ -0,0 +1,552 @@ +/** + * CbmDeviceBuildRawEvents.cxx + * + * @since 2020-05-24 + * @author P.-A. Loizeau + */ + +#include "CbmDeviceBuildRawEvents.h" + +/// CBM headers +#include "CbmEvent.h" +#include "CbmFlesCanvasTools.h" +#include "CbmMQDefs.h" +#include "CbmMatch.h" +#include "CbmMvdDigi.h" + +#include "TimesliceMetaData.h" + +/// FAIRROOT headers +#include "FairMQLogger.h" +#include "FairMQProgOptions.h" // device->fConfig +#include "FairParGenericSet.h" +#include "FairRunOnline.h" + +#include "BoostSerializer.h" + +#include "RootSerializer.h" + +/// FAIRSOFT headers (geant, boost, ...) +#include "TCanvas.h" +#include "TFile.h" +#include "TH1.h" +#include "TList.h" +#include "TNamed.h" + +#include <boost/archive/binary_iarchive.hpp> +#include <boost/serialization/utility.hpp> + +/// C/C++ headers +#include <array> +#include <iomanip> +#include <stdexcept> +#include <string> +struct InitTaskError : std::runtime_error { + using std::runtime_error::runtime_error; +}; + +using namespace std; + +CbmDeviceBuildRawEvents::CbmDeviceBuildRawEvents() { fpAlgo = new CbmAlgoBuildRawEvents(); } + +void CbmDeviceBuildRawEvents::InitTask() +try { + /// Read options from executable + LOG(info) << "Init options for CbmDeviceBuildRawEvents."; + fbFillHistos = fConfig->GetValue<bool>("FillHistos"); + fbIgnoreTsOverlap = fConfig->GetValue<bool>("IgnOverMs"); + + fsEvtOverMode = fConfig->GetValue<std::string>("EvtOverMode"); + fsRefDet = fConfig->GetValue<std::string>("RefDet"); + fvsAddDet = fConfig->GetValue<std::vector<std::string>>("AddDet"); + fvsDelDet = fConfig->GetValue<std::vector<std::string>>("DelDet"); + fvsSetTrigWin = fConfig->GetValue<std::vector<std::string>>("SetTrigWin"); + fvsSetTrigMinNb = fConfig->GetValue<std::vector<std::string>>("SetTrigMinNb"); + + fsChannelNameDataInput = fConfig->GetValue<std::string>("TsNameIn"); + fsChannelNameDataOutput = fConfig->GetValue<std::string>("EvtNameOut"); + fsChannelNameHistosInput = fConfig->GetValue<std::string>("ChNameIn"); + fsChannelNameHistosConfig = fConfig->GetValue<std::string>("ChNameHistCfg"); + fsChannelNameCanvasConfig = fConfig->GetValue<std::string>("ChNameCanvCfg"); + fsAllowedChannels[0] = fsChannelNameDataInput; + + fuPublishFreqTs = fConfig->GetValue<uint32_t>("PubFreqTs"); + fdMinPublishTime = fConfig->GetValue<double_t>("PubTimeMin"); + fdMaxPublishTime = fConfig->GetValue<double_t>("PubTimeMax"); + + // 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, &CbmDeviceBuildRawEvents::HandleData); + } + } + + /// FIXME: Disable clang formatting for now as it corrupts all alignment + /* clang-format off */ + + /// Initialize the Algorithm parameters + fpAlgo->SetFillHistos(fbFillHistos); + fpAlgo->SetIgnoreTsOverlap(fbIgnoreTsOverlap); + /// Extract Event Overlap Mode + EOverlapModeRaw mode = + ("NoOverlap" == fsEvtOverMode ? EOverlapModeRaw::NoOverlap + : ("MergeOverlap" == fsEvtOverMode ? EOverlapModeRaw::MergeOverlap + : ("AllowOverlap" == fsEvtOverMode ? EOverlapModeRaw::AllowOverlap + : EOverlapModeRaw::NoOverlap))); + fpAlgo->SetEventOverlapMode(mode); + /// Extract refdet + RawEventBuilderDetector refDet = ("kT0" == fsRefDet ? kRawEventBuilderDetT0 + : ("kSts" == fsRefDet ? kRawEventBuilderDetMuch + : ("kMuch" == fsRefDet ? kRawEventBuilderDetTrd + : ("kTrd" == fsRefDet ? kRawEventBuilderDetTrd + : ("kTof" == fsRefDet ? kRawEventBuilderDetTof + : ("kRich" == fsRefDet ? kRawEventBuilderDetRich + : ("kPsd" == fsRefDet ? kRawEventBuilderDetPsd + : kRawEventBuilderDetUndef))))))); + if (kRawEventBuilderDetUndef != refDet) { + fpAlgo->SetReferenceDetector(refDet); + } + else { + LOG(info) << "CbmDeviceBuildRawEvents::InitTask => Trying to change " + "reference to unsupported detector, ignored! " + << fsRefDet; + } + + /// Extract detector to add if any + for (std::vector<std::string>::iterator itStrAdd = fvsAddDet.begin(); + itStrAdd != fvsAddDet.end(); + ++itStrAdd) { + RawEventBuilderDetector addDet = ("kT0" == *itStrAdd ? kRawEventBuilderDetT0 + : ("kSts" == *itStrAdd ? kRawEventBuilderDetSts + : ("kMuch" == *itStrAdd ? kRawEventBuilderDetMuch + : ("kTrd" == *itStrAdd ? kRawEventBuilderDetTrd + : ("kTof" == *itStrAdd ? kRawEventBuilderDetTof + : ("kRich" == *itStrAdd ? kRawEventBuilderDetRich + : ("kPsd" == *itStrAdd ? kRawEventBuilderDetPsd + : kRawEventBuilderDetUndef))))))); + if (kRawEventBuilderDetUndef != addDet) { + fpAlgo->AddDetector(addDet); + } + else { + LOG(info) << "CbmDeviceBuildRawEvents::InitTask => Trying to add " + "unsupported detector, ignored! " + << (*itStrAdd); + continue; + } + } + + /// Extract detector to remove if any + for (std::vector<std::string>::iterator itStrRem = fvsDelDet.begin(); + itStrRem != fvsDelDet.end(); + ++itStrRem) { + RawEventBuilderDetector remDet = ("kT0" == *itStrRem ? kRawEventBuilderDetT0 + : ("kSts" == *itStrRem ? kRawEventBuilderDetSts + : ("kMuch" == *itStrRem ? kRawEventBuilderDetMuch + : ("kTrd" == *itStrRem ? kRawEventBuilderDetTrd + : ("kTof" == *itStrRem ? kRawEventBuilderDetTof + : ("kRich" == *itStrRem ? kRawEventBuilderDetRich + : ("kPsd" == *itStrRem ? kRawEventBuilderDetPsd + : kRawEventBuilderDetUndef))))))); + if (kRawEventBuilderDetUndef != remDet) { + fpAlgo->RemoveDetector(remDet); + } + else { + LOG(info) << "CbmDeviceBuildRawEvents::InitTask => Trying to remove " + "unsupported detector, ignored! " + << (*itStrRem); + continue; + } + } + /// Extract Trigger window to add if any + for (std::vector<std::string>::iterator itStrTrigWin = fvsSetTrigWin.begin(); + itStrTrigWin != fvsSetTrigWin.end(); + ++itStrTrigWin) { + size_t charPosDel = (*itStrTrigWin).find(','); + if (std::string::npos == charPosDel) { + LOG(info) + << "CbmDeviceBuildRawEvents::InitTask => " + << "Trying to set trigger window with invalid option pattern, ignored! " + << " (Should be ECbmModuleId,dWinBeg,dWinEnd but instead found " + << (*itStrTrigWin) << " )"; + continue; + } + + /// Detector Enum Tag + std::string sSelDet = (*itStrTrigWin).substr(0, charPosDel); + ECbmModuleId selDet = ("kT0" == sSelDet ? ECbmModuleId::kT0 + : ("kSts" == sSelDet ? ECbmModuleId::kSts + : ("kMuch" == sSelDet ? ECbmModuleId::kMuch + : ("kTrd" == sSelDet ? ECbmModuleId::kTrd + : ("kTof" == sSelDet ? ECbmModuleId::kTof + : ("kRich" == sSelDet ? ECbmModuleId::kRich + : ("kPsd" == sSelDet ? ECbmModuleId::kPsd + : ECbmModuleId::kNotExist))))))); + if (ECbmModuleId::kNotExist == selDet) { + LOG(info) + << "CbmDeviceBuildRawEvents::InitTask => " + << "Trying to set trigger window for unsupported detector, ignored! " + << sSelDet; + continue; + } + + /// Window beginning + charPosDel++; + std::string sNext = (*itStrTrigWin).substr(charPosDel); + charPosDel = sNext.find(','); + if (std::string::npos == charPosDel) { + LOG(info) + << "CbmDeviceBuildRawEvents::InitTask => " + << "Trying to set trigger window with invalid option pattern, ignored! " + << " (Should be ECbmModuleId,dWinBeg,dWinEnd but instead found " + << (*itStrTrigWin) << " )"; + continue; + } + Double_t dWinBeg = std::stod(sNext.substr(0, charPosDel)); + + /// Window end + charPosDel++; + Double_t dWinEnd = std::stod(sNext.substr(charPosDel)); + + fpAlgo->SetTriggerWindow(selDet, dWinBeg, dWinEnd); + } + /// Extract MinNb for trigger if any + for (std::vector<std::string>::iterator itStrMinNb = fvsSetTrigMinNb.begin(); + itStrMinNb != fvsSetTrigMinNb.end(); + ++itStrMinNb) { + size_t charPosDel = (*itStrMinNb).find(','); + if (std::string::npos == charPosDel) { + LOG(info) + << "CbmDeviceBuildRawEvents::InitTask => " + << "Trying to set trigger min Nb with invalid option pattern, ignored! " + << " (Should be ECbmModuleId,uMinNb but instead found " << (*itStrMinNb) + << " )"; + continue; + } + + /// Detector Enum Tag + std::string sSelDet = (*itStrMinNb).substr(0, charPosDel); + ECbmModuleId selDet = ("kT0" == sSelDet ? ECbmModuleId::kT0 + : ("kSts" == sSelDet ? ECbmModuleId::kSts + : ("kMuch" == sSelDet ? ECbmModuleId::kMuch + : ("kTrd" == sSelDet ? ECbmModuleId::kTrd + : ("kTof" == sSelDet ? ECbmModuleId::kTof + : ("kRich" == sSelDet ? ECbmModuleId::kRich + : ("kPsd" == sSelDet ? ECbmModuleId::kPsd + : ECbmModuleId::kNotExist))))))); + if (ECbmModuleId::kNotExist == selDet) { + LOG(info) + << "CbmDeviceBuildRawEvents::InitTask => " + << "Trying to set trigger min Nb for unsupported detector, ignored! " + << sSelDet; + continue; + } + + /// Min number + charPosDel++; + UInt_t uMinNb = std::stoul((*itStrMinNb).substr(charPosDel)); + + fpAlgo->SetTriggerMinNumber(selDet, uMinNb); + } + + /// FIXME: Re-enable clang formatting after formatted lines + /* clang-format on */ + + /// Create input vectors + fvDigiT0 = new std::vector<CbmTofDigi>(); + fvDigiSts = new std::vector<CbmStsDigi>(); + fvDigiMuch = new std::vector<CbmMuchBeamTimeDigi>(); + fvDigiTrd = new std::vector<CbmTrdDigi>(); + fvDigiTof = new std::vector<CbmTofDigi>(); + fvDigiRich = new std::vector<CbmRichDigi>(); + fvDigiPsd = new std::vector<CbmPsdDigi>(); + + fTimeSliceMetaDataArray = new TClonesArray("TimesliceMetaData", 1); + if (NULL == fTimeSliceMetaDataArray) { throw InitTaskError("Failed creating the TS meta data TClonesarray "); } + fpAlgo->SetTimeSliceMetaDataArray(fTimeSliceMetaDataArray); + + /// Digis storage + fpAlgo->SetT0Digis(fvDigiT0); + fpAlgo->SetStsDigis(fvDigiSts); + fpAlgo->SetMuchBeamTimeDigis(fvDigiMuch); + fpAlgo->SetTrdDigis(fvDigiTrd); + fpAlgo->SetTofDigis(fvDigiTof); + fpAlgo->SetRichDigis(fvDigiRich); + fpAlgo->SetPsdDigis(fvDigiPsd); + + // Mvd currently not implemented in event builder + //std::vector<CbmMvdDigi>* pMvdDigi = new std::vector<CbmMvdDigi>(); + + /// Create output TClonesArray + fEvents = new TClonesArray("CbmEvent", 500); + + /// Now that everything is set, initialize the Algorithm + if (kFALSE == fpAlgo->InitAlgo()) { throw InitTaskError("Failed to initilize the algorithm class."); } + + /// Histograms management + if (kTRUE == fbFillHistos) { + /// Obtain vector of pointers on each histo from the algo (+ optionally desired folder) + std::vector<std::pair<TNamed*, std::string>> vHistos = fpAlgo->GetHistoVector(); + /// Obtain vector of pointers on each canvas from the algo (+ optionally desired folder) + std::vector<std::pair<TCanvas*, std::string>> vCanvases = fpAlgo->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) { throw InitTaskError("Problem sending histo config"); } + LOG(info) << "Config of hist " << psHistoConfig.first.data() << " in folder " << psHistoConfig.second.data(); + } + + /// 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) { throw InitTaskError("Problem sending canvas config"); } + + LOG(info) << "Config string of Canvas " << psCanvConfig.first.data() << " is " << psCanvConfig.second.data(); + } + } +} +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 CbmDeviceBuildRawEvents::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; + } + } + LOG(info) << "Channel name " << channelName << " not found in list of allowed channel names."; + LOG(error) << "Stop device."; + return false; +} + +// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0) +bool CbmDeviceBuildRawEvents::HandleData(FairMQParts& parts, int /*index*/) +{ + fulNumMessages++; + LOG(debug) << "Received message number " << fulNumMessages << " with " << parts.Size() << " parts" + << ", size0: " << parts.At(0)->GetSize(); + + if (0 == fulNumMessages % 10000) LOG(info) << "Received " << fulNumMessages << " messages"; + + /// Extract unpacked data from input message + uint32_t uPartIdx = 0; + + /// TS metadata + Deserialize<RootSerializer>(*parts.At(uPartIdx), fTsMetaData); + new ((*fTimeSliceMetaDataArray)[fTimeSliceMetaDataArray->GetEntriesFast()]) + TimesliceMetaData(std::move(*fTsMetaData)); + ++uPartIdx; + + /// T0 + std::string msgStrT0(static_cast<char*>(parts.At(uPartIdx)->GetData()), (parts.At(uPartIdx))->GetSize()); + std::istringstream issT0(msgStrT0); + boost::archive::binary_iarchive inputArchiveT0(issT0); + inputArchiveT0 >> *fvDigiT0; + ++uPartIdx; + + /// STS + std::string msgStrSts(static_cast<char*>(parts.At(uPartIdx)->GetData()), (parts.At(uPartIdx))->GetSize()); + std::istringstream issSts(msgStrSts); + boost::archive::binary_iarchive inputArchiveSts(issSts); + inputArchiveSts >> *fvDigiSts; + ++uPartIdx; + + /// MUCH + std::string msgStrMuch(static_cast<char*>(parts.At(uPartIdx)->GetData()), (parts.At(uPartIdx))->GetSize()); + std::istringstream issMuch(msgStrMuch); + boost::archive::binary_iarchive inputArchiveMuch(issMuch); + inputArchiveMuch >> *fvDigiMuch; + ++uPartIdx; + + /// TRD + std::string msgStrTrd(static_cast<char*>(parts.At(uPartIdx)->GetData()), (parts.At(uPartIdx))->GetSize()); + std::istringstream issTrd(msgStrTrd); + boost::archive::binary_iarchive inputArchiveTrd(issTrd); + inputArchiveTrd >> *fvDigiTrd; + ++uPartIdx; + + /// T0F + std::string msgStrTof(static_cast<char*>(parts.At(uPartIdx)->GetData()), (parts.At(uPartIdx))->GetSize()); + std::istringstream issTof(msgStrTof); + boost::archive::binary_iarchive inputArchiveTof(issTof); + inputArchiveTof >> *fvDigiTof; + ++uPartIdx; + + /// RICH + std::string msgStrRich(static_cast<char*>(parts.At(uPartIdx)->GetData()), (parts.At(uPartIdx))->GetSize()); + std::istringstream issRich(msgStrRich); + boost::archive::binary_iarchive inputArchiveRich(issRich); + inputArchiveRich >> *fvDigiRich; + ++uPartIdx; + + /// PSD + std::string msgStrPsd(static_cast<char*>(parts.At(uPartIdx)->GetData()), (parts.At(uPartIdx))->GetSize()); + std::istringstream issPsd(msgStrPsd); + boost::archive::binary_iarchive inputArchivePsd(issPsd); + inputArchivePsd >> *fvDigiPsd; + ++uPartIdx; + + /// Call Algo ProcessTs method + fpAlgo->ProcessTs(); + + /// Send events vector to ouput + if (!SendEvents(parts)) return false; + + /// Clear metadata + fTimeSliceMetaDataArray->Clear(); + + /// Clear vectors + fvDigiT0->clear(); + fvDigiSts->clear(); + fvDigiMuch->clear(); + fvDigiTrd->clear(); + fvDigiTof->clear(); + fvDigiRich->clear(); + fvDigiPsd->clear(); + + /// Clear event vector after usage + fpAlgo->ClearEventVector(); + fEvents->Clear("C"); + + /// Histograms management + if (kTRUE == fbFillHistos) { + /// 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(); + } + } + + return true; +} + +bool CbmDeviceBuildRawEvents::SendEvents(FairMQParts& partsIn) +{ + /// Clear events TClonesArray before usage. + fEvents->Delete(); + + /// Get vector reference from algo + std::vector<CbmEvent*> vEvents = fpAlgo->GetEventVector(); + + /// Move CbmEvent from temporary vector to TClonesArray + for (CbmEvent* event : vEvents) { + LOG(debug) << "Vector: " << event->ToString(); + new ((*fEvents)[fEvents->GetEntriesFast()]) CbmEvent(std::move(*event)); + LOG(debug) << "TClonesArray: " << static_cast<CbmEvent*>(fEvents->At(fEvents->GetEntriesFast() - 1))->ToString(); + } + + /// Serialize the array of events into a single MQ message + FairMQMessagePtr message(NewMessage()); + Serialize<RootSerializer>(*message, fEvents); + + /// Add it at the end of the input composed message + FairMQParts partsOut(std::move(partsIn)); + partsOut.AddPart(std::move(message)); + + if (Send(partsOut, fsChannelNameDataOutput) < 0) { + LOG(error) << "Problem sending data to " << fsChannelNameDataOutput; + return false; + } + + return true; +} + +bool CbmDeviceBuildRawEvents::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; + } + + /// Reset the histograms after sending them (but do not reset the time) + fpAlgo->ResetHistograms(kFALSE); + + return true; +} + +CbmDeviceBuildRawEvents::~CbmDeviceBuildRawEvents() +{ + /// Clear metadata + fTimeSliceMetaDataArray->Clear(); + delete fTsMetaData; + + /// Clear vectors + fvDigiT0->clear(); + fvDigiSts->clear(); + fvDigiMuch->clear(); + fvDigiTrd->clear(); + fvDigiTof->clear(); + fvDigiRich->clear(); + fvDigiPsd->clear(); + + /// Clear events TClonesArray + fEvents->Delete(); + + delete fpRun; + delete fTimeSliceMetaDataArray; + delete fEvents; + delete fpAlgo; +} + +void CbmDeviceBuildRawEvents::Finish() {} diff --git a/MQ/mcbm/CbmDeviceBuildRawEvents.h b/MQ/mcbm/CbmDeviceBuildRawEvents.h new file mode 100644 index 0000000000..b1f1b2fb97 --- /dev/null +++ b/MQ/mcbm/CbmDeviceBuildRawEvents.h @@ -0,0 +1,135 @@ +/** + * CbmDeviceBuildRawEvents.h + * + * @since 2020-05-24 + * @author P.-A. Loizeau + */ + +#ifndef CBMDEVICEBUILDRAWEVENTS_H_ +#define CBMDEVICEBUILDRAWEVENTS_H_ + +/// CBM headers +#include "CbmAlgoBuildRawEvents.h" +#include "CbmMuchBeamTimeDigi.h" +#include "CbmPsdDigi.h" +#include "CbmRichDigi.h" +#include "CbmStsDigi.h" +#include "CbmTofDigi.h" +#include "CbmTrdDigi.h" + +/// FAIRROOT headers +#include "FairMQDevice.h" + +/// FAIRSOFT headers (geant, boost, ...) +#include "Rtypes.h" +#include "TMessage.h" +#include "TObjArray.h" + +/// C/C++ headers +#include <chrono> +#include <map> +#include <vector> + +class TList; +class TClonesArray; +class FairRunOnline; +class TimesliceMetaData; + +class CbmDeviceBuildRawEvents : public FairMQDevice { +public: + CbmDeviceBuildRawEvents(); + virtual ~CbmDeviceBuildRawEvents(); + +protected: + virtual void InitTask(); + bool HandleData(FairMQParts&, int); + bool HandleCommand(FairMQMessagePtr&, int); + +private: + /// Constants + + /// Control flags + Bool_t fbIgnoreTsOverlap = kFALSE; //! Ignore data in Overlap part of the TS + Bool_t fbFillHistos = kTRUE; //! Switch ON/OFF filling of histograms + + /// User settings parameters + /// Algo enum settings + std::string fsEvtOverMode = "NoOverlap"; + std::string fsRefDet = "kT0"; + std::vector<std::string> fvsAddDet = {}; + std::vector<std::string> fvsDelDet = {}; + std::vector<std::string> fvsSetTrigWin = {}; + std::vector<std::string> fvsSetTrigMinNb = {}; + /// message queues + std::string fsChannelNameDataInput = "unpts_0"; + std::string fsChannelNameDataOutput = "events"; + std::string fsChannelNameCommands = "commands"; + std::string fsChannelNameHistosInput = "histogram-in"; + std::string fsChannelNameHistosConfig = "histo-conf"; + std::string fsChannelNameCanvasConfig = "canvas-conf"; + /// Histograms management + uint32_t fuPublishFreqTs = 100; + double_t fdMinPublishTime = 0.5; + double_t fdMaxPublishTime = 5.0; + + /// List of MQ channels names + std::vector<std::string> fsAllowedChannels = {fsChannelNameDataInput}; + + /// Statistics & first TS rejection + uint64_t fulNumMessages = 0; + uint64_t fulTsCounter = 0; + std::chrono::system_clock::time_point fLastPublishTime = std::chrono::system_clock::now(); + + /// Processing algos + CbmAlgoBuildRawEvents* fpAlgo = nullptr; + + /// TS MetaData stable values storage + size_t fuNbCoreMsPerTs = 0; //! + size_t fuNbOverMsPerTs = 0; //! + Double_t fdMsSizeInNs = 1280000; //! Size of a single MS, [nanoseconds] + Double_t fdTsCoreSizeInNs = -1.0; //! Total size of the core MS in a TS, [nanoseconds] + Double_t fdTsOverSizeInNs = -1.0; //! Total size of the overlap MS in a TS, [nanoseconds] + Double_t fdTsFullSizeInNs = -1.0; //! Total size of all MS in a TS, [nanoseconds] + + /// Data reception + /// TS MetaData storage + TClonesArray* fTimeSliceMetaDataArray = nullptr; //! + TimesliceMetaData* fTsMetaData = nullptr; + /// Digis storage + std::vector<CbmTofDigi>* fvDigiT0 = nullptr; + std::vector<CbmStsDigi>* fvDigiSts = nullptr; + std::vector<CbmMuchBeamTimeDigi>* fvDigiMuch = nullptr; + std::vector<CbmTrdDigi>* fvDigiTrd = nullptr; + std::vector<CbmTofDigi>* fvDigiTof = nullptr; + std::vector<CbmRichDigi>* fvDigiRich = nullptr; + std::vector<CbmPsdDigi>* fvDigiPsd = nullptr; + /// Data emission + TClonesArray* fEvents = nullptr; //! output container of CbmEvents + // std::vector< CbmEvent * > & fEventVector; //! vector with all created events + + /// Internal data registration (for FairRootManager -> DigiManager links) + FairRunOnline* fpRun = nullptr; + + /// 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); + void Finish(); + bool SendEvents(FairMQParts& partsIn); + 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 /* CBMDEVICEBUILDRAWEVENTS_H_ */ diff --git a/MQ/mcbm/runBuildRawEvents.cxx b/MQ/mcbm/runBuildRawEvents.cxx new file mode 100644 index 0000000000..f0487f28dd --- /dev/null +++ b/MQ/mcbm/runBuildRawEvents.cxx @@ -0,0 +1,48 @@ +#include "CbmDeviceBuildRawEvents.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()("FillHistos", bpo::value<bool>()->default_value(true), + "Fill histograms and send them to histo server if true"); + options.add_options()("IgnTsOver", bpo::value<bool>()->default_value(false), "Ignore TS overlap if true"); + options.add_options()("EvtOverMode", bpo::value<std::string>()->default_value("NoOverlap"), + "Set the event overlap mode, use string matching an EOverlapMode "); + options.add_options()("RefDet", bpo::value<std::string>()->default_value("kT0"), + "Set the reference (seed) detector, use string matching an ECbmModuleId "); + options.add_options()("AddDet", bpo::value<std::vector<std::string>>()->multitoken()->composing(), + "Add a detector for digis selection, use string matching an ECbmModuleId "); + options.add_options()("DelDet", bpo::value<std::vector<std::string>>()->multitoken()->composing(), + "Remove a detector for digis selection, use string matching an " + "ECbmModuleId "); + options.add_options()("SetTrigWin", bpo::value<std::vector<std::string>>()->multitoken()->composing(), + "Set trigger window for selected detector, use string matching " + "ECbmModuleId,dWinBeg,dWinEnd e.g. kSts,-10.5,100.0"); + options.add_options()("SetTrigMinNb", bpo::value<std::vector<std::string>>()->multitoken()->composing(), + "Set minimum number of digis for selected detector, use string matching " + "ECbmModuleId,uMinNb e.g. kTof,10"); + options.add_options()("TsNameIn", bpo::value<std::string>()->default_value("unpts_0"), + "MQ channel name for unpacked TS data"); + options.add_options()("EvtNameOut", bpo::value<std::string>()->default_value("events"), + "MQ channel name for built events"); + 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"); + 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"); +} + +FairMQDevicePtr getDevice(const FairMQProgOptions& /*config*/) { return new CbmDeviceBuildRawEvents(); } diff --git a/MQ/mcbm/startMQBuildRawEvents.sh.in b/MQ/mcbm/startMQBuildRawEvents.sh.in new file mode 100755 index 0000000000..0b94c5b453 --- /dev/null +++ b/MQ/mcbm/startMQBuildRawEvents.sh.in @@ -0,0 +1,264 @@ +#!/bin/bash +$SIMPATH/bin/fairmq-shmmonitor --cleanup + +if [ $# -ge 1 ]; then + _nbmoni=$1 + ((_pubfreqts = $_nbmoni*100 )) + _pubminsec=1.0 + _pubmaxsec=10.0 + + if [ $# -ge 4 ]; then + _filename="" + _dirname="" + _hostname=$4 + + if [ $# -ge 5 ]; then + _pubfreqts=$5 + + if [ $# -ge 6 ]; then + _pubminsec=$6 + + if [ $# -ge 7 ]; then + _pubmaxsec=$7 + fi + fi + fi + 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 'startMQMcbmPulserMonitor2020.sh' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> <full filename pattern list>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> <filename pattern> <folder_path>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> "" "" <hostname(s) list>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> "" "" <hostname(s) list> <Hist publish freq. in TS>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> "" "" <hostname(s) list> <Hist publish freq. in TS> <Min Hist pub. in s>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> "" "" <hostname(s) list> <Hist publish freq. in TS> <Min Hist pub. in s> <Max Hist pub. in s>' + _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 'startMQMcbmPulserMonitor2020.sh' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> <full filename pattern list>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> <filename pattern> <folder_path>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> "" "" <hostname(s) list>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> "" "" <hostname(s) list> <Hist publish freq. in TS>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> "" "" <hostname(s) list> <Hist publish freq. in TS> <Min Hist pub. in s>' + echo 'startMQMcbmPulserMonitor2020.sh <Nb Unp & Moni processes> "" "" <hostname(s) list> <Hist publish freq. in TS> <Min Hist pub. in s> <Max Hist pub. in s>' + _filename="" + _dirname="" + _hostname="localhost" + _nbmoni=1 + _pubfreqts=100 + _pubminsec=1.0 + _pubmaxsec=10.0 +fi + +_parfileSts=$VMCWORKDIR/macro/beamtime/mcbm2020/mStsPar.par +_parfileMuch=$VMCWORKDIR/macro/beamtime/mcbm2020/mMuchPar.par +_parfileTrdAsic=$VMCWORKDIR/parameters/trd/trd_v18q_mcbm.asic.par +_parfileTrdDigi=$VMCWORKDIR/parameters/trd/trd_v18q_mcbm.digi.par +_parfileTrdGas=$VMCWORKDIR/parameters/trd/trd_v18q_mcbm.gas.par +_parfileTrdGain=$VMCWORKDIR/parameters/trd/trd_v18q_mcbm.gain.par +_parfileTof=$VMCWORKDIR/macro/beamtime/mcbm2020/mTofPar.par +_parfileRich=$VMCWORKDIR/macro/beamtime/mcbm2020/mRichPar.par +_parfilePsd=$VMCWORKDIR/macro/beamtime/mcbm2020/mPsdPar.par + +LOGFILETAG=`hostname` +LOGFILETAG+="_" +LOGFILETAG+=`date +%Y_%m_%d_%H_%M_%S` +LOGFILETAG+=".log" + +(( _paraBuffSz=100 )) +(( _singBuffSz=_paraBuffSz*_nbmoni )) + +echo "Buffer size for parallel devices $_paraBuffSz" +echo "Buffer size for singleton devices $_singBuffSz" + +SAMPLER="MultiTsaSampler" +SAMPLER+=" --id sampler1" +#SAMPLER+=" --max-timeslices 0" +#SAMPLER+=" --max-timeslices 10" +#SAMPLER+=" --max-timeslices 100" +SAMPLER+=" --max-timeslices 300" +#SAMPLER+=" --max-timeslices 1000" +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+=" --no-split-ts 1" +SAMPLER+=" --ChNameMissTs missedts" +SAMPLER+=" --ChNameCmds commands" +SAMPLER+=" --channel-config name=fullts,type=push,method=bind,address=tcp://127.0.0.1:11555" +#SAMPLER+=" --channel-config name=fullts,type=push,method=bind,address=tcp://127.0.0.1:11555,sndBufSize=$_singBuffSz,rcvBuffSize=$_paraBuffSz" +#SAMPLER+=" --transport shmem" +SAMPLER+=" --transport zeromq" +#SAMPLER+=" --transport nanomsg" +SAMPLER+=" --channel-config name=missedts,type=pub,method=bind,address=tcp://127.0.0.1:11006" +SAMPLER+=" --channel-config name=commands,type=pub,method=bind,address=tcp://127.0.0.1:11007" +# Replaces log filename Xterm.log.hostname.yyyy.mm.dd.hh.mm.ss.XXXXXX +# with ProcessName_hostname_yyyy_mm_dd_hh_mm_ss.log +SAMPLER_LOG="sampler1_$LOGFILETAG" +xterm -l -lf $SAMPLER_LOG -geometry 80x23+0+0 -hold -e @CMAKE_BINARY_DIR@/bin/MQ/source/$SAMPLER & + +echo $SAMPLER + +_iMoni=0 +while (( _iMoni < _nbmoni )); do + (( _yOffset=200*_iMoni )) + (( _iMoni += 1 )) + (( _iPort = 11680 + _iMoni )) + + UNPACKER="McbmUnpack" + UNPACKER+=" --id unp$_iMoni" + UNPACKER+=" --severity info" + UNPACKER+=" --IgnOverMs 1" + UNPACKER+=" --SetTimeOffs kSTS,-985" + UNPACKER+=" --SetTimeOffs kMUCH,-885" + UNPACKER+=" --SetTimeOffs kTRD,-25" + UNPACKER+=" --SetTimeOffs kTOF,25" + UNPACKER+=" --SetTimeOffs kRICH,-310" + UNPACKER+=" --SetTimeOffs kPSD,-240" + UNPACKER+=" --TsNameOut unpts$_iMoni" + UNPACKER+=" --channel-config name=fullts,type=pull,method=connect,address=tcp://127.0.0.1:11555" + #UNPACKER+=" --transport shmem" + UNPACKER+=" --transport zeromq" + #UNPACKER+=" --transport nanomsg" +# UNPACKER+=" --channel-config name=parameters,type=req,method=connect,transport=zeromq,address=tcp://127.0.0.1:11005" + UNPACKER+=" --channel-config name=parameters,type=req,method=connect,transport=zeromq,address=tcp://127.0.0.1:11005,rateLogging=0" + UNPACKER+=" --channel-config name=unpts$_iMoni,type=push,method=bind,transport=zeromq,address=tcp://127.0.0.1:$_iPort" +# UNPACKER+=" --channel-config name=unpts$_iMoni,type=push,method=bind,transport=zeromq,address=tcp://127.0.0.1:$_iPort,sndBufSize=$_paraBuffSz,rcvBuffSize=$_paraBuffSz" +# UNPACKER+=" --channel-config name=commands,type=sub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11007" + #UNPACKER+=" --channel-config name=histogram-in,type=pub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11666" + #UNPACKER+=" --channel-config name=histo-conf,type=pub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11667,rateLogging=0" + #UNPACKER+=" --channel-config name=canvas-conf,type=pub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11668,rateLogging=0" + # Replaces log filename Xterm.log.hostname.yyyy.mm.dd.hh.mm.ss.XXXXXX + # with ProcessName_hostname_yyyy_mm_dd_hh_mm_ss.log + UNPACKER_LOG="unp$_iMoni" + UNPACKER_LOG+="_$LOGFILETAG" + VALGRIND_UNP="valgrind -v --error-limit=no --suppressions=$ROOTSYS/share/root/etc/valgrind-root.supp --leak-check=full --show-reachable=yes --log-file=valgrind_unp_log.txt" + VALGHEAP_UNP="valgrind -v --tool=massif --massif-out-file=valgrind_unp_massif.out" + xterm -l -lf $UNPACKER_LOG -geometry 80x23+400+$_yOffset -hold -e @CMAKE_BINARY_DIR@/bin/MQ/mcbm/$UNPACKER & +# xterm -l -lf $UNPACKER_LOG -geometry 80x23+400+$_yOffset -hold -e $VALGRIND_UNP @CMAKE_BINARY_DIR@/bin/MQ/mcbm/$UNPACKER & +# xterm -l -lf $UNPACKER_LOG -geometry 80x23+400+$_yOffset -hold -e $VALGHEAP_UNP @CMAKE_BINARY_DIR@/bin/MQ/mcbm/$UNPACKER & + + EVTBUILDER="BuildRawEvents" + EVTBUILDER+=" --id build$_iMoni" + EVTBUILDER+=" --severity info" + EVTBUILDER+=" --PubFreqTs $_pubfreqts" + EVTBUILDER+=" --PubTimeMin $_pubminsec" + EVTBUILDER+=" --PubTimeMax $_pubmaxsec" + EVTBUILDER+=" --FillHistos true" + EVTBUILDER+=" --IgnTsOver false" + EVTBUILDER+=" --EvtOverMode NoOverlap" + EVTBUILDER+=" --SetTrigWin kT0,-1,10" # To get T0 Digis (seed + close-by digis) in the event + EVTBUILDER+=" --SetTrigWin kSts,-50,100" + EVTBUILDER+=" --SetTrigWin kMuch,-150,50" + EVTBUILDER+=" --SetTrigWin kTrd,-250,100" + EVTBUILDER+=" --SetTrigWin kTof,-150,10" + EVTBUILDER+=" --SetTrigWin kRich,-150,20" + EVTBUILDER+=" --SetTrigWin kPsd,-50,10" + EVTBUILDER+=" --SetTrigMinNb kT0,1" + EVTBUILDER+=" --SetTrigMinNb kSts,0" + EVTBUILDER+=" --SetTrigMinNb kMuch,0" + EVTBUILDER+=" --SetTrigMinNb kTrd,0" + EVTBUILDER+=" --SetTrigMinNb kTof,10" + EVTBUILDER+=" --SetTrigMinNb kRich,0" + EVTBUILDER+=" --SetTrigMinNb kPsd,0" + EVTBUILDER+=" --TsNameIn unpts$_iMoni" + EVTBUILDER+=" --EvtNameOut events" + EVTBUILDER+=" --channel-config name=unpts$_iMoni,type=pull,method=connect,transport=zeromq,address=tcp://127.0.0.1:$_iPort" + #EVTBUILDER+=" --transport shmem" + EVTBUILDER+=" --transport zeromq" + #EVTBUILDER+=" --transport nanomsg" + EVTBUILDER+=" --channel-config name=events,type=push,method=connect,transport=zeromq,address=tcp://127.0.0.1:11556" +# EVTBUILDER+=" --channel-config name=commands,type=sub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11007" + EVTBUILDER+=" --channel-config name=parameters,type=req,method=connect,transport=zeromq,address=tcp://127.0.0.1:11005,rateLogging=0" + EVTBUILDER+=" --channel-config name=histogram-in,type=pub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11666" + EVTBUILDER+=" --channel-config name=histo-conf,type=pub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11667,rateLogging=0" + EVTBUILDER+=" --channel-config name=canvas-conf,type=pub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11668,rateLogging=0" + # Replaces log filename Xterm.log.hostname.yyyy.mm.dd.hh.mm.ss.XXXXXX + # with ProcessName_hostname_yyyy_mm_dd_hh_mm_ss.log + EVTBUILDER_LOG="build$_iMoni" + EVTBUILDER_LOG+="_$LOGFILETAG" + VALGRIND_EVT="valgrind -v --error-limit=no --suppressions=$ROOTSYS/share/root/etc/valgrind-root.supp --leak-check=full --show-reachable=yes --log-file=valgrind_evt_log.txt" + VALGHEAP_EVT="valgrind --tool=massif --massif-out-file=valgrind_evt_massif.out" + xterm -l -lf $EVTBUILDER_LOG -geometry 80x23+800+$_yOffset -hold -e @CMAKE_BINARY_DIR@/bin/MQ/mcbm/$EVTBUILDER & +# xterm -l -lf $EVTBUILDER_LOG -geometry 80x23+800+$_yOffset -hold -e $VALGRIND_EVT @CMAKE_BINARY_DIR@/bin/MQ/mcbm/$EVTBUILDER & +# xterm -l -lf $EVTBUILDER_LOG -geometry 80x23+800+$_yOffset -hold -e $VALGHEAP_EVT @CMAKE_BINARY_DIR@/bin/MQ/mcbm/$EVTBUILDER & + +done + +EVTSINK="McbmEventSink" +EVTSINK+=" --id evtsink1" +EVTSINK+=" --severity info" +EVTSINK+=" --OutFileName mcbm_digis_events.root" +EVTSINK+=" --FillHistos false" +EVTSINK+=" --PubFreqTs $_pubfreqts" +EVTSINK+=" --PubTimeMin $_pubminsec" +EVTSINK+=" --PubTimeMax $_pubmaxsec" +EVTSINK+=" --EvtNameIn events" +EVTSINK+=" --channel-config name=events,type=pull,method=bind,transport=zeromq,address=tcp://127.0.0.1:11556" +#EVTSINK+=" --channel-config name=events,type=pull,method=bind,transport=zeromq,address=tcp://127.0.0.1:11556,sndBufSize=$_paraBuffSz,rcvBuffSize=$_unpBufSz" +EVTSINK+=" --channel-config name=missedts,type=sub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11006" +EVTSINK+=" --channel-config name=commands,type=sub,method=connect,transport=zeromq,address=tcp://127.0.0.1:11007" +EVTSINK+=" --channel-config name=histogram-in,type=sub,method=bind,transport=zeromq,address=tcp://127.0.0.1:11666" +EVTSINK+=" --channel-config name=histo-conf,type=sub,method=bind,transport=zeromq,address=tcp://127.0.0.1:11667,rateLogging=0" +EVTSINK+=" --channel-config name=canvas-conf,type=sub,method=bind,transport=zeromq,address=tcp://127.0.0.1:11668,rateLogging=0" +# Replaces log filename Xterm.log.hostname.yyyy.mm.dd.hh.mm.ss.XXXXXX +# with ProcessName_hostname_yyyy_mm_dd_hh_mm_ss.log +EVTSINK_LOG="evtsink1_$LOGFILETAG" +VALGRIND_SINK="valgrind -v --error-limit=no --suppressions=$ROOTSYS/share/root/etc/valgrind-root.supp --leak-check=full --show-reachable=yes --log-file=valgrind_sink_log.txt" +VALGHEAP_SINK="valgrind -v --tool=massif --massif-out-file=valgrind_sink_massif.out" +VALGCPU_SINK="valgrind -v --tool=callgrind" +xterm -l -lf $EVTSINK_LOG -geometry 80x23+1200+0 -hold -e @CMAKE_BINARY_DIR@/bin/MQ/mcbm/$EVTSINK & +#xterm -l -lf $EVTSINK_LOG -geometry 80x23+1200+0 -hold -e $VALGRIND_SINK @CMAKE_BINARY_DIR@/bin/MQ/mcbm/$EVTSINK & +#xterm -l -lf $EVTSINK_LOG -geometry 80x23+1200+0 -hold -e $VALGHEAP_SINK @CMAKE_BINARY_DIR@/bin/MQ/mcbm/$EVTSINK & +#xterm -l -lf $EVTSINK_LOG -geometry 80x23+1200+0 -hold -e $VALGCPU_SINK @CMAKE_BINARY_DIR@/bin/MQ/mcbm/$EVTSINK & + +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" +PARAMETERSERVER+=" --channel-config name=parameters,type=rep,method=bind,transport=zeromq,address=tcp://127.0.0.1:11005,rateLogging=0" +PARAMETERSERVER+=" --first-input-name $_parfileSts;$_parfileMuch;$_parfileTrdAsic;$_parfileTrdDigi;$_parfileTrdGas;$_parfileTrdGain;$_parfileTof;$_parfileRich;$_parfilePsd" +PARAMETERSERVER+=" --first-input-type ASCII" +PARAMETERSERVER+=" --libs-to-load=libCbmFlibMcbm2018" # doesn't work due to runtime problem +# Replaces log filename Xterm.log.hostname.yyyy.mm.dd.hh.mm.ss.XXXXXX +# with ProcessName_hostname_yyyy_mm_dd_hh_mm_ss.log +PARAMSRV_LOG="parmq_$LOGFILETAG" +xterm -l -lf $PARAMSRV_LOG -geometry 80x23+1600+0 -hold -e @CMAKE_BINARY_DIR@/bin/MQ/parmq/$PARAMETERSERVER & + +HISTSERVER="MqHistoServer" +HISTSERVER+=" --id server1" +HISTSERVER+=" --severity info" +HISTSERVER+=" --histport 8081" +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,rateLogging=0" +HISTSERVER+=" --channel-config name=canvas-conf,type=sub,method=bind,transport=zeromq,address=tcp://127.0.0.1:11668,rateLogging=0" +# Replaces log filename Xterm.log.hostname.yyyy.mm.dd.hh.mm.ss.XXXXXX +# with ProcessName_hostname_yyyy_mm_dd_hh_mm_ss.log +HISTSRV_LOG="server1_$LOGFILETAG" +xterm -l -lf $HISTSRV_LOG -geometry 80x23+2000+0 -hold -e @CMAKE_BINARY_DIR@/bin/MQ/histogramServer/$HISTSERVER & -- GitLab