ATLAS Offline Software
Loading...
Searching...
No Matches
JetVoronoiDiagramHelpers.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7
8using boost::geometry::area;
9using boost::geometry::intersection;
10
11
13 // operators *
14 Point operator*(double a, const Point &b){
15 coord x = (a * b.x);
16 coord y = (a * b.y);
17 return {x,y};
18 }
19
20 Point operator*(const Point &b,double a){
21 return a * b;
22 }
23
24 double operator*(const Point &a, const Point &b){
25 coord x = (a.x * b.x);
26 coord y = (a.y * b.y);
27 return x+y;
28 }
29
30
31 // operators +
32 Point operator+(const Point &a, const Point &b){
33 coord x = (a.x + b.x);
34 coord y = (a.y + b.y);
35 return {x,y};
36 }
37
38 Point operator+(double a, const Point &b){
39 coord x = (a + b.x);
40 coord y = (a + b.y);
41 return {x,y};
42 }
43
44 Point operator+(const Point &b, double a){
45 return a+b;
46 }
47
48
49 // operators -
50 Point operator-(const Point &a, const Point &b){
51 coord x = (a.x - b.x);
52 coord y = (a.y - b.y);
53 return {x,y};
54 }
55
57 return -1*b;
58 }
59
60
61 // logic operators
62 bool operator== (const Point &a, const Point &b){
63 bool isSame = true;
64 isSame &= (a.x == b.x);
65 isSame &= (a.y == b.y);
66 return isSame;
67 }
68
69 bool operator!= (const Point &a, const Point &b){
70 return ! (a==b);
71 }
72
73
74 // space functions
75 Point Center(const Point &a, const Point &b) {
76 return 0.5* (a+b);
77 }
78
79 Point Norm(const Point &a) {
80 return {a.y, -a.x};
81 }
82
83
84
85 Diagram::Diagram(const std::string & name)
86 : asg::AsgTool(name)
87 , m_x_min(-10.)
88 , m_x_max( 10.)
89 , m_y_min(-4. )
90 , m_y_max( 4. )
91 , m_scaleIntFloat( 1 )
92 , m_area_borders( 0 )
93 , m_N_points( 0 )
94 {
95 }
96
97
98 StatusCode Diagram::initialize() {
100 // recalculate borders
101 double w_x = (m_x_max - m_x_min) ;
102 double w_y = (m_y_max - m_y_min) ;
103 if (w_x<=0 || w_y<=0){
104 ATH_MSG_WARNING( "Wrong range setting x: " << m_x_min << " .. " << m_x_max << " y " << m_y_min << " .. " << m_y_max );
105 return StatusCode::FAILURE;
106 }
107 m_scaleIntFloat = ( (w_x >= w_y ) ? 1e7/w_x : 1e7/w_y );
108 m_borders.Add( m_x_min, m_y_min );
109 m_borders.Add( m_x_max, m_y_min );
110 m_borders.Add( m_x_max, m_y_max );
111 m_borders.Add( m_x_min, m_y_max );
112 m_area_borders = w_x*w_y;
113 ATH_MSG_INFO( "Initialized with range x: " << m_x_min << " .. " << m_x_max << " y " << m_y_min << " .. " << m_y_max );
114 return StatusCode::SUCCESS;
115 }
116
117
118 float Diagram::getCellArea(const coord x, const coord y) const{
119 Point p ( x , y );
120 size_t i_p = findPointIndex(p);
121 if ( i_p >= m_N_points ) {
122 ATH_MSG_WARNING("Can not find point : " << p.x << " " << p.y);
123 return 0;
124 }
125 return m_area_cells[i_p];
126 }
127
128
129 size_t Diagram::findPointIndex(const Point &a) const{
130 size_t index=0;
131 for (const Point& b: m_voro_vtx){
132 if (a==b) return index;
133 index++;
134 }
135 index++;
136 return index;
137 }
138
139
141 m_voro_vtx .clear();
142 m_area_cells .clear();
143 // m_voro_cells.clear();
144 m_N_points = 0;
145 }
146
147
149 m_N_points = m_voro_vtx.size();
150 if (m_N_points==0) {
151 ATH_MSG_WARNING( "Trying to create diagram withou any input");
152 return StatusCode::FAILURE;
153 }
154 Polygon mypts;
155 for (const Point& p : m_voro_vtx) mypts.Add(p.x*m_scaleIntFloat,p.y*m_scaleIntFloat);
156 VoronoiBoost vd;
157 // boost make voronoi
158 construct_voronoi(mypts.begin(), mypts.end(), &vd);
159 int cell_i = 0;
160 for (VoronoiCellBoost cell : vd.cells() ){ // for all cells in diagram
161 Polygon cell_area_tmp; // temprary polygon of cell
162 const VoronoiEdgeBoost * edge = cell.incident_edge(); // first edge
163 int csi = cell.source_index(); // index of cell
164 do { // for all edges which the cell has
165 const VoronoiVtxBoost * vtx0 = edge->vertex0();
166 const VoronoiVtxBoost * vtx1 = edge->vertex1();
167 int csi_ngbr = edge->twin()->cell()->source_index() ; // index of neighbour cell
168 if (edge->is_primary()){ // is nonintersecting edge (or something like that)
169 // first vertex in infinity -- interpolate
170 if ( vtx0==nullptr ) cell_area_tmp.push_back( interpolateInfinityVertex( csi, csi_ngbr ) );
171 // adding only second vertex if exists
172 if ( vtx1!=nullptr ) cell_area_tmp.Add(vtx1->x()/m_scaleIntFloat, vtx1->y()/m_scaleIntFloat); // correct for scale
173 // second vertex in infinity -- interpolate (notice the change of index order)
174 else cell_area_tmp.push_back( interpolateInfinityVertex( csi_ngbr, csi ) );
175 }
176 edge=edge->next();
177 } while (edge != cell.incident_edge() );
178 // intersection and are calculation
179 Polygon cell_area;
180 double areasize = intersectionAndArea(cell_area_tmp,m_borders,cell_area);
181 // m_voro_cells.push_back(cell_area); // save cell polygon
182 m_area_cells.push_back(areasize);
183 cell_i++;
184 }
185 return checkStatus(vd,cell_i);
186 }
187
188
189 Point Diagram::interpolateInfinityVertex(const int i_a, const int i_b){
190 double sign = 300; // to limit infinity
191 Point A = m_voro_vtx[i_a];
192 Point B = m_voro_vtx[i_b];
193 return Center(A,B) + Norm(B-A) * sign ;
194 }
195
196
197 bool Diagram::checkSameNumber(double in, double out, const std::string & description){
198 double den = std::abs(in)+std::abs(out);
199 if (den < std::numeric_limits<double>::epsilon()) return true;
200 if ( fabs(in-out)/den > 1e4) {
201 ATH_MSG_WARNING("Difference in " << description.c_str() << ": " << in << " (should be " << out << ")");
202 return false;
203 };
204 return true;
205 }
206
207
208 StatusCode Diagram::checkStatus(const VoronoiBoost &vd, size_t n_cells_processed){
209 bool isAllOK = true;
210 double sum = 0; for (double voroarea : m_area_cells) sum+=voroarea;
211 isAllOK &= checkSameNumber( vd.cells().size() , m_voro_vtx.size(), "number of boost cells" );
212 isAllOK &= checkSameNumber( n_cells_processed , m_voro_vtx.size(), "number of processed cells" );
213 isAllOK &= checkSameNumber( m_area_cells.size(), m_voro_vtx.size(), "number of calculated areas" );
214 isAllOK &= checkSameNumber( sum , m_area_borders , "area sum" );
215 if(!isAllOK){
216 m_N_points = 0;
217 return StatusCode::FAILURE;
218 }
219 return StatusCode::SUCCESS;
220 }
221
222
223 double Diagram::intersectionAndArea(Polygon const & geo1, Polygon const & geo2, Polygon &out){
224 VoronoiPolygonBoost pol1, pol2;
225 std::deque<VoronoiPolygonBoost> pol3; // list of poly's because intersection could be more than one polygon (not in our case)
226 geo1.FillVoroPolygon(pol1);
227 geo2.FillVoroPolygon(pol2);
228 // boost make intersection
229 intersection(pol1,pol2,pol3);
230 if ( !pol3.empty() ){ // it has something our shape is on first place
231 for ( const VoronoiPointBoost vp: pol3.at(0).outer() ) out.Add(vp.x(),vp.y());
232 }
233 else return 0;
234 // boost calculate area
235 return area(pol3.at(0));
236 }
237
238}
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
double area(double R)
boost::geometry::model::d2::point_xy< double > VoronoiPointBoost
boost::polygon::voronoi_diagram< double >::cell_type VoronoiCellBoost
boost::polygon::voronoi_diagram< double >::edge_type VoronoiEdgeBoost
boost::polygon::voronoi_diagram< double >::vertex_type VoronoiVtxBoost
boost::polygon::voronoi_diagram< double > VoronoiBoost
Jakub Cuth May 2015.
boost::geometry::model::polygon< VoronoiPointBoost > VoronoiPolygonBoost
static Double_t a
int sign(int a)
#define y
#define x
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
std::string description
glabal timer - how long have I taken so far?
Definition hcg.cxx:91
bool operator!=(const Point &a, const Point &b)
Point Center(const Point &a, const Point &b)
Point operator+(const Point &a, const Point &b)
Point operator-(const Point &a, const Point &b)
bool operator==(const Point &a, const Point &b)
Point operator*(double a, const Point &b)
double coord
Type of coordination system.
Definition index.py:1
hold the test vectors and ease the comparison
size_t findPointIndex(const Point &a) const
StatusCode checkStatus(const VoronoiBoost &vd, size_t n_cells_processed)
bool checkSameNumber(double in, double out, const std::string &description)
Point interpolateInfinityVertex(const int i_a, const int i_b)
float getCellArea(const coord x, const coord y) const
StatusCode initialize()
Dummy implementation of the initialisation function.
double intersectionAndArea(JetVoronoiDiagramHelpers::Polygon const &geo1, JetVoronoiDiagramHelpers::Polygon const &geo2, JetVoronoiDiagramHelpers::Polygon &out)
void FillVoroPolygon(VoronoiPolygonBoost &out) const