Skip to content

Commit c49d6d5

Browse files
committed
[PWGDQ] improved momentum rescaling for global forward tracks
The MCH tracks are extrapolated to the first measured MFT point using TrackExtrap::extrapToVertex() instead of TrackExtrap::extrapToVertexWithoutBranson(), which cures large inaccuracies in the MCH momentum estimation at the MFT front for some tracks. Those inaccuracies were contributing to high-mass tails in the di-muon invariant mass distribution reconstructed from global forward tracks with rescaled momentum.
1 parent 821f296 commit c49d6d5

2 files changed

Lines changed: 76 additions & 76 deletions

File tree

PWGDQ/Tasks/muonGlobalAlignment.cxx

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
#include <Framework/InitContext.h>
4242
#include <Framework/runDataProcessing.h>
4343
#include <GPU/GPUROOTCartesianFwd.h>
44-
#include <GlobalTracking/MatchGlobalFwd.h>
4544
#include <MCHBase/TrackerParam.h>
4645
#include <MCHGeometryTransformer/Transformations.h>
4746
#include <MCHTracking/Track.h>
@@ -348,8 +347,8 @@ struct muonGlobalAlignment { // o2-linter: disable=name/workflow-file,name/struc
348347
base::Propagator::initFieldFromGRP(grpmag);
349348
TrackExtrap::setField();
350349
TrackExtrap::useExtrapV2();
351-
fieldB = static_cast<o2::field::MagneticField*>(TGeoGlobalMagField::Instance()->GetField()); // for MFT
352-
std::array<double, 3> centerMFT{0, 0, -61.4}; // or use middle point between Vtx and MFT?
350+
fieldB = dynamic_cast<o2::field::MagneticField*>(TGeoGlobalMagField::Instance()->GetField()); // for MFT
351+
std::array<double, 3> centerMFT{0, 0, -61.4}; // or use middle point between Vtx and MFT?
353352
mBzAtMftCenter = fieldB->getBz(centerMFT.data());
354353
} else {
355354
LOGF(fatal, "GRP object is not available in CCDB at timestamp=%llu", bc.timestamp());
@@ -1301,8 +1300,8 @@ struct muonGlobalAlignment { // o2-linter: disable=name/workflow-file,name/struc
13011300
collision.posX(),
13021301
collision.posY(),
13031302
collision.posZ(),
1304-
collision.covXX(),
1305-
collision.covYY());
1303+
std::sqrt(collision.covXX()),
1304+
std::sqrt(collision.covYY()));
13061305
}
13071306

13081307
template <class TMFT>
@@ -1380,7 +1379,12 @@ struct muonGlobalAlignment { // o2-linter: disable=name/workflow-file,name/struc
13801379

13811380
// extrapolation with MCH tools
13821381
auto mchTrackAtMFT = FwdtoMCH(mchTrackPar);
1383-
o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrackAtMFT, mftTrackPar.getZ());
1382+
o2::mch::TrackExtrap::extrapToVertex(mchTrackAtMFT,
1383+
mftTrackPar.getX(),
1384+
mftTrackPar.getY(),
1385+
mftTrackPar.getZ(),
1386+
std::sqrt(mftTrackPar.getSigma2X()),
1387+
std::sqrt(mftTrackPar.getSigma2Y()));
13841388
UpdateTrackMomentum(mftTrackPar, mchTrackAtMFT);
13851389

13861390
// double propVec[3] = {};
@@ -1406,13 +1410,18 @@ struct muonGlobalAlignment { // o2-linter: disable=name/workflow-file,name/struc
14061410
return result;
14071411
}
14081412

