7#include <TFileMerger.h>
23std::string PointRun::fgEnvironment =
"";
30 TH1::AddDirectory(kFALSE);
31 fMacro = Utils::OpenMacro(macro.c_str());
32 if (fMacro) fMacro->Load();
43 std::string userConfigRaw,
bool show, std::string outfilename)
49 if (!Core::LoadConfig(config, userConfig, environment, userConfigRaw))
return 1;
51 if (!gCfg[
"ndmspc"][
"verbose"].is_null() && gCfg[
"ndmspc"][
"verbose"].is_number_integer())
52 fVerbose = gCfg[
"ndmspc"][
"verbose"].get<
int>();
54 if (!gCfg[
"ndmspc"][
"file"][
"cache"].is_null() && gCfg[
"ndmspc"][
"file"][
"cache"].is_string()) {
55 std::string cacheDir = gCfg[
"ndmspc"][
"file"][
"cache"].get<std::string>();
56 if (!cacheDir.empty()) {
57 Printf(
"Setting cache directory to '%s' ...", gSystem->ExpandPathName(cacheDir.c_str()));
58 TFile::SetCacheFileDir(gSystem->ExpandPathName(cacheDir.c_str()), 1, 1);
62 if (show) Printf(
"%s", gCfg.dump(2).c_str());
64 if (!outfilename.empty()) {
65 std::ofstream file(outfilename.c_str());
67 Printf(
"Config saved to file '%s' ...", outfilename.c_str());
79 if (
fVerbose >= 2) Printf(
"Ndmspc::PointRun::Init ...");
80 if (!gCfg[
"ndmspc"][
"process"][
"type"].get<std::string>().compare(
"all") &&
81 gCfg[
"ndmspc"][
"process"][
"ranges"].is_null() &&
82 !gCfg[
"ndmspc"][
"output"][
"delete"].get<std::string>().compare(
"onInit")) {
84 if (gCfg[
"ndmspc"][
"output"][
"host"].get<std::string>().empty()) {
85 gCfg[
"ndmspc"][
"output"][
"opt"] =
"";
88 std::string outFileName;
89 if (!gCfg[
"ndmspc"][
"output"][
"dir"].get<std::string>().empty()) {
92 outFileName += gCfg[
"ndmspc"][
"output"][
"dir"].get<std::string>();
95 std::string environment = gCfg[
"ndmspc"][
"environment"].get<std::string>();
96 outFileName += environment +
"/";
98 outFileName += Utils::GetCutsPath(gCfg[
"ndmspc"][
"cuts"]);
118 outFileName +=
"bins";
120 if (!extraPath.empty()) {
121 outFileName +=
"/" + extraPath;
122 outFileName.pop_back();
126 if (!outFileName.empty()) {
127 if (gCfg[
"ndmspc"][
"output"][
"host"].is_string() &&
128 !gCfg[
"ndmspc"][
"output"][
"host"].get<std::string>().empty()) {
130 Printf(
"Deleting output eos directory '%s' ...", outFileName.c_str());
132 TString::Format(
"%s/proc/user/?mgm.cmd=rm&mgm.path=%s&mgm.option=rf&mgm.format=json&filetype=raw",
133 gCfg[
"ndmspc"][
"output"][
"host"].get<std::string>().c_str(), outFileName.c_str())
136 if (
fVerbose >= 2) Printf(
"rmUrl '%s' ...", rmUrl.c_str());
139 Printf(
"Directory '%s' deleted", outFileName.c_str());
143 Printf(
"Directory '%s' deleted", outFileName.c_str());
144 gSystem->Exec(TString::Format(
"rm -rf %s", outFileName.c_str()));
149 if (
fVerbose >= 2) Printf(
"Ndmspc::PointRun::Init done ...");
160 if (
fVerbose >= 2) Printf(
"[<-] Ndmspc::PointRun::OpenInputs");
162 if (
fInputFile && fInputList)
return fInputList;
164 if (gCfg[
"ndmspc"][
"data"][
"file"].get<std::string>().empty()) {
165 Printf(
"Error: Input file is empty !!! Aborting ...");
168 if (
fVerbose >= 0) Printf(
"Opening file '%s' ...", gCfg[
"ndmspc"][
"data"][
"file"].get<std::string>().c_str());
171 Printf(
"Error: Cannot open file '%s' !", gCfg[
"ndmspc"][
"data"][
"file"].get<std::string>().c_str());
175 if (!fInputList) fInputList =
new TList();
178 for (
auto & obj : gCfg[
"ndmspc"][
"data"][
"objects"]) {
179 if (obj.get<std::string>().empty())
continue;
182 if (!gCfg[
"ndmspc"][
"data"][
"directory"].is_null() && gCfg[
"ndmspc"][
"data"][
"directory"].is_string())
183 dirName = gCfg[
"ndmspc"][
"data"][
"directory"].get<std::string>();
185 std::stringstream srcfull(obj.get<std::string>().c_str());
187 std::string srcName, sparseName;
189 getline(srcfull, srcName,
':');
190 getline(srcfull, sparseName,
':');
191 if (
fVerbose >= 2) Printf(
"srcName=%s customName=%s", srcName.c_str(), sparseName.c_str());
193 std::stringstream src(srcName.c_str());
197 while (getline(src, item,
'+')) {
200 if (!dirName.empty()) objName = dirName +
"/";
202 if (
fVerbose >= 1) Printf(
"Opening obj='%s' ...", objName.c_str());
205 s = (THnSparse *)
fInputFile->Get(objName.c_str());
207 if (
fVerbose >= 1) Printf(
"Warning: Cannot open object '%s' !!!", objName.c_str());
211 if (s && !sparseName.empty()) s->SetName(sparseName.c_str());
214 if (
fVerbose >= 1) Printf(
"Adding obj='%s' ...", objName.c_str());
215 stmp = (THnSparse *)
fInputFile->Get(objName.c_str());
216 if (stmp ==
nullptr) {
217 if (
fVerbose >= 1) Printf(
"Warning: Cannot open object '%s' !!!", objName.c_str());
228 Printf(
"Warning : Could not open '%s' from file '%s' !!! Skipping ...", obj.get<std::string>().c_str(),
229 gCfg[
"ndmspc"][
"data"][
"file"].get<std::string>().c_str());
234 TFunction * fun = gROOT->GetGlobalFunction(
"NdmspcOpenInputsUser",
nullptr, kTRUE);
236 gROOT->ProcessLine(TString::Format(
"NdmspcOpenInputsUser((Ndmspc::PointRun*)%p),",
this));
239 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::OpenInputs");
250 if (
fVerbose >= 2) Printf(
"[<-] Ndmspc::PointRun::CreateResult fResultObject=%p", (
void *)fResultObject);
252 if (fResultObject)
return fResultObject;
254 THnSparse * s = (THnSparse *)fInputList->At(0);
258 int nDimsProccess = fCurrentProcessHistogramAxes.size();
260 for (
auto & cut : gCfg[
"ndmspc"][
"cuts"]) {
261 if (cut[
"enabled"].is_boolean() && cut[
"enabled"].get<
bool>() ==
false)
continue;
265 for (
auto & value : gCfg[
"ndmspc"][
"result"][
"axes"]) {
269 const Int_t ndims = nDimsCuts + nDimsParams + nDimsProccess + 1;
271 Double_t xmin[ndims];
272 Double_t xmax[ndims];
273 std::vector<std::string> names;
274 std::vector<std::string> titles;
275 std::vector<TAxis *> cutAxes;
276 fMapAxesType =
new TH1S(
"mapAxesType",
"Type Axes Map", ndims, 0, ndims);
279 Int_t nParameters = gCfg[
"ndmspc"][
"result"][
"parameters"][
"labels"].size();
280 if (nParameters <= 0)
return nullptr;
284 bins[i] = nParameters;
286 xmax[i] = nParameters;
287 names.push_back(
"parameters");
288 titles.push_back(
"parameters");
289 fMapAxesType->GetXaxis()->SetBinLabel(i + 1,
"par");
295 for (
auto & a : fCurrentProcessHistogramAxes) {
297 bins[i] = a->GetNbins();
298 xmin[i] = a->GetXmin();
299 xmax[i] = a->GetXmax();
302 names.push_back(a->GetName());
303 std::string t = a->GetTitle();
304 if (t.empty()) t = a->GetName();
307 fMapAxesType->GetXaxis()->SetBinLabel(i + 1,
"data");
309 fMapAxesType->GetXaxis()->SetBinLabel(i + 1,
"sys-out");
315 Int_t rebin_start = 1;
316 for (
auto & cut : gCfg[
"ndmspc"][
"cuts"]) {
317 if (
fVerbose >= 3) std::cout <<
"CreateResult() : " << cut.dump() << std::endl;
320 Int_t rebin_start = 1;
321 Int_t rebin_minimum = 1;
322 if (cut[
"enabled"].is_boolean() && cut[
"enabled"].get<
bool>() ==
false)
continue;
323 if (cut[
"rebin"].is_number_integer()) rebin = cut[
"rebin"].get<Int_t>();
324 if (cut[
"rebin_start"].is_number_integer()) rebin_start = cut[
"rebin_start"].get<Int_t>();
326 if (rebin_start > 1) {
327 rebin_minimum = (rebin_start % rebin);
330 TAxis * a = (TAxis *)s->GetListOfAxes()->FindObject(cut[
"axis"].get<std::string>().c_str());
331 if (a ==
nullptr)
return nullptr;
334 a = (TAxis *)a->Clone();
335 Int_t rebins_max = a->GetNbins() / rebin;
336 if ((a->GetNbins() - rebin_minimum + 1) % rebin == 0) rebins_max++;
337 Double_t arr[rebins_max];
343 for (i = rebin_minimum; i <= a->GetNbins(); i += rebin) {
345 arr[count++] = a->GetBinLowEdge(i);
348 if (count < rebins_max) arr[count++] = a->GetBinLowEdge(i);
352 a->Set(count - 1, arr);
355 bins[i] = a->GetNbins();
356 xmin[i] = a->GetXmin();
357 xmax[i] = a->GetXmax();
359 cutAxes.push_back(a);
360 names.push_back(a->GetName());
361 std::string t = a->GetTitle();
362 if (t.empty()) t = a->GetName();
364 fMapAxesType->GetXaxis()->SetBinLabel(i + 1,
"proj");
369 for (
auto & value : gCfg[
"ndmspc"][
"result"][
"axes"]) {
370 if (!value[
"labels"].is_null()) {
371 bins[i] = value[
"labels"].size();
373 xmax[i] = value[
"labels"].size();
375 else if (!value[
"ranges"].is_null()) {
376 bins[i] = value[
"ranges"].size();
378 xmax[i] = value[
"ranges"].size();
381 Printf(
"Error: 'labels' or 'ranges' is missing !!!");
385 names.push_back(value[
"name"].get<std::string>().c_str());
386 titles.push_back(value[
"name"].get<std::string>().c_str());
387 fMapAxesType->GetXaxis()->SetBinLabel(i + 1,
"sys-in");
391 fCurrentPointLabels = names;
393 THnSparse * fres =
new THnSparseD(
"results",
"Final results", i, bins, xmin, xmax);
395 Printf(
"Error: Could not create 'results' THnSparse object !!!");
399 TAxis * a = fres->GetAxis(iAxis);
401 Printf(
"Error: 'parameters' axis was not found !!!");
405 for (
auto & n : gCfg[
"ndmspc"][
"result"][
"parameters"][
"labels"]) {
406 a->SetNameTitle(names.at(iAxis).c_str(), titles.at(iAxis).c_str());
407 a->SetBinLabel(iLablel++, n.get<std::string>().c_str());
416 for (
auto & axis : fCurrentProcessHistogramAxes) {
417 if (axis->GetXbins()->GetArray()) fres->GetAxis(iAxis)->Set(axis->GetNbins(), axis->GetXbins()->GetArray());
418 fres->GetAxis(iAxis)->SetNameTitle(names.at(iAxis).c_str(), titles.at(iAxis).c_str());
420 for (iLabel = 1; iLabel < fCurrentProccessHistogram->GetAxis(iPIdx)->GetNbins() + 1; iLabel++) {
421 std::string l = fCurrentProccessHistogram->GetAxis(iPIdx)->GetBinLabel(iLabel);
422 if (!l.empty()) fres->GetAxis(iAxis)->SetBinLabel(iLabel, l.c_str());
424 fCurrentPoint[iAxis] = fCurrentProcessHistogramPoint[iPIdx];
430 for (
auto & a : cutAxes) {
432 fres->GetAxis(iAxis)->SetNameTitle(names.at(iAxis).c_str(), titles.at(iAxis).c_str());
433 if (a->GetXbins()->GetArray()) fres->GetAxis(iAxis)->Set(a->GetNbins(), a->GetXbins()->GetArray());
439 for (
auto & value : gCfg[
"ndmspc"][
"result"][
"axes"]) {
442 if (!value[
"labels"].is_null()) {
443 for (
auto & n : value[
"labels"]) {
444 fres->GetAxis(iAxis)->SetNameTitle(names.at(iAxis).c_str(), titles.at(iAxis).c_str());
445 fres->GetAxis(iAxis)->SetBinLabel(iLabel++, n.get<std::string>().c_str());
449 if (!value[
"ranges"].is_null()) {
450 for (
auto & n : value[
"ranges"]) {
451 fres->GetAxis(iAxis)->SetNameTitle(names.at(iAxis).c_str(), titles.at(iAxis).c_str());
452 fres->GetAxis(iAxis)->SetBinLabel(iLabel++, n[
"name"].get<std::string>().c_str());
458 if (
fVerbose >= 2) fres->Print(
"all");
462 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::CreateResult fResultObject=%p", (
void *)fres);
468 if (
fVerbose >= 2) Printf(
"[<-] Ndmspc::PointRun::ApplyCuts");
471 TString titlePostfix =
"";
476 Int_t rebin_start = 1;
478 fCurrentPoint[iCut] = 0;
479 for (
size_t i = 0; i < fInputList->GetEntries(); i++) {
480 s = (THnSparse *)fInputList->At(i);
482 for (
auto & cut : gCfg[
"ndmspc"][
"cuts"]) {
484 if (cut.is_null())
continue;
486 if (cut[
"enabled"].is_boolean() && cut[
"enabled"].get<
bool>() ==
false)
continue;
488 if (cut[
"rebin"].is_number_integer()) rebin = cut[
"rebin"].get<Int_t>();
489 if (cut[
"rebin_start"].is_number_integer()) rebin_start = cut[
"rebin_start"].get<Int_t>();
491 if (cut[
"axis"].is_string() && cut[
"axis"].get<std::string>().empty()) {
492 std::cerr <<
"Error: Axis name is empty ('" << cut <<
"') !!! Exiting ..." << std::endl;
495 if (cut[
"bin"][
"min"].get<Int_t>() < 0 || cut[
"bin"][
"max"].get<Int_t>() < 0) {
496 std::cerr <<
"Error: Bin min or max is less then 0 ('" << cut <<
"') !!! Exiting ..." << std::endl;
500 Int_t
id = s->GetListOfAxes()->IndexOf(s->GetListOfAxes()->FindObject(cut[
"axis"].get<std::string>().c_str()));
501 if (
id == s->GetListOfAxes()->GetEntries()) {
502 Printf(
"Axis '%s' was not found !!! Skipping ...", cut[
"axis"].get<std::string>().c_str());
506 Int_t binLocal = Utils::GetBinFromBase(cut[
"bin"][
"min"].get<int>(), rebin, rebin_start);
507 fCurrentPoint[iCut + fCurrentProcessHistogramPoint.size()] = binLocal;
509 Int_t binMin = cut[
"bin"][
"min"].get<Int_t>();
510 Int_t binMax = cut[
"bin"][
"max"].get<Int_t>();
516 Printf(
"cut=%s binLocal=%d binMin=%d binMax=%d", cut[
"axis"].get<std::string>().c_str(), binLocal, binMin,
518 s->GetAxis(
id)->SetRange(binMin, binMax);
521 if (s->GetAxis(
id)->IsAlphanumeric()) {
523 TString::Format(
"%s[%s bin=%d] ", s->GetAxis(
id)->GetName(), s->GetAxis(
id)->GetBinLabel(binMin), binMin);
526 titlePostfix += TString::Format(
"%s[%.2f,%.2f] ", s->GetAxis(
id)->GetName(),
527 s->GetAxis(
id)->GetBinLowEdge(binMin), s->GetAxis(
id)->GetBinUpEdge(binMax));
533 if (!titlePostfix.IsNull()) {
534 titlePostfix.Remove(titlePostfix.Length() - 1);
535 Printf(
"Processing '%s' ...", titlePostfix.Data());
536 gCfg[
"ndmspc"][
"projection"][
"title"] = titlePostfix.Data();
539 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::ApplyCuts");
542bool PointRun::ProcessSinglePoint()
544 if (
fVerbose >= 2) Printf(
"[<-] Ndmspc::PointRun::ProcessSinglePoint");
546 fIsProcessOk =
false;
552 if (fResultObject !=
nullptr) {
553 delete fResultObject;
554 fResultObject =
nullptr;
559 json resultAxes = gCfg[
"ndmspc"][
"result"][
"axes"];
561 std::vector<std::string> names;
562 for (
auto & value : resultAxes) {
563 std::string n = value[
"name"].get<std::string>();
564 names.push_back(n.c_str());
569 if (
fVerbose >= 1) Printf(
"Starting User Process() ...");
571 bool ok = ProcessRecursiveInner(resultAxes.size() - 1, names);
573 if (
fVerbose >= 1) Printf(
"User Process() done ...");
579 if (
fVerbose >= 0) Printf(
"Skipping ...");
582 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::ProcessSinglePoint");
585bool PointRun::ProcessRecursive(
int i)
587 if (
fVerbose >= 2) Printf(
"[<-] Ndmspc::PointRun::ProcessRecursive[%d]", i);
590 return ProcessSinglePoint();
593 THnSparse * s = (THnSparse *)fInputList->At(0);
594 TAxis * a = (TAxis *)s->GetListOfAxes()->FindObject(gCfg[
"ndmspc"][
"cuts"][i][
"axis"].get<std::string>().c_str());
596 Printf(
"Error: Axis canot be found");
600 Int_t end = a->GetNbins();
602 Int_t rebin_start = 1;
603 Int_t rebin_minimum = 1;
604 if (gCfg[
"ndmspc"][
"cuts"][i][
"rebin"].is_number_integer()) rebin = gCfg[
"ndmspc"][
"cuts"][i][
"rebin"].get<Int_t>();
605 if (gCfg[
"ndmspc"][
"cuts"][i][
"rebin_start"].is_number_integer())
606 rebin_start = gCfg[
"ndmspc"][
"cuts"][i][
"rebin_start"].get<Int_t>();
608 gCfg[
"ndmspc"][
"cuts"][i][
"rebin_minimum"] = rebin_minimum;
609 if (rebin > 1) end /= rebin;
610 if (rebin_start > 1) {
611 rebin_minimum = (rebin_start % rebin);
612 gCfg[
"ndmspc"][
"cuts"][i][
"rebin_minimum"] = rebin_minimum;
613 start = (rebin_start / rebin) + 1;
614 end = (a->GetNbins() - rebin_minimum + 1) / rebin;
620 if (gCfg[
"ndmspc"][
"process"][
"ranges"].is_array()) {
621 int range_min = gCfg[
"ndmspc"][
"process"][
"ranges"][i][0].get<
int>();
622 int range_max = gCfg[
"ndmspc"][
"process"][
"ranges"][i][1].get<
int>();
623 if (range_max > end || range_min < start || range_min > range_max || range_min > end || range_max < start) {
624 Printf(
"Error: Process range is out of bounds histogram(after rebin)=[%d,%d] request=[%d,%d] or requested min is "
625 "higher then requested max !!!",
626 start, end, range_min, range_max);
630 if (gCfg[
"ndmspc"][
"process"][
"ranges"][i][1] < end) end = range_max;
634 for (Int_t iBin = start; iBin <= end; iBin++) {
635 Int_t binMin = (iBin - 1) * rebin + rebin_minimum;
636 Int_t binMax = (iBin * rebin) - 1 + rebin_minimum;
638 Printf(
"axis=%s rebin=%d rebin_minimum=%d binMin=%d binMax=%d [%f,%f]", a->GetName(), rebin, rebin_minimum,
639 binMin, binMax, a->GetBinLowEdge(binMin), a->GetBinUpEdge(binMax));
640 gCfg[
"ndmspc"][
"cuts"][i][
"bin"][
"min"] = binMin;
641 gCfg[
"ndmspc"][
"cuts"][i][
"bin"][
"max"] = binMax;
642 ProcessRecursive(i - 1);
645 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::ProcessRecursive[%d]", i);
649bool PointRun::ProcessRecursiveInner(Int_t i, std::vector<std::string> & n)
651 if (
fVerbose >= 2) Printf(
"[<-] Ndmspc::PointRun::ProcessRecursiveInner[%d]", i);
653 if (fIsSkipBin)
return false;
655 if (!fResultObject) {
656 fIsProcessExit =
true;
660 if (fIsProcessExit) gSystem->Exit(1);
663 TList * outputList =
new TList();
664 SetOutputList(outputList);
666 Printf(
"\tPoint: %s", fCurrentPointValue.dump().c_str());
669 if (
fVerbose >= 2) Printf(
"Running point macro '%s.C' ...", fMacro->GetName());
676 Longptr_t ok = gROOT->ProcessLine(TString::Format(
"%s((Ndmspc::PointRun*)%p);", fMacro->GetName(),
this));
688 if (ok &&
fVerbose >= 5) outputList->Print();
696 if (fCurrentOutputFile ==
nullptr) {
700 TDirectory * outputDir = fCurrentOutputRootDirectory;
704 for (
int iPoint = 1; iPoint < fResultObject->GetNdimensions(); iPoint++) {
705 path += std::to_string(fCurrentPoint[iPoint]) +
"/";
717 fCurrentOutputRootDirectory->mkdir(path.c_str(),
"",
true);
718 outputDir = fCurrentOutputRootDirectory->GetDirectory(path.c_str());
725 std::string axisName = gCfg[
"ndmspc"][
"result"][
"axes"][i][
"name"].get<std::string>();
726 if (!gCfg[
"ndmspc"][
"result"][
"axes"][i][
"labels"].is_null()) {
727 for (
auto & v : gCfg[
"ndmspc"][
"result"][
"axes"][i][
"labels"]) {
728 TAxis * a = (TAxis *)fResultObject->GetListOfAxes()->FindObject(axisName.c_str());
729 Int_t
id = fResultObject->GetListOfAxes()->IndexOf(a);
730 fCurrentPoint[id] = a->FindBin(v.get<std::string>().c_str());
731 fCurrentPointValue[axisName] = v;
732 fCurrentPointLabels[id] = v.get<std::string>().c_str();
733 ProcessRecursiveInner(i - 1, n);
736 else if (!gCfg[
"ndmspc"][
"result"][
"axes"][i][
"ranges"].is_null()) {
737 for (
auto & v : gCfg[
"ndmspc"][
"result"][
"axes"][i][
"ranges"]) {
738 TAxis * a = (TAxis *)fResultObject->GetListOfAxes()->FindObject(axisName.c_str());
739 Int_t
id = fResultObject->GetListOfAxes()->IndexOf(a);
740 fCurrentPoint[id] = a->FindBin(v[
"name"].get<std::string>().c_str());
741 fCurrentPointValue[axisName] = v;
742 fCurrentPointLabels[id] = v[
"name"].get<std::string>().c_str();
743 ProcessRecursiveInner(i - 1, n);
747 Printf(
"Error: ProcessRecursiveInner : No 'labels' or 'ranges' !!!");
752 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::ProcessRecursiveInner[%d]", i);
755void PointRun::OutputFileOpen()
758 if (
fVerbose >= 2) Printf(
"[<-] Ndmspc::PointRun::OutputFileOpen");
762 fCurrentOutputFileName =
"";
764 if (!gCfg[
"ndmspc"][
"output"][
"host"].get<std::string>().empty())
765 fCurrentOutputFileName += gCfg[
"ndmspc"][
"output"][
"host"].get<std::string>().c_str();
766 if (!gCfg[
"ndmspc"][
"output"][
"dir"].get<std::string>().empty())
767 fCurrentOutputFileName += gCfg[
"ndmspc"][
"output"][
"dir"].get<std::string>().c_str();
769 if (gCfg[
"ndmspc"][
"cuts"].is_array() && !fCurrentOutputFileName.empty()) {
796 std::string cutsName = Utils::GetCutsPath(gCfg[
"ndmspc"][
"cuts"]);
800 if (cutsName.length() > 0) {
801 fCurrentOutputFileName +=
"/";
802 fCurrentOutputFileName += gCfg[
"ndmspc"][
"environment"].get<std::string>().c_str();
803 fCurrentOutputFileName +=
"/";
804 fCurrentOutputFileName += cutsName.c_str();
806 fCurrentOutputFileName +=
"bins";
807 fCurrentOutputFileName +=
"/";
810 if (gCfg[
"ndmspc"][
"output"][
"post"].is_string()) {
811 std::string post = gCfg[
"ndmspc"][
"output"][
"post"].get<std::string>();
813 if (!fCurrentOutputFileName.empty() && fCurrentOutputFileName[fCurrentOutputFileName.size() - 1] !=
'/')
814 fCurrentOutputFileName +=
"/";
816 fCurrentOutputFileName += post;
820 for (
auto & cut : gCfg[
"ndmspc"][
"cuts"]) {
821 if (cut[
"enabled"].is_boolean() && cut[
"enabled"].get<bool>() ==
false)
continue;
823 Int_t rebin_start = 1;
824 Int_t rebin_minimum = 1;
826 if (cut[
"rebin"].is_number_integer()) rebin = cut[
"rebin"].get<Int_t>();
827 if (cut[
"rebin_start"].is_number_integer()) rebin_start = cut[
"rebin_start"].get<Int_t>();
829 if (rebin_start > 1) {
830 rebin_minimum = (rebin_start % rebin);
831 if (rebin_minimum == 0) rebin_minimum = 1;
834 Int_t bin_min = cut[
"bin"][
"min"].get<Int_t>();
837 Int_t bin_min_converted = (bin_min - rebin_minimum) / rebin + 1;
838 fCurrentOutputFileName += std::to_string(bin_min_converted) +
"/";
843 fCurrentOutputFileName += gCfg[
"ndmspc"][
"environment"].get<std::string>().c_str();
844 fCurrentOutputFileName +=
"/";
847 if (!fCurrentOutputFileName.empty() && fCurrentOutputFileName[fCurrentOutputFileName.size() - 1] !=
'/')
848 fCurrentOutputFileName +=
"/";
850 if (!gCfg[
"ndmspc"][
"output"][
"file"].get<std::string>().empty())
851 fCurrentOutputFileName += gCfg[
"ndmspc"][
"output"][
"file"].get<std::string>().c_str();
853 fCurrentOutputFileName = gSystem->ExpandPathName(fCurrentOutputFileName.c_str());
856 gCfg[
"ndmspc"][
"output"][
"opt"].get<std::string>().c_str())
861 fCurrentOutputFile->mkdir(
"content");
862 fCurrentOutputRootDirectory = fCurrentOutputFile->GetDirectory(
"content");
863 fCurrentOutputRootDirectory->cd();
865 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::OutputFileOpen");
867void PointRun::OutputFileClose()
869 if (
fVerbose >= 2) Printf(
"[<-] Ndmspc::PointRun::OutputFileClose");
871 if (fCurrentOutputFile ==
nullptr)
return;
873 if (
fVerbose >= 2) Printf(
"Closing file '%s' ...", fCurrentOutputFileName.c_str());
874 fCurrentOutputRootDirectory->Write();
876 fCurrentOutputFile->cd();
877 fResultObject->Write();
878 fMapAxesType->Write();
879 fCurrentOutputFile->Close();
881 fCurrentOutputFile =
nullptr;
882 fCurrentOutputRootDirectory =
nullptr;
884 if (
fVerbose >= 0) Printf(
"Objects stored in '%s'", fCurrentOutputFileName.c_str());
886 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::OutputFileClose");
888bool PointRun::Finish()
891 if (
fVerbose >= 2) Printf(
"[<-] Ndmspc::PointRun::Finish");
895 fInputList =
nullptr;
903 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::Finish");
907int PointRun::ProcessSingleFile()
911 if (gCfg[
"ndmspc"][
"process"][
"type"].is_string()) type = gCfg[
"ndmspc"][
"process"][
"type"].get<std::string>();
914 Printf(
"Warning: [ndmspc][process][type] is missing or is empty in configuration !!! Setting it ot 'single' ...");
916 gCfg[
"ndmspc"][
"process"][
"type"] = type;
920 if (inputList ==
nullptr)
return 1;
922 if (!type.compare(
"single")) {
923 if (!ProcessSinglePoint())
return 3;
925 else if (!type.compare(
"all")) {
928 for (
auto & cut : gCfg[
"ndmspc"][
"cuts"]) {
929 if (cut[
"enabled"].is_boolean() && cut[
"enabled"].get<bool>() ==
false)
continue;
932 gCfg[
"ndmspc"][
"cuts"] = cuts;
934 ProcessRecursive(gCfg[
"ndmspc"][
"cuts"].size() - 1);
937 Printf(
"Error: Value [process][type]='%s' is not supported !!! Exiting ...", type.c_str());
951int PointRun::ProcessHistogramRun()
954 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::ProcessHistogramRun");
956 std::string fileNameHistogram = gCfg[
"ndmspc"][
"data"][
"histogram"][
"file"].get<std::string>();
957 std::string objName = gCfg[
"ndmspc"][
"data"][
"histogram"][
"obj"].get<std::string>();
960 if (!fProccessHistogram) {
961 Printf(
"Error: Proccess input histogram file '%s' could not opened !!!", fileNameHistogram.c_str());
964 fCurrentProccessHistogram = (THnSparse *)fProccessHistogram->Get(objName.c_str());
965 if (!fCurrentProccessHistogram) {
966 Printf(
"Error: Proccess input histogram object '%s' could not opened !!!", objName.c_str());
969 TObjArray * axesArray = fCurrentProccessHistogram->GetListOfAxes();
970 for (
int iAxis = 0; iAxis < axesArray->GetEntries(); iAxis++) {
972 TAxis * aTmp = (TAxis *)axesArray->At(iAxis);
974 fCurrentProcessHistogramAxes.push_back(aTmp);
977 if (gCfg[
"ndmspc"][
"data"][
"histogram"][
"bins"].is_array()) {
979 for (
auto & v : gCfg[
"ndmspc"][
"data"][
"histogram"][
"bins"]) {
980 Printf(
"%s", v.dump().c_str());
983 for (
auto & idx : v) {
988 fCurrentProccessHistogram->SetBinContent(p, 1);
992 if (fCurrentProccessHistogram->GetNbins()) {
993 Int_t proccessPoint[fCurrentProccessHistogram->GetNdimensions()];
994 for (
int iBin = 0; iBin < fCurrentProccessHistogram->GetNbins(); iBin++) {
995 fCurrentProcessHistogramPoint.clear();
996 fCurrentProccessHistogram->GetBinContent(iBin, proccessPoint);
1000 for (
auto & p : proccessPoint) {
1002 fCurrentProcessHistogramPoint.push_back(p);
1003 path += std::to_string(std::abs(p)) +
"/";
1006 std::string fullPath = gCfg[
"ndmspc"][
"data"][
"histogram"][
"base"].get<std::string>();
1009 fullPath += gCfg[
"ndmspc"][
"data"][
"histogram"][
"filename"].get<std::string>();
1011 gCfg[
"ndmspc"][
"data"][
"file"] = fullPath;
1013 gCfg[
"ndmspc"][
"output"][
"post"] = path;
1017 Int_t rc = ProcessSingleFile();
1024 Printf(
"Error: No entries in proccess histogram !!! Nothing to process !!!");
1028 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::ProcessHistogramRun");
1031bool PointRun::Run(std::string filename, std::string userConfig, std::string environment, std::string userConfigRaw,
1032 bool show, std::string outfilename)
1034 if (
fVerbose >= 2) Printf(
"[<-] Ndmspc::PointRun::Run");
1036 if (!fMacro)
return 1;
1038 if (!
LoadConfig(filename, userConfig, environment, userConfigRaw, show, outfilename))
return false;
1041 if (!gCfg[
"ndmspc"][
"data"][
"histogram"].is_null() && !gCfg[
"ndmspc"][
"data"][
"histogram"][
"enabled"].is_null() &&
1042 gCfg[
"ndmspc"][
"data"][
"histogram"][
"enabled"].get<bool>() ==
true) {
1043 ProcessHistogramRun();
1046 ProcessSingleFile();
1048 if (
fVerbose >= 2) Printf(
"[->] Ndmspc::PointRun::Run");
1059 Printf(
"Genrating point run with name '%s' ...", name.c_str());
1070 "output": { "dir": "$HOME/.ndmspc/analyses/generated", "host": "" }
1073 "environment": "local",
1075 "file": "input.root",
1076 "objects": ["hNSparse"]
1080 "parameters": { "labels": ["Integral"], "default": "Integral" }
1085 "file": "content.root",
1092 "type": "error-only",
1093 "dir": "root://eos.ndmspc.io//eos/ndmspc/scratch/ndmspc/logs"
1102 std::string macroTemplateHeader = R""""(
1105#include <THnSparse.h>
1107#include <ndmspc/PointRun.h>
1108#include <ndmspc/Utils.h>
1111 std::string macroTemplate = R""""(
1113 json cfg = pr->Cfg();
1114 TList * inputList = pr->GetInputList();
1115 THnSparse * resultObject = pr->GetResultObject();
1116 Int_t * point = pr->GetCurrentPoint();
1117 std::vector<std::string> pointLabels = pr->GetCurrentPointLabels();
1118 json pointValue = pr->GetCurrentPointValue();
1119 TList * outputList = pr->GetOutputList();
1122 if (!cfg["user"]["verbose"].is_null() && cfg["user"]["verbose"].is_number_integer()) {
1123 verbose = cfg["user"]["verbose"].get<int>();
1126 THnSparse * hs = (THnSparse *)inputList->At(0);
1128 int projId = cfg["user"]["proj"].get<int>();
1129 TH1D * h = hs->Projection(projId, "O");
1131 TString titlePostfix = "(no cuts)";
1132 if (cfg["ndmspc"]["projection"]["title"].is_string())
1133 titlePostfix = cfg["ndmspc"]["projection"]["title"].get<std::string>();
1134 h->SetNameTitle("h", TString::Format("h - %s", titlePostfix.Data()).Data());
1137 // Skip bin (do not save any output)
1138 if (h->GetEntries() < cfg["user"]["minEntries"].get<int>())
1141 Double_t integral = h->Integral();
1143 Printf("Integral = %f ", integral);
1147 Ndmspc::Utils::SetResultValueError(cfg, resultObject, "Integral", point, integral, TMath::Sqrt(integral), false, true);
1150 if (!gROOT->IsBatch() && !cfg["ndmspc"]["process"]["type"].get<std::string>().compare("single")) {
1159 cfg["ndmspc"][
"data"][
"file"] = inFile.c_str();
1160 cfg[
"ndmspc"][
"data"][
"objects"] = {inObjectName.c_str()};
1162 if (cfg[
"ndmspc"][
"cuts"].size() == 0) {
1167 Printf(
"Error: Problem opening file '%s' !!! Exiting ...", inFile.c_str());
1171 THnSparse * tmpSparse = (THnSparse *)tmpFile->Get(inObjectName.c_str());
1173 Printf(
"Error: Problem opening object '%s' !!! Exiting ...", inObjectName.c_str());
1177 TObjArray * axes = tmpSparse->GetListOfAxes();
1179 for (
int i = 0; i < axes->GetEntries(); i++) {
1180 a = (TAxis *)axes->At(i);
1183 Printf(
"Init axis '%s' with enabled=false", a->GetName());
1184 cfg[
"ndmspc"][
"cuts"][i][
"enabled"] =
false;
1185 cfg[
"ndmspc"][
"cuts"][i][
"axis"] = a->GetName();
1186 cfg[
"ndmspc"][
"cuts"][i][
"bin"][
"min"] = 1;
1187 cfg[
"ndmspc"][
"cuts"][i][
"bin"][
"max"] = 1;
1188 cfg[
"ndmspc"][
"cuts"][i][
"rebin"] = 1;
1194 std::string outputConfig = name +
".json";
1195 std::ofstream fileConfig(outputConfig.c_str());
1196 fileConfig << std::setw(2) << cfg << std::endl;
1198 std::string outputMacro = name +
".C";
1199 std::ofstream file(outputMacro.c_str());
1200 file << macroTemplateHeader.c_str();
1201 file <<
"bool " << name.c_str() <<
"(Ndmspc::PointRun *pr)";
1202 file << macroTemplate.c_str();
1204 Printf(
"File '%s.C' and '%s.json' were generated ...", name.c_str(), name.c_str());
1208bool PointRun::Merge(std::string config, std::string userConfig, std::string environment, std::string userConfigRaw,
1209 std::string fileOpt)
1215 if (!Core::LoadConfig(config, userConfig, environment, userConfigRaw))
return false;
1217 if (gCfg[
"ndmspc"][
"output"][
"host"].get<std::string>().empty()) {
1218 gCfg[
"ndmspc"][
"output"][
"opt"] =
"";
1221 std::string hostUrl = gCfg[
"ndmspc"][
"output"][
"host"].get<std::string>();
1227 if (!hostUrl.empty()) path = hostUrl +
"/";
1228 path += gCfg[
"ndmspc"][
"output"][
"dir"].get<std::string>() +
"/";
1230 path += environment +
"/";
1243 path += Utils::GetCutsPath(gCfg[
"ndmspc"][
"cuts"]);
1245 path = gSystem->ExpandPathName(path.c_str());
1247 std::string outFile = path +
"results.root";
1251 TUrl url(path.c_str());
1252 std::string outHost = url.GetHost();
1253 std::string inputDirectory = url.GetFile();
1254 std::string linesMerge =
"";
1256 if (outHost.empty()) {
1257 if (gSystem->AccessPathName(path.c_str())) {
1258 Printf(
"Error: Nothing to merge, because path '%s' does not exist !!!", path.c_str());
1261 Printf(
"Doing local find %s -name %s", path.c_str(), gCfg[
"ndmspc"][
"output"][
"file"].get<std::string>().c_str());
1262 linesMerge = gSystem->GetFromPipe(
1263 TString::Format(
"find %s -name %s", path.c_str(), gCfg[
"ndmspc"][
"output"][
"file"].get<std::string>().c_str())
1270 Printf(
"Doing eos find -f %s", path.c_str());
1272 std::string contentFile = gCfg[
"ndmspc"][
"output"][
"file"].get<std::string>();
1276 std::vector<std::string> tokens;
1278 if (!inputDirectory.empty()) {
1279 findUrl = TString::Format(
1280 "root://%s//proc/user/?mgm.cmd=find&mgm.find.match=%s&mgm.path=%s&mgm.format=json&mgm.option=f&filetype=raw",
1281 outHost.c_str(), contentFile.c_str(), inputDirectory.c_str());
1288 int buffsize = 4096;
1289 char buff[buffsize + 1];
1291 Long64_t buffread = 0;
1292 std::string content;
1293 while (buffread < f->GetSize()) {
1295 if (buffread + buffsize > f->GetSize()) buffsize = f->GetSize() - buffread;
1298 f->ReadBuffer(buff, buffread, buffsize);
1299 buff[buffsize] =
'\0';
1301 buffread += buffsize;
1306 std::string ss =
"mgm.proc.stdout=";
1307 size_t pos = ss.size() + 1;
1308 content = content.substr(pos);
1311 std::stringstream check1(content);
1313 std::string intermediate;
1316 while (getline(check1, intermediate,
'&')) {
1317 tokens.push_back(intermediate);
1321 tokens.push_back(contentFile.c_str());
1323 linesMerge = tokens[0];
1325 std::stringstream check2(linesMerge);
1327 std::string outFileLocal =
"/tmp/ndmspc-merged-" + std::to_string(gSystem->GetPid()) +
".root";
1329 if (hostUrl.empty()) {
1330 outFileLocal = outFile;
1333 outFileLocal = gSystem->ExpandPathName(outFileLocal.c_str());
1335 TFileMerger m(kFALSE);
1336 m.OutputFile(TString::Format(
"%s%s", outFileLocal.c_str(), fileOpt.c_str()));
1341 while (std::getline(check2, line)) {
1343 Printf(
"Adding file '%s' ...", line.data());
1344 if (!outHost.empty()) {
1345 m.AddFile(TString::Format(
"root://%s/%s", outHost.c_str(), line.c_str()).Data());
1348 m.AddFile(line.c_str());
1352 Printf(
"Merging ...");
1356 Printf(
"Copy '%s' to '%s' ...", outFileLocal.c_str(), outFile.c_str());
1357 TFile::Cp(outFileLocal.c_str(), outFile.c_str());
1358 std::string rm =
"rm -f " + outFileLocal;
1359 Printf(
"Doing '%s' ...", rm.c_str());
1360 gSystem->Exec(rm.c_str());
1362 Printf(
"Output: '%s'", outFile.c_str());
TFile * fInputFile
Bin Count (TODO! rename to axis level maybe)
bool Init(std::string extraPath="")
int fBinCount
Verbose level.
THnSparse * CreateResult()
PointRun(std::string macro="NdmspcPointRun.C")
static bool Generate(std::string name="myAnalysis", std::string inFile="myFile.root", std::string inObjectName="myNDHistogram")
bool LoadConfig(std::string config, std::string userConfig="", std::string environment="", std::string userConfigRaw="", bool show=false, std::string outfilename="")
Environment.
static TFile * OpenFile(std::string filename, std::string mode="READ", bool createLocalDir=true)