ATLAS Offline Software
LArWheelSolidDisToIn.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 // DistanceToIn stuff for LArWheelSolid
6 #include <cassert>
7 #ifndef PORTABLE_LAR_SHAPE
9 #else
10 #endif
11 #include "CLHEP/Units/PhysicalConstants.h"
12 
14 #include "LArWheelSolid.h"
15 #include "LArFanSection.h"
16 
17 G4double LArWheelSolid::DistanceToIn(const G4ThreeVector &inputP) const
18 {
19  LWSDBG(1, std::cout << TypeStr() << " DisToIn" << MSG_VECTOR(inputP) << std::endl);
20  if(m_BoundingShape->Inside(inputP) == kOutside) {
21  // here is an approximation - for the point outside m_BoundingShape
22  // the solid looks like a m_BoundingShape
23  // it's okay since the result could be underestimated
24  LWSDBG(2, std::cout << "Outside BS" << std::endl);
25  return m_BoundingShape->DistanceToIn(inputP);
26  }
27  G4ThreeVector p(inputP);
28 
29  //
30  // DistanceToTheNearestFan:
31  // rotates point p to the localFan coordinates and returns fan number to out_fan_number parameter
32  // returns distance to fan as result
33  //
34 
35  int p_fan = 0;
36  const G4double d = fabs(GetCalculator()->DistanceToTheNearestFan(p, p_fan));
37  if(d > m_FHTplusT){
38  const G4double result = d - m_FanHalfThickness;
39  LWSDBG(2, std::cout << "dti result = " << result << std::endl);
40  return result;
41  }
42  LWSDBG(2, std::cout << "already inside, return 0" << MSG_VECTOR(p) << std::endl);
43  return 0.;
44 }
45 
46 G4double LArWheelSolid::DistanceToIn(const G4ThreeVector &inputP,
47  const G4ThreeVector &inputV) const
48 {
49  LWSDBG(1, std::cout << TypeStr() << " DisToIn" << MSG_VECTOR(inputP)
50  << MSG_VECTOR(inputV) << std::endl);
51 
52  G4double distance = 0.;
53  const EInside inside_BS = m_BoundingShape->Inside(inputP);
54  G4ThreeVector p(inputP);
55  if(inside_BS == kOutside) {
56  distance = m_BoundingShape->DistanceToIn(inputP, inputV);
57  if(distance == kInfinity) {
58  LWSDBG(2, std::cout << "Infinity distance to m_BoundingShape" << MSG_VECTOR(inputP) << MSG_VECTOR(inputV) << std::endl);
59  return kInfinity;
60  }
61  p += inputV * distance;
62  assert(m_BoundingShape->Inside(p) != kOutside);
63  LWSDBG(2, std::cout << "shift" << MSG_VECTOR(inputP) << std::endl);
64  }
65 
66  const G4double phi0 = p.phi();
67  int p_fan = 0;
68  const G4double d = GetCalculator()->DistanceToTheNearestFan(p, p_fan);
69  if(fabs(d) < m_FHTminusT){
70  LWSDBG(2, std::cout << "already inside fan" << MSG_VECTOR(p) << std::endl);
71  // if initial point is on BS surface and inside fan volume it is a real surface
72  if(inside_BS == kSurface) {
73  LWSDBG(2, std::cout << "On BS surface" << std::endl);
74  return m_BoundingShape->DistanceToIn(inputP, inputV);
75  }
76  return distance;
77  }
78  G4ThreeVector v(inputV);
79  v.rotateZ(p.phi() - phi0);
80 
81  const G4double d0 = distance_to_in(p, v, p_fan);
82  distance += d0;
83 
84 #ifdef DEBUG_LARWHEELSOLID
85  if(Verbose > 2){
86  if(Verbose > 3){
87  std::cout << MSG_VECTOR(inputP)
88  << " " << MSG_VECTOR(inputV) << std::endl;
89  }
90  std::cout << "dti: " << d0 << ", DTI: " << distance << std::endl;
91  }
92  if(Verbose > 3){
93  if(d0 < kInfinity){
94  G4ThreeVector p2 = inputP + inputV*distance;
95  EInside i = Inside(p2);
96  std::cout << "DTI hit at dist. " << distance << ", point "
97  << MSG_VECTOR(p2) << ", "
98  << inside(i) << std::endl;
99  } else {
100  std::cout << "got infinity from dti" << std::endl;
101  }
102  }
103 #ifdef LWS_HARD_TEST_DTI
104  if(test_dti(inputP, inputV, distance)){
105  if(Verbose == 1){
106  std::cout << TypeStr() << " DisToIn" << MSG_VECTOR(inputP)
107  << MSG_VECTOR(inputV) << std::endl;
108  }
109  }
110  if(Verbose == 1){
111  std::cout << TypeStr() << " DisToIn" << MSG_VECTOR(inputP)
112  << MSG_VECTOR(inputV) << " " << distance << std::endl;
113  }
114 #endif // ifdef LWS_HARD_TEST_DTI
115 
116 #endif // ifdef DEBUG_LARWHEELSOLID
117 
118  return distance;
119 }
120 
121 // This functions should be called in the case when we are sure that
122 // points p (which sould be OUTSIDE of vertical fan) and out_point have
123 // the surface of the vertical fan between them.
124 // returns distance from point p to absorber surface
125 // sets last parameter to the founded point
127  const G4ThreeVector &p, G4double dist_p, G4ThreeVector &B, int p_fan
128 ) const
129 {
130  LWSDBG(6, std::cout << "iip from " << p << " to " << B
131  << " dir " << (B - p).unit()
132  << std::endl);
133 
134  G4ThreeVector A, C, diff;
135  A = p;
136  G4double dist_c;
137  unsigned int niter = 0;
138  // assert(fabs(GetCalculator()->DistanceToTheNeutralFibre(A)) > m_FHTplusT);
139  // assert(GetCalculator()->DistanceToTheNeutralFibre(A) == dist_p);
140  do {
141  C = A + B;
142  C *= 0.5;
143  dist_c = GetCalculator()->DistanceToTheNeutralFibre(C, p_fan);
144  if(dist_c * dist_p < 0. || fabs(dist_c) < m_FHTminusT){
145  B = C;
146  } else {
147  A = C;
148  }
149  niter ++;
150  diff = A - B;
151  } while(diff.mag2() > s_IterationPrecision2 && niter < s_IterationsLimit);
152  assert(niter < s_IterationsLimit);
153  assert(fabs(GetCalculator()->DistanceToTheNeutralFibre(B, p_fan)) < m_FHTplusT);
154  diff = p - B;
155  LWSDBG(7, std::cout << "iip result in " << niter << " = " << B
156  << " " << diff.mag() << std::endl);
157  return diff.mag();
158 }
159 
160 // search for the nearest to the neutral fibre of the vertical fan point
161 // on the segment between p_in and p_out
163  const G4ThreeVector &p_in, const G4double dist_p_in,
164  const G4ThreeVector &p_out, int p_fan
165 ) const
166 {
167  LWSDBG(6, std::cout << "sfnp " << MSG_VECTOR(p_in) << " "
168  << MSG_VECTOR(p_out) << std::endl);
169 
170  G4ThreeVector A, B, C, l, diff;
171  A = p_in;
172  B = p_out;
173  diff = B - A;
174  l = diff.unit() * s_IterationPrecision;
175  // this is to correctly take the sign of the distance into account
176  G4double sign = dist_p_in < 0.? -1. : 1.;
177  G4double d_prime;
178  G4double dist_c;
179  unsigned long niter = 0;
180  do {
181  C = A + B;
182  C *= 0.5;
183  dist_c = GetCalculator()->DistanceToTheNeutralFibre(C, p_fan);
184  if(dist_c * sign <= 0.){ // we are in coditions for in_iteration_process
185  LWSDBG(7, std::cout << "sfnp0 " << dist_c << std::endl);
186  return in_iteration_process(p_in, dist_p_in, C, p_fan);
187  }
188  // calculate sign of derivative of distance to the neutral fibre
189  // hope this substitution is acceptable
190  diff = C - l;
191  d_prime = (dist_c - GetCalculator()->DistanceToTheNeutralFibre(diff, p_fan)) * sign;
192  if(d_prime < 0.) A = C;
193  else B = C;
194  niter ++;
195  diff = A - B;
196  } while(diff.mag2() > s_IterationPrecision2 && niter < s_IterationsLimit);
197  assert(niter < s_IterationsLimit);
198  if(fabs(dist_c) < m_FHTminusT){
199  LWSDBG(7, std::cout << "sfnp1 " << dist_c << std::endl);
200  return in_iteration_process(p_in, dist_p_in, C, p_fan);
201  }
202  // let's check at p_in and p_out
203  if(dist_p_in * sign < dist_c * sign){
204  C = p_in;
205  dist_c = dist_p_in;
206  }
207  G4double dist_p_out = GetCalculator()->DistanceToTheNeutralFibre(p_out, p_fan);
208  if(dist_p_out *sign < dist_c * sign) C = p_out;
209  if(fabs(dist_p_out) < m_FHTminusT){
210  LWSDBG(7, std::cout << "sfnp2 " << dist_p_out << std::endl);
211  return in_iteration_process(p_in, dist_p_in, C, p_fan);
212  }
213  return kInfinity;
214 }
215 
216 G4double LArWheelSolid::distance_to_in(G4ThreeVector &p, const G4ThreeVector &v, int p_fan) const
217 {
218  LWSDBG(4, std::cout << "dti: " << MSG_VECTOR(p) << " "
219  << MSG_VECTOR(v) << std::endl);
220 
221  G4double distance = 0.;
222 #ifdef LARWHEELSOLID_USE_FANBOUND
223  if(FanBound->Inside(p) == kOutside) {
224  const G4double d = FanBound->DistanceToIn(p, v);
225  p += v * d;
226  distance += d;
227  }
228 #else
229  if(p.x() > m_fs->xmax) {
230  if(v.x() >= 0.) return kInfinity;
231  const G4double b = (m_fs->xmax - p.x()) / v.x();
232  const G4double y2 = p.y() + v.y() * b;
233  const G4double z2 = p.z() + v.z() * b;
234  p.set(m_fs->xmax, y2, z2);
235  distance += b;
236  } else if(p.x() < m_fs->xmin) {
237  if(v.x() <= 0.) return kInfinity;
238  const G4double b = (m_fs->xmin - p.x()) / v.x();
239  const G4double y2 = p.y() + v.y() * b;
240  const G4double z2 = p.z() + v.z() * b;
241  p.set(m_fs->xmin, y2, z2);
242  distance += b;
243  }
244 #endif
245 
246 // here p is on surface of or inside the "FanBound",
247 // distance corrected, misses are accounted for
248  LWSDBG(5, std::cout << "dti corrected: " << MSG_VECTOR(p) << std::endl);
249 
250  G4double dist_p = GetCalculator()->DistanceToTheNeutralFibre(p, p_fan);
251  if(fabs(dist_p) < m_FHTminusT) {
252  LWSDBG(5, std::cout << "hit fan dist_p=" << dist_p << ", m_FHTminusT=" << m_FHTminusT << std::endl);
253  return distance;
254  }
255 
256 #ifdef CHECK_DIRTONORM_ANGLE_ON_SURFACE
257  if(fabs(dist_p) > m_FHTplusT) {
258  LWSDBG(5, std::cout << "outside fan dist_p=" << dist_p << ", m_FHTplusT=" << m_FHTplusT << std::endl);
259  } else {
260  LWSDBG(5, std::cout << "on fan surface dist_p=" << dist_p << ", m_FHTplusT=" << m_FHTplusT << ", m_FHTminusT=" << m_FHTminusT << std::endl);
261 
262  const G4ThreeVector d = GetCalculator()->NearestPointOnNeutralFibre(p, p_fan);
263  // check dot product between normal and v
264  if ( (p-d).cosTheta(v) < -AngularTolerance ) {
265  // direction "v" definitely pointing inside
266  // return 0.0, it should be in "distance"
267  return distance;
268  }
269  }
270 #endif
271 
272  G4ThreeVector q;
273 #ifdef LARWHEELSOLID_USE_FANBOUND
274  q = p + v * FanBound->DistanceToOut(p, v);
275 #else
276  find_exit_point(p, v, q);
277 #endif
278 
279  G4int start = select_section(p.z());
280  G4int stop = select_section(q.z());
281  G4int step = -1;
282  if(stop > start) { step = 1; start ++; stop ++; }
283  LWSDBG(5, std::cout << "dti sections " << start << " " << stop
284  << " " << step << std::endl);
285  G4ThreeVector p1;
286  for(G4int i = start; i != stop; i += step){
287 // v.z() can't be 0, otherwise start == stop, so the exit point could be only
288 // at z border of the fan section
289  const G4double d1 = (m_Zsect[i] - p.z()) / v.z();
290  const G4double x1 = p.x() + v.x() * d1, y1 = p.y() + v.y() * d1;
291  p1.set(x1, y1, m_Zsect[i]);
292  G4double dist_p1 = GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan);
293  LWSDBG(5, std::cout << i << ">" << p << " " << dist_p << " "
294  << p1 << " " << dist_p1 << std::endl);
295  G4double dd = kInfinity;
296  if(dist_p * dist_p1 < 0.){// it certanly cross current half-wave
297  dd = in_iteration_process(p, dist_p, p1, p_fan);
298  }
299  G4double d2 = search_for_nearest_point(p, dist_p, p1, p_fan);
300  LWSDBG(6, std::cout << i << "> dd=" << dd << ", d2=" << d2 << ", distance=" << distance << std::endl);
301  if(d2 < kInfinity){
302  return distance + d2; // this half-wave is intersected
303  } else if(dd < kInfinity){
304  return distance + dd;
305  }
306  distance += d1;
307  p.set(x1, y1, m_Zsect[i]);
308  dist_p = dist_p1;
309  }
310 
311  G4double dist_q = GetCalculator()->DistanceToTheNeutralFibre(q, p_fan);
312  LWSDBG(5, std::cout << "dti exit point: " << MSG_VECTOR(q) << " "
313  << dist_q << std::endl);
314  G4double dd = kInfinity;
315  if(dist_p * dist_q < 0.){// it certanly cross current half-wave
316  dd = in_iteration_process(p, dist_p, q, p_fan);
317  }
318  G4double d2 = search_for_nearest_point(p, dist_p, q, p_fan);
319  if(d2 < kInfinity){
320  return distance + d2; // this half-wave is intersected
321  } else if(dd < kInfinity){
322  return distance + dd;
323  }
324  return kInfinity;
325 }
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
LArWheelSolid::m_FHTminusT
G4double m_FHTminusT
Definition: LArWheelSolid.h:149
get_generator_info.result
result
Definition: get_generator_info.py:21
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
LArWheelSolid::search_for_nearest_point
G4double search_for_nearest_point(const G4ThreeVector &, const G4double, const G4ThreeVector &, int) const
Definition: LArWheelSolidDisToIn.cxx:162
AthMsgStreamMacros.h
hist_file_dump.d
d
Definition: hist_file_dump.py:137
InDetAccessor::phi0
@ phi0
Definition: InDetAccessor.h:33
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
DMTest::C
C_v1 C
Definition: C.h:26
LArWheelSolid::find_exit_point
FanBoundExit_t find_exit_point(const G4ThreeVector &p, const G4ThreeVector &v, G4ThreeVector &q) const
Definition: LArFanSection.cxx:216
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
dq_defect_virtual_defect_validation.d1
d1
Definition: dq_defect_virtual_defect_validation.py:79
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
PixelModuleFeMask_create_db.stop
int stop
Definition: PixelModuleFeMask_create_db.py:76
LArWheelSolid::m_FHTplusT
G4double m_FHTplusT
Definition: LArWheelSolid.h:149
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
LArFanSection.h
dqt_zlumi_alleff_HIST.A
A
Definition: dqt_zlumi_alleff_HIST.py:110
LArWheelSolid.h
LArWheelSolid::GetCalculator
const LArWheelCalculator * GetCalculator(void) const
Definition: LArWheelSolid.h:130
LWSDBG
#define LWSDBG(a, b)
Definition: LArWheelSliceSolid.h:28
lumiFormat.i
int i
Definition: lumiFormat.py:92
makeTRTBarrelCans.y2
tuple y2
Definition: makeTRTBarrelCans.py:18
TRT::Track::d0
@ d0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:62
sign
int sign(int a)
Definition: TRT_StrawNeighbourSvc.h:127
LArWheelSolid::m_Zsect
std::vector< G4double > m_Zsect
Definition: LArWheelSolid.h:159
LArWheelSolid::Inside
EInside Inside(const G4ThreeVector &) const
Definition: LArWheelSolid.cxx:15
LArWheelSolid::m_fs
LArFanSections * m_fs
Definition: LArWheelSolid.h:162
LArWheelSolid::select_section
G4int select_section(const G4double &Z) const
Definition: LArWheelSolid.cxx:164
LArFanSections::xmax
G4double xmax
Definition: LArFanSection.h:18
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
LArWheelSolid::m_FanHalfThickness
G4double m_FanHalfThickness
Definition: LArWheelSolid.h:149
dqt_zlumi_alleff_HIST.B
B
Definition: dqt_zlumi_alleff_HIST.py:110
LArWheelSolid::s_IterationPrecision2
static const G4double s_IterationPrecision2
Definition: LArWheelSolid.h:143
library_scraper.dd
list dd
Definition: library_scraper.py:46
LArWheelCalculator::DistanceToTheNearestFan
double DistanceToTheNearestFan(CLHEP::Hep3Vector &p, int &out_fan_number) const
Determines the nearest to the input point fan.
Definition: LArWheelCalculatorGeometry.cxx:90
python.PyAthena.v
v
Definition: PyAthena.py:157
Trk::inside
@ inside
Definition: PropDirection.h:29
LArWheelSolid::DistanceToIn
G4double DistanceToIn(const G4ThreeVector &, const G4ThreeVector &) const
Definition: LArWheelSolidDisToIn.cxx:46
LArWheelCalculator::NearestPointOnNeutralFibre
CLHEP::Hep3Vector NearestPointOnNeutralFibre(const CLHEP::Hep3Vector &p, int fan_number) const
Definition: LArWheelCalculatorGeometry.cxx:113
LArWheelSolid::in_iteration_process
G4double in_iteration_process(const G4ThreeVector &, G4double, G4ThreeVector &, int) const
Definition: LArWheelSolidDisToIn.cxx:126
unit
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
Definition: AmgMatrixBasePlugin.h:20
dq_defect_virtual_defect_validation.d2
d2
Definition: dq_defect_virtual_defect_validation.py:81
LArCellBinning.step
step
Definition: LArCellBinning.py:158
extractSporadic.q
list q
Definition: extractSporadic.py:98
LArWheelCalculator::DistanceToTheNeutralFibre
double DistanceToTheNeutralFibre(const CLHEP::Hep3Vector &p, int fan_number) const
Calculates aproximate, probably underestimate, distance to the neutral fibre of the vertical fan.
Definition: LArWheelCalculatorGeometry.cxx:108
LArWheelSolid::s_IterationPrecision
static const G4double s_IterationPrecision
Definition: LArWheelSolid.h:142
LArWheelSolid::m_BoundingShape
G4VSolid * m_BoundingShape
Definition: LArWheelSolid.h:154
LArWheelSolid::s_IterationsLimit
static const unsigned int s_IterationsLimit
Definition: LArWheelSolid.h:144
LArWheelSolid::distance_to_in
virtual G4double distance_to_in(G4ThreeVector &, const G4ThreeVector &, int) const
Definition: LArWheelSolidDisToIn.cxx:216
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
LArFanSections::xmin
G4double xmin
Definition: LArFanSection.h:18
LArWheelCalculator.h