// $Id$ /************************************************************ * The Data Acquisition Backbone Core (DABC) * ************************************************************ * Copyright (C) 2009 - * * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * Planckstr. 1, 64291 Darmstadt, Germany * * Contact: http://dabc.gsi.de * ************************************************************ * This software can be used under the GPL license * * agreements as stated in LICENSE.txt file * * which is part of the distribution. * ************************************************************/ #include "stream/DabcProcMgr.h" #include "dabc/Buffer.h" #include "dabc/Iterator.h" #include "dabc/Factory.h" #include "dabc/Manager.h" #include "dabc/BinaryFile.h" #include "dabc/timing.h" #include #include stream::DabcProcMgr::DabcProcMgr() : base::ProcMgr(), fTop(), fWorkingFlag(true), fStore(), fStoreInfo("no store created"), fSortOrder(true), fDefaultFill(3) { } stream::DabcProcMgr::~DabcProcMgr() { } void stream::DabcProcMgr::SetTop(dabc::Hierarchy& top, bool withcmds) { fTop = top; if (!withcmds) return; dabc::Hierarchy h = fTop.CreateHChild("Control/Clear"); h.SetField("_kind","Command"); h.SetField("_title", "Clear all histograms in the server"); h.SetField("_icon", "dabc_plugins/stream/icons/clear.png"); h.SetField("_fastcmd", "true"); h.SetField("_numargs", "0"); h = fTop.CreateHChild("Control/Save"); h.SetField("_kind","Command"); h.SetField("_title", "Save all histograms in the dabc.root file"); h.SetField("_icon", "dabc_plugins/stream/icons/save.png"); h.SetField("_fastcmd", "true"); h.SetField("_numargs", "0"); h = fTop.CreateHChild("Control/Start"); h.SetField("_kind","Command"); h.SetField("_title", "Start processing of data"); h.SetField("_icon", "dabc_plugins/stream/icons/start.png"); h.SetField("_fastcmd", "true"); h.SetField("_numargs", "0"); h = fTop.CreateHChild("Control/Stop"); h.SetField("_kind","Command"); h.SetField("_title", "Stop processing of data"); h.SetField("_icon", "dabc_plugins/stream/icons/stop.png"); h.SetField("_fastcmd", "true"); h.SetField("_numargs", "0"); h = fTop.CreateHChild("Control/RunLog"); h.SetField(dabc::prop_kind, "log"); h.EnableHistory(1000); h = fTop.CreateHChild("Control/ErrLog"); h.SetField(dabc::prop_kind, "log"); h.EnableHistory(1000); } void stream::DabcProcMgr::AddRunLog(const char *msg) { dabc::Hierarchy h = fTop.GetHChild("Control/RunLog"); h.SetField("value", msg); h.MarkChangedItems(); } void stream::DabcProcMgr::AddErrLog(const char *msg) { dabc::Hierarchy h = fTop.GetHChild("Control/ErrLog"); h.SetField("value", msg); h.MarkChangedItems(); } void stream::DabcProcMgr::PrintLog(const char *msg) { if (fDebug >= 0) DOUT0("%s",msg); } base::H1handle stream::DabcProcMgr::MakeH1(const char *name, const char *title, int nbins, double left, double right, const char *options) { if (IsBlockHistCreation()) { DOUT0("Block H1 creation %s due to multithreading", name); return nullptr; } std::string xtitle, ytitle, xlbls, fillcolor, drawopt, hmin, hmax; bool reuse = false, clear_protect = false; while (options) { const char *separ = strchr(options,';'); std::string part = options; if (separ) { part.resize(separ-options); options = separ+1; } else { options = nullptr; } if (part.find("xbin:") == 0) { xlbls = part; xlbls.erase(0, 5); } else if (part.find("fill:") == 0) { fillcolor = part; fillcolor.erase(0,5); } else if (part.find("opt:") == 0) { drawopt = part; drawopt.erase(0,4); } else if (part.find("hmin:") == 0) { hmin = part; hmin.erase(0,5); } else if (part.find("hmax:") == 0) { hmax = part; hmax.erase(0,5); } else if (part.find("kind:") == 0) { } else if (part.find("reuse") == 0) { reuse = true; } else if (part.find("clear_protect") == 0) { clear_protect = true; } else if (xtitle.empty()) xtitle = part; else ytitle = part; } dabc::LockGuard lock(fTop.GetHMutex()); dabc::Hierarchy h = fTop.GetHChild(name); if (!h.null() && reuse && h.GetFieldPtr("bins")) return (base::H1handle) h.GetFieldPtr("bins")->GetDoubleArr(); if (!h) { std::string sname = name; auto pos = sname.find_last_of("/"); if ((pos != std::string::npos) && fSortOrder) h = fTop.CreateHChild(sname.substr(0,pos).c_str(), false, true).CreateHChild(sname.substr(pos+1).c_str()); else h = fTop.CreateHChild(name); } if (!h) return nullptr; h.SetField("_kind","ROOT.TH1D"); h.SetField("_title", title); h.SetField("_dabc_hist", true); // indicate for browser that it is DABC histogram h.SetField("_make_request", "DABC.ReqH"); // provide proper request h.SetField("_after_request", "DABC.ConvertH"); // convert object into ROOT histogram h.SetField("nbins", nbins); h.SetField("left", left); h.SetField("right", right); if (!xtitle.empty()) h.SetField("xtitle", xtitle); if (!ytitle.empty()) h.SetField("ytitle", ytitle); if (xlbls.length()>0) h.SetField("xlabels", xlbls); h.SetField("fillcolor", fillcolor.empty() ? fDefaultFill : std::stoi(fillcolor)); if (drawopt.length() > 0) h.SetField("drawopt", drawopt); if (!hmin.empty()) h.SetField("hmin", std::stof(hmin)); if (!hmax.empty()) h.SetField("hmax", std::stof(hmax)); if (clear_protect) h.SetField("_no_reset", "true"); std::vector bins; bins.resize(nbins+5, 0.); bins[0] = nbins; bins[1] = left; bins[2] = right; h.SetField("bins", bins); fTop.MarkChangedItems(); return (base::H1handle) h.GetFieldPtr("bins")->GetDoubleArr(); } base::H2handle stream::DabcProcMgr::MakeH2(const char *name, const char *title, int nbins1, double left1, double right1, int nbins2, double left2, double right2, const char *options) { if (IsBlockHistCreation()) { DOUT0("Block H2 creation %s due to multithreading", name); return nullptr; } std::string xtitle, ytitle, xlbls, ylbls, fillcolor, drawopt, hmin, hmax, h2poly; bool reuse = false, clear_protect = false; while (options != nullptr) { const char *separ = strchr(options,';'); std::string part = options; if (separ) { part.resize(separ-options); options = separ+1; } else { options = nullptr; } if (part.find("xbin:") == 0) { xlbls = part; xlbls.erase(0, 5); } else if (part.find("ybin:") == 0) { ylbls = part; ylbls.erase(0, 5); } else if (part.find("fill:") == 0) { fillcolor = part; fillcolor.erase(0,5); } else if (part.find("opt:") == 0) { drawopt = part; drawopt.erase(0,4); } else if (part.find("hmin:") == 0) { hmin = part; hmin.erase(0,5); } else if (part.find("hmax:") == 0) { hmax = part; hmax.erase(0,5); } else if (part.find("kind:") == 0) { } else if (part.find("h2poly:") == 0) { h2poly = part; h2poly.erase(0,7); } else if (part.find("reuse") == 0) { reuse = true; } else if (part.find("clear_protect") == 0) { clear_protect = true; } else if (xtitle.empty()) xtitle = part; else ytitle = part; } dabc::LockGuard lock(fTop.GetHMutex()); dabc::Hierarchy h = fTop.GetHChild(name); if (!h.null() && reuse && h.GetFieldPtr("bins")) return (base::H1handle) h.GetFieldPtr("bins")->GetDoubleArr(); if (!h) { std::string sname = name; auto pos = sname.find_last_of("/"); if ((pos != std::string::npos) && fSortOrder) h = fTop.CreateHChild(sname.substr(0,pos).c_str(), false, true).CreateHChild(sname.substr(pos+1).c_str()); else h = fTop.CreateHChild(name); } if (!h) return nullptr; h.SetField("_kind", h2poly.empty() ? "ROOT.TH2D" : "ROOT.TH2Poly"); h.SetField("_title", title); h.SetField("_dabc_hist", true); // indicate for browser that it is DABC histogram h.SetField("_make_request", "DABC.ReqH"); // provide proper request h.SetField("_after_request", "DABC.ConvertH"); // convert object into ROOT histogram h.SetField("nbins1", nbins1); h.SetField("left1", left1); h.SetField("right1", right1); h.SetField("nbins2", nbins2); h.SetField("left2", left2); h.SetField("right2", right2); if (!xtitle.empty()) h.SetField("xtitle", xtitle); if (!ytitle.empty()) h.SetField("ytitle", ytitle); if (xlbls.length() > 0) h.SetField("xlabels", xlbls); if (ylbls.length() > 0) h.SetField("ylabels", ylbls); if (!fillcolor.empty()) h.SetField("fillcolor", std::stoi(fillcolor)); h.SetField("drawopt", drawopt.empty() ? std::string("colz") : drawopt); if (!hmin.empty()) h.SetField("hmin", std::stof(hmin)); if (!hmax.empty()) h.SetField("hmax", std::stof(hmax)); if (!h2poly.empty()) h.SetField("h2poly", h2poly); if (clear_protect) h.SetField("_no_reset", "true"); std::vector bins; bins.resize(6+(nbins1+2)*(nbins2+2), 0.); bins[0] = nbins1; bins[1] = left1; bins[2] = right1; bins[3] = nbins2; bins[4] = left2; bins[5] = right2; h.SetField("bins", bins); fTop.MarkChangedItems(); return (base::H2handle) h.GetFieldPtr("bins")->GetDoubleArr(); } dabc::Hierarchy stream::DabcProcMgr::FindHistogram(void *handle) { if (IsBlockHistCreation()) { DOUT0("FindHistogram when blocked due to threaing?\n"); } if (!handle) return nullptr; dabc::Iterator iter(fTop); while (iter.next()) { dabc::Hierarchy item = iter.ref(); if (item.HasField("_dabc_hist")) if (item.GetFieldPtr("bins")->GetDoubleArr() == handle) return item; } return nullptr; } void stream::DabcProcMgr::SetH1Title(base::H1handle h1, const char *title) { auto item = FindHistogram(h1); if (!item.null()) item.SetField("_title", title); } void stream::DabcProcMgr::TagH1Time(base::H1handle h1) { auto item = FindHistogram(h1); if (!item.null()) { auto now = dabc::DateTime().GetNow(); item.SetField("_humantime", now.AsString(3, true)); item.SetField("_time", now.AsUTCSeconds()); } } void stream::DabcProcMgr::SetH2Title(base::H2handle h2, const char *title) { auto item = FindHistogram(h2); if (!item.null()) item.SetField("_title", title); } void stream::DabcProcMgr::TagH2Time(base::H2handle h2) { auto item = FindHistogram(h2); if (!item.null()) { auto now = dabc::DateTime().GetNow(); item.SetField("_humantime", now.AsString(3, true)); item.SetField("_time", now.AsUTCSeconds()); } } bool stream::DabcProcMgr::ClearHistogram(dabc::Hierarchy &item) { if (!item.HasField("_dabc_hist") || (item.GetFieldPtr("bins") == nullptr)) return false; if (item.HasField("_no_reset")) return true; int indx = item.GetField("_kind").AsStr()=="ROOT.TH1D" ? 3 : 6; double* arr = item.GetFieldPtr("bins")->GetDoubleArr(); int len = item.GetFieldPtr("bins")->GetArraySize(); while (indxGetDoubleArr(); if (!bins) return false; name.erase(0,5); // remove HCMD_ prefix if ((name == "GetMean") || (name=="GetRMS") || (name=="GetEntries")) { if (kind != "ROOT.TH1D") return false; int nbins = item.GetField("nbins").AsInt(); double left = item.GetField("left").AsDouble(); double right = item.GetField("right").AsDouble(); double sum0 = 0, sum1 = 0, sum2 = 0; for (int n=0;n0) { mean = sum1/sum0; rms = sqrt(sum2/sum0 - mean*mean); } if (name == "GetEntries") res = dabc::format("%14.7g",sum0); else if (name == "GetMean") res = dabc::format("%8.6g",mean); else res = dabc::format("%8.6g",rms); } else if (name=="Clear") { res = ClearHistogram(item) ? "true" : "false"; } else { return false; } } cmd.SetStrRawData(res); return true; } typedef void StreamCallFunc(void*); bool stream::DabcProcMgr::CallFunc(const char *funcname, void* arg) { if (!funcname) return false; void* symbol = dabc::Factory::FindSymbol(funcname); if (!symbol) return false; StreamCallFunc* func = (StreamCallFunc*) symbol; func(arg); return true; } bool stream::DabcProcMgr::CreateStore(const char *storename) { fStore = dabc::mgr.CreateObject("root::TreeStore","stream_store"); if (fStore.null()) { fStoreInfo = "Fail to create root::TreeStore, check libDabcRoot plugin"; return false; } dabc::Command cmd("Create"); cmd.SetStr("fname", storename); cmd.SetStr("ftitle", "File with stored stream data"); cmd.SetStr("tname", "T"); cmd.SetStr("ttitle", "Tree with stream data"); if (!fStore.Execute(cmd)) { fStoreInfo = dabc::format("Fail to create ROOT file %s", storename); return false; } // set pointer to inform base class that storage exists fTree = (TTree*) cmd.GetPtr("tree_ptr"); fStoreInfo = dabc::format("Create ROOT file %s", storename); return true; } bool stream::DabcProcMgr::CloseStore() { fTree = nullptr; fStore.Execute("Close"); fStore.Release(); fStoreInfo = "ROOT store closed"; return true; } bool stream::DabcProcMgr::CreateBranch(const char *name, const char *class_name, void** obj) { DOUT3("Create Branch1 %s", name); dabc::Command cmd("CreateBranch"); cmd.SetStr("name", name); cmd.SetStr("class_name", class_name); cmd.SetPtr("obj", (void*) obj); return fStore.Execute(cmd); } bool stream::DabcProcMgr::CreateBranch(const char *name, void* member, const char *kind) { DOUT3("Create Branch2 %s", name); dabc::Command cmd("CreateBranch"); cmd.SetStr("name", name); cmd.SetPtr("member", member); cmd.SetStr("kind", kind); return fStore.Execute(cmd); } bool stream::DabcProcMgr::StoreEvent() { if (fStore.null()) return false; dabc::Command cmd("Fill"); if (!fStore.Execute(cmd)) return false; fStoreInfo = cmd.GetStr("StoreInfo"); return true; }