Belle II Software development
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
15using namespace std;
16
17namespace 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
318success:
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:283
EType m_type
quartz segment type at last propagation step
Definition: PhotonState.h:286
double m_cosy
maximal cosine of impact angle to surface in y
Definition: PhotonState.h:280
int m_nx
signed number of reflections in x at last propagation step
Definition: PhotonState.h:277
double m_zD
unfolded prism detection position in z
Definition: PhotonState.h:285
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:270
static double s_maxLen
maximal allowed propagation length
Definition: PhotonState.h:289
PhotonState()
Default constructor.
Definition: PhotonState.h:44
double m_ky
direction in y
Definition: PhotonState.h:274
double m_A
width of the quartz segment (dimension in x) for unfolding
Definition: PhotonState.h:281
double m_cosx
maximal cosine of impact angle to surface in x
Definition: PhotonState.h:279
int m_ny
signed number of reflections in y at last propagation step
Definition: PhotonState.h:278
double m_kx
direction in x
Definition: PhotonState.h:273
double m_yD
unfolded prism detection position in y
Definition: PhotonState.h:284
double m_B
thickness of the quartz segment (dimension in y) for unfolding
Definition: PhotonState.h:282
bool m_status
propagation status
Definition: PhotonState.h:287
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:272
@ 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:271
double m_propLen
propagation length since initial position
Definition: PhotonState.h:276
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:275
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 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
void fold(double xu, double A, double &x, double &kx, int &nx)
fold a coordinate (inverse of unfold).
Definition: func.h:59
Abstract base class for different kinds of events.
STL namespace.
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'