Skip to content

Commit 7a03095

Browse files
committed
Common: add fwdtrackUtilities.h
1 parent e858d6a commit 7a03095

2 files changed

Lines changed: 105 additions & 69 deletions

File tree

Common/Core/fwdtrackUtilities.h

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file fwdtrackUtilities.h
13+
/// \brief Utilities for manipulating parameters of fwdtracks
14+
/// \author Maurice Coquet <maurice.louis.coquet@cern.ch>
15+
/// \author Luca Micheletti <luca.micheletti@cern.ch>
16+
/// \author Daiki Sekihata <daiki.sekihata@cern.ch>
17+
18+
#ifndef COMMON_CORE_FWDTRACKUTILITIES_H_
19+
#define COMMON_CORE_FWDTRACKUTILITIES_H_
20+
21+
#include <utility>
22+
#include "Math/SMatrix.h"
23+
#include "TGeoGlobalMagField.h"
24+
25+
namespace o2::aod
26+
{
27+
namespace fwdtrackutils
28+
{
29+
// Index used to set different options for muon propagation
30+
enum class propagationPoint : int {
31+
kToVertex = 0,
32+
kToDCA = 1,
33+
kToRabs = 2,
34+
};
35+
using SMatrix55 = ROOT::Math::SMatrix<double, 5, 5, ROOT::Math::MatRepSym<double, 5>>;
36+
using SMatrix5 = ROOT::Math::SVector<double, 5>;
37+
38+
/// propagate fwdtrack to a certain point.
39+
template <typename TFwdTrack, typename TCollision>
40+
o2::dataformats::GlobalFwdTrack propagateMuon(TFwdTrack const& muon, TCollision const& collision, const propagationPoint endPoint)
41+
{
42+
double chi2 = muon.chi2();
43+
SMatrix5 tpars(muon.x(), muon.y(), muon.phi(), muon.tgl(), muon.signed1Pt());
44+
std::vector<double> v1{muon.cXX(), muon.cXY(), muon.cYY(), muon.cPhiX(), muon.cPhiY(),
45+
muon.cPhiPhi(), muon.cTglX(), muon.cTglY(), muon.cTglPhi(), muon.cTglTgl(),
46+
muon.c1PtX(), muon.c1PtY(), muon.c1PtPhi(), muon.c1PtTgl(), muon.c1Pt21Pt2()};
47+
SMatrix55 tcovs(v1.begin(), v1.end());
48+
o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2};
49+
o2::dataformats::GlobalFwdTrack propmuon;
50+
o2::globaltracking::MatchGlobalFwd mMatching;
51+
52+
if (static_cast<int>(muon.trackType()) > 2) { // MCH-MID or MCH standalone
53+
o2::dataformats::GlobalFwdTrack track;
54+
track.setParameters(tpars);
55+
track.setZ(fwdtrack.getZ());
56+
track.setCovariances(tcovs);
57+
auto mchTrack = mMatching.FwdtoMCH(track);
58+
59+
if (endPoint == propagationPoint::kToVertex) {
60+
o2::mch::TrackExtrap::extrapToVertex(mchTrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY());
61+
}
62+
if (endPoint == propagationPoint::kToDCA) {
63+
o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrack, collision.posZ());
64+
}
65+
if (endPoint == propagationPoint::kToRabs) {
66+
o2::mch::TrackExtrap::extrapToZ(mchTrack, -505.);
67+
}
68+
69+
auto proptrack = mMatching.MCHtoFwd(mchTrack);
70+
propmuon.setParameters(proptrack.getParameters());
71+
propmuon.setZ(proptrack.getZ());
72+
propmuon.setCovariances(proptrack.getCovariances());
73+
} else if (static_cast<int>(muon.trackType()) < 2) { // MFT-MCH-MID
74+
const double centerMFT[3] = {0, 0, -61.4};
75+
o2::field::MagneticField* field = static_cast<o2::field::MagneticField*>(TGeoGlobalMagField::Instance()->GetField());
76+
auto Bz = field->getBz(centerMFT); // Get field at centre of MFT
77+
auto geoMan = o2::base::GeometryManager::meanMaterialBudget(muon.x(), muon.y(), muon.z(), collision.posX(), collision.posY(), collision.posZ());
78+
auto x2x0 = static_cast<float>(geoMan.meanX2X0);
79+
fwdtrack.propagateToVtxhelixWithMCS(collision.posZ(), {collision.posX(), collision.posY()}, {collision.covXX(), collision.covYY()}, Bz, x2x0);
80+
propmuon.setParameters(fwdtrack.getParameters());
81+
propmuon.setZ(fwdtrack.getZ());
82+
propmuon.setCovariances(fwdtrack.getCovariances());
83+
}
84+
85+
v1.clear();
86+
v1.shrink_to_fit();
87+
88+
return propmuon;
89+
}
90+
} // namespace fwdtrackutils
91+
} // namespace o2::aod
92+
93+
#endif // COMMON_CORE_FWDTRACKUTILITIES_H_

