1212// / \file SegmentationMosaix.h
1313// / \brief Definition of the SegmentationMosaix class
1414// / \author felix.schlepper@cern.ch
15+ // / \author chunzheng.wang@cern.ch
1516
1617#ifndef ALICEO2_ITS3_SEGMENTATIONMOSAIX_H_
1718#define ALICEO2_ITS3_SEGMENTATIONMOSAIX_H_
@@ -43,24 +44,22 @@ class SegmentationMosaix
4344 // 3. The detector coordinate system. Defined by the row and column segmentation
4445 // defined at the upper edge in the flat coord.
4546
46- // row,col=0
47- // |
48- // v
49- // x----------------------x
47+ // O----------------------|
5048 // | | |
49+ // | | | ^ x
50+ // | | | |
51+ // | | | |
52+ // | | | |
53+ // | | | X----> z X marks (x,z)=(0,0)
54+ // |-----------X----------|
55+ // | | | O----> col O marks (row,col)=(0,0)
56+ // | | | |
57+ // | | | |
58+ // | | | v
59+ // | | | row
5160 // | | |
52- // | | | ^ x
53- // | | | |
54- // | | | |
55- // | | | |
56- // |-----------X----------| X marks (x,z)=(0,0) X----> z
57- // | | |
58- // | | |
59- // | | |
60- // | | |
61- // | | |
62- // | | |
63- // x----------------------x
61+ // |----------------------|
62+
6463 public:
6564 constexpr SegmentationMosaix (int layer) : mRadius(static_cast <float >(constants::radiiMiddle[layer])) {}
6665 constexpr ~SegmentationMosaix () = default ;
@@ -79,7 +78,7 @@ class SegmentationMosaix
7978 static constexpr float PitchCol{constants::pixelarray::pixels::mosaix::pitchZ};
8079 static constexpr float PitchRow{constants::pixelarray::pixels::mosaix::pitchX};
8180 static constexpr float SensorLayerThickness{constants::totalThickness};
82- static constexpr float NominalYShift{constants::nominalYShift };
81+ static constexpr float NominalYShift{0 . 0f };
8382
8483 // / Transformation from the curved surface to a flat surface.
8584 // / Additionally a shift in the flat coordinates must be applied because
@@ -102,9 +101,9 @@ class SegmentationMosaix
102101 // stack
103102 float dist = std::hypot (xCurved, yCurved);
104103 float phi = std::atan2 (yCurved, xCurved);
105- xFlat = (mRadius * phi) - WidthH;
106104 // the y position is in the silicon volume however we need the chip volume (silicon+metalstack)
107105 // this is accounted by a y shift
106+ xFlat = WidthH - mRadius * phi;
108107 yFlat = dist - mRadius + NominalYShift;
109108 }
110109
@@ -122,11 +121,12 @@ class SegmentationMosaix
122121 {
123122 // MUST align the flat surface with the curved surface with the original pixel array is on and account for metal
124123 // stack
124+ float dist = yFlat - NominalYShift + mRadius ;
125+ float phi = (WidthH - xFlat) / mRadius ;
125126 // the y position is in the chip volume however we need the silicon volume
126127 // this is accounted by a -y shift
127- float dist = yFlat - NominalYShift + mRadius ;
128- xCurved = dist * std::cos ((xFlat + WidthH) / mRadius );
129- yCurved = dist * std::sin ((xFlat + WidthH) / mRadius );
128+ xCurved = dist * std::cos (phi);
129+ yCurved = dist * std::sin (phi);
130130 }
131131
132132 // / Transformation from Geant detector centered local coordinates (cm) to
@@ -142,8 +142,11 @@ class SegmentationMosaix
142142 // / \param int iCol Detector z cell coordinate.
143143 constexpr bool localToDetector (float const xRow, float const zCol, int & iRow, int & iCol) const noexcept
144144 {
145+ if (!isValidLoc (xRow, zCol)) {
146+ return false ;
147+ }
145148 localToDetectorUnchecked (xRow, zCol, iRow, iCol);
146- if (!isValid (iRow, iCol)) {
149+ if (!isValidDet (iRow, iCol)) {
147150 iRow = iCol = -1 ;
148151 return false ;
149152 }
@@ -167,24 +170,27 @@ class SegmentationMosaix
167170 // / center of the sensitive volume.
168171 // / If iRow and or iCol is outside of the segmentation range a value of -0.5*Dx()
169172 // / or -0.5*Dz() is returned.
170- constexpr bool detectorToLocal (int const iRow, int const iCol, float & xRow, float & zCol) const noexcept
173+ template <typename T>
174+ constexpr bool detectorToLocal (T const row, T const col, float & xRow, float & zCol) const noexcept
171175 {
172- if (!isValid (iRow, iCol )) {
176+ if (!isValidDet (row, col )) {
173177 return false ;
174178 }
175- detectorToLocalUnchecked (iRow, iCol , xRow, zCol);
176- return isValid (xRow, zCol);
179+ detectorToLocalUnchecked (row, col , xRow, zCol);
180+ return isValidLoc (xRow, zCol);
177181 }
178182
179183 // Same as detectorToLocal w.o. checks.
180184 // We position ourself in the middle of the pixel.
181- constexpr void detectorToLocalUnchecked (int const iRow, int const iCol, float & xRow, float & zCol) const noexcept
185+ template <typename T>
186+ constexpr void detectorToLocalUnchecked (T const row, T const col, float & xRow, float & zCol) const noexcept
182187 {
183- xRow = -(static_cast <float >(iRow ) + 0 .5f ) * PitchRow + WidthH;
184- zCol = (static_cast <float >(iCol ) + 0 .5f ) * PitchCol - LengthH;
188+ xRow = -(static_cast <float >(row ) + 0 .5f ) * PitchRow + WidthH;
189+ zCol = (static_cast <float >(col ) + 0 .5f ) * PitchCol - LengthH;
185190 }
186191
187- bool detectorToLocal (int const row, int const col, math_utils::Point3D<float >& loc) const noexcept
192+ template <typename T>
193+ constexpr bool detectorToLocal (T const row, T const col, math_utils::Point3D<float >& loc) const noexcept
188194 {
189195 float xRow{0 .}, zCol{0 .};
190196 if (!detectorToLocal (row, col, xRow, zCol)) {
@@ -194,22 +200,28 @@ class SegmentationMosaix
194200 return true ;
195201 }
196202
197- void detectorToLocalUnchecked (int const row, int const col, math_utils::Point3D<float >& loc) const noexcept
203+ template <typename T>
204+ constexpr void detectorToLocalUnchecked (T const row, T const col, math_utils::Point3D<float >& loc) const noexcept
198205 {
199206 float xRow{0 .}, zCol{0 .};
200207 detectorToLocalUnchecked (row, col, xRow, zCol);
201208 loc.SetCoordinates (xRow, NominalYShift, zCol);
202209 }
203210
204211 private:
212+ // Check local coordinates (cm) validity.
205213 template <typename T>
206- [[nodiscard]] constexpr bool isValid (T const row , T const col ) const noexcept
214+ constexpr bool isValidLoc (T const x , T const z ) const noexcept
207215 {
208- if constexpr (std::is_floating_point_v<T>) { // compares in local coord.
209- return (-WidthH < row && row < WidthH && -LengthH < col && col < LengthH);
210- } else { // compares in rows/cols
211- return !static_cast <bool >(row < 0 || row >= static_cast <int >(NRows) || col < 0 || col >= static_cast <int >(NCols));
212- }
216+ return (-WidthH < x && x < WidthH && -LengthH < z && z < LengthH);
217+ }
218+
219+ // Check detector coordinates validity.
220+ template <typename T>
221+ constexpr bool isValidDet (T const row, T const col) const noexcept
222+ {
223+ return (row >= 0 && row < static_cast <T>(NRows) &&
224+ col >= 0 && col < static_cast <T>(NCols));
213225 }
214226
215227 float mRadius ;
0 commit comments