|
| 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 TPCFastTransformGeoPOD.h |
| 13 | +/// \brief Version using constexpr GPUTPCGeometry to be used for TPCFastTransformationPOD |
| 14 | +/// |
| 15 | +/// \author David Rohr <drohr@cern.ch> |
| 16 | + |
| 17 | +#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_TPCFASTTRANSFORMGEOPOD_H |
| 18 | +#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_TPCFASTTRANSFORMGEOPOD_H |
| 19 | + |
| 20 | +#include "GPUCommonDef.h" |
| 21 | +#include "GPUCommonMath.h" |
| 22 | +#include "GPUTPCGeometry.h" |
| 23 | + |
| 24 | +namespace o2::gpu |
| 25 | +{ |
| 26 | + |
| 27 | +/// |
| 28 | +/// The TPCFastTransformGeoPOD class contains TPC geometry needed for the TPCFastTransform |
| 29 | +/// |
| 30 | +struct TPCFastTransformGeoPOD { |
| 31 | + /// The struct contains necessary info for TPC sector |
| 32 | + struct SectorInfo { |
| 33 | + float sinAlpha{0.f}; ///< sin of the angle between the local x and the global x |
| 34 | + float cosAlpha{0.f}; ///< cos of the angle between the local x and the global x |
| 35 | + }; |
| 36 | + |
| 37 | + /// The struct contains necessary info about TPC padrow |
| 38 | + struct RowInfo { |
| 39 | + float x{0.f}; ///< nominal X coordinate of the padrow [cm] |
| 40 | + int32_t maxPad{0}; ///< maximal pad number = n pads - 1 |
| 41 | + float padWidth{0.f}; ///< width of pads [cm] |
| 42 | + float yMin{0.f}; ///< min. y coordinate |
| 43 | + |
| 44 | + /// get Y min |
| 45 | + GPUdi() float getYmin() const { return yMin; } |
| 46 | + |
| 47 | + /// get Y max |
| 48 | + GPUdi() float getYmax() const { return -yMin; } |
| 49 | + |
| 50 | + /// get width in Y |
| 51 | + GPUdi() float getYwidth() const { return -2.f * yMin; } |
| 52 | + }; |
| 53 | + |
| 54 | + /// Gives number of TPC sectors |
| 55 | + inline static constexpr int32_t getNumberOfSectors() { return GPUTPCGeometry::NSECTORS; } |
| 56 | + |
| 57 | + /// Gives number of TPC sectors on the A side |
| 58 | + inline static constexpr int32_t getNumberOfSectorsA() { return GPUTPCGeometry::NSECTORS / 2; } |
| 59 | + |
| 60 | + /// Gives number of TPC rows |
| 61 | + GPUdi() int32_t getNumberOfRows() const { return GPUTPCGeometry::NROWS; } |
| 62 | + |
| 63 | + /// Gives sector info |
| 64 | + GPUd() const SectorInfo& getSectorInfo(uint32_t sector) const; |
| 65 | + |
| 66 | + /// Gives TPC row info |
| 67 | + GPUd() float getRowInfoX(uint32_t row) const { return GPUTPCGeometry::Row2X(row); } |
| 68 | + GPUd() int32_t getRowInfoMaxPad(uint32_t row) const { return GPUTPCGeometry::NPads(row) - 1; } |
| 69 | + GPUd() float getRowInfoPadWidth(uint32_t row) const { return GPUTPCGeometry::PadWidth(row); } |
| 70 | + |
| 71 | + /// Gives Z length of the TPC, one Z side |
| 72 | + GPUdi() float getTPCzLength() const { return GPUTPCGeometry::TPCLength(); } |
| 73 | + |
| 74 | + /// Gives Z range for the corresponding TPC side |
| 75 | + GPUd() float getZmin(uint32_t sector) const; |
| 76 | + GPUd() float getZmax(uint32_t sector) const; |
| 77 | + GPUd() float getZreadout(uint32_t sector) const; |
| 78 | + |
| 79 | + /// _______________ Conversion of coordinate systems __________ |
| 80 | + |
| 81 | + /// convert Local -> Global c.s. |
| 82 | + GPUd() void convLocalToGlobal(uint32_t sector, float lx, float ly, float lz, float& gx, float& gy, float& gz) const; |
| 83 | + |
| 84 | + /// convert Global->Local c.s. |
| 85 | + GPUd() void convGlobalToLocal(uint32_t sector, float gx, float gy, float gz, float& lx, float& ly, float& lz) const; |
| 86 | + |
| 87 | + /// convert Pad, DriftLength -> Local c.s. |
| 88 | + GPUd() void convPadDriftLengthToLocal(uint32_t sector, uint32_t row, float pad, float driftLength, float& y, float& z) const; |
| 89 | + |
| 90 | + /// convert DriftLength -> Local c.s. |
| 91 | + GPUd() float convDriftLengthToZ1(uint32_t sector, float driftLength) const; |
| 92 | + |
| 93 | + /// convert Z to DriftLength |
| 94 | + GPUd() float convZtoDriftLength1(uint32_t sector, float z) const; |
| 95 | + |
| 96 | + /// convert Local c.s. -> Pad, DriftLength |
| 97 | + GPUd() void convLocalToPadDriftLength(uint32_t sector, uint32_t row, float y, float z, float& pad, float& l) const; |
| 98 | + |
| 99 | + private: |
| 100 | + /// _______________ Data members _______________________________________________ |
| 101 | + |
| 102 | + uint32_t mConstructionMask = 0; |
| 103 | + |
| 104 | + /// _______________ Geometry _______________________________________________ |
| 105 | + |
| 106 | + int32_t mNumberOfRows = 0; ///< Number of TPC rows. It is different for the Run2 and the Run3 setups |
| 107 | + float mTPCzLength = 0.f; ///< Z length of one TPC side (A or C) |
| 108 | + |
| 109 | + SectorInfo mSectorInfos[GPUTPCGeometry::NSECTORS + 1]; ///< array of sector information [fixed size] |
| 110 | + RowInfo mRowInfos[160 + 1]; ///< array of row information [fixed size] |
| 111 | +}; |
| 112 | + |
| 113 | +// ======================================================================= |
| 114 | +// Inline implementations of some methods |
| 115 | +// ======================================================================= |
| 116 | + |
| 117 | +GPUdi() const TPCFastTransformGeoPOD::SectorInfo& TPCFastTransformGeoPOD::getSectorInfo(uint32_t sector) const |
| 118 | +{ |
| 119 | + return mSectorInfos[sector]; |
| 120 | +} |
| 121 | + |
| 122 | +GPUdi() void TPCFastTransformGeoPOD::convLocalToGlobal(uint32_t sector, float lx, float ly, float lz, float& gx, float& gy, float& gz) const |
| 123 | +{ |
| 124 | + /// convert Local -> Global c.s. |
| 125 | + const SectorInfo& sectorInfo = getSectorInfo(sector); |
| 126 | + gx = lx * sectorInfo.cosAlpha - ly * sectorInfo.sinAlpha; |
| 127 | + gy = lx * sectorInfo.sinAlpha + ly * sectorInfo.cosAlpha; |
| 128 | + gz = lz; |
| 129 | +} |
| 130 | + |
| 131 | +GPUdi() void TPCFastTransformGeoPOD::convGlobalToLocal(uint32_t sector, float gx, float gy, float gz, float& lx, float& ly, float& lz) const |
| 132 | +{ |
| 133 | + /// convert Global -> Local c.s. |
| 134 | + const SectorInfo& sectorInfo = getSectorInfo(sector); |
| 135 | + lx = gx * sectorInfo.cosAlpha + gy * sectorInfo.sinAlpha; |
| 136 | + ly = -gx * sectorInfo.sinAlpha + gy * sectorInfo.cosAlpha; |
| 137 | + lz = gz; |
| 138 | +} |
| 139 | + |
| 140 | +GPUdi() void TPCFastTransformGeoPOD::convPadDriftLengthToLocal(uint32_t sector, uint32_t row, float pad, float driftLength, float& y, float& z) const |
| 141 | +{ |
| 142 | + /// convert Pad, DriftLength -> Local c.s. |
| 143 | + const float maxPad = getRowInfoMaxPad(row); |
| 144 | + const float padWidth = getRowInfoPadWidth(row); |
| 145 | + const float u = (pad - 0.5f * maxPad) * padWidth; |
| 146 | + if (sector < getNumberOfSectorsA()) { // TPC side A |
| 147 | + y = u; |
| 148 | + z = getTPCzLength() - driftLength; |
| 149 | + } else { // TPC side C |
| 150 | + y = -u; // pads are mirrorred on C-side |
| 151 | + z = driftLength - getTPCzLength(); // drift direction is mirrored on C-side |
| 152 | + } |
| 153 | +} |
| 154 | + |
| 155 | +GPUdi() float TPCFastTransformGeoPOD::convDriftLengthToZ1(uint32_t sector, float driftLength) const |
| 156 | +{ |
| 157 | + /// convert DriftLength -> Local c.s. |
| 158 | + return (sector < getNumberOfSectorsA()) ? (getTPCzLength() - driftLength) : (driftLength - getTPCzLength()); |
| 159 | +} |
| 160 | + |
| 161 | +GPUdi() float TPCFastTransformGeoPOD::convZtoDriftLength1(uint32_t sector, float z) const |
| 162 | +{ |
| 163 | + /// convert Z to DriftLength |
| 164 | + return (sector < getNumberOfSectorsA()) ? (getTPCzLength() - z) : (z + getTPCzLength()); |
| 165 | +} |
| 166 | + |
| 167 | +GPUdi() float TPCFastTransformGeoPOD::getZmin(uint32_t sector) const |
| 168 | +{ |
| 169 | + /// z min for the sector |
| 170 | + if (sector < getNumberOfSectorsA()) { // TPC side A |
| 171 | + return 0.f; |
| 172 | + } else { // TPC side C |
| 173 | + return -getTPCzLength(); |
| 174 | + } |
| 175 | +} |
| 176 | + |
| 177 | +GPUdi() float TPCFastTransformGeoPOD::getZmax(uint32_t sector) const |
| 178 | +{ |
| 179 | + /// z max for the sector |
| 180 | + if (sector < getNumberOfSectorsA()) { // TPC side A |
| 181 | + return getTPCzLength(); |
| 182 | + } else { // TPC side C |
| 183 | + return 0.f; |
| 184 | + } |
| 185 | +} |
| 186 | + |
| 187 | +GPUdi() float TPCFastTransformGeoPOD::getZreadout(uint32_t sector) const |
| 188 | +{ |
| 189 | + /// z readout for the sector |
| 190 | + if (sector < getNumberOfSectorsA()) { // TPC side A |
| 191 | + return getTPCzLength(); |
| 192 | + } else { // TPC side C |
| 193 | + return -getTPCzLength(); |
| 194 | + } |
| 195 | +} |
| 196 | + |
| 197 | +GPUdi() void TPCFastTransformGeoPOD::convLocalToPadDriftLength(uint32_t sector, uint32_t row, float y, float z, float& pad, float& l) const |
| 198 | +{ |
| 199 | + /// convert Local c.s. -> Pad, DriftLength |
| 200 | + float u; |
| 201 | + if (sector < getNumberOfSectorsA()) { // TPC side A |
| 202 | + u = y; |
| 203 | + l = getTPCzLength() - z; |
| 204 | + } else { // TPC side C |
| 205 | + u = -y; // pads are mirrorred on C-side |
| 206 | + l = z + getTPCzLength(); // drift direction is mirrored on C-side |
| 207 | + } |
| 208 | + const float maxPad = getRowInfoMaxPad(row); |
| 209 | + const float padWidth = getRowInfoPadWidth(row); |
| 210 | + pad = u / padWidth + 0.5f * maxPad; |
| 211 | +} |
| 212 | + |
| 213 | +} // namespace o2::gpu |
| 214 | + |
| 215 | +#endif |
0 commit comments