Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4OuterHcalField.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4OuterHcalField.cc
1 // $Id: $
2 
11 #include "PHG4OuterHcalField.h"
12 
13 #include <TSystem.h>
14 
15 #include <Geant4/G4Field.hh> // for G4Field
16 #include <Geant4/G4FieldManager.hh>
17 #include <Geant4/G4PhysicalConstants.hh>
18 #include <Geant4/G4SystemOfUnits.hh>
19 #include <Geant4/G4TransportationManager.hh>
20 #include <Geant4/G4Types.hh> // for G4double, G4int
21 #include <Geant4/G4Vector3D.hh>
22 
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wshadow"
25 #include <boost/stacktrace.hpp>
26 #pragma GCC diagnostic pop
27 
28 #include <cassert> // for assert
29 #include <cmath> // for atan2, cos, sin, sqrt
30 #include <cstdlib> // for exit
31 #include <iostream>
32 
33 PHG4OuterHcalField::PHG4OuterHcalField(bool isInIron, G4int steelPlates,
34  G4double scintiGap, G4double tiltAngle)
35  : is_in_iron(isInIron)
36  , n_steel_plates(steelPlates)
37  , scinti_gap(scintiGap)
38  , tilt_angle(tiltAngle)
39 {
40 }
41 
42 void PHG4OuterHcalField::GetFieldValue(const double Point[4], double* Bfield) const
43 {
44  G4FieldManager* field_manager =
45  G4TransportationManager::GetTransportationManager()->GetFieldManager();
46 
47  if (!field_manager)
48  {
49  std::cout << "PHG4OuterHcalField::GetFieldValue"
50  << " - Error! can not find field manager in G4TransportationManager"
51  << std::endl;
52  gSystem->Exit(1);
53  exit(1);
54  }
55 
56  const G4Field* default_field = field_manager->GetDetectorField();
57 
58  if (default_field)
59  {
60  default_field->GetFieldValue(Point, Bfield);
61  // scale_factor for field component along the plate surface
62  double x = Point[0];
63  double y = Point[1];
64  // double z = Point[2];
65 
66  assert(cos(tilt_angle) > 0);
68 
69  // input 2D magnetic field vector
70  const G4Vector3D B0(Bfield[0], Bfield[1], Bfield[2]);
71  const G4Vector3D B0XY(Bfield[0], Bfield[1], 0);
72  const G4Vector3D B0Z(0, 0, Bfield[2]);
73 
74  const double R = sqrt(x * x + y * y);
75  const double layer_RdPhi = R * twopi / n_steel_plates;
76  const double layer_width = layer_RdPhi * cos(tilt_angle);
77  const double gap_width = scinti_gap;
78  if (gap_width >= layer_width)
79  {
80  std::cout << "PHG4OuterHcalField::GetFieldValue gap_width " << gap_width
81  << " < layer_width: " << layer_width
82  << " existing now, here is some debug info" << std::endl;
83  std::cout << "coordinates: x: " << Point[0] / cm
84  << ", y: " << Point[1] / cm
85  << ", z: " << Point[2] / cm << std::endl;
86  std::cout << "n_steel_plates: " << n_steel_plates << std::endl;
87  std::cout << "Radius: " << R << std::endl;
88  std::cout << "layer_RdPhi: " << layer_RdPhi << std::endl;
89  std::cout << "layer_width: " << layer_width << std::endl;
90  std::cout << "tilt_angle: " << tilt_angle << std::endl;
91  std::cout << "And this is who called it:" << std::endl;
92  std::cout << boost::stacktrace::stacktrace();
93  std::cout << std::endl;
94  return;
95  }
96  // sign definition of tilt_angle is rotation around the -z axis
97  const G4Vector3D absorber_dir(cos(atan2(y, x) - tilt_angle),
98  sin(atan2(y, x) - tilt_angle), 0);
99  const G4Vector3D radial_dir(cos(atan2(y, x)), sin(atan2(y, x)), 0);
100 
101  const double radial_flux_per_layer = layer_RdPhi * (B0XY.dot(radial_dir));
102  double B_XY_mag = radial_flux_per_layer / (relative_permeability_absorber * (layer_width - gap_width) + relative_permeability_gap * gap_width);
103  B_XY_mag *=
105 
106  const G4Vector3D B_New_XY = B_XY_mag * absorber_dir;
107 
108  const double z_flux_per_layer = layer_width * B0Z.z();
109  double B_Z_mag = z_flux_per_layer / (relative_permeability_absorber * (layer_width - gap_width) + relative_permeability_gap * gap_width);
110  B_Z_mag *=
112  const G4Vector3D B_New_Z(0, 0, B_Z_mag);
113 
114  // scale B_T component
115  G4Vector3D B_New = B_New_Z + B_New_XY;
116  Bfield[0] = B_New.x();
117  Bfield[1] = B_New.y();
118  Bfield[2] = B_New.z();
119  }
120  else
121  {
122  std::cout << "PHG4OuterHcalField::GetFieldValue"
123  << " - Error! can not find detecor field in field manager!"
124  << std::endl;
125  gSystem->Exit(1);
126  exit(1);
127  }
128 }