ATLAS Offline Software
Loading...
Searching...
No Matches
WheelFanCalculator.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef LARWHEELCALCULATOR_IMPL_WHEELFANCALCULATOR_H
6#define LARWHEELCALCULATOR_IMPL_WHEELFANCALCULATOR_H
7
8#include "IFanCalculator.h"
10
11#ifdef HARDDEBUG
12#undef HARDDEBUG
13#endif
14
16{
17
18 // mode marker classes
19 class SaggingOn_t {};
20 class SaggingOff_t {};
21
22 template <typename SaggingType>
24
25 template<>
27 {
28 public:
29 static inline double calculate(const LArWheelCalculator* lwc, int fan_number, CLHEP::Hep3Vector &p) {
30 //lwc->set_m_fan_number(fan_number);
31 return lwc->DistanceToTheNeutralFibre(p, lwc->adjust_fan_number(fan_number));
32 }
33 };
34
36 {
37 public:
38 static inline double calculate(const LArWheelCalculator* lwc, int /*fan_number*/, CLHEP::Hep3Vector &p) {
39 // saggingOff distance calculations does not use fan_number, use arbitrary recognisible magic number
40 return lwc->DistanceToTheNeutralFibre(p, -531135);
41 }
42 };
43
45 FORWARD = 1, // delta = 1
46 BACKWARD = -1 // delta = -1
47 };
48
49
50 template <typename SaggingType, FanSearchDirection_t dir >
51 class StepFan {};
52
53
54 template <FanSearchDirection_t dir >
56 {
57 public:
58 static inline void next(int &/*fan_number*/) {}
59 static inline void adjust(int &/*fan_number*/) {}
60 };
61
62
63 template <>
65 {
66 public:
67 static inline void next(int &fan_number) {
68 fan_number++;
69 }
70 static inline void adjust(int &fan_number) {
71 fan_number--;
72 }
73 };
74
75 template <>
77 {
78 public:
79 static inline void next(int &fan_number) {
80 fan_number--;
81 }
82 static inline void adjust(int &/*fan_number*/) {}
83 };
84
85 template <FanSearchDirection_t dir>
86 class DoSearch {};
87
88 template <>
90 {
91 public:
92 template <typename T >
93 static inline bool pred(T val) {
94 return (val > 0.);
95 }
96 };
97
98 template <>
100 {
101 public:
102 template <typename T >
103 static inline bool pred(T val) {
104 return (val < 0.);
105 }
106 };
107
109 template <typename SaggingType, FanSearchDirection_t dir, class NFDistance >
110 inline void rotate_to_nearest_fan(const LArWheelCalculator* lwc, int &fan_number,
111 const double angle, CLHEP::Hep3Vector &p)
112 {
113 p.rotateZ(angle);
115 //fan_number += delta;
116 double d1 = NFDistance::calculate(lwc, fan_number, p);
117
118 //while(d0 * d1 > 0.) -> dir*d1 > 0 -> FORWARD: d1 > 0., BACKWARD: d1 < 0.
119
120 while ( DoSearch<dir>::pred(d1) ) { // search:
121 p.rotateZ(angle);
123 //fan_number += delta;
124
125 d1 = NFDistance::calculate(lwc, fan_number, p);
126 //lwc()->set_m_fan_number(fan_number);
127 //d1 = lwc()->DistanceToTheNeutralFibre(p);
128
129 }
130 // if signs of d1 and d0 are different, the point is between current pair
132 //if(delta > 0) fan_number --;
133 }
134
135
138 template <typename SaggingType>
140 {
141 public:
146
149
150 virtual double DistanceToTheNearestFan(CLHEP::Hep3Vector &p, int & out_fan_number) const
151 {
152 static const double halfpi=M_PI/2.0;
153 int fan_number = int((p.phi() - halfpi - lwc()->m_ZeroFanPhi_ForDetNeaFan) / lwc()->m_FanStepOnPhi);
154 const double angle = lwc()->m_FanStepOnPhi * fan_number + lwc()->m_ZeroFanPhi_ForDetNeaFan;
155#ifdef HARDDEBUG
156 printf("DistanceToTheNearestFan: initial FN %4d\n", fan_number);
157#endif
158 p.rotateZ(-angle);
159 // determine search direction
161
162 const double d0 = NFDistance::calculate(lwc(), fan_number, p);
163 //lwc()->set_m_fan_number(fan_number);
164 //double d0 = lwc()->DistanceToTheNeutralFibre(p);
165
166 const int delta = (d0 < 0.) ? -1 : 1;
167 //int delta = 1; // delta = signof(d0)
168 //if(d0 < 0.) delta = -1; // search direction has been determined
169
170 const double step_angle = - lwc()->m_FanStepOnPhi * delta;
171
172 if (delta > 0) { // forward search
174 } else { // backward search
176 }
177
178 /*
179 double d1 = d0;
180 do { // search:
181 p.rotateZ(angle);
182 fan_number += delta;
183
184 d1 = NFDistance::calculate(lwc(), fan_number, p);
185 //lwc()->set_m_fan_number(fan_number);
186 //d1 = lwc()->DistanceToTheNeutralFibre(p);
187
188#ifdef HARDDEBUG
189 printf("DistanceToTheNearestFan: step FN %4d %4d\n", fan_number, lwc()->m_fan_number);
190#endif
191 } while(d0 * d1 > 0.);
192 // if signs of d1 and d0 are different, the point is between current pair
193 if(delta > 0) fan_number --;
194 */
195
196 p.rotateZ(-0.5 * step_angle);
197#ifdef HARDDEBUG
198 printf("DistanceToTheNearestFan: final FN %4d\n", fan_number);
199#endif
200
201 out_fan_number = lwc()->adjust_fan_number(fan_number);
202 return lwc()->DistanceToTheNeutralFibre(p, out_fan_number);
203 }
204
205 virtual int PhiGapNumberForWheel(int i) const
206 {
207 return i;
208 }
209
210 virtual std::pair<int, int> GetPhiGapAndSide(const CLHEP::Hep3Vector &p) const
211 {
212 static const double halfpi=M_PI/2.0;
213 CLHEP::Hep3Vector p1 = p;
214
215 int fan_number = int((p.phi() - halfpi - lwc()->m_ZeroFanPhi) / lwc()->m_FanStepOnPhi);
216 const double angle = lwc()->m_FanStepOnPhi * fan_number + lwc()->m_ZeroFanPhi;
217 p1.rotateZ(-angle);
218
220
221 const double d0 = NFDistance::calculate(lwc(), fan_number, p1);
222 //lwc()->set_m_fan_number(fan_number);
223 //double d0 = lwc()->DistanceToTheNeutralFibre(p1);
224
225 double d1 = d0;
226
227 const int delta = (d0 < 0.) ? -1 : 1;
228 //int delta = 1;
229 //if(d0 < 0.) delta = -1;
230 const double step_angle = - lwc()->m_FanStepOnPhi * delta;
231 do {
232 p1.rotateZ(step_angle);
233 fan_number += delta;
234 d1 = NFDistance::calculate(lwc(), fan_number, p1);
235 //lwc()->set_m_fan_number(fan_number);
236 //d1 = lwc()->DistanceToTheNeutralFibre(p1);
237 } while(d0 * d1 > 0.);
238
239 if(delta > 0) fan_number --;
240 if(!lwc()->m_isElectrode) fan_number ++;
241
242 p1.rotateZ(-0.5 * step_angle);
243
244 const int a_fan_number = lwc()->adjust_fan_number(fan_number);
245 double dd = lwc()->DistanceToTheNeutralFibre(p1, a_fan_number);
246 int side = dd < 0.? -1: 1;
247#ifdef HARDDEBUG
248 printf("GetPhiGapAndSide: MFN %4d\n", a_fan_number);
249#endif
250 return std::pair<int, int>(a_fan_number, side);
251 }
252
254
255 inline const LArWheelCalculator *lwc() const { return m_lwc; };
256
257 private:
259
260 };
261
262}
263
264#endif // LARWHEELCALCULATOR_IMPL_WHEELFANCALCULATOR_H
#define M_PI
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
static double calculate(const LArWheelCalculator *lwc, int, CLHEP::Hep3Vector &p)
static double calculate(const LArWheelCalculator *lwc, int fan_number, CLHEP::Hep3Vector &p)
Abstract interface for fan calculator classes that handle distance calculation to parts of the LAr en...
virtual std::pair< int, int > GetPhiGapAndSide(const CLHEP::Hep3Vector &p) const
virtual double DistanceToTheNearestFan(CLHEP::Hep3Vector &p, int &out_fan_number) const
const LArWheelCalculator * lwc() const
This class separates some of the geometry details of the LAr endcap.
int adjust_fan_number(int fan_number) const
double DistanceToTheNeutralFibre(const CLHEP::Hep3Vector &p, int fan_number) const
Calculates aproximate, probably underestimate, distance to the neutral fibre of the vertical fan.
void rotate_to_nearest_fan(const LArWheelCalculator *lwc, int &fan_number, const double angle, CLHEP::Hep3Vector &p)