Skip to content

Commit 5c31504

Browse files
mcoquet642Maurice Coquet
andauthored
[PWGDQ] Allowing independent shifts of global tracks for MFT top or bottom halves (#17689)
Co-authored-by: Maurice Coquet <mcoquet@alicecerno2.cern.ch>
1 parent fc109ca commit 5c31504

3 files changed

Lines changed: 99 additions & 46 deletions

File tree

PWGDQ/Core/VarManager.cxx

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ float VarManager::fgzMatching = -77.5;
5959
float VarManager::fgxShiftFwd = 0.0;
6060
float VarManager::fgyShiftFwd = 0.0;
6161
float VarManager::fgzShiftFwd = 0.0;
62+
bool VarManager::fgUseTopBottomShift = false;
63+
float VarManager::fgxShiftFwdBottom = 0.0;
64+
float VarManager::fgyShiftFwdBottom = 0.0;
65+
float VarManager::fgzShiftFwdBottom = 0.0;
6266
float VarManager::fgValues[VarManager::kNVars] = {0.0f};
6367
float VarManager::fgTPCInterSectorBoundary = 1.0; // cm
6468
int VarManager::fgITSROFbias = 0;
@@ -147,7 +151,7 @@ void VarManager::ResetValues(int startValue, int endValue, float* values)
147151
}
148152

149153
//__________________________________________________________________
150-
void VarManager::SetCollisionSystem(TString system, float energy)
154+
void VarManager::SetCollisionSystem(const TString& system, float energy)
151155
{
152156
//
153157
// Set the collision system and the center of mass energy
@@ -200,8 +204,8 @@ void VarManager::SetCollisionSystem(TString system, float energy)
200204
// TO Do: add more systems
201205

202206
// set the beam 4-momentum vectors
203-
float beamAEnergy = energy / 2.0 * sqrt(NumberOfProtonsA * NumberOfProtonsC / NumberOfProtonsC / NumberOfProtonsA); // GeV
204-
float beamCEnergy = energy / 2.0 * sqrt(NumberOfProtonsC * NumberOfProtonsA / NumberOfProtonsA / NumberOfProtonsC); // GeV
207+
float beamAEnergy = energy / 2.0f * std::sqrt(static_cast<float>(NumberOfProtonsA) * NumberOfProtonsC / NumberOfProtonsC / NumberOfProtonsA); // GeV
208+
float beamCEnergy = energy / 2.0f * std::sqrt(static_cast<float>(NumberOfProtonsC) * NumberOfProtonsA / NumberOfProtonsA / NumberOfProtonsC); // GeV
205209
float beamAMomentum = std::sqrt(beamAEnergy * beamAEnergy - NumberOfNucleonsA * NumberOfNucleonsA * MassProton * MassProton);
206210
float beamCMomentum = std::sqrt(beamCEnergy * beamCEnergy - NumberOfNucleonsC * NumberOfNucleonsC * MassProton * MassProton);
207211
fgBeamA.SetPxPyPzE(0, 0, beamAMomentum, beamAEnergy);
@@ -243,7 +247,7 @@ void VarManager::FillTrackDerived(float* values)
243247
}
244248

245249
//__________________________________________________________________
246-
float VarManager::calculateCosPA(KFParticle kfp, KFParticle PV)
250+
float VarManager::calculateCosPA(const KFParticle& kfp, const KFParticle& PV)
247251
{
248252
return cpaFromKF(kfp, PV);
249253
}
@@ -256,7 +260,8 @@ double VarManager::ComputePIDcalibration(int species, double nSigmaValue)
256260

