CHeT Library
Loading...
Searching...
No Matches
CHeTGlobalSettings.cc
Go to the documentation of this file.
2
3// Standard TMath or cmath defines check
4#ifndef M_PI
5#define M_PI 3.14159265358979323846
6#endif
7
8namespace CHeT
9{
10namespace Config
11{
12
13// --- Internal Data Structures (Hidden from Header) ---
14
15// Backing variables for geometry settings
16static double g_OFFSET_EXP = 40.0 * (M_PI / 180.0);
17static std::vector<double> g_DELTAS = { 1.267, 1.420 + (18.0 * M_PI / 180.0), 0.0, 0.0, 0.0, 0.0 };
18static bool g_GeometryDirty = true;
19static std::vector<CylinderConfig> g_Cylinders;
20
21// Rotation Globals (Euler angles in radians)
22static double g_RotX = 0.0;
23static double g_RotY = 0.0;
24static double g_RotZ = 0.0;
25// Precomputed Rotation Matrix (Local -> Global)
26static double g_R[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
27static bool g_IsRotated = false;
28
29// Translation Globals [mm]
30static double g_TransX = 0.0;
31static double g_TransY = 0.0;
32static double g_TransZ = 0.0;
33
34// Static map for board offsets
35static std::vector<int> g_ActiveCylinders;
36
37static const std::map<int, int> BOARD_OFFSETS = {
38 { 0, 0 }, // Board 0: Cylinder 0 (Inner)
39 { 1, 0 }, // Board 1: Cylinder 0 (Outer)
40 { 2, 94 }, // Board 2: After Cylinder 0 (45+49)
41 { 3, 94 } // Board 3: After Cylinder 0
42 //{4, 213}, // Board 4: Hypothetical Cyl 2 (94+119)
43};
44
45// Huge map for channel mapping. Defined here to keep header clean.
46static const std::map<int, std::map<int, int>> BOARD_MAPS = {
47 { 0,
48 { { 31, 0 }, { 27, 1 }, { 23, 2 }, { 19, 3 }, { 15, 4 }, { 11, 5 }, { 7, 6 }, { 3, 7 },
49 { 29, 8 }, { 25, 9 }, { 21, 10 }, { 17, 11 }, { 13, 12 }, { 9, 13 }, { 5, 14 },
50 { 1, 15 }, { 0, 16 }, { 4, 17 }, { 8, 18 }, { 12, 19 }, { 16, 20 }, { 20, 21 },
51 { 24, 22 }, { 28, 23 }, { 2, 24 }, { 6, 25 }, { 10, 26 }, { 14, 27 }, { 18, 28 },
52 { 22, 29 }, { 26, 30 }, { 30, 31 }, { 32, 32 }, { 36, 33 }, { 40, 34 }, { 44, 35 },
53 { 48, 36 }, { 52, 37 }, { 56, 38 }, { 60, 39 }, { 34, 40 }, { 38, 41 }, { 42, 42 },
54 { 46, 43 }, { 50, 44 }, { 54, 45 }, { 58, 46 }, { 62, 47 } } },
55 { 1,
56 { { 31, 48 }, { 27, 49 }, { 23, 50 }, { 19, 51 }, { 15, 52 }, { 11, 53 }, { 7, 54 },
57 { 3, 55 }, { 29, 56 }, { 25, 57 }, { 21, 58 }, { 17, 59 }, { 13, 60 }, { 9, 61 },
58 { 5, 62 }, { 1, 63 }, { 0, 64 }, { 4, 65 }, { 8, 66 }, { 12, 67 }, { 16, 68 },
59 { 20, 69 }, { 24, 70 }, { 28, 71 }, { 2, 72 }, { 6, 73 }, { 10, 74 }, { 14, 75 },
60 { 18, 76 }, { 22, 77 }, { 26, 78 }, { 30, 79 }, { 32, 80 }, { 36, 81 }, { 40, 82 },
61 { 44, 83 }, { 48, 84 }, { 52, 85 }, { 56, 86 }, { 60, 87 }, { 34, 88 }, { 38, 89 },
62 { 42, 90 }, { 46, 91 }, { 50, 92 }, { 54, 93 } } },
63 { 2,
64 { { 31, 0 }, { 27, 1 }, { 23, 2 }, { 19, 3 }, { 15, 4 }, { 11, 5 }, { 7, 6 }, { 3, 7 },
65 { 29, 8 }, { 25, 9 }, { 21, 10 }, { 17, 11 }, { 13, 12 }, { 9, 13 }, { 5, 14 },
66 { 1, 15 }, { 0, 16 }, { 4, 17 }, { 8, 18 }, { 12, 19 }, { 16, 20 }, { 20, 21 },
67 { 24, 22 }, { 28, 23 }, { 2, 24 }, { 6, 25 }, { 10, 26 }, { 14, 27 }, { 18, 28 },
68 { 22, 29 }, { 26, 30 }, { 30, 31 }, { 63, 32 }, { 59, 33 }, { 55, 34 }, { 51, 35 },
69 { 47, 36 }, { 43, 37 }, { 39, 38 }, { 35, 39 }, { 61, 40 }, { 57, 41 }, { 53, 42 },
70 { 49, 43 }, { 45, 44 }, { 41, 45 }, { 37, 46 }, { 33, 47 }, { 32, 48 }, { 36, 49 },
71 { 40, 50 }, { 44, 51 }, { 48, 52 }, { 52, 53 }, { 56, 54 }, { 60, 55 }, { 34, 56 },
72 { 38, 57 }, { 42, 58 }, { 46, 59 }, { 50, 60 }, { 54, 61 }, { 58, 62 }, { 62, 63 } } },
73 { 3,
74 { { 31, 64 }, { 27, 65 }, { 23, 66 }, { 19, 67 }, { 15, 68 }, { 11, 69 }, { 7, 70 },
75 { 3, 71 }, { 29, 72 }, { 25, 73 }, { 21, 74 }, { 17, 75 }, { 13, 76 }, { 9, 77 },
76 { 5, 78 }, { 1, 79 }, { 0, 80 }, { 4, 81 }, { 8, 82 }, { 12, 83 }, { 16, 84 },
77 { 20, 85 }, { 24, 86 }, { 28, 87 }, { 2, 88 }, { 6, 89 }, { 10, 90 }, { 14, 91 },
78 { 18, 92 }, { 22, 93 }, { 26, 94 }, { 30, 95 }, { 63, 96 }, { 59, 97 }, { 55, 98 },
79 { 51, 99 }, { 47, 100 }, { 43, 101 }, { 39, 102 }, { 35, 103 }, { 61, 104 },
80 { 57, 105 }, { 53, 106 }, { 49, 107 }, { 45, 108 }, { 41, 109 }, { 37, 110 },
81 { 33, 111 }, { 32, 112 }, { 36, 113 }, { 40, 114 }, { 44, 115 }, { 48, 116 },
82 { 52, 117 }, { 56, 118 } } }
83};
84
85// --- Implementation ---
86
88{
89 return g_OFFSET_EXP;
90}
91void SetOffsetExp(double val)
92{
93 g_OFFSET_EXP = val;
94 g_GeometryDirty = true;
95}
96
97double GetDeltaI(int cylIdx)
98{
99 if(cylIdx >= 0 && cylIdx < g_DELTAS.size())
100 return g_DELTAS[cylIdx];
101 return 0.0;
102}
103
104void SetDeltaI(int cylIdx, double val)
105{
106 if(cylIdx >= 0 && cylIdx < g_DELTAS.size())
107 {
108 g_DELTAS[cylIdx] = val;
109 g_GeometryDirty = true;
110 }
111}
112
113void SetDeltas(const std::vector<double> &deltas)
114{
115 g_DELTAS = deltas;
116 // ensure it has at least 6 elements
117 if(g_DELTAS.size() < 6)
118 g_DELTAS.resize(6, 0.0);
119 g_GeometryDirty = true;
120}
121
122std::vector<double> GetDeltas()
123{
124 return g_DELTAS;
125}
126
127void SetRotation(double rx, double ry, double rz)
128{
129 g_RotX = rx;
130 g_RotY = ry;
131 g_RotZ = rz;
132 g_IsRotated = (std::abs(rx) > 1e-9 || std::abs(ry) > 1e-9 || std::abs(rz) > 1e-9);
133
134 if(g_IsRotated)
135 {
136 double cx = std::cos(rx), sx = std::sin(rx);
137 double cy = std::cos(ry), sy = std::sin(ry);
138 double cz = std::cos(rz), sz = std::sin(rz);
139
140 // Calculate Rotation Matrix Columns by transforming basis vectors
141 auto rotate = [&](double x, double y, double z, double &ox, double &oy, double &oz)
142 {
143 // Rx
144 double y1 = y * cx - z * sx;
145 double z1 = y * sx + z * cx;
146 double x1 = x;
147 // Ry
148 double z2 = z1 * cy - x1 * sy;
149 double x2 = z1 * sy + x1 * cy;
150 double y2 = y1;
151 // Rz
152 double x3 = x2 * cz - y2 * sz;
153 double y3 = x2 * sz + y2 * cz;
154 double z3 = z2;
155 ox = x3;
156 oy = y3;
157 oz = z3;
158 };
159
160 // Col 0
161 rotate(1, 0, 0, g_R[0][0], g_R[1][0], g_R[2][0]);
162 // Col 1
163 rotate(0, 1, 0, g_R[0][1], g_R[1][1], g_R[2][1]);
164 // Col 2
165 rotate(0, 0, 1, g_R[0][2], g_R[1][2], g_R[2][2]);
166 }
167 else
168 {
169 // Identity
170 g_R[0][0] = 1;
171 g_R[0][1] = 0;
172 g_R[0][2] = 0;
173 g_R[1][0] = 0;
174 g_R[1][1] = 1;
175 g_R[1][2] = 0;
176 g_R[2][0] = 0;
177 g_R[2][1] = 0;
178 g_R[2][2] = 1;
179 }
180}
181
182void GetRotation(double &rx, double &ry, double &rz)
183{
184 rx = g_RotX;
185 ry = g_RotY;
186 rz = g_RotZ;
187}
188
189void SetTranslation(double tx, double ty, double tz)
190{
191 g_TransX = tx;
192 g_TransY = ty;
193 g_TransZ = tz;
194}
195
196void GetTranslation(double &tx, double &ty, double &tz)
197{
198 tx = g_TransX;
199 ty = g_TransY;
200 tz = g_TransZ;
201}
202
203void ApplyRotation(double &x, double &y, double &z)
204{
205 if(!g_IsRotated)
206 return;
207
208 double xn = g_R[0][0] * x + g_R[0][1] * y + g_R[0][2] * z;
209 double yn = g_R[1][0] * x + g_R[1][1] * y + g_R[1][2] * z;
210 double zn = g_R[2][0] * x + g_R[2][1] * y + g_R[2][2] * z;
211
212 x = xn;
213 y = yn;
214 z = zn;
215}
216
217void ApplyInverseRotation(double &x, double &y, double &z)
218{
219 if(!g_IsRotated)
220 return;
221
222 // Transpose multiplication
223 double xn = g_R[0][0] * x + g_R[1][0] * y + g_R[2][0] * z;
224 double yn = g_R[0][1] * x + g_R[1][1] * y + g_R[2][1] * z;
225 double zn = g_R[0][2] * x + g_R[1][2] * y + g_R[2][2] * z;
226
227 x = xn;
228 y = yn;
229 z = zn;
230}
231
232void ApplyTransformation(double &x, double &y, double &z)
233{
234 // 1. Rotation (Local -> Aligned Global)
235 ApplyRotation(x, y, z);
236
237 // 2. Translation (Aligned Global -> Global)
238 x += g_TransX;
239 y += g_TransY;
240 z += g_TransZ;
241}
242
243void ApplyInverseTransformation(double &x, double &y, double &z)
244{
245 // 1. Inverse Translation (Global -> Aligned Global)
246 x -= g_TransX;
247 y -= g_TransY;
248 z -= g_TransZ;
249
250 // 2. Inverse Rotation (Aligned Global -> Local)
251 ApplyInverseRotation(x, y, z);
252}
253
254int GetBoardGlobalOffset(int board_id)
255{
256 auto it = BOARD_OFFSETS.find(board_id);
257 if(it != BOARD_OFFSETS.end())
258 return it->second;
259
260 // Placeholder for new cylinders (approximate continuation)
261 // Cylinder 0+1 end at 94 + 119 = 213
262 if(board_id >= 4)
263 {
264 return 213 + (board_id - 4) * 64;
265 }
266 return -1;
267}
268
269void SetActiveCylinders(const std::vector<int> &active_ids)
270{
271 g_ActiveCylinders = active_ids;
272 g_GeometryDirty = true;
273}
274
275std::vector<int> GetActiveCylinders()
276{
277 if(g_ActiveCylinders.empty())
278 return { 0, 1, 2, 3, 4, 5 };
279 return g_ActiveCylinders;
280}
281
282const std::vector<CylinderConfig> &GetCylinders()
283{
284 if(g_GeometryDirty || g_Cylinders.empty())
285 {
286 g_Cylinders.clear();
287
288 // Check which cylinders are active (empty means all)
289 auto &active = g_ActiveCylinders;
290 auto isActive = [&](int id)
291 {
292 if(active.empty())
293 return true;
294 return std::find(active.begin(), active.end(), id) != active.end();
295 };
296
297 // Full definition
298 std::vector<CylinderConfig> all
299 = { {
300 0, 17.0, // Cylinder 1 (id, nominalRadius)
301 { 45, 16.8, 0.5, 4.294 + g_DELTAS[0] + g_OFFSET_EXP, -1, GetStereoAngle(16.8),
302 632 }, // Inner (Red)
303 { 49, 17.45, 0.5, 3.829 + g_DELTAS[0] + g_OFFSET_EXP, 1, GetStereoAngle(17.45),
304 807 } // Outer (Orange)
305 },
306 {
307 1, 21.0, // Cylinder 2
308 { 59, 20.8, 0.5, 2.609 + g_DELTAS[1] + g_OFFSET_EXP, -1, GetStereoAngle(20.8),
309 600 }, // Inner (Blue)
310 { 60, 21.45, 0.5, 3.351 + g_DELTAS[1] + g_OFFSET_EXP, 1,
311 GetStereoAngle(21.45), 432 } // Outer (Cyan)
312 },
313 {
314 2, 37.0, // Cylinder 3
315 { 96, 36.8, 0.5, g_DELTAS[2] + g_OFFSET_EXP, -1, GetStereoAngle(36.8),
316 418 }, // Inner (Dark Green)
317 { 96, 37.45, 0.5, g_DELTAS[2] + g_OFFSET_EXP, 1, GetStereoAngle(37.45),
318 817 } // Outer (Light Green)
319 },
320 {
321 3, 65.0, // Cylinder 4
322 { 151, 64.8, 0.5, g_DELTAS[3] + g_OFFSET_EXP, -1, GetStereoAngle(64.8),
323 882 }, // Inner (Dark Violet)
324 { 152, 65.45, 0.5, g_DELTAS[3] + g_OFFSET_EXP, 1, GetStereoAngle(65.45),
325 609 } // Outer (Pink)
326 },
327 {
328 4, 69.0, // Cylinder 5
329 { 160, 68.8, 0.5, g_DELTAS[4] + g_OFFSET_EXP, -1, GetStereoAngle(68.8),
330 803 }, // Inner (Brown)
331 { 162, 69.45, 0.5, g_DELTAS[4] + g_OFFSET_EXP, 1, GetStereoAngle(69.45),
332 805 } // Outer (Light Brown)
333 },
334 {
335 5, 73.0, // Cylinder 6
336 { 170, 72.8, 0.5, g_DELTAS[5] + g_OFFSET_EXP, -1, GetStereoAngle(72.8),
337 923 }, // Inner (Dark Gray)
338 { 171, 73.45, 0.5, g_DELTAS[5] + g_OFFSET_EXP, 1, GetStereoAngle(73.45),
339 921 } // Outer (Silver)
340 } };
341
342 // Filter active cylinders
343 for(const auto &c : all)
344 {
345 if(isActive(c.id))
346 {
347 g_Cylinders.push_back(c);
348 }
349 }
350 g_GeometryDirty = false;
351 }
352 return g_Cylinders;
353}
354
355double wrap0_2pi(double angle)
356{
357 double wrapped = std::fmod(angle, 2.0 * M_PI);
358 if(wrapped < 0)
359 wrapped += 2.0 * M_PI;
360 return wrapped;
361}
362
364{
365 const auto &cylinders = GetCylinders();
366 int offset = 0;
367
368 for(const auto &cyl : cylinders)
369 {
370 // Check Inner
371 if(b_id < offset + cyl.inner.nBundles)
372 {
373 int b_loc = b_id - offset;
374 return { cyl.id, 0, cyl.inner.radius,
375 wrap0_2pi(2.0 * M_PI * (-b_loc) / cyl.inner.nBundles + cyl.inner.phiOffset),
376 cyl.inner.direction, cyl.inner.color };
377 }
378 offset += cyl.inner.nBundles;
379
380 // Check Outer
381 if(b_id < offset + cyl.outer.nBundles)
382 {
383 int b_loc = b_id - offset;
384 return { cyl.id, 1, cyl.outer.radius,
385 wrap0_2pi(2.0 * M_PI * (b_loc) / cyl.outer.nBundles + cyl.outer.phiOffset),
386 cyl.outer.direction, cyl.outer.color };
387 }
388 offset += cyl.outer.nBundles;
389 }
390 // Return invalid prop
391 return { -1, -1, 0, 0, 0, 0 };
392}
393
394int GetGlobalBundleId(int board_id, int channel_id)
395{
396 int local_val = -1;
397
398 auto boardMapIt = BOARD_MAPS.find(board_id);
399 if(boardMapIt != BOARD_MAPS.end())
400 {
401 auto chanIt = boardMapIt->second.find(channel_id);
402 if(chanIt != boardMapIt->second.end())
403 {
404 local_val = chanIt->second;
405 }
406 }
407 else
408 {
409 // Placeholder 1-1 mapping for future boards
410 local_val = channel_id;
411 }
412
413 if(local_val == -1)
414 return -1;
415
416 // Get board offset
417 // Apply offset
418 int boardOffset = GetBoardGlobalOffset(board_id);
419 if(boardOffset == -1)
420 return -1;
421
422 return local_val + boardOffset;
423}
424
425std::vector<BundlesIntersection> FindIntersections(const std::vector<int> &hit_ids)
426{
427 std::vector<BundlesIntersection> out;
428 // Optimization: reserve memory if hits are many, though tricky to guess how
429 // many intersections
430
431 for(size_t i = 0; i < hit_ids.size(); ++i)
432 {
433 for(size_t j = i + 1; j < hit_ids.size(); ++j)
434 {
435 FiberProp p1 = GetFiberProp(hit_ids[i]);
436 FiberProp p2 = GetFiberProp(hit_ids[j]);
437
438 // Intersection logic: Same cylinder, different layers
439 if(p1.cylinderId == p2.cylinderId && p1.cylinderId != -1 && p1.layerId != p2.layerId)
440 {
441 double dphi0 = p2.phi0 - p1.phi0;
442 double ddir = p1.dir - p2.dir;
443
444 // Typical case: +1 vs -1 -> diff is 2 or -2.
445 // Loop over possible periodic intersections
446 for(int k = -2; k <= 2; ++k)
447 {
448 // Avoid division by zero
449 if(std::abs(ddir) < 1e-9)
450 continue;
451
452 double alpha = (dphi0 + 2.0 * k * M_PI) / (ddir * M_PI);
453
454 if(alpha >= 0.0 && alpha <= 1.0)
455 {
456 double zi = alpha * (2.0 * L_HALF) - L_HALF;
457 double ph = p1.phi0 + p1.dir * alpha * M_PI;
458
459 // Z Thickness Calculation
460 // DeltaZ depends on Bundle Width and Helix slope.
461 double deltaZ = (BUNDLE_WIDTH / p1.r) * (L_HALF / M_PI);
462
463 // Calculate local coordinates
464 double x_loc = p1.r * std::cos(ph);
465 double y_loc = p1.r * std::sin(ph);
466 double z_loc = zi;
467
468 // Apply global rotation (to copies)
469 double x_rot = x_loc;
470 double y_rot = y_loc;
471 double z_rot = z_loc;
472 ApplyTransformation(x_rot, y_rot, z_rot);
473
474 out.push_back(
475 { z_rot, x_rot, y_rot, z_loc, x_loc, y_loc, p1.cylinderId, deltaZ });
476 }
477 }
478 }
479 }
480 }
481 return out;
482}
483
484// --- Debug / Helper Functions Implementation ---
485
486int GetGlobalIdFromGeometry(int cyl_id, int layer_id, int layer_idx)
487{
488 const auto &cylinders = GetCylinders();
489 int global_offset = 0;
490
491 for(const auto &cyl : cylinders)
492 {
493 if(cyl.id == cyl_id)
494 {
495 // Check limits
496 int limit = (layer_id == 0) ? cyl.inner.nBundles : cyl.outer.nBundles;
497
498 if(layer_idx < 0 || layer_idx >= limit)
499 {
500 std::cerr << " [ERROR] Index " << layer_idx << " out of range for Cylinder "
501 << cyl_id << " Layer " << layer_id << "!\n";
502 return -1;
503 }
504
505 // Calculate ID: Offset + Local Base + Index
506 int local_base = (layer_id == 0) ? 0 : cyl.inner.nBundles;
507 return global_offset + local_base + layer_idx;
508 }
509 // Accumulate offset if not current cylinder
510 global_offset += (cyl.inner.nBundles + cyl.outer.nBundles);
511 }
512 return -1; // Cylinder not found
513}
514
515void PrintBundleMapping(int global_id)
516{
517 if(global_id < 0)
518 return;
519
520 std::cout << "\n >>> INFO BUNDLE ID: " << global_id << " <<<\n";
521
522 // A. Check Hardware Mapping
523 bool found_hw = false;
524 for(auto const &[board, map] : BOARD_MAPS)
525 {
526 int off = GetBoardGlobalOffset(board);
527 if(off < 0)
528 continue;
529
530 // Reverse lookup: value == global_id - offset
531 int target_local = global_id - off;
532
533 for(auto const &[chan, val] : map)
534 {
535 if(val == target_local)
536 {
537 std::cout << " [HARDWARE] Board: " << board << " | Channel: " << chan << "\n";
538 found_hw = true;
539 break;
540 }
541 }
542 if(found_hw)
543 break;
544 }
545 if(!found_hw)
546 std::cout << " [HARDWARE] Not mapped on any board.\n";
547
548 // B. Check Geometry Mapping
549 const auto &cylinders = GetCylinders();
550 int current_offset = 0;
551 bool found_geo = false;
552
553 for(const auto &cyl : cylinders)
554 {
555 int tot = cyl.inner.nBundles + cyl.outer.nBundles;
556 if(global_id >= current_offset && global_id < current_offset + tot)
557 {
558 int local = global_id - current_offset;
559 bool isInner = (local < cyl.inner.nBundles);
560 int layerIdx = isInner ? local : (local - cyl.inner.nBundles);
561
562 std::cout << " [GEOMETRY] Cylinder: " << cyl.id
563 << " | Layer: " << (isInner ? "INNER" : "OUTER") << " | Index: " << layerIdx
564 << "\n";
565 found_geo = true;
566 break;
567 }
568 current_offset += tot;
569 }
570
571 if(!found_geo)
572 std::cout << " [GEOMETRY] ID out of geometric range.\n";
573}
574
576{
577 int mode;
578 while(true)
579 {
580 std::cout << "\n-----------------------------------\n";
581 std::cout << " 1. Info from Global ID\n";
582 std::cout << " 2. Info from Board/Channel\n";
583 std::cout << " 3. Info from Geometry (Cyl, Lay, Idx)\n";
584 std::cout << " 4. First bundle of Cylinder (N/A in this version)\n"; // Placeholder
585 // based
586 // on
587 // original
588 // menu
589 // logic
590 std::cout << " 5. First bundle of Layer\n";
591 std::cout << " 0. Quit\n";
592 std::cout << "Choice: ";
593 std::cin >> mode;
594
595 if(!std::cin)
596 { // Handle non-integer input to avoid infinite loop
597 std::cin.clear();
598 std::cin.ignore(10000, '\n');
599 continue;
600 }
601
602 if(mode == 0)
603 break;
604
605 int target_id = -1;
606
607 if(mode == 1)
608 {
609 std::cout << "Global ID: ";
610 std::cin >> target_id;
611 }
612 else if(mode == 2)
613 {
614 int b, c;
615 std::cout << "Board: ";
616 std::cin >> b;
617 std::cout << "Chan: ";
618 std::cin >> c;
619 target_id = GetGlobalBundleId(b, c);
620 }
621 else if(mode >= 3 && mode <= 5)
622 {
623 int c, l = 0, i = 0;
624 std::cout << "Cylinder ID: ";
625 std::cin >> c;
626 if(mode == 3 || mode == 5)
627 {
628 std::cout << "Layer (0=In, 1=Out): ";
629 std::cin >> l;
630 }
631 if(mode == 3)
632 {
633 std::cout << "Index: ";
634 std::cin >> i;
635 }
636 // Use the geometry helper
637 target_id = GetGlobalIdFromGeometry(c, l, i);
638 }
639
640 // Print result
641 if(target_id != -1)
642 PrintBundleMapping(target_id);
643 else
644 std::cout << " -> Mapping not found or wrong parameters.\n";
645 }
646}
647
648} // namespace Config
649} // namespace CHeT
#define M_PI
FiberProp GetFiberProp(int b_id)
Retrieves fiber properties given a global bundle ID.
int GetBoardGlobalOffset(int board_id)
Returns the global offset (bundle count) for a specific board.
void ApplyInverseTransformation(double &x, double &y, double &z)
Transforms a 3D POINT in-place from the Global Lab Frame to the Detector Local Frame....
double GetOffsetExp()
Retrieves the current experimental angular offset (OFFSET_EXP).
void SetDeltaI(int cylIdx, double val)
Sets the experimental parameter DELTA for a specific cylinder.
void ApplyRotation(double &x, double &y, double &z)
Rotates a 3D VECTOR in-place from the Detector Local Frame to the Global Lab Frame....
std::vector< BundlesIntersection > FindIntersections(const std::vector< int > &hit_ids)
Finds 3D intersections between a list of hit bundles.
void SetDeltas(const std::vector< double > &deltas)
Sets the experimental parameter DELTA for all cylinders.
constexpr double BUNDLE_WIDTH
Physical width of a bundle [mm].
std::vector< int > GetActiveCylinders()
Retrieves the list of currently active cylinder IDs.
void ApplyTransformation(double &x, double &y, double &z)
Transforms a 3D POINT in-place from the Detector Local Frame to the Global Lab Frame....
void SetActiveCylinders(const std::vector< int > &active_ids)
Sets the list of active cylinder IDs. This defines the physical composition of the detector for the c...
void SetOffsetExp(double val)
Sets the experimental angular offset (OFFSET_EXP).
double wrap0_2pi(double angle)
Wraps an angle into the [0, 2*PI) range.
int GetGlobalBundleId(int board_id, int channel_id)
Converts Hardware Board/Channel to Global Bundle ID.
void SetTranslation(double tx, double ty, double tz)
Sets the global translation of the detector origin.
void MapExplorer()
Interactive CLI menu to explore the mapping.
const std::vector< CylinderConfig > & GetCylinders()
Retrieves the configuration for all active cylinders.
int GetGlobalIdFromGeometry(int cyl_id, int layer_id, int layer_idx)
Helper: Converts Geometry (Cyl, Layer, Index) to Global ID.
void PrintBundleMapping(int global_id)
Helper: Prints mapping details for a given Global ID to stdout.
double GetDeltaI(int cylIdx)
Retrieves the current experimental parameter DELTA for a specific cylinder.
constexpr double L_HALF
Half-length of the detector [mm].
std::vector< double > GetDeltas()
Gets the experimental parameter DELTA for all cylinders.
void ApplyInverseRotation(double &x, double &y, double &z)
Rotates a 3D VECTOR in-place from the Global Lab Frame to the Detector Local Frame....
void GetRotation(double &rx, double &ry, double &rz)
Retrieves the current global rotation angles.
void SetRotation(double rx, double ry, double rz)
Sets the global rotation of the detector using Euler angles. Rotations are applied in order: X,...
void GetTranslation(double &tx, double &ty, double &tz)
Retrieves the current global translation.
double GetStereoAngle(double radius, double deltaPhi=M_PI, double length=2.0 *L_HALF)
Computes the analytical stereo angle for a given radius.
Root namespace for the Cylindrical Helix Tracker (CHeT) project.
Properties of a specific reconstructed fiber.
int layerId
0 for inner, 1 for outer
int dir
Winding direction.
double phi0
Initial angle [rad].