ATLAS Offline Software
LArWheelSolidDisToOut.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <cassert>
6 
8 #include "LArWheelSolid.h"
9 #include "LArFanSection.h"
10 
11 G4double LArWheelSolid::DistanceToOut(const G4ThreeVector &inputP) const
12 {
13  LWSDBG(1, std::cout << TypeStr() << " DisToOut" << MSG_VECTOR(inputP) << std::endl);
14  if(m_BoundingShape->Inside(inputP) != kInside){
15  LWSDBG(2, std::cout << "DistanceToOut(p):"
16  << " point " << MSG_VECTOR(inputP)
17  << " is not inside of the m_BoundingShape."
18  << std::endl);
19  return 0.;
20  }
21  G4ThreeVector p( inputP );
22  int p_fan = 0;
23  const G4double d = m_FanHalfThickness - fabs(GetCalculator()->DistanceToTheNearestFan(p, p_fan));
24  if(d < s_Tolerance){
25  LWSDBG(2, std::cout << "already not inside " << MSG_VECTOR(p) << std::endl);
26  return 0.;
27  }
28  const G4double d0 = m_BoundingShape->DistanceToOut(inputP);
29  LWSDBG(2, std::cout << "dto " << d << " " << d0 << std::endl);
30  if(d > d0) return d0;
31  else return d;
32 }
33 
34 G4double LArWheelSolid::DistanceToOut(const G4ThreeVector &inputP,
35  const G4ThreeVector &inputV,
36  const G4bool calcNorm,
37  G4bool* validNorm,
38  G4ThreeVector* sn) const
39 {
40  LWSDBG(1, std::cout << TypeStr() << " DisToOut" << MSG_VECTOR(inputP)
41  << MSG_VECTOR(inputV) << std::endl);
42 
43  const EInside inside_BS = m_BoundingShape->Inside(inputP);
44  if(inside_BS == kOutside){
45  LWSDBG(2, std::cout << "DistanceToOut(p):"
46  << " point " << MSG_VECTOR(inputP)
47  << " is outside of m_BoundingShape." << std::endl);
48  if(calcNorm) *validNorm = false;
49  return 0.;
50  }
51 
52  // If here inside or on surface of BS
53  G4ThreeVector p(inputP);
54  int p_fan = 0;
55  const G4double adtnf_p = fabs(GetCalculator()->DistanceToTheNearestFan(p, p_fan));
56  if(adtnf_p >= m_FHTplusT) {
57  LWSDBG(2, std::cout << "DistanceToOut(p, v): point "
58  << MSG_VECTOR(inputP)
59  << " is outside of solid." << std::endl);
60  if(calcNorm) *validNorm = false;
61  return 0.;
62  }
63 
64  G4ThreeVector v(inputV);
65  const G4double phi0 = p.phi() - inputP.phi();
66  v.rotateZ(phi0);
67 
68 #ifdef CHECK_DIRTONORM_ANGLE_ON_SURFACE
69  if(adtnf_p < FHTminusT) {
70  LWSDBG(5, std::cout << "inside fan point " << MSG_VECTOR(inputP) << ", FHTminusT=" << FHTminusT << std::endl);
71  } else {
72  LWSDBG(5, std::cout << "on fan surface adtnf_p=" << adtnf_p << ", m_FHTplusT=" << m_FHTplusT << ", FHTminusT=" << FHTminusT << std::endl);
73 
74  const G4ThreeVector d = GetCalculator()->NearestPointOnNeutralFibre(p, p_fan);
75  // check dot product between normal and v
76  if ( (p-d).cosTheta(v) > AngularTolerance ) {
77  // direction "v" definitely pointing outside
78  // return 0.0
79  return 0.;
80  }
81  }
82 #endif
83 
84 // former distance_to_out starts here
85  LWSDBG(4, std::cout << "dto: " << MSG_VECTOR(p) << " "
86  << MSG_VECTOR(v) << std::endl);
87 
88  G4ThreeVector q(p);
89 #ifdef LARWHEELSOLID_USE_BS_DTO
90  const G4double dto_bs = m_BoundingShape->DistanceToOut(
91  inputP, inputV, calcNorm, validNorm, sn
92  );
93  q = p + v * dto_bs;
94  if(q.y() < m_Ymin){
95  LWSDBG(5, std::cout << "dto exit point too low " << MSG_VECTOR(q) << std::endl);
96  const G4double dy = (m_Ymin - p.y()) / v.y();
97  q.setX(p.x() + v.x() * dy);
98  q.setY(m_Ymin);
99  q.setZ(p.z() + v.z() * dy);
100  }
101 #else
103  LWSDBG(5, std::cout << "dto exit " << exit << std::endl);
104 #endif
105  LWSDBG(5, std::cout << "dto exit point " << MSG_VECTOR(q) << std::endl);
106 
107  G4double distance = 0.;
108  G4int start = select_section(p.z());
109  G4int stop = select_section(q.z());
110  G4int step = -1;
111  if(stop > start){ step = 1; start ++; stop ++; }
112  LWSDBG(5, std::cout << "dto sections " << start << " " << stop << " " << step << std::endl);
113 
114  G4double tmp;
115  G4ThreeVector p1, C;
116 
117  for(G4int i = start; i != stop; i += step){
118  const G4double d1 = (m_Zsect[i] - p.z()) / v.z();
119 // v.z() can't be 0, otherwise start == stop, so the exit point could be only
120 // at z border of the fan section
121  LWSDBG(5, std::cout << "at " << i << " dist to zsec = " << d1 << std::endl);
122  const G4double x1 = p.x() + v.x() * d1, y1 = p.y() + v.y() * d1;
123  p1.set(x1, y1, m_Zsect[i]);
124  const G4double dd = fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan));
125  if(dd > m_FHTplusT){
126  tmp = out_iteration_process(p, p1, p_fan);
127  //while(search_for_most_remoted_point(p, out_section, C)){
128  if(search_for_most_remoted_point(p, p1, C, p_fan)){
129  tmp = out_iteration_process(p, C, p_fan);
130  }
131  distance += tmp;
132 #ifndef LARWHEELSOLID_USE_BS_DTO
133  exit = NoCross;
134 #endif
135  goto end_dto;
136  }
137  if(search_for_most_remoted_point(p, p1, C, p_fan)){
138  distance += out_iteration_process(p, C, p_fan);
139 #ifndef LARWHEELSOLID_USE_BS_DTO
140  exit = NoCross;
141 #endif
142  goto end_dto;
143  }
144  distance += d1;
145  p.set(x1, y1, m_Zsect[i]);
146  }
147 
148  if(fabs(GetCalculator()->DistanceToTheNeutralFibre(q, p_fan)) > m_FHTplusT){
149  LWSDBG(5, std::cout << "q=" << MSG_VECTOR(q) << " outside fan cur distance=" << distance << ", m_FHTplusT=" << m_FHTplusT << std::endl);
150  tmp = out_iteration_process(p, q, p_fan);
151 #ifndef LARWHEELSOLID_USE_BS_DTO
152  exit = NoCross;
153 #endif
154  } else {
155  tmp = (q - p).mag();
156  }
157  //while(search_for_most_remoted_point(out, out1, C, p_fan)){
158  if(search_for_most_remoted_point(p, q, C, p_fan)){
159  tmp = out_iteration_process(p, C, p_fan);
160 #ifndef LARWHEELSOLID_USE_BS_DTO
161  exit = NoCross;
162 #endif
163  }
164  distance += tmp;
165 // former distance_to_out ends here
166  end_dto:
167  LWSDBG(5, std::cout << "At end_dto distance=" << distance << std::endl);
168 #ifdef LARWHEELSOLID_USE_BS_DTO
169  if(calcNorm && distance < dto_bs) *validNorm = false;
170 #else
171  if(calcNorm){
172  LWSDBG(5, std::cout << "dto calc norm " << exit << std::endl);
173  switch(exit){
174  case ExitAtBack:
175  sn->set(0., 0., 1.);
176  *validNorm = true;
177  break;
178  case ExitAtFront:
179  sn->set(0., 0., -1.);
180  *validNorm = true;
181  break;
182  case ExitAtOuter:
183  q.rotateZ(-phi0);
184  sn->set(q.x(), q.y(), 0.);
185  if(q.z() <= m_Zmid) sn->setZ(- q.perp() * m_fs->Amax);
186  sn->setMag(1.0);
187  *validNorm = true;
188  break;
189  default:
190  *validNorm = false;
191  break;
192  }
193  }
194 #endif
195 
196 #ifdef DEBUG_LARWHEELSOLID
197  if(Verbose > 2){
198  std::cout << "DTO: " << distance << " ";
199  if (*validNorm) {
200  std::cout << *validNorm << " " << MSG_VECTOR((*sn));
201  } else {
202  std::cout << "Norm is not valid";
203  }
204  std::cout << std::endl;
205  if(Verbose > 3){
206  G4ThreeVector p2 = inputP + inputV * distance;
207  EInside i = Inside(p2);
208  std::cout << "DTO hit at " << MSG_VECTOR(p2) << ", "
209  << inside(i) << std::endl;
210  }
211  }
212 #ifdef LWS_HARD_TEST_DTO
213  if(test_dto(inputP, inputV, distance)){
214  if(Verbose == 1){
215  std::cout << TypeStr() << " DisToOut" << MSG_VECTOR(inputP)
216  << MSG_VECTOR(inputV) << std::endl;
217  }
218  }
219 #endif
220 #endif
221  return distance;
222 }
223 
224 // This functions should be called in the case when we are sure that
225 // point p is NOT OUTSIDE of vertical fan and point out is NOT INSIDE vertical fan
226 // returns distance from point p to fan surface, sets last
227 // parameter to the found point
228 // may give wrong answer - see description
229 G4double LArWheelSolid::out_iteration_process(const G4ThreeVector &p,
230  G4ThreeVector &B, const int p_fan) const
231 {
232  LWSDBG(6, std::cout << "oip: " << p << " " << B);
233  assert(fabs(GetCalculator()->DistanceToTheNeutralFibre(p, p_fan)) < m_FHTplusT);
234  assert(fabs(GetCalculator()->DistanceToTheNeutralFibre(B, p_fan)) > m_FHTminusT);
235  G4ThreeVector A(p), C, diff;
236  unsigned int niter = 0;
237  do {
238  C = A + B;
239  C *= 0.5;
240  if(fabs(GetCalculator()->DistanceToTheNeutralFibre(C, p_fan)) < m_FHTplusT){
241  A = C;
242  } else {
243  B = C;
244  }
245  niter ++;
246  diff = A - B;
247  } while(diff.mag2() > s_IterationPrecision2 && niter < s_IterationsLimit);
248  assert(fabs(GetCalculator()->DistanceToTheNeutralFibre(B, p_fan)) > m_FHTplusT);
249  assert(niter < s_IterationsLimit);
250  diff = p - B;
251  LWSDBG(7, std::cout << " -> " << B << " " << diff.mag());
252  LWSDBG(6, std::cout << std::endl);
253  return diff.mag();
254 }
255 
256 // returns true if the point being outside vert. fan is found, also set C to
257 // that point in this case
258 // returns false if the whole track looks like being inside vert. fan
260  const G4ThreeVector &a, const G4ThreeVector &b, G4ThreeVector &C, const int p_fan
261 ) const
262 {
263  LWSDBG(6, std::cout << "sfmrp " << a << " " << b << std::endl);
264  G4ThreeVector diff(b - a);
265 
266  if(diff.mag2() <= s_IterationPrecision2) return false;
267  G4ThreeVector A(a), B(b), l(diff.unit() * s_IterationPrecision);
268  // find the most remoted point on the line AB
269  // and check if it is outside vertical fan
270  // small vector along the segment AB
271  G4double d1, d2;
272  unsigned int niter = 0;
273  // searching for maximum of (GetCalculator()->DistanceToTheNeutralFibre)^2 along AB
274  do {
275  C = A + B;
276  C *= 0.5;
278  if(fabs(d1) > m_FHTplusT){
279  // here out_iteration_process gives the answer
280  LWSDBG(7, std::cout << "sfmrp -> " << C << " " << fabs(d1)
281  << " " << (C - a).unit() << " "
282  << (C - a).mag() << std::endl);
283  return true;
284  }
285  // sign of derivative
286  //d1 = GetCalculator()->DistanceToTheNeutralFibre(C + l);
288  if(d1 * d1 - d2 * d2 > 0.) A = C;
289  else B = C;
290  niter ++;
291  diff = A - B;
292  } while(diff.mag2() > s_IterationPrecision2 && niter < s_IterationsLimit);
293  // the line entirely lies inside fan
294  assert(niter < s_IterationsLimit);
295  return false;
296 }
LArWheelSolid::ExitAtFront
@ ExitAtFront
Definition: LArWheelSolid.h:191
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
LArWheelSolid::m_FHTminusT
G4double m_FHTminusT
Definition: LArWheelSolid.h:149
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
LArWheelSolid::ExitAtOuter
@ ExitAtOuter
Definition: LArWheelSolid.h:190
LArWheelSolid::s_Tolerance
static const G4double s_Tolerance
Definition: LArWheelSolid.h:140
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::search_for_most_remoted_point
G4bool search_for_most_remoted_point(const G4ThreeVector &, const G4ThreeVector &, G4ThreeVector &, const int) const
Definition: LArWheelSolidDisToOut.cxx:259
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
LArWheelSolid::m_Ymin
G4double m_Ymin
Definition: LArWheelSolid.h:167
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
LArFanSections::Amax
G4double Amax
Definition: LArFanSection.h:14
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
LArWheelSolid::DistanceToOut
G4double DistanceToOut(const G4ThreeVector &, const G4ThreeVector &, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
Definition: LArWheelSolidDisToOut.cxx:34
LWSDBG
#define LWSDBG(a, b)
Definition: LArWheelSliceSolid.h:28
lumiFormat.i
int i
Definition: lumiFormat.py:92
TRT::Track::d0
@ d0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:62
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
LArWheelSolid::m_Zsect
std::vector< G4double > m_Zsect
Definition: LArWheelSolid.h:159
LArWheelSolid::Inside
EInside Inside(const G4ThreeVector &) const
Definition: LArWheelSolid.cxx:15
calibdata.exit
exit
Definition: calibdata.py:236
LArWheelSolid::m_fs
LArFanSections * m_fs
Definition: LArWheelSolid.h:162
LArWheelSolid::select_section
G4int select_section(const G4double &Z) const
Definition: LArWheelSolid.cxx:164
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
LArWheelSolid::NoCross
@ NoCross
Definition: LArWheelSolid.h:190
library_scraper.dd
list dd
Definition: library_scraper.py:46
python.PyAthena.v
v
Definition: PyAthena.py:157
Trk::inside
@ inside
Definition: PropDirection.h:29
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
a
TList * a
Definition: liststreamerinfos.cxx:10
LArWheelCalculator::NearestPointOnNeutralFibre
CLHEP::Hep3Vector NearestPointOnNeutralFibre(const CLHEP::Hep3Vector &p, int fan_number) const
Definition: LArWheelCalculatorGeometry.cxx:113
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
LArWheelSolid::FanBoundExit_t
FanBoundExit_t
Definition: LArWheelSolid.h:189
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
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
LArWheelSolid::m_Zmid
G4double m_Zmid
Definition: LArWheelSolid.h:165
mag
Scalar mag() const
mag method
Definition: AmgMatrixBasePlugin.h:25
LArWheelSolid::out_iteration_process
G4double out_iteration_process(const G4ThreeVector &, G4ThreeVector &, const int) const
Definition: LArWheelSolidDisToOut.cxx:229
LArWheelCalculator.h
LArWheelSolid::ExitAtBack
@ ExitAtBack
Definition: LArWheelSolid.h:191