Project
Loading...
Searching...
No Matches
Tracking.cxx
Go to the documentation of this file.
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
15
17#include "TRDQC/Tracking.h"
20#include "TRDBase/Geometry.h"
21#include "TRDBase/PadPlane.h"
22#include <fairlogger/Logger.h>
23
24using namespace o2::trd;
25using namespace o2::trd::constants;
26
28{
29 mRecoParam.init(o2::base::Propagator::Instance()->getNominalBz());
30}
31
33{
34 mTracksTPC = input.getTPCTracks();
35 mTracksITSTPC = input.getTPCITSTracks();
36 mTracksITSTPCTRD = input.getITSTPCTRDTracks<TrackTRD>();
37 mTracksTPCTRD = input.getTPCTRDTracks<TrackTRD>();
38 mTrackletsRaw = input.getTRDTracklets();
39 mTrackletsCalib = input.getTRDCalibratedTracklets();
40 mTrackTriggerRecordsITSTPCTRD = input.getITSTPCTRDTriggers();
41 mTrackTriggerRecordsTPCTRD = input.getTPCTRDTriggers();
42}
43
45{
46 mCurrentTriggerRecord = 0;
47 mCurrentTrackId = 0;
48 for (const auto& trkTrd : mTracksTPCTRD) {
49 checkTrack(trkTrd, true);
50 mCurrentTrackId++;
51 }
52 mCurrentTriggerRecord = 0;
53 mCurrentTrackId = 0;
54 for (const auto& trkTrd : mTracksITSTPCTRD) {
55 checkTrack(trkTrd, false);
56 mCurrentTrackId++;
57 }
58}
59
60void Tracking::checkTrack(const TrackTRD& trkTrd, bool isTPCTRD)
61{
62 auto propagator = o2::base::Propagator::Instance();
63 auto id = trkTrd.getRefGlobalTrackId();
64 TrackQC qcStruct;
65
66 qcStruct.refGlobalTrackId = id;
67 qcStruct.trackTRD = trkTrd;
68
69 LOGF(debug, "Got track with %i tracklets and ID %i", trkTrd.getNtracklets(), (int)id);
70 o2::track::TrackParCov trk = isTPCTRD ? mTracksTPC[id].getParamOut() : mTracksITSTPC[id].getParamOut();
71 qcStruct.trackSeed = trk;
72 if (mPID) {
73 qcStruct.dEdxTotTPC = isTPCTRD ? mTracksTPC[id].getdEdx().dEdxTotTPC : mTracksTPC[mTracksITSTPC[id].getRefTPC()].getdEdx().dEdxTotTPC;
74 }
75
76 // find corresponding track trigger record to get track timing
77 int triggeredBC = 0;
78 for (; mCurrentTriggerRecord < (isTPCTRD ? mTrackTriggerRecordsTPCTRD.size() : mTrackTriggerRecordsITSTPCTRD.size()); mCurrentTriggerRecord++) {
79 auto& tRecord = (isTPCTRD ? mTrackTriggerRecordsTPCTRD[mCurrentTriggerRecord] : mTrackTriggerRecordsITSTPCTRD[mCurrentTriggerRecord]);
80 if (mCurrentTrackId >= tRecord.getFirstTrack() && mCurrentTrackId < tRecord.getFirstTrack() + tRecord.getNumberOfTracks()) {
81 triggeredBC = tRecord.getBCData().differenceInBC({0, mFirstOrbit});
82 break;
83 }
84 }
85
86 // Find most probable BCs and RMS for pile-up correction and error. Same BC is assumed for all tracklets
87 float tCorrPileUp = 0.;
88 float tErrPileUp2 = 0;
89 float maxProb = 0.f;
90 // The uncertainty is the RMS wrt the default correction of all possible corrections weighted by their probability
91 float sumCorr = 0.f;
92 float sumCorr2 = 0.f;
93 float sumProb = 0.f;
94 for (int iBC = 0; iBC < mTriggeredBCFT0.size(); iBC++) {
95 int deltaBC = roundf(mTriggeredBCFT0[iBC] - triggeredBC);
96 if (deltaBC <= mRecoParam.getPileUpRangeBefore()) {
97 continue;
98 }
99 if (deltaBC >= mRecoParam.getPileUpRangeAfter()) {
100 break;
101 }
102 // collect the charges
103 std::array<int, 6> q0;
104 std::array<int, 6> q1;
105 for (int iLy = 0; iLy < NLAYER; iLy++) {
106 int trkltId = trkTrd.getTrackletIndex(iLy);
107 if (trkltId < 0) {
108 q0[iLy] = -1;
109 q1[iLy] = -1;
110 } else {
111 q0[iLy] = mTrackletsRaw[trkltId].getQ0();
112 q1[iLy] = mTrackletsRaw[trkltId].getQ1();
113 }
114 }
115 // get pile-up probability
116 float probBC = mRecoParam.getPileUpProbTrack(deltaBC, q0, q1);
117 sumCorr += probBC * deltaBC;
118 sumCorr2 += probBC * deltaBC * deltaBC;
119 sumProb += probBC;
120 if (probBC > maxProb) {
121 maxProb = probBC;
122 tCorrPileUp = -deltaBC;
123 }
124 }
125 if (sumProb > 1e-6) {
126 tErrPileUp2 = sumCorr2 / sumProb - 2 * tCorrPileUp * sumCorr / sumProb + tCorrPileUp * tCorrPileUp;
127 }
128
129 for (int iLayer = 0; iLayer < NLAYER; ++iLayer) {
130 int trkltId = trkTrd.getTrackletIndex(iLayer);
131 if (trkltId < 0) {
132 continue;
133 }
134 const auto& tracklet = mTrackletsRaw[trkltId];
135 qcStruct.trklt64[iLayer] = tracklet;
136 qcStruct.trkltCalib[iLayer] = mTrackletsCalib[trkltId];
137 int trkltDet = tracklet.getDetector();
138 int trkltSec = trkltDet / (NLAYER * NSTACK);
139 if (trkltSec != o2::math_utils::angle2Sector(trk.getAlpha())) {
140 if (!trk.rotate(o2::math_utils::sector2Angle(trkltSec))) {
141 LOGF(debug, "Track could not be rotated in tracklet coordinate system");
142 break;
143 }
144 }
145 if (!propagator->PropagateToXBxByBz(trk, mTrackletsCalib[trkltId].getX(), mMaxSnp, mMaxStep, mMatCorr)) {
146 LOGF(debug, "Track propagation failed in layer %i (pt=%f, xTrk=%f, xToGo=%f)", iLayer, trk.getPt(), trk.getX(), mTrackletsCalib[trkltId].getX());
147 break;
148 }
149 const PadPlane* pad = Geometry::instance()->getPadPlane(trkltDet);
150 float tilt = tan(TMath::DegToRad() * pad->getTiltingAngle()); // tilt is signed! and returned in degrees
151 float tiltCorrUp = tilt * (mTrackletsCalib[trkltId].getZ() - trk.getZ());
152 float dyTiltCorr = tilt * trk.getTgl() * Geometry::instance()->cdrHght();
153 float zPosCorrUp = mTrackletsCalib[trkltId].getZ() + mRecoParam.getZCorrCoeffNRC() * trk.getTgl();
154 float padLength = pad->getRowSize(tracklet.getPadRow());
155 if (!((trk.getSigmaZ2() < (padLength * padLength / 12.f)) && (std::fabs(mTrackletsCalib[trkltId].getZ() - trk.getZ()) < padLength))) {
156 tiltCorrUp = 0.f;
157 }
158
159 // conversion from slope in pad per time bin to slope in cm per BC = tracklets[trkltIdx].getSlopeFloat() * padWidth / BCperTimeBin
160 float slopeFactor = mTrackletsRaw[trkltId].getSlopeFloat() * pad->getWidthIPad() / 4.f;
161 float yCorrPileUp = tCorrPileUp * slopeFactor;
162 float yAddErrPileUp2 = tErrPileUp2 * slopeFactor * slopeFactor;
163
164 float angularPull = (mTrackletsCalib[trkltId].getDy() + dyTiltCorr - mRecoParam.convertAngleToDy(trk.getSnp())) / std::sqrt(mRecoParam.getDyRes(trk.getSnp(), 0));
165
166 std::array<float, 2> trkltPosUp{mTrackletsCalib[trkltId].getY() - tiltCorrUp + yCorrPileUp, zPosCorrUp};
167 std::array<float, 3> trkltCovUp;
168 mRecoParam.recalcTrkltCov(tilt, trk.getSnp(), pad->getRowSize(tracklet.getPadRow()), trkltCovUp, angularPull, 0);
169 trkltCovUp[0] += yAddErrPileUp2;
170 auto chi2trklt = trk.getPredictedChi2(trkltPosUp, trkltCovUp);
171
172 qcStruct.trackProp[iLayer] = trk;
173 qcStruct.trackletY[iLayer] = trkltPosUp[0];
174 qcStruct.trackletZ[iLayer] = trkltPosUp[1];
175 qcStruct.trackletChi2[iLayer] = chi2trklt;
176
178 // To correct for longer drift lengths in the drfit chamber and hence more energy deposition,
179 // we calculate the variation to reference for the tracklets (exrapolated from the track fit).
180 // \sqrt{ (dx/dx)^2 + (dy/dx)^2 + (dz/dx)^2}
181 auto tphi = trk.getSnp() / std::sqrt((1.f - trk.getSnp()) * (1.f + trk.getSnp()));
182 auto trackletLength = std::sqrt(1.f + tphi * tphi + trk.getTgl() * trk.getTgl());
183 auto cor = mLocalGain.getValue(tracklet.getHCID() / 2, tracklet.getPadCol(mApplyShift), tracklet.getPadRow()) * trackletLength;
184 float q0{tracklet.getQ0() / cor}, q1{tracklet.getQ1() / cor}, q2{tracklet.getQ2() / cor};
185
186 // z-row merging
187 if (trkTrd.getIsCrossingNeighbor(iLayer) && trkTrd.getHasNeighbor()) {
188 for (const auto& trklt : mTrackletsRaw) {
189 if (tracklet.getTrackletWord() == trklt.getTrackletWord()) { // skip original tracklet
190 continue;
191 }
192 if (std::abs(tracklet.getPadCol(mApplyShift) - trklt.getPadCol(mApplyShift)) <= 1 && std::abs(tracklet.getPadRow() - trklt.getPadRow()) == 1) {
193 // Add charge information
194 auto cor = mLocalGain.getValue(trklt.getHCID() / 2, trklt.getPadCol(mApplyShift), trklt.getPadRow()) * trackletLength;
195 q0 += trklt.getQ0() / cor;
196 q1 += trklt.getQ1() / cor;
197 q2 += trklt.getQ2() / cor;
198 break;
199 }
200 }
201 }
202
203 qcStruct.trackletCorCharges[iLayer] = {q0, q1, q2};
204 }
205 mTrackQC.push_back(qcStruct);
206}
Wrapper container for different reconstructed object types.
Definition of the GeometryManager class.
std::ostringstream debug
Check the performance of the TRD in global tracking.
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
Definition Propagator.h:178
void init(float bz, const GPUSettingsRec *rec=nullptr)
Load parameterization for given magnetic field.
static Geometry * instance()
Definition Geometry.h:33
T getValue(int roc, int col, int row) const
void setInput(const o2::globaltracking::RecoContainer &input)
Initialize the input arrays.
Definition Tracking.cxx:32
void run()
Main processing function.
Definition Tracking.cxx:44
void checkTrack(const TrackTRD &trk, bool isTPCTRD)
Check track QC.
Definition Tracking.cxx:60
void init()
Load geometry and apply magnetic field setting.
Definition Tracking.cxx:27
GLuint id
Definition glcorearb.h:650
int angle2Sector(float phi)
Definition Utils.h:183
float sector2Angle(int sect)
Definition Utils.h:193
TrackParCovF TrackParCov
Definition Track.h:33
constexpr int NLAYER
the number of layers
Definition Constants.h:27
constexpr int NSTACK
the number of stacks per sector
Definition Constants.h:26
gsl::span< const o2::trd::CalibratedTracklet > getTRDCalibratedTracklets() const
gsl::span< const o2::trd::Tracklet64 > getTRDTracklets() const
float dEdxTotTPC
raw total dEdx information for seeding track in TPC
Definition Tracking.h:55
std::array< o2::track::TrackPar, constants::NLAYER > trackProp
the track parameters stored at the radius where the track is updated with TRD info
Definition Tracking.h:57
GTrackID refGlobalTrackId
GlobalTrackID of the seeding track (either ITS-TPC or TPC)
Definition Tracking.h:52
std::array< float, constants::NLAYER > trackletChi2
estimated chi2 for the update of the track with the given tracklet
Definition Tracking.h:63
std::array< CalibratedTracklet, constants::NLAYER > trkltCalib
the TRD space point used for the update (not yet tilt-corrected and z-shift corrected)
Definition Tracking.h:59
TrackTRD trackTRD
the found TRD track
Definition Tracking.h:53
std::array< float, constants::NLAYER > trackletY
y-position of tracklet used for track update (including correction)
Definition Tracking.h:61
std::array< std::array< float, constants::NCHARGES >, constants::NLAYER > trackletCorCharges
corrected charges of tracklets
Definition Tracking.h:64
std::array< Tracklet64, constants::NLAYER > trklt64
the raw tracklet used for the update (includes uncorrected charges)
Definition Tracking.h:58
std::array< float, constants::NLAYER > trackletZ
z-position of tracklet used for track update (including correction)
Definition Tracking.h:62
o2::track::TrackParCov trackSeed
outer param of the seeding track
Definition Tracking.h:54