9#include "FairMQProgOptions.h"
17#include "THttpServer.h"
21#include "TRootSniffer.h"
24#include "BoostSerializer.h"
25#include <boost/serialization/utility.hpp>
29#include "RootSerializer.h"
47 LOG(info) <<
"Init options for CbmMqHistoServer.";
63 fServer->GetSniffer()->SetScanGlobalDir(kFALSE);
64 const char* jsrootsys = gSystem->Getenv(
"JSROOTSYS");
65 if (!jsrootsys) jsrootsys = gEnv->GetValue(
"HttpServ.JSRootPath", jsrootsys);
67 LOG(info) <<
"JSROOT location: " << jsrootsys;
78 LOG(debug) <<
"CbmMqHistoServer::ReceiveData => Processing histograms update";
79 TObject* tempObject =
nullptr;
82 RootSerializer().Deserialize(*msg, tempObject);
84 if (TString(tempObject->ClassName()).EqualTo(
"TObjArray")) {
85 std::lock_guard<std::mutex> lk(
mtx);
86 TObjArray* arrayHisto =
static_cast<TObjArray*
>(tempObject);
87 for (Int_t i = 0; i < arrayHisto->GetEntriesFast(); i++) {
88 TObject* pObj = arrayHisto->At(i);
90 if (
nullptr !=
dynamic_cast<TProfile*
>(pObj)) {
93 else if (
nullptr !=
dynamic_cast<TH2*
>(pObj)) {
96 else if (
nullptr !=
dynamic_cast<TH1*
>(pObj)) {
100 LOG(warning) <<
"Unsupported object type for " << pObj->GetName();
103 LOG(debug) <<
"CbmMqHistoServer::ReceiveData => Deleting array";
105 arrayHisto->Delete();
110 LOG(debug) <<
"CbmMqHistoServer::ReceiveData => Checking for canvases updates";
121 LOG(fatal) <<
"CbmMqHistoServer::ReceiveData => Wrong object type at input: " << tempObject->ClassName();
125 if (
nullptr != tempObject)
delete tempObject;
129 if (bMqHistoServerResetHistos) {
130 std::lock_guard<std::mutex> lk(mtx);
131 // LOG(info) << "Reset Monitor histos ";
133 bMqHistoServerResetHistos = kFALSE;
134 } // if( bMqHistoServerResetHistos )
136 if (bMqHistoServerSaveHistos) {
137 std::lock_guard<std::mutex> lk(mtx);
138 // LOG(info) << "Save All histos & canvases";
140 bMqHistoServerSaveHistos = kFALSE;
141 } // if( bMqHistoServerSaveHistos )
143 LOG(debug) <<
"CbmMqHistoServer::ReceiveData => Finished processing histograms update";
150 std::pair<std::string, std::string> tempObject;
153 BoostSerializer<std::pair<std::string, std::string>>().Deserialize(*msg, tempObject);
156 LOG(info) <<
" Received configuration for histo " << tempObject.first <<
" : " << tempObject.second;
160 UInt_t uPrevHist = 0;
166 LOG(info) <<
" Ignored new configuration for histo " << tempObject.first
167 <<
" due to previously received one: " << tempObject.second;
172 fvHistos.push_back(std::pair<TNamed*, std::string>(
nullptr,
""));
182 std::pair<std::string, std::string> tempObject;
185 BoostSerializer<std::pair<std::string, std::string>>().Deserialize(*msg, tempObject);
187 LOG(info) <<
" Received configuration for canvas " << tempObject.first <<
" : " << tempObject.second;
191 uint32_t uPrevCanv = 0;
197 LOG(warning) <<
" Ignored new configuration for Canvas " << tempObject.first
198 <<
" due to previously received one: " << tempObject.second;
206 fvCanvas.push_back(std::pair<TCanvas*, std::string>(
nullptr,
""));
216 if (parts.Size() < 4) {
217 if (1 == parts.Size()) {
221 LOG(debug) <<
"CbmMqHistoServer::ReceiveConfigAndData => only 1 parts found in input, "
222 <<
"assuming data only message routed to wrong method!";
225 LOG(fatal) <<
"CbmMqHistoServer::ReceiveConfigAndData => Wrong number of parts: " << parts.Size()
226 <<
" instead of at least 4 (Header + Histo Config + Canvas config + Data)!";
229 LOG(info) <<
"CbmMqHistoServer::ReceiveConfigAndData => Received composed message with " << parts.Size() <<
" parts";
232 std::pair<uint32_t, uint32_t> pairHeader;
234 BoostSerializer<std::pair<uint32_t, uint32_t>>().Deserialize(*parts.At(0), pairHeader);
236 LOG(info) <<
"CbmMqHistoServer::ReceiveConfigAndData => Received configuration for " << pairHeader.first
237 <<
" histos and " << pairHeader.second <<
" canvases";
239 uint32_t uOffsetHistoConfig = pairHeader.first;
240 if (0 == pairHeader.first) {
241 uOffsetHistoConfig = 1;
242 if (0 < (parts.At(uOffsetHistoConfig))->GetSize()) {
243 LOG(fatal) <<
"CbmMqHistoServer::ReceiveConfigAndData => No histo config expected but corresponding message is"
244 <<
" not empty: " << (parts.At(uOffsetHistoConfig))->GetSize();
248 uint32_t uOffsetCanvasConfig = pairHeader.second;
249 if (0 == pairHeader.second) {
250 uOffsetCanvasConfig = 1;
251 if (0 < (parts.At(uOffsetHistoConfig + uOffsetCanvasConfig))->GetSize()) {
252 LOG(fatal) <<
"CbmMqHistoServer::ReceiveConfigAndData => No Canvas config expected but corresponding message is"
253 <<
" not empty: " << (parts.At(uOffsetHistoConfig + uOffsetCanvasConfig))->GetSize();
257 if (
static_cast<size_t>(parts.Size()) != 1 + uOffsetHistoConfig + uOffsetCanvasConfig + 1) {
258 LOG(fatal) <<
"CbmMqHistoServer::ReceiveConfigAndData => Number of parts not matching header: " << parts.Size()
259 <<
" instead of " << 1 + uOffsetHistoConfig + uOffsetCanvasConfig + 1;
263 for (uint32_t uHisto = 0; uHisto < pairHeader.first; ++uHisto) {
268 for (uint32_t uCanv = 0; uCanv < pairHeader.second; ++uCanv) {
273 ReceiveData(parts.At(1 + uOffsetHistoConfig + uOffsetCanvasConfig), 0);
275 LOG(info) <<
"CbmMqHistoServer::ReceiveConfigAndData => Finished processing composed message with " << parts.Size()
290 std::this_thread::sleep_for(std::chrono::milliseconds(10));
291 std::lock_guard<std::mutex> lk(
mtx);
305template<
class HistoT>
310 HistoT* histogram_new =
static_cast<HistoT*
>(pHist->Clone());
313 LOG(info) <<
"Received new histo " << pHist->GetName();
327 LOG(info) <<
"registered histo " <<
fvHistos[uHist].first->GetName() <<
" in folder "
346 HistoT* histogram_existing =
dynamic_cast<HistoT*
>(
fArrayHisto.At(index1));
347 if (
nullptr == histogram_existing) {
348 LOG(error) <<
"CbmMqHistoServer::ReadHistogram => "
349 <<
"Incompatible type found during update for histo " << pHist->GetName();
353 histogram_existing->Add(pHist);
360 for (
int iHist = 0; iHist <
fArrayHisto.GetEntriesFast(); ++iHist) {
362 if (TString(obj->GetName()).EqualTo(name)) {
return iHist; }
369 for (
int iHist = 0; iHist <
fArrayHisto.GetEntriesFast(); ++iHist) {
370 dynamic_cast<TH1*
>(
fArrayHisto.At(iHist))->Reset();
376 LOG(debug) <<
" Extracting configuration for canvas index " << uCanvIdx;
381 for (uint32_t uPadIdx = 0; uPadIdx < uNbPads; ++uPadIdx) {
383 for (uint32_t uObjIdx = 0; uObjIdx < uNbObj; ++uObjIdx) {
384 std::string sName(conf.
GetObjName(uPadIdx, uObjIdx));
386 if (
"nullptr" != sName) {
394 LOG(info) <<
" All histos found for canvas " << conf.
GetName().data() <<
", now preparing it";
397 TCanvas* pNewCanv =
new TCanvas(conf.
GetName().data(), conf.
GetTitle().data());
401 for (uint32_t uPadIdx = 0; uPadIdx < uNbPads; ++uPadIdx) {
402 pNewCanv->cd(1 + uPadIdx);
406 gPad->SetLogx(conf.
GetLogx(uPadIdx));
407 gPad->SetLogy(conf.
GetLogy(uPadIdx));
408 gPad->SetLogz(conf.
GetLogz(uPadIdx));
412 for (uint32_t uObjIdx = 0; uObjIdx < uNbObj; ++uObjIdx) {
413 std::string sName(conf.
GetObjName(uPadIdx, uObjIdx));
414 if (
"nullptr" != sName) {
417 if (
nullptr !=
dynamic_cast<TProfile*
>(pObj)) {
418 dynamic_cast<TProfile*
>(pObj)->Draw(conf.
GetOption(uPadIdx, uObjIdx).data());
420 else if (
nullptr !=
dynamic_cast<TH2*
>(pObj)) {
421 dynamic_cast<TH2*
>(pObj)->Draw(conf.
GetOption(uPadIdx, uObjIdx).data());
423 else if (
nullptr !=
dynamic_cast<TH1*
>(pObj)) {
424 dynamic_cast<TH1*
>(pObj)->Draw(conf.
GetOption(uPadIdx, uObjIdx).data());
427 LOG(warning) <<
" Unsupported object type for " << sName <<
" when preparing canvas " << conf.
GetName();
429 LOG(info) <<
" Configured histo " << sName <<
" on pad " << (1 + uPadIdx) <<
" for canvas "
435 fvCanvas[uCanvIdx] = std::pair<TCanvas*, std::string>(pNewCanv,
"canvases");
439 LOG(info) <<
" Registered canvas " <<
fvCanvas[uCanvIdx].first->GetName() <<
" in folder "
457 TFile* oldFile = gFile;
458 TDirectory* oldDir = gDirectory;
461 TFile* histoFile =
nullptr;
468 if (
nullptr == histoFile)
return false;
471 for (UInt_t uHisto = 0; uHisto <
fvHistos.size(); ++uHisto) {
473 TString sFolder =
fvHistos[uHisto].second.data();
474 if (
nullptr == gDirectory->Get(sFolder)) gDirectory->mkdir(sFolder);
475 gDirectory->cd(sFolder);
483 for (UInt_t uCanvas = 0; uCanvas <
fvCanvas.size(); ++uCanvas) {
485 TString sFolder =
fvCanvas[uCanvas].second.data();
486 if (
nullptr == gDirectory->Get(sFolder)) gDirectory->mkdir(sFolder);
487 gDirectory->cd(sFolder);
uint32_t GetNbPadsY() const
bool GetLogz(uint32_t uPadIdx) const
bool GetGridy(uint32_t uPadIdx) const
bool GetLogy(uint32_t uPadIdx) const
std::string GetOption(uint32_t uPadIdx, uint32_t uObjIdx) const
std::string GetTitle() const
std::string GetName() const
accessors
bool GetLogx(uint32_t uPadIdx) const
uint32_t GetNbObjsInPad(uint32_t uPadIdx) const
bool GetGridx(uint32_t uPadIdx) const
accessors
uint32_t GetNbPadsX() const
std::string GetObjName(uint32_t uPadIdx, uint32_t uObjIdx) const
uint32_t GetNbPads() const
virtual ~CbmMqHistoServer()
std::string fsChannelNameHistosInput
Parameters.
int fNMessages
Internal status.
bool PrepareCanvas(uint32_t uCanvIdx)
bool fbAllCanvasRegistered
std::vector< std::pair< std::string, std::string > > fvpsHistosFolder
Vector of string with ( HistoName, FolderPath ) to send to the histogram server.
std::string fsChannelNameHistosConfig
bool fbAllHistosRegistered
bool ReceiveData(FairMQMessagePtr &msg, int index)
std::vector< bool > fvbCanvasRegistered
Vector of Canvas pointers and folder path.
TObjArray fArrayHisto
Array of histograms with unique names.
int FindHistogram(const std::string &name)
uint32_t fuHttpServerPort
std::vector< bool > fvbCanvasReady
std::vector< std::pair< std::string, std::string > > fvpsCanvasConfig
bool ReceiveConfigAndData(FairMQParts &msg, int index)
bool ReceiveCanvasConfig(FairMQMessagePtr &msg, int index)
bool ReceiveHistoConfig(FairMQMessagePtr &msg, int index)
std::vector< bool > fvbHistoRegistered
Vector of Histos pointers and folder path.
std::string fsChannelNameCanvasConfig
bool ReadHistogram(HistoT *pHist)
std::vector< std::pair< TNamed *, std::string > > fvHistos
std::vector< std::pair< TCanvas *, std::string > > fvCanvas
std::string fsHistoFileName