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