ATLAS Offline Software
Loading...
Searching...
No Matches
LArWheelSliceSolidDisToOut.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <cassert>
6
9
10G4double LArWheelSliceSolid::DistanceToOut(const G4ThreeVector &inputP) const
11{
12 LWSDBG(1, std::cout << TypeStr() << " DisToOut" << MSG_VECTOR(inputP) << std::endl);
13 if(m_BoundingShape->Inside(inputP) != kInside){
14 LWSDBG(2, std::cout << "DistanceToOut(p):"
15 << " point " << MSG_VECTOR(inputP)
16 << " is not inside of the m_BoundingShape."
17 << std::endl);
18 return 0.;
19 }
20 G4ThreeVector p(inputP);
21 int p_fan = 0;
22 const G4double d = m_FanHalfThickness - fabs(GetCalculator()->DistanceToTheNearestFan(p, p_fan));
23 if(d < s_Tolerance){
24 LWSDBG(2, std::cout << "already not inside " << MSG_VECTOR(p) << std::endl);
25 return 0.;
26 }
27 const G4double d0 = m_BoundingShape->DistanceToOut(inputP);
28 LWSDBG(2, std::cout << "dto " << d << " " << d0 << std::endl);
29 if(d > d0) return d0;
30 else return d;
31}
32
33G4double LArWheelSliceSolid::DistanceToOut(const G4ThreeVector &inputP,
34 const G4ThreeVector &inputV,
35 const G4bool calcNorm,
36 G4bool* validNorm,
37 G4ThreeVector* sn) const
38{
39 LWSDBG(1, std::cout << TypeStr() << " DisToOut" << MSG_VECTOR(inputP)
40 << MSG_VECTOR(inputV) << std::endl);
41
42 const EInside inside_BS = m_BoundingShape->Inside(inputP);
43 if(inside_BS == kOutside){
44 LWSDBG(2, std::cout << "DistanceToOut(p):"
45 << " point " << MSG_VECTOR(inputP)
46 << " is outside of m_BoundingShape." << std::endl);
47 if(calcNorm) *validNorm = false;
48 return 0.;
49 }
50
51 // If here inside or on surface of BS
52 G4ThreeVector p(inputP);
53 int p_fan = 0;
54 const G4double adtnf_p = fabs(GetCalculator()->DistanceToTheNearestFan(p, p_fan));
55 if(adtnf_p >= m_FHTplusT) {
56 LWSDBG(2, std::cout << "DistanceToOut(p, v): point "
57 << MSG_VECTOR(inputP)
58 << " is outside of solid." << std::endl);
59 if(calcNorm) *validNorm = false;
60 return 0.;
61 }
62
63 G4ThreeVector v(inputV);
64 const G4double phi0 = p.phi() - inputP.phi();
65 v.rotateZ(phi0);
66
67// former distance_to_out starts here
68 LWSDBG(4, std::cout << "dto: " << MSG_VECTOR(p) << " "
69 << MSG_VECTOR(v) << std::endl);
70
71 G4ThreeVector q(p);
72
73 const G4double dto_bs = m_BoundingShape->DistanceToOut(
74 inputP, inputV, calcNorm, validNorm, sn
75 );
76 q = p + v * dto_bs;
77 if(q.y() < m_Ymin){
78 LWSDBG(5, std::cout << "dto exit point too low " << MSG_VECTOR(q) << std::endl);
79 const G4double dy = (m_Ymin - p.y()) / v.y();
80 q.setX(p.x() + v.x() * dy);
81 q.setY(m_Ymin);
82 q.setZ(p.z() + v.z() * dy);
83 }
84 LWSDBG(5, std::cout << "dto exit point " << MSG_VECTOR(q) << std::endl);
85
86 G4double tmp;
87 G4double distance = 0.;
88 if(fabs(GetCalculator()->DistanceToTheNeutralFibre(q, p_fan)) > m_FHTplusT){
89 LWSDBG(5, std::cout << "q=" << MSG_VECTOR(q)
90 << " outside fan cur distance="
91 << distance << ", m_FHTplusT="
92 << m_FHTplusT << std::endl);
93 tmp = out_iteration_process(p, q, p_fan);
94 } else {
95 tmp = (q - p).mag();
96 }
97 G4ThreeVector C;
98 if(search_for_most_remoted_point(p, q, C, p_fan)){
99 tmp = out_iteration_process(p, C, p_fan);
100 }
101 distance += tmp;
102
103 LWSDBG(5, std::cout << "At end_dto distance=" << distance << std::endl);
104 if(calcNorm && distance < dto_bs) *validNorm = false;
105
106#ifdef DEBUG_LARWHEELSLICESOLID
107 if(Verbose > 2){
108 std::cout << "DTO: " << distance << " ";
109 if (*validNorm) {
110 std::cout << *validNorm << " " << MSG_VECTOR((*sn));
111 } else {
112 std::cout << "Norm is not valid";
113 }
114 std::cout << std::endl;
115 if(Verbose > 3){
116 G4ThreeVector p2 = inputP + inputV * distance;
117 EInside i = Inside(p2);
118 std::cout << "DTO hit at " << MSG_VECTOR(p2) << ", "
119 << inside(i) << std::endl;
120 }
121 }
122#ifdef LWS_HARD_TEST_DTO
123 if(test_dto(inputP, inputV, distance)){
124 if(Verbose == 1){
125 std::cout << TypeStr() << " DisToOut" << MSG_VECTOR(inputP)
126 << MSG_VECTOR(inputV) << std::endl;
127 }
128 }
129#endif
130#endif
131 return distance;
132}
133
134// This functions should be called in the case when we are sure that
135// point p is NOT OUTSIDE of vertical fan and point out is NOT INSIDE vertical fan
136// returns distance from point p to fan surface, sets last
137// parameter to the found point
138// may give wrong answer - see description
139G4double LArWheelSliceSolid::out_iteration_process(const G4ThreeVector &p,
140 G4ThreeVector &B, const int p_fan) const
141{
142 LWSDBG(6, std::cout << "oip: " << p << " " << B);
143 assert(fabs(GetCalculator()->DistanceToTheNeutralFibre(p, p_fan)) < m_FHTplusT);
144 assert(fabs(GetCalculator()->DistanceToTheNeutralFibre(B, p_fan)) > m_FHTminusT);
145 G4ThreeVector A(p), C, diff;
146 unsigned int niter = 0;
147 do {
148 C = A + B;
149 C *= 0.5;
150 if(fabs(GetCalculator()->DistanceToTheNeutralFibre(C, p_fan)) < m_FHTplusT){
151 A = C;
152 } else {
153 B = C;
154 }
155 niter ++;
156 diff = A - B;
157 } while(diff.mag2() > s_IterationPrecision2 && niter < s_IterationsLimit);
158 assert(fabs(GetCalculator()->DistanceToTheNeutralFibre(B, p_fan)) > m_FHTplusT);
159 assert(niter < s_IterationsLimit);
160 diff = p - B;
161 LWSDBG(7, std::cout << " -> " << B << " " << diff.mag());
162 LWSDBG(6, std::cout << std::endl);
163 return diff.mag();
164}
165
166// returns true if the point being outside vert. fan is found, also set C to
167// that point in this case
168// returns false if the whole track looks like being inside vert. fan
170 const G4ThreeVector &a, const G4ThreeVector &b, G4ThreeVector &C, const int p_fan
171) const
172{
173 LWSDBG(6, std::cout << "sfmrp " << a << " " << b << std::endl);
174 G4ThreeVector diff(b - a);
175
176 if(diff.mag2() <= s_IterationPrecision2) return false;
177 G4ThreeVector A(a), B(b), l(diff.unit() * s_IterationPrecision);
178 // find the most remoted point on the line AB
179 // and check if it is outside vertical fan
180 // small vector along the segment AB
181 G4double d1, d2;
182 unsigned int niter = 0;
183 // searching for maximum of (GetCalculator()->DistanceToTheNeutralFibre)^2 along AB
184 do {
185 C = A + B;
186 C *= 0.5;
188 if(fabs(d1) > m_FHTplusT){
189 // here out_iteration_process gives the answer
190 LWSDBG(7, std::cout << "sfmrp -> " << C << " " << fabs(d1)
191 << " " << (C - a).unit() << " "
192 << (C - a).mag() << std::endl);
193 return true;
194 }
195 // sign of derivative
196 //d1 = GetCalculator()->DistanceToTheNeutralFibre(C + l);
197 d2 = GetCalculator()->DistanceToTheNeutralFibre(C - l, p_fan);
198 if(d1 * d1 - d2 * d2 > 0.) A = C;
199 else B = C;
200 niter ++;
201 diff = A - B;
202 } while(diff.mag2() > s_IterationPrecision2 && niter < s_IterationsLimit);
203 // the line entirely lies inside fan
204 assert(niter < s_IterationsLimit);
205 return false;
206}
Scalar mag() const
mag method
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
static Double_t a
#define LWSDBG(a, b)
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
double DistanceToTheNeutralFibre(const CLHEP::Hep3Vector &p, int fan_number) const
Calculates aproximate, probably underestimate, distance to the neutral fibre of the vertical fan.
static const G4double s_IterationPrecision
static const unsigned int s_IterationsLimit
G4double DistanceToOut(const G4ThreeVector &, const G4ThreeVector &, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
const LArWheelCalculator * GetCalculator(void) const
static const G4double s_Tolerance
static const G4double s_IterationPrecision2
EInside Inside(const G4ThreeVector &) const
G4String TypeStr(void) const
G4double out_iteration_process(const G4ThreeVector &, G4ThreeVector &, const int) const
G4bool search_for_most_remoted_point(const G4ThreeVector &, const G4ThreeVector &, G4ThreeVector &, const int) const
struct color C
hold the test vectors and ease the comparison