Skip to content

Commit 36c3698

Browse files
Merge branch 'AliceO2Group:master' into master
2 parents faf8b2a + eb44a5c commit 36c3698

229 files changed

Lines changed: 18938 additions & 6631 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/labeler.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ infrastructure:
2323
- 'packaging/**'
2424
- 'pyproject.toml'
2525

26+
datamodel:
27+
- changed-files:
28+
- any-glob-to-any-file: ['DataModel/**', '*/DataModel/**']
29+
2630
dpg:
2731
- changed-files:
2832
- any-glob-to-any-file: ['DPG/**']

CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
/Common/CCDB @alibuild @jgrosseo @iarsene @ekryshen @ddobrigk
1616
/Common/Tools/Multiplicity @alibuild @ddobrigk @victor-gonzalez
1717
/ALICE3 @alibuild @njacazio @hscheid
18-
/DPG @alibuild @chiarazampolli @noferini
18+
/DPG @alibuild @chiarazampolli @alcaliva @catalinristea
1919
/DPG/Tasks/AOTEvent @alibuild @ekryshen @strogolo @altsybee
2020
/DPG/Tasks/AOTTrack @alibuild @mfaggin @iouribelikov @njacazio
2121
/DPG/Tasks/TOF @alibuild @noferini @njacazio

Common/Core/PID/PIDTOF.h

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,19 @@
2828
#include "TMath.h"
2929
#include "TGraph.h"
3030
#include "TFile.h"
31+
#include "TF2.h"
3132

3233
// O2 includes
3334
#include "DataFormatsTOF/ParameterContainers.h"
3435
#include "Framework/Logger.h"
3536
#include "ReconstructionDataFormats/PID.h"
3637
#include "Framework/DataTypes.h"
38+
#include "CommonConstants/PhysicsConstants.h"
3739

