Project
Loading...
Searching...
No Matches
CathodeSegmentationImpl4.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
14
16#include "boost/format.hpp"
17#include <boost/geometry.hpp>
19#include "PadGroup.h"
20#include "PadSize.h"
23#include <array>
24#include <iostream>
25#include <map>
26#include <memory>
27#include <set>
28#include <stdexcept>
29#include <string>
30#include <vector>
31#include <gsl/gsl>
32#include <fmt/format.h>
33
34using namespace o2::mch::mapping::impl4;
35
36namespace o2
37{
38namespace mch
39{
40namespace mapping
41{
42namespace impl4
43{
44
46 bool isBendingPlane)
47{
48 int segType = detElemId2SegType(detElemId);
50 if (creator == nullptr) {
51 return nullptr;
52 }
53 return creator(isBendingPlane);
54}
55
56void CathodeSegmentation::fillRtree()
57{
58 int catPadIndex{0};
59
60 for (auto padGroupIndex = 0; padGroupIndex < mPadGroups.size();
61 ++padGroupIndex) {
62 mPadGroupIndex2CatPadIndexIndex.push_back(catPadIndex);
63 auto& pg = mPadGroups[padGroupIndex];
64 auto& pgt = mPadGroupTypes[pg.mPadGroupTypeId];
65 double dx{mPadSizes[pg.mPadSizeId].first};
66 double dy{mPadSizes[pg.mPadSizeId].second};
67 for (int ix = 0; ix < pgt.getNofPadsX(); ++ix) {
68 for (int iy = 0; iy < pgt.getNofPadsY(); ++iy) {
69 if (pgt.id(ix, iy) >= 0) {
70
71 double xmin = ix * dx + pg.mX;
72 double xmax = (ix + 1) * dx + pg.mX;
73 double ymin = iy * dy + pg.mY;
74 double ymax = (iy + 1) * dy + pg.mY;
75
76 mRtree.insert(std::make_pair(
78 CathodeSegmentation::Point(xmax, ymax)},
79 catPadIndex));
80
81 mCatPadIndex2PadGroupIndex.push_back(padGroupIndex);
82 mCatPadIndex2PadGroupTypeFastIndex.push_back(pgt.fastIndex(ix, iy));
83 ++catPadIndex;
84 }
85 }
86 }
87 }
88}
89
90std::set<int> getUnique(const std::vector<PadGroup>& padGroups)
91{
92 // extract from padGroup vector the unique integer values given by func
93 std::set<int> u;
94 for (auto& pg : padGroups) {
95 u.insert(pg.mFECId);
96 }
97 return u;
98}
99
100#if 0
101void dump(const std::string &msg, const std::vector<int> &v)
102{
103 std::cout << msg << " of size " << v.size() << " : ";
104
105 for (auto &value: v) {
106 std::cout << boost::format("%3d") % value << ",";
107 }
108 std::cout << "\n";
109}
110#endif
111
113 int segType, bool isBendingPlane, std::vector<PadGroup> padGroups,
114 std::vector<PadGroupType> padGroupTypes,
115 std::vector<std::pair<float, float>> padSizes)
116 : mSegType{segType},
117 mIsBendingPlane{isBendingPlane},
118 mPadGroups{std::move(padGroups)},
119 mDualSampaIds{getUnique(mPadGroups)},
120 mPadGroupTypes{std::move(padGroupTypes)},
121 mPadSizes{std::move(padSizes)},
122 mCatPadIndex2PadGroupIndex{},
123 mCatPadIndex2PadGroupTypeFastIndex{},
124 mPadGroupIndex2CatPadIndexIndex{},
125 mDualSampaId2CatPadIndices{}
126{
127 fillRtree();
128 for (auto dualSampaId : mDualSampaIds) {
129 mDualSampaId2CatPadIndices.emplace(dualSampaId, catPadIndices(dualSampaId));
130 }
131}
132
133std::vector<int> CathodeSegmentation::catPadIndices(int dualSampaId) const
134{
135 std::vector<int> pi;
136
137 for (auto padGroupIndex = 0; padGroupIndex < mPadGroups.size();
138 ++padGroupIndex) {
139 if (mPadGroups[padGroupIndex].mFECId == dualSampaId) {
140 const auto& pgt = mPadGroupTypes[mPadGroups[padGroupIndex].mPadGroupTypeId];
141 const auto& i1 = mPadGroupIndex2CatPadIndexIndex[padGroupIndex];
142 for (auto i = i1; i < i1 + pgt.getNofPads(); ++i) {
143 pi.emplace_back(i);
144 }
145 }
146 }
147 return pi;
148}
149
150std::vector<int> CathodeSegmentation::getCatPadIndices(int dualSampaId) const
151{
152 auto it = mDualSampaId2CatPadIndices.find(dualSampaId);
153 if (it == mDualSampaId2CatPadIndices.end()) {
154 return {};
155 }
156 return it->second;
157}
158
159std::vector<int> CathodeSegmentation::getCatPadIndices(double xmin, double ymin,
160 double xmax,
161 double ymax) const
162{
163 std::vector<CathodeSegmentation::Value> result_n;
164 mRtree.query(boost::geometry::index::intersects(
165 CathodeSegmentation::Box({xmin, ymin}, {xmax, ymax})),
166 std::back_inserter(result_n));
167 std::vector<int> catPadIndices;
168 for (auto& r : result_n) {
169 catPadIndices.push_back(r.second);
170 }
171 return catPadIndices;
172}
173
175 int catPadIndex) const
176{
177 double x = padPositionX(catPadIndex);
178 double y = padPositionY(catPadIndex);
179 double dx = padSizeX(catPadIndex) / 2.0;
180 double dy = padSizeY(catPadIndex) / 2.0;
181
182 const double offset{0.1}; // 1 mm
183
184 auto pads = getCatPadIndices(x - dx - offset, y - dy - offset, x + dx + offset,
185 y + dy + offset);
186 pads.erase(std::remove(begin(pads), end(pads), catPadIndex), end(pads));
187 return pads;
188}
189
190bool CathodeSegmentation::isValid(int catPadIndex) const
191{
192 return catPadIndex >= 0 && catPadIndex < static_cast<int>(mCatPadIndex2PadGroupIndex.size());
193}
194
195double CathodeSegmentation::squaredDistance(int catPadIndex, double x,
196 double y) const
197{
198 double px = padPositionX(catPadIndex) - x;
199 double py = padPositionY(catPadIndex) - y;
200 return px * px + py * py;
201}
202
204{
205 const double epsilon{1E-4};
206 auto pads =
207 getCatPadIndices(x - epsilon, y - epsilon, x + epsilon, y + epsilon);
208
209 double dmin{std::numeric_limits<double>::max()};
210 int catPadIndex{InvalidCatPadIndex};
211
212 for (auto i = 0; i < pads.size(); ++i) {
213 double d{squaredDistance(pads[i], x, y)};
214 if (d < dmin) {
215 catPadIndex = pads[i];
216 dmin = d;
217 }
218 }
219
220 return catPadIndex;
221}
222
223const PadGroup& CathodeSegmentation::padGroup(int catPadIndex) const
224{
225 return gsl::at(mPadGroups, mCatPadIndex2PadGroupIndex[catPadIndex]);
226}
227
228const PadGroupType& CathodeSegmentation::padGroupType(int catPadIndex) const
229{
230 return gsl::at(mPadGroupTypes, padGroup(catPadIndex).mPadGroupTypeId);
231}
232
234 int dualSampaChannel) const
235{
236 auto it = mDualSampaId2CatPadIndices.find(dualSampaId);
237 if (it == mDualSampaId2CatPadIndices.end()) {
238 return InvalidCatPadIndex;
239 }
240 const auto& padIndices = it->second;
241 for (const auto& catPadIndex : padIndices) {
242 if (padGroupType(catPadIndex)
243 .id(mCatPadIndex2PadGroupTypeFastIndex[catPadIndex]) ==
244 dualSampaChannel) {
245 return catPadIndex;
246 }
247 }
248 return InvalidCatPadIndex;
249}
250
251double CathodeSegmentation::padPositionX(int catPadIndex) const
252{
253 auto& pg = padGroup(catPadIndex);
254 auto& pgt = padGroupType(catPadIndex);
255 return pg.mX +
256 (pgt.ix(mCatPadIndex2PadGroupTypeFastIndex[catPadIndex]) + 0.5) *
257 mPadSizes[pg.mPadSizeId].first;
258}
259
260double CathodeSegmentation::padPositionY(int catPadIndex) const
261{
262 auto& pg = padGroup(catPadIndex);
263 auto& pgt = padGroupType(catPadIndex);
264 return pg.mY +
265 (pgt.iy(mCatPadIndex2PadGroupTypeFastIndex[catPadIndex]) + 0.5) *
266 mPadSizes[pg.mPadSizeId].second;
267}
268
269double CathodeSegmentation::padSizeX(int catPadIndex) const
270{
271 return mPadSizes[padGroup(catPadIndex).mPadSizeId].first;
272}
273
274double CathodeSegmentation::padSizeY(int catPadIndex) const
275{
276 return mPadSizes[padGroup(catPadIndex).mPadSizeId].second;
277}
278
279int CathodeSegmentation::padDualSampaId(int catPadIndex) const
280{
281 return padGroup(catPadIndex).mFECId;
282}
283
285{
286 return padGroupType(catPadIndex)
287 .id(mCatPadIndex2PadGroupTypeFastIndex[catPadIndex]);
288}
289
290std::ostream& operator<<(std::ostream& out, const std::pair<float, float>& p)
291{
292 out << p.first << "," << p.second;
293 return out;
294}
295
296template <typename T>
297void dump(std::ostream& out, const std::string& msg, const std::vector<T>& v,
298 int n)
299{
300
301 out << msg << "\n";
302 for (auto i = 0; i < n; ++i) {
303 if (i < v.size()) {
304 out << v[i] << "\n";
305 }
306 }
307}
308
309std::ostream& operator<<(std::ostream& os, const CathodeSegmentation& seg)
310{
311 os << "segType " << seg.mSegType << "-" << (seg.mIsBendingPlane ? "B" : "NB");
312
313 os << boost::format(" %3d PG %2d PGT %2d PS\n") % seg.mPadGroups.size() %
314 seg.mPadGroupTypes.size() % seg.mPadSizes.size();
315
316 dump(os, "PG", seg.mPadGroups, seg.mPadGroups.size());
317 dump(os, "PGT", seg.mPadGroupTypes, seg.mPadGroupTypes.size());
318 dump(os, "PS", seg.mPadSizes, seg.mPadSizes.size());
319 return os;
320}
321
322} // namespace impl4
323} // namespace mapping
324} // namespace mch
325} // namespace o2
bool isBendingPlane
o2::mch::mapping::CathodeSegmentation seg
int32_t i
int findPadByFEE(int dualSampaId, int dualSampaChannel) const
std::vector< int > getNeighbouringCatPadIndices(int catPadIndex) const
boost::geometry::model::point< double, 2, boost::geometry::cs::cartesian > Point
std::vector< int > getCatPadIndices(int dualSampaId) const
Return the list of catPadIndices for the pads of the given dual sampa.
CathodeSegmentation(int segType, bool isBendingPlane, std::vector< PadGroup > padGroups, std::vector< PadGroupType > padGroupTypes, std::vector< std::pair< float, float > > padSizes)
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint GLuint end
Definition glcorearb.h:469
const GLdouble * v
Definition glcorearb.h:832
GLint y
Definition glcorearb.h:270
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLintptr offset
Definition glcorearb.h:660
GLboolean r
Definition glcorearb.h:1233
CathodeSegmentationCreator getCathodeSegmentationCreator(int segType)
CathodeSegmentation * createCathodeSegmentation(int detElemId, bool isBendingPlane)
int detElemId2SegType(int detElemId)
void dump(std::ostream &out, const std::string &msg, const std::vector< T > &v, int n)
CathodeSegmentation *(*)(bool) CathodeSegmentationCreator
std::set< int > getUnique(const std::vector< PadGroup > &padGroups)
std::ostream & operator<<(std::ostream &out, const std::pair< float, float > &p)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
uint64_t const void const *restrict const msg
Definition x9.h:153