Common/TableProducer/fwdtrackPropagation.cxx

Lines changed: 12 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
#include <map>
2121
#include <unordered_map>
2222

23-
#include "Math/SMatrix.h"
24-
2523
#include "Framework/DataTypes.h"
2624
#include "Framework/runDataProcessing.h"
2725
#include "Framework/AnalysisTask.h"
@@ -39,23 +37,18 @@
3937

4038
#include "Common/DataModel/CollisionAssociationTables.h"
4139
#include "Common/DataModel/PropagatedFwdTrackTables.h"
40+
#include "Common/Core/fwdtrackUtilities.h"
4241

4342
using namespace o2;
4443
using namespace o2::aod;
4544
using namespace o2::soa;
4645
using namespace o2::framework;
4746
using namespace o2::framework::expressions;
47+
using namespace o2::aod::fwdtrackutils;
4848

4949
struct FwdTrackPropagation {
5050
using MyFwdTracks = soa::Join<aod::FwdTracks, aod::FwdTracksCov>;
5151

52-
// Index used to set different options for Muon propagation
53-
enum class propagationPoint : int {
54-
kToVertex = 0,
55-
kToDCA = 1,
56-
kToRabs = 2,
57-
};
58-
5952
Produces<aod::StoredPropagatedFwdTracks> propfwdtracks;
6053
Produces<aod::StoredPropagatedFwdTracksCov> propfwdtrackscov;
6154

@@ -156,61 +149,6 @@ struct FwdTrackPropagation {
156149
fRegistry.add("MCHMID/hDCAyResolutionvsPt", "DCA_{y} vs. p_{T};p_{T} (GeV/c);DCA_{y} resolution (#mum);", kTH2F, {{100, 0, 10.f}, {500, 0, 5e+5}}, false);
157150
}
158151

159-
using SMatrix55 = ROOT::Math::SMatrix<double, 5, 5, ROOT::Math::MatRepSym<double, 5>>;
160-
using SMatrix5 = ROOT::Math::SVector<double, 5>;
161-
o2::globaltracking::MatchGlobalFwd mMatching;
162-
163-
template <typename TFwdTrack, typename TCollision>
164-
o2::dataformats::GlobalFwdTrack PropagateMuon(TFwdTrack const& muon, TCollision const& collision, const FwdTrackPropagation::propagationPoint endPoint)
165-
{
166-
double chi2 = muon.chi2();
167-
SMatrix5 tpars(muon.x(), muon.y(), muon.phi(), muon.tgl(), muon.signed1Pt());
168-
std::vector<double> v1{muon.cXX(), muon.cXY(), muon.cYY(), muon.cPhiX(), muon.cPhiY(),
169-
muon.cPhiPhi(), muon.cTglX(), muon.cTglY(), muon.cTglPhi(), muon.cTglTgl(),
170-
muon.c1PtX(), muon.c1PtY(), muon.c1PtPhi(), muon.c1PtTgl(), muon.c1Pt21Pt2()};
171-
SMatrix55 tcovs(v1.begin(), v1.end());
172-
o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2};
173-
o2::dataformats::GlobalFwdTrack propmuon;
174-
175-
if (static_cast<int>(muon.trackType()) > 2) { // MCH-MID or MCH standalone
176-
o2::dataformats::GlobalFwdTrack track;
177-
track.setParameters(tpars);
178-
track.setZ(fwdtrack.getZ());
179-
track.setCovariances(tcovs);
180-
auto mchTrack = mMatching.FwdtoMCH(track);
181-
182-
if (endPoint == FwdTrackPropagation::propagationPoint::kToVertex) {
183-
o2::mch::TrackExtrap::extrapToVertex(mchTrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY());
184-
}
185-
if (endPoint == FwdTrackPropagation::propagationPoint::kToDCA) {
186-
o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrack, collision.posZ());
187-
}
188-
if (endPoint == FwdTrackPropagation::propagationPoint::kToRabs) {
189-
o2::mch::TrackExtrap::extrapToZ(mchTrack, -505.);
190-
}
191-
192-
auto proptrack = mMatching.MCHtoFwd(mchTrack);
193-
propmuon.setParameters(proptrack.getParameters());
194-
propmuon.setZ(proptrack.getZ());
195-
propmuon.setCovariances(proptrack.getCovariances());
196-
} else if (static_cast<int>(muon.trackType()) < 2) { // MFT-MCH-MID
197-
const double centerMFT[3] = {0, 0, -61.4};
198-
o2::field::MagneticField* field = static_cast<o2::field::MagneticField*>(TGeoGlobalMagField::Instance()->GetField());
199-
auto Bz = field->getBz(centerMFT); // Get field at centre of MFT
200-
auto geoMan = o2::base::GeometryManager::meanMaterialBudget(muon.x(), muon.y(), muon.z(), collision.posX(), collision.posY(), collision.posZ());
201-
auto x2x0 = static_cast<float>(geoMan.meanX2X0);
202-
fwdtrack.propagateToVtxhelixWithMCS(collision.posZ(), {collision.posX(), collision.posY()}, {collision.covXX(), collision.covYY()}, Bz, x2x0);
203-
propmuon.setParameters(fwdtrack.getParameters());
204-
propmuon.setZ(fwdtrack.getZ());
205-
propmuon.setCovariances(fwdtrack.getCovariances());
206-
}
207-
208-
v1.clear();
209-
v1.shrink_to_fit();
210-
211-
return propmuon;
212-
}
213-
214152
bool isSelected(const float pt, const float eta, const float rAtAbsorberEnd, const float pDCA, const float chi2, const uint8_t trackType)
215153
{
216154
if (pt < minPt || maxPt < pt) {
@@ -265,8 +203,8 @@ struct FwdTrackPropagation {
265203
}
266204
} // reduce useless propagation
267205

268-
o2::dataformats::GlobalFwdTrack propmuonAtPV = PropagateMuon(fwdtrack, collision, FwdTrackPropagation::propagationPoint::kToVertex);
269-
o2::dataformats::GlobalFwdTrack propmuonAtDCA = PropagateMuon(fwdtrack, collision, FwdTrackPropagation::propagationPoint::kToDCA);
206+
o2::dataformats::GlobalFwdTrack propmuonAtPV = propagateMuon(fwdtrack, collision, propagationPoint::kToVertex);
207+
o2::dataformats::GlobalFwdTrack propmuonAtDCA = propagateMuon(fwdtrack, collision, propagationPoint::kToDCA);
270208

271209
float pt = propmuonAtPV.getPt();
272210
float eta = propmuonAtPV.getEta();
@@ -287,7 +225,7 @@ struct FwdTrackPropagation {
287225
float dFdy = 2.f * dcaY / dcaXY;
288226
float sigma_dcaXY = std::sqrt(cXXatDCA * dFdx * dFdx + cYYatDCA * dFdy * dFdy + 2.f * cXYatDCA * dFdx * dFdy);
289227

290-
float pDCA = fwdtrack.p() * dcaXY; // why not p at PV?
228+
float pDCA = fwdtrack.p() * dcaXY;
291229
int nClustersMFT = 0;
292230
float etaMatchedMCHMID = propmuonAtPV.getEta();
293231
float phiMatchedMCHMID = propmuonAtPV.getPhi();
@@ -302,10 +240,15 @@ struct FwdTrackPropagation {
302240
// etaMatchedMCHMID = mchtrack.eta();
303241
// phiMatchedMCHMID = mchtrack.phi();
304242
// o2::math_utils::bringTo02Pi(phiMatchedMCHMID);
305-
o2::dataformats::GlobalFwdTrack propmuonAtPV_Matched = PropagateMuon(mchtrack, collision, FwdTrackPropagation::propagationPoint::kToVertex);
243+
o2::dataformats::GlobalFwdTrack propmuonAtPV_Matched = propagateMuon(mchtrack, collision, propagationPoint::kToVertex);
306244
etaMatchedMCHMID = propmuonAtPV_Matched.getEta();
307245
phiMatchedMCHMID = propmuonAtPV_Matched.getPhi();
308246
o2::math_utils::bringTo02Pi(phiMatchedMCHMID);
247+
o2::dataformats::GlobalFwdTrack propmuonAtDCA_Matched = propagateMuon(mchtrack, collision, propagationPoint::kToDCA);
248+
float dcaX_Matched = propmuonAtDCA_Matched.getX() - collision.posX();
249+
float dcaY_Matched = propmuonAtDCA_Matched.getY() - collision.posY();
250+
float dcaXY_Matched = std::sqrt(dcaX_Matched * dcaX_Matched + dcaY_Matched * dcaY_Matched);
251+
pDCA = mchtrack.p() * dcaXY_Matched;
309252

310253
const auto& mfttrack = fwdtrack.template matchMFTTrack_as<TMFTTracks>();
311254
nClustersMFT = mfttrack.nClusters();
@@ -322,7 +265,7 @@ struct FwdTrackPropagation {
322265
}
323266
chi2mft = mfttrack.chi2();
324267
} else if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) {
325-
o2::dataformats::GlobalFwdTrack propmuonAtRabs = PropagateMuon(fwdtrack, collision, FwdTrackPropagation::propagationPoint::kToRabs); // this is necessary only for MuonStandaloneTrack
268+
o2::dataformats::GlobalFwdTrack propmuonAtRabs = propagateMuon(fwdtrack, collision, propagationPoint::kToRabs); // this is necessary only for MuonStandaloneTrack
326269
float xAbs = propmuonAtRabs.getX();
327270
float yAbs = propmuonAtRabs.getY();
328271
rAtAbsorberEnd = std::sqrt(xAbs * xAbs + yAbs * yAbs); // Redo propagation only for muon tracks // propagation of MFT tracks alredy done in reconstruction

0 commit comments

Comments
 (0)