Project
Loading...
Searching...
No Matches
ContourCreator.inl
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 O2_MCH_CONTOUR_CONTOURCREATOR_INL
16#define O2_MCH_CONTOUR_CONTOURCREATOR_INL
17
18#include <utility>
19#include <vector>
20#include <iostream>
21#include "Edge.h"
22#include "Polygon.h"
23#include "Contour.h"
24#include "SegmentTree.h"
25#include <algorithm>
26
27namespace o2
28{
29namespace mch
30{
31namespace contour
32{
33namespace impl
34{
35
36template <typename T>
38{
39 // sort vertical edges in ascending x order
40 // if same x, insure that left edges are before right edges
41 // within same x, order by increasing bottommost y
42 // Mind your steps ! This sorting is critical to the contour merging algorithm !
43
44 std::sort(edges.begin(), edges.end(), [](const VerticalEdge<T>& e1, const VerticalEdge<T>& e2) {
45
46 auto x1 = e1.begin().x;
47 auto x2 = e2.begin().x;
48
49 auto y1 = bottom(e1);
50 auto y2 = bottom(e2);
51
52 if (areEqual(x1, x2)) {
53 if (isLeftEdge(e1) && isRightEdge(e2)) {
54 return true;
55 }
56 if (isRightEdge(e1) && isLeftEdge(e2)) {
57 return false;
58 }
59 return y1 < y2;
60 } else if (x1 < x2) {
61 return true;
62 } else {
63 return false;
64 }
65 });
66}
67
68template <typename T>
70{
71 auto y1 = edge.begin().y;
72 auto y2 = edge.end().y;
73 return y2 > y1 ? Interval<T>(y1, y2) : Interval<T>(y2, y1);
74}
75
76template <typename T>
77std::vector<VerticalEdge<T>> getVerticalEdges(const Polygon<T>& polygon)
78{
80 std::vector<VerticalEdge<T>> edges;
81 for (auto i = 0; i < polygon.size() - 1; ++i) {
82 auto current = polygon[i];
83 auto next = polygon[i + 1];
84 if (current.x == next.x) {
85 edges.push_back({ current.x, current.y, next.y });
86 }
87 }
88 return edges;
89}
90
91template <typename T>
92std::vector<VerticalEdge<T>> getVerticalEdges(const std::vector<Polygon<T>>& polygons)
93{
94 std::vector<VerticalEdge<T>> edges;
95 for (const auto& p : polygons) {
96 auto e = getVerticalEdges(p);
97 edges.insert(edges.end(), e.begin(), e.end());
98 }
99 return edges;
100}
101
102template <typename T>
103T getX(const Vertex<T>& v)
104{
105 return v.x;
106}
107
108template <typename T>
109T getY(const Vertex<T>& v)
110{
111 return v.y;
112}
113
114template <typename T>
115using GetVertexPosFunc = T (*)(const Vertex<T>&);
116
117template <typename T>
118std::vector<T> getPositions(const std::vector<Polygon<T>>& polygons, GetVertexPosFunc<T> func)
119{
120 std::vector<T> ypos;
121 for (auto i = 0; i < polygons.size(); ++i) {
122 for (auto j = 0; j < polygons[i].size(); ++j) {
123 ypos.push_back(func(polygons[i][j]));
124 }
125 }
126 std::sort(ypos.begin(), ypos.end());
127 auto last = std::unique(ypos.begin(), ypos.end(), [](const T& a, const T& b) { return areEqual(a, b); });
128 ypos.erase(last, ypos.end());
129 return ypos;
130}
131
132template <typename T>
133std::vector<T> getYPositions(const std::vector<Polygon<T>>& polygons)
134{
135 return getPositions(polygons, getY);
136}
137
138template <typename T>
139std::vector<T> getXPositions(const std::vector<Polygon<T>>& polygons)
140{
141 return getPositions(polygons, getX);
142}
143
144template <typename T>
145std::vector<VerticalEdge<T>> sweep(Node<T>* segmentTree, const std::vector<VerticalEdge<T>>& polygonVerticalEdges)
146{
147 std::vector<VerticalEdge<T>> contourVerticalEdges;
148
149 std::vector<Interval<T>> edgeStack;
150
151 for (auto i = 0; i < polygonVerticalEdges.size(); ++i) {
152
153 const auto& edge = polygonVerticalEdges[i];
154 auto ival = interval(edge);
155
156 if (isLeftEdge(edge)) {
157 segmentTree->contribution(ival, edgeStack);
158 segmentTree->insertInterval(ival);
159 } else {
160 segmentTree->deleteInterval(ival);
161 segmentTree->contribution(ival, edgeStack);
162 }
163
164 auto e1{ edge };
165
166 if (i < polygonVerticalEdges.size() - 1) {
167 e1 = polygonVerticalEdges[i + 1];
168 }
169
170 if ((isLeftEdge(edge) != isLeftEdge(e1)) || (!areEqual(edge.begin().x, e1.begin().x)) ||
171 (i == polygonVerticalEdges.size() - 1)) {
172 for (auto es : edgeStack) {
173 contourVerticalEdges.push_back(isRightEdge(edge) ? VerticalEdge<T>{ edge.begin().x, es.begin(), es.end() }
174 : VerticalEdge<T>{ edge.begin().x, es.end(), es.begin() });
175 }
176 edgeStack.clear();
177 }
178 }
179
180 return contourVerticalEdges;
181}
182
191template <typename T>
192std::vector<HorizontalEdge<T>> verticalsToHorizontals(const std::vector<VerticalEdge<T>>& verticals)
193{
194 std::vector<HorizontalEdge<T>> horizontals(verticals.size());
195
196 using VertexWithRef = std::pair<Vertex<T>, T>;
197 std::vector<VertexWithRef> vertices;
198
199 for (auto i = 0; i < verticals.size(); ++i) {
200 const auto& edge = verticals[i];
201 vertices.push_back({ edge.begin(), i });
202 vertices.push_back({ edge.end(), i });
203 }
204
205 std::sort(vertices.begin(), vertices.end(),
206 [](const VertexWithRef& v1, const VertexWithRef& v2) { return v1.first < v2.first; });
207
208 for (auto i = 0; i < vertices.size() / 2; ++i) {
209 const auto& p1 = vertices[2 * i];
210 const auto& p2 = vertices[2 * i + 1];
211 const VerticalEdge<T>& refEdge = verticals[p1.second];
212 auto e = p1.first.x;
213 auto b = p2.first.x;
214 if ((areEqual(p1.first.y, bottom(refEdge)) && isLeftEdge(refEdge)) ||
215 (areEqual(p1.first.y, top(refEdge)) && isRightEdge(refEdge))) {
216 std::swap(b, e);
217 }
218 HorizontalEdge<T> h{ p1.first.y, b, e };
219 // which vertical edge is preceding this horizontal ?
220 int preceding = p1.second;
221 int next = p2.second;
222 if (b > e) {
223 std::swap(preceding, next);
224 }
225 horizontals[preceding] = h;
226 }
227 return horizontals;
228}
229
230template <typename T>
231Contour<T> finalizeContour(const std::vector<VerticalEdge<T>>& verticals,
232 const std::vector<HorizontalEdge<T>>& horizontals)
233{
234 if (verticals.size() != horizontals.size()) {
235 throw std::invalid_argument("should get the same number of verticals and horizontals");
236 }
237
238 for (auto i = 0; i < verticals.size(); ++i) {
239 if (horizontals[i].begin() != verticals[i].end()) {
240 throw std::invalid_argument("got an horizontal edge not connected to its (supposedly) preceding vertical edge");
241 }
242 }
243
244 std::vector<ManhattanEdge<T>> all;
245
246 for (auto i = 0; i < verticals.size(); ++i) {
247 all.push_back(verticals[i]);
248 all.push_back(horizontals[i]);
249 }
250
251 Contour<T> contour;
252
253 std::vector<bool> alreadyAdded(all.size(), false);
254 std::vector<int> inorder;
255
256 int nofUsed{ 0 };
257 int iCurrent{ 0 };
258
259 ManhattanEdge<T> startSegment{ all[iCurrent] };
260
261 while (nofUsed < all.size()) {
262
263 const ManhattanEdge<T>& currentSegment{ all[iCurrent] };
264 inorder.push_back(iCurrent);
265 alreadyAdded[iCurrent] = true;
266 ++nofUsed;
267 if (currentSegment.end() == startSegment.begin()) {
268 if (inorder.empty()) {
269 throw std::runtime_error("got an empty polygon");
270 }
271 std::vector<Vertex<T>> vertices;
272 vertices.reserve(inorder.size());
273 for (auto i : inorder) {
274 vertices.push_back(all[i].begin());
275 }
276 Polygon<T> polygon(vertices.begin(), vertices.end());
277 contour.addPolygon(close(polygon));
278 iCurrent = std::distance(alreadyAdded.begin(), std::find_if(alreadyAdded.begin(), alreadyAdded.end(),
279 [](bool a) { return a == false; }));
280 if (iCurrent<all.size()) {
281 startSegment = all[iCurrent];
282 inorder.clear();
283 }
284 }
285
286 for (auto i = 0; i < alreadyAdded.size(); ++i) {
287 if (i != iCurrent && alreadyAdded[i] == false) {
288 if (currentSegment.end() == all[i].begin()) {
289 iCurrent = i;
290 break;
291 }
292 }
293 }
294 }
295
296 return contour;
297}
298
299} // namespace impl
300} // namespace contour
301} // namespace mch
302} // namespace o2
303
304#endif // ALO_CONTOURCREATOR_INL
bool areEqual(double a, double b)
int32_t i
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char e
constexpr int p2()
constexpr int p1()
constexpr to accelerate the coordinates changing
std::vector< LocalPoint > getPositions(int npoints)
std::vector< SidecarEdge > edges
uint32_t j
Definition RawData.h:0
Class for time synchronization of RawReader instances.
Contour< T > & addPolygon(const Polygon< T > &polygon)
Definition Contour.h:78
size_type size() const
Definition Polygon.h:61
Vertex< T > begin() const
Definition Edge.h:46
Vertex< T > end() const
Definition Edge.h:48
void insertInterval(Interval< T > i)
void deleteInterval(Interval< T > i)
void contribution(Interval< T > i, std::vector< o2::mch::contour::impl::Interval< T > > &edgeStack)
GLenum func
Definition glcorearb.h:778
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition glcorearb.h:5034
GLuint GLuint end
Definition glcorearb.h:469
const GLdouble * v
Definition glcorearb.h:832
GLuint GLfloat GLfloat GLfloat x1
Definition glcorearb.h:5034
GLdouble GLdouble GLdouble GLdouble top
Definition glcorearb.h:4077
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint GLint bottom
Definition glcorearb.h:1979
GLfloat GLfloat v1
Definition glcorearb.h:812
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLfloat GLfloat GLfloat v2
Definition glcorearb.h:813
GLsizei startSegment
Definition glcorearb.h:5505
bool isLeftEdge(const VerticalEdge< T > &edge)
Definition Edge.h:102
std::vector< VerticalEdge< T > > sweep(Node< T > *segmentTree, const std::vector< VerticalEdge< T > > &polygonVerticalEdges)
std::vector< VerticalEdge< T > > getVerticalEdges(const Polygon< T > &polygon)
Interval< T > interval(const VerticalEdge< T > &edge)
bool isRightEdge(const VerticalEdge< T > &edge)
Definition Edge.h:108
std::vector< HorizontalEdge< T > > verticalsToHorizontals(const std::vector< VerticalEdge< T > > &verticals)
Contour< T > finalizeContour(const std::vector< VerticalEdge< T > > &verticals, const std::vector< HorizontalEdge< T > > &horizontals)
T(*)(const Vertex< T > &) GetVertexPosFunc
std::vector< T > getYPositions(const std::vector< Polygon< T > > &polygons)
std::vector< T > getXPositions(const std::vector< Polygon< T > > &polygons)
void sortVerticalEdges(std::vector< VerticalEdge< T > > &edges)
Polygon< T > close(Polygon< T > polygon)
Definition Polygon.h:126
double * getX(double *xyDxy, int N)
double * getY(double *xyDxy, int N)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...