Project
Loading...
Searching...
No Matches
SegmentationChip.h
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
14
15#ifndef ALICEO2_TRK_SEGMENTATIONCHIP_H_
16#define ALICEO2_TRK_SEGMENTATIONCHIP_H_
17
18#include <type_traits>
19#include <fairlogger/Logger.h>
20
21#include "MathUtils/Cartesian.h"
22#include "TRKBase/Specs.h"
23
24namespace o2::trk
25{
26
30{
31 // This class defines the segmenation of the TRK chips in the ALICE3 upgrade.
32 // The "global coordinate system" refers to the hit position in cm in the global coordinate system centered in 0,0,0
33 // The "local coordinate system" refers to the hit position in cm in the coordinate system of the sensor, which
34 // is centered in 0,0,0 in the case of curved layers, and in the middle of the chip in the case of flat layers
35 // The "detector coordinate system" refers to the hit position in row,col inside the sensor
36 // This class provides the transformations from the local and detector coordinate systems
37 // The conversion between global and local coordinate systems is operated by the transformation matrices
38 // For the curved VD layers there exist four coordinate systems.
39 // 1. The global (curved) coordinate system. The chip's center of coordinate system is
40 // defined at the the mid-point of the detector.
41 // 2. The local (curved) coordinate system, centered in 0,0,0.
42 // 3. The local (flat) coordinate system. This is the tube segment projected onto a flat
43 // surface, centered in the middle of the chip, with the y axis pointing towards the interaction point.
44 // In the projection we implicitly assume that the inner and outer stretch does not depend on the radius.
45 // 4. The detector coordinate system. Defined by the row and column segmentation.
46 // For the flat ML and OT layers, there exist two coordinate systems:
47 // 1. The global (flat) coordinate system. The chip's center of coordinate system is
48 // defined at the the mid-point of the detector.
49 // 2. The detector coordinate system. Defined by the row and column segmentation.
50 // TODO: add segmentation for VD disks
51
52 public:
53 constexpr SegmentationChip() = default;
54 ~SegmentationChip() = default;
55 constexpr SegmentationChip(const SegmentationChip&) = default;
56 constexpr SegmentationChip(SegmentationChip&&) = delete;
57 constexpr SegmentationChip& operator=(const SegmentationChip&) = default;
59
60 static constexpr float PitchColVD{constants::VD::petal::layer::pitchZ};
61 static constexpr float PitchRowVD{constants::VD::petal::layer::pitchX};
62
65
66 static constexpr float SensorLayerThicknessVD = {constants::VD::petal::layer::totalThickness}; // physical thickness of sensitive part = 30 um
67 static constexpr float SensorLayerThicknessML = {constants::moduleMLOT::chip::totalThickness}; // physical thickness of sensitive part = 100 um
68 static constexpr float SensorLayerThicknessOT = {constants::moduleMLOT::chip::totalThickness}; // physical thickness of sensitive part = 100 um
69
70 static constexpr float SiliconThicknessVD = constants::VD::silicon::thickness; // effective thickness of sensitive part
71 static constexpr float SiliconThicknessMLOT = constants::moduleMLOT::silicon::thickness; // effective thickness of sensitive part
72
73 static constexpr std::array<double, constants::VD::petal::nLayers> radiiVD = constants::VD::petal::layer::radii;
74
89 static bool localToDetector(float xRow, float zCol, int& iRow, int& iCol, int subDetID, int layer, int disk) noexcept
90 {
91 if (!isValidLoc(xRow, zCol, subDetID, layer)) {
92 LOGP(debug, "Local coordinates not valid: row = {} cm, col = {} cm", xRow, zCol);
93 return false;
94 }
95 localToDetectorUnchecked(xRow, zCol, iRow, iCol, subDetID, layer, disk);
96
97 LOG(debug) << "Result from localToDetectorUnchecked: xRow " << xRow << " -> iRow " << iRow << ", zCol " << zCol << " -> iCol " << iCol << " on subDetID, layer, disk: " << subDetID << " " << layer << " " << disk;
98
99 if (!isValidDet(iRow, iCol, subDetID, layer)) {
100 iRow = iCol = -1;
101 LOGP(debug, "Detector coordinates not valid: iRow = {}, iCol = {}", iRow, iCol);
102 return false;
103 }
104 return true;
105 };
107 static void localToDetectorUnchecked(float xRow, float zCol, int& iRow, int& iCol, int subDetID, int layer, int disk) noexcept
108 {
109 // convert to row/col w/o over/underflow check
110 float pitchRow(0), pitchCol(0);
111 float maxWidth(0), maxLength(0);
112
113 if (subDetID == 0) {
114 pitchRow = PitchRowVD;
115 pitchCol = PitchColVD;
116 maxWidth = constants::VD::petal::layer::width[layer];
117 maxLength = constants::VD::petal::layer::length;
118 // TODO: change this to use the layer and disk
119 } else if (subDetID == 1) {
120 pitchRow = PitchRowMLOT;
121 pitchCol = PitchColMLOT;
122 maxWidth = constants::moduleMLOT::chip::width - constants::moduleMLOT::chip::passiveEdgeReadOut;
124 }
125 // convert to row/col
126 iRow = static_cast<int>(std::floor((maxWidth / 2 - xRow) / pitchRow));
127 iCol = static_cast<int>(std::floor((zCol + maxLength / 2) / pitchCol));
128 };
129
130 // Check local coordinates (cm) validity.
131 static constexpr bool isValidLoc(float x, float z, int subDetID, int layer) noexcept
132 {
133 float maxWidth(0), maxLength(0);
134 if (subDetID == 0) {
135 maxWidth = constants::VD::petal::layer::width[layer];
136 maxLength = constants::VD::petal::layer::length;
137 // TODO: change this to use the layer and disk
138 } else if (subDetID == 1) { // ML/OT
139 maxWidth = constants::moduleMLOT::chip::width - constants::moduleMLOT::chip::passiveEdgeReadOut;
141 }
142 return (-maxWidth / 2 < x && x < maxWidth / 2 && -maxLength / 2 < z && z < maxLength / 2);
143 }
144
145 // Check detector coordinates validity.
146 static constexpr bool isValidDet(int row, int col, int subDetID, int layer) noexcept
147 {
148 // Check if the row and column are within the valid range
149 int nRows(0), nCols(0);
150 if (subDetID == 0) {
151 nRows = constants::VD::petal::layer::nRows[layer];
152 nCols = constants::VD::petal::layer::nCols;
153 // TODO: change this to use the layer and disk
154 } else if (subDetID == 1) {
157 }
158 return (row >= 0 && row < nRows && col >= 0 && col < nCols);
159 }
160
174 static constexpr bool detectorToLocal(int iRow, int iCol, float& xRow, float& zCol, int subDetID, int layer, int disk) noexcept
175 {
176 if (!isValidDet(iRow, iCol, subDetID, layer)) {
177 LOGP(debug, "Detector coordinates not valid: iRow = {}, iCol = {}", iRow, iCol);
178 return false;
179 }
180 detectorToLocalUnchecked(iRow, iCol, xRow, zCol, subDetID, layer, disk);
181 LOG(debug) << "Result from detectorToLocalUnchecked: iRow " << iRow << " -> xRow " << xRow << ", iCol " << iCol << " -> zCol " << zCol << " on subDetID, layer, disk: " << subDetID << " " << layer << " " << disk;
182
183 if (!isValidLoc(xRow, zCol, subDetID, layer)) {
184 LOGP(debug, "Local coordinates not valid: row = {} cm, col = {} cm", xRow, zCol);
185 return false;
186 }
187 return true;
188 };
189
190 // Same as detectorToLocal w.o. checks.
191 // We position ourself in the middle of the pixel.
192 static void detectorToLocalUnchecked(int row, int col, float& xRow, float& zCol, int subDetID, int layer, int disk) noexcept
193 {
196 if (subDetID == 0) {
197 xRow = 0.5 * (constants::VD::petal::layer::width[layer] - PitchRowVD) - (row * PitchRowVD);
198 zCol = col * PitchColVD + 0.5 * (PitchColVD - constants::VD::petal::layer::length);
199 } else if (subDetID == 1) { // ML/OT
200 xRow = 0.5 * (constants::moduleMLOT::chip::width - constants::moduleMLOT::chip::passiveEdgeReadOut - PitchRowMLOT) - (row * PitchRowMLOT);
202 }
203 }
204
216 // in cm with respect to the center of the sensitive volume.
217 static math_utils::Vector2D<float> curvedToFlat(const int layer, const float xCurved, const float yCurved) noexcept
218 {
219 // Align the flat surface with the curved survace of the original chip (and account for metal stack, TODO)
220 float dist = std::hypot(xCurved, yCurved);
221 float phi = std::atan2(yCurved, xCurved);
222
223 // the y position is in the silicon volume however we need the chip volume (silicon+metalstack)
224 // this is accounted by a y shift
225 float xFlat = constants::VD::petal::layer::radii[layer] * phi;
226 float yFlat = constants::VD::petal::layer::radii[layer] - dist;
227 return math_utils::Vector2D<float>(xFlat, yFlat);
228 }
229
238 // in cm with respect to the center of the sensitive volume.
239 static constexpr math_utils::Vector2D<float> flatToCurved(int layer, float xFlat, float yFlat) noexcept
240 {
241 // Revert the curvedToFlat transformation
242 float dist = constants::VD::petal::layer::radii[layer] - yFlat;
243 float phi = xFlat / constants::VD::petal::layer::radii[layer];
244 // the y position is in the chip volume however we need the silicon volume
245 // this is accounted by a -y shift
246 float xCurved = dist * std::cos(phi);
247 float yCurved = dist * std::sin(phi);
248 return math_utils::Vector2D<float>(xCurved, yCurved);
249 }
250
252 static void Print() noexcept
253 {
254 LOG(info) << "Number of rows:\nVD L0: " << constants::VD::petal::layer::nRows[0]
255 << "\nVD L1: " << constants::VD::petal::layer::nRows[1]
256 << "\nVD L2: " << constants::VD::petal::layer::nRows[2]
257 << "\nML/OT chip: " << constants::moduleMLOT::chip::nRows;
258
259 LOG(info) << "Number of cols:\nVD: " << constants::VD::petal::layer::nCols
260 << "\nML/OT chip: " << constants::moduleMLOT::chip::nCols;
261
262 LOG(info) << "Pitch rows x cols [um]:\nVD: " << PitchRowVD * 1e4 << "x" << PitchColVD * 1e4
263 << "\nML/OT chip: " << PitchRowMLOT * 1e4 << "x" << PitchColMLOT * 1e4;
264 }
265};
266
267} // namespace o2::trk
268
269#endif
std::ostringstream debug
uint32_t col
Definition RawData.h:4
specs of the ALICE3 TRK
static void localToDetectorUnchecked(float xRow, float zCol, int &iRow, int &iCol, int subDetID, int layer, int disk) noexcept
same but w/o check for row/column range
static constexpr math_utils::Vector2D< float > flatToCurved(int layer, float xFlat, float yFlat) noexcept
static constexpr float SiliconThicknessVD
static constexpr float SensorLayerThicknessOT
static constexpr bool detectorToLocal(int iRow, int iCol, float &xRow, float &zCol, int subDetID, int layer, int disk) noexcept
constexpr SegmentationChip()=default
static void detectorToLocalUnchecked(int row, int col, float &xRow, float &zCol, int subDetID, int layer, int disk) noexcept
constexpr SegmentationChip(SegmentationChip &&)=delete
static constexpr float SensorLayerThicknessML
static constexpr float SensorLayerThicknessVD
static constexpr float PitchColVD
constexpr SegmentationChip & operator=(SegmentationChip &&)=delete
static bool localToDetector(float xRow, float zCol, int &iRow, int &iCol, int subDetID, int layer, int disk) noexcept
static constexpr float PitchColMLOT
static constexpr float PitchRowMLOT
static constexpr std::array< double, constants::VD::petal::nLayers > radiiVD
static void Print() noexcept
Print segmentation info.
static constexpr float PitchRowVD
constexpr SegmentationChip & operator=(const SegmentationChip &)=default
static constexpr bool isValidDet(int row, int col, int subDetID, int layer) noexcept
static constexpr bool isValidLoc(float x, float z, int subDetID, int layer) noexcept
constexpr SegmentationChip(const SegmentationChip &)=default
static constexpr float SiliconThicknessMLOT
static math_utils::Vector2D< float > curvedToFlat(const int layer, const float xCurved, const float yCurved) noexcept
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
constexpr double thickness
Definition Specs.h:37
constexpr double totalThickness
Definition Specs.h:83
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< int > row