Project
Loading...
Searching...
No Matches
RecoGeomHelper.cxx
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
15
19#include "Framework/Logger.h"
20
21using namespace o2::its;
22
23//_____________________________________________________________________
25{
26 // update limits from the edge point in tracking frame
27 yRange.update(pntTra.Y());
28 zRange.update(pntTra.Z());
29}
30
31//_____________________________________________________________________
33{
34 LOGF(info, "Ch#%4d Alp: %+.3f X:%5.2f %+6.3f<y<%+6.3f %+6.3f<z<%+6.3f | XYEdges: {%+6.3f,%+6.3f}{%+6.3f,%+6.3f}\n",
35 id, alp, xRef, yRange.getMin(), yRange.getMax(), zRange.getMin(), zRange.getMax(),
36 xyEdges.getX0(), xyEdges.getY0(), xyEdges.getX1(), xyEdges.getY1());
37}
38
39//_____________________________________________________________________
41{
42 // update limits from the point in Global frame
43 float phi = pntGlo.phi(); // -pi:pi range
44 o2::math_utils::bringTo02Pi(phi); // temporary bring to 0:2pi range
45 o2::math_utils::bringTo02Pi(phiRange.getMin());
46 o2::math_utils::bringTo02Pi(phiRange.getMax());
47 phiRange.update(phi);
48 phiMean = phiRange.mean();
49 dphiH = 0.5 * phiRange.delta();
50 if (phiRange.delta() > o2::constants::math::PI) { // wrapping, swap
51 phiRange.set(phiRange.getMax(), phiRange.getMin()); // swap
52 phiMean -= o2::constants::math::PI;
53 dphiH = o2::constants::math::PI - dphiH;
54 }
55 o2::math_utils::bringToPMPi(phiRange.getMin()); // -pi:pi range
56 o2::math_utils::bringToPMPi(phiRange.getMax());
58 //
59 zRange.update(pntGlo.Z());
60}
61
62//_____________________________________________________________________
64{
65 auto& chip = chips[0].xyEdges;
66 float x0(chip.getX0()), y0(chip.getY0()), x1(chip.getX1()), y1(chip.getY1());
67 for (int i = 1; i < (int)chips.size(); i++) {
68 chip = chips[i].xyEdges;
69 x0 = chip.getDX() > 0 ? std::min(x0, chip.getX0()) : std::max(x0, chip.getX0());
70 x1 = chip.getDX() > 0 ? std::max(x1, chip.getX1()) : std::min(x1, chip.getX1());
71 y0 = chip.getDY() > 0 ? std::min(y0, chip.getY0()) : std::max(y0, chip.getY0());
72 y1 = chip.getDY() > 0 ? std::max(y1, chip.getY1()) : std::min(y1, chip.getY1());
73 }
74 xyEdges.setEdges(x0, y0, x1, y1);
75}
76
77//_____________________________________________________________________
79{
80 assert(overlapWithNext != Undefined || chips.size() == 0); // make sure there are no undefined ladders after init is done
81 LOGF(info, "Ladder %3d %.3f<phi[<%.3f>]<%.3f dPhiH:%.3f | XYEdges: {%+6.3f,%+6.3f}{%+6.3f,%+6.3f} | %3d chips | OvlNext: %s\n",
82 id, phiRange.getMin(), phiMean, phiRange.getMax(), dphiH,
83 xyEdges.getX0(), xyEdges.getY0(), xyEdges.getX1(), xyEdges.getY1(), (int)chips.size(),
84 overlapWithNext == Undefined ? "N/A" : ((overlapWithNext == NoOverlap ? "NO" : (overlapWithNext == Above ? "Above" : "Below"))));
85 for (const auto& ch : chips) {
86 ch.print();
87 }
88}
89
90//_____________________________________________________________________
92{
94 gm->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2L)); // more matrices ?
95
96 int nHStaves = gm->getNumberOfHalfStaves(id);
97 int nStaves = gm->getNumberOfStaves(id);
98 float dxH = o2::itsmft::SegmentationAlpide::SensorSizeRows / 2; // half width in rphi
99 float dzH = o2::itsmft::SegmentationAlpide::SensorSizeCols / 2; // half width in Z
100 int nCh = gm->getNumberOfChipsPerLayer(id), chip0 = gm->getFirstChipIndex(id);
101 int nChMod = gm->getNumberOfChipsPerModule(id), nChModH = nChMod / 2;
102 nLadders = nHStaves > 1 ? nStaves * nHStaves * 2 : nStaves; // 2 ladders per h-stave for OB
103 ladders.resize(nLadders);
104
105 for (auto lad : ladders) {
106 lad.chips.reserve(gm->getNumberOfChipsPerHalfStave(id) / (id > 2 ? 2 : 1)); // 2 ladders per h-stave for OB
107 }
108 for (int ich = 0; ich < nCh; ich++) {
109 int chipID = chip0 + ich, lay, sta, ssta, mod, chipInMod;
110 gm->getChipId(chipID, lay, sta, ssta, mod, chipInMod);
111 int ladID = sta; // count from negative to positive Z, contrary to official chips numbering
112 if (nHStaves > 1) { // OB
113 int modUpper = chipInMod / nChModH;
114 ladID = sta * 4 + ssta * 2 + modUpper; // OB module covers 2 "ladders"
115 }
116 auto& ladder = ladders[ladID];
117 auto& chip = ladder.chips.emplace_back();
118 chip.id = chipID;
119 gm->getSensorXAlphaRefPlane(chipID, chip.xRef, chip.alp);
120 o2::math_utils::sincos(chip.alp, chip.snAlp, chip.csAlp);
121
122 o2::math_utils::Point3D<float> edgeLoc(-dxH, 0.f, -dzH);
123 auto edgeTra = gm->getMatrixT2L(chipID) ^ (edgeLoc); // edge in tracking frame
124 chip.updateLimits(edgeTra);
125 auto edgeGloM = gm->getMatrixT2GRot(chipID)(edgeTra); // edge in global frame
126 updateLimits(edgeGloM);
127 ladder.updateLimits(edgeGloM);
128
129 edgeLoc.SetXYZ(dxH, 0.f, dzH);
130 edgeTra = gm->getMatrixT2L(chipID) ^ (edgeLoc); // edge in tracking frame
131 chip.updateLimits(edgeTra);
132 auto edgeGloP = gm->getMatrixT2GRot(chipID)(edgeTra); // edge in globalframe
133 updateLimits(edgeGloP);
134 ladder.updateLimits(edgeGloP);
135 chip.xyEdges.setEdges(edgeGloM.X(), edgeGloM.Y(), edgeGloP.X(), edgeGloP.Y());
136 }
137
138 // sort according to mean phi (in -pi:pi range!!!)
139 std::sort(ladders.begin(), ladders.end(), [](auto& a, auto& b) {
140 float pha = a.phiMean, phb = b.phiMean;
141 o2::math_utils::bringTo02Pi(pha);
142 o2::math_utils::bringTo02Pi(phb);
143 return pha < phb;
144 });
145
146 // make sure chips within the ladder are ordered in Z, renumber ladders
147 for (int i = nLadders; i--;) {
148 auto& lad = ladders[i];
149 std::sort(lad.chips.begin(), lad.chips.end(), [](auto& a, auto& b) { return a.zRange.getMin() < b.zRange.getMin(); });
150 lad.id = i;
151 lad.init();
152 }
153 // relate to its neighbour: is the egde at higher R than the edge of the next ladder and do we check for overlaps ?
154 for (int i = nLadders; i--;) {
155 auto& lad = ladders[i];
156 auto& plad = i > 0 ? ladders[i - 1] : ladders[nLadders - 1];
157 if (nHStaves == 2) { // on the OB the ladders of the same halfstave do not overlap
158 int tlay, tsta, tssta, tmod, tchipInMod;
159 int play, psta, pssta, pmod, pchipInMod;
160 gm->getChipId(lad.chips.front().id, tlay, tsta, tssta, tmod, tchipInMod);
161 gm->getChipId(plad.chips.front().id, play, psta, pssta, pmod, pchipInMod);
162 if (tsta == psta && tssta == pssta) { // these are 2 ladders of the same halfstave, no overlap
163 plad.overlapWithNext = RecoLadder::NoOverlap;
164 continue;
165 }
166 }
167 // need to compare the radius of the edge at lowest phi for this ladder with radius at highest phi of prev ladder
168 // find the radius of the edge at low phi
169 float phi0 = std::atan2(lad.xyEdges.getY0(), lad.xyEdges.getX0());
170 float phi1 = std::atan2(lad.xyEdges.getY1(), lad.xyEdges.getX1());
171 o2::math_utils::bringTo02Pi(phi0); // we don't know a priori if edge0/1 corresponds to low/high phi or vice versa
172 o2::math_utils::bringTo02Pi(phi1);
173 float r2This = (phi0 < phi1 && phi1 - phi0 < o2::constants::math::PI) ? // pick R of lowest angle
174 lad.xyEdges.getX0() * lad.xyEdges.getX0() + lad.xyEdges.getY0() * lad.xyEdges.getY0()
175 : lad.xyEdges.getX1() * lad.xyEdges.getX1() + lad.xyEdges.getY1() * lad.xyEdges.getY1();
176 //
177 phi0 = std::atan2(plad.xyEdges.getY0(), plad.xyEdges.getX0());
178 phi1 = std::atan2(plad.xyEdges.getY1(), plad.xyEdges.getX1());
179 o2::math_utils::bringTo02Pi(phi0); // we don't know a priori if edge0/1 corresponds to low/high phi or vice versa
180 o2::math_utils::bringTo02Pi(phi1);
181 float r2Prev = (phi0 < phi1 && phi1 - phi0 < o2::constants::math::PI) ? // pick R of highest angle
182 plad.xyEdges.getX1() * plad.xyEdges.getX1() + plad.xyEdges.getY1() * plad.xyEdges.getY1()
183 : plad.xyEdges.getX0() * plad.xyEdges.getX0() + plad.xyEdges.getY0() * plad.xyEdges.getY0();
184 //
185 plad.overlapWithNext = r2Prev > r2This ? RecoLadder::Above : RecoLadder::Below;
186 }
187
188 int nPhiBins = nLadders * 3; // number of bins for mapping
189 phi2ladder.resize(nPhiBins + 1);
190 float dphi = o2::constants::math::TwoPI / nPhiBins;
191 int laddId = 0;
192 for (int i = 0; i < nPhiBins; i++) {
193 float phi = (0.5 + i) * dphi;
195 while (laddId < nLadders) {
196 const auto& lad = ladders[laddId];
197 auto rel = lad.isPhiOutside(phi);
198 if (rel != RecoGeomHelper::Above) {
199 break;
200 }
201 laddId++; // laddId was below phi, catch up
202 }
203 phi2ladder[i] = laddId % nLadders;
204 }
205 phi2ladder[nPhiBins] = phi2ladder[0]; // safety bin
206 phi2bin = nPhiBins / o2::constants::math::TwoPI;
207 lastChipInLadder = ladders[0].chips.size();
208 z2chipID = lastChipInLadder / zRange.delta();
209 lastChipInLadder--;
210 rInv = 1. / rRange.mean();
211}
212
213//_____________________________________________________________________
215{
216 // update limits from the point in global frame
217 rRange.update(pntGlo.Rho());
218 zRange.update(pntGlo.Z());
219}
220
221//_____________________________________________________________________
223{
224 LOGF(info, "\nLayer %d %.2f<r<%.2f %+.2f<z<%+.2f %d ladders\n",
225 id, rRange.getMin(), rRange.getMax(), zRange.getMin(), zRange.getMax(), (int)ladders.size());
226 for (const auto& ld : ladders) {
227 ld.print();
228 }
229}
230
231//_____________________________________________________________________
233{
234 for (int il = int(layers.size()); il--;) {
235 auto& lr = layers[il];
236 lr.id = il;
237 lr.init();
238 }
239}
240
241//_____________________________________________________________________
243{
244 for (const auto& lr : layers) {
245 lr.print();
246 }
247}
int32_t i
Definition of the GeometryTGeo class.
Declarations of the helper class for clusters / roadwidth matching.
Definition of the SegmentationAlpide class.
static GeometryTGeo * Instance()
static constexpr float SensorSizeCols
static constexpr float SensorSizeRows
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition glcorearb.h:5034
GLuint GLfloat GLfloat GLfloat x1
Definition glcorearb.h:5034
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLuint GLfloat x0
Definition glcorearb.h:5034
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLuint GLfloat GLfloat y0
Definition glcorearb.h:5034
constexpr float TwoPI
constexpr float PI
void bringToPMPi(float &phi)
Definition Utils.h:100
void updateLimits(const o2::math_utils::Point3D< float > &pnt)
void updateLimits(const o2::math_utils::Point3D< float > &pnt)
void updateLimits(const o2::math_utils::Point3D< float > &pnt)
std::array< RecoLayer, o2::itsmft::ChipMappingITS::NLayers > layers
static constexpr int T2L
Definition Cartesian.h:55
static constexpr int T2GRot
Definition Cartesian.h:57