Belle II Software  release-08-01-10
ExtCylSurfaceTarget.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <simulation/kernel/ExtCylSurfaceTarget.h>
10 #include <G4GeometryTolerance.hh>
11 #include <geomdefs.hh>
12 #include <G4Normal3D.hh>
13 #include <G4Plane3D.hh>
14 #include <framework/logging/Logger.h>
15 
16 using namespace std;
17 using namespace Belle2;
18 using namespace Belle2::Simulation;
19 
20 ExtCylSurfaceTarget::ExtCylSurfaceTarget(const G4double& radius,
21  const G4double& zmin,
22  const G4double& zmax) :
23  m_radius(radius),
24  m_zmin(zmin),
25  m_zmax(zmax),
26  m_tolerance(1000.0 * G4GeometryTolerance::GetInstance()->GetSurfaceTolerance())
27 {
28  theType = G4ErrorTarget_CylindricalSurface;
29  B2DEBUG(1, "Simulation::ExtCylSurfaceTarget created with radius "
30  << m_radius << " zmin " << zmin << " zmax " << zmax);
31 }
32 
34 {
35 }
36 
37 G4double ExtCylSurfaceTarget::GetDistanceFromPoint(const G4ThreeVector& point,
38  const G4ThreeVector& dir) const
39 {
40  if (fabs(dir.mag() - 1.0) > 1.0E-10) {
41  B2FATAL("Simulation::ExtCylSurfaceTarget::GetDistanceFromPoint() direction is not a unit vector: " << dir);
42  }
43 
44  // Get distance to intersection point with the cylinder's curved surface
45  // should be negative if outside! G4double dist = (point - IntersectLocal(point, dir)).mag();
46  G4double dist = (IntersectLocal(point, dir) - point) * dir;
47 
48  // Get intersection point with the plane at either zmin or zmax
49  G4double dirz = dir.z();
50  if (dirz < -1.0E-10) {
51  dist = fmin(dist, (m_zmin - point.z()) / dirz);
52  } else if (dirz > 1.0E-10) {
53  dist = fmin(dist, (m_zmax - point.z()) / dirz);
54  }
55 
56  B2DEBUG(300, "Simulation::ExtCylSurfaceTarget::GetDistanceFromPoint(): Global point "
57  << point << " dir " << dir << " distance " << dist);
58 
59  return dist;
60 }
61 
62 G4double ExtCylSurfaceTarget::GetDistanceFromPoint(const G4ThreeVector& point) const
63 {
64 
65  G4double dist = m_radius - point.perp();
66  dist = fmin(dist, point.z() - m_zmin);
67  dist = fmin(dist, m_zmax - point.z());
68 
69  B2DEBUG(300, "Simulation::ExtCylSurfaceTarget::GetDistanceFromPoint(): Global point "
70  << point << " minimum distance " << dist);
71 
72  return dist;
73 }
74 
75 G4ThreeVector ExtCylSurfaceTarget::IntersectLocal(const G4ThreeVector& localPoint,
76  const G4ThreeVector& localDir) const
77 {
78  // localDir has already been verified to be a unit vector
79  G4double eqa = localDir.x() * localDir.x() + localDir.y() * localDir.y();
80  G4double eqb = 2.0 * (localPoint.x() * localDir.x() + localPoint.y() * localDir.y());
81  G4double eqc = localPoint.x() * localPoint.x() + localPoint.y() * localPoint.y()
82  - m_radius * m_radius;
83  G4double eqaInside = (localPoint.perp() > m_radius) ? -eqa : eqa;
84 
85  G4ThreeVector intersection = localPoint;
86  if (eqaInside > 0.0) {
87  intersection += localDir * ((-eqb + sqrt(eqb * eqb - 4.0 * eqa * eqc)) / (2.0 * eqa));
88  } else if (eqaInside < 0.0) {
89  intersection += localDir * ((-eqb - sqrt(eqb * eqb - 4.0 * eqa * eqc)) / (2.0 * eqa));
90  } else {
91  if (eqb != 0.0) {
92  intersection -= localDir * (eqc / eqb);
93  } else {
94  B2WARNING("Simulation::ExtCylSurfaceTarget::IntersectLocal(): localPoint "
95  << localPoint << " localDir " << localDir << " does not intersect with cylinder");
96  intersection = localDir * kInfinity;
97  }
98  }
99 
100  B2DEBUG(300, "Simulation::ExtCylSurfaceTarget::IntersectLocal(): localPoint "
101  << localPoint << " localDir " << localDir << " radial intersection " << intersection.perp());
102 
103  return intersection;
104 }
105 
106 G4Plane3D ExtCylSurfaceTarget::GetTangentPlane(const G4ThreeVector& point) const
107 {
108  // check that point is at the cylinder's curved surface
109  if (fabs(point.perp() - m_radius) > m_tolerance) {
110  B2ERROR("Simulation::ExtCylSurfaceTarget::GetTangentPlane(): point "
111  << point << " is not at surface; radial distance is " << point.perp() - m_radius);
112  }
113 
114  G4Normal3D normal(point);
115 
116  return G4Plane3D(normal, point);
117 }
118 
120 void ExtCylSurfaceTarget::Dump(const G4String&) const
121 {
122 }
123 
G4double m_tolerance
Tolerance for distance between a point and cylinder's curved surface.
virtual G4Plane3D GetTangentPlane(const G4ThreeVector &point) const
Get the plane tangent to the cylinder at a given point.
virtual void Dump(const G4String &msg) const
Dump the cylinder parameters.
virtual G4ThreeVector IntersectLocal(const G4ThreeVector &point, const G4ThreeVector &direc) const
Return the intersection of the cylinder with the line defined in local (cylinder) coordinates by poin...
G4double m_zmax
Cylinder maximum-z coordinate.
virtual G4double GetDistanceFromPoint(const G4ThreeVector &point, const G4ThreeVector &direc) const
Get the distance from a point to the cylinder along direc.
G4double m_zmin
Cylinder minimum-z coordinate.
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.