mana: add a root-histogram plugin and improve ManaCountingSink

Currently only histograms the hit counts per input array element, not
the actual data.

The counting plugin now also tracks and prints 'eventArrayIndexHits'.
This commit is contained in:
Florian Lüke 2024-12-26 01:46:58 +01:00
parent edf0d291a9
commit 6f7102549e
6 changed files with 138 additions and 31 deletions

View file

@ -36,5 +36,5 @@ if (ROOT_FOUND)
message("-- Using ROOT installation from ${ROOT_USE_FILE}")
include(${ROOT_USE_FILE})
add_library(mana-plugin-root-histogram SHARED mana_plugin_root_histogram.cc)
target_link_libraries(mana-plugin-root-histogram PRIVATE mana ${ROOT_LIBRARIES})
target_link_libraries(mana-plugin-root-histogram PRIVATE mana mesytec-mnode rxi-logc ${ROOT_LIBRARIES})
endif()

View file

@ -274,14 +274,14 @@ inline void module_data_stage_process_system_event(ModuleDataStage &ctx, const u
struct ManaCountingSink: public ManaPlugin
{
std::vector<size_t> eventCounts;
std::vector<std::vector<size_t>> eventArrayHits;
std::vector<std::vector<std::vector<size_t>>> eventArrayIndexHits;
size_t totalBytes = 0;
size_t systemEventCount = 0;
size_t systemEventBytes = 0;
void reset()
{
eventCounts.clear();
eventArrayHits.clear();
eventArrayIndexHits.clear();
totalBytes = 0;
}
@ -295,31 +295,58 @@ struct ManaCountingSink: public ManaPlugin
auto jRun = nlohmann::json::parse(descriptor_json);
reset();
eventCounts.resize(jRun["events"].size());
eventArrayHits.resize(eventCounts.size());
// TODO: resize nested vectors
eventArrayIndexHits.resize(eventCounts.size());
}
MANA_DEFINE_PLUGIN_END_RUN(end_run) override
{
(void)context;
(void)descriptor_json;
auto jRun = nlohmann::json::parse(descriptor_json);
spdlog::info("ManaCountingSink: eventCounts=[{}], totalBytes={}, systemEvents={}, "
"systemEventBytes={}",
fmt::join(eventCounts, ", "), totalBytes, systemEventCount, systemEventBytes);
for (size_t ei = 0; ei < eventArrayIndexHits.size(); ++ei)
{
spdlog::info("event[{}]: {} hits", ei, eventCounts[ei]);
for (size_t ai = 0; ai < eventArrayIndexHits[ei].size(); ++ai)
{
auto name = jRun["events"][ei]["outputs"][ai]["name"];
auto arrayHits = eventArrayIndexHits[ei][ai];
auto sumHits = std::accumulate(std::begin(arrayHits), std::end(arrayHits),
static_cast<size_t>(0u));
spdlog::info(" {}[{}]: [{}], sum={}", name, arrayHits.size(),
fmt::join(arrayHits, ", "), sumHits);
}
}
}
MANA_DEFINE_PLUGIN_EVENT_DATA(process_event) override
{
(void)context;
eventCounts.resize(std::max(eventCounts.size(), static_cast<size_t>(eventIndex + 1)));
eventArrayHits.resize(eventCounts.size());
eventArrayHits[eventIndex].resize(std::max(eventArrayHits[eventIndex].size(), arrayCount));
eventArrayIndexHits.resize(eventCounts.size());
eventArrayIndexHits[eventIndex].resize(
std::max(eventArrayIndexHits[eventIndex].size(), arrayCount));
++eventCounts[eventIndex];
for (size_t ai = 0; ai < arrayCount; ++ai)
{
auto input = get_span<float>(arrays[ai]);
bool hit = std::any_of(std::begin(input), std::end(input),
[](float v) { return !std::isnan(v); });
if (hit)
++eventArrayHits[eventIndex][ai];
eventArrayIndexHits[eventIndex][ai].resize(input.size());
for (size_t i = 0; i < input.size(); ++i)
{
if (!std::isnan(input[i]))
{
++eventArrayIndexHits[eventIndex][ai][i];
}
}
}
this->totalBytes += totalBytes;
}

View file

@ -7,6 +7,7 @@
#include <mesytec-mvlc/util/data_filter.h>
#include <nlohmann/json.hpp>
#include "mana_api.h"
#include "mana_arena.h"
namespace mesytec::mnode::mana
{

View file

@ -9,6 +9,7 @@ struct Context
MANA_DEFINE_PLUGIN_INIT(init)
{
log_set_level(LOG_DEBUG);
struct Context *ctx = calloc(1, sizeof(*ctx));
log_debug("init: ctx=%p", ctx);
return ctx;

View file

@ -0,0 +1,97 @@
#include <TFile.h>
#include <TH1.h>
#include "internal/mana_lib.hpp"
extern "C"
{
#include "internal/rxi/log.h"
}
using namespace mesytec::mnode;
struct Context
{
std::unique_ptr<TFile> outputFile;
std::vector<std::vector<TH1 *>> histograms;
};
MANA_DEFINE_PLUGIN_INIT(init)
{
log_set_level(LOG_DEBUG);
static Context g_ctx;
log_debug("init: ctx=%p", &g_ctx);
return &g_ctx;
}
MANA_DEFINE_PLUGIN_SHUTDOWN(shutdown)
{
(void)context;
log_debug("shutdown");
}
MANA_DEFINE_PLUGIN_BEGIN_RUN(begin_run)
{
log_debug("begin_run: context=%p, descriptor_json=%s", context, descriptor_json);
auto jRun = nlohmann::json::parse(descriptor_json);
auto ctx = reinterpret_cast<Context *>(context);
ctx->histograms.clear();
ctx->outputFile = std::make_unique<TFile>("output.root", "RECREATE");
for (const auto &jEvent: jRun["events"])
{
std::vector<TH1 *> eventHistograms;
for (const auto &jOutput: jEvent["outputs"])
{
auto name = jOutput["name"].get<std::string>();
auto size = jOutput["size"].get<size_t>();
auto th1 = new TH1F(name.c_str(), name.c_str(), size, 0.0, size);
eventHistograms.emplace_back(std::move(th1));
}
ctx->histograms.emplace_back(std::move(eventHistograms));
}
}
MANA_DEFINE_PLUGIN_END_RUN(end_run)
{
log_debug("end: context=%p, descriptor_json=%s", context, descriptor_json);
auto ctx = reinterpret_cast<Context *>(context);
ctx->outputFile->Write();
*ctx = {};
}
MANA_DEFINE_PLUGIN_EVENT_DATA(process_event)
{
log_trace("event: ctx=%p, eventIndex=%d, arrayCount=%zu, totalBytes=%zu", context, eventIndex,
arrayCount, totalBytes);
auto ctx = reinterpret_cast<Context *>(context);
auto &eventHistograms = ctx->histograms.at(eventIndex);
for (size_t ai = 0; ai < arrayCount; ++ai)
{
auto &histogram = eventHistograms.at(ai);
auto input = mana::get_span<float>(arrays[ai]);
for (size_t i = 0; i < input.size(); ++i)
{
if (!std::isnan(input[i]))
{
histogram->Fill(i);
}
}
}
}
MANA_DEFINE_PLUGIN_SYSTEM_EVENT(process_system_event)
{
log_trace("system_event: ctx=%p, size=%zu", context, size);
}
extern "C" MANA_DEFINE_GET_PLUGIN(mana_get_plugin)
{
mana_plugin_t plugin;
plugin.init = init;
plugin.shutdown = shutdown;
plugin.begin_run = begin_run;
plugin.end_run = end_run;
plugin.process_event = process_event;
plugin.process_system_event = process_system_event;
return plugin;
}

View file

@ -160,7 +160,7 @@ int main(int argc, char *argv[])
const auto jModuleDataSources = nlohmann::json::parse(f.begin(), f.end());
argh::parser parser({"-h", "--help", "--plugin"});
parser.parse(argv);
parser.parse(argc, argv);
auto filename = parser[1];
@ -266,24 +266,5 @@ int main(int argc, char *argv[])
mana.sink->end_run(mana.sinkContext, mana.runDescriptor.dump().c_str());
mana.sink->shutdown(mana.sinkContext);
if (auto cp = dynamic_cast<mana::ManaCountingSink *>(manaPlugin.get()))
{
spdlog::info("ManaCountingSink: eventCounts=[{}], totalBytes={}, systemEvents={}, "
"systemEventBytes={}",
fmt::join(cp->eventCounts, ", "), cp->totalBytes, cp->systemEventCount,
cp->systemEventBytes);
for (size_t ei = 0; ei < cp->eventArrayHits.size(); ++ei)
{
spdlog::info("event[{}]: {} hits", ei, cp->eventCounts[ei]);
for (size_t ai = 0; ai < cp->eventArrayHits[ei].size(); ++ai)
{
auto name = mana.runDescriptor["events"][ei]["outputs"][ai]["name"];
spdlog::info(" {}: {}", name, cp->eventArrayHits[ei][ai]);
}
}
}
return 0;
}