diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 00000000..59eceb91
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1,9 @@
+# Code owners
+#
+# Lines starting with '#' are comments.
+# Each line is a file pattern followed by one or more owners.
+
+# These owners will be the default owners for everything in the repo.
+* @ginnocen @vkucera
+
+# Order is important. The last matching pattern has the most precedence.
diff --git a/FirstAnalysis/README.md b/FirstAnalysis/README.md
index be0f0f48..a426ca78 100644
--- a/FirstAnalysis/README.md
+++ b/FirstAnalysis/README.md
@@ -1,19 +1,29 @@
-# O2 First analysis utilities
-
-## Table of contents
-
-* [Introduction](#introduction)
-* [Available samples ALICE3](#available-samples-alice3)
-
+# O2 first analysis utilities
## Introduction
The main purpose of this folder is to provide analysis tools to perform analysis of O2 analysis task outputs.
It includes for the moment a set of QA plotting macros to inspect `AnalysisResults.root` of MC and data samples.
-It also includes some preliminary functionalities for performing efficiency corrections of HF analyses. It is currently being used
-also for performing Run5 analysis.
+It also includes some preliminary functionalities for performing efficiency corrections of HF analyses.
+It is currently being used also for performing Run5 analysis.
+## Instructions for contributors
+
+* Write documentation comments to make the code easy to understand.
+* Every file should contain the following details at the top:
+ * what the code does,
+ * which input it needs (e.g. output of which O2 workflow),
+ * how to run it (in case simply executing the script is not enough),
+ * names of authors, contributors, maintainers (to contact in case of problems or questions).
+* Follow [PEP 8 naming conventions](https://www.python.org/dev/peps/pep-0008/#naming-conventions) in Python code.
+* Do not use hard-coded paths! A default path should point to a file directly produced by the framework (e.g. `../codeHF/AnalysisResults_O2.root`).
## Available samples ALICE3
* D2H KrKr production (X events):
* AOD O2 tables: `/data/Run5data/EMBEDDING_KrKr_CCBARLc_scenario3/TEST`
* Analysis result: `/data/Run5data_samples/EMBEDDING_KrKr_CCBARLc_scenario3_20210224/AnalysisResults_O2.root`
+
+## Plotting
+The analyses validation is supposed to use the [HFPlot tool](https://github.com/benedikt-voelkel/HFPlot) for plotting purposes in the future.
+It is basically a *pythonic* wrapper around `ROOT` with some automated features.
+As a first use case it is implemented in [distrib_studies.py](distrib_studies.py).
+A more extensive README can be found [here](https://github.com/benedikt-voelkel/HFPlot) and there are also some examples provided.
diff --git a/FirstAnalysis/distrib_studies.py b/FirstAnalysis/distrib_studies.py
index 1b83fdbc..9c2b0249 100644
--- a/FirstAnalysis/distrib_studies.py
+++ b/FirstAnalysis/distrib_studies.py
@@ -4,7 +4,7 @@
import yaml
from hfplot.plot_spec_root import ROOTFigure
-from hfplot.style import ROOTStyle1D
+from hfplot.style import StyleObject1D
from ROOT import TFile
@@ -47,12 +47,12 @@ def distr_studies(hadron="X3872", collision="pp14p0", yrange="absy1p44"):
lptMax = []
# Define some styles
- style_sig = ROOTStyle1D()
+ style_sig = StyleObject1D()
style_sig.markercolor = 2
style_sig.markerstyle = 21
style_sig.markersize = 2
style_sig.draw_options = "P"
- style_bkg = ROOTStyle1D()
+ style_bkg = StyleObject1D()
style_bkg.markerstyle = 23
style_bkg.markersize = 2
style_bkg.draw_options = "P"
diff --git a/README.md b/README.md
index 3a0f8ac8..4b921f23 100644
--- a/README.md
+++ b/README.md
@@ -3,24 +3,6 @@
[](https://github.com/marketplace/actions/mega-linter)
[](https://github.com/marketplace/actions/clang-format-lint)
-## Table of contents
-
-* [Introduction](#introduction)
-* [Overview](#overview)
- * [Execution](#execution)
- * [Configuration](#configuration)
-* [Preparation](#preparation)
- * [Build AliPhysics and O2](#build-aliphysics-and-o2)
- * [Download the validation framework](#download-the-validation-framework)
- * [Install parallelisation software](#install-parallelisation-software)
-* [Run the framework](#run-the-framework)
-* [Job debugging](#job-debugging)
-* [Heavy-flavour analyses](#heavy-flavour-analyses)
-* [Keep your repositories and installations up to date and clean](#keep-your-repositories-and-installations-up-to-date-and-clean)
-* [Continuous integration tests](#continuous-integration-tests)
- * [C++](#c)
- * [Python](#python)
-
## Introduction
The main purpose of the Run 3 validation framework is to provide a compact and flexible tool for validation of the
@@ -251,25 +233,25 @@ You can easily extend the script to include any other local Git repository and a
## Continuous integration tests
Validity and quality of the code in the repository are checked on GitHub by several tools (linters) that support many coding languages.
-Linters run automatically for every push or pull request.
+Linters run automatically for every push or pull request event.
**Please make sure that your code passes all the tests before making a pull request.**
-Here are some tips how to check your code locally with the linters that usually complain the most.
+It is possible to check your code locally (before even committing or pushing):
-### C++
+### Space checker
-* [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html) - automatic reformatting of C++ sources files according to configurable style guides
+```bash
+bash /exec/check_spaces.sh
+```
+
+### [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html)
```bash
clang-format -style=file -i
```
-### Python
-
-* [Black](https://github.com/psf/black) - “uncompromising Python code formatter”
-* [flake8](https://gitlab.com/pycqa/flake8) - “tool that glues together pep8, pyflakes, mccabe, and third-party plugins to check the style and quality of some python code”
-* [isort](https://github.com/PyCQA/isort) - “utility to sort imports alphabetically, and automatically separated into sections and by type”
+### [Mega-Linter](https://nvuillam.github.io/mega-linter/mega-linter-runner/)
```bash
-black . && flake8 . && isort .
+mega-linter-runner
```
diff --git a/codeHF/Compare.C b/codeHF/Compare.C
index 444ffc0a..ee085338 100644
--- a/codeHF/Compare.C
+++ b/codeHF/Compare.C
@@ -37,15 +37,17 @@ Int_t Compare(TString filerun3 = "AnalysisResults_O2.root", TString filerun1 = "
return 1;
}
+ TString labelParticle = "";
+
// Histogram specification: axis label, Run 1 name, Run 3 path/name, rebin, log scale histogram, log scale ratio
VecSpecHis vecHisTracks;
- AddHistogram(vecHisTracks, "#it{p}_{T} before selections (GeV/#it{c})", "hPtAllTracks", "hf-produce-sel-track/hpt_nocuts", 2, 1, 0);
- AddHistogram(vecHisTracks, "#it{p}_{T} after selections (GeV/#it{c})", "hPtSelTracks", "hf-produce-sel-track/hpt_cuts_2prong", 2, 1, 0);
- AddHistogram(vecHisTracks, "DCA XY to prim. vtx. (2-prong sel.) (cm)", "hImpParSelTracks2prong", "hf-produce-sel-track/hdcatoprimxy_cuts_2prong", 2, 1, 0);
- AddHistogram(vecHisTracks, "DCA XY to prim. vtx. (3-prong sel.) (cm)", "hImpParSelTracks3prong", "hf-produce-sel-track/hdcatoprimxy_cuts_3prong", 2, 1, 0);
- AddHistogram(vecHisTracks, "#it{#eta} (2-prong sel.)", "hEtaSelTracks2prong", "hf-produce-sel-track/heta_cuts_2prong", 2, 0, 0);
- AddHistogram(vecHisTracks, "#it{#eta} (3-prong sel.)", "hEtaSelTracks3prong", "hf-produce-sel-track/heta_cuts_3prong", 2, 0, 0);
+ AddHistogram(vecHisTracks, "#it{p}_{T} before selections (GeV/#it{c})", "hPtAllTracks", "hf-tag-sel-tracks/hpt_nocuts", 2, 1, 0);
+ AddHistogram(vecHisTracks, "#it{p}_{T} after selections (GeV/#it{c})", "hPtSelTracks", "hf-tag-sel-tracks/hpt_cuts_2prong", 2, 1, 0);
+ AddHistogram(vecHisTracks, "DCA XY to prim. vtx. (2-prong sel.) (cm)", "hImpParSelTracks2prong", "hf-tag-sel-tracks/hdcatoprimxy_cuts_2prong", 2, 1, 0);
+ AddHistogram(vecHisTracks, "DCA XY to prim. vtx. (3-prong sel.) (cm)", "hImpParSelTracks3prong", "hf-tag-sel-tracks/hdcatoprimxy_cuts_3prong", 2, 1, 0);
+ AddHistogram(vecHisTracks, "#it{#eta} (2-prong sel.)", "hEtaSelTracks2prong", "hf-tag-sel-tracks/heta_cuts_2prong", 2, 0, 0);
+ AddHistogram(vecHisTracks, "#it{#eta} (3-prong sel.)", "hEtaSelTracks3prong", "hf-tag-sel-tracks/heta_cuts_3prong", 2, 0, 0);
VecSpecHis vecHisSkim;
AddHistogram(vecHisSkim, "secondary vtx x - 2prong (cm)", "h2ProngVertX", "hf-track-index-skims-creator/hvtx2_x", 5, 1, 0);
@@ -76,7 +78,14 @@ Int_t Compare(TString filerun3 = "AnalysisResults_O2.root", TString filerun1 = "
AddHistogram(vecHisD0, "decay length XY (cm)", "hDecLenXYD0", "hf-task-d0/hdeclengthxy", 2, 1, 0);
AddHistogram(vecHisD0, "decay length error (cm)", "hDecLenErrD0", "hf-task-d0/hDecLenErr", 1, 1, 0);
AddHistogram(vecHisD0, "decay length XY error (cm)", "hDecLenXYErrD0", "hf-task-d0/hDecLenXYErr", 1, 1, 0);
- AddHistogram(vecHisD0, "cos. pointing angle", "hCosPointD0", "hf-task-d0/hCPA", 2, 1, 0);
+ AddHistogram(vecHisD0, "cos pointing angle", "hCosPointD0", "hf-task-d0/hCPA", 2, 1, 0);
+
+ labelParticle = "D^{0} #rightarrow #pi K";
+ VecSpecHis vecHisD0MC;
+ AddHistogram(vecHisD0MC, labelParticle + ", matched prompt: #it{p}_{T}^{rec} (GeV/#it{c})", "hPtRecoPromptD0Kpi", "hf-task-d0-mc/hPtRecSigPrompt", 2, 1, 0);
+ AddHistogram(vecHisD0MC, labelParticle + ", gen. prompt: #it{p}_{T}^{gen} (GeV/#it{c})", "hPtGenPromptD0Kpi", "hf-task-d0-mc/hPtGenPrompt", 2, 1, 0);
+ AddHistogram(vecHisD0MC, labelParticle + ", matched non-prompt: #it{p}_{T}^{rec} (GeV/#it{c})", "hPtRecoFeeddwD0Kpi", "hf-task-d0-mc/hPtRecSigNonPrompt", 2, 1, 0);
+ AddHistogram(vecHisD0MC, labelParticle + ", gen. non-prompt: #it{p}_{T}^{gen} (GeV/#it{c})", "hPtGenFeeddwD0Kpi", "hf-task-d0-mc/hPtGenNonPrompt", 2, 1, 0);
VecSpecHis vecHisDPlus;
AddHistogram(vecHisDPlus, "#it{p}_{T} prong 0 (GeV/#it{c})", "hPtDplusDau0", "hf-task-dplus/hPtProng0", 2, 1, 0);
@@ -88,13 +97,14 @@ Int_t Compare(TString filerun3 = "AnalysisResults_O2.root", TString filerun1 = "
AddHistogram(vecHisDPlus, "decay length (cm)", "hDecLenDplus", "hf-task-dplus/hDecayLength", 4, 1, 0);
AddHistogram(vecHisDPlus, "decay length XY (cm)", "hDecLenXYDplus", "hf-task-dplus/hDecayLengthXY", 4, 1, 0);
AddHistogram(vecHisDPlus, "norm. decay length XY", "hNormDecLenXYDplus", "hf-task-dplus/hNormalisedDecayLengthXY", 2, 1, 0);
- AddHistogram(vecHisDPlus, "cos. pointing angle", "hCosPointDplus", "hf-task-dplus/hCPA", 2, 1, 0);
- AddHistogram(vecHisDPlus, "cos. pointing angle XY", "hCosPointXYDplus", "hf-task-dplus/hCPAxy", 2, 1, 0);
+ AddHistogram(vecHisDPlus, "cos pointing angle", "hCosPointDplus", "hf-task-dplus/hCPA", 2, 1, 0);
+ AddHistogram(vecHisDPlus, "cos pointing angle XY", "hCosPointXYDplus", "hf-task-dplus/hCPAxy", 2, 1, 0);
AddHistogram(vecHisDPlus, "norm. IP", "hNormIPDplus", "hf-task-dplus/hMaxNormalisedDeltaIP", 4, 1, 0);
AddHistogram(vecHisDPlus, "decay length error (cm)", "hDecLenErrDplus", "hf-task-dplus/hDecayLengthError", 2, 1, 0);
AddHistogram(vecHisDPlus, "decay length XY error (cm)", "hDecLenXYErrDplus", "hf-task-dplus/hDecayLengthXYError", 2, 1, 0);
AddHistogram(vecHisDPlus, "prong 0 impact parameter (cm)", "hImpParDplusDau0", "hf-task-dplus/hd0Prong0", 2, 1, 0);
AddHistogram(vecHisDPlus, "prong 1 impact parameter (cm)", "hImpParDplusDau1", "hf-task-dplus/hd0Prong1", 2, 1, 0);
+ AddHistogram(vecHisDPlus, "prong 2 impact parameter (cm)", "hImpParDplusDau2", "hf-task-dplus/hd0Prong2", 2, 1, 0);
AddHistogram(vecHisDPlus, "prong impact parameter error (cm)", "hImpParErrDplusDau", "hf-task-dplus/hImpactParameterError", 2, 1, 0);
AddHistogram(vecHisDPlus, "sq. sum of prong imp. par. (cm^{2})", "hSumSqImpParDplusDau", "hf-task-dplus/hImpactParameterProngSqSum", 2, 1, 0);
@@ -105,7 +115,14 @@ Int_t Compare(TString filerun3 = "AnalysisResults_O2.root", TString filerun1 = "
AddHistogram(vecHisLc, "#it{p}_{T} #Lambda_{c}^{#plus} (GeV/#it{c})", "hPtLc", "hf-task-lc/hptcand", 2, 1, 0);
AddHistogram(vecHisLc, "3-prong mass (p K #pi) (GeV/#it{c}^{2})", "hInvMassLc", "hf-task-lc/hmass", 2, 0, 0);
AddHistogram(vecHisLc, "decay length (cm)", "hDecLenLc", "hf-task-lc/hdeclength", 2, 1, 0);
- AddHistogram(vecHisLc, "cos. pointing angle", "hCosPointLc", "hf-task-lc/hCPA", 2, 1, 0);
+ AddHistogram(vecHisLc, "cos pointing angle", "hCosPointLc", "hf-task-lc/hCPA", 2, 1, 0);
+
+ labelParticle = "#Lambda_{c}^{#plus} #rightarrow p K #pi";
+ VecSpecHis vecHisLcMC;
+ AddHistogram(vecHisLcMC, labelParticle + ", matched prompt: #it{p}_{T}^{rec} (GeV/#it{c})", "hPtRecoPromptLcpKpi", "hf-task-lc-mc/hPtRecSigPrompt", 2, 1, 0);
+ AddHistogram(vecHisLcMC, labelParticle + ", gen. prompt: #it{p}_{T}^{gen} (GeV/#it{c})", "hPtGenPromptLcpKpi", "hf-task-lc-mc/hPtGenPrompt", 2, 1, 0);
+ AddHistogram(vecHisLcMC, labelParticle + ", matched non-prompt: #it{p}_{T}^{rec} (GeV/#it{c})", "hPtRecoFeeddwLcpKpi", "hf-task-lc-mc/hPtRecSigNonPrompt", 2, 1, 0);
+ AddHistogram(vecHisLcMC, labelParticle + ", gen. non-prompt: #it{p}_{T}^{gen} (GeV/#it{c})", "hPtGenFeeddwLcpKpi", "hf-task-lc-mc/hPtGenNonPrompt", 2, 1, 0);
VecSpecHis vecHisJpsi;
AddHistogram(vecHisJpsi, "#it{p}_{T} prong 0 (GeV/#it{c})", "hPtJpsiDau0", "hf-task-jpsi/hptprong0", 2, 1, 0);
@@ -117,7 +134,7 @@ Int_t Compare(TString filerun3 = "AnalysisResults_O2.root", TString filerun1 = "
AddHistogram(vecHisJpsi, "d0 prong 1 (cm)", "hImpParJpsiDau1", "hf-task-jpsi/hd0Prong1", 2, 1, 0);
AddHistogram(vecHisJpsi, "decay length (cm)", "hDecLenJpsi", "hf-task-jpsi/hdeclength", 2, 1, 0);
AddHistogram(vecHisJpsi, "decay length XY (cm)", "hDecLenXYJpsi", "hf-task-jpsi/hdeclengthxy", 2, 1, 0);
- AddHistogram(vecHisJpsi, "cos. pointing angle", "hCosPointJpsi", "hf-task-jpsi/hCPA", 2, 1, 0);
+ AddHistogram(vecHisJpsi, "cos pointing angle", "hCosPointJpsi", "hf-task-jpsi/hCPA", 2, 1, 0);
AddHistogram(vecHisJpsi, "decay length error (cm)", "hDecLenErrJpsi", "hf-task-jpsi/hDecLenErr", 1, 1, 0);
AddHistogram(vecHisJpsi, "decay length XY error (cm)", "hDecLenXYErrJpsi", "hf-task-jpsi/hDecLenXYErr", 1, 1, 0);
@@ -125,21 +142,25 @@ Int_t Compare(TString filerun3 = "AnalysisResults_O2.root", TString filerun1 = "
std::vector> vecSpecVecSpec;
// Add vector specifications in the vector.
- if (options.Contains("tracks"))
+ if (options.Contains(" tracks "))
vecSpecVecSpec.push_back(std::make_tuple("tracks", vecHisTracks, 5, 3));
- if (options.Contains("skim"))
+ if (options.Contains(" skim "))
vecSpecVecSpec.push_back(std::make_tuple("skim", vecHisSkim, 5, 3));
- if (options.Contains("cand2"))
+ if (options.Contains(" cand2 "))
vecSpecVecSpec.push_back(std::make_tuple("cand2", vecHisCand2, 5, 3));
- if (options.Contains("cand3"))
+ if (options.Contains(" cand3 "))
vecSpecVecSpec.push_back(std::make_tuple("cand3", vecHisCand3, 5, 3));
- if (options.Contains("d0"))
+ if (options.Contains(" d0 "))
vecSpecVecSpec.push_back(std::make_tuple("d0", vecHisD0, 5, 3));
- if (options.Contains("dplus"))
- vecSpecVecSpec.push_back(std::make_tuple("dplus", vecHisDPlus, 6, 3));
- if (options.Contains("lc"))
+ if (options.Contains(" d0-mc "))
+ vecSpecVecSpec.push_back(std::make_tuple("d0-mc", vecHisD0MC, 2, 2));
+ if (options.Contains(" dplus "))
+ vecSpecVecSpec.push_back(std::make_tuple("dplus", vecHisDPlus, 5, 4));
+ if (options.Contains(" lc "))
vecSpecVecSpec.push_back(std::make_tuple("lc", vecHisLc, 5, 3));
- if (options.Contains("jpsi"))
+ if (options.Contains(" lc-mc "))
+ vecSpecVecSpec.push_back(std::make_tuple("lc-mc", vecHisLcMC, 2, 2));
+ if (options.Contains(" jpsi "))
vecSpecVecSpec.push_back(std::make_tuple("jpsi", vecHisJpsi, 5, 3));
// Histogram plot vertical margins
diff --git a/codeHF/MC_d0_eff_ref.pdf b/codeHF/MC_d0_eff_ref.pdf
index cab9a9cc..7816765a 100644
Binary files a/codeHF/MC_d0_eff_ref.pdf and b/codeHF/MC_d0_eff_ref.pdf differ
diff --git a/codeHF/MC_d0_pT_ref.pdf b/codeHF/MC_d0_pT_ref.pdf
index 02c9e3c8..050f4909 100644
Binary files a/codeHF/MC_d0_pT_ref.pdf and b/codeHF/MC_d0_pT_ref.pdf differ
diff --git a/codeHF/PlotEfficiency.C b/codeHF/PlotEfficiency.C
index 39677eea..876db6a9 100644
--- a/codeHF/PlotEfficiency.C
+++ b/codeHF/PlotEfficiency.C
@@ -10,17 +10,22 @@ Int_t PlotEfficiency(TString pathFile = "AnalysisResults.root", TString particle
gStyle->SetFrameFillColor(0);
// vertical margins of the pT spectra plot
- Float_t marginHigh = 0.05;
- Float_t marginLow = 0.05;
+ float marginHigh = 0.05;
+ float marginLow = 0.05;
bool logScaleH = true;
// vertical margins of the efficiency plot
- Float_t marginRHigh = 0.05;
- Float_t marginRLow = 0.05;
+ float marginRHigh = 0.05;
+ float marginRLow = 0.05;
bool logScaleR = false;
- Float_t yMin, yMax;
- Int_t nRec, nGen;
+ double yMin, yMax;
+ int nRec, nGen;
+ int colours[] = {1, 2, 4};
+ int markers[] = {24, 25, 46};
+
// binning
Int_t iNRebin = 4;
+ //Double_t* dRebin = nullptr;
+ //const Int_t NRebin = 1;
Double_t dRebin[] = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 8, 10};
const Int_t NRebin = sizeof(dRebin) / sizeof(dRebin[0]) - 1;
@@ -30,8 +35,9 @@ Int_t PlotEfficiency(TString pathFile = "AnalysisResults.root", TString particle
return 1;
}
+ // get list of particles
TObjArray* arrayParticle = 0;
- arrayParticle = particles.Tokenize("-");
+ arrayParticle = particles.Tokenize(" ");
TString particle = "";
// loop over particles
@@ -43,59 +49,166 @@ Int_t PlotEfficiency(TString pathFile = "AnalysisResults.root", TString particle
}
Printf("\nPlotting efficiency for: %s", particle.Data());
- TString histonameRec = Form("hf-task-%s-mc/hPtGenSig", particle.Data()); // Use hPtRecSig for reconstruction level pT.
- TH1F* hPtRec = (TH1F*)file->Get(histonameRec.Data());
- if (!hPtRec) {
- Printf("Error: Failed to load %s from %s", histonameRec.Data(), pathFile.Data());
+ TString outputDir = Form("hf-task-%s-mc", particle.Data()); // analysis output directory with histograms
+
+ // inclusive candidates
+ TString nameHistRec = outputDir + "/hPtRecSig"; // reconstruction level pT of matched candidates
+ //nameHistRec = outputDir + "/hPtGenSig"; // generator level pT of matched candidates (no pT smearing)
+ TString nameHistgen = outputDir + "/hPtGen"; // generator level pT of generated particles
+ TH1F* hPtRecIncl = (TH1F*)file->Get(nameHistRec.Data());
+ if (!hPtRecIncl) {
+ Printf("Error: Failed to load %s from %s", nameHistRec.Data(), pathFile.Data());
return 1;
}
-
- TString histonameGen = Form("hf-task-%s-mc/hPtGen", particle.Data());
- TH1F* hPtGen = (TH1F*)file->Get(histonameGen.Data());
- if (!hPtGen) {
- Printf("Error: Failed to load %s from %s", histonameGen.Data(), pathFile.Data());
+ TH1F* hPtGenIncl = (TH1F*)file->Get(nameHistgen.Data());
+ if (!hPtGenIncl) {
+ Printf("Error: Failed to load %s from %s", nameHistgen.Data(), pathFile.Data());
return 1;
}
+ // prompt candidates
+ bool okPrompt = true;
+ nameHistRec = outputDir + "/hPtRecSigPrompt";
+ TH1F* hPtRecPrompt = (TH1F*)file->Get(nameHistRec.Data());
+ if (!hPtRecPrompt) {
+ Printf("Warning: Failed to load %s from %s", nameHistRec.Data(), pathFile.Data());
+ okPrompt = false;
+ }
+ nameHistgen = outputDir + "/hPtGenPrompt";
+ TH1F* hPtGenPrompt = (TH1F*)file->Get(nameHistgen.Data());
+ if (!hPtGenPrompt) {
+ Printf("Warning: Failed to load %s from %s", nameHistgen.Data(), pathFile.Data());
+ okPrompt = false;
+ }
+
+ // non-prompt candidates
+ bool okNonPrompt = true;
+ nameHistRec = outputDir + "/hPtRecSigNonPrompt";
+ TH1F* hPtRecNonPrompt = (TH1F*)file->Get(nameHistRec.Data());
+ if (!hPtRecNonPrompt) {
+ Printf("Warning: Failed to load %s from %s", nameHistRec.Data(), pathFile.Data());
+ okNonPrompt = false;
+ }
+ nameHistgen = outputDir + "/hPtGenNonPrompt";
+ TH1F* hPtGenNonPrompt = (TH1F*)file->Get(nameHistgen.Data());
+ if (!hPtGenNonPrompt) {
+ Printf("Warning: Failed to load %s from %s", nameHistgen.Data(), pathFile.Data());
+ okNonPrompt = false;
+ }
+
TCanvas* canPt = new TCanvas(Form("canPt_%s", particle.Data()), "Pt", 1200, 1000);
+ TLegend* legendPt = new TLegend(0.72, 0.72, 0.92, 0.92);
TCanvas* canEff = new TCanvas(Form("canEff_%s", particle.Data()), "Eff", 1200, 1000);
+ TLegend* legendEff = new TLegend(0.1, 0.72, 0.3, 0.92);
- nGen = hPtGen->GetEntries();
- nRec = hPtRec->GetEntries();
+ nGen = hPtGenIncl->GetEntries();
+ nRec = hPtRecIncl->GetEntries();
// pT spectra
- auto padH = canPt->cd();
- hPtGen->Rebin(iNRebin);
- hPtRec->Rebin(iNRebin);
- //hPtRec = (TH1F*)hPtRec->Rebin(NRebin, "hPtRecR", dRebin);
- //hPtGen = (TH1F*)hPtGen->Rebin(NRebin, "hPtGenR", dRebin);
- hPtGen->SetLineColor(1);
- hPtGen->SetLineWidth(2);
- hPtRec->SetLineColor(2);
- hPtRec->SetLineWidth(1);
- hPtGen->SetTitle(Form("Entries: Rec: %d, Gen: %d;#it{p}_{T} (GeV/#it{c});entries", nRec, nGen));
- hPtGen->GetYaxis()->SetMaxDigits(3);
- yMin = TMath::Min(hPtRec->GetMinimum(0), hPtGen->GetMinimum(0));
- yMax = TMath::Max(hPtRec->GetMaximum(), hPtGen->GetMaximum());
- SetHistogram(hPtGen, yMin, yMax, marginLow, marginHigh, logScaleH);
- SetPad(padH, logScaleH);
- hPtGen->Draw();
- hPtRec->Draw("same");
- TLegend* legend = new TLegend(0.72, 0.72, 0.92, 0.92);
- legend->AddEntry(hPtRec, "Rec", "L");
- legend->AddEntry(hPtGen, "Gen", "L");
- legend->Draw();
+ auto padPt = canPt->cd();
+ // inclusive
+ if (iNRebin > 1) {
+ hPtGenIncl->Rebin(iNRebin);
+ hPtRecIncl->Rebin(iNRebin);
+ } else if (NRebin > 1) {
+ hPtGenIncl = (TH1F*)hPtGenIncl->Rebin(NRebin, "hPtGenInclR", dRebin);
+ hPtRecIncl = (TH1F*)hPtRecIncl->Rebin(NRebin, "hPtRecInclR", dRebin);
+ }
+ yMin = std::min(hPtRecIncl->GetMinimum(0), hPtGenIncl->GetMinimum(0));
+ yMax = std::max(hPtRecIncl->GetMaximum(), hPtGenIncl->GetMaximum());
+ SetHistogramStyle(hPtGenIncl, colours[0], markers[0], 1.5, 2);
+ SetHistogramStyle(hPtRecIncl, colours[0], markers[0], 1.5, 2);
+ hPtGenIncl->SetTitle(Form("Entries: Rec: %d, Gen: %d;#it{p}_{T} (GeV/#it{c});entries", nRec, nGen));
+ hPtGenIncl->GetYaxis()->SetMaxDigits(3);
+ // prompt
+ if (okPrompt) {
+ if (iNRebin > 1) {
+ hPtGenPrompt->Rebin(iNRebin);
+ hPtRecPrompt->Rebin(iNRebin);
+ } else if (NRebin > 1) {
+ hPtGenPrompt = (TH1F*)hPtGenPrompt->Rebin(NRebin, "hPtGenPromptR", dRebin);
+ hPtRecPrompt = (TH1F*)hPtRecPrompt->Rebin(NRebin, "hPtRecPromptR", dRebin);
+ }
+ yMin = std::min({yMin, hPtRecPrompt->GetMinimum(0), hPtGenPrompt->GetMinimum(0)});
+ yMax = std::max({yMax, hPtRecPrompt->GetMaximum(), hPtGenPrompt->GetMaximum()});
+ SetHistogramStyle(hPtGenPrompt, colours[1], markers[1], 1.5, 2);
+ SetHistogramStyle(hPtRecPrompt, colours[1], markers[1], 1.5, 2);
+ }
+ // non-prompt
+ if (okNonPrompt) {
+ if (iNRebin > 1) {
+ hPtGenNonPrompt->Rebin(iNRebin);
+ hPtRecNonPrompt->Rebin(iNRebin);
+ } else if (NRebin > 1) {
+ hPtGenNonPrompt = (TH1F*)hPtGenNonPrompt->Rebin(NRebin, "hPtGenNonPromptR", dRebin);
+ hPtRecNonPrompt = (TH1F*)hPtRecNonPrompt->Rebin(NRebin, "hPtRecNonPromptR", dRebin);
+ }
+ yMin = std::min({yMin, hPtRecNonPrompt->GetMinimum(0), hPtGenNonPrompt->GetMinimum(0)});
+ yMax = std::max({yMax, hPtRecNonPrompt->GetMaximum(), hPtGenNonPrompt->GetMaximum()});
+ SetHistogramStyle(hPtGenNonPrompt, colours[2], markers[2], 1.5, 2);
+ SetHistogramStyle(hPtRecNonPrompt, colours[2], markers[2], 1.5, 2);
+ }
+ SetHistogram(hPtGenIncl, yMin, yMax, marginLow, marginHigh, logScaleH);
+ SetPad(padPt, logScaleH);
+ hPtGenIncl->Draw();
+ hPtRecIncl->Draw("same EP");
+ legendPt->AddEntry(hPtRecIncl, "inclusive rec", "P");
+ legendPt->AddEntry(hPtGenIncl, "inclusive gen", "L");
+ if (okPrompt) {
+ hPtGenPrompt->Draw("same");
+ hPtRecPrompt->Draw("same EP");
+ legendPt->AddEntry(hPtRecPrompt, "prompt rec", "P");
+ legendPt->AddEntry(hPtGenPrompt, "prompt gen", "L");
+ }
+ if (okNonPrompt) {
+ hPtGenNonPrompt->Draw("same");
+ hPtRecNonPrompt->Draw("same EP");
+ legendPt->AddEntry(hPtRecNonPrompt, "non-prompt rec", "P");
+ legendPt->AddEntry(hPtGenNonPrompt, "non-prompt gen", "L");
+ }
+ legendPt->Draw();
// efficiency
- auto padR = canEff->cd();
- TH1F* hEff = (TH1F*)hPtRec->Clone("hEff");
- hEff->Divide(hEff, hPtGen, 1., 1., "B");
- hEff->SetTitle(Form("Entries ratio: %g;#it{p}_{T} (GeV/#it{c});efficiency", (double)nRec / (double)nGen));
- yMin = hEff->GetMinimum(0);
- yMax = hEff->GetMaximum();
- SetHistogram(hEff, yMin, yMax, marginRLow, marginRHigh, logScaleR);
- SetPad(padR, logScaleR);
- hEff->Draw("PE");
+ auto padEff = canEff->cd();
+ TH1F* hEffIncl = nullptr;
+ TH1F* hEffPrompt = nullptr;
+ TH1F* hEffNonPrompt = nullptr;
+ // inclusive
+ hEffIncl = (TH1F*)hPtRecIncl->Clone("hEffIncl");
+ hEffIncl->Divide(hEffIncl, hPtGenIncl, 1., 1., "B");
+ yMin = hEffIncl->GetMinimum(0);
+ yMax = hEffIncl->GetMaximum();
+ SetHistogramStyle(hEffIncl, colours[0], markers[0], 1.5, 2);
+ hEffIncl->SetTitle(Form("Entries ratio: %g;#it{p}_{T} (GeV/#it{c});reconstruction efficiency", (double)nRec / (double)nGen));
+ // prompt
+ if (okPrompt) {
+ hEffPrompt = (TH1F*)hPtRecPrompt->Clone("hEffPrompt");
+ hEffPrompt->Divide(hPtRecPrompt, hPtGenPrompt, 1., 1., "B");
+ yMin = std::min(yMin, hEffPrompt->GetMinimum(0));
+ yMax = std::max(yMax, hEffPrompt->GetMaximum());
+ SetHistogramStyle(hEffPrompt, colours[1], markers[1], 1.5, 2);
+ }
+ // non-prompt
+ if (okNonPrompt) {
+ hEffNonPrompt = (TH1F*)hPtRecNonPrompt->Clone("hEffNonPrompt");
+ hEffNonPrompt->Divide(hPtRecNonPrompt, hPtGenNonPrompt, 1., 1., "B");
+ yMin = std::min(yMin, hEffNonPrompt->GetMinimum(0));
+ yMax = std::max(yMax, hEffNonPrompt->GetMaximum());
+ SetHistogramStyle(hEffNonPrompt, colours[2], markers[2], 1.5, 2);
+ }
+ SetHistogram(hEffIncl, yMin, yMax, marginRLow, marginRHigh, logScaleR);
+ SetPad(padEff, logScaleR);
+ hEffIncl->Draw("EP");
+ legendEff->AddEntry(hEffIncl, "inclusive", "P");
+ if (okPrompt) {
+ hEffPrompt->Draw("same EP");
+ legendEff->AddEntry(hEffPrompt, "prompt", "P");
+ }
+ if (okNonPrompt) {
+ hEffNonPrompt->Draw("same EP");
+ legendEff->AddEntry(hEffNonPrompt, "non-prompt", "P");
+ }
+ legendEff->Draw();
canPt->SaveAs(Form("MC_%s_pT.pdf", particle.Data()));
canEff->SaveAs(Form("MC_%s_eff.pdf", particle.Data()));
diff --git a/codeHF/RunHFTaskLocal.C b/codeHF/RunHFTaskLocal.C
index aefc7ef2..13970929 100644
--- a/codeHF/RunHFTaskLocal.C
+++ b/codeHF/RunHFTaskLocal.C
@@ -40,7 +40,7 @@ Long64_t RunHFTaskLocal(TString txtfile = "./list_ali.txt",
AliPhysicsSelectionTask* physSelTask = reinterpret_cast(gInterpreter->ProcessLine(Form(".x %s(%d)", gSystem->ExpandPathName("$ALICE_PHYSICS/OADB/macros/AddTaskPhysicsSelection.C"), isMC)));
- AliAnalysisTaskHFSimpleVertices* tasktr3 = reinterpret_cast(gInterpreter->ProcessLine(Form(".x %s(\"\",\"%s\")", gSystem->ExpandPathName("$ALICE_PHYSICS/PWGHF/vertexingHF/macros/AddTaskHFSimpleVertices.C"), jsonfilename.Data())));
+ AliAnalysisTaskHFSimpleVertices* tasktr3 = reinterpret_cast(gInterpreter->ProcessLine(Form(".x %s(\"\",\"%s\",%d)", gSystem->ExpandPathName("$ALICE_PHYSICS/PWGHF/vertexingHF/macros/AddTaskHFSimpleVertices.C"), jsonfilename.Data(), isMC)));
if (useO2Vertexer) {
tasktr3->SetUseO2Vertexer();
}
diff --git a/codeHF/clean.sh b/codeHF/clean.sh
index 7316819e..e8a6c872 100644
--- a/codeHF/clean.sh
+++ b/codeHF/clean.sh
@@ -9,14 +9,17 @@ comparison_histos_skim.pdf comparison_ratios_skim.pdf \
comparison_histos_cand2.pdf comparison_ratios_cand2.pdf \
comparison_histos_cand3.pdf comparison_ratios_cand3.pdf \
comparison_histos_d0.pdf comparison_ratios_d0.pdf \
+comparison_histos_d0-mc.pdf comparison_ratios_d0-mc.pdf \
comparison_histos_dplus.pdf comparison_ratios_dplus.pdf \
comparison_histos_lc.pdf comparison_ratios_lc.pdf \
+comparison_histos_lc-mc.pdf comparison_ratios_lc-mc.pdf \
comparison_histos_jpsi.pdf comparison_ratios_jpsi.pdf \
MC_d0_eff.pdf MC_d0_pT.pdf \
MC_dplus_eff.pdf MC_dplus_pT.pdf \
MC_lc_eff.pdf MC_lc_pT.pdf \
MC_xic_eff.pdf MC_xic_pT.pdf \
MC_jpsi_eff.pdf MC_jpsi_pT.pdf \
+MC_lc-tok0sP_eff.pdf MC_lc-tok0sP_pT.pdf \
./*.log \
output_* \
|| { echo "Error: Failed to delete files."; exit 1; }
diff --git a/codeHF/comparison_histos_cand2_ref.pdf b/codeHF/comparison_histos_cand2_ref.pdf
index facaf089..d4a05016 100644
Binary files a/codeHF/comparison_histos_cand2_ref.pdf and b/codeHF/comparison_histos_cand2_ref.pdf differ
diff --git a/codeHF/comparison_histos_d0_ref.pdf b/codeHF/comparison_histos_d0_ref.pdf
index 503f0fee..b6232c30 100644
Binary files a/codeHF/comparison_histos_d0_ref.pdf and b/codeHF/comparison_histos_d0_ref.pdf differ
diff --git a/codeHF/comparison_histos_skim_ref.pdf b/codeHF/comparison_histos_skim_ref.pdf
index 15aed5ee..4defa534 100644
Binary files a/codeHF/comparison_histos_skim_ref.pdf and b/codeHF/comparison_histos_skim_ref.pdf differ
diff --git a/codeHF/comparison_histos_tracks_ref.pdf b/codeHF/comparison_histos_tracks_ref.pdf
index ead033c2..a5e5fa34 100644
Binary files a/codeHF/comparison_histos_tracks_ref.pdf and b/codeHF/comparison_histos_tracks_ref.pdf differ
diff --git a/codeHF/config_tasks.sh b/codeHF/config_tasks.sh
index c7fbea3d..1fc131bd 100644
--- a/codeHF/config_tasks.sh
+++ b/codeHF/config_tasks.sh
@@ -28,10 +28,12 @@ DATABASE_O2="workflows.yml"
MAKE_GRAPH=0 # Make topology graph.
# Activation of O2 workflows
+# Event selection
+DOO2_EVSEL=0 # event-selection and timestamp
# QA
DOO2_REJ_ALICE3=1 # qa-rejection
DOO2_QA_EFF=0 # qa-efficiency
-DOO2_QA_SIM=0 # qa-simple
+DOO2_QA_EVTRK=0 # qa-event-track
DOO2_MC_VALID=0 # hf-mc-validation
# PID
DOO2_PID_TPC=0 # pid-tpc-full
@@ -41,6 +43,7 @@ DOO2_PID_TOF_QA=0 # pid-tof-qa-mc
DOO2_SKIM=0 # hf-track-index-skims-creator
DOO2_CAND_2PRONG=0 # hf-candidate-creator-2prong
DOO2_CAND_3PRONG=0 # hf-candidate-creator-3prong
+DOO2_CAND_CASC=0 # hf-candidate-creator-cascade
DOO2_CAND_X=0 # hf-candidate-creator-x
# Selectors
DOO2_SEL_D0=0 # hf-d0-candidate-selector
@@ -49,6 +52,7 @@ DOO2_SEL_LC=0 # hf-lc-candidate-selector
DOO2_SEL_XIC=0 # hf-xic-topkpi-candidate-selector
DOO2_SEL_JPSI=0 # hf-jpsi-candidate-selector
DOO2_SEL_X=0 # hf-xic-topkpi-candidate-selector
+DOO2_SEL_LCK0SP=0 # hf-lc-tok0sp-candidate-selector
# User tasks
DOO2_TASK_D0=0 # hf-task-d0
DOO2_TASK_DPLUS=0 # hf-task-dplus
@@ -57,6 +61,7 @@ DOO2_TASK_XIC=0 # hf-task-xic
DOO2_TASK_JPSI=1 # hf-task-jpsi
DOO2_TASK_BPLUS=0 # hf-task-bplus
DOO2_TASK_X=0 # hf-task-x
+DOO2_TASK_LCK0SP=0 # hf-task-lc-tok0sp
# Tree creators
DOO2_TREE_D0=0 # hf-tree-creator-d0-tokpi
DOO2_TREE_LC=0 # hf-tree-creator-lc-topkpi
@@ -68,6 +73,7 @@ APPLYCUTS_LC=0 # Apply Λc selection cuts.
APPLYCUTS_XIC=0 # Apply Ξc selection cuts.
APPLYCUTS_JPSI=1 # Apply J/ψ selection cuts.
APPLYCUTS_X=0 # Apply X selection cuts.
+APPLYCUTS_LCK0SP=0 # Apply Λc → K0S p selection cuts.
SAVETREES=0 # Save O2 tables to trees.
USEO2VERTEXER=0 # Use the O2 vertexer in AliPhysics.
@@ -84,6 +90,7 @@ function Clean {
[ "$1" -eq 2 ] && {
rm -f "$LISTFILES_ALI" "$LISTFILES_O2" "$SCRIPT_ALI" "$SCRIPT_O2" "$SCRIPT_POSTPROCESS" || ErrExit "Failed to rm created files."
[ "$JSON_EDIT" ] && { rm "$JSON_EDIT" || ErrExit "Failed to rm $JSON_EDIT."; }
+ [ "$DATABASE_O2_EDIT" ] && { rm "$DATABASE_O2_EDIT" || ErrExit "Failed to rm $DATABASE_O2_EDIT."; }
}
return 0
@@ -93,7 +100,7 @@ function Clean {
function AdjustJson {
# Make a copy of the default JSON file to modify it.
JSON_EDIT=""
- if [[ $APPLYCUTS_D0 -eq 1 || $APPLYCUTS_DPLUS -eq 1 || $APPLYCUTS_LC -eq 1 || $APPLYCUTS_XIC -eq 1 || $APPLYCUTS_JPSI -eq 1 || $APPLYCUTS_X -eq 1 ]]; then
+ if [[ $APPLYCUTS_D0 -eq 1 || $APPLYCUTS_DPLUS -eq 1 || $APPLYCUTS_LC -eq 1 || $APPLYCUTS_XIC -eq 1 || $APPLYCUTS_JPSI -eq 1 || $APPLYCUTS_X -eq 1 || $APPLYCUTS_LCK0SP -eq 1 ]]; then
JSON_EDIT="${JSON/.json/_edit.json}"
cp "$JSON" "$JSON_EDIT" || ErrExit "Failed to cp $JSON $JSON_EDIT."
JSON="$JSON_EDIT"
@@ -124,7 +131,7 @@ function AdjustJson {
ReplaceString "\"d_selectionFlagXic\": \"0\"" "\"d_selectionFlagXic\": \"1\"" "$JSON" || ErrExit "Failed to edit $JSON."
fi
- # Enable J/ψ selection.
+ # Enable J/ψ selection.
if [ $APPLYCUTS_JPSI -eq 1 ]; then
MsgWarn "\nUsing J/ψ selection cuts"
ReplaceString "\"d_selectionFlagJpsi\": \"0\"" "\"d_selectionFlagJpsi\": \"1\"" "$JSON" || ErrExit "Failed to edit $JSON."
@@ -135,27 +142,48 @@ function AdjustJson {
MsgWarn "\nUsing X(3872) selection cuts"
ReplaceString "\"d_selectionFlagX\": \"0\"" "\"d_selectionFlagX\": \"1\"" "$JSON" || ErrExit "Failed to edit $JSON."
fi
+ # Enable Λc → K0S p selection.
+ if [ $APPLYCUTS_LCK0SP -eq 1 ]; then
+ MsgWarn "\nUsing Λc → K0S p selection cuts"
+ ReplaceString "\"selectionFlagLcK0sp\": \"0\"" "\"selectionFlagLcK0sp\": \"1\"" "$JSON" || ErrExit "Failed to edit $JSON."
+ fi
}
# Generate the O2 script containing the full workflow specification.
function MakeScriptO2 {
+ # Enable cascade reconstruction in case of Λc → K0S p tasks
+ [[ $DOO2_CAND_CASC -eq 1 || $DOO2_SEL_LCK0SP -eq 1 || $DOO2_TASK_LCK0SP -eq 1 ]] && DOO2_CASC=1 || DOO2_CASC=0
+ # Cascade reconstruction
+ [ $DOO2_CASC -eq 1 ] && SUFFIX_CASC="-v0" || SUFFIX_CASC=""
+ # Event selection
+ [ $DOO2_EVSEL -eq 1 ] && SUFFIX_EVSEL="-evsel" || SUFFIX_EVSEL=""
+
WORKFLOWS=""
+ # QA
[ $DOO2_REJ_ALICE3 -eq 1 ] && WORKFLOWS+=" o2-analysis-qa-rejection"
[ $DOO2_QA_EFF -eq 1 ] && WORKFLOWS+=" o2-analysis-qa-efficiency"
- [ $DOO2_QA_SIM -eq 1 ] && WORKFLOWS+=" o2-analysis-qa-simple"
- [ $DOO2_SKIM -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-track-index-skims-creator"
- [ $DOO2_CAND_2PRONG -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-candidate-creator-2prong"
- [ $DOO2_CAND_3PRONG -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-candidate-creator-3prong"
- [ $DOO2_CAND_X -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-candidate-creator-x"
+ [ $DOO2_QA_EVTRK -eq 1 ] && WORKFLOWS+=" o2-analysis-qa-event-track"
+ [ $DOO2_MC_VALID -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-mc-validation"
+ # PID
[ $DOO2_PID_TPC -eq 1 ] && WORKFLOWS+=" o2-analysis-pid-tpc-full"
[ $DOO2_PID_TOF -eq 1 ] && WORKFLOWS+=" o2-analysis-pid-tof-full"
[ $DOO2_PID_TOF_QA -eq 1 ] && WORKFLOWS+=" o2-analysis-pid-tof-qa-mc"
+ # Vertexing
+ WF_SKIM="o2-analysis-hf-track-index-skims-creator${SUFFIX_EVSEL}${SUFFIX_CASC}"
+ [ $DOO2_SKIM -eq 1 ] && WORKFLOWS+=" $WF_SKIM"
+ [ $DOO2_CAND_2PRONG -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-candidate-creator-2prong"
+ [ $DOO2_CAND_3PRONG -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-candidate-creator-3prong"
+ [ $DOO2_CAND_X -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-candidate-creator-x"
+ [ $DOO2_CAND_CASC -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-candidate-creator-cascade"
+ # Selectors
[ $DOO2_SEL_D0 -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-d0-candidate-selector"
[ $DOO2_SEL_JPSI -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-jpsi-candidate-selector"
[ $DOO2_SEL_DPLUS -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-dplus-topikpi-candidate-selector"
[ $DOO2_SEL_LC -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-lc-candidate-selector"
[ $DOO2_SEL_XIC -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-xic-topkpi-candidate-selector"
[ $DOO2_SEL_X -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-x-tojpsipipi-candidate-selector"
+ [ $DOO2_SEL_LCK0SP -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-lc-tok0sp-candidate-selector"
+ # User tasks
[ $DOO2_TASK_D0 -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-task-d0"
[ $DOO2_TASK_JPSI -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-task-jpsi"
[ $DOO2_TASK_DPLUS -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-task-dplus"
@@ -163,9 +191,10 @@ function MakeScriptO2 {
[ $DOO2_TASK_XIC -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-task-xic"
[ $DOO2_TASK_BPLUS -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-task-bplus"
[ $DOO2_TASK_X -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-task-x"
+ [ $DOO2_TASK_LCK0SP -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-task-lc-tok0sp"
+ # Tree creators
[ $DOO2_TREE_D0 -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-tree-creator-d0-tokpi"
[ $DOO2_TREE_LC -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-tree-creator-lc-topkpi"
- [ $DOO2_MC_VALID -eq 1 ] && WORKFLOWS+=" o2-analysis-hf-mc-validation"
# Translate options into arguments of the generating script.
OPT_MAKECMD=""
@@ -174,6 +203,17 @@ function MakeScriptO2 {
[ $SAVETREES -eq 1 ] && OPT_MAKECMD+=" -t"
[ $MAKE_GRAPH -eq 1 ] && OPT_MAKECMD+=" -g"
+ # Make a copy of the default workflow database file before modifying it.
+ DATABASE_O2_EDIT=""
+ if [[ $DOO2_EVSEL -eq 1 || $DOO2_CASC -eq 1 ]]; then
+ DATABASE_O2_EDIT="${DATABASE_O2/.yml/_edit.yml}"
+ cp "$DATABASE_O2" "$DATABASE_O2_EDIT" || ErrExit "Failed to cp $DATABASE_O2 $DATABASE_O2_EDIT."
+ DATABASE_O2="$DATABASE_O2_EDIT"
+
+ # Adjust workflow database in case of event selection or cascades enabled.
+ ReplaceString "- o2-analysis-hf-track-index-skims-creator" "- $WF_SKIM" "$DATABASE_O2" || ErrExit "Failed to edit $DATABASE_O2."
+ fi
+
# Generate the O2 command.
MAKECMD="python3 $DIR_EXEC/make_command_o2.py $DATABASE_O2 $OPT_MAKECMD"
O2EXEC=$($MAKECMD -w "$WORKFLOWS")
@@ -185,8 +225,8 @@ function MakeScriptO2 {
#!/bin/bash
FileIn="\$1"
JSON="\$2"
-mkdir sockets && \
-$O2EXEC && \
+mkdir sockets && \\
+$O2EXEC && \\
rm -r sockets
EOF
}
@@ -206,25 +246,25 @@ function MakeScriptPostprocess {
# Compare AliPhysics and O2 histograms.
[[ $DOALI -eq 1 && $DOO2 -eq 1 ]] && {
OPT_COMPARE=""
- [ $DOO2_SKIM -eq 1 ] && OPT_COMPARE+="-tracks-skim"
- [ $DOO2_CAND_2PRONG -eq 1 ] && OPT_COMPARE+="-cand2"
- [ $DOO2_CAND_3PRONG -eq 1 ] && OPT_COMPARE+="-cand3"
- [ $DOO2_TASK_D0 -eq 1 ] && OPT_COMPARE+="-d0"
- [ $DOO2_TASK_DPLUS -eq 1 ] && OPT_COMPARE+="-dplus"
- [ $DOO2_TASK_LC -eq 1 ] && OPT_COMPARE+="-lc"
- [ $DOO2_TASK_XIC -eq 1 ] && OPT_COMPARE+="-xic"
- [ $DOO2_TASK_JPSI -eq 1 ] && OPT_COMPARE+="-jpsi"
+ [ $DOO2_SKIM -eq 1 ] && OPT_COMPARE+=" tracks skim "
+ [ $DOO2_CAND_2PRONG -eq 1 ] && OPT_COMPARE+=" cand2 "
+ [ $DOO2_CAND_3PRONG -eq 1 ] && OPT_COMPARE+=" cand3 "
+ [ $DOO2_TASK_D0 -eq 1 ] && { OPT_COMPARE+=" d0 "; [ "$ISMC" -eq 1 ] && OPT_COMPARE+=" d0-mc "; }
+ [ $DOO2_TASK_DPLUS -eq 1 ] && OPT_COMPARE+=" dplus "
+ [ $DOO2_TASK_LC -eq 1 ] && { OPT_COMPARE+=" lc "; [ "$ISMC" -eq 1 ] && OPT_COMPARE+=" lc-mc "; }
+ [ $DOO2_TASK_XIC -eq 1 ] && OPT_COMPARE+=" xic "
+ [ $DOO2_TASK_JPSI -eq 1 ] && OPT_COMPARE+=" jpsi "
[ "$OPT_COMPARE" ] && POSTEXEC+=" && root -b -q -l \"$DIR_TASKS/Compare.C(\\\"\$FileO2\\\", \\\"\$FileAli\\\", \\\"$OPT_COMPARE\\\", $DORATIO)\""
}
# Plot particle reconstruction efficiencies.
[[ $DOO2 -eq 1 && $ISMC -eq 1 ]] && {
PARTICLES=""
- [ $DOO2_TASK_D0 -eq 1 ] && PARTICLES+="-d0"
- [ $DOO2_TASK_DPLUS -eq 1 ] && PARTICLES+="-dplus"
- [ $DOO2_TASK_LC -eq 1 ] && PARTICLES+="-lc"
- [ $DOO2_TASK_XIC -eq 1 ] && PARTICLES+="-xic"
- [ $DOO2_TASK_JPSI -eq 1 ] && PARTICLES+="-jpsi"
- [ $DOO2_TASK_X -eq 1 ] && PARTICLES+="-x"
+ [ $DOO2_TASK_D0 -eq 1 ] && PARTICLES+=" d0 "
+ [ $DOO2_TASK_DPLUS -eq 1 ] && PARTICLES+=" dplus "
+ [ $DOO2_TASK_LC -eq 1 ] && PARTICLES+=" lc "
+ [ $DOO2_TASK_XIC -eq 1 ] && PARTICLES+=" xic "
+ [ $DOO2_TASK_JPSI -eq 1 ] && PARTICLES+=" jpsi "
+ [ $DOO2_TASK_LCK0SP -eq 1 ] && PARTICLES+=" lc-tok0sP "
[ "$PARTICLES" ] && POSTEXEC+=" && root -b -q -l \"$DIR_TASKS/PlotEfficiency.C(\\\"\$FileO2\\\", \\\"$PARTICLES\\\")\""
}
cat << EOF > "$SCRIPT_POSTPROCESS"
diff --git a/codeHF/dpl-config_run3.json b/codeHF/dpl-config_run3.json
index 1bd0895e..3afe3614 100644
--- a/codeHF/dpl-config_run3.json
+++ b/codeHF/dpl-config_run3.json
@@ -189,7 +189,40 @@
"d_pidTOFMaxpT": "-1.",
"d_TPCNClsFindablePIDCut": "50.",
"d_nSigmaTPC": "3.",
- "d_nSigmaTOF": "3."
+ "d_nSigmaTOF": "3.",
+ "pTBins": {
+ "values": [
+ "1.",
+ "2.",
+ "3.",
+ "4.",
+ "5.",
+ "6.",
+ "7.",
+ "8.",
+ "10.",
+ "12.",
+ "16.",
+ "24.",
+ "36."
+ ]
+ },
+ "DPlus_to_Pi_K_Pi_cuts": {
+ "values": [
+ ["0.2", "0.3", "0.3", "0.07", "6.", "0.96", "0.985", "2.5"],
+ ["0.2", "0.3", "0.3", "0.07", "5.", "0.96", "0.985", "2.5"],
+ ["0.2", "0.3", "0.3", "0.10", "5.", "0.96", "0.980", "2.5"],
+ ["0.2", "0.3", "0.3", "0.10", "5.", "0.96", "0.000", "2.5"],
+ ["0.2", "0.3", "0.3", "0.10", "5.", "0.96", "0.000", "2.5"],
+ ["0.2", "0.3", "0.3", "0.10", "5.", "0.96", "0.000", "2.5"],
+ ["0.2", "0.3", "0.3", "0.10", "5.", "0.96", "0.000", "2.5"],
+ ["0.2", "0.3", "0.3", "0.12", "5.", "0.96", "0.000", "2.5"],
+ ["0.2", "0.3", "0.3", "0.12", "5.", "0.96", "0.000", "2.5"],
+ ["0.2", "0.3", "0.3", "0.12", "5.", "0.96", "0.000", "2.5"],
+ ["0.2", "0.3", "0.3", "0.12", "5.", "0.96", "0.000", "2.5"],
+ ["0.2", "0.3", "0.3", "0.20", "5.", "0.94", "0.000", "2.5"]
+ ]
+ }
},
"hf-lc-candidate-selector": {
"d_pTCandMin": "0.",
diff --git a/codeHF/utils_plot.h b/codeHF/utils_plot.h
index 6500c28c..94f98bf3 100644
--- a/codeHF/utils_plot.h
+++ b/codeHF/utils_plot.h
@@ -34,3 +34,12 @@ void SetHistogram(TH1* his, Float_t yMin, Float_t yMax, Float_t marginLow, Float
his->GetYaxis()->SetRangeUser(yMin - marginLow / k * yRange, yMax + marginHigh / k * yRange);
}
}
+
+void SetHistogramStyle(TH1* his, Int_t colour = 1, Int_t markerStyle = 1, Float_t markerSize = 1, Float_t lineWidth = 1)
+{
+ his->SetLineColor(colour);
+ his->SetLineWidth(lineWidth);
+ his->SetMarkerColor(colour);
+ his->SetMarkerStyle(markerStyle);
+ his->SetMarkerSize(markerSize);
+}
diff --git a/codeHF/versions_ref.txt b/codeHF/versions_ref.txt
index b37a5d78..d859c446 100644
--- a/codeHF/versions_ref.txt
+++ b/codeHF/versions_ref.txt
@@ -1,4 +1,4 @@
-alidist: master 2021-02-03 22:10:18 +0100 c9b6c5a bump infologger (#2808)
-AliPhysics: master 2021-02-03 23:01:26 +0100 64ee243e1d Merge pull request #16821 from fjonasALICE/master
-O2: dev 2021-02-03 23:37:25 +0100 64d56ea416 Digits labels should be read via ConstMCTruthContainer
-Run 3 validation: master 2021-02-04 00:54:48 +0100 3938aed Update input cases.
+alidist: master 2021-06-19 20:37:59 +0200 a1f6ba0 Auto-update defaults-generators.sh and aligenerators.sh (#3116)
+AliPhysics: master 2021-06-20 14:53:55 +0200 58e2b8e609c8 Merge pull request #17961 from jokonig/master
+O2: dev 2021-06-21 00:54:13 +0200 e095f7dd17 Fix typo in PVertexer debris cleanup
+Run 3 validation: master 2021-06-20 23:38:45 +0200 bd90f03 Catch more O2 errors
diff --git a/codeHF/workflows.yml b/codeHF/workflows.yml
index 156cc5d4..245ff11a 100644
--- a/codeHF/workflows.yml
+++ b/codeHF/workflows.yml
@@ -1,20 +1,54 @@
+---
options:
global: "--fairmq-ipc-prefix sockets"
- local: ["--aod-memory-rate-limit 2000000000", "--shm-segment-size 16000000000", "--configuration json://$JSON", "-b"]
+ local:
+ - "-b"
+ - "--configuration json://$JSON"
+ - "--aod-memory-rate-limit 2000000000"
+ - "--shm-segment-size 16000000000"
+ - "--min-failure-level error"
workflows:
+ # Event selection
+
+ o2-analysis-timestamp:
+ options:
+ mc: "--isMC 1"
+
+ o2-analysis-event-selection:
+ options:
+ mc: "--isMC 1"
+
# Skimming
- o2-analysis-hf-track-index-skims-creator:
- activate: no
+ o2-analysis-hf-track-index-skims-creator: &skim_creator
+ executable: o2-analysis-hf-track-index-skims-creator
tables: [HFSELTRACK, HFTRACKIDXP2, HFTRACKIDXP3]
+ o2-analysis-hf-track-index-skims-creator-evsel:
+ <<: *skim_creator
+ dependencies: [o2-analysis-timestamp, o2-analysis-event-selection]
+ options: "--doEvSel"
+ tables: [HFSELCOL, HFSELTRACK, HFTRACKIDXP2, HFTRACKIDXP3]
+
+ o2-analysis-hf-track-index-skims-creator-v0:
+ <<: *skim_creator
+ dependencies: o2-analysis-lambdakzerobuilder
+ options: "--do-LcK0Sp"
+ tables: [HFSELTRACK, HFTRACKIDXCASC, HFTRACKIDXP2, HFTRACKIDXP3]
+
+ o2-analysis-hf-track-index-skims-creator-evsel-v0:
+ <<: *skim_creator
+ dependencies: [o2-analysis-timestamp, o2-analysis-event-selection, o2-analysis-lambdakzerobuilder]
+ options: ["--doEvSel", "--do-LcK0Sp"]
+ tables: [HFSELCOL, HFSELTRACK, HFTRACKIDXCASC, HFTRACKIDXP2, HFTRACKIDXP3]
+
# Candidate creators
o2-analysis-hf-candidate-creator-2prong: &cand_creator
- activate: no
- dependencies: [o2-analysis-hf-track-index-skims-creator]
+ dependencies:
+ - o2-analysis-hf-track-index-skims-creator
options:
mc: "--doMC"
tables:
@@ -23,99 +57,95 @@ workflows:
o2-analysis-hf-candidate-creator-3prong:
<<: *cand_creator
- activate: no
tables:
default: [HFCANDP3BASE, HFCANDP3EXT]
mc: [HFCANDP3MCREC, HFCANDP3MCGEN]
+ o2-analysis-hf-candidate-creator-cascade:
+ <<: *cand_creator
+ tables:
+ default: [HFCANDCASCBASE, HFCANDCASCEXT]
+ mc: [HFCANDCASCMCREC, HFCANDCASCMCGEN]
+
+ o2-analysis-hf-candidate-creator-x:
+ <<: *cand_creator
+ dependencies: o2-analysis-hf-jpsi-candidate-selector
+ tables:
+ default: [HFCANDXBASE, HFCANDXEXT]
+ mc: [HFCANDXMCREC, HFCANDXMCGEN]
+
# Selectors
o2-analysis-hf-d0-candidate-selector: &selector_2prong
- activate: no
dependencies: [o2-analysis-hf-candidate-creator-2prong, o2-analysis-pid-tpc-full, o2-analysis-pid-tof-full]
+ tables: HFSELD0CAND
o2-analysis-hf-jpsi-candidate-selector:
<<: *selector_2prong
- activate: no
tables: HFSELJPSICAND
o2-analysis-hf-dplus-topikpi-candidate-selector: &selector_3prong
- activate: no
dependencies: [o2-analysis-hf-candidate-creator-3prong, o2-analysis-pid-tpc-full, o2-analysis-pid-tof-full]
+ tables: HFSELDPLUSCAND
o2-analysis-hf-lc-candidate-selector:
<<: *selector_3prong
- activate: no
+ tables: HFSELLCCAND
o2-analysis-hf-xic-topkpi-candidate-selector:
<<: *selector_3prong
- activate: no
+ tables: HFSELXICCAND
- # Cascade candidate creators
-
- o2-analysis-hf-candidate-creator-x: &cand_creator_casc
- activate: no
- dependencies: [o2-analysis-hf-jpsi-candidate-selector]
- options:
- mc: "--doMC"
- tables:
- default: [HFCANDXBASE, HFCANDXEXT]
- mc: [HFCANDXMCREC, HFCANDXMCGEN]
+ o2-analysis-hf-lc-tok0sp-candidate-selector:
+ dependencies: [o2-analysis-hf-candidate-creator-cascade, o2-analysis-pid-tpc-full, o2-analysis-pid-tof-full]
+ tables: HFSELLCK0SPCAND
- # Cascade candidate selectors
-
- o2-analysis-hf-x-tojpsipipi-candidate-selector: &selector_casc
- activate: no
+ o2-analysis-hf-x-tojpsipipi-candidate-selector:
dependencies: [o2-analysis-hf-candidate-creator-x, o2-analysis-pid-tpc-full, o2-analysis-pid-tof-full]
# Analysis tasks
o2-analysis-hf-task-d0: &task
- activate: no
dependencies: o2-analysis-hf-d0-candidate-selector
options:
mc: "--doMC"
o2-analysis-hf-task-jpsi:
<<: *task
- activate: no
dependencies: o2-analysis-hf-jpsi-candidate-selector
o2-analysis-hf-task-dplus:
<<: *task
- activate: no
dependencies: o2-analysis-hf-dplus-topikpi-candidate-selector
o2-analysis-hf-task-lc:
<<: *task
- activate: no
dependencies: o2-analysis-hf-lc-candidate-selector
o2-analysis-hf-task-xic:
<<: *task
- activate: no
dependencies: o2-analysis-hf-xic-topkpi-candidate-selector
o2-analysis-hf-task-bplus:
<<: *task
- activate: no
dependencies: o2-analysis-hf-d0-candidate-selector
o2-analysis-hf-task-x:
<<: *task
- activate: no
dependencies: o2-analysis-hf-x-tojpsipipi-candidate-selector
+ o2-analysis-hf-task-lc-tok0sp:
+ <<: *task
+ dependencies: o2-analysis-hf-lc-tok0sp-candidate-selector
+
# Tree creators
o2-analysis-hf-tree-creator-d0-tokpi:
- activate: no
requires_mc: yes
dependencies: o2-analysis-hf-d0-candidate-selector
tables: [HFCANDP2Full, HFCANDP2FullE, HFCANDP2FullP]
o2-analysis-hf-tree-creator-lc-topkpi:
- activate: no
requires_mc: yes
dependencies: o2-analysis-hf-lc-candidate-selector
tables: [HFCANDP3Full, HFCANDP3FullE, HFCANDP3FullP]
@@ -123,36 +153,41 @@ workflows:
# QA
o2-analysis-qa-efficiency:
- activate: no
requires_mc: yes
options: "--eff-el 1 --eff-mu 1 --eff-pi 1 --eff-ka 1 --eff-pr 1"
- o2-analysis-qa-simple:
- activate: no
+ o2-analysis-qa-event-track:
requires_mc: yes
o2-analysis-qa-rejection:
- activate: no
requires_mc: yes
- dependencies: [o2-analysis-hf-track-index-skims-creator, o2-analysis-pid-tpc-full, o2-analysis-pid-tof-full]
+ dependencies:
+ - o2-analysis-hf-track-index-skims-creator
+ - o2-analysis-pid-tpc-full
+ - o2-analysis-pid-tof-full
o2-analysis-pid-tof-qa-mc:
- activate: no
requires_mc: yes
dependencies: [o2-analysis-pid-tof-full, o2-analysis-pid-tof-beta]
o2-analysis-hf-mc-validation:
- activate: no
requires_mc: yes
dependencies: o2-analysis-hf-d0-candidate-selector
# PID
- o2-analysis-pid-tpc-full:
- activate: no
+ o2-analysis-pid-tpc-full: {}
+
+ o2-analysis-pid-tof-full: {}
+
+ o2-analysis-pid-tof-beta: {}
+
+ # LF
+
+ o2-analysis-lambdakzerobuilder:
+ dependencies: [o2-analysis-trackextension, o2-analysis-weak-decay-indices]
+ options: "--v0radius 0.9"
- o2-analysis-pid-tof-full:
- activate: no
+ o2-analysis-trackextension: {}
- o2-analysis-pid-tof-beta:
- activate: no
+ o2-analysis-weak-decay-indices: {}
diff --git a/exec/batch_ali.sh b/exec/batch_ali.sh
index 072c1b6c..9bcbb4d6 100644
--- a/exec/batch_ali.sh
+++ b/exec/batch_ali.sh
@@ -27,13 +27,14 @@ JSON="$(realpath "$JSON")"
LogFile="log_ali.log"
ListIn="list_ali.txt"
FilesToMerge="ListOutToMergeAli.txt"
-DirBase="$PWD"
IndexFile=0
-ListRunScripts="$DirBase/ListRunScriptsAli.txt"
+IndexJob=0
DirOutMain="output_ali"
+CMDPARALLEL="cd \"$DirOutMain/{}\" && bash \"$DIR_THIS/run_ali.sh\" \"$SCRIPT\" \"$ListIn\" \"$JSON\" \"$LogFile\""
+
# Clean before running.
-rm -rf "$ListRunScripts" "$FilesToMerge" "$FILEOUT" "$DirOutMain" || ErrExit "Failed to delete output files."
+rm -rf "$FilesToMerge" "$FILEOUT" "$DirOutMain" || ErrExit "Failed to delete output files."
CheckFile "$LISTINPUT"
echo "Output directory: $DirOutMain (logfiles: $LogFile)"
@@ -46,30 +47,25 @@ while read -r FileIn; do
# New job
if [ $((IndexFile % NFILESPERJOB)) -eq 0 ]; then
mkdir -p $DirOut || ErrExit "Failed to mkdir $DirOut."
- FileOut="$DirOut/$FILEOUT"
- echo "$FileOut" >> "$DirBase/$FilesToMerge" || ErrExit "Failed to echo to $DirBase/$FilesToMerge."
- # Add this job in the list of commands.
- echo "cd \"$DirOut\" && bash \"$DIR_THIS/run_ali.sh\" \"$SCRIPT\" \"$ListIn\" \"$JSON\" \"$LogFile\"" >> "$ListRunScripts" || ErrExit "Failed to echo to $ListRunScripts."
+ echo "$DirOut/$FILEOUT" >> "$FilesToMerge" || ErrExit "Failed to echo to $FilesToMerge."
fi
echo "$FileIn" >> "$DirOut/$ListIn" || ErrExit "Failed to echo to $DirOut/$ListIn."
[ "$DEBUG" -eq 1 ] && echo "Input file ($IndexFile, job $IndexJob): $FileIn"
- ((IndexFile+=1))
+ ((IndexFile++))
done < "$LISTINPUT"
-CheckFile "$ListRunScripts"
-echo "Running AliPhysics jobs... ($(wc -l < "$ListRunScripts") jobs, $NFILESPERJOB files/job)"
+echo "Running AliPhysics jobs... ($((IndexJob+1)) jobs, $NFILESPERJOB files/job)"
OPT_PARALLEL="--halt soon,fail=100%"
if [ "$DEBUG" -eq 0 ]; then
# shellcheck disable=SC2086 # Ignore unquoted options.
- parallel $OPT_PARALLEL < "$ListRunScripts" > $LogFile 2>&1
+ parallel $OPT_PARALLEL "$CMDPARALLEL" ::: $(seq 0 $IndexJob) > $LogFile 2>&1
else
# shellcheck disable=SC2086 # Ignore unquoted options.
- parallel $OPT_PARALLEL --will-cite --progress < "$ListRunScripts" > $LogFile
+ parallel $OPT_PARALLEL --will-cite --progress "$CMDPARALLEL" ::: $(seq 0 $IndexJob) > $LogFile
fi || ErrExit "\nCheck $(realpath $LogFile)"
grep -q -e '^'"W-" -e '^'"Warning" "$LogFile" && MsgWarn "There were warnings!\nCheck $(realpath $LogFile)"
grep -q -e '^'"E-" -e '^'"Error" "$LogFile" && MsgErr "There were errors!\nCheck $(realpath $LogFile)"
grep -q -e '^'"F-" -e '^'"Fatal" -e "segmentation" "$LogFile" && ErrExit "There were fatal errors!\nCheck $(realpath $LogFile)"
-rm -f "$ListRunScripts" || ErrExit "Failed to rm $ListRunScripts."
echo "Merging output files... (output file: $FILEOUT, logfile: $LogFile)"
hadd "$FILEOUT" @"$FilesToMerge" >> $LogFile 2>&1 || \
diff --git a/exec/batch_convert.sh b/exec/batch_convert.sh
index b67f616e..1ce7b273 100644
--- a/exec/batch_convert.sh
+++ b/exec/batch_convert.sh
@@ -21,13 +21,14 @@ source "$DIR_THIS/utilities.sh" || { echo "Error: Failed to load utilities."; ex
LogFile="log_convert.log"
ListIn="list_convert.txt"
-DirBase="$PWD"
IndexFile=0
-ListRunScripts="$DirBase/ListRunScriptsConversion.txt"
+IndexJob=0
DirOutMain="output_conversion"
+CMDPARALLEL="cd \"$DirOutMain/{}\" && bash \"$DIR_THIS/run_convert.sh\" \"$ListIn\" $ISMC \"$LogFile\""
+
# Clean before running.
-rm -rf "$ListRunScripts" "$LISTOUTPUT" "$DirOutMain" || ErrExit "Failed to delete output files."
+rm -rf "$LISTOUTPUT" "$DirOutMain" || ErrExit "Failed to delete output files."
CheckFile "$LISTINPUT"
echo "Output directory: $DirOutMain (logfiles: $LogFile)"
@@ -40,29 +41,24 @@ while read -r FileIn; do
# New job
if [ $((IndexFile % NFILESPERJOB)) -eq 0 ]; then
mkdir -p $DirOut || ErrExit "Failed to mkdir $DirOut."
- FileOut="$DirOut/$FILEOUT"
- echo "$DirBase/$FileOut" >> "$DirBase/$LISTOUTPUT" || ErrExit "Failed to echo to $DirBase/$LISTOUTPUT."
- # Add this job in the list of commands.
- echo "cd \"$DirOut\" && bash \"$DIR_THIS/run_convert.sh\" \"$ListIn\" $ISMC \"$LogFile\"" >> "$ListRunScripts" || ErrExit "Failed to echo to $ListRunScripts."
+ echo "$DirOut/$FILEOUT" >> "$LISTOUTPUT" || ErrExit "Failed to echo to $LISTOUTPUT."
fi
echo "$FileIn" >> "$DirOut/$ListIn" || ErrExit "Failed to echo to $DirOut/$ListIn."
[ "$DEBUG" -eq 1 ] && echo "Input file ($IndexFile, job $IndexJob): $FileIn"
- ((IndexFile+=1))
+ ((IndexFile++))
done < "$LISTINPUT"
-CheckFile "$ListRunScripts"
-echo "Running conversion jobs... ($(wc -l < "$ListRunScripts") jobs, $NFILESPERJOB files/job)"
+echo "Running conversion jobs... ($((IndexJob+1)) jobs, $NFILESPERJOB files/job)"
OPT_PARALLEL="--halt soon,fail=100%"
if [ "$DEBUG" -eq 0 ]; then
# shellcheck disable=SC2086 # Ignore unquoted options.
- parallel $OPT_PARALLEL < "$ListRunScripts" > $LogFile 2>&1
+ parallel $OPT_PARALLEL "$CMDPARALLEL" ::: $(seq 0 $IndexJob) > $LogFile 2>&1
else
# shellcheck disable=SC2086 # Ignore unquoted options.
- parallel $OPT_PARALLEL --will-cite --progress < "$ListRunScripts" > $LogFile
+ parallel $OPT_PARALLEL --will-cite --progress "$CMDPARALLEL" ::: $(seq 0 $IndexJob) > $LogFile
fi || ErrExit "\nCheck $(realpath $LogFile)"
grep -q -e '^'"W-" -e '^'"Warning" "$LogFile" && MsgWarn "There were warnings!\nCheck $(realpath $LogFile)"
grep -q -e '^'"E-" -e '^'"Error" "$LogFile" && MsgErr "There were errors!\nCheck $(realpath $LogFile)"
grep -q -e '^'"F-" -e '^'"Fatal" -e "segmentation" "$LogFile" && ErrExit "There were fatal errors!\nCheck $(realpath $LogFile)"
-rm -f "$ListRunScripts" || ErrExit "Failed to rm $ListRunScripts."
exit 0
diff --git a/exec/batch_o2.sh b/exec/batch_o2.sh
index 8c66831e..b253a298 100644
--- a/exec/batch_o2.sh
+++ b/exec/batch_o2.sh
@@ -29,13 +29,14 @@ LogFile="log_o2.log"
ListIn="list_o2.txt"
FilesToMerge="ListOutToMergeO2.txt"
FilesToMergeTree="ListOutToMergeO2Tree.txt"
-DirBase="$PWD"
IndexFile=0
-ListRunScripts="$DirBase/ListRunScriptsO2.txt"
+IndexJob=0
DirOutMain="output_o2"
+CMDPARALLEL="cd \"$DirOutMain/{}\" && bash \"$DIR_THIS/run_o2.sh\" \"$SCRIPT\" \"$ListIn\" \"$JSON\" \"$LogFile\""
+
# Clean before running.
-rm -rf "$ListRunScripts" "$FilesToMerge" "$FilesToMergeTree" "$FILEOUT" "$FILEOUT_TREE" "$DirOutMain" || ErrExit "Failed to delete output files."
+rm -rf "$FilesToMerge" "$FilesToMergeTree" "$FILEOUT" "$FILEOUT_TREE" "$DirOutMain" || ErrExit "Failed to delete output files."
CheckFile "$LISTINPUT"
echo "Output directory: $DirOutMain (logfiles: $LogFile)"
@@ -48,33 +49,26 @@ while read -r FileIn; do
# New job
if [ $((IndexFile % NFILESPERJOB)) -eq 0 ]; then
mkdir -p $DirOut || ErrExit "Failed to mkdir $DirOut."
- FileOut="$DirOut/$FILEOUT"
- echo "$FileOut" >> "$DirBase/$FilesToMerge" || ErrExit "Failed to echo to $DirBase/$FilesToMerge."
- [ "$FILEOUT_TREE" ] && {
- FileOutTree="$DirOut/$FILEOUT_TREE"
- echo "$FileOutTree" >> "$DirBase/$FilesToMergeTree" || ErrExit "Failed to echo to $DirBase/$FilesToMergeTree."
- }
- # Add this job in the list of commands.
- echo "cd \"$DirOut\" && bash \"$DIR_THIS/run_o2.sh\" \"$SCRIPT\" \"$ListIn\" \"$JSON\" \"$LogFile\"" >> "$ListRunScripts" || ErrExit "Failed to echo to $ListRunScripts."
+ echo "$DirOut/$FILEOUT" >> "$FilesToMerge" || ErrExit "Failed to echo to $FilesToMerge."
+ [ "$FILEOUT_TREE" ] && \
+ { echo "$DirOut/$FILEOUT_TREE" >> "$FilesToMergeTree" || ErrExit "Failed to echo to $FilesToMergeTree."; }
fi
echo "$FileIn" >> "$DirOut/$ListIn" || ErrExit "Failed to echo to $DirOut/$ListIn."
[ "$DEBUG" -eq 1 ] && echo "Input file ($IndexFile, job $IndexJob): $FileIn"
- ((IndexFile+=1))
+ ((IndexFile++))
done < "$LISTINPUT"
-CheckFile "$ListRunScripts"
-echo "Running O2 jobs... ($(wc -l < "$ListRunScripts") jobs, $NJOBSPARALLEL parallel, $NFILESPERJOB files/job)"
+echo "Running O2 jobs... ($((IndexJob+1)) jobs, $NJOBSPARALLEL parallel, $NFILESPERJOB files/job)"
OPT_PARALLEL="--halt soon,fail=100% --jobs $NJOBSPARALLEL"
if [ "$DEBUG" -eq 0 ]; then
# shellcheck disable=SC2086 # Ignore unquoted options.
- parallel $OPT_PARALLEL < "$ListRunScripts" > $LogFile 2>&1
+ parallel $OPT_PARALLEL "$CMDPARALLEL" ::: $(seq 0 $IndexJob) > $LogFile 2>&1
else
# shellcheck disable=SC2086 # Ignore unquoted options.
- parallel $OPT_PARALLEL --will-cite --progress < "$ListRunScripts" > $LogFile
+ parallel $OPT_PARALLEL --will-cite --progress "$CMDPARALLEL" ::: $(seq 0 $IndexJob) > $LogFile
fi || ErrExit "\nCheck $(realpath $LogFile)"
grep -q "\\[WARN\\]" "$LogFile" && MsgWarn "There were warnings!\nCheck $(realpath $LogFile)"
grep -q -e "\\[ERROR\\]" -e "segmentation" "$LogFile" && MsgErr "There were errors!\nCheck $(realpath $LogFile)"
-rm -f "$ListRunScripts" || ErrExit "Failed to rm $ListRunScripts."
echo "Merging output files... (output file: $FILEOUT, logfile: $LogFile)"
hadd $FILEOUT @"$FilesToMerge" >> $LogFile 2>&1 || \
diff --git a/exec/check_spaces.sh b/exec/check_spaces.sh
index 39ca7678..654ba83a 100644
--- a/exec/check_spaces.sh
+++ b/exec/check_spaces.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Find tabs in text files
+# Find tabs and trailing whitespaces in text files
# This directory
DIR_THIS="$(dirname "$(realpath "$0")")"
diff --git a/exec/make_command_o2.py b/exec/make_command_o2.py
index 8cfeeb93..bcfe1290 100644
--- a/exec/make_command_o2.py
+++ b/exec/make_command_o2.py
@@ -88,20 +88,15 @@ def healthy_structure(dic_full: dict):
if not isinstance(dic_wf, dict):
msg_err('"workflows" is not a dictionary.')
return False
- # Check mandatory workflow keys.
+ # Check workflow keys.
for wf in dic_wf:
dic_wf_single = dic_wf[wf]
if not isinstance(dic_wf_single, dict):
msg_err("%s is not a dictionary." % wf)
return False
- good = True
- for key in ["activate"]:
- if key not in dic_wf_single:
- msg_err('Key "%s" not found in workflow %s.' % (key, wf))
- good = False
- if not good:
- return False
- if not isinstance(dic_wf_single["activate"], bool):
+ if "activate" in dic_wf_single and not isinstance(
+ dic_wf_single["activate"], bool
+ ):
msg_err('"activate" in workflow %s is not a boolean.' % wf)
return False
return True
@@ -123,7 +118,7 @@ def activate_workflow(wf: str, dic_wf: dict, mc=False, level=0, debug=False):
dic_wf_single["activate"] = False
return
# Activate.
- if not dic_wf_single["activate"]:
+ if "activate" not in dic_wf_single or not dic_wf_single["activate"]:
dic_wf_single["activate"] = True
# Activate dependencies recursively.
if "dependencies" in dic_wf_single:
@@ -197,11 +192,13 @@ def main():
# Get list of primary workflows to run.
# already activated in the database
- list_wf_activated = [wf for wf in dic_wf if dic_wf[wf]["activate"]]
+ list_wf_activated = [
+ wf for wf in dic_wf if "activate" in dic_wf[wf] and dic_wf[wf]["activate"]
+ ]
if debug and list_wf_activated:
eprint("\nWorkflows activated in the database:")
eprint("\n".join(" " + wf for wf in list_wf_activated))
- # requested at command line
+ # requested on command line
if workflows_add:
if debug:
eprint("\nWorkflows specified on command line:")
@@ -223,7 +220,7 @@ def main():
if save_tables:
tables = [] # list of all tables of activated workflows
for wf, dic_wf_single in dic_wf.items():
- if not dic_wf_single["activate"]:
+ if "activate" not in dic_wf_single or not dic_wf_single["activate"]:
continue
if "tables" not in dic_wf_single:
continue
@@ -233,6 +230,8 @@ def main():
elif isinstance(tab_wf, dict):
if "default" in tab_wf:
join_to_list(tab_wf["default"], tables)
+ if not mc_mode and "real" in tab_wf:
+ join_to_list(tab_wf["real"], tables)
if mc_mode and "mc" in tab_wf:
join_to_list(tab_wf["mc"], tables)
else:
@@ -251,11 +250,23 @@ def main():
command = ""
eprint("\nActivated workflows:")
for wf, dic_wf_single in dic_wf.items():
- if not dic_wf_single["activate"]:
+ if "activate" not in dic_wf_single or not dic_wf_single["activate"]:
continue
msg_bold(" " + wf)
- string_wf = wf
- # Process options
+ # Determine the workflow executable.
+ if "executable" in dic_wf_single:
+ exec_wf = dic_wf_single["executable"]
+ if not isinstance(exec_wf, str):
+ msg_err('"executable" in %s must be str, is %s' % (wf, type(exec_wf)))
+ sys.exit(1)
+ string_wf = exec_wf
+ else:
+ string_wf = wf
+ # Detect duplicate workflows.
+ if string_wf + " " in command:
+ msg_err("Workflow %s is already present." % string_wf)
+ sys.exit(1)
+ # Process options.
if "options" in dic_wf_single:
opt_wf = dic_wf_single["options"]
if isinstance(opt_wf, (str, list)):
@@ -263,6 +274,8 @@ def main():
elif isinstance(opt_wf, dict):
if "default" in opt_wf:
string_wf += " " + join_strings(opt_wf["default"])
+ if not mc_mode and "real" in opt_wf:
+ string_wf += " " + join_strings(opt_wf["real"])
if mc_mode and "mc" in opt_wf:
string_wf += " " + join_strings(opt_wf["mc"])
else:
@@ -273,12 +286,12 @@ def main():
sys.exit(1)
if opt_local:
string_wf += " " + opt_local
- command += " | " + string_wf
+ command += "| \\\n" + string_wf + " "
if not command:
msg_err("Nothing to do!")
sys.exit(1)
- # Remove the leading " | ".
- command = command[3:]
+ # Remove the leading "| \\\n".
+ command = command[4:]
# Append global options.
if opt_global:
command += " " + opt_global
@@ -299,11 +312,11 @@ def main():
dot += " ranksep=2 // vertical node separation\n"
dot += ' node [shape=box, style="filled,rounded", fillcolor=papayawhip, fontname=Courier, fontsize=20]\n'
for wf, dic_wf_single in dic_wf.items():
- if not dic_wf_single["activate"]:
+ if "activate" not in dic_wf_single or not dic_wf_single["activate"]:
continue
- # hyphens are not allowed in node names
+ # Hyphens are not allowed in node names.
node_wf = wf.replace("-", "_")
- # replace hyphens with line breaks to save horizontal space
+ # Replace hyphens with line breaks to save horizontal space.
label_wf = wf.replace("-", "\\n")
dot += ' %s [label="%s"]\n' % (node_wf, label_wf)
if "dependencies" in dic_wf_single:
diff --git a/exec/run_o2.sh b/exec/run_o2.sh
index ca690ffe..5d8090a9 100644
--- a/exec/run_o2.sh
+++ b/exec/run_o2.sh
@@ -10,6 +10,6 @@ bash "$SCRIPT" "$FILEIN" "$JSON" > "$LOGFILE" 2>&1
ExitCode=$?
# Show warnings and errors in the log file.
-grep -e "\\[WARN\\]" -e "\\[ERROR\\]" -e "segmentation" "$LOGFILE" | sort -u
+grep -e "\\[WARN\\]" -e "\\[ERROR\\]" -e "\\[FATAL\\]" -e "segmentation" -e "command not found" -e "Error:" "$LOGFILE" | sort -u
exit $ExitCode
diff --git a/exec/runtest.sh b/exec/runtest.sh
index e4dc5303..c73f223f 100644
--- a/exec/runtest.sh
+++ b/exec/runtest.sh
@@ -59,8 +59,7 @@ FILEOUT_TREES_O2="AnalysisResults_trees_O2.root"
# Steering commands
ENVALI="alienv setenv AliPhysics/latest -c"
ENVO2="alienv setenv O2/latest -c"
-#ENVALIO2="alienv setenv AliPhysics/latest,O2/latest -c"
-ENVPOST="$ENVALI"
+ENVPOST="alienv setenv ROOT/latest -c"
# Step scripts
SCRIPT_O2="script_o2.sh"
@@ -158,8 +157,6 @@ if [ $DOALI -eq 1 ]; then
[ "$O2_ROOT" ] && { MsgWarn "O2 environment is loaded - expect errors!"; }
[ "$ALICE_PHYSICS" ] && { MsgWarn "AliPhysics environment is already loaded."; ENVALI=""; }
$ENVALI bash "$DIR_EXEC/batch_ali.sh" "$LISTFILES_ALI" "$JSON" "$SCRIPT_ALI" $DEBUG "$NFILESPERJOB_ALI" || exit 1
- # Run the batch script in the ALI+O2 environment.
- #$ENVALIO2 bash "$DIR_EXEC/batch_ali.sh" $LISTFILES_ALI $JSON $SCRIPT_ALI $DEBUG || exit 1
mv "$FILEOUT" "$FILEOUT_ALI" || ErrExit "Failed to mv $FILEOUT $FILEOUT_ALI."
fi
@@ -189,10 +186,9 @@ if [ $DOPOSTPROCESS -eq 1 ]; then
MsgStep "Postprocessing... (logfile: $LogFile)"
MakeScriptPostprocess || ErrExit "MakeScriptPostprocess failed."
CheckFile "$SCRIPT_POSTPROCESS"
- [ $DEBUG -eq 1 ] && echo "Loading AliPhysics..."
+ [ $DEBUG -eq 1 ] && echo "Loading ROOT..."
# Run the batch script in the postprocessing environment.
- [ "$O2_ROOT" ] && { MsgWarn "O2 environment is loaded - expect errors!"; }
- [ "$ALICE_PHYSICS" ] && { MsgWarn "AliPhysics environment is already loaded."; ENVALI=""; }
+ [ "$ROOTSYS" ] && { MsgWarn "ROOT environment is already loaded."; ENVPOST=""; }
$ENVPOST bash "$SCRIPT_POSTPROCESS" "$FILEOUT_O2" "$FILEOUT_ALI" > $LogFile 2>&1 || ErrExit "\nCheck $(realpath $LogFile)"
grep -q -e '^'"W-" -e '^'"Warning" -e "warning" "$LogFile" && MsgWarn "There were warnings!\nCheck $(realpath $LogFile)"
grep -q -e '^'"E-" -e '^'"Error" "$LogFile" && MsgErr "There were errors!\nCheck $(realpath $LogFile)"