ATLAS Offline Software
LArWheelSliceSolidDisToIn.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 LArWheelSliceSolid
6 #include <cassert>
7 #ifndef PORTABLE_LAR_SHAPE
9 #endif
10 #include "CLHEP/Units/PhysicalConstants.h"
11 
13 #include "LArWheelSliceSolid.h"
14 
15 G4double LArWheelSliceSolid::DistanceToIn(const G4ThreeVector &inputP) const
16 {
17  LWSDBG(1, std::cout << TypeStr() << " DisToIn" << MSG_VECTOR(inputP) << std::endl);
18  if(m_BoundingShape->Inside(inputP) == kOutside) {
19  // here is an approximation - for the point outside m_BoundingShape
20  // the solid looks like a m_BoundingShape
21  // it's okay since the result could be underestimated
22  LWSDBG(2, std::cout << "Outside BS" << std::endl);
23  return m_BoundingShape->DistanceToIn(inputP);
24  }
25  G4ThreeVector p(inputP);
26 
27  //
28  // DistanceToTheNearestFan:
29  // rotates point p to the localFan coordinates and returns fan number to out_fan_number parameter
30  // returns distance to fan as result
31  //
32 
33  int p_fan = 0;
34  const G4double d = fabs(GetCalculator()->DistanceToTheNearestFan(p, p_fan));
35  if(d > m_FHTplusT){
36  const G4double result = d - m_FanHalfThickness;
37  LWSDBG(2, std::cout << "dti result = " << result << std::endl);
38  return result;
39  }
40  LWSDBG(2, std::cout << "already inside, return 0" << MSG_VECTOR(p) << std::endl);
41  return 0.;
42 }
43 
44 G4double LArWheelSliceSolid::DistanceToIn(const G4ThreeVector &inputP,
45  const G4ThreeVector &inputV) const
46 {
47  LWSDBG(1, std::cout << TypeStr() << " DisToIn" << MSG_VECTOR(inputP)
48  << MSG_VECTOR(inputV) << std::endl);
49 
50  G4double distance = 0.;
51  const EInside inside_BS = m_BoundingShape->Inside(inputP);
52  G4ThreeVector p(inputP);
53  if(inside_BS == kOutside) {
54  distance = m_BoundingShape->DistanceToIn(inputP, inputV);
55  if(distance == kInfinity) {
56  LWSDBG(2, std::cout << "Infinity distance to m_BoundingShape"
57  << MSG_VECTOR(inputP) << MSG_VECTOR(inputV)
58  << 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_LARWHEELSLICESOLID
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_LARWHEELSLICESOLID
117 
118  return distance;
119 }
120 
121 G4double LArWheelSliceSolid::distance_to_in(G4ThreeVector &p, const G4ThreeVector &v, int p_fan) const
122 {
123  LWSDBG(4, std::cout << "dti: " << MSG_VECTOR(p) << " "
124  << MSG_VECTOR(v) << std::endl);
125 
126  G4double distance = 0.;
127 
128  if(p.x() > m_Xmax) {
129  if(v.x() >= 0.) return kInfinity;
130  const G4double b = (m_Xmax - p.x()) / v.x();
131  const G4double y2 = p.y() + v.y() * b;
132  const G4double z2 = p.z() + v.z() * b;
133  p.set(m_Xmax, y2, z2);
134  distance += b;
135  } else if(p.x() < m_Xmin) {
136  if(v.x() <= 0.) return kInfinity;
137  const G4double b = (m_Xmin - p.x()) / v.x();
138  const G4double y2 = p.y() + v.y() * b;
139  const G4double z2 = p.z() + v.z() * b;
140  p.set(m_Xmin, y2, z2);
141  distance += b;
142  }
143 
144 // here p is on surface of or inside the "FanBound",
145 // distance corrected, misses are accounted for
146  LWSDBG(5, std::cout << "dti corrected: " << MSG_VECTOR(p) << std::endl);
147 
148  G4double dist_p = GetCalculator()->DistanceToTheNeutralFibre(p, p_fan);
149  if(fabs(dist_p) < m_FHTminusT) {
150  LWSDBG(5, std::cout << "hit fan dist_p=" << dist_p << ", m_FHTminusT=" << m_FHTminusT << std::endl);
151  return distance;
152  }
153 
154  G4ThreeVector q;
155  q = p + v * m_BoundingShape->DistanceToOut(p, v);
156  G4double dist_q = GetCalculator()->DistanceToTheNeutralFibre(q, p_fan);
157  LWSDBG(5, std::cout << "dti exit point: " << MSG_VECTOR(q) << " "
158  << dist_q << std::endl);
159  G4double dd = kInfinity;
160  if(dist_p * dist_q < 0.){// it certanly cross current half-wave
161  dd = in_iteration_process(p, dist_p, q, p_fan);
162  }
163  G4double d2 = search_for_nearest_point(p, dist_p, q, p_fan);
164  if(d2 < kInfinity){
165  return distance + d2; // this half-wave is intersected
166  } else if(dd < kInfinity){
167  return distance + dd;
168  }
169  return kInfinity;
170 }
171 
172 // This functions should be called in the case when we are sure that
173 // points p (which sould be OUTSIDE of vertical fan) and out_point have
174 // the surface of the vertical fan between them.
175 // returns distance from point p to absorber surface
176 // sets last parameter to the founded point
178  const G4ThreeVector &p, G4double dist_p, G4ThreeVector &B, int p_fan
179 ) const
180 {
181  LWSDBG(6, std::cout << "iip from " << p << " to " << B
182  << " dir " << (B - p).unit()
183  << std::endl);
184 
185  G4ThreeVector A, C, diff;
186  A = p;
187  G4double dist_c;
188  unsigned int niter = 0;
189  // assert(fabs(GetCalculator()->DistanceToTheNeutralFibre(A)) > m_FHTplusT);
190  // assert(GetCalculator()->DistanceToTheNeutralFibre(A) == dist_p);
191  do {
192  C = A + B;
193  C *= 0.5;
194  dist_c = GetCalculator()->DistanceToTheNeutralFibre(C, p_fan);
195  if(dist_c * dist_p < 0. || fabs(dist_c) < m_FHTminusT){
196  B = C;
197  } else {
198  A = C;
199  }
200  niter ++;
201  diff = A - B;
202  } while(diff.mag2() > s_IterationPrecision2 && niter < s_IterationsLimit);
203  assert(niter < s_IterationsLimit);
204  assert(fabs(GetCalculator()->DistanceToTheNeutralFibre(B, p_fan)) < m_FHTplusT);
205  diff = p - B;
206  LWSDBG(7, std::cout << "iip result in " << niter << " = " << B
207  << " " << diff.mag() << std::endl);
208  return diff.mag();
209 }
210 
211 // search for the nearest to the neutral fibre of the vertical fan point
212 // on the segment between p_in and p_out
214  const G4ThreeVector &p_in, const G4double dist_p_in,
215  const G4ThreeVector &p_out, int p_fan
216 ) const
217 {
218  LWSDBG(6, std::cout << "sfnp " << MSG_VECTOR(p_in) << " "
219  << MSG_VECTOR(p_out) << std::endl);
220 
221  G4ThreeVector A, B, C, l, diff;
222  A = p_in;
223  B = p_out;
224  diff = B - A;
225  l = diff.unit() * s_IterationPrecision;
226  // this is to correctly take the sign of the distance into account
227  G4double sign = dist_p_in < 0.? -1. : 1.;
228  G4double d_prime;
229  G4double dist_c;
230  unsigned long niter = 0;
231  do {
232  C = A + B;
233  C *= 0.5;
234  dist_c = GetCalculator()->DistanceToTheNeutralFibre(C, p_fan);
235  if(dist_c * sign <= 0.){ // we are in coditions for in_iteration_process
236  LWSDBG(7, std::cout << "sfnp0 " << dist_c << std::endl);
237  return in_iteration_process(p_in, dist_p_in, C, p_fan);
238  }
239  // calculate sign of derivative of distance to the neutral fibre
240  // hope this substitution is acceptable
241  diff = C - l;
242  d_prime = (dist_c - GetCalculator()->DistanceToTheNeutralFibre(diff, p_fan)) * sign;
243  if(d_prime < 0.) A = C;
244  else B = C;
245  niter ++;
246  diff = A - B;
247  } while(diff.mag2() > s_IterationPrecision2 && niter < s_IterationsLimit);
248  assert(niter < s_IterationsLimit);
249  if(fabs(dist_c) < m_FHTminusT){
250  LWSDBG(7, std::cout << "sfnp1 " << dist_c << std::endl);
251  return in_iteration_process(p_in, dist_p_in, C, p_fan);
252  }
253  // let's check at p_in and p_out
254  if(dist_p_in * sign < dist_c * sign){
255  C = p_in;
256  dist_c = dist_p_in;
257  }
258  G4double dist_p_out = GetCalculator()->DistanceToTheNeutralFibre(p_out, p_fan);
259  if(dist_p_out *sign < dist_c * sign) C = p_out;
260  if(fabs(dist_p_out) < m_FHTminusT){
261  LWSDBG(7, std::cout << "sfnp2 " << dist_p_out << std::endl);
262  return in_iteration_process(p_in, dist_p_in, C, p_fan);
263  }
264  return kInfinity;
265 }
266 
get_generator_info.result
result
Definition: get_generator_info.py:21
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
LArWheelSliceSolid::GetCalculator
const LArWheelCalculator * GetCalculator(void) const
Definition: LArWheelSliceSolid.h:92
AthMsgStreamMacros.h
LArWheelSliceSolid.h
hist_file_dump.d
d
Definition: hist_file_dump.py:137
LArWheelSliceSolid::TypeStr
G4String TypeStr(void) const
Definition: LArWheelSliceSolid.cxx:67
LArWheelSliceSolid::in_iteration_process
G4double in_iteration_process(const G4ThreeVector &, G4double, G4ThreeVector &, int) const
Definition: LArWheelSliceSolidDisToIn.cxx:177
InDetAccessor::phi0
@ phi0
Definition: InDetAccessor.h:33
DMTest::C
C_v1 C
Definition: C.h:26
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
LArWheelSliceSolid::distance_to_in
virtual G4double distance_to_in(G4ThreeVector &, const G4ThreeVector &, int) const
Definition: LArWheelSliceSolidDisToIn.cxx:121
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
LArWheelSliceSolid::m_Xmin
G4double m_Xmin
Definition: LArWheelSliceSolid.h:109
LArWheelSliceSolid::search_for_nearest_point
G4double search_for_nearest_point(const G4ThreeVector &, const G4double, const G4ThreeVector &, int) const
Definition: LArWheelSliceSolidDisToIn.cxx:213
dqt_zlumi_alleff_HIST.A
A
Definition: dqt_zlumi_alleff_HIST.py:110
LArWheelSliceSolid::s_IterationsLimit
static const unsigned int s_IterationsLimit
Definition: LArWheelSliceSolid.h:99
LWSDBG
#define LWSDBG(a, b)
Definition: LArWheelSliceSolid.h:28
LArWheelSliceSolid::m_Xmax
G4double m_Xmax
Definition: LArWheelSliceSolid.h:109
lumiFormat.i
int i
Definition: lumiFormat.py:92
makeTRTBarrelCans.y2
tuple y2
Definition: makeTRTBarrelCans.py:18
LArWheelSliceSolid::DistanceToIn
G4double DistanceToIn(const G4ThreeVector &, const G4ThreeVector &) const
Definition: LArWheelSliceSolidDisToIn.cxx:44
TRT::Track::d0
@ d0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:62
sign
int sign(int a)
Definition: TRT_StrawNeighbourSvc.h:127
LArWheelSliceSolid::s_IterationPrecision2
static const G4double s_IterationPrecision2
Definition: LArWheelSliceSolid.h:98
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
dqt_zlumi_alleff_HIST.B
B
Definition: dqt_zlumi_alleff_HIST.py:110
LArWheelSliceSolid::m_BoundingShape
G4VSolid * m_BoundingShape
Definition: LArWheelSliceSolid.h:104
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
LArWheelSliceSolid::s_IterationPrecision
static const G4double s_IterationPrecision
Definition: LArWheelSliceSolid.h:97
LArWheelSliceSolid::m_FHTplusT
G4double m_FHTplusT
Definition: LArWheelSliceSolid.h:106
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
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
LArWheelSliceSolid::m_FanHalfThickness
G4double m_FanHalfThickness
Definition: LArWheelSliceSolid.h:106
LArWheelSliceSolid::m_FHTminusT
G4double m_FHTminusT
Definition: LArWheelSliceSolid.h:106
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
LArWheelSliceSolid::Inside
EInside Inside(const G4ThreeVector &) const
Definition: LArWheelSliceSolid.cxx:15
LArWheelCalculator.h