ndmspc  0.20250128.0
ndmspc-cli.cxx
1 #include <getopt.h>
2 #include <cstdlib>
3 #include <nlohmann/detail/value_t.hpp>
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 "Results.h"
23 #include "PointRun.h"
24 #include "PointDraw.h"
25 #include "HttpServer.h"
26 #include "HnSparseBrowser.h"
27 #include "Cuts.h"
28 
29 std::string app_description()
30 {
31  size_t size = 64;
32  char buf[size];
33  size =
34  std::snprintf(buf, size, "%s v%d.%d.%d-%s", NDMSPC_NAME, NDMSPC_VERSION_MAJOR(NDMSPC_VERSION),
35  NDMSPC_VERSION_MINOR(NDMSPC_VERSION), NDMSPC_VERSION_PATCH(NDMSPC_VERSION), NDMSPC_VERSION_RELEASE);
36  return std::string(buf, size);
37 }
38 
39 int main(int argc, char ** argv)
40 {
41  CLI::App app{app_description()};
42  app.require_subcommand(); // 1 or more
43  argv = app.ensure_utf8(argv);
44  app.set_help_all_flag("--help-all", "Expand all help");
45 
46  std::string name = "";
47  std::string basedir = "";
48  std::string fileName = "";
49  std::string objectName = "";
50  std::string configFileName = "";
51  std::string userConfigFileName = "";
52  std::string userConfigRaw = "";
53  std::string macroFileName = "";
54  std::string directoryToken = "";
55  std::string environement = "";
56  std::string cutBaseAxis = "";
57  std::string cutRanges = "";
58 
59  /*app.add_option("-c,--config", configFileName, "Config file name");*/
60 
61  CLI::App * point = app.add_subcommand("point", "Point");
62  point->require_subcommand(); // 1 or more
63  point->add_option("-c,--config", configFileName, "Config file name");
64  point->add_option("-u,--user-config", userConfigFileName, "User config file name");
65  point->add_option("-r,--user-config-raw", userConfigRaw, "User config raw");
66  point->add_option("-m,--macro", macroFileName, "Macro path");
67  point->add_option("-e,--environement", environement, "environement");
68 
69  CLI::App * point_gen = point->add_subcommand("gen", "Point generate");
70  point_gen->add_option("-n,--name", name, "Name");
71  point_gen->add_option("-f,--file", fileName, "Input file");
72  point_gen->add_option("-o,--object", objectName, "Input object");
73 
74  CLI::App * point_run = point->add_subcommand("run", "Point run");
75  point_run->add_option("-n,--name", name, "Name");
76  point_run->add_option("-d,--basedir", basedir, "Base dir");
77  point_run->add_option("-c,--config", configFileName, "Config file name");
78  point_run->add_option("-u,--user-config", userConfigFileName, "User config file name");
79  point_run->add_option("-r,--user-config-raw", userConfigRaw, "User config raw");
80  point_run->add_option("-m,--macro", macroFileName, "Macro path");
81  point_run->add_option("-e,--environement", environement, "environement");
82 
83  CLI::App * point_merge = point->add_subcommand("merge", "Point merge");
84  point_merge->add_option("-n,--name", name, "Name");
85  point_merge->add_option("-d,--basedir", basedir, "Base dir");
86  point_merge->add_option("-c,--config", configFileName, "Config file name");
87  point_merge->add_option("-u,--user-config", userConfigFileName, "User config file name");
88  point_merge->add_option("-r,--user-config-raw", userConfigRaw, "User config raw");
89  point_merge->add_option("-e,--environement", environement, "environement");
90 
91  CLI::App * point_draw = point->add_subcommand("draw", "Point draw");
92  point_draw->add_option("-n,--name", name, "Name");
93  point_draw->add_option("-d,--basedir", basedir, "Base dir");
94  point_draw->add_option("-c,--config", configFileName, "Config file name");
95  point_draw->add_option("-u,--user-config", userConfigFileName, "User config file name");
96  point_draw->add_option("-r,--user-config-raw", userConfigRaw, "User config raw");
97  point_draw->add_option("-e,--environement", environement, "environement");
98 
99  CLI::App * serve = app.add_subcommand("serve", "Http Server");
100  serve->require_subcommand(); // 1 or more
101  CLI::App * serve_default = serve->add_subcommand("default", "Default http server");
102  CLI::App * serve_stress = serve->add_subcommand("stress", "Stress http server");
103  int fill = 1;
104  serve_stress->add_option("-f,--fill", fill, "N fill (default: 1)");
105  int timeout = 100;
106  serve_stress->add_option("-t,--timeout", timeout, "Publish timeout in miliseconds (default: 100)");
107  int reset = 100;
108  serve_stress->add_option("-r,--reset", reset, "Reset every n events (default: 100)");
109  int seed = 0;
110  serve_stress->add_option("-s,--seed", seed, "Random seed (default: 0)");
111  bool batch = false;
112  serve_stress->add_option("-b,--batch", batch, "Batch mode without graphics (default: false)");
113 
114  CLI::App * browser = app.add_subcommand("browser", "Object browser");
115  browser->require_subcommand(); // 1 or more
116 
117  CLI::App * browser_hnsparse = browser->add_subcommand("hnsparse", "HnSparse browser");
118  browser_hnsparse->add_option("-f,--file", fileName, "Input file");
119  browser_hnsparse->add_option("-o,--objects", objectName, "Input objects");
120  browser_hnsparse->add_option("-t,--token", directoryToken, "Directory token (default: '/')");
121 
122  CLI::App * browser_result = browser->add_subcommand("result", "Ndmspc result browser");
123  browser_result->add_option("-c,--config", configFileName, "Config file name");
124  browser_result->add_option("-u,--user-config", userConfigFileName, "User config file name");
125  browser_result->add_option("-r,--user-config-raw", userConfigRaw, "User config raw");
126  browser_result->add_option("-e,--environement", environement, "environement");
127 
128  CLI::App * cuts = app.add_subcommand("cuts", "Cuts");
129  cuts->add_option("-b,--base", cutBaseAxis, "Base axis (<nBins>,<min>,<max>)");
130  cuts->add_option("-r,--ranges", cutBaseAxis, "Range (<rebin1>:<nbins1>,...,<rebinN>:<nbinsN>)");
131 
132  CLI11_PARSE(app, argc, argv);
133  if (getenv("NDMSPC_POINT_NAME")) {
134  if (name.empty()) name = getenv("NDMSPC_POINT_NAME");
135  }
136  if (getenv("NDMSPC_POINT_BASEDIR")) {
137  if (basedir.empty()) basedir = getenv("NDMSPC_POINT_BASEDIR");
138  }
139  if (getenv("NDMSPC_POINT_CONFIG")) {
140  if (configFileName.empty()) configFileName = getenv("NDMSPC_POINT_CONFIG");
141  }
142  if (getenv("NDMSPC_POINT_CONFIG_USER")) {
143  if (userConfigFileName.empty()) userConfigFileName = getenv("NDMSPC_POINT_CONFIG_USER");
144  }
145  if (getenv("NDMSPC_POINT_MACRO")) {
146  if (macroFileName.empty()) macroFileName = getenv("NDMSPC_POINT_MACRO");
147  }
148  if (getenv("NDMSPC_POINT_ENVIRONMENT")) {
149  if (environement.empty()) environement = getenv("NDMSPC_POINT_ENVIRONMENT");
150  }
151  if (getenv("NDMSPC_BROWSER_FILE")) {
152  if (fileName.empty()) fileName = getenv("NDMSPC_BROWSER_FILE");
153  }
154  if (getenv("NDMSPC_BROWSER_OBJECTS")) {
155  if (objectName.empty()) objectName = getenv("NDMSPC_BROWSER_OBJECTS");
156  }
157 
158  if (getenv("NDMSPC_BROWSER_DIRECTORY_TOKEN")) {
159  if (directoryToken.empty()) directoryToken = getenv("NDMSPC_BROWSER_DIRECTORY_TOKEN");
160  }
161  if (getenv("NDMSPC_CUTS_BASE_AXIS")) {
162  if (cutBaseAxis.empty()) cutBaseAxis = getenv("NDMSPC_CUTS_BASE_AXIS");
163  }
164  if (getenv("NDMSPC_CUTS_RANGES")) {
165  if (cutRanges.empty()) cutRanges = getenv("NDMSPC_CUTS_RANGES");
166  }
167 
168  if (!basedir.empty()) {
169  if (basedir[basedir.size() - 1] != '/') basedir += "/";
170  if (!name.empty()) {
171  if (configFileName.empty()) configFileName = basedir + name + ".json";
172  if (macroFileName.empty()) macroFileName = basedir + name + ".C";
173  }
174  else {
175  configFileName = basedir + configFileName;
176  macroFileName = basedir + macroFileName;
177  }
178  }
179 
180  if (directoryToken.empty()) directoryToken = "/";
181 
182  if (environement.empty()) environement = "default";
183 
184  // std::cout << "Working on --file from start: " << file << '\n';
185  // std::cout << "Working on --count from stop: " << s->count() << ", direct count: " << stop->count("--count") <<
186  // '\n'; std::cout << "Count of --random flag: " << app.count("--random") << '\n';
187  for (auto * subcom : app.get_subcommands()) {
188  // std::cout << "Subcommand: " << subcom->get_name() << std::endl;
189  if (!subcom->get_name().compare("point")) {
190 
191  for (auto * subsubcom : subcom->get_subcommands()) {
192  if (!subsubcom->get_name().compare("gen")) {
193  Ndmspc::PointRun::Generate(name, fileName, objectName);
194  }
195  if (!subsubcom->get_name().compare("run")) {
196  TStopwatch timer;
197  timer.Start();
198  Ndmspc::PointRun pr(macroFileName);
199  pr.Run(configFileName, userConfigFileName, environement, userConfigRaw, false);
200  timer.Stop();
201  timer.Print();
202  }
203  if (!subsubcom->get_name().compare("merge")) {
204  TStopwatch timer;
205  timer.Start();
206  Ndmspc::PointRun::Merge(configFileName, userConfigFileName, environement, userConfigRaw);
207  timer.Stop();
208  timer.Print();
209  }
210  if (!subsubcom->get_name().compare("draw")) {
212  pd.Draw(configFileName, userConfigFileName, environement, userConfigRaw);
213  }
214  }
215  }
216  if (!subcom->get_name().compare("browser")) {
217  for (auto * subsubcom : subcom->get_subcommands()) {
218  if (!subsubcom->get_name().compare("hnsparse")) {
219  Ndmspc::HnSparseBrowser browser;
220  browser.Draw(fileName, objectName, directoryToken);
221  }
222  if (!subsubcom->get_name().compare("result")) {
223  Ndmspc::Results result;
224  result.LoadConfig(configFileName, userConfigFileName, environement, userConfigRaw);
225  result.Draw();
226  }
227  }
228  }
229  if (!subcom->get_name().compare("serve")) {
230  for (auto * subsubcom : subcom->get_subcommands()) {
231  if (!subsubcom->get_name().compare("default")) {
232  TApplication app("myapp", &argc, argv);
233  int port = 8080;
234  if (gSystem->Getenv("PORT")) {
235  port = atoi(gSystem->Getenv("PORT"));
236  }
237 
238  Ndmspc::HttpServer * serv = new Ndmspc::HttpServer(TString::Format("http:%d?top=aaa", port).Data());
239  // press Ctrl-C to stop macro
240  while (!gSystem->ProcessEvents()) {
241  gSystem->Sleep(100);
242  }
243  app.Run();
244  }
245  if (!subsubcom->get_name().compare("stress")) {
246  TApplication app("myapp", &argc, argv);
247  int port = 8080;
248  if (gSystem->Getenv("PORT")) {
249  port = atoi(gSystem->Getenv("PORT"));
250  }
251 
252  Ndmspc::HttpServer * serv = new Ndmspc::HttpServer(TString::Format("http:%d?top=aaa", port).Data());
253  Printf("Starting server on port %d ...", port);
254  Ndmspc::WebSocketHandler * ws = serv->GetWebSocketHandler();
255 
256  // when read-only mode disabled one could execute object methods like TTree::Draw()
257  serv->SetReadOnly(kFALSE);
258 
259  Ndmspc::StressHistograms sh(fill, reset, seed, batch);
260 
261  // press Ctrl-C to stop macro
262  while (!gSystem->ProcessEvents()) {
263  if (!sh.HandleEvent(ws)) break;
264  gSystem->Sleep(timeout);
265  }
266  app.Run();
267  }
268  }
269  }
270  if (!subcom->get_name().compare("cuts")) {
271  TApplication app("myapp", &argc, argv);
272 
273  std::vector<std::string> a = Ndmspc::Utils::Tokenize(cutBaseAxis, ',');
274  if (a.size() != 3) {
275  Printf("Error: Invalid base axis format: %s", cutBaseAxis.c_str());
276  return 1;
277  }
278  TAxis * a1 = new TAxis(atoi(a[0].c_str()), atof(a[1].c_str()), atof(a[2].c_str()));
279  a1->SetName("a1");
280 
281  Ndmspc::Axis * axis1 = new Ndmspc::Axis(a1, 1, 0, 1, -1);
282  std::vector<std::string> rangesArray = Ndmspc::Utils::Tokenize(cutRanges, ',');
283  for (auto r : rangesArray) {
284  std::vector<std::string> range = Ndmspc::Utils::Tokenize(r, ':');
285  if (range.size() != 2) {
286  Printf("Error: Invalid range format: %s", r.c_str());
287  return 1;
288  }
289  axis1->AddRange(atoi(range[0].c_str()), atoi(range[1].c_str()));
290  }
291  if (!axis1->IsRangeValid()) {
292  return 1;
293  }
294 
295  TAxis * varBinningAxis = new TAxis();
296  axis1->FillAxis(varBinningAxis);
297 
298  TH1D * h = new TH1D("hAxis",
299  TString::Format("Base %s nbins=%d min=%.2f max=%.2f with=%.2f", a1->GetName(), a1->GetNbins(),
300  a1->GetXmin(), a1->GetXmax(), a1->GetBinWidth(1))
301  .Data(),
302  varBinningAxis->GetNbins(), varBinningAxis->GetXbins()->GetArray());
303 
304  for (int i = 0; i < varBinningAxis->GetNbins(); i++) {
305  h->SetBinContent(i + 1, i + 1);
306  }
307  h->Draw();
308 
309  // axis1->Validate();
310  // Ndmspc::Cuts cuts;
311  // TAxis * a1 = new TAxis(200, 0, 20);
312  // a1->SetName("a1");
313  // Ndmspc::Axis * axis1 = new Ndmspc::Axis(a1);
314  // axis1->AddChild(2, 0, 1, -1);
315  // axis1->AddChild(10, 0, 1, -1);
316  // axis1->AddChild(10, 2, 1, -1);
317  // axis1->AddChild(10, 9, 1, -1);
318  // axis1->Validate();
319  // cuts.AddAxis(axis1);
320  // TAxis * a2 = new TAxis(100, 0, 100);
321  // a2->SetName("a2");
322  // Ndmspc::Axis * axis2 = new Ndmspc::Axis(a2);
323  // axis2->AddChild(2, 0, 1, -1);
324  // axis2->AddChild(2, 1, 1, -1);
325  // axis2->AddChild(5, 3, 1, -1);
326  // axis2->AddChild(5, 12, 5);
327  // axis2->AddChild(7, 15, 3);
328  // axis2->Validate();
329  // cuts.AddAxis(axis2);
330  // cuts.Print("");
331 
332  // cuts.Print("ranges");
333  app.Run();
334  }
335  };
336 
337  // Printf("Using config file '%s' ...", filename.c_str());
338  return 0;
339 }
Axis object.
Definition: Axis.h:16
HnSparseBrowser object.
int Draw(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 Draw(std::string config="myAnalysis.json", std::string userConfig="", std::string environment="", std::string userConfigRaw="")
Definition: PointDraw.cxx:38
PointRun object.
Definition: PointRun.h:23
static bool Generate(std::string name="myAnalysis", std::string inFile="myFile.root", std::string inObjectName="myNDHistogram")
Definition: PointRun.cxx:1052
Results object.
Definition: Results.h:20
virtual void Draw(Option_t *option="")
Definition: Results.cxx:252