10#include <TStopwatch.h>
11#include <TApplication.h>
17#include <TBenchmark.h>
18#include <TBufferJSON.h>
20#include "StressHistograms.h"
26#include "HttpServer.h"
27#include "HnSparseBrowser.h"
29std::string app_description()
33 size = std::snprintf(buf, size,
"%s v%s-%s", NDMSPC_NAME, NDMSPC_VERSION, NDMSPC_VERSION_RELEASE);
34 return std::string(buf, size);
37int main(
int argc,
char ** argv)
39 CLI::App app{app_description()};
40 app.require_subcommand();
41 argv = app.ensure_utf8(argv);
42 app.set_help_all_flag(
"--help-all",
"Expand all help");
44 std::string name =
"";
45 std::string basedir =
"";
46 std::string fileName =
"";
47 std::string objectName =
"";
48 std::string configFileName =
"";
49 std::string userConfigFileName =
"";
50 std::string userConfigRaw =
"";
51 std::string macroFileName =
"";
52 std::string directoryToken =
"";
53 std::string environement =
"";
54 std::string binnings =
"";
55 std::string jobs =
"";
56 std::string jobdir =
"/tmp/ndmspc-jobs";
57 std::string cutBaseAxis =
"";
58 std::string cutRanges =
"";
59 std::string mergeFromStr =
"0";
60 std::string mergeToStr =
"-1";
61 std::string levelStr =
"-1";
62 std::string cacheDir =
"${PWD}/.ndmspc_cache_dir";
63 std::string binning =
"";
67 CLI::App * point = app.add_subcommand(
"point",
"Point");
68 point->require_subcommand();
69 point->add_option(
"-c,--config", configFileName,
"Config file name");
70 point->add_option(
"-u,--user-config", userConfigFileName,
"User config file name");
71 point->add_option(
"-r,--user-config-raw", userConfigRaw,
"User config raw");
72 point->add_option(
"-m,--macro", macroFileName,
"Macro path");
73 point->add_option(
"-e,--environement", environement,
"Environement");
74 point->add_option(
"-b,--binning", binning,
"Binning");
76 CLI::App * point_gen = point->add_subcommand(
"gen",
"Point generate");
77 point_gen->add_option(
"-n,--name", name,
"Name");
78 point_gen->add_option(
"-f,--file", fileName,
"Input file");
79 point_gen->add_option(
"-o,--object", objectName,
"Input object");
81 CLI::App * point_run = point->add_subcommand(
"run",
"Point run");
82 point_run->add_option(
"-n,--name", name,
"Name");
83 point_run->add_option(
"-d,--basedir", basedir,
"Base dir");
84 point_run->add_option(
"-c,--config", configFileName,
"Config file name");
85 point_run->add_option(
"-u,--user-config", userConfigFileName,
"User config file name");
86 point_run->add_option(
"-r,--user-config-raw", userConfigRaw,
"User config raw");
87 point_run->add_option(
"-m,--macro", macroFileName,
"Macro path");
88 point_run->add_option(
"-e,--environement", environement,
"environement");
89 point_run->add_option(
"--binnings", binnings,
"Generate Binning jobs");
90 point_run->add_option(
"-b,--binning", binning,
"Binning");
91 point_run->add_option(
"-j,--jobs", jobs,
"Generate jobs");
92 point_run->add_option(
"-o,--output-dir", jobdir,
"Generate jobs output dir");
94 CLI::App * point_merge = point->add_subcommand(
"merge",
"Point merge");
95 point_merge->add_option(
"-n,--name", name,
"Name");
96 point_merge->add_option(
"-d,--basedir", basedir,
"Base dir");
97 point_merge->add_option(
"-c,--config", configFileName,
"Config file name");
98 point_merge->add_option(
"-u,--user-config", userConfigFileName,
"User config file name");
99 point_merge->add_option(
"-r,--user-config-raw", userConfigRaw,
"User config raw");
100 point_merge->add_option(
"-e,--environement", environement,
"Environement");
101 point_merge->add_option(
"-b,--binning", binning,
"Binning");
102 point_merge->add_option(
"-f,--from", mergeFromStr,
"Merge from (default: 0)");
103 point_merge->add_option(
"-t,--to", mergeToStr,
"Merge to (default: 1)");
105 CLI::App * point_draw = point->add_subcommand(
"draw",
"Point draw");
106 point_draw->add_option(
"-n,--name", name,
"Name");
107 point_draw->add_option(
"-d,--basedir", basedir,
"Base dir");
108 point_draw->add_option(
"-c,--config", configFileName,
"Config file name");
109 point_draw->add_option(
"-u,--user-config", userConfigFileName,
"User config file name");
110 point_draw->add_option(
"-r,--user-config-raw", userConfigRaw,
"User config raw");
111 point_draw->add_option(
"-e,--environement", environement,
"environement");
112 point_draw->add_option(
"-b,--binning", binning,
"Binning");
113 point_draw->add_option(
"-l,--level", levelStr,
"Level");
115 CLI::App * serve = app.add_subcommand(
"serve",
"Http Server");
116 serve->require_subcommand();
117 CLI::App * serve_default = serve->add_subcommand(
"default",
"Default http server");
118 if (serve_default ==
nullptr) {
119 Printf(
"Problem creating serve subcommand");
122 CLI::App * serve_stress = serve->add_subcommand(
"stress",
"Stress http server");
123 if (serve_stress ==
nullptr) {
124 Printf(
"Problem creating serve stress subcommand");
128 serve_stress->add_option(
"-f,--fill", fill,
"N fill (default: 1)");
130 serve_stress->add_option(
"-t,--timeout", timeout,
"Publish timeout in miliseconds (default: 100)");
132 serve_stress->add_option(
"-r,--reset", reset,
"Reset every n events (default: 100)");
134 serve_stress->add_option(
"-s,--seed", seed,
"Random seed (default: 0)");
136 serve_stress->add_option(
"-b,--batch", batch,
"Batch mode without graphics (default: false)");
138 CLI::App * browser = app.add_subcommand(
"browser",
"Object browser");
139 browser->require_subcommand();
141 CLI::App * browser_hnsparse = browser->add_subcommand(
"hnsparse",
"HnSparse browser");
142 browser_hnsparse->add_option(
"-f,--file", fileName,
"Input file");
143 browser_hnsparse->add_option(
"-o,--objects", objectName,
"Input objects");
144 browser_hnsparse->add_option(
"-t,--token", directoryToken,
"Directory token (default: '/')");
146 CLI::App * browser_result = browser->add_subcommand(
"result",
"Ndmspc result browser");
147 browser_result->add_option(
"-c,--config", configFileName,
"Config file name");
148 browser_result->add_option(
"-u,--user-config", userConfigFileName,
"User config file name");
149 browser_result->add_option(
"-r,--user-config-raw", userConfigRaw,
"User config raw");
150 browser_result->add_option(
"-e,--environement", environement,
"environement");
152 CLI::App * cuts = app.add_subcommand(
"cuts",
"Cuts");
153 cuts->add_option(
"-b,--base", cutBaseAxis,
"Base axis (<nBins>,<min>,<max>)");
154 cuts->add_option(
"-r,--ranges", cutBaseAxis,
"Range (<rebin1>:<nbins1>,...,<rebinN>:<nbinsN>)");
156 CLI11_PARSE(app, argc, argv);
157 if (getenv(
"NDMSPC_POINT_NAME")) {
158 if (name.empty()) name = getenv(
"NDMSPC_POINT_NAME");
160 if (getenv(
"NDMSPC_POINT_BASEDIR")) {
161 if (basedir.empty()) basedir = getenv(
"NDMSPC_POINT_BASEDIR");
163 if (getenv(
"NDMSPC_POINT_CONFIG")) {
164 if (configFileName.empty()) configFileName = getenv(
"NDMSPC_POINT_CONFIG");
166 if (getenv(
"NDMSPC_POINT_CONFIG_USER")) {
167 if (userConfigFileName.empty()) userConfigFileName = getenv(
"NDMSPC_POINT_CONFIG_USER");
169 if (getenv(
"NDMSPC_POINT_MACRO")) {
170 if (macroFileName.empty()) macroFileName = getenv(
"NDMSPC_POINT_MACRO");
172 if (getenv(
"NDMSPC_POINT_ENVIRONMENT")) {
173 if (environement.empty()) environement = getenv(
"NDMSPC_POINT_ENVIRONMENT");
175 if (getenv(
"NDMSPC_POINT_MERGE_CACHE_DIR")) {
176 cacheDir = getenv(
"NDMSPC_POINT_MERGE_CACHE_DIR");
178 if (getenv(
"NDMSPC_POINT_JOBS")) {
179 if (jobs.empty()) jobs = getenv(
"NDMSPC_POINT_JOBS");
180 if (jobs.empty()) jobs =
"1:1:1";
182 if (getenv(
"NDMSPC_POINT_BINNING")) {
183 if (binning.empty()) binning = getenv(
"NDMSPC_POINT_BINNING");
185 if (getenv(
"NDMSPC_POINT_BINNINGS")) {
186 if (binnings.empty()) binnings = getenv(
"NDMSPC_POINT_BINNINGS");
188 if (getenv(
"NDMSPC_BROWSER_FILE")) {
189 if (fileName.empty()) fileName = getenv(
"NDMSPC_BROWSER_FILE");
191 if (getenv(
"NDMSPC_BROWSER_OBJECTS")) {
192 if (objectName.empty()) objectName = getenv(
"NDMSPC_BROWSER_OBJECTS");
195 if (getenv(
"NDMSPC_BROWSER_DIRECTORY_TOKEN")) {
196 if (directoryToken.empty()) directoryToken = getenv(
"NDMSPC_BROWSER_DIRECTORY_TOKEN");
198 if (getenv(
"NDMSPC_CUTS_BASE_AXIS")) {
199 if (cutBaseAxis.empty()) cutBaseAxis = getenv(
"NDMSPC_CUTS_BASE_AXIS");
201 if (getenv(
"NDMSPC_CUTS_RANGES")) {
202 if (cutRanges.empty()) cutRanges = getenv(
"NDMSPC_CUTS_RANGES");
205 if (!basedir.empty()) {
206 if (basedir[basedir.size() - 1] !=
'/') basedir +=
"/";
208 if (configFileName.empty()) configFileName = basedir + name +
".json";
209 if (macroFileName.empty()) macroFileName = basedir + name +
".C";
212 configFileName = basedir + configFileName;
213 macroFileName = basedir + macroFileName;
217 if (directoryToken.empty()) directoryToken =
"/";
224 for (
auto * subcom : app.get_subcommands()) {
226 if (!subcom->get_name().compare(
"point")) {
228 for (
auto * subsubcom : subcom->get_subcommands()) {
229 if (!subsubcom->get_name().compare(
"gen")) {
232 if (!subsubcom->get_name().compare(
"run")) {
237 pr.GenerateJobs(jobs, configFileName, userConfigFileName, environement, userConfigRaw, jobdir, binnings);
240 pr.Run(configFileName, userConfigFileName, environement, userConfigRaw, binning,
false);
244 if (!subsubcom->get_name().compare(
"merge")) {
247 int mergeFrom = atoi(mergeFromStr.c_str());
248 int mergeTo = atoi(mergeToStr.c_str());
254 if (!subsubcom->get_name().compare(
"draw")) {
256 int level = atoi(levelStr.c_str());
257 pd.
DrawPoint(level, configFileName, userConfigFileName, environement, userConfigRaw, binning);
261 if (!subcom->get_name().compare(
"browser")) {
262 for (
auto * subsubcom : subcom->get_subcommands()) {
263 if (!subsubcom->get_name().compare(
"hnsparse")) {
265 browser.
DrawBrowser(fileName, objectName, directoryToken);
267 if (!subsubcom->get_name().compare(
"result")) {
269 result.
LoadConfig(configFileName, userConfigFileName, environement, userConfigRaw);
274 if (!subcom->get_name().compare(
"serve")) {
275 for (
auto * subsubcom : subcom->get_subcommands()) {
276 if (!subsubcom->get_name().compare(
"default")) {
277 TApplication app(
"myapp", &argc, argv);
279 if (gSystem->Getenv(
"PORT")) {
280 port = atoi(gSystem->Getenv(
"PORT"));
283 Ndmspc::HttpServer * serv =
new Ndmspc::HttpServer(TString::Format(
"http:%d?top=aaa", port).Data());
284 if (serv ==
nullptr) {
285 Printf(
"Server was not created !!!");
289 while (!gSystem->ProcessEvents()) {
294 if (!subsubcom->get_name().compare(
"stress")) {
295 TApplication app(
"myapp", &argc, argv);
297 if (gSystem->Getenv(
"PORT")) {
298 port = atoi(gSystem->Getenv(
"PORT"));
301 Ndmspc::HttpServer * serv =
new Ndmspc::HttpServer(TString::Format(
"http:%d?top=aaa", port).Data());
302 Printf(
"Starting server on port %d ...", port);
303 Ndmspc::WebSocketHandler * ws = serv->GetWebSocketHandler();
306 serv->SetReadOnly(kFALSE);
308 Ndmspc::StressHistograms sh(fill, reset, seed, batch);
311 while (!gSystem->ProcessEvents()) {
312 if (!sh.HandleEvent(ws))
break;
313 gSystem->Sleep(timeout);
319 if (!subcom->get_name().compare(
"cuts")) {
320 TApplication app(
"myapp", &argc, argv);
324 Printf(
"Error: Invalid base axis format: %s", cutBaseAxis.c_str());
327 TAxis * a1 =
new TAxis(atoi(a[0].c_str()), atof(a[1].c_str()), atof(a[2].c_str()));
332 for (
auto r : rangesArray) {
334 if (range.size() != 2) {
335 Printf(
"Error: Invalid range format: %s", r.c_str());
338 axis1->
AddRange(atoi(range[0].c_str()), atoi(range[1].c_str()));
344 TAxis * varBinningAxis =
new TAxis();
347 TH1D * h =
new TH1D(
"hAxis",
348 TString::Format(
"Base %s nbins=%d min=%.2f max=%.2f with=%.2f", a1->GetName(), a1->GetNbins(),
349 a1->GetXmin(), a1->GetXmax(), a1->GetBinWidth(1))
351 varBinningAxis->GetNbins(), varBinningAxis->GetXbins()->GetArray());
353 for (
int i = 0; i < varBinningAxis->GetNbins(); i++) {
354 h->SetBinContent(i + 1, i + 1);
Axis * AddRange(int rebin, int nBins=-1)
Add range.
void FillAxis(TAxis *axis)
Fill axis.
bool IsRangeValid()
Checks if range is valid.
virtual int DrawBrowser(std::string filename="root://eos.ndmspc.io//eos/ndmspc/scratch/alice/hyperloop/PWGLF-376/222580/AnalysisResults.root", std::string objects="phianalysis-t-hn-sparse_default/unlikepm,phianalysis-t-hn-sparse_default/likepp", std::string dirtoken="/")
int DrawPoint(int level, std::string config="myAnalysis.json", std::string userConfig="", std::string environment="", std::string userConfigRaw="", std::string binning="")
static bool Merge(int from=0, int to=1, std::string name="myAnalysis.json", std::string userConfig="", std::string environment="", std::string userConfigRaw="", std::string binning="", std::string cacheDir="${PWD}/.ndmspc_merge_cache", std::string fileOpt="?remote=1")
Merge.
static bool Generate(std::string name="myAnalysis", std::string inFile="myFile.root", std::string inObjectName="myNDHistogram")
bool LoadConfig(std::string configfilename="config.json", std::string userconfig="", std::string environment="", std::string userConfigRaw="")
virtual void Draw(Option_t *option="")
static std::vector< std::string > Tokenize(std::string_view input, const char delim)