257261
if (fgCalibrationType == 1) {
258262
// get the calibration histograms
259-
CalibObjects calibMean, calibSigma;
263+
CalibObjects calibMean = kTPCElectronMean;
264+
CalibObjects calibSigma = kTPCElectronSigma;
260265
switch (species) {
261266
case 0:
262267
calibMean = kTPCElectronMean;
@@ -279,8 +284,8 @@ double VarManager::ComputePIDcalibration(int species, double nSigmaValue)
279284
return -999.0; // Return zero if species is invalid
280285
}
281286

282-
TH3F* calibMeanHist = reinterpret_cast<TH3F*>(fgCalibs[calibMean]);
283-
TH3F* calibSigmaHist = reinterpret_cast<TH3F*>(fgCalibs[calibSigma]);
287+
TH3F* calibMeanHist = dynamic_cast<TH3F*>(fgCalibs[calibMean]);
288+
TH3F* calibSigmaHist = dynamic_cast<TH3F*>(fgCalibs[calibSigma]);
284289
if (!calibMeanHist || !calibSigmaHist) {
285290
LOG(fatal) << "Calibration histograms not found for species: " << species;
286291
return -999.0; // Return zero if histograms are not found
@@ -302,7 +307,9 @@ double VarManager::ComputePIDcalibration(int species, double nSigmaValue)
302307
return (nSigmaValue - mean) / sigma; // Return the calibrated nSigma value
303308
} else if (fgCalibrationType == 2) {
304309
// get the calibration histograms
305-
CalibObjects calibMean, calibSigma, calibStatus;
310+
CalibObjects calibMean = kTPCElectronMean;
311+
CalibObjects calibSigma = kTPCElectronSigma;
312+
CalibObjects calibStatus = kTPCElectronStatus;
306313
switch (species) {
307314
case 0:
308315
calibMean = kTPCElectronMean;
@@ -329,9 +336,9 @@ double VarManager::ComputePIDcalibration(int species, double nSigmaValue)
329336
return -999.0; // Return zero if species is invalid
330337
}
331338

332-
THnF* calibMeanHist = reinterpret_cast<THnF*>(fgCalibs[calibMean]);
333-
THnF* calibSigmaHist = reinterpret_cast<THnF*>(fgCalibs[calibSigma]);
334-
THnF* calibStatusHist = reinterpret_cast<THnF*>(fgCalibs[calibStatus]);
339+
THnF* calibMeanHist = dynamic_cast<THnF*>(fgCalibs[calibMean]);
340+
THnF* calibSigmaHist = dynamic_cast<THnF*>(fgCalibs[calibSigma]);
341+
THnF* calibStatusHist = dynamic_cast<THnF*>(fgCalibs[calibStatus]);
335342
if (!calibMeanHist || !calibSigmaHist || !calibStatusHist) {
336343
LOG(fatal) << "Calibration histograms not found for species: " << species;
337344
return -999.0; // Return zero if histograms are not found
@@ -351,17 +358,18 @@ double VarManager::ComputePIDcalibration(int species, double nSigmaValue)
351358
binTlong = (binTlong == 0 ? 1 : binTlong);
352359
binTlong = (binTlong > calibMeanHist->GetAxis(3)->GetNbins() ? calibMeanHist->GetAxis(3)->GetNbins() : binTlong);
353360

354-
int bin[4] = {binEta, binNpv, binNlong, binTlong};
355-
int status = static_cast<int>(calibStatusHist->GetBinContent(bin));
356-
double mean = calibMeanHist->GetBinContent(bin);
357-
double sigma = calibSigmaHist->GetBinContent(bin);
361+
std::array<int, 4> bin{binEta, binNpv, binNlong, binTlong};
362+
int status = static_cast<int>(calibStatusHist->GetBinContent(bin.data()));
363+
double mean = calibMeanHist->GetBinContent(bin.data());
364+
double sigma = calibSigmaHist->GetBinContent(bin.data());
358365
switch (status) {
359366
case 0:
360367
// good calibration, return the calibrated nSigma value
361368
return (nSigmaValue - mean) / sigma;
362369
break;
363370
case 1:
364-
// calibration not valid, return the original nSigma value
371+
case 4:
372+
// calibration not valid or interpolation failed, return the original nSigma value
365373
return nSigmaValue;
366374
break;
367375
case 2: // calibration constant has poor stat uncertainty, consider the user option for what to do
@@ -374,10 +382,6 @@ double VarManager::ComputePIDcalibration(int species, double nSigmaValue)
374382
return nSigmaValue;
375383
}
376384
break;
377-
case 4:
378-
// calibration constants interpolation failed, return the original nSigma value
379-
return nSigmaValue;
380-
break;
381385
default:
382386
return nSigmaValue; // unknown status, return the original nSigma value
383387
break;
@@ -419,7 +423,7 @@ void VarManager::FillEfficiency(float* values)
419423
LOG(fatal) << "efficiency histogram not set";
420424
return;
421425
}
422-
TH3F* efficiencyHist = reinterpret_cast<TH3F*>(fgEfficiencyHist);
426+
TH3F* efficiencyHist = dynamic_cast<TH3F*>(fgEfficiencyHist);
423427
// Get the bin indices for the efficiency histogram
424428
int binPt = efficiencyHist->GetXaxis()->FindBin(values[kPt]);
425429
binPt = (binPt == 0 ? 1 : binPt);
@@ -439,7 +443,7 @@ void VarManager::FillEfficiency(float* values)
439443
LOG(fatal) << "efficiency histogram not set";
440444
return;
441445
}
442-
TH3F* efficiencyHist = reinterpret_cast<TH3F*>(fgEfficiencyHist);
446+
TH3F* efficiencyHist = dynamic_cast<TH3F*>(fgEfficiencyHist);
443447
// Get the bin indices for the efficiency histogram
444448
int binPt = efficiencyHist->GetXaxis()->FindBin(values[kPt]);
445449
binPt = (binPt == 0 ? 1 : binPt);
@@ -541,10 +545,9 @@ std::tuple<float, float, float, float, float> VarManager::BimodalityCoefficientU
541545
float mean = std::accumulate(data.begin(), data.end(), 0.0) / n;
542546

543547
float m2 = 0.0, m3 = 0.0, m4 = 0.0;
544-
float diff, diff2;
545-
for (float x : data) {
546-
diff = x - mean;
547-
diff2 = diff * diff;
548+
for (const float& x : data) {
549+
const float diff = x - mean;
550+
const float diff2 = diff * diff;
548551
m2 += diff2;
549552
m3 += diff2 * diff;
550553
m4 += diff2 * diff2;
@@ -581,7 +584,7 @@ std::tuple<float, float, float, float, float, int> VarManager::BimodalityCoeffic
581584
int nBins = static_cast<int>((max - min) / binWidth);
582585
std::vector<int> counts(nBins, 0.0);
583586

584-
for (float x : data) {
587+
for (const float& x : data) {
585588
if (x < min || x >= max) {
586589
continue; // skip out-of-range values
587590
}
@@ -688,14 +691,13 @@ std::tuple<float, float, float, float, float, int> VarManager::BimodalityCoeffic
688691

689692
// then compute the second, third, and fourth central moments
690693
float m2 = 0.0, m3 = 0.0, m4 = 0.0;
691-
float diff, diff2, binCenter;
692694
for (int i = 0; i < nBins; ++i) {
693695
if (counts[i] == 0) {
694696
continue; // skip empty bins
695697
}
696-
binCenter = min + (i + 0.5) * binWidth;
697-
diff = binCenter - mean;
698-
diff2 = diff * diff;
698+
const float binCenter = min + (i + 0.5f) * binWidth;
699+
const float diff = binCenter - mean;
700+
const float diff2 = diff * diff;
699701
m2 += counts[i] * diff2;
700702
m3 += counts[i] * diff2 * diff;
701703
m4 += counts[i] * diff2 * diff2;

PWGDQ/Core/VarManager.h

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,7 +1274,7 @@ class VarManager : public TObject
12741274
}
12751275

12761276
// Setup the collision system
1277-
static void SetCollisionSystem(TString system, float energy);
1277+
static void SetCollisionSystem(const TString& system, float energy);
12781278
static void SetCollisionSystem(o2::parameters::GRPLHCIFData* grplhcif);
12791279

12801280
static void SetMagneticField(float magField)
@@ -1297,6 +1297,7 @@ class VarManager : public TObject
12971297
static void SetZShift(float z)
12981298
{
12991299
fgzShiftFwd = z;
1300+
fgUseTopBottomShift = false;
13001301
}
13011302

13021303
// Set x, y and z shifts for forward tracks
@@ -1305,6 +1306,33 @@ class VarManager : public TObject
13051306
fgxShiftFwd = x;
13061307
fgyShiftFwd = y;
13071308
fgzShiftFwd = z;
1309+
fgUseTopBottomShift = false;
1310+
}
1311+
1312+
// Set separate x, y, z shifts for top (y >= 0) and bottom (y < 0) forward tracks
1313+
// Top shifts are stored in fgx/y/zShiftFwd; bottom shifts in fgx/y/zShiftFwdBottom
1314+
static void SetTopBottom3DShift(float xTop, float yTop, float zTop, float xBottom, float yBottom, float zBottom)
1315+
{
1316+
fgxShiftFwd = xTop;
1317+
fgyShiftFwd = yTop;
1318+
fgzShiftFwd = zTop;
1319+
fgxShiftFwdBottom = xBottom;
1320+
fgyShiftFwdBottom = yBottom;
1321+
fgzShiftFwdBottom = zBottom;
1322+
fgUseTopBottomShift = true;
1323+
}
1324+
1325+
static void GetFwdShiftForY(float y, float& xShift, float& yShift, float& zShift)
1326+
{
1327+
if (fgUseTopBottomShift && y < 0.f) {
1328+
xShift = fgxShiftFwdBottom;
1329+
yShift = fgyShiftFwdBottom;
1330+
zShift = fgzShiftFwdBottom;
1331+
} else {
1332+
xShift = fgxShiftFwd;
1333+
yShift = fgyShiftFwd;
1334+
zShift = fgzShiftFwd;
1335+
}
13081336
}
13091337

13101338
// Setup the 2 prong KFParticle
@@ -1619,6 +1647,10 @@ class VarManager : public TObject
16191647
static float fgxShiftFwd;
16201648
static float fgyShiftFwd;
16211649
static float fgzShiftFwd;
1650+
static bool fgUseTopBottomShift;
1651+
static float fgxShiftFwdBottom;
1652+
static float fgyShiftFwdBottom;
1653+
static float fgzShiftFwdBottom;
16221654
static float fgCenterOfMassEnergy; // collision energy
16231655
static float fgMassofCollidingParticle; // mass of the colliding particle
16241656
static float fgTPCInterSectorBoundary; // TPC inter-sector border size at the TPC outer radius, in cm
@@ -1641,7 +1673,7 @@ class VarManager : public TObject
16411673
static KFPTrack createKFPFwdTrackFromFwdTrack(const T& muon);
16421674
template <typename T>
16431675
static KFPVertex createKFPVertexFromCollision(const T& collision);
1644-
static float calculateCosPA(KFParticle kfp, KFParticle PV);
1676+
static float calculateCosPA(const KFParticle& kfp, const KFParticle& PV);
16451677
template <int pairType, typename T1, typename T2>
16461678
static float calculatePhiV(const T1& t1, const T2& t2);
16471679
template <typename T1, typename T2>
@@ -1797,7 +1829,11 @@ o2::dataformats::VertexBase VarManager::RecalculatePrimaryVertex(T const& track0
17971829
template <typename T, typename C>
17981830
o2::dataformats::GlobalFwdTrack VarManager::PropagateMuon(const T& muon, const C& collision, const int endPoint)
17991831
{
1800-
o2::track::TrackParCovFwd fwdtrack = o2::aod::fwdtrackutils::getTrackParCovFwd3DShift(muon, fgxShiftFwd, fgyShiftFwd, fgzShiftFwd, muon);
1832+
float xShift = 0.f;
1833+
float yShift = 0.f;
1834+
float zShift = 0.f;
1835+
GetFwdShiftForY(muon.y(), xShift, yShift, zShift);
1836+
o2::track::TrackParCovFwd fwdtrack = o2::aod::fwdtrackutils::getTrackParCovFwd3DShift(muon, xShift, yShift, zShift, muon);
18011837
o2::dataformats::GlobalFwdTrack propmuon;
18021838
if (static_cast<int>(muon.trackType()) > 2) {
18031839
o2::dataformats::GlobalFwdTrack track;
@@ -1924,12 +1960,16 @@ void VarManager::FillGlobalMuonRefit(T1 const& muontrack, T2 const& mfttrack, co
19241960
values = fgValues;
19251961
}
19261962
if constexpr ((fillMap & MuonCov) > 0 || (fillMap & ReducedMuonCov) > 0) {
1927-
o2::dataformats::GlobalFwdTrack propmuon = PropagateMuon(muontrack, collision);
1963+
float xShift = 0.f;
1964+
float yShift = 0.f;
1965+
float zShift = 0.f;
1966+
GetFwdShiftForY(mfttrack.y(), xShift, yShift, zShift);
1967+
o2::dataformats::GlobalFwdTrack propmuon = PropagateMuon(muontrack, collision, kToVertex);
19281968
double px = propmuon.getP() * std::sin(o2::constants::math::PIHalf - std::atan(mfttrack.tgl())) * std::cos(mfttrack.phi());
19291969
double py = propmuon.getP() * std::sin(o2::constants::math::PIHalf - std::atan(mfttrack.tgl())) * std::sin(mfttrack.phi());
19301970
double pz = propmuon.getP() * std::cos(o2::constants::math::PIHalf - std::atan(mfttrack.tgl()));
19311971
double pt = std::sqrt(std::pow(px, 2) + std::pow(py, 2));
1932-
auto mftprop = o2::aod::fwdtrackutils::getTrackParCovFwd3DShift(mfttrack, fgxShiftFwd, fgyShiftFwd, fgzShiftFwd);
1972+
auto mftprop = o2::aod::fwdtrackutils::getTrackParCovFwd3DShift(mfttrack, xShift, yShift, zShift);
19331973
values[kX] = mftprop.getX();
19341974
values[kY] = mftprop.getY();
19351975
values[kZ] = mftprop.getZ();
@@ -1949,8 +1989,12 @@ void VarManager::FillGlobalMuonRefitCov(T1 const& muontrack, T2 const& mfttrack,
19491989
}
19501990
if constexpr ((MuonfillMap & MuonCov) > 0) {
19511991
if constexpr ((MFTfillMap & MFTCov) > 0) {
1952-
o2::dataformats::GlobalFwdTrack propmuon = PropagateMuon(muontrack, collision);
1953-
auto mft = o2::aod::fwdtrackutils::getTrackParCovFwd3DShift(mfttrack, fgxShiftFwd, fgyShiftFwd, fgzShiftFwd, mftcov);
1992+
float xShift = 0.f;
1993+
float yShift = 0.f;
1994+
float zShift = 0.f;
1995+
GetFwdShiftForY(mfttrack.y(), xShift, yShift, zShift);
1996+
o2::dataformats::GlobalFwdTrack propmuon = PropagateMuon(muontrack, collision, kToVertex);
1997+
auto mft = o2::aod::fwdtrackutils::getTrackParCovFwd3DShift(mfttrack, xShift, yShift, zShift, mftcov);
19541998

19551999
o2::dataformats::GlobalFwdTrack globalRefit = o2::aod::fwdtrackutils::refitGlobalMuonCov(propmuon, mft);
19562000
values[kX] = globalRefit.getX();
@@ -3369,7 +3413,11 @@ void VarManager::FillTrack(T const& track, float* values)
33693413
values[kMuonC1Pt21Pt2] = track.c1Pt21Pt2();
33703414
}
33713415
if constexpr ((fillMap & MuonCov) > 0 || (fillMap & MuonCovRealign) > 0) {
3372-
auto muonTrack = o2::aod::fwdtrackutils::getTrackParCovFwd3DShift(track, fgxShiftFwd, fgyShiftFwd, fgzShiftFwd, track);
3416+
float xShift = 0.f;
3417+
float yShift = 0.f;
3418+
float zShift = 0.f;
3419+
GetFwdShiftForY(track.y(), xShift, yShift, zShift);
3420+
auto muonTrack = o2::aod::fwdtrackutils::getTrackParCovFwd3DShift(track, xShift, yShift, zShift, track);
33733421
auto muonCov = muonTrack.getCovariances();
33743422
values[kX] = muonTrack.getX();
33753423
values[kY] = muonTrack.getY();
@@ -4052,11 +4100,7 @@ void VarManager::FillPairRotation(T1 const& t1, T2 const& t2, int rotation, floa
40524100
rotationphi2 = 2 * values[kPsi2A] - t2.phi() + o2::constants::math::PI;
40534101
}
40544102

4055-
if (rotationphi2 >= o2::constants::math::TwoPI) {
4056-
rotationphi2 -= o2::constants::math::TwoPI;
4057-
} else if (rotationphi2 < 0) {
4058-
rotationphi2 += o2::constants::math::TwoPI;
4059-
}
4103+
rotationphi2 = RecoDecay::constrainAngle(rotationphi2);
40604104

40614105
values[kCharge] = t1.sign() + t2.sign();
40624106
values[kCharge1] = t1.sign();

PWGDQ/TableProducer/tableMaker_withAssoc.cxx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ struct TableMaker {
288288
Configurable<int64_t> fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"};
289289
Configurable<std::string> fConfigGeoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"};
290290
Configurable<std::string> fConfigGrpMagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"};
291-
Configurable<std::string> fFwdShiftPath{"fwdShiftPath", "Users/m/mcoquet/ZShift", "CCDB path for the shift to apply to forward tracks, either 1 value (z) or 3 values (x, y, z)"};
291+
Configurable<std::string> fFwdShiftPath{"fwdShiftPath", "Users/m/mcoquet/ZShift", "CCDB path for the shift to apply to forward tracks: 1 (z), 3 (x,y,z), or 10 (x,y,z,slopeX,slopeY for top then bottom; slopes unused)"};
292292
Configurable<bool> fUseRemoteFwdShift{"cfgUseRemoteFwdShift", false, "Enable getting the forward track shift from ccdb"};
293293
Configurable<float> fManualZShift{"cfgManualZShift", 0.f, "Manual value for the Zshift for muons."};
294294
Configurable<std::string> fConfigGrpMagPathRun2{"grpmagPathRun2", "GLO/GRP/GRP", "CCDB path of the GRPObject (Usage for Run 2)"};
@@ -1870,8 +1870,15 @@ struct TableMaker {
18701870
VarManager::SetZShift((*fFwdShift)[0]);
18711871
} else if (fFwdShift->size() == 3) {
18721872
VarManager::Set3DShift((*fFwdShift)[0], (*fFwdShift)[1], (*fFwdShift)[2]);
1873+
} else if (fFwdShift->size() == 10) {
1874+
// x_top, y_top, z_top, slopeX_top, slopeY_top, x_bottom, y_bottom, z_bottom, slopeX_bottom, slopeY_bottom
1875+
// Slopes are unused for now; shift is selected from track y (top: y >= 0, bottom: y < 0)
1876+
VarManager::SetTopBottom3DShift((*fFwdShift)[0], (*fFwdShift)[1], (*fFwdShift)[2],
1877+
(*fFwdShift)[5], (*fFwdShift)[6], (*fFwdShift)[7]);
1878+
LOG(info) << "Loaded top/bottom forward track shifts from CCDB: top=(" << (*fFwdShift)[0] << ", " << (*fFwdShift)[1] << ", " << (*fFwdShift)[2]
1879+
<< "), bottom=(" << (*fFwdShift)[5] << ", " << (*fFwdShift)[6] << ", " << (*fFwdShift)[7] << ")";
18731880
} else {
1874-
LOG(fatal) << "Unexpected number of shift values from CCDB: " << fFwdShift->size() << ", expected 1 (z) or 3 (x, y, z)";
1881+
LOG(fatal) << "Unexpected number of shift values from CCDB: " << fFwdShift->size() << ", expected 1 (z), 3 (x, y, z) or 10 (top/bottom x,y,z + slopes)";
18751882
}
18761883
} else {
18771884
VarManager::SetZShift(fConfigCCDB.fManualZShift.value);

0 commit comments

Comments
 (0)