Project
Loading...
Searching...
No Matches
CathodeSegmentationImpl3.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
33using namespace o2::mch::mapping::impl3;
34
35namespace o2
36{
37namespace mch
38{
39namespace mapping
40{
41namespace impl3
42{
43
45{
46 int segType = detElemId2SegType(detElemId);
48 if (creator == nullptr) {
49 return nullptr;
50 }
51 return creator(isBendingPlane);
52}
53
54void CathodeSegmentation::fillRtree()
55{
56 int catPadIndex{0};
57
58 for (auto padGroupIndex = 0; padGroupIndex < mPadGroups.size(); ++padGroupIndex) {
59 mPadGroupIndex2CatPadIndexIndex.push_back(catPadIndex);
60 auto& pg = mPadGroups[padGroupIndex];
61 auto& pgt = mPadGroupTypes[pg.mPadGroupTypeId];
62 double dx{mPadSizes[pg.mPadSizeId].first};
63 double dy{mPadSizes[pg.mPadSizeId].second};
64 for (int ix = 0; ix < pgt.getNofPadsX(); ++ix) {
65 for (int iy = 0; iy < pgt.getNofPadsY(); ++iy) {
66 if (pgt.id(ix, iy) >= 0) {
67
68 double xmin = ix * dx + pg.mX;
69 double xmax = (ix + 1) * dx + pg.mX;
70 double ymin = iy * dy + pg.mY;
71 double ymax = (iy + 1) * dy + pg.mY;
72
73 mRtree.insert(std::make_pair(
75
76 mCatPadIndex2PadGroupIndex.push_back(padGroupIndex);
77 mCatPadIndex2PadGroupTypeFastIndex.push_back(pgt.fastIndex(ix, iy));
78 ++catPadIndex;
79 }
80 }
81 }
82 }
83}
84
85std::set<int> getUnique(const std::vector<PadGroup>& padGroups)
86{
87 // extract from padGroup vector the unique integer values given by func
88 std::set<int> u;
89 for (auto& pg : padGroups) {
90 u.insert(pg.mFECId);
91 }
92 return u;
93}
94
95#if 0
96void dump(const std::string &msg, const std::vector<int> &v)
97{
98 std::cout << msg << " of size " << v.size() << " : ";
99
100 for (auto &value: v) {
101 std::cout << boost::format("%3d") % value << ",";
102 }
103 std::cout << "\n";
104}
105#endif
106
107CathodeSegmentation::CathodeSegmentation(int segType, bool isBendingPlane, std::vector<PadGroup> padGroups,
108 std::vector<PadGroupType> padGroupTypes, std::vector<std::pair<float, float>> padSizes)
109 : mSegType{segType},
110 mIsBendingPlane{isBendingPlane},
111 mPadGroups{std::move(padGroups)},
112 mDualSampaIds{getUnique(mPadGroups)},
113 mPadGroupTypes{std::move(padGroupTypes)},
114 mPadSizes{std::move(padSizes)},
115 mCatPadIndex2PadGroupIndex{},
116 mCatPadIndex2PadGroupTypeFastIndex{},
117 mPadGroupIndex2CatPadIndexIndex{}
118{
119 fillRtree();
120}
121
122std::vector<int> CathodeSegmentation::getCatPadIndexs(int dualSampaId) const
123{
124 std::vector<int> pi;
125
126 for (auto padGroupIndex = 0; padGroupIndex < mPadGroups.size(); ++padGroupIndex) {
127 if (mPadGroups[padGroupIndex].mFECId == dualSampaId) {
128 auto& pgt = mPadGroupTypes[mPadGroups[padGroupIndex].mPadGroupTypeId];
129 auto i1 = mPadGroupIndex2CatPadIndexIndex[padGroupIndex];
130 for (auto i = i1; i < i1 + pgt.getNofPads(); ++i) {
131 pi.push_back(i);
132 }
133 }
134 }
135
136 return pi;
137}
138
139std::vector<int> CathodeSegmentation::getCatPadIndexs(double xmin, double ymin, double xmax, double ymax) const
140{
141 std::vector<CathodeSegmentation::Value> result_n;
142 mRtree.query(boost::geometry::index::intersects(CathodeSegmentation::Box({xmin, ymin}, {xmax, ymax})),
143 std::back_inserter(result_n));
144 std::vector<int> catPadIndexs;
145 for (auto& r : result_n) {
146 catPadIndexs.push_back(r.second);
147 }
148 return catPadIndexs;
149}
150
151std::vector<int> CathodeSegmentation::getNeighbouringCatPadIndexs(int catPadIndex) const
152{
153 double x = padPositionX(catPadIndex);
154 double y = padPositionY(catPadIndex);
155 double dx = padSizeX(catPadIndex) / 2.0;
156 double dy = padSizeY(catPadIndex) / 2.0;
157
158 const double offset{0.1}; // 1 mm
159
160 auto pads = getCatPadIndexs(x - dx - offset, y - dy - offset, x + dx + offset, y + dy + offset);
161 pads.erase(std::remove(begin(pads), end(pads), catPadIndex), end(pads));
162 return pads;
163}
164
165bool CathodeSegmentation::isValid(int catPadIndex) const
166{
167 return catPadIndex >= 0 && catPadIndex < static_cast<int>(mCatPadIndex2PadGroupIndex.size());
168}
169
170double CathodeSegmentation::squaredDistance(int catPadIndex, double x, double y) const
171{
172 double px = padPositionX(catPadIndex) - x;
173 double py = padPositionY(catPadIndex) - y;
174 return px * px + py * py;
175}
176
178{
179 const double epsilon{1E-4};
180 auto pads = getCatPadIndexs(x - epsilon, y - epsilon, x + epsilon, y + epsilon);
181
182 double dmin{std::numeric_limits<double>::max()};
183 int catPadIndex{InvalidCatPadIndex};
184
185 for (auto i = 0; i < pads.size(); ++i) {
186 double d{squaredDistance(pads[i], x, y)};
187 if (d < dmin) {
188 catPadIndex = pads[i];
189 dmin = d;
190 }
191 }
192
193 return catPadIndex;
194}
195
196const PadGroup& CathodeSegmentation::padGroup(int catPadIndex) const { return gsl::at(mPadGroups, mCatPadIndex2PadGroupIndex[catPadIndex]); }
197
198const PadGroupType& CathodeSegmentation::padGroupType(int catPadIndex) const
199{
200 return gsl::at(mPadGroupTypes, padGroup(catPadIndex).mPadGroupTypeId);
201}
202
203int CathodeSegmentation::findPadByFEE(int dualSampaId, int dualSampaChannel) const
204{
205 for (auto catPadIndex : getCatPadIndexs(dualSampaId)) {
206 if (padGroupType(catPadIndex).id(mCatPadIndex2PadGroupTypeFastIndex[catPadIndex]) == dualSampaChannel) {
207 return catPadIndex;
208 }
209 }
210 return InvalidCatPadIndex;
211}
212
213double CathodeSegmentation::padPositionX(int catPadIndex) const
214{
215 auto& pg = padGroup(catPadIndex);
216 auto& pgt = padGroupType(catPadIndex);
217 return pg.mX + (pgt.ix(mCatPadIndex2PadGroupTypeFastIndex[catPadIndex]) + 0.5) * mPadSizes[pg.mPadSizeId].first;
218}
219
220double CathodeSegmentation::padPositionY(int catPadIndex) const
221{
222 auto& pg = padGroup(catPadIndex);
223 auto& pgt = padGroupType(catPadIndex);
224 return pg.mY + (pgt.iy(mCatPadIndex2PadGroupTypeFastIndex[catPadIndex]) + 0.5) * mPadSizes[pg.mPadSizeId].second;
225}
226
227double CathodeSegmentation::padSizeX(int catPadIndex) const { return mPadSizes[padGroup(catPadIndex).mPadSizeId].first; }
228
229double CathodeSegmentation::padSizeY(int catPadIndex) const { return mPadSizes[padGroup(catPadIndex).mPadSizeId].second; }
230
231int CathodeSegmentation::padDualSampaId(int catPadIndex) const { return padGroup(catPadIndex).mFECId; }
232
234{
235 return padGroupType(catPadIndex).id(mCatPadIndex2PadGroupTypeFastIndex[catPadIndex]);
236}
237
238std::ostream& operator<<(std::ostream& out, const std::pair<float, float>& p)
239{
240 out << p.first << "," << p.second;
241 return out;
242}
243
244template <typename T>
245void dump(std::ostream& out, const std::string& msg, const std::vector<T>& v, int n)
246{
247
248 out << msg << "\n";
249 for (auto i = 0; i < n; ++i) {
250 if (i < v.size()) {
251 out << v[i] << "\n";
252 }
253 }
254}
255
256std::ostream& operator<<(std::ostream& os, const CathodeSegmentation& seg)
257{
258 os << "segType " << seg.mSegType << "-" << (seg.mIsBendingPlane ? "B" : "NB");
259
260 os << boost::format(" %3d PG %2d PGT %2d PS\n") % seg.mPadGroups.size() % seg.mPadGroupTypes.size() %
261 seg.mPadSizes.size();
262
263 dump(os, "PG", seg.mPadGroups, seg.mPadGroups.size());
264 dump(os, "PGT", seg.mPadGroupTypes, seg.mPadGroupTypes.size());
265 dump(os, "PS", seg.mPadSizes, seg.mPadSizes.size());
266 return os;
267}
268
269} // namespace impl3
270} // namespace mapping
271} // namespace mch
272} // namespace o2
bool isBendingPlane
o2::mch::mapping::CathodeSegmentation seg
int32_t i
int findPadByFEE(int dualSampaId, int dualSampaChannel) const
std::vector< int > getCatPadIndexs(int dualSampaIds) const
Return the list of catPadIndexs for the pads of the given dual sampa.
std::vector< int > getNeighbouringCatPadIndexs(int catPadIndex) const
Return the list of catPadIndexs of the pads which are neighbours to catPadIndex.
CathodeSegmentation(int segType, bool isBendingPlane, std::vector< PadGroup > padGroups, std::vector< PadGroupType > padGroupTypes, std::vector< std::pair< float, float > > padSizes)
boost::geometry::model::point< double, 2, boost::geometry::cs::cartesian > Point
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
CathodeSegmentation *(*)(bool) CathodeSegmentationCreator
void dump(std::ostream &out, const std::string &msg, const std::vector< T > &v, int n)
std::set< int > getUnique(const std::vector< PadGroup > &padGroups)
int detElemId2SegType(int detElemId)
CathodeSegmentation * createCathodeSegmentation(int detElemId, bool isBendingPlane)
CathodeSegmentationCreator getCathodeSegmentationCreator(int segType)
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