ATLAS Offline Software
VolumeSplitterUtils.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3  */
4 
5 
7 #include "GeoModelKernel/GeoTube.h"
8 #include "GeoModelKernel/GeoPcon.h"
9 #include <iostream>
10 
11 namespace InDetDD {
12  const SegmentList&
13  SegmentSplitter::split(const Zone* zone, const Ray& ray) {
14  addChildSegment(zone, ray);
15  return m_segments;
16  }
17 
18  Ray
20  //std::cout << "addChildSegment: " << zone->label() << " " << ray << std::endl;
21  // Point startPoint = ray.start();
22  // If start point is not yet know to be in current zone. We need to search children.
23  // If not in children searchPoint will return a copy of ray. Otherwise it will
24  // add segments of the child and return a ray that starts from the exit of the child.
25  Ray nextRay = ray;
26 
27  if (!ray.foundStart()) {
28  nextRay = searchPoint(zone, ray);
29  }
30  bool exit = false;
31  while (nextRay.valid() && !exit) {
32  Point nextPoint = getNextBoundary(zone, nextRay);
33  addSegment(zone, nextRay.start(), nextPoint);
34 
35  //std::cout << "Next boundary: " << nextPoint;
36  //if (nextPoint.last()) std::cout << " Last ";
37  //if (nextPoint.exit()) std::cout << " Exit ";
38  //if (nextPoint.child()) std::cout << " Child: " << nextPoint.child()->label();
39  //std::cout << std::endl;
40 
41  if (nextPoint.last()) { // last indicates end of ray. ie ray ended before exit or child entry.
42  nextRay.setInvalid();
43  } else {
44  nextRay.set(nextPoint, nextRay.end());
45  }
46  exit = nextPoint.exit();
47  if (nextPoint.child()) {
48  nextRay = addChildSegment(nextPoint.child(), nextRay);
49  }
50  }
51  return nextRay;
52  }
53 
54  void
56  m_segments.add(zone->label(), start, end, zone->rotated());
57  }
58 
59  Point
61  Point nextPoint; //invalid
62 
63  // Search children
64  for (Zone::ChildIterator iter = zone->begin(); iter != zone->end(); ++iter) {
65  const Zone* child = *iter;
66  // return invalid if not crossed.
67  Point newPoint = child->findEntry(ray);
68  nextPoint = nearestPoint(newPoint, nextPoint);
69  }
70  //search exit
71  nextPoint = nearestPoint(zone->findExit(ray), nextPoint);
72  if (!nextPoint.valid()) {
73  // Return endpoint
74  return ray.end();
75  }
76  return nextPoint;
77  }
78 
79  Point
80  SegmentSplitter::nearestPoint(const Point& point1, const Point& point2) {
81  if (!point2.valid()) return point1;
82 
83  if (!point1.valid()) return point2;
84 
85  if ((point2.r() == point1.r() && point2.z() < point1.z()) ||
86  (point2.z() == point1.z() && point2.r() < point1.r())) {
87  return point2;
88  }
89  return point1;
90  //return first point. If either invalid return the other.
91  // If both invalid return invalid
92  }
93 
94  Ray
95  SegmentSplitter::searchPoint(const Zone* zone, const Ray& ray) {
96  // If not found in children return original ray.
97  //std::cout << "Searching for point " << ray.start() << std::endl;
98  Ray nextRay = ray;
99 
100  for (Zone::ChildIterator iter = zone->begin(); iter != zone->end(); ++iter) {
101  const Zone* child = *iter;
102  if (child->inSide(ray.start())) {
103  //std::cout << "Point " << ray.start() << " found in zone " << child->label() << std::endl;
104  nextRay = addChildSegment(child, ray);
105  break;
106  }
107  }
108  nextRay.setFound();
109  return nextRay;
110  }
111 
112  Zone::Zone(const std::string& label, bool rotated)
113  : m_label(label),
114  m_rotated(rotated)
115  {}
116 
118  for (ChildIterator iter = begin(); iter != end(); ++iter) {
119  delete *iter;
120  }
121  }
122 
123  void
124  Zone::add(const Zone* zone) {
125  m_children.push_back(zone);
126  }
127 
129  : Zone(label)
130  {}
131 
132  bool
133  UnboundedZone::inSide(const Point&) const {
134  return true;
135  }
136 
137  Point
139  // Will never be called.
140  return {};
141  }
142 
143  Point
144  UnboundedZone::findExit(const Ray&) const {
145  // Invalid means no exit point.
146  return {};
147  }
148 
149  TubeZone::TubeZone(const std::string& label, double zmin, double zmax, double rmin, double rmax, bool rotated)
150  : Zone(label, rotated),
151  m_zmin(zmin),
152  m_zmax(zmax),
153  m_rmin(rmin),
154  m_rmax(rmax)
155  {}
156 
157  TubeZone::TubeZone(const std::string& label, const GeoTube* shape, double zOffset, bool rotated)
158  : Zone(label, rotated),
159  m_zmin(zOffset - shape->getZHalfLength()),
160  m_zmax(zOffset + shape->getZHalfLength()),
161  m_rmin(shape->getRMin()),
162  m_rmax(shape->getRMax())
163  {}
164 
165 
166  bool
167  TubeZone::inSide(const Point& point) const {
168  return(inZ(point.z()) && inR(point.r()));
169  }
170 
171  bool
172  TubeZone::inZ(double z) const {
173  return(z >= m_zmin && z < m_zmax);
174  }
175 
176  bool
177  TubeZone::inR(double r) const {
178  return(r >= m_rmin && r < m_rmax);
179  }
180 
181 // Assume either vertical or horizontal.
182  Point
183  TubeZone::findEntry(const Ray& ray) const {
184  if (ray.horizontal()) {
185  if (inR(ray.start().r()) && ray.start().z() < m_zmin && ray.end().z() > m_zmin) {
186  Point p(m_zmin, ray.start().r());
187  p.setChild(this);
188  return p;
189  }
190  } else if (ray.vertical()) {
191  if (inZ(ray.start().z()) && ray.start().r() < m_rmin && ray.end().r() > m_rmin) {
192  Point p(ray.start().z(), m_rmin);
193  p.setChild(this);
194  return p;
195  }
196  } else {
197  std::cout << "Unexpected case" << std::endl;
198  }
199  // Return invalid point since doesn't intersect.
200  return {}; // invalid point
201  }
202 
203 // Assume already inside.
204  Point
205  TubeZone::findExit(const Ray& ray) const {
206  if (ray.horizontal()) {
207  if (ray.end().z() > m_zmax) {
208  Point p(m_zmax, ray.start().r());
209  p.setExit();
210  return p;
211  }
212  } else if (ray.vertical()) {
213  if (ray.end().r() > m_rmax) {
214  Point p(ray.start().z(), m_rmax);
215  p.setExit();
216  return p;
217  }
218  } else {
219  std::cout << "Unexpected case" << std::endl;
220  }
221  // ends with. Return invalid point.
222  return {};
223  }
224 
225  PconZone::PconZone(const std::string& label, bool rotated)
226  : Zone(label, rotated)
227  {}
228 
229  PconZone::PconZone(const std::string& label, const GeoPcon* shape, bool rotated)
230  : Zone(label, rotated) {
231  for (unsigned int i = 0; i < shape->getNPlanes(); ++i) {
232  addPlane(shape->getZPlane(i), shape->getRMinPlane(i), shape->getRMaxPlane(i));
233  }
234  }
235 
236  void
237  PconZone::addPlane(double z, double rmin, double rmax) {
238  m_z.push_back(z);
239  m_rmin.push_back(rmin);
240  m_rmax.push_back(rmax);
241  }
242 
243  bool
244  PconZone::inSide(const Point& point) const {
245  // Assume comes in pairs with same CLHEP::radii.
246  for (unsigned int i = 0; i + 1 < m_z.size(); i += 2) {
247  if (inZ(i, point.z()) && inR(i, point.r())) return true;
248  }
249  return false;
250  }
251 
252  bool
253  PconZone::inZ(unsigned int i, double z) const {
254  return(z >= m_z[i] && z < m_z[i + 1]);
255  }
256 
257  bool
258  PconZone::inR(unsigned int i, double r) const {
259  if (i >= m_z.size()) return false;
260 
261  return(r >= m_rmin[i] && r < m_rmax[i]);
262  }
263 
264 // Assume either vertical or horizontal.
265  Point
266  PconZone::findEntry(const Ray& ray) const {
267  if (ray.horizontal()) {
268  for (unsigned int i = 0; i + 1 < m_z.size(); i += 2) {
269  if (inR(i, ray.start().r()) && ray.start().z() < m_z[i] && ray.end().z() > m_z[i]) {
270  Point p(m_z[i], ray.start().r());
271  p.setChild(this);
272  return p;
273  }
274  }
275  } else if (ray.vertical()) {
276  for (unsigned int i = 0; i + 1 < m_z.size(); i += 2) {
277  if (inZ(i, ray.start().z()) && ray.start().r() < m_rmin[i] && ray.end().r() > m_rmin[i]) {
278  Point p(ray.start().z(), m_rmin[i]);
279  p.setChild(this);
280  return p;
281  }
282  }
283  } else {
284  std::cout << "Unexpected case" << std::endl;
285  }
286  // Return invalid point since doesn't intersect.
287  return {}; // invalid point
288  }
289 
290 // Assume already inside.
291  Point
292  PconZone::findExit(const Ray& ray) const {
293  if (ray.horizontal()) {
294  for (unsigned int i = 0; i + 1 < m_z.size(); i += 2) {
295  if (inZ(i, ray.start().z()) && ray.end().z() > m_z[i + 1] && !inR(i + 2, ray.start().r())) {
296  Point p(m_z[i + 1], ray.start().r());
297  p.setExit();
298  return p;
299  }
300  }
301  } else if (ray.vertical()) {
302  for (unsigned int i = 0; i + 1 < m_z.size(); i += 2) {
303  if (inZ(i, ray.start().z()) && ray.end().r() > m_rmax[i]) {
304  Point p(ray.start().z(), m_rmax[i]);
305  p.setExit();
306  return p;
307  }
308  }
309  } else {
310  std::cout << "Unexpected case" << std::endl;
311  }
312  // ends with. Return invalid point.
313  return {};
314  }
315 
317  : m_valid(false),
318  m_found(false),
319  m_horizontal(false),
320  m_vertical(false)
321  {}
322 
323  Ray::Ray(const Point& start, const Point& end)
324  : m_valid(true),
325  m_found(false),
326  m_start(start),
327  m_end(end) {
328  m_end.setLast();
329  setDirection();
330  }
331 
332  void
333  Ray::set(const Point& start, const Point& end) {
334  m_start = start;
335  m_end = end;
336  setDirection();
337  }
338 
339  void
341  m_vertical = (m_start.z() == m_end.z());
342  m_horizontal = (m_start.r() == m_end.r());
343  if (m_vertical && m_horizontal) {
344  m_vertical = false;
345  m_horizontal = false;
346  }
347  }
348 
350  : m_valid(false),
351  m_exit(false),
352  m_last(false),
353  m_z(0),
354  m_r(0),
355  m_child(nullptr)
356  {}
357 
358  Point::Point(double z, double r)
359  : m_valid(true),
360  m_exit(false),
361  m_last(false),
362  m_z(z),
363  m_r(r),
364  m_child(nullptr)
365  {}
366 
367  Segment::Segment(const std::string& label, const Point& start, const Point& end, bool rotated)
368  : m_label(label),
369  m_rotated(rotated),
370  m_zmin(start.z()),
371  m_zmax(end.z()),
372  m_rmin(start.r()),
373  m_rmax(end.r())
374  {}
375 
376  void
377  SegmentList::add(const std::string& label, const Point& start, const Point& end, bool rotated) {
378  m_segments.emplace_back(label, start, end, rotated);
379  }
380 
381  void
383  m_segments.push_back(segment);
384  }
385 
386  bool
388  if (size() > 0) {
389  const Segment& seg = m_segments[0];
390  return(seg.rmin() == seg.rmax());
391  }
392  // Not relevant if array empty.
393  return true;
394  }
395 
396  void
398  for (std::vector<Segment>::const_iterator iter = m_segments.begin(); iter != m_segments.end(); ++iter) {
399  iter->print();
400  }
401  }
402 
403  void
404  Segment::print() const {
405  std::cout << m_label << " "
406  << m_zmin << " "
407  << m_zmax << " "
408  << m_rmin << " "
409  << m_rmax
410  << std::endl;
411  }
412 
413  std::ostream&
414  operator << (std::ostream& os, const InDetDD::Ray& ray) {
415  if (!ray.valid()) {
416  os << "INVALID";
417  } else {
418  os << ray.start() << " --> " << ray.end();
419  }
420  return os;
421  }
422 
423  std::ostream&
424  operator << (std::ostream& os, const InDetDD::Point& point) {
425  if (!point.valid()) {
426  os << "INVALID";
427  } else {
428  os << "(" << point.z() << ", " << point.r() << ")";
429  }
430  return os;
431  }
432 }
InDetDD::Zone::ChildIterator
std::vector< const Zone * >::const_iterator ChildIterator
Definition: VolumeSplitterUtils.h:73
beamspotman.r
def r
Definition: beamspotman.py:676
InDetDD::Segment::m_rmin
double m_rmin
Definition: VolumeSplitterUtils.h:151
InDetDD::Point::child
const Zone * child() const
Definition: VolumeSplitterUtils.h:30
InDetDD::SegmentSplitter::addSegment
void addSegment(const Zone *, const Point &start, const Point &end)
Definition: VolumeSplitterUtils.cxx:55
InDetDD::PconZone::addPlane
void addPlane(double z, double rmin, double rmax)
Definition: VolumeSplitterUtils.cxx:237
InDetDD::SegmentSplitter::split
const SegmentList & split(const Zone *, const Ray &)
Definition: VolumeSplitterUtils.cxx:13
InDetDD::Point::valid
bool valid() const
Definition: VolumeSplitterUtils.h:24
InDetDD::Ray::m_start
Point m_start
Definition: VolumeSplitterUtils.h:65
InDetDD::Point::Point
Point()
Definition: VolumeSplitterUtils.cxx:349
InDetDD::PconZone::m_z
std::vector< double > m_z
Definition: VolumeSplitterUtils.h:131
InDetDD::Ray::setDirection
void setDirection()
Definition: VolumeSplitterUtils.cxx:340
InDetDD::SegmentList::m_segments
std::vector< Segment > m_segments
Definition: VolumeSplitterUtils.h:170
InDetDD::Zone::begin
ChildIterator begin() const
Definition: VolumeSplitterUtils.h:80
InDetDD::UnboundedZone::findExit
virtual Point findExit(const Ray &ray) const
Definition: VolumeSplitterUtils.cxx:144
InDetDD::Segment::rmin
double rmin() const
Definition: VolumeSplitterUtils.h:143
InDetDD::Segment::Segment
Segment(const std::string &label, const Point &start, const Point &end, bool rotated=false)
Definition: VolumeSplitterUtils.cxx:367
PixelAthClusterMonAlgCfg.zmin
zmin
Definition: PixelAthClusterMonAlgCfg.py:169
InDetDD::Zone::add
void add(const Zone *)
Definition: VolumeSplitterUtils.cxx:124
PlotCalibFromCool.label
label
Definition: PlotCalibFromCool.py:78
InDetDD::Zone
Definition: VolumeSplitterUtils.h:71
InDetDD::Ray::end
const Point & end() const
Definition: VolumeSplitterUtils.h:50
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
InDetDD::TubeZone::inZ
bool inZ(double z) const
Definition: VolumeSplitterUtils.cxx:172
InDetDD::SegmentSplitter::nearestPoint
Point nearestPoint(const Point &point1, const Point &point2)
Definition: VolumeSplitterUtils.cxx:80
InDetDD::Segment::print
void print() const
Definition: VolumeSplitterUtils.cxx:404
InDetDD::SegmentSplitter::addChildSegment
Ray addChildSegment(const Zone *, const Ray &)
Definition: VolumeSplitterUtils.cxx:19
InDetDD::Point::exit
bool exit() const
Definition: VolumeSplitterUtils.h:25
InDetDD::Point::last
bool last() const
Definition: VolumeSplitterUtils.h:26
InDetDD::TubeZone::m_rmin
double m_rmin
Definition: VolumeSplitterUtils.h:115
InDetDD::Ray::setInvalid
void setInvalid()
Definition: VolumeSplitterUtils.h:56
InDetDD::Segment::m_zmin
double m_zmin
Definition: VolumeSplitterUtils.h:149
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
InDetDD::Point::z
double z() const
Definition: VolumeSplitterUtils.h:28
InDetDD::operator<<
std::ostream & operator<<(std::ostream &os, const SiCellId &cellId)
Definition: SiCellId.cxx:8
InDetDD::Segment::m_zmax
double m_zmax
Definition: VolumeSplitterUtils.h:150
InDetDD::Point::setLast
void setLast()
Definition: VolumeSplitterUtils.h:34
InDetDD::Zone::~Zone
virtual ~Zone()
Definition: VolumeSplitterUtils.cxx:117
InDetDD::PconZone::inR
bool inR(unsigned int i, double r) const
Definition: VolumeSplitterUtils.cxx:258
InDetDD::Ray
Definition: VolumeSplitterUtils.h:44
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
InDetDD::PconZone::m_rmax
std::vector< double > m_rmax
Definition: VolumeSplitterUtils.h:133
InDetDD::TubeZone::findEntry
virtual Point findEntry(const Ray &ray) const
Definition: VolumeSplitterUtils.cxx:183
InDetDD::Segment::m_label
std::string m_label
Definition: VolumeSplitterUtils.h:147
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
InDetDD::Ray::horizontal
bool horizontal() const
Definition: VolumeSplitterUtils.h:53
InDetDD::SegmentList::size
unsigned int size() const
Definition: VolumeSplitterUtils.h:160
InDetDD::PconZone::PconZone
PconZone(const std::string &label, bool rotated=false)
Definition: VolumeSplitterUtils.cxx:225
InDetDD::Zone::end
ChildIterator end() const
Definition: VolumeSplitterUtils.h:81
InDetDD::SegmentSplitter::getNextBoundary
Point getNextBoundary(const Zone *, const Ray &)
Definition: VolumeSplitterUtils.cxx:60
InDetDD::SegmentSplitter::m_segments
SegmentList m_segments
Definition: VolumeSplitterUtils.h:187
PixelAthClusterMonAlgCfg.zmax
zmax
Definition: PixelAthClusterMonAlgCfg.py:169
InDetDD::PconZone::inSide
virtual bool inSide(const Point &point) const
Definition: VolumeSplitterUtils.cxx:244
InDetDD::Point
Definition: VolumeSplitterUtils.h:20
InDetDD::SegmentList::horizontal
bool horizontal() const
Definition: VolumeSplitterUtils.cxx:387
calibdata.exit
exit
Definition: calibdata.py:236
InDetDD::Ray::start
const Point & start() const
Definition: VolumeSplitterUtils.h:49
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
InDetDD::SegmentList::add
void add(const std::string &label, const Point &start, const Point &end, bool rotated=false)
Definition: VolumeSplitterUtils.cxx:377
InDetDD::Zone::inSide
virtual bool inSide(const Point &point) const =0
InDetDD::PconZone::m_rmin
std::vector< double > m_rmin
Definition: VolumeSplitterUtils.h:132
InDetDD::UnboundedZone::findEntry
virtual Point findEntry(const Ray &ray) const
Definition: VolumeSplitterUtils.cxx:138
python.draw_obj.zone
def zone(nx, ny)
Definition: draw_obj.py:288
InDetDD::Ray::setFound
void setFound()
Definition: VolumeSplitterUtils.h:55
InDetDD::Ray::set
void set(const Point &start, const Point &end)
Definition: VolumeSplitterUtils.cxx:333
InDetDD::UnboundedZone::inSide
virtual bool inSide(const Point &point) const
Definition: VolumeSplitterUtils.cxx:133
InDetDD::PconZone::findEntry
virtual Point findEntry(const Ray &ray) const
Definition: VolumeSplitterUtils.cxx:266
InDetDD::Zone::m_children
std::vector< const Zone * > m_children
Definition: VolumeSplitterUtils.h:87
InDetDD::Segment
Definition: VolumeSplitterUtils.h:136
InDetDD::TubeZone::findExit
virtual Point findExit(const Ray &ray) const
Definition: VolumeSplitterUtils.cxx:205
python.changerun.m_start
m_start
Definition: changerun.py:84
InDetDD::TubeZone::m_rmax
double m_rmax
Definition: VolumeSplitterUtils.h:116
InDetDD::Zone::findEntry
virtual Point findEntry(const Ray &ray) const =0
InDetDD::UnboundedZone::UnboundedZone
UnboundedZone(const std::string &label)
Definition: VolumeSplitterUtils.cxx:128
VolumeSplitterUtils.h
InDetDD::PconZone::inZ
bool inZ(unsigned int i, double z) const
Definition: VolumeSplitterUtils.cxx:253
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
InDetDD::Zone::Zone
Zone(const std::string &label, bool rotated=false)
Definition: VolumeSplitterUtils.cxx:112
InDetDD::Ray::Ray
Ray()
Definition: VolumeSplitterUtils.cxx:316
InDetDD::Segment::rmax
double rmax() const
Definition: VolumeSplitterUtils.h:144
InDetDD::SegmentList::print
void print() const
Definition: VolumeSplitterUtils.cxx:397
InDetDD::TubeZone::inR
bool inR(double r) const
Definition: VolumeSplitterUtils.cxx:177
InDetDD::TubeZone::inSide
virtual bool inSide(const Point &point) const
Definition: VolumeSplitterUtils.cxx:167
InDetDD::Point::r
double r() const
Definition: VolumeSplitterUtils.h:29
InDetDD::Segment::m_rmax
double m_rmax
Definition: VolumeSplitterUtils.h:152
InDetDD::Ray::m_end
Point m_end
Definition: VolumeSplitterUtils.h:66
InDetDD::TubeZone::TubeZone
TubeZone(const std::string &label, double zmin, double zmax, double rmin, double rmax, bool rotated=false)
Definition: VolumeSplitterUtils.cxx:149
InDetDD::TubeZone::m_zmax
double m_zmax
Definition: VolumeSplitterUtils.h:114
InDetDD::Ray::vertical
bool vertical() const
Definition: VolumeSplitterUtils.h:54
InDetDD::TubeZone::m_zmin
double m_zmin
Definition: VolumeSplitterUtils.h:113
InDetDD::Ray::m_vertical
bool m_vertical
Definition: VolumeSplitterUtils.h:64
InDetDD::Ray::valid
bool valid() const
Definition: VolumeSplitterUtils.h:51
InDetDD::Ray::foundStart
bool foundStart() const
Definition: VolumeSplitterUtils.h:52
InDetDD::SegmentSplitter::searchPoint
Ray searchPoint(const Zone *zone, const Ray &ray)
Definition: VolumeSplitterUtils.cxx:95
InDetDD::Ray::m_horizontal
bool m_horizontal
Definition: VolumeSplitterUtils.h:63
NSWL1::PadTriggerAdapter::segment
Muon::NSW_PadTriggerSegment segment(const NSWL1::PadTrigger &data)
Definition: PadTriggerAdapter.cxx:5
InDetDD::PconZone::findExit
virtual Point findExit(const Ray &ray) const
Definition: VolumeSplitterUtils.cxx:292