forked from AliceO2Group/AliceO2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTrackletTransformer.cxx
More file actions
142 lines (117 loc) · 5.12 KB
/
TrackletTransformer.cxx
File metadata and controls
142 lines (117 loc) · 5.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
#include "DetectorsBase/GeometryManager.h"
#include "DataFormatsTRD/Constants.h"
#include "TRDBase/TrackletTransformer.h"
#include "TMath.h"
using namespace o2::trd;
using namespace o2::trd::constants;
void TrackletTransformer::init()
{
mGeo = Geometry::instance();
mGeo->createPadPlaneArray();
mGeo->createClusterMatrixArray();
// 3.35 cm
mXAnode = mGeo->cdrHght() + mGeo->camHght() / 2;
}
float TrackletTransformer::calculateZ(int padrow, const PadPlane* padPlane) const
{
double rowPos = padPlane->getRowPos(padrow);
double rowSize = padPlane->getRowSize(padrow);
double middleRowPos = padPlane->getRowPos(padPlane->getNrows() / 2);
return rowPos - rowSize / 2. - middleRowPos;
}
float TrackletTransformer::calculateDy(int detector, int slope, const PadPlane* padPlane) const
{
double padWidth = padPlane->getWidthIPad();
float vDrift = mCalVdriftExB->getVdrift(detector);
float exb = mCalVdriftExB->getExB(detector);
// dy = slope * nTimeBins * padWidth * GRANULARITYTRKLSLOPE;
// nTimeBins should be number of timebins in drift region. 1 timebin is 100 nanosecond
double rawDy = slope * ((mGeo->cdrHght() / vDrift) * 10.) * padWidth * GRANULARITYTRKLSLOPE / ADDBITSHIFTSLOPE;
// NOTE: check what drift height is used in calibration code to ensure consistency
// NOTE: check sign convention of Lorentz angle
// NOTE: confirm the direction in which vDrift is measured/determined. Is it in x or in direction of drift?
// The Lorentz correction have to be applied both at the point of entrance and at the end of the drift region
double lorentzCorrection = TMath::Tan(exb) * mGeo->cdrHght();
// assuming angle in Bailhache, fig. 4.17 would be positive in our calibration code
double calibratedDy = rawDy - lorentzCorrection;
return calibratedDy;
}
float TrackletTransformer::calibrateX(double x) const
{
// Hard-coded value will be replaced once t0 calibration is available from CCDB
float t0Correction = -0.279;
return x += t0Correction;
}
std::array<float, 3> TrackletTransformer::transformL2T(int detector, std::array<double, 3> point) const
{
auto transformationMatrix = mGeo->getMatrixT2L(detector);
ROOT::Math::Impl::Transform3D<double>::Point localPoint(point[0], point[1], point[2]);
auto gobalPoint = transformationMatrix ^ localPoint;
return {(float)gobalPoint.x(), (float)gobalPoint.y(), (float)gobalPoint.z()};
}
CalibratedTracklet TrackletTransformer::transformTracklet(Tracklet64 tracklet, bool trackingFrame) const
{
auto detector = tracklet.getDetector();
auto hcid = tracklet.getHCID();
auto padrow = tracklet.getPadRow();
auto column = tracklet.getColumn();
int position;
int slope;
if (mApplyXOR) {
position = tracklet.getPosition() ^ 0x80;
if (position & (1 << (constants::NBITSTRKLPOS - 1))) {
position = -((~(position - 1)) & ((1 << constants::NBITSTRKLPOS) - 1));
}
slope = tracklet.getSlope() ^ 0x80;
if (slope & (1 << (constants::NBITSTRKLSLOPE - 1))) {
slope = -((~(slope - 1)) & ((1 << constants::NBITSTRKLSLOPE) - 1));
}
} else {
position = tracklet.getPositionBinSigned();
slope = tracklet.getSlopeBinSigned();
}
// calculate raw local chamber space point
const auto padPlane = mGeo->getPadPlane(detector);
// 5mm below cathode plane to reduce error propogation from tracklet fit and driftV
float x = mGeo->cdrHght() - 0.5;
float y = tracklet.getUncalibratedY(mApplyShift);
float z = calculateZ(padrow, padPlane);
float dy = calculateDy(detector, slope, padPlane);
float calibratedX = calibrateX(x);
// NOTE: Correction to y position based on x calibration NOT YET implemented. Need t0.
if (trackingFrame) {
std::array<float, 3> sectorSpacePoint = transformL2T(detector, std::array<double, 3>{calibratedX, y, z});
LOG(debug) << "x: " << sectorSpacePoint[0] << " | "
<< "y: " << sectorSpacePoint[1] << " | "
<< "z: " << sectorSpacePoint[2];
return CalibratedTracklet(sectorSpacePoint[0], sectorSpacePoint[1], sectorSpacePoint[2], dy);
} else {
return CalibratedTracklet(calibratedX, y, z, dy); // local frame
}
}
double TrackletTransformer::getTimebin(int detector, double x) const
{
// calculate timebin from x position within chamber
float vDrift = mCalVdriftExB->getVdrift(detector);
double t0 = 4.0; // time (in timebins) of start of drift region
double timebin;
// x = 0 at anode plane and points toward pad plane.
if (x < -mGeo->camHght() / 2) {
// drift region
timebin = t0 - (x + mGeo->camHght() / 2) / (vDrift * 0.1);
} else {
// anode region: very rough guess
timebin = t0 - 1.0 + fabs(x);
}
return timebin;
}