3840
namespace o2::pid::tof
3941
{
4042

41-
// Utility values
43+
// Utility values (to remove!)
4244
static constexpr float kCSPEED = TMath::C() * 1.0e2f * 1.0e-12f; /// Speed of light in TOF units (cm/ps)
4345
static constexpr float kCSPEDDInv = 1.f / kCSPEED; /// Inverse of the Speed of light in TOF units (ps/cm)
4446
static constexpr float defaultReturnValue = -999.f; /// Default return value in case TOF measurement is not available
@@ -55,7 +57,7 @@ class Beta
5557
/// \param length Length in cm of the track
5658
/// \param tofSignal TOF signal in ps for the track
5759
/// \param collisionTime collision time in ps for the event of the track
58-
static float GetBeta(const float length, const float tofSignal, const float collisionTime) { return length / (tofSignal - collisionTime) * kCSPEDDInv; }
60+
static float GetBeta(const float length, const float tofSignal, const float collisionTime) { return length / (tofSignal - collisionTime) * o2::constants::physics::invLightSpeedCm2PS; }
5961

6062
/// Gets the beta for the track of interest
6163
/// \param track Track of interest
@@ -139,6 +141,11 @@ class TOFResoParamsV2 : public o2::tof::Parameters<13>
139141

140142
~TOFResoParamsV2() = default;
141143

144+
template <o2::track::PID::ID pid>
145+
float getResolution(const float, const float) const
146+
{
147+
return -1.f;
148+
}
142149
// Momentum shift for charge calibration
143150
void setMomentumChargeShiftParameters(std::unordered_map<std::string, float> const& pars)
144151
{
@@ -254,14 +261,12 @@ class TOFResoParamsV2 : public o2::tof::Parameters<13>
254261
class TOFResoParamsV3 : public o2::tof::Parameters<13>
255262
{
256263
public:
257-
TOFResoParamsV3() : Parameters(std::array<std::string, 13>{"TrkRes.Pi.P0", "TrkRes.Pi.P1", "TrkRes.Pi.P2", "TrkRes.Pi.P3", "time_resolution",
258-
"TrkRes.Ka.P0", "TrkRes.Ka.P1", "TrkRes.Ka.P2", "TrkRes.Ka.P3",
259-
"TrkRes.Pr.P0", "TrkRes.Pr.P1", "TrkRes.Pr.P2", "TrkRes.Pr.P3"},
264+
TOFResoParamsV3() : Parameters(std::array<std::string, 13>{"time_resolution", "time_resolution", "time_resolution", "time_resolution", "time_resolution",
265+
"time_resolution", "time_resolution", "time_resolution", "time_resolution",
266+
"time_resolution", "time_resolution", "time_resolution", "time_resolution"},
260267
"TOFResoParamsV3")
261268
{
262-
setParameters(std::array<float, 13>{0.008, 0.008, 0.002, 40.0, 60.0,
263-
0.008, 0.008, 0.002, 40.0,
264-
0.008, 0.008, 0.002, 40.0});
269+
setParameters(std::array<float, 13>{60.0});
265270
} // Default constructor with default parameters
266271

267272
~TOFResoParamsV3() = default;
@@ -313,7 +318,7 @@ class TOFResoParamsV3 : public o2::tof::Parameters<13>
313318
}
314319
}
315320

316-
// Time shift for post calibration
321+
// Time shift for post calibration to realign as a function of eta
317322
void setTimeShiftParameters(std::unordered_map<std::string, float> const& pars, bool positive)
318323
{
319324
std::string baseOpt = positive ? "TimeShift.Pos." : "TimeShift.Neg.";
@@ -367,13 +372,55 @@ class TOFResoParamsV3 : public o2::tof::Parameters<13>
367372
return gNegEtaTimeCorr->Eval(eta);
368373
}
369374

375+
void setResolutionParametrization(std::unordered_map<std::string, float> const& pars)
376+
{
377+
static constexpr std::array<const char*, 9> particleNames = {"El", "Mu", "Pi", "Ka", "Pr", "De", "Tr", "He", "Al"};
378+
for (int i = 0; i < 9; ++i) {
379+
const std::string baseOpt = Form("tofResTrack.%s_", particleNames[i]);
380+
// Check if a key begins with a string
381+
for (const auto& [key, value] : pars) {
382+
if (key.find(baseOpt) == 0) {
383+
// Remove from the key the baseOpt
384+
const std::string fun = key.substr(baseOpt.size());
385+
mResolution[i] = new TF2(baseOpt.c_str(), fun.c_str(), 0., 20, -1, 1.);
386+
LOG(info) << "Set the resolution function for " << particleNames[i] << " with formula " << mResolution[i]->GetFormula()->GetExpFormula();
387+
break;
388+
}
389+
}
390+
}
391+
// Print a summary
392+
for (int i = 0; i < 9; ++i) {
393+
if (!mResolution[i]) {
394+
LOG(info) << "Resolution function for " << particleNames[i] << " not provided, using default " << mDefaultResoParams[i];
395+
mResolution[i] = new TF2(Form("tofResTrack.%s_Default", particleNames[i]), mDefaultResoParams[i], 0., 20, -1, 1.);
396+
}
397+
LOG(info) << "Resolution function for " << particleNames[i] << " is " << mResolution[i]->GetName() << " with formula " << mResolution[i]->GetFormula()->GetExpFormula();
398+
}
399+
}
400+
401+
template <o2::track::PID::ID pid>
402+
float getResolution(const float p, const float eta) const
403+
{
404+
return mResolution[pid]->Eval(p, eta);
405+
}
406+
370407
private:
371408
// Charge calibration
372409
int mEtaN = 0; // Number of eta bins, 0 means no correction
373410
float mEtaStart = 0.f;
374411
float mEtaStop = 0.f;
375412
float mInvEtaWidth = 9999.f;
376413
std::vector<float> mContent;
414+
std::array<TF2*, 9> mResolution{nullptr};
415+
static constexpr std::array<const char*, 9> mDefaultResoParams{"14.3*TMath::Power((TMath::Max(x-0.319,0.1))*(1-0.4235*y*y),-0.8467)",
416+
"14.3*TMath::Power((TMath::Max(x-0.319,0.1))*(1-0.4235*y*y),-0.8467)",
417+
"14.3*TMath::Power((TMath::Max(x-0.319,0.1))*(1-0.4235*y*y),-0.8467)",
418+
"42.66*TMath::Power((TMath::Max(x-0.417,0.1))*(1-0.4235*y*y),-0.7145)",
419+
"99.46*TMath::Power((TMath::Max(x-0.447,0.1))*(1-0.4235*y*y),-0.8094)",
420+
"216*TMath::Power((TMath::Max(x-0.647,0.1))*(1-0.4235*y*y),-0.76)",
421+
"315*TMath::Power((TMath::Max(x-0.811,0.1))*(1-0.4235*y*y),-0.783)",
422+
"157*TMath::Power((TMath::Max(x-0.556,0.1))*(1-0.4235*y*y),-0.783)",
423+
"216*TMath::Power((TMath::Max(x-0.647,0.1))*(1-0.4235*y*y),-0.76)"};
377424

378425
// Time shift for post calibration
379426
TGraph* gPosEtaTimeCorr = nullptr; /// Time shift correction for positive tracks
@@ -391,7 +438,7 @@ class ExpTimes
391438
static constexpr float mMassZSqared = mMassZ * mMassZ; /// (M/z)^2
392439

393440
/// Computes the expected time of a track, given it TOF expected momentum
394-
static float ComputeExpectedTime(const float tofExpMom, const float length) { return length * sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (kCSPEED * tofExpMom); }
441+
static float ComputeExpectedTime(const float tofExpMom, const float length) { return length * sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); }
395442

396443
/// Gets the expected signal of the track of interest under the PID assumption
397444
/// \param track Track of interest
@@ -401,7 +448,7 @@ class ExpTimes
401448
return defaultReturnValue;
402449
}
403450
if (track.trackType() == o2::aod::track::Run2Track) {
404-
return ComputeExpectedTime(track.tofExpMom() * kCSPEDDInv, track.length());
451+
return ComputeExpectedTime(track.tofExpMom() * o2::constants::physics::invLightSpeedCm2PS, track.length());
405452
}
406453
return ComputeExpectedTime(track.tofExpMom(), track.length());
407454
}
@@ -416,7 +463,7 @@ class ExpTimes
416463
return defaultReturnValue;
417464
}
418465
if (track.trackType() == o2::aod::track::Run2Track) {
419-
return ComputeExpectedTime(track.tofExpMom() * kCSPEDDInv / (1.f + track.sign() * parameters.getMomentumChargeShift(track.eta())), track.length());
466+
return ComputeExpectedTime(track.tofExpMom() * o2::constants::physics::invLightSpeedCm2PS / (1.f + track.sign() * parameters.getMomentumChargeShift(track.eta())), track.length());
420467
}
421468
LOG(debug) << "TOF exp. mom. " << track.tofExpMom() << " shifted = " << track.tofExpMom() / (1.f + track.sign() * parameters.getMomentumChargeShift(track.eta()));
422469
return ComputeExpectedTime(track.tofExpMom() / (1.f + track.sign() * parameters.getMomentumChargeShift(track.eta())), track.length()) + parameters.getTimeShift(track.eta(), track.sign());
@@ -432,9 +479,14 @@ class ExpTimes
432479
static float GetExpectedSigma(const ParamType& parameters, const TrackType& track, const float tofSignal, const float collisionTimeRes)
433480
{
434481
const float& mom = track.p();
482+
const float& eta = track.eta();
435483
if (mom <= 0) {
436484
return -999.f;
437485
}
486+
const float reso = parameters.template getResolution<id>(mom, eta);
487+
if (reso > 0) {
488+
return std::sqrt(reso * reso + parameters[4] * parameters[4] + collisionTimeRes * collisionTimeRes);
489+
}
438490
if constexpr (id <= o2::track::PID::Pion) {
439491
LOG(debug) << "Using parameters for the pion hypothesis and ID " << id;
440492
const float dpp = parameters[0] + parameters[1] * mom + parameters[2] * mMassZ / mom; // mean relative pt resolution;

Common/Core/RecoDecay.h

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,119 @@ struct RecoDecay {
10351035
}
10361036
return OriginType::None;
10371037
}
1038+
1039+
/// based on getCharmHardronOrigin in order to extend general particle
1040+
/// Finding the origin (from charm hadronisation or beauty-hadron decay) of paritcle (b, c and others)
1041+
/// \param particlesMC table with MC particles
1042+
/// \param particle MC particle
1043+
/// \param searchUpToQuark if true tag origin based on charm/beauty quark otherwise on the presence of a b-hadron or c-hadron
1044+
/// \param idxBhadMothers optional vector of b-hadron indices (might be more than one in case of searchUpToQuark in case of beauty resonances)
1045+
/// \return an integer corresponding to the origin (0: none(others), 1: charm, 2: beauty) as in OriginType
1046+
template <typename T>
1047+
static int getParticleOrigin(const T& particlesMC,
1048+
const typename T::iterator& particle,
1049+
const bool searchUpToQuark = false,
1050+
std::vector<int>* idxBhadMothers = nullptr)
1051+
{
1052+
int stage = 0; // mother tree level (just for debugging)
1053+
1054+
// vector of vectors with mother indices; each line corresponds to a "stage"
1055+
std::vector<std::vector<int64_t>> arrayIds{};
1056+
std::vector<int64_t> initVec{particle.globalIndex()};
1057+
arrayIds.push_back(initVec); // the first vector contains the index of the original particle
1058+
auto PDGParticle = std::abs(particle.pdgCode());
1059+
bool couldBeCharm = false;
1060+
if (PDGParticle / 100 == 4 || PDGParticle / 1000 == 4) {
1061+
couldBeCharm = true;
1062+
}
1063+
while (arrayIds[-stage].size() > 0) {
1064+
// vector of mother indices for the current stage
1065+
std::vector<int64_t> arrayIdsStage{};
1066+
for (auto& iPart : arrayIds[-stage]) { // check all the particles that were the mothers at the previous stage
1067+
auto particleMother = particlesMC.rawIteratorAt(iPart - particlesMC.offset());
1068+
if (particleMother.has_mothers()) {
1069+
1070+
// we break immediately if searchUpToQuark is false and the first mother is a parton (an hadron should never be the mother of a parton)
1071+
if (!searchUpToQuark) {
1072+
auto mother = particlesMC.rawIteratorAt(particleMother.mothersIds().front() - particlesMC.offset());
1073+
auto PDGParticleIMother = std::abs(mother.pdgCode()); // PDG code of the mother
1074+
if (PDGParticleIMother < 9 || (PDGParticleIMother > 20 && PDGParticleIMother < 38)) {
1075+
auto PDGPaticle = std::abs(particleMother.pdgCode());
1076+
if (
1077+
(PDGParticleIMother / 100 == 5 || // b mesons
1078+
PDGParticleIMother / 1000 == 5) // b baryons
1079+
) {
1080+
return OriginType::NonPrompt; // beauty
1081+
}
1082+
if (
1083+
(PDGParticleIMother / 100 == 4 || // c mesons
1084+
PDGParticleIMother / 1000 == 4) // c baryons
1085+
) {
1086+
return OriginType::Prompt; // charm
1087+
}
1088+
break;
1089+
}
1090+
}
1091+
1092+
for (auto iMother = particleMother.mothersIds().front(); iMother <= particleMother.mothersIds().back(); ++iMother) { // loop over the mother particles of the analysed particle
1093+
if (std::find(arrayIdsStage.begin(), arrayIdsStage.end(), iMother) != arrayIdsStage.end()) { // if a mother is still present in the vector, do not check it again
1094+
continue;
1095+
}
1096+
auto mother = particlesMC.rawIteratorAt(iMother - particlesMC.offset());
1097+
// Check status code
1098+
auto motherStatusCode = std::abs(mother.getGenStatusCode());
1099+
auto PDGParticleIMother = std::abs(mother.pdgCode()); // PDG code of the mother
1100+
// Check mother's PDG code.
1101+
// printf("getMother: ");
1102+
// for (int i = stage; i < 0; i++) // Indent to make the tree look nice.
1103+
// printf(" ");
1104+
// printf("Stage %d: Mother PDG: %d, status: %d, Index: %d\n", stage, PDGParticleIMother, motherStatusCode, iMother);
1105+
1106+
if (searchUpToQuark) {
1107+
if (idxBhadMothers) {
1108+
if (PDGParticleIMother / 100 == 5 || // b mesons
1109+
PDGParticleIMother / 1000 == 5) // b baryons
1110+
{
1111+
idxBhadMothers->push_back(iMother);
1112+
}
1113+
}
1114+
if (PDGParticleIMother == 5) { // b quark
1115+
return OriginType::NonPrompt; // beauty
1116+
}
1117+
if (PDGParticleIMother == 4) { // c quark
1118+
return OriginType::Prompt; // charm
1119+
}
1120+
} else {
1121+
if (
1122+
(PDGParticleIMother / 100 == 5 || // b mesons
1123+
PDGParticleIMother / 1000 == 5) // b baryons
1124+
) {
1125+
if (idxBhadMothers) {
1126+
idxBhadMothers->push_back(iMother);
1127+
}
1128+
return OriginType::NonPrompt; // beauty
1129+
}
1130+
if (
1131+
(PDGParticleIMother / 100 == 4 || // c mesons
1132+
PDGParticleIMother / 1000 == 4) // c baryons
1133+
) {
1134+
couldBeCharm = true;
1135+
}
1136+
}
1137+
// add mother index in the vector for the current stage
1138+
arrayIdsStage.push_back(iMother);
1139+
}
1140+
}
1141+
}
1142+
// add vector of mother indices for the current stage
1143+
arrayIds.push_back(arrayIdsStage);
1144+
stage--;
1145+
}
1146+
if (couldBeCharm) {
1147+
return OriginType::Prompt; // charm
1148+
}
1149+
return OriginType::None;
1150+
}
10381151
};
10391152

10401153
/// Calculations using (pT, η, φ) coordinates, aka (transverse momentum, pseudorapidity, azimuth)

0 commit comments

Comments
 (0)