Belle II Software  release-05-01-25
BFieldComponentKlm1.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010-2011 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Andreas Moll, SUMISAWA Kazutaka *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <geometry/bfieldmap/BFieldComponentKlm1.h>
12 
13 #include <framework/utilities/FileSystem.h>
14 #include <framework/logging/Logger.h>
15 
16 #include <boost/iostreams/filtering_stream.hpp>
17 #include <boost/iostreams/device/file.hpp>
18 
19 #include <cmath>
20 
21 using namespace std;
22 using namespace Belle2;
23 namespace io = boost::iostreams;
24 
25 void BFieldComponentKlm1::initialize()
26 {
27  if (m_mapFilename.empty()) {
28  B2ERROR("The filename for the magnetic field Component is empty !");
29  return;
30  }
31 
32  string fullPath = FileSystem::findFile("/data/" + m_mapFilename);
33 
34  if (!FileSystem::fileExists(fullPath)) {
35  B2ERROR("The magnetic field map file '" << m_mapFilename << "' could not be found !");
36  return;
37  }
38 
39  //Load the map file
40  io::filtering_istream fieldMapFile;
41  fieldMapFile.push(io::file_source(fullPath));
42 
43  //read the data from the file
44  B2DEBUG(10, "Loading the magnetic field from file '" << m_mapFilename << "' in to the memory...");
45 
46  char dummy[100];
47 
48  //store parameters for Barrel
49  fieldMapFile.getline(dummy, sizeof(dummy));
50  for (int layer = 0; layer < m_nBarrelLayers; ++layer) {
51  int l;
52  fieldMapFile >> l >> m_barrelZBreakpoint[layer] >> m_barrelRBreakpoint[layer]
53  >> m_barrelFieldZSlope1[layer]
54  >> m_barrelFieldZIntercept1[layer]
55  >> m_barrelFieldZSlope2[layer]
56  >> m_barrelFieldZIntercept2[layer]
57  >> m_barrelFieldRSlope1[layer]
58  >> m_barrelFieldRIntercept1[layer]
59  >> m_barrelFieldRSlope2[layer]
60  >> m_barrelFieldRIntercept2[layer];
61 
62  if (layer != l)
63  B2ERROR("Barrel Parameter file is something wrong ! " << layer << " " << l);
64  }
65 
66  //store parameters for Endcap
67  fieldMapFile.getline(dummy, sizeof(dummy));
68  fieldMapFile.getline(dummy, sizeof(dummy));
69  for (int GapIron = 0; GapIron < 2; GapIron++) {
70  for (int layer = 0; layer < m_nEndcapLayers + 1; layer++) {
71  for (int j = 0; j < 5; j++) {
72  int g, l, jj;
73  fieldMapFile >> g >> l >> jj
74  >> m_endcapZBreakpoint[GapIron][layer][j] >> m_endcapRBreakpoint[GapIron][layer][j]
75  >> m_endcapFieldZSlope[GapIron][layer][j]
76  >> m_endcapFieldZIntercept[GapIron][layer][j]
77  >> m_endcapFieldRSlope[GapIron][layer][j]
78  >> m_endcapFieldRIntercept[GapIron][layer][j];
79  if (GapIron != g || layer != l || jj != j)
80  B2ERROR("Endcap Parameter file is something wrong ! " << g << " " << l << " " << jj);
81  }
82  }
83  }
84 
85  B2DEBUG(10, "... loaded ");
86 }
87 
88 
89 B2Vector3D BFieldComponentKlm1::calculate(const B2Vector3D& point) const
90 {
91  //Get the r and z Component
92  double r = point.Perp();
93  double x = point.X();
94  double y = point.Y();
95  double z = point.Z() - m_mapOffset;
96  double absZ = std::abs(z);
97 
98  B2Vector3D bField(0., 0., 0.);
99 
100  // Barrel
101  if (absZ < m_barrelZMax) {
102 
103  // This code assumes that we are in the barrel KLM. Use the field map
104  // inside an iron plate; use zero in the gap between the iron plates.
105 
106  double cosphi = std::abs(x) / r;
107  double d = ((cosphi < m_cospi8) ? ((cosphi < m_cos3pi8) ? std::abs(y)
108  : (std::abs(x) + std::abs(y)) * m_cospi4)
109  : std::abs(x)) - m_barrelRMin - m_barrelGapHeightLayer0;
110 
111  if (d >= 0.0) {
112  int layer = static_cast<int>(floor(d / m_dLayer));
113 
114  // make sure layer is in a valid range
115  if (layer < 0 || layer > m_nBarrelLayers) return bField;
116  if (layer == m_nBarrelLayers) {
117  layer = m_nBarrelLayers - 1;
118  d = layer * m_dLayer; // for extra-thick outermost iron plate
119  }
120  if ((d - layer * m_dLayer) < m_barrelIronThickness) {
121  double br = ((absZ > m_barrelRBreakpoint[layer]) ?
122  m_barrelFieldRIntercept2[layer] + m_barrelFieldRSlope2[layer] * absZ :
123  m_barrelFieldRIntercept1[layer] + m_barrelFieldRSlope1[layer] * absZ);
124  if (z < 0.0) { br = -br; }
125  bField.SetXYZ(br * x / r, br * y / r,
126  ((absZ > m_barrelZBreakpoint[layer]) ?
127  m_barrelFieldZIntercept2[layer] + m_barrelFieldZSlope2[layer] * absZ :
128  m_barrelFieldZIntercept1[layer] + m_barrelFieldZSlope1[layer] * absZ));
129  }
130  }
131  } else if (absZ > m_endcapZMin) {
132  //Endcap
133  if (r <= m_endcapRMin) return bField;
134 
135  // This code assumes that we are in the endcap KLM.
136  // The field in an inter-plate gap in the endcap is not zero.
137 
138  double dz = absZ - (m_endcapZMin - m_endcapGapHeight);
139  int layer = static_cast<int>(floor(dz / m_dLayer));
140  // make sure layer is in a valid range
141  if (layer < 0 || layer >= m_nEndcapLayers) return bField;
142 
143  int GapIron = 0; // in gap
144  if ((dz - m_dLayer * layer) > m_endcapGapHeight) GapIron = 1; // in Iron plate?
145  for (int j = 0; j < 5; j++) {
146  if (r < m_endcapRBreakpoint[GapIron][layer][j]) {
147  double br = m_endcapFieldRIntercept[GapIron][layer][j] + m_endcapFieldRSlope[GapIron][layer][j] * r;
148  if (z < 0.0) { br = -br; }
149  bField.SetX(br * x / r);
150  bField.SetY(br * y / r);
151  break;
152  }
153  }
154  for (int j = 0; j < 5; j++) {
155  if (r < m_endcapZBreakpoint[GapIron][layer][j]) {
156  bField.SetZ(m_endcapFieldZIntercept[GapIron][layer][j] + m_endcapFieldZSlope[GapIron][layer][j] * r);
157  break;
158  }
159  }
160  }
161 
162  return bField;
163 }
164 
165 
166 void BFieldComponentKlm1::terminate()
167 {
168 }
Belle2::B2Vector3::Perp
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
Definition: B2Vector3.h:199
Belle2::B2Vector3::Z
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:434
Belle2::B2Vector3::SetY
void SetY(DataType y)
set Y/2nd-coordinate
Definition: B2Vector3.h:454
Belle2::B2Vector3< double >
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::B2Vector3::X
DataType X() const
access variable X (= .at(0) without boundary check)
Definition: B2Vector3.h:430
Belle2::B2Vector3::SetXYZ
void SetXYZ(DataType x, DataType y, DataType z)
set all coordinates using data type
Definition: B2Vector3.h:459
Belle2::B2Vector3::SetZ
void SetZ(DataType z)
set Z/3rd-coordinate
Definition: B2Vector3.h:456
Belle2::B2Vector3::Y
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:432
Belle2::B2Vector3::SetX
void SetX(DataType x)
set X/1st-coordinate
Definition: B2Vector3.h:452