Belle II Software  release-06-01-15
PhotonState.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 <top/reconstruction_cpp/PhotonState.h>
10 #include <top/reconstruction_cpp/func.h>
11 #include <framework/logging/Logger.h>
12 #include <cmath>
13 #include <algorithm>
14 
15 using namespace std;
16 
17 namespace Belle2 {
22  namespace TOP {
23 
24  double PhotonState::s_maxLen = 10000;
25 
26  PhotonState::PhotonState(const TVector3& position, const TVector3& direction):
27  m_x(position.X()), m_y(position.Y()), m_z(position.Z()),
28  m_kx(direction.X()), m_ky(direction.Y()), m_kz(direction.Z()),
29  m_status(true)
30  {}
31 
32 
33  PhotonState::PhotonState(const TVector3& position, double kx, double ky, double kz):
34  m_x(position.X()), m_y(position.Y()), m_z(position.Z()),
35  m_kx(kx), m_ky(ky), m_kz(kz),
36  m_status(true)
37  {}
38 
39  PhotonState::PhotonState(const TVector3& position, const TVector3& trackDir, double thc, double fic):
40  m_x(position.X()), m_y(position.Y()), m_z(position.Z()),
41  m_status(true)
42  {
43  TVector3 dir(cos(fic) * sin(thc), sin(fic) * sin(thc), cos(thc));
44  dir.RotateUz(trackDir);
45  m_kx = dir.X();
46  m_ky = dir.Y();
47  m_kz = dir.Z();
48  }
49 
51  {
52  if (abs(m_x) > bar.A / 2) return false;
53  if (abs(m_y) > bar.B / 2) return false;
54  if (m_z < bar.zL or m_z > bar.zR) return false;
55  return true;
56  }
57 
58 
60  {
61  if (abs(m_x) > bar.A / 2) return false;
62  if (abs(m_y) > bar.B / 2) return false;
63  if (m_z < bar.zL) return false;
64  double Rsq = pow(m_x - mirror.xc, 2) + pow(m_y - mirror.yc, 2) + pow(m_z - mirror.zc, 2);
65  if (Rsq > pow(mirror.R, 2)) return false;
66  return true;
67  }
68 
69 
71  {
72  if (abs(m_x) > prism.A / 2) return false;
73  if (m_z < prism.zL or m_z > prism.zR) return false;
74  if (m_y > prism.yUp or m_y < prism.yDown) return false;
75  double y = prism.yDown + (prism.yDown + prism.B / 2) / (prism.zFlat - prism.zR) * (m_z - prism.zFlat);
76  if (m_y < y) return false;
77  return true;
78  }
79 
80 
82  {
83  if (not m_status) return;
84 
85  m_cosx = abs(m_kx);
86  m_cosy = abs(m_ky);
87  m_A = bar.A;
88  m_B = bar.B;
90 
91  double z = bar.zR;
92  if (m_kz < 0) z = bar.zL;
93  if (z == m_z) return;
94 
95  m_status = false;
96 
97  double len = (z - m_z) / m_kz;
98  if (len < 0 or len > s_maxLen) return;
99  m_propLen += len;
100 
101  func::fold(m_x + len * m_kx, bar.A, m_x, m_kx, m_nx);
102  func::fold(m_y + len * m_ky, bar.B, m_y, m_ky, m_ny);
103  m_z = z;
104 
105  m_status = true;
106  }
107 
108 
110  {
111  if (not m_status) return;
112 
113  m_cosx = abs(m_kx);
114  m_cosy = abs(m_ky);
115  m_A = bar.A;
116  m_B = bar.B;
118 
119  m_status = false;
120 
121  if (m_kz < 0) return;
122 
123  double len = 0;
124  if (m_z < mirror.zb) {
125  len = (mirror.zb - m_z) / m_kz;
126  if (len > s_maxLen) return;
127  }
128 
129  double xm = m_x + len * m_kx;
130  int nx = lround(xm / bar.A);
131  double ss = m_kx * m_kx + m_kz * m_kz;
132  if (ss == 0) return;
133  int i = 0;
134  while (true) {
135  double xc = func::unfold(mirror.xc, nx, bar.A);
136  double x = m_x - xc;
137  double z = m_z - mirror.zc;
138  double rdir = x * m_kx + z * m_kz;
139  double rr = x * x + z * z;
140  double D = rdir * rdir + (mirror.R * mirror.R - rr) * ss;
141  if (D < 0) return;
142  D = sqrt(D);
143  len = (D - rdir) / ss;
144  if (len < 0 or len > s_maxLen) return;
145  double xmm = m_x + len * m_kx;
146  int nxx = lround(xmm / bar.A);
147  if (nxx == nx) break;
148  i++;
149  if (i == 10) {
150  if (abs(xmm - xm) < 0.001) break;
151  B2DEBUG(20, "TOP::PhotonState::propagateSemiLinear: not converging");
152  return;
153  }
154  nx = nxx;
155  xm = xmm;
156  }
157 
158  m_propLen += len;
159 
160  func::fold(m_x + len * m_kx, bar.A, m_x, m_kx, m_nx);
161  func::fold(m_y + len * m_ky, bar.B, m_y, m_ky, m_ny);
162  m_y = mirror.yc;
163  m_z += len * m_kz;
164 
165  double normX = (m_x - mirror.xc) / mirror.R;
166  double normZ = (m_z - mirror.zc) / mirror.R;
167  double s = 2 * (m_kx * normX + m_kz * normZ);
168  m_kx -= s * normX;
169  m_kz -= s * normZ;
170 
171  m_status = true;
172  }
173 
174 
176  {
177  if (not m_status) return;
178 
179  m_cosx = abs(m_kx);
180  m_cosy = abs(m_ky);
181  m_A = bar.A;
182  m_B = bar.B;
184 
185  m_status = false;
186 
187  if (m_kz < 0) return;
188 
189  double len = 0;
190  if (m_z < mirror.zb) {
191  len = (mirror.zb - m_z) / m_kz;
192  if (len > s_maxLen) return;
193  }
194 
195  double xm = m_x + len * m_kx;
196  int nx = lround(xm / bar.A);
197  double ym = m_y + len * m_ky;
198  int ny = lround(ym / bar.B);
199  int i = 0;
200  while (true) {
201  double xc = func::unfold(mirror.xc, nx, bar.A);
202  double yc = func::unfold(mirror.yc, ny, bar.B);
203  double x = m_x - xc;
204  double y = m_y - yc;
205  double z = m_z - mirror.zc;
206  double rdir = x * m_kx + y * m_ky + z * m_kz;
207  double rr = x * x + y * y + z * z;
208  double D = rdir * rdir + (mirror.R * mirror.R - rr);
209  if (D < 0) return;
210  D = sqrt(D);
211  len = (D - rdir);
212  if (len < 0 or len > s_maxLen) return;
213  double xmm = m_x + len * m_kx;
214  int nxx = lround(xmm / bar.A);
215  double ymm = m_y + len * m_ky;
216  int nyy = lround(ymm / bar.B);
217  if (nxx == nx and nyy == ny) break;
218  i++;
219  if (i == 10) {
220  if (abs(xmm - xm) < 0.001 and abs(ymm - ym) < 0.001) break;
221  B2DEBUG(20, "TOP::PhotonState::propagateExact: not converging");
222  return;
223  }
224  nx = nxx;
225  ny = nyy;
226  }
227 
228  m_propLen += len;
229 
230  func::fold(m_x + len * m_kx, bar.A, m_x, m_kx, m_nx);
231  func::fold(m_y + len * m_ky, bar.B, m_y, m_ky, m_ny);
232  m_z += len * m_kz;
233 
234  double normX = (m_x - mirror.xc) / mirror.R;
235  double normY = (m_y - mirror.yc) / mirror.R;
236  double normZ = (m_z - mirror.zc) / mirror.R;
237  double s = 2 * (m_kx * normX + m_ky * normY + m_kz * normZ);
238  m_kx -= s * normX;
239  m_ky -= s * normY;
240  m_kz -= s * normZ;
241 
242  m_status = true;
243  }
244 
245 
247  {
248  if (not m_status) return;
249 
250  m_status = false;
251 
252  m_cosx = abs(m_kx);
253  m_A = prism.A;
254  m_B = prism.yUp - prism.yDown;
255  m_y0 = (prism.yUp + prism.yDown) / 2;
256  m_type = c_Prism;
257 
258  if (m_kz > 0) {
259  if (m_z >= prism.zR or abs(m_ky / m_kz) < abs(prism.slope)) return;
260  if (abs(m_y + m_ky / m_kz * (prism.zR - m_z)) < prism.B / 2) return;
261  }
262  double ky_in = m_ky;
263  double kz_in = m_kz;
264 
265  if (m_z > prism.zFlat) {
266 
267  int step = 1;
268  int ii = 0;
269  if (m_ky < 0) {
270  step = -1;
271  ii = 1;
272  m_y = std::min(m_y, prism.yUp);
273  }
274 
275  unsigned k = prism.k0;
276  while (k < prism.unfoldedWindows.size()) {
277  const auto& win = prism.unfoldedWindows[k];
278  double s = m_ky * win.sz - m_kz * win.sy;
279  if (s == 0) {
280  k += step;
281  ii = (ii + 1) % 2;
282  continue;
283  }
284  double len = ((win.y0 - m_y) * win.sz - (win.z0 - m_z) * win.sy) / s;
285  m_yD = m_y + len * m_ky;
286  m_zD = m_z + len * m_kz;
287  double yu = m_yD - win.y0;
288  double zu = m_zD - win.z0;
289  double y = yu * win.sy + zu * win.sz;
290  if (y >= prism.yDown and y <= prism.yUp) {
291  if (len < 0 or len > s_maxLen) return;
292  double ky = m_ky * win.sy + m_kz * win.sz;
293  double kz = m_kz * win.sy - m_ky * win.sz;
294  m_x += len * m_kx;
295  m_y = y;
296  m_ky = ky;
297  m_ny = k - prism.k0;
298  m_z = prism.zFlat;
299  m_kz = m_ny % 2 == 0 ? kz : -kz;
300  m_propLen += len;
301  goto success;
302  }
303  m_cosy = std::max(m_cosy, abs(ky_in * win.nsy[ii] + kz_in * win.nsz[ii]));
304  k += step;
305  ii = (ii + 1) % 2;
306  }
307  B2DEBUG(20, "TOP::PhotonState::propagate: unfolded prism window not found"
308  << LogVar("yUp", prism.yUp) << LogVar("yDown", prism.yDown) << LogVar("zR", prism.zR)
309  << LogVar("y", m_y) << LogVar("z", m_z)
310  << LogVar("ky", ky_in) << LogVar("kz", kz_in));
311  return;
312  } else {
313  m_yD = m_y;
314  m_zD = m_z;
315  }
316 
317 success:
318  double len = (prism.zD - m_z) / m_kz;
319  if (len < 0 or len > s_maxLen) return;
320  func::fold(m_x + len * m_kx, prism.A, m_x, m_kx, m_nx);
321  m_y += len * m_ky;
322  m_z = prism.zD;
323  m_propLen += len;
324  m_yD += len * ky_in;
325  m_zD += len * kz_in;
326 
327  m_status = true;
328  }
329 
330 
331  } // namespace TOP
333 } // namespace Belle2
334 
335 
double m_y0
origin in y for unfolding
Definition: PhotonState.h:285
EType m_type
quartz segment type at last propagation step
Definition: PhotonState.h:288
double m_cosy
maximal cosine of impact angle to surface in y
Definition: PhotonState.h:282
int m_nx
signed number of reflections in x at last propagation step
Definition: PhotonState.h:279
double m_zD
unfolded prism detection position in z
Definition: PhotonState.h:287
void propagate(const RaytracerBase::BarSegment &bar)
Propagate photon to the exit of bar segment.
Definition: PhotonState.cc:81
double m_x
position in x
Definition: PhotonState.h:272
static double s_maxLen
maximal allowed propagation length
Definition: PhotonState.h:291
PhotonState()
Default constructor.
Definition: PhotonState.h:42
double m_ky
direction in y
Definition: PhotonState.h:276
double m_A
width of the quartz segment (dimension in x) for unfolding
Definition: PhotonState.h:283
double m_cosx
maximal cosine of impact angle to surface in x
Definition: PhotonState.h:281
int m_ny
signed number of reflections in y at last propagation step
Definition: PhotonState.h:280
double m_kx
direction in x
Definition: PhotonState.h:275
double m_yD
unfolded prism detection position in y
Definition: PhotonState.h:286
double m_B
thickness of the quartz segment (dimension in y) for unfolding
Definition: PhotonState.h:284
bool m_status
propagation status
Definition: PhotonState.h:289
void propagateSemiLinear(const RaytracerBase::BarSegment &bar, const RaytracerBase::Mirror &mirror)
Propagate photon to the mirror and reflect it using semi-linear mirror optics.
Definition: PhotonState.cc:109
double m_z
position in z
Definition: PhotonState.h:274
@ c_BarSegment
bar segment
Definition: PhotonState.h:34
@ c_MirrorSegment
mirror segment
Definition: PhotonState.h:35
double m_y
position in y
Definition: PhotonState.h:273
double m_propLen
propagation length since initial position
Definition: PhotonState.h:278
void propagateExact(const RaytracerBase::BarSegment &bar, const RaytracerBase::Mirror &mirror)
Propagate photon to the mirror and reflect it using exact mirror optics.
Definition: PhotonState.cc:175
bool isInside(const RaytracerBase::BarSegment &bar) const
Checks if photon is inside the bar segment (including surface).
Definition: PhotonState.cc:50
double m_kz
direction in z
Definition: PhotonState.h:277
Class to store variables with their name which were sent to the logging service.
double unfold(double x, int nx, double A)
unfold a coordinate.
Definition: func.h:29
void fold(double xu, double A, double &x, double &kx, int &nx)
fold a coordinate (inverse of unfold).
Definition: func.h:57
Abstract base class for different kinds of events.
bar segment data in module local frame.
Definition: RaytracerBase.h:49
double A
width (dimension in x)
Definition: RaytracerBase.h:50
double B
thickness (dimension in y)
Definition: RaytracerBase.h:51
spherical mirror data in module local frame.
Definition: RaytracerBase.h:79
double yc
center of curvature in y
Definition: RaytracerBase.h:81
double xc
center of curvature in x
Definition: RaytracerBase.h:80
double zb
minimum of mirror surface in z
Definition: RaytracerBase.h:84
double zc
center of curvature in z
Definition: RaytracerBase.h:82
prism data in module local frame.
double A
width (dimension in x)
std::vector< TOPGeoPrism::UnfoldedWindow > unfoldedWindows
unfolded prism exit windows
double yDown
minimal y of exit window
double slope
slope of slanted surface (dy/dz)
double yUp
maximal y of exit window
double zFlat
z where flat continues to slanted surface
double zR
maximal z, i.e position of prism-bar joint
double B
thickness at bar (dimension in y)
double zD
detector (photo-cathode) position
int k0
index of true prism in the vector 'unfoldedWindows'