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 three coordinate systems and one is transient.
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 (flat) coordinate system. This is the tube segment projected onto a flat
42 // surface. In the projection we implicitly assume that the inner and outer
43 // stretch does not depend on the radius.
44 // 3. The detector coordinate system. Defined by the row and column segmentation
45 // defined at the upper edge in the flat coord.
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 (!isValidGlob(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 && layer <= 3) { // ML
120 pitchRow = PitchRowMLOT;
121 pitchCol = PitchColMLOT;
122 maxWidth = constants::ML::width;
123 maxLength = constants::ML::length;
124 } else if (subDetID == 1 && layer >= 4) { // OT
125 pitchRow = PitchRowMLOT;
126 pitchCol = PitchColMLOT;
127 maxWidth = constants::OT::width;
128 maxLength = constants::OT::length;
129 }
130 // convert to row/col
131 iRow = static_cast<int>(std::floor((maxWidth / 2 - xRow) / pitchRow));
132 iCol = static_cast<int>(std::floor((zCol + maxLength / 2) / pitchCol));
133 };
134
135 // Check local coordinates (cm) validity.
136 static constexpr bool isValidGlob(float x, float z, int subDetID, int layer) noexcept
137 {
138 float maxWidth(0), maxLength(0);
139 if (subDetID == 0) {
140 maxWidth = constants::VD::petal::layer::width[layer];
141 maxLength = constants::VD::petal::layer::length;
142 // TODO: change this to use the layer and disk
143 } else if (subDetID == 1 && layer <= 3) { // ML
144 maxWidth = constants::ML::width;
145 maxLength = constants::ML::length;
146 } else if (subDetID == 1 && layer >= 4) { // OT
147 maxWidth = constants::OT::width;
148 maxLength = constants::OT::length;
149 }
150 return (-maxWidth / 2 < x && x < maxWidth / 2 && -maxLength / 2 < z && z < maxLength / 2);
151 }
152
153 // Check detector coordinates validity.
154 static constexpr bool isValidDet(float row, float col, int subDetID, int layer) noexcept
155 {
156 // Check if the row and column are within the valid range
157 int nRows(0), nCols(0);
158 if (subDetID == 0) {
159 nRows = constants::VD::petal::layer::nRows[layer];
160 nCols = constants::VD::petal::layer::nCols;
161 // TODO: change this to use the layer and disk
162 } else if (subDetID == 1 && layer <= 3) { // ML
163 nRows = constants::ML::nRows;
164 nCols = constants::ML::nCols;
165 } else if (subDetID == 1 && layer >= 4) { // OT
166 nRows = constants::OT::nRows;
167 nCols = constants::OT::nCols;
168 }
169 return (row >= 0 && row < static_cast<float>(nRows) && col >= 0 && col < static_cast<float>(nCols));
170 }
171
185 static constexpr bool detectorToLocal(int iRow, int iCol, float& xRow, float& zCol, int subDetID, int layer, int disk) noexcept
186 {
187 if (!isValidDet(iRow, iCol, subDetID, layer)) {
188 LOGP(debug, "Detector coordinates not valid: iRow = {}, iCol = {}", iRow, iCol);
189 return false;
190 }
191 detectorToLocalUnchecked(iRow, iCol, xRow, zCol, subDetID, layer, disk);
192 LOG(debug) << "Result from detectorToLocalUnchecked: iRow " << iRow << " -> xRow " << xRow << ", iCol " << iCol << " -> zCol " << zCol << " on subDetID, layer, disk: " << subDetID << " " << layer << " " << disk;
193
194 if (!isValidGlob(xRow, zCol, subDetID, layer)) {
195 LOGP(debug, "Local coordinates not valid: row = {} cm, col = {} cm", xRow, zCol);
196 return false;
197 }
198 return true;
199 };
200
201 // Same as detectorToLocal w.o. checks.
202 // We position ourself in the middle of the pixel.
203 static void detectorToLocalUnchecked(int row, int col, float& xRow, float& zCol, int subDetID, int layer, int disk) noexcept
204 {
207 if (subDetID == 0) {
208 xRow = 0.5 * (constants::VD::petal::layer::width[layer] - PitchRowVD) - (row * PitchRowVD);
209 zCol = col * PitchColVD + 0.5 * (PitchColVD - constants::VD::petal::layer::length);
210 } else if (subDetID == 1 && layer <= 3) { // ML
211 xRow = 0.5 * (constants::ML::width - PitchRowMLOT) - (row * PitchRowMLOT);
213 } else if (subDetID == 1 && layer >= 4) { // OT
214 xRow = 0.5 * (constants::OT::width - PitchRowMLOT) - (row * PitchRowMLOT);
216 }
217 }
218
230 // in cm with respect to the center of the sensitive volume.
231 static math_utils::Vector2D<float> curvedToFlat(const int layer, const float xCurved, const float yCurved) noexcept
232 {
233 // Align the flat surface with the curved survace of the original chip (and account for metal stack, TODO)
234 float dist = std::hypot(xCurved, yCurved);
235 float phi = std::atan2(yCurved, xCurved);
236
237 // the y position is in the silicon volume however we need the chip volume (silicon+metalstack)
238 // this is accounted by a y shift
239 float xFlat = constants::VD::petal::layer::radii[layer] * phi;
240 float yFlat = constants::VD::petal::layer::radii[layer] - dist;
241 return math_utils::Vector2D<float>(xFlat, yFlat);
242 }
243
252 // in cm with respect to the center of the sensitive volume.
253 static constexpr math_utils::Vector2D<float> flatToCurved(int layer, float xFlat, float yFlat) noexcept
254 {
255 // Revert the curvedToFlat transformation
256 float dist = constants::VD::petal::layer::radii[layer] - yFlat;
257 float phi = xFlat / constants::VD::petal::layer::radii[layer];
258 // the y position is in the chip volume however we need the silicon volume
259 // this is accounted by a -y shift
260 float xCurved = dist * std::cos(phi);
261 float yCurved = dist * std::sin(phi);
262 return math_utils::Vector2D<float>(xCurved, yCurved);
263 }
264
266 static const void Print() noexcept
267 {
268 LOG(info) << "Number of rows:\nVD L0: " << constants::VD::petal::layer::nRows[0]
269 << "\nVD L1: " << constants::VD::petal::layer::nRows[1]
270 << "\nVD L2: " << constants::VD::petal::layer::nRows[2]
271 << "\nML stave: " << constants::ML::nRows
272 << "\nOT stave: " << constants::OT::nRows;
273
274 LOG(info) << "Number of cols:\nVD: " << constants::VD::petal::layer::nCols
275 << "\nML stave: " << constants::ML::nCols
276 << "\nOT stave: " << constants::OT::nCols;
277 }
278};
279
280} // namespace o2::trk
281
282#endif
uint32_t col
Definition RawData.h:4
specs of the ALICE3 TRK
std::ostringstream debug
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 bool isValidGlob(float x, float z, int subDetID, int layer) noexcept
static constexpr float PitchColVD
static constexpr bool isValidDet(float row, float col, int subDetID, int layer) noexcept
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 const void Print() noexcept
Print segmentation info.
static constexpr float PitchRowVD
constexpr SegmentationChip & operator=(const SegmentationChip &)=default
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 length
Definition Specs.h:106
constexpr int nRows
Definition Specs.h:107
constexpr double width
Definition Specs.h:105
constexpr int nCols
Definition Specs.h:108
constexpr int nRows
Definition Specs.h:115
constexpr int nCols
Definition Specs.h:116
constexpr double width
Definition Specs.h:113
constexpr double length
Definition Specs.h:114
constexpr double thickness
Definition Specs.h:37
constexpr double totalThickness
Definition Specs.h:85
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< int > row