ndmspc 0.20250304.0
Loading...
Searching...
No Matches
ndmspc-cli.cxx
1#include <getopt.h>
2#include <cstddef>
3#include <cstdlib>
4#include <string>
5#include <CLI11.hpp>
6#include <vector>
7#include <TAxis.h>
8#include <TSystem.h>
9#include <TString.h>
10#include <TStopwatch.h>
11#include <TApplication.h>
12#include <TRandom3.h>
13#include <TH1F.h>
14#include <TH2F.h>
15#include <TCanvas.h>
16#include <TFrame.h>
17#include <TBenchmark.h>
18#include <TBufferJSON.h>
19
20#include "StressHistograms.h"
21#include "ndmspc.h"
22#include "Axis.h"
23#include "Results.h"
24#include "PointRun.h"
25#include "PointDraw.h"
26#include "HttpServer.h"
27#include "HnSparseBrowser.h"
28
29std::string app_description()
30{
31 size_t size = 64;
32 char buf[size];
33 size = std::snprintf(buf, size, "%s v%s-%s", NDMSPC_NAME, NDMSPC_VERSION, NDMSPC_VERSION_RELEASE);
34 return std::string(buf, size);
35}
36
37int main(int argc, char ** argv)
38{
39 CLI::App app{app_description()};
40 app.require_subcommand(); // 1 or more
41 argv = app.ensure_utf8(argv);
42 app.set_help_all_flag("--help-all", "Expand all help");
43
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 = "";
64
65 /*app.add_option("-c,--config", configFileName, "Config file name");*/
66
67 CLI::App * point = app.add_subcommand("point", "Point");
68 point->require_subcommand(); // 1 or more
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");
75
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");
80
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");
93
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)");
104
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");
114
115 CLI::App * serve = app.add_subcommand("serve", "Http Server");
116 serve->require_subcommand(); // 1 or more
117 CLI::App * serve_default = serve->add_subcommand("default", "Default http server");
118 if (serve_default == nullptr) {
119 Printf("Problem creating serve subcommand");
120 return 1;
121 }
122 CLI::App * serve_stress = serve->add_subcommand("stress", "Stress http server");
123 if (serve_stress == nullptr) {
124 Printf("Problem creating serve stress subcommand");
125 return 1;
126 }
127 int fill = 1;
128 serve_stress->add_option("-f,--fill", fill, "N fill (default: 1)");
129 int timeout = 100;
130 serve_stress->add_option("-t,--timeout", timeout, "Publish timeout in miliseconds (default: 100)");
131 int reset = 100;
132 serve_stress->add_option("-r,--reset", reset, "Reset every n events (default: 100)");
133 int seed = 0;
134 serve_stress->add_option("-s,--seed", seed, "Random seed (default: 0)");
135 bool batch = false;
136 serve_stress->add_option("-b,--batch", batch, "Batch mode without graphics (default: false)");
137
138 CLI::App * browser = app.add_subcommand("browser", "Object browser");
139 browser->require_subcommand(); // 1 or more
140
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: '/')");
145
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");
151
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>)");
155
156 CLI11_PARSE(app, argc, argv);
157 if (getenv("NDMSPC_POINT_NAME")) {
158 if (name.empty()) name = getenv("NDMSPC_POINT_NAME");
159 }
160 if (getenv("NDMSPC_POINT_BASEDIR")) {
161 if (basedir.empty()) basedir = getenv("NDMSPC_POINT_BASEDIR");
162 }
163 if (getenv("NDMSPC_POINT_CONFIG")) {
164 if (configFileName.empty()) configFileName = getenv("NDMSPC_POINT_CONFIG");
165 }
166 if (getenv("NDMSPC_POINT_CONFIG_USER")) {
167 if (userConfigFileName.empty()) userConfigFileName = getenv("NDMSPC_POINT_CONFIG_USER");
168 }
169 if (getenv("NDMSPC_POINT_MACRO")) {
170 if (macroFileName.empty()) macroFileName = getenv("NDMSPC_POINT_MACRO");
171 }
172 if (getenv("NDMSPC_POINT_ENVIRONMENT")) {
173 if (environement.empty()) environement = getenv("NDMSPC_POINT_ENVIRONMENT");
174 }
175 if (getenv("NDMSPC_POINT_MERGE_CACHE_DIR")) {
176 cacheDir = getenv("NDMSPC_POINT_MERGE_CACHE_DIR");
177 }
178 if (getenv("NDMSPC_POINT_JOBS")) {
179 if (jobs.empty()) jobs = getenv("NDMSPC_POINT_JOBS");
180 if (jobs.empty()) jobs = "1:1:1";
181 }
182 if (getenv("NDMSPC_POINT_BINNING")) {
183 if (binning.empty()) binning = getenv("NDMSPC_POINT_BINNING");
184 }
185 if (getenv("NDMSPC_POINT_BINNINGS")) {
186 if (binnings.empty()) binnings = getenv("NDMSPC_POINT_BINNINGS");
187 }
188 if (getenv("NDMSPC_BROWSER_FILE")) {
189 if (fileName.empty()) fileName = getenv("NDMSPC_BROWSER_FILE");
190 }
191 if (getenv("NDMSPC_BROWSER_OBJECTS")) {
192 if (objectName.empty()) objectName = getenv("NDMSPC_BROWSER_OBJECTS");
193 }
194
195 if (getenv("NDMSPC_BROWSER_DIRECTORY_TOKEN")) {
196 if (directoryToken.empty()) directoryToken = getenv("NDMSPC_BROWSER_DIRECTORY_TOKEN");
197 }
198 if (getenv("NDMSPC_CUTS_BASE_AXIS")) {
199 if (cutBaseAxis.empty()) cutBaseAxis = getenv("NDMSPC_CUTS_BASE_AXIS");
200 }
201 if (getenv("NDMSPC_CUTS_RANGES")) {
202 if (cutRanges.empty()) cutRanges = getenv("NDMSPC_CUTS_RANGES");
203 }
204
205 if (!basedir.empty()) {
206 if (basedir[basedir.size() - 1] != '/') basedir += "/";
207 if (!name.empty()) {
208 if (configFileName.empty()) configFileName = basedir + name + ".json";
209 if (macroFileName.empty()) macroFileName = basedir + name + ".C";
210 }
211 else {
212 configFileName = basedir + configFileName;
213 macroFileName = basedir + macroFileName;
214 }
215 }
216
217 if (directoryToken.empty()) directoryToken = "/";
218
219 // if (environement.empty()) environement = "default";
220
221 // std::cout << "Working on --file from start: " << file << '\n';
222 // std::cout << "Working on --count from stop: " << s->count() << ", direct count: " << stop->count("--count") <<
223 // '\n'; std::cout << "Count of --random flag: " << app.count("--random") << '\n';
224 for (auto * subcom : app.get_subcommands()) {
225 // std::cout << "Subcommand: " << subcom->get_name() << std::endl;
226 if (!subcom->get_name().compare("point")) {
227
228 for (auto * subsubcom : subcom->get_subcommands()) {
229 if (!subsubcom->get_name().compare("gen")) {
230 Ndmspc::PointRun::Generate(name, fileName, objectName);
231 }
232 if (!subsubcom->get_name().compare("run")) {
233 TStopwatch timer;
234 timer.Start();
235 Ndmspc::PointRun pr(macroFileName);
236 if (!jobs.empty()) {
237 pr.GenerateJobs(jobs, configFileName, userConfigFileName, environement, userConfigRaw, jobdir, binnings);
238 return 0;
239 }
240 pr.Run(configFileName, userConfigFileName, environement, userConfigRaw, binning, false);
241 timer.Stop();
242 timer.Print();
243 }
244 if (!subsubcom->get_name().compare("merge")) {
245 TStopwatch timer;
246 timer.Start();
247 int mergeFrom = atoi(mergeFromStr.c_str());
248 int mergeTo = atoi(mergeToStr.c_str());
249 Ndmspc::PointRun::Merge(mergeFrom, mergeTo, configFileName, userConfigFileName, environement, userConfigRaw,
250 binning, cacheDir);
251 timer.Stop();
252 timer.Print();
253 }
254 if (!subsubcom->get_name().compare("draw")) {
256 int level = atoi(levelStr.c_str());
257 pd.DrawPoint(level, configFileName, userConfigFileName, environement, userConfigRaw, binning);
258 }
259 }
260 }
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);
266 }
267 if (!subsubcom->get_name().compare("result")) {
268 Ndmspc::Results result;
269 result.LoadConfig(configFileName, userConfigFileName, environement, userConfigRaw);
270 result.Draw();
271 }
272 }
273 }
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);
278 int port = 8080;
279 if (gSystem->Getenv("PORT")) {
280 port = atoi(gSystem->Getenv("PORT"));
281 }
282
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 !!!");
286 exit(1);
287 }
288 // press Ctrl-C to stop macro
289 while (!gSystem->ProcessEvents()) {
290 gSystem->Sleep(100);
291 }
292 app.Run();
293 }
294 if (!subsubcom->get_name().compare("stress")) {
295 TApplication app("myapp", &argc, argv);
296 int port = 8080;
297 if (gSystem->Getenv("PORT")) {
298 port = atoi(gSystem->Getenv("PORT"));
299 }
300
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();
304
305 // when read-only mode disabled one could execute object methods like TTree::Draw()
306 serv->SetReadOnly(kFALSE);
307
308 Ndmspc::StressHistograms sh(fill, reset, seed, batch);
309
310 // press Ctrl-C to stop macro
311 while (!gSystem->ProcessEvents()) {
312 if (!sh.HandleEvent(ws)) break;
313 gSystem->Sleep(timeout);
314 }
315 app.Run();
316 }
317 }
318 }
319 if (!subcom->get_name().compare("cuts")) {
320 TApplication app("myapp", &argc, argv);
321
322 std::vector<std::string> a = Ndmspc::Utils::Tokenize(cutBaseAxis, ',');
323 if (a.size() != 3) {
324 Printf("Error: Invalid base axis format: %s", cutBaseAxis.c_str());
325 return 1;
326 }
327 TAxis * a1 = new TAxis(atoi(a[0].c_str()), atof(a[1].c_str()), atof(a[2].c_str()));
328 a1->SetName("a1");
329
330 Ndmspc::Axis * axis1 = new Ndmspc::Axis(a1, 1, 0, 1, -1);
331 std::vector<std::string> rangesArray = Ndmspc::Utils::Tokenize(cutRanges, ',');
332 for (auto r : rangesArray) {
333 std::vector<std::string> range = Ndmspc::Utils::Tokenize(r, ':');
334 if (range.size() != 2) {
335 Printf("Error: Invalid range format: %s", r.c_str());
336 return 1;
337 }
338 axis1->AddRange(atoi(range[0].c_str()), atoi(range[1].c_str()));
339 }
340 if (!axis1->IsRangeValid()) {
341 return 1;
342 }
343
344 TAxis * varBinningAxis = new TAxis();
345 axis1->FillAxis(varBinningAxis);
346
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))
350 .Data(),
351 varBinningAxis->GetNbins(), varBinningAxis->GetXbins()->GetArray());
352
353 for (int i = 0; i < varBinningAxis->GetNbins(); i++) {
354 h->SetBinContent(i + 1, i + 1);
355 }
356 h->Draw();
357
358 // axis1->Validate();
359 // Ndmspc::Cuts cuts;
360 // TAxis * a1 = new TAxis(200, 0, 20);
361 // a1->SetName("a1");
362 // Ndmspc::Axis * axis1 = new Ndmspc::Axis(a1);
363 // axis1->AddChild(2, 0, 1, -1);
364 // axis1->AddChild(10, 0, 1, -1);
365 // axis1->AddChild(10, 2, 1, -1);
366 // axis1->AddChild(10, 9, 1, -1);
367 // axis1->Validate();
368 // cuts.AddAxis(axis1);
369 // TAxis * a2 = new TAxis(100, 0, 100);
370 // a2->SetName("a2");
371 // Ndmspc::Axis * axis2 = new Ndmspc::Axis(a2);
372 // axis2->AddChild(2, 0, 1, -1);
373 // axis2->AddChild(2, 1, 1, -1);
374 // axis2->AddChild(5, 3, 1, -1);
375 // axis2->AddChild(5, 12, 5);
376 // axis2->AddChild(7, 15, 3);
377 // axis2->Validate();
378 // cuts.AddAxis(axis2);
379 // cuts.Print("");
380
381 // cuts.Print("ranges");
382 app.Run();
383 }
384 };
385
386 // Printf("Using config file '%s' ...", filename.c_str());
387 return 0;
388}
Axis object.
Definition Axis.h:16
Axis * AddRange(int rebin, int nBins=-1)
Add range.
Definition Axis.cxx:84
void FillAxis(TAxis *axis)
Fill axis.
Definition Axis.cxx:160
bool IsRangeValid()
Checks if range is valid.
Definition Axis.cxx:119
HnSparseBrowser object.
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="/")
PointDraw object.
Definition PointDraw.h:21
int DrawPoint(int level, std::string config="myAnalysis.json", std::string userConfig="", std::string environment="", std::string userConfigRaw="", std::string binning="")
Definition PointDraw.cxx:37
PointRun object.
Definition PointRun.h:24
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")
Results object.
Definition Results.h:20
bool LoadConfig(std::string configfilename="config.json", std::string userconfig="", std::string environment="", std::string userConfigRaw="")
Definition Results.cxx:25
virtual void Draw(Option_t *option="")
Definition Results.cxx:266
static std::vector< std::string > Tokenize(std::string_view input, const char delim)
Definition Utils.cxx:256