1409-
o2::dataformats::GlobalFwdTrack PropagateMFTtoMCH(o2::track::TrackParCovFwd mftTrackPar,
1413+
o2::dataformats::GlobalFwdTrack PropagateMFTtoMCH(const o2::track::TrackParCovFwd& mftTrackPar,
14101414
const o2::mch::TrackParam& mchTrackPar,
14111415
const double z)
14121416
{
14131417
// extrapolation with MCH tools
14141418
auto mchTrackAtMFT = mchTrackPar;
1415-
o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrackAtMFT, mftTrackPar.getZ());
1419+
o2::mch::TrackExtrap::extrapToVertex(mchTrackAtMFT,
1420+
mftTrackPar.getX(),
1421+
mftTrackPar.getY(),
1422+
mftTrackPar.getZ(),
1423+
std::sqrt(mftTrackPar.getSigma2X()),
1424+
std::sqrt(mftTrackPar.getSigma2Y()));
14161425

14171426
auto mftTrackProp = FwdtoMCH(mftTrackPar);
14181427
UpdateTrackMomentum(mftTrackProp, mchTrackAtMFT);
@@ -1449,24 +1458,20 @@ struct muonGlobalAlignment { // o2-linter: disable=name/workflow-file,name/struc
14491458
{
14501459
// extrapolation with MCH tools
14511460
auto mchTrackAtMFT = FwdtoMCH(mchTrackPar);
1452-
o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrackAtMFT, mftTrackPar.getZ());
1461+
o2::mch::TrackExtrap::extrapToVertex(mchTrackAtMFT,
1462+
mftTrackPar.getX(),
1463+
mftTrackPar.getY(),
1464+
mftTrackPar.getZ(),
1465+
std::sqrt(mftTrackPar.getSigma2X()),
1466+
std::sqrt(mftTrackPar.getSigma2Y()));
14531467

1454-
auto mftTrackProp = FwdtoMCH(mftTrackPar);
1455-
1456-
// update global track momentum from the MCH track
1457-
double pRatio = mftTrackProp.p() / mchTrackAtMFT.p();
1458-
double newInvBendMom = mftTrackProp.getInverseBendingMomentum() * pRatio;
1459-
mftTrackProp.setInverseBendingMomentum(newInvBendMom);
1460-
mftTrackProp.setCharge(mchTrackAtMFT.getCharge());
1468+
auto fwdTrackProp = fwdtrackutils::refitGlobalMuonCov(MCHtoFwd(mchTrackAtMFT), mftTrackPar);
14611469

1462-
o2::mch::TrackExtrap::extrapToVertex(mftTrackProp,
1463-
collision.posX(),
1464-
collision.posY(),
1465-
collision.posZ(),
1466-
collision.covXX(),
1467-
collision.covYY());
1470+
auto geoMan = o2::base::GeometryManager::meanMaterialBudget(fwdTrackProp.getX(), fwdTrackProp.getY(), fwdTrackProp.getZ(), collision.posX(), collision.posY(), collision.posZ());
1471+
auto x2x0 = static_cast<float>(geoMan.meanX2X0);
1472+
fwdTrackProp.propagateToVtxhelixWithMCS(collision.posZ(), {collision.posX(), collision.posY()}, {collision.covXX(), collision.covYY()}, mBzAtMftCenter, x2x0);
14681473

1469-
return MCHtoFwd(mftTrackProp);
1474+
return fwdTrackProp;
14701475
}
14711476

14721477
void getMuonPairs(const CollisionInfo& collisionInfo,

PWGDQ/Tasks/qaMatching.cxx

Lines changed: 48 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "PWGDQ/Core/VarManager.h"
1818

1919
#include "Common/CCDB/RCTSelectionFlags.h"
20+
#include "Common/Core/fwdtrackUtilities.h"
2021
#include "Common/DataModel/Centrality.h"
2122
#include "Common/DataModel/CollisionAssociationTables.h"
2223
#include "Common/DataModel/EventSelection.h"
@@ -84,8 +85,6 @@
8485
#include <utility>
8586
#include <vector>
8687

87-
#include <math.h>
88-
8988
using namespace o2;
9089
using namespace o2::framework;
9190
using namespace o2::aod;
@@ -250,7 +249,7 @@ struct QaMatching {
250249
kMatchTypeWrongNonLeading = 5,
251250
kMatchTypeDecayNonLeading = 6,
252251
kMatchTypeFakeNonLeading = 7,
253-
kMatchTypeUndefined
252+
kMatchTypeUndefined = 8
254253
};
255254

256255
static constexpr int GlobalTrackTypeMax = 2;
@@ -476,7 +475,7 @@ struct QaMatching {
476475

477476
int mRunNumber{0}; // needed to detect if the run changed and trigger update of magnetic field
478477

479-
Service<o2::ccdb::BasicCCDBManager> ccdbManager;
478+
Service<o2::ccdb::BasicCCDBManager> ccdbManager{};
480479
o2::ccdb::CcdbApi fCCDBApi;
481480

482481
o2::aod::rctsel::RCTFlagsChecker rctChecker{"CBT_muon_glo", false, false, true};
@@ -714,7 +713,7 @@ struct QaMatching {
714713
o2::framework::HistPtr hDeltaEta;
715714
o2::framework::HistPtr hRabs;
716715

717-
MatchFeaturesHistos(std::string path, HistogramRegistry* registry, int numCandidates, double scoreMax)
716+
MatchFeaturesHistos(const std::string& path, HistogramRegistry* registry, int numCandidates, double scoreMax)
718717
{
719718
AxisSpec indexAxis = {numCandidates, 0, static_cast<double>(numCandidates), "ranking index"};
720719
int matchTypeMax = static_cast<int>(kMatchTypeUndefined) + 1;
@@ -754,13 +753,13 @@ struct QaMatching {
754753
o2::framework::HistPtr histVsDeltaChi2;
755754
o2::framework::HistPtr histVsProdRanking;
756755

757-
MatchRankingHistos(std::string histName, std::string histTitle, HistogramRegistry* registry, int mftMultMax, int numCandidates)
756+
MatchRankingHistos(const std::string& histName, const std::string& histTitle, HistogramRegistry* registry, int mftMultMax, int numCandidates)
758757
{
759758
AxisSpec pAxis = {100, 0, 100, "p (GeV/c)"};
760759
AxisSpec ptAxis = {100, 0, 10, "p_{T} (GeV/c)"};
761760
AxisSpec dzAxis = {100, -1, 4, "#Deltaz (cm)"};
762-
AxisSpec trackMultAxis = {static_cast<int>(mftMultMax) / 10, 0, static_cast<double>(mftMultMax), "MFT track mult."};
763-
AxisSpec matchAttemptsAxis = {static_cast<int>(mftMultMax) / 10, 0, static_cast<double>(mftMultMax), "match attempts"};
761+
AxisSpec trackMultAxis = {mftMultMax / 10, 0, static_cast<double>(mftMultMax), "MFT track mult."};
762+
AxisSpec matchAttemptsAxis = {mftMultMax / 10, 0, static_cast<double>(mftMultMax), "match attempts"};
764763
AxisSpec trackTypeAxis = {2, 0, 2, "MFT track type"};
765764
int matchTypeMax = static_cast<int>(kMatchTypeUndefined);
766765
AxisSpec matchTypeAxis = {matchTypeMax, 0, static_cast<double>(matchTypeMax), "match type"};
@@ -833,16 +832,16 @@ struct QaMatching {
833832
std::unique_ptr<EfficiencyPlotter> fMatchingEfficiencyPlotter;
834833
std::unique_ptr<EfficiencyPlotter> fFakeMatchingEfficiencyPlotter;
835834

836-
HistogramRegistry* registry;
835+
HistogramRegistry* registry{nullptr};
837836

838837
MatchingPlotter(const std::string& path,
839838
HistogramRegistry* reg,
840839
bool createPdgMomHistograms,
841840
int mftMultMax,
842841
int numCandidates,
843842
bool isMc)
843+
: registry(reg)
844844
{
845-
registry = reg;
846845
AxisSpec pAxis = {100, 0, 100, "p (GeV/c)"};
847846
AxisSpec ptAxis = {100, 0, 10, "p_{T} (GeV/c)"};
848847
AxisSpec dzAxis = {100, 0, 50, "#Deltaz (cm)"};
@@ -973,8 +972,9 @@ struct QaMatching {
973972
template <typename BC>
974973
void initCcdb(BC const& bc)
975974
{
976-
if (mRunNumber == bc.runNumber())
975+
if (mRunNumber == bc.runNumber()) {
977976
return;
977+
}
978978

979979
mRunNumber = bc.runNumber();
980980
std::map<std::string, std::string> metadata;
@@ -988,10 +988,10 @@ struct QaMatching {
988988
ccdbManager->get<TGeoManager>(geoPath);
989989
}
990990
o2::mch::TrackExtrap::setField();
991-
auto* fieldB = static_cast<o2::field::MagneticField*>(TGeoGlobalMagField::Instance()->GetField());
991+
auto* fieldB = dynamic_cast<o2::field::MagneticField*>(TGeoGlobalMagField::Instance()->GetField());
992992
if (fieldB) {
993-
double centerMft[3] = {0, 0, -61.4}; // Field at center of MFT
994-
mBzAtMftCenter = fieldB->getBz(centerMft);
993+
const std::array<double, 3> centerMft{0, 0, -61.4}; // Field at center of MFT
994+
mBzAtMftCenter = fieldB->getBz(centerMft.data());
995995
// std::cout << "fieldB: " << (void*)fieldB << std::endl;
996996
}
997997
}
@@ -1110,8 +1110,8 @@ struct QaMatching {
11101110
SVector5 mK(mftTrack.getX(), mftTrack.getY(), mftTrack.getPhi(),
11111111
mftTrack.getTanl(), mftTrack.getInvQPt()),
11121112
rKKminus1;
1113-
SVector5 globalMuonTrackParameters = mchTrack.getParameters();
1114-
SMatrix55Sym globalMuonTrackCovariances = mchTrack.getCovariances();
1113+
const SVector5& globalMuonTrackParameters = mchTrack.getParameters();
1114+
const SMatrix55Sym& globalMuonTrackCovariances = mchTrack.getCovariances();
11151115
vK(0, 0) = mftTrack.getCovariances()(0, 0);
11161116
vK(1, 1) = mftTrack.getCovariances()(1, 1);
11171117
vK(2, 2) = mftTrack.getCovariances()(2, 2);
@@ -1145,8 +1145,8 @@ struct QaMatching {
11451145
SVector4 mK(mftTrack.getX(), mftTrack.getY(), mftTrack.getPhi(),
11461146
mftTrack.getTanl()),
11471147
rKKminus1;
1148-
SVector5 globalMuonTrackParameters = mchTrack.getParameters();
1149-
SMatrix55Sym globalMuonTrackCovariances = mchTrack.getCovariances();
1148+
const SVector5& globalMuonTrackParameters = mchTrack.getParameters();
1149+
const SMatrix55Sym& globalMuonTrackCovariances = mchTrack.getCovariances();
11501150
vK(0, 0) = mftTrack.getCovariances()(0, 0);
11511151
vK(1, 1) = mftTrack.getCovariances()(1, 1);
11521152
vK(2, 2) = mftTrack.getCovariances()(2, 2);
@@ -1176,8 +1176,8 @@ struct QaMatching {
11761176
SMatrix25 hK;
11771177
SMatrix22 vK;
11781178
SVector2 mK(mftTrack.getX(), mftTrack.getY()), rKKminus1;
1179-
SVector5 globalMuonTrackParameters = mchTrack.getParameters();
1180-
SMatrix55Sym globalMuonTrackCovariances = mchTrack.getCovariances();
1179+
const SVector5& globalMuonTrackParameters = mchTrack.getParameters();
1180+
const SMatrix55Sym& globalMuonTrackCovariances = mchTrack.getCovariances();
11811181
vK(0, 0) = mftTrack.getCovariances()(0, 0);
11821182
vK(1, 1) = mftTrack.getCovariances()(1, 1);
11831183
hK(0, 0) = 1.0;
@@ -1640,8 +1640,8 @@ struct QaMatching {
16401640
collision.posX(),
16411641
collision.posY(),
16421642
collision.posZ(),
1643-
collision.covXX(),
1644-
collision.covYY());
1643+
std::sqrt(collision.covXX()),
1644+
std::sqrt(collision.covYY()));
16451645
}
16461646

16471647
o2::dataformats::GlobalFwdTrack propagateToVertexMft(o2::dataformats::GlobalFwdTrack muon,
@@ -1667,8 +1667,8 @@ struct QaMatching {
16671667
collision.posX(),
16681668
collision.posY(),
16691669
collision.posZ(),
1670-
collision.covXX(),
1671-
collision.covYY());
1670+
std::sqrt(collision.covXX()),
1671+
std::sqrt(collision.covYY()));
16721672
}
16731673

16741674
template <typename TMCH, typename TMFT, class C>
@@ -1678,24 +1678,19 @@ struct QaMatching {
16781678
{
16791679
// extrapolation with MCH tools
16801680
auto mchTrackAtMFT = mExtrap.FwdtoMCH(fwdToTrackPar(mchTrack));
1681-
o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrackAtMFT, mftTrack.z());
1681+
o2::mch::TrackExtrap::extrapToVertex(mchTrackAtMFT,
1682+
mftTrack.x(),
1683+
mftTrack.y(),
1684+
mftTrack.z(),
1685+
0, 0);
16821686

1683-
auto mftTrackProp = mExtrap.FwdtoMCH(fwdToTrackPar(mftTrack));
1687+
auto fwdTrackProp = fwdtrackutils::refitGlobalMuonCov(mExtrap.MCHtoFwd(mchTrackAtMFT), fwdToTrackPar(mftTrack));
16841688

1685-
// update global track momentum from the MCH track
1686-
double pRatio = mftTrackProp.p() / mchTrackAtMFT.p();
1687-
double newInvBendMom = mftTrackProp.getInverseBendingMomentum() * pRatio;
1688-
mftTrackProp.setInverseBendingMomentum(newInvBendMom);
1689-
mftTrackProp.setCharge(mchTrackAtMFT.getCharge());
1690-
1691-
o2::mch::TrackExtrap::extrapToVertex(mftTrackProp,
1692-
collision.posX(),
1693-
collision.posY(),
1694-
collision.posZ(),
1695-
collision.covXX(),
1696-
collision.covYY());
1689+
auto geoMan = o2::base::GeometryManager::meanMaterialBudget(fwdTrackProp.getX(), fwdTrackProp.getY(), fwdTrackProp.getZ(), collision.posX(), collision.posY(), collision.posZ());
1690+
auto x2x0 = static_cast<float>(geoMan.meanX2X0);
1691+
fwdTrackProp.propagateToVtxhelixWithMCS(collision.posZ(), {collision.posX(), collision.posY()}, {collision.covXX(), collision.covYY()}, mBzAtMftCenter, x2x0);
16971692

1698-
return mExtrap.MCHtoFwd(mftTrackProp);
1693+
return fwdTrackProp;
16991694
}
17001695

17011696
template <class MCP>
@@ -2164,8 +2159,8 @@ struct QaMatching {
21642159
mchTrackIndex,
21652160
mftTrackIndex,
21662161
static_cast<int>(muonTrack.trackType()),
2167-
mftTrackProp,
2168-
mchTrackProp,
2162+
static_cast<const o2::track::TrackParCovFwd&>(mftTrackProp),
2163+
static_cast<const o2::track::TrackParCovFwd&>(mchTrackProp),
21692164
matchScore,
21702165
matchChi2,
21712166
-1,
@@ -2180,8 +2175,8 @@ struct QaMatching {
21802175
mchTrackIndex,
21812176
mftTrackIndex,
21822177
static_cast<int>(muonTrack.trackType()),
2183-
mftTrackProp,
2184-
mchTrackProp,
2178+
static_cast<const o2::track::TrackParCovFwd&>(mftTrackProp),
2179+
static_cast<const o2::track::TrackParCovFwd&>(mchTrackProp),
21852180
matchScore,
21862181
matchChi2,
21872182
-1,
@@ -2812,8 +2807,8 @@ struct QaMatching {
28122807
mchIndex,
28132808
mftTrack.globalIndex(),
28142809
candidate.trackType,
2815-
mftTrackProp,
2816-
mchTrackProp,
2810+
static_cast<const o2::track::TrackParCovFwd&>(mftTrackProp),
2811+
static_cast<const o2::track::TrackParCovFwd&>(mchTrackProp),
28172812
matchScore,
28182813
matchChi2,
28192814
-1,
@@ -2827,8 +2822,8 @@ struct QaMatching {
28272822
mchIndex,
28282823
mftTrack.globalIndex(),
28292824
candidate.trackType,
2830-
mftTrackProp,
2831-
mchTrackProp,
2825+
static_cast<const o2::track::TrackParCovFwd&>(mftTrackProp),
2826+
static_cast<const o2::track::TrackParCovFwd&>(mchTrackProp),
28322827
matchScore,
28332828
matchChi2,
28342829
-1,
@@ -2865,7 +2860,7 @@ struct QaMatching {
28652860
TMUON const& muonTracks,
28662861
TMFT const& mftTracks,
28672862
CMFT const& mftCovs,
2868-
std::string label,
2863+
const std::string& label,
28692864
const std::vector<std::pair<int64_t, int64_t>>& matchablePairs,
28702865
const MatchingCandidates& matchingCandidates,
28712866
MatchingCandidates& newMatchingCandidates)
@@ -2898,7 +2893,7 @@ struct QaMatching {
28982893
TMUON const& muonTracks,
28992894
TMFT const& mftTracks,
29002895
CMFT const& mftCovs,
2901-
std::string label,
2896+
const std::string& label,
29022897
const std::vector<std::pair<int64_t, int64_t>>& matchablePairs,
29032898
const MatchingCandidates& matchingCandidates,
29042899
MatchingCandidates& newMatchingCandidates)
@@ -2958,8 +2953,8 @@ struct QaMatching {
29582953
mchIndex,
29592954
mftTrack.globalIndex(),
29602955
candidate.trackType,
2961-
mftTrackProp,
2962-
mchTrackProp,
2956+
static_cast<const o2::track::TrackParCovFwd&>(mftTrackProp),
2957+
static_cast<const o2::track::TrackParCovFwd&>(mchTrackProp),
29632958
matchScore,
29642959
matchChi2,
29652960
-1,
@@ -2973,8 +2968,8 @@ struct QaMatching {
29732968
mchIndex,
29742969
mftTrack.globalIndex(),
29752970
candidate.trackType,
2976-
mftTrackProp,
2977-
mchTrackProp,
2971+
static_cast<const o2::track::TrackParCovFwd&>(mftTrackProp),
2972+
static_cast<const o2::track::TrackParCovFwd&>(mchTrackProp),
29782973
matchScore,
29792974
matchChi2,
29802975
-1,

0 commit comments

Comments
 (0)