ATLAS Offline Software
VolumeSplitter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3  */
4 
8 #include "GaudiKernel/SystemOfUnits.h"
9 
10 #include <sstream>
11 #include <algorithm>
12 
13 namespace InDetDD {
15  : m_ownVolumes(true),
16  m_epsilon(0.0001 * Gaudi::Units::mm)
17  {}
18 
20  if (m_ownVolumes) {
21  for (std::vector<const ServiceVolume*>::iterator iter = m_volumes.begin(); iter != m_volumes.end(); ++iter) {
22  delete *iter;
23  }
24  }
25  }
26 
27  const std::vector<const ServiceVolume*>&
28  VolumeSplitter::splitAll(const Zone& zone, const std::vector<const ServiceVolume*>& origVolumeList) {
29  for (unsigned int i = 0; i < origVolumeList.size(); ++i) {
30  split(zone, *(origVolumeList[i]));
31  }
32  return m_volumes;
33  }
34 
35  void
36  VolumeSplitter::split(const Zone& zone, const ServiceVolume& origVolume) {
37  makeVolumes(&zone, origVolume);
38  }
39 
40  Ray
42  double zmin = origVolume.zmin();
43  double zmax = origVolume.zmax();
44  double rmin = origVolume.rmin();
45  double rmax = origVolume.rmax();
46 
47  if (zmax < zmin) std::swap(zmin, zmax);
48  if (rmax < rmin) std::swap(rmin, rmax);
49 
50  bool horizontal = (std::abs(zmax - zmin) > std::abs(rmax - rmin));
51  if (horizontal) {
52  double rmid = 0.5 * (rmin + rmax);
53  return Ray(Point(zmin, rmid), Point(zmax, rmid));
54  } else {
55  double zmid = 0.5 * (zmin + zmax);
56  return Ray(Point(zmid, rmin), Point(zmid, rmax));
57  }
58  }
59 
60  void
61  VolumeSplitter::makeVolumes(const Zone* zone, const ServiceVolume& origVolume) {
62  // See if its a symmetric volume
63  if (origVolume.zsymm()) {
64  ServiceVolume param1(origVolume);
65  ServiceVolume param2(origVolume);
66  param1.addLabel("A");
67  param1.setNeedsRotation(false);
68  param2.addLabel("C");
69  param2.setZmin(-origVolume.zmax());
70  param2.setZmax(-origVolume.zmin());
71  param2.setNeedsRotation(origVolume.needsRotation());
72  splitVolume(zone, param1);
73  splitVolume(zone, param2);
74  } else {
75  ServiceVolume param1(origVolume);
76  param1.setNeedsRotation(false);
77  splitVolume(zone, param1);
78  }
79  }
80 
81  void
83  Ray ray = makeRay(param);
84  SegmentSplitter splitter;
85  const SegmentList& segments = splitter.split(zone, ray);
86 
87  //std::cout << "Segments: " << std::endl;
88  //segments.print();
89 
90  double volumeTotal = 0;
91 
92  std::vector<ServiceVolume* > tmpServiceVec;
93  tmpServiceVec.reserve(segments.size());
94  for (unsigned int i = 0; i < segments.size(); ++i) {
95  const Segment& seg = segments.getSegment(i);
96  ServiceVolume* paramNew = new ServiceVolume(param);
97 
98  if (segments.horizontal()) {
99  if (param.splittableInZ()) {
100  paramNew->setZmin(seg.zmin());
101  paramNew->setZmax(seg.zmax());
102  // If z changed adjust r in cone like volumes
103  adjustR(param, paramNew);
104  } else if (i == 1) {
105  std::cout << "Volume " << param.fullLabel() << " cannot be split in Z" << std::endl;
106  }
107  } else {
108  // vertical
109  if (param.splittableInR()) {
110  paramNew->setRmin(seg.rmin());
111  paramNew->setRmax(seg.rmax());
112  } else if (i == 1) {
113  std::cout << "Volume " << param.fullLabel() << " cannot be split in R" << std::endl;
114  }
115  }
116 
117  if (seg.rotated()) {
118  // Often the -ve endcap region is created as the +ve endcap and then rotated. Therefore we have to reflect the z
119  // coords.
120  // Also have to turn off the needsRotation flag in case it was set.
121  //std::cout << "Segment " << i << " rotated " << paramNew->zmin() << " " << paramNew->zmax() <<std::endl;
122  double zminTmp = paramNew->zmin();
123  paramNew->setZmin(-paramNew->zmax());
124  paramNew->setZmax(-zminTmp);
125  paramNew->setNeedsRotation(false);
126  //std::cout << "After adjusted " << paramNew->zmin() << " " << paramNew->zmax() <<std::endl;
127  }
128 
129  if (param.splittableInZ()) {
130  paramNew->reduceSize(m_epsilon); // safety gap between volumes
131  }
132 
133  paramNew->setRegion(seg.label());
134  tmpServiceVec.push_back(paramNew);
135 
136  paramNew->getShape();
137  volumeTotal += paramNew->volume();
138  //std::cout << i << ": volume: " << paramNew->volume() << std::endl;
139  }
140  //std::cout << "Total volume: " << volumeTotal << std::endl;
141  for (unsigned int i = 0; i < segments.size(); ++i) {
142  ServiceVolume* paramNew = tmpServiceVec[i];
143  if (segments.size() > 1) {
144  std::ostringstream ostr;
145  ostr << "_" << i + 1;
146  paramNew->addLabel(ostr.str());
147  }
148  paramNew->setOrigVolume(volumeTotal);
149  m_volumes.push_back(paramNew);
150  }
151  }
152 
153 // This takes care of cone like volumes and adjust the radius according to the adjusted z.
154  void
156  double z1 = param.zmin();
157  double z2 = param.zmax();
158  double z1New = paramNew->zmin();
159  double z2New = paramNew->zmax();
160  double rmin1 = param.rmin();
161  double rmin2 = param.rmin2();
162  double rmax1 = param.rmax();
163  double rmax2 = param.rmax2();
164 
165  // Make sure z1 < z2
166  // as r1, r2 order assumes this
167  if (z1 > z2) std::swap(z1, z2);
168  if (z1New > z2New) std::swap(z1New, z2New);
169 
170  // Avoid divide by zero.
171  if (z1 == z2) return;
172 
173  if (z1 != z1New || z2 != z2New) {
174  if (rmin2 > 0 && rmax2 > 0 && (rmin1 != rmin2 || rmax1 != rmax2)) {
175  double slopeMin = (rmin2 - rmin1) / (z2 - z1);
176  double slopeMax = (rmax2 - rmax1) / (z2 - z1);
177 
178  double rmin1New = (z1New - z1) * slopeMin + rmin1;
179  double rmin2New = (z2New - z1) * slopeMin + rmin1;
180 
181  double rmax1New = (z1New - z1) * slopeMax + rmax1;
182  double rmax2New = (z2New - z1) * slopeMax + rmax1;
183 
184  paramNew->setRmin(rmin1New);
185  paramNew->setRmax(rmax1New);
186  paramNew->setRmin2(rmin2New);
187  paramNew->setRmax2(rmax2New);
188  }
189  }
190  }
191 } // end namespace
InDetDD::ServiceVolume::zmax
double zmax() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:67
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
InDetDD::ServiceVolume::needsRotation
bool needsRotation() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:76
InDetDD::ServiceVolume::setRmin2
void setRmin2(double rmin2)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:31
InDetDD::ServiceVolume::reduceSize
void reduceSize(double safety)
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:161
InDetDD::VolumeSplitter::splitAll
const std::vector< const ServiceVolume * > & splitAll(const Zone &zone, const std::vector< const ServiceVolume * > &)
Definition: VolumeSplitter.cxx:28
InDetDD::SegmentSplitter::split
const SegmentList & split(const Zone *, const Ray &)
Definition: VolumeSplitterUtils.cxx:13
InDetDD::ServiceVolume::splittableInZ
bool splittableInZ() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:90
InDetDD::ServiceVolume::setZmax
void setZmax(double zmax)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:34
InDetDD::ServiceVolume::splittableInR
bool splittableInR() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:89
InDetDD::Segment::rmin
double rmin() const
Definition: VolumeSplitterUtils.h:143
PixelAthClusterMonAlgCfg.zmin
zmin
Definition: PixelAthClusterMonAlgCfg.py:176
InDetDD::ServiceVolume::rmax
double rmax() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:63
InDetDD::Zone
Definition: VolumeSplitterUtils.h:71
InDetDD::ServiceVolume::setOrigVolume
void setOrigVolume(double volume)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:51
InDetDD::VolumeSplitter::adjustR
void adjustR(const ServiceVolume &param, ServiceVolume *paramNew)
Definition: VolumeSplitter.cxx:155
InDetDD::Segment::zmax
double zmax() const
Definition: VolumeSplitterUtils.h:142
InDetDD::VolumeSplitter::splitVolume
void splitVolume(const Zone *zone, const ServiceVolume &vol)
Definition: VolumeSplitter.cxx:82
InDetDD::ServiceVolume::getShape
const GeoShape * getShape() const
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:198
InDetDD::ServiceVolume::setRegion
void setRegion(const std::string &region)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:46
InDetDD::ServiceVolume::rmax2
double rmax2() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:65
InDetDD::SegmentList
Definition: VolumeSplitterUtils.h:156
InDetDD::VolumeSplitter::m_ownVolumes
bool m_ownVolumes
Definition: VolumeSplitter.h:32
InDetDD::ServiceVolume::zsymm
bool zsymm() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:69
InDetDD::Ray
Definition: VolumeSplitterUtils.h:44
InDetDD::Segment::label
const std::string & label() const
Definition: VolumeSplitterUtils.h:139
InDetDD::ServiceVolume::volume
double volume() const
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:328
lumiFormat.i
int i
Definition: lumiFormat.py:92
InDetDD::SegmentList::size
unsigned int size() const
Definition: VolumeSplitterUtils.h:160
InDetDD::ServiceVolume::setRmin
void setRmin(double rmin)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:29
InDetDD::VolumeSplitter::~VolumeSplitter
~VolumeSplitter()
Definition: VolumeSplitter.cxx:19
InDetDD::Segment::rotated
bool rotated() const
Definition: VolumeSplitterUtils.h:140
PixelAthClusterMonAlgCfg.zmax
zmax
Definition: PixelAthClusterMonAlgCfg.py:176
InDetDD::SegmentSplitter
Definition: VolumeSplitterUtils.h:175
InDetDD::Point
Definition: VolumeSplitterUtils.h:20
InDetDD::SegmentList::horizontal
bool horizontal() const
Definition: VolumeSplitterUtils.cxx:387
InDetDD::VolumeSplitter::makeRay
Ray makeRay(const ServiceVolume &origVolume)
Definition: VolumeSplitter.cxx:41
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
InDetDD::ServiceVolume::fullLabel
std::string fullLabel() const
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:180
InDetDD::ServiceVolume::setRmax2
void setRmax2(double rmax2)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:32
InDetDD::ServiceVolume::setZmin
void setZmin(double zmin)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:33
InDetDD::VolumeSplitter::m_epsilon
double m_epsilon
Definition: VolumeSplitter.h:33
Athena::Units
Definition: Units.h:45
InDetDD::ServiceVolume::setNeedsRotation
void setNeedsRotation(bool flag)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:43
InDetDD::ServiceVolume::rmin2
double rmin2() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:64
python.draw_obj.zone
def zone(nx, ny)
Definition: draw_obj.py:288
InDetDD::VolumeSplitter::m_volumes
std::vector< const ServiceVolume * > m_volumes
Definition: VolumeSplitter.h:34
InDetDD::VolumeSplitter::VolumeSplitter
VolumeSplitter()
Definition: VolumeSplitter.cxx:14
InDetDD::Segment
Definition: VolumeSplitterUtils.h:136
InDetDD::Segment::zmin
double zmin() const
Definition: VolumeSplitterUtils.h:141
InDetDD::ServiceVolume::setRmax
void setRmax(double rmax)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:30
InDetDD::ServiceVolume::rmin
double rmin() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:62
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
VolumeSplitterUtils.h
InDetDD::VolumeSplitter::split
void split(const Zone &zone, const ServiceVolume &origVolume)
Definition: VolumeSplitter.cxx:36
InDetDD::ServiceVolume::addLabel
void addLabel(const std::string &name)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:49
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
InDetDD::Segment::rmax
double rmax() const
Definition: VolumeSplitterUtils.h:144
InDetDD::VolumeSplitter::makeVolumes
void makeVolumes(const Zone *zone, const ServiceVolume &origVolume)
Definition: VolumeSplitter.cxx:61
Gaudi
=============================================================================
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:273
ServiceVolume.h
InDetDD::ServiceVolume
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:24
InDetDD::SegmentList::getSegment
const Segment & getSegment(unsigned int i) const
Definition: VolumeSplitterUtils.h:161
VolumeSplitter.h
InDetDD::ServiceVolume::zmin
double zmin() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:66