|
| 1 | +// Copyright CERN and copyright holders of ALICE O2. This software is |
| 2 | +// distributed under the terms of the GNU General Public License v3 (GPL |
| 3 | +// Version 3), copied verbatim in the file "COPYING". |
| 4 | +// |
| 5 | +// See http://alice-o2.web.cern.ch/license for full licensing information. |
| 6 | +// |
| 7 | +// In applying this license CERN does not waive the privileges and immunities |
| 8 | +// granted to it by virtue of its status as an Intergovernmental Organization |
| 9 | +// or submit itself to any jurisdiction. |
| 10 | + |
| 11 | +#include "DetectorsBase/GeometryManager.h" |
| 12 | +#include "TRDBase/TrackletTransformer.h" |
| 13 | +#include "TMath.h" |
| 14 | + |
| 15 | +using namespace o2::trd; |
| 16 | +using namespace o2::trd::constants; |
| 17 | + |
| 18 | +TrackletTransformer::TrackletTransformer() |
| 19 | +{ |
| 20 | + o2::base::GeometryManager::loadGeometry(); |
| 21 | + mGeo = Geometry::instance(); |
| 22 | + mGeo->createPadPlaneArray(); |
| 23 | + mGeo->createClusterMatrixArray(); |
| 24 | + |
| 25 | + // 3 cm |
| 26 | + mXCathode = mGeo->cdrHght(); |
| 27 | + // 2.221 |
| 28 | + // mXAnode = mGeo->anodePos(); |
| 29 | + // 3.35 |
| 30 | + mXAnode = mGeo->cdrHght() + mGeo->camHght() / 2; |
| 31 | + // 2.5 |
| 32 | + mXDrift = mGeo->cdrHght() - 0.5; |
| 33 | + mXtb0 = -100; |
| 34 | + |
| 35 | + // dummy values for testing. This will change in the future when values are pulled from CCDB |
| 36 | + mt0Correction = -0.1; |
| 37 | + mOldLorentzAngle = 0.16; |
| 38 | + mLorentzAngle = -0.14; |
| 39 | + mDriftVRatio = 1.1; |
| 40 | +} |
| 41 | + |
| 42 | +void TrackletTransformer::loadPadPlane(int hcid) |
| 43 | +{ |
| 44 | + int detector = hcid / 2; |
| 45 | + int stack = mGeo->getStack(detector); |
| 46 | + int layer = mGeo->getLayer(detector); |
| 47 | + mPadPlane = mGeo->getPadPlane(layer, stack); |
| 48 | +} |
| 49 | + |
| 50 | +float TrackletTransformer::calculateY(int hcid, int column, int position) |
| 51 | +{ |
| 52 | + double padWidth = mPadPlane->getWidthIPad(); |
| 53 | + int side = hcid % 2; |
| 54 | + |
| 55 | + // slightly modified TDP eq 16.1 (appended -1 to the end to account for MCM shared pads) |
| 56 | + double pad = float(position - (1 << (NBITSTRKLPOS - 1))) * GRANULARITYTRKLPOS + NCOLMCM * (4 * side + column) + 10.5 - 1; |
| 57 | + float y = padWidth * (pad - 72); |
| 58 | + |
| 59 | + return y; |
| 60 | +} |
| 61 | + |
| 62 | +float TrackletTransformer::calculateZ(int padrow) |
| 63 | +{ |
| 64 | + double rowPos = mPadPlane->getRowPos(padrow); |
| 65 | + double rowWidth = mPadPlane->getRowSize(padrow); |
| 66 | + double middleRowPos = mPadPlane->getRowPos(mPadPlane->getNrows() / 2); |
| 67 | + |
| 68 | + float z = rowPos - rowWidth / 2. - middleRowPos; |
| 69 | + |
| 70 | + return z; |
| 71 | +} |
| 72 | + |
| 73 | +float TrackletTransformer::calculateDy(int slope, double oldLorentzAngle, double lorentzAngle, double driftVRatio) |
| 74 | +{ |
| 75 | + double padWidth = mPadPlane->getWidthIPad(); |
| 76 | + |
| 77 | + // temporary dummy value in cm/microsecond |
| 78 | + float vDrift = 1.56; |
| 79 | + float driftHeight = mGeo->cdrHght(); |
| 80 | + |
| 81 | + // dy = slope * nTimeBins * padWidth * GRANULARITYTRKLSLOPE; |
| 82 | + // nTimeBins should be number of timebins in drift region. 1 timebin is 100 nanosecond |
| 83 | + double rawDy = slope * ((driftHeight / vDrift) / 0.1) * padWidth * GRANULARITYTRKLSLOPE; |
| 84 | + |
| 85 | + // driftDistance = 3.35 |
| 86 | + float driftDistance = mGeo->cdrHght() + mGeo->camHght(); |
| 87 | + |
| 88 | + float cmSlope = rawDy / driftDistance; |
| 89 | + |
| 90 | + double calibratedDy = rawDy - (TMath::Tan(lorentzAngle) * driftDistance); |
| 91 | + calibratedDy += (TMath::Tan(oldLorentzAngle) * driftDistance * driftVRatio) + cmSlope * (driftDistance * (1 - driftVRatio)); |
| 92 | + |
| 93 | + // ALTERNATIVE METHOD |
| 94 | + |
| 95 | + // double x_anode_hit = driftDistance*driftVRatio/cmSlope; |
| 96 | + // double y_anode_hit = driftDistance*driftVRatio; |
| 97 | + |
| 98 | + // double x_Lorentz_drift_hit = TMath::Tan(oldLorentzAngle)*driftDistance*driftVRatio - TMath::Tan(lorentzAngle)*driftDistance; |
| 99 | + // double y_Lorentz_drift_hit = driftDistance*driftVRatio - driftDistance; |
| 100 | + |
| 101 | + // double Delta_x_Lorentz_drift_hit = x_anode_hit - x_Lorentz_drift_hit; |
| 102 | + // double Delta_y_Lorentz_drift_hit = y_anode_hit - y_Lorentz_drift_hit; |
| 103 | + // double impact_angle_rec = TMath::ATan2(Delta_y_Lorentz_drift_hit,Delta_x_Lorentz_drift_hit); |
| 104 | + |
| 105 | + // float calibrationShift = TMath::Tan(impact_angle_rec) * driftDistance; |
| 106 | + |
| 107 | + // LOG(info) << "ORIGINAL: " << calibratedDy; |
| 108 | + // LOG(info) << "ALTERNATIVE: " << rawDy + calibrationShift; |
| 109 | + |
| 110 | + return calibratedDy; |
| 111 | +} |
| 112 | + |
| 113 | +float TrackletTransformer::calibrateX(double x, double t0Correction) |
| 114 | +{ |
| 115 | + return x += t0Correction; |
| 116 | +} |
| 117 | + |
| 118 | +std::array<float, 3> TrackletTransformer::transformL2T(int hcid, std::array<double, 3> point) |
| 119 | +{ |
| 120 | + int detector = hcid / 2; |
| 121 | + auto transformationMatrix = mGeo->getMatrixT2L(detector); |
| 122 | + |
| 123 | + ROOT::Math::Impl::Transform3D<double>::Point localPoint(point[0], point[1], point[2]); |
| 124 | + auto gobalPoint = transformationMatrix ^ localPoint; |
| 125 | + |
| 126 | + return {(float)gobalPoint.x(), (float)gobalPoint.y(), (float)gobalPoint.z()}; |
| 127 | +} |
| 128 | + |
| 129 | +CalibratedTracklet TrackletTransformer::transformTracklet(Tracklet64 tracklet) |
| 130 | +{ |
| 131 | + uint64_t trackletWord = tracklet.getTrackletWord(); |
| 132 | + uint64_t hcid = tracklet.getHCID(); |
| 133 | + uint64_t padrow = tracklet.getPadRow(); |
| 134 | + uint64_t column = tracklet.getColumn(); |
| 135 | + // 0-2048 | units:pad-widths | granularity=1/75 (measured from center pad 10) 1024 is 0/center of pad 10 |
| 136 | + uint64_t position = tracklet.getPosition(); |
| 137 | + // 0-127 | units:pads/timebin | granularity=1/1000 |
| 138 | + uint64_t slope = tracklet.getSlope(); |
| 139 | + |
| 140 | + // calculate raw local chamber space point |
| 141 | + loadPadPlane(hcid); |
| 142 | + float x = getXDrift(); |
| 143 | + float y = calculateY(hcid, column, position); |
| 144 | + float z = calculateZ(padrow); |
| 145 | + |
| 146 | + float dy = calculateDy(slope, mOldLorentzAngle, mLorentzAngle, mDriftVRatio); |
| 147 | + float calibratedX = calibrateX(x, mt0Correction); |
| 148 | + |
| 149 | + std::array<float, 3> sectorSpacePoint = transformL2T(hcid, std::array<double, 3>{x, y, z}); |
| 150 | + |
| 151 | + LOG(debug) << "x: " << sectorSpacePoint[0] << " | " |
| 152 | + << "y: " << sectorSpacePoint[1] << " | " |
| 153 | + << "z: " << sectorSpacePoint[2]; |
| 154 | + |
| 155 | + CalibratedTracklet calibratedTracklet = CalibratedTracklet(trackletWord, sectorSpacePoint[0], sectorSpacePoint[1], sectorSpacePoint[2], dy); |
| 156 | + |
| 157 | + return calibratedTracklet; |
| 158 | +} |
0 commit comments