ATLAS Offline Software
Loading...
Searching...
No Matches
SolenoidParametrization.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5/***************************************************************************
6 Fast (approximate) methods for solenoidal field properties
7 ----------------------------------------------------------
8 ***************************************************************************/
9
10#ifndef TRKEXSOLENOIDALINTERSECTOR_SOLENOIDPARAMETRIZATION_H
11#define TRKEXSOLENOIDALINTERSECTOR_SOLENOIDPARAMETRIZATION_H
12
13//<<<<<< INCLUDES >>>>>>
14
15#include <cassert>
16#include <cmath>
19class MsgStream;
20
21// class SolenoidParametrization
22//
23// This is a singleton class so that any object can obtain access to the
24// approximate field without repeating the expensive parametrisation method
25//
26
27namespace Trk
28{
29
31{
32
33public:
35 {
36 public:
37 BinParameters (const double zAtAxis, const double cotTheta)
38 : m_cotTheta (cotTheta), m_zAtAxis (zAtAxis) {}
39 BinParameters (const double r, const double z, const double cotTheta);
40 double m_signTheta = 1;
41 double m_cotTheta = 0;
42 double m_zAtAxis = 0;
43 double m_interpolateZ = 0;
44 double m_complementZ = 0;
47 };
49 : public BinParameters
50 {
51 public:
53 const double r, const double z, const double cotTheta);
56 double m_cubicTerm{};
57 };
58
59 SolenoidParametrization (const AtlasFieldCacheCondObj &field_cond_obj); // configuration from Intersector
61
62 // forbidden copy constructor
63 // forbidden assignment operator
64
65 double centralField() const;
66 double fieldComponent (double z,
67 const Parameters& parms) const; // parametrized - perp to track in rz-plane
68 double fieldComponent (double r,
69 double z,
70 double cotTheta,
71 MagField::AtlasFieldCache &fieldCache) const; // from MagFieldSvc
72 void fieldIntegrals (double& firstIntegral,
73 double& secondIntegral,
74 double zBegin,
75 double zEnd,
76 Parameters& parms) const;
77 double maximumR() const; // param valid to maximumR
78 double maximumZ() const; // param valid to maximumZ
79 void printFieldIntegrals(MsgStream& m) const;
80 void printParametersForEtaLine(double eta, double z_origin, MsgStream & msg) const;
81 void printResidualForEtaLine (double eta, double zOrigin, MsgStream & msg) const;
82 bool validOrigin(const Amg::Vector3D& origin) const; // param valid for this origin?
83
84 // OK to use this parametrization for CURRENT?
85 bool currentMatches (double current) const;
86
87private:
88 friend class Parameters;
89
90 static int fieldKey(BinParameters& parms);
91 void integrate(double& firstIntegral,
92 double& secondIntegral,
93 double zBegin,
94 double zEnd,
95 const Parameters& parms) const;
96 double interpolate(int key1, int key2,
97 int key3, int key4,
98 const Parameters& parms) const;
100 void setTerms(int, Parameters& parms) const;
101
102 static const double s_binInvSizeTheta;
103 static const double s_binInvSizeZ;
104 static const double s_binZeroTheta;
105 static const double s_binZeroZ;
106 static const double s_lightSpeed;
107 static const int s_maxBinTheta;
108 static const int s_maxBinZ;
109 static const double s_maximumImpactAtOrigin;
110 static const double s_maximumZatOrigin;
111 static const int s_numberParameters;
112 static const double s_rInner;
113 static const double s_rOuter;
114 static const double s_zInner;
115 static const double s_zOuter;
116
118 double m_currentMin{};
119 double m_currentMax{};
121 double m_parameters[14688];
122
123 // copy, assignment: no semantics, no implementation
126};
127
128//<<<<<< INLINE PRIVATE MEMBER FUNCTIONS >>>>>>
129
130inline int
132{
133 double z = parms.m_zAtAxis - s_binZeroZ;
134 int zBin = static_cast<int>(s_binInvSizeZ*z);
135 parms.m_interpolateZ = z*s_binInvSizeZ - double(zBin);
136 if (zBin < 0)
137 {
138 parms.m_interpolateZ = 0.;
139 zBin = 0;
140 }
141 else if (zBin > s_maxBinZ - 2)
142 {
143 parms.m_interpolateZ = 0.;
144 zBin = s_maxBinZ - 1;
145 }
146 parms.m_complementZ = 1. - parms.m_interpolateZ;
147
148 int thetaBin = static_cast<int>(s_binInvSizeTheta*parms.m_cotTheta);
149 parms.m_interpolateTheta = parms.m_cotTheta*s_binInvSizeTheta - double(thetaBin);
150 if (thetaBin > s_maxBinTheta - 3)
151 {
152 parms.m_interpolateTheta = 0.;
153 thetaBin = s_maxBinTheta - 2;
154 }
155 parms.m_complementTheta = 1. - parms.m_interpolateTheta;
156 return 2*s_numberParameters*(s_maxBinTheta*zBin + thetaBin);
157}
158
159inline void
161 double& secondIntegral,
162 double zBegin,
163 double zEnd,
164 const Parameters& parms) const
165{
166 double zDiff = zEnd - zBegin;
167 double zBeg2 = zBegin*zBegin;
168 double zBeg3 = zBeg2*zBegin;
169 double zEnd2 = zEnd*zEnd;
170 double zEnd3 = zEnd2*zEnd;
171 double zDiff4 = 0.25*(zEnd2 + zBeg2)*(zEnd2 - zBeg2);
172
173 firstIntegral += parms.m_fieldAtOrigin*zDiff +
174 parms.m_quadraticTerm*(zEnd3 - zBeg3)*0.333333333333 +
175 parms.m_cubicTerm*zDiff4;
176 double zDiffInv = 1./zDiff;
177 secondIntegral += parms.m_fieldAtOrigin*zDiff +
178 parms.m_quadraticTerm*(zDiffInv*zDiff4 - zBeg3)*0.666666666667 +
179 parms.m_cubicTerm*(0.1*zDiffInv*(zEnd2*zEnd3 - zBeg2*zBeg3) - 0.5*zBeg2*zBeg2);
180}
181
182inline double
184 int key2,
185 int key3,
186 int key4,
187 const Parameters& parms) const
188{
189 return ((m_parameters[key1]*parms.m_complementZ +
191 (m_parameters[key3]*parms.m_complementZ +
193}
194
195inline void
197{
198 int key2 = key1 + s_numberParameters;
199 int key3 = key2 + s_numberParameters;
200 int key4 = key3 + s_numberParameters;
201
202 assert (key1 >= 0);
203 assert (key4 < 14688);
204 assert (m_parameters[key1] != 0.);
205 assert (m_parameters[key3] != 0.);
206 if (parms.m_cotTheta < 7.)
207 {
208 assert (m_parameters[key2] != 0.);
209 assert (m_parameters[key4] != 0.);
210 }
211
212
213 parms.m_fieldAtOrigin = interpolate(key1++,key2++,key3++,key4++,parms);
214 parms.m_quadraticTerm = interpolate(key1++,key2++,key3++,key4++,parms);
215 parms.m_cubicTerm = interpolate(key1,key2,key3,key4,parms);
216}
217
218//<<<<<< INLINE PUBLIC MEMBER FUNCTIONS >>>>>>
219
220inline double
223
224inline double
226{
227 double z_local = parms.m_signTheta*z - parms.m_zAtAxis;
228 double z_squared = z_local*z_local;
229 double value = parms.m_fieldAtOrigin +
230 parms.m_quadraticTerm*z_squared +
231 parms.m_cubicTerm*z_squared*z_local;
232 return value;
233}
234
235inline double
236SolenoidParametrization::fieldComponent (double r, double z, double cotTheta, MagField::AtlasFieldCache &fieldCache) const
237{
238 Amg::Vector3D field;
239 Amg::Vector3D position(r, 0., z);
240 fieldCache.getField(position.data(),field.data());
241 return s_lightSpeed*(field.z() - field.perp()*cotTheta);
242}
243
244inline void
246 double& secondIntegral,
247 double zBegin,
248 double zEnd,
249 Parameters& parms) const
250{
251 zBegin = parms.m_signTheta*zBegin;
252 zEnd = parms.m_signTheta*zEnd;
253 if (zEnd < s_zInner || zBegin > s_zInner)
254 {
255 integrate(firstIntegral,secondIntegral,zBegin-parms.m_zAtAxis,zEnd-parms.m_zAtAxis, parms);
256 }
257 else
258 {
259 integrate(firstIntegral,secondIntegral,zBegin-parms.m_zAtAxis,s_zInner, parms);
260 int key = fieldKey(parms) + s_numberParameters/2;
261 setTerms(key, parms);
262 integrate(firstIntegral,secondIntegral,s_zInner,zEnd-parms.m_zAtAxis,parms);
263 }
264}
265
266inline double
268{ return s_rInner; }
269
270inline double
272{ return s_zInner; }
273
274inline bool
276{ return (origin.perp() < s_maximumImpactAtOrigin
277 && std::abs(origin.z()) < s_maximumZatOrigin); }
278
279} // end of namespace
280
283#include "AthenaKernel/CondCont.h"
285
286#endif // TRKEXSOLENOIDALINTERSECTOR_SOLENOIDPARAMETRIZATION_H
Scalar eta() const
pseudorapidity method
#define CONDCONT_DEF(...)
Definition CondCont.h:1413
macros to associate a CLID to a type
#define CLASS_DEF(NAME, CID, VERSION)
associate a clid and a version to a type eg
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
BinParameters(const double zAtAxis, const double cotTheta)
Parameters(const SolenoidParametrization &spar, const double r, const double z, const double cotTheta)
static int fieldKey(BinParameters &parms)
void printParametersForEtaLine(double eta, double z_origin, MsgStream &msg) const
double interpolate(int key1, int key2, int key3, int key4, const Parameters &parms) const
SolenoidParametrization(const SolenoidParametrization &)=delete
void integrate(double &firstIntegral, double &secondIntegral, double zBegin, double zEnd, const Parameters &parms) const
bool validOrigin(const Amg::Vector3D &origin) const
bool currentMatches(double current) const
void fieldIntegrals(double &firstIntegral, double &secondIntegral, double zBegin, double zEnd, Parameters &parms) const
void setTerms(int, Parameters &parms) const
SolenoidParametrization(const AtlasFieldCacheCondObj &field_cond_obj)
const AtlasFieldCacheCondObj * m_fieldCondObj
void printFieldIntegrals(MsgStream &m) const
double fieldComponent(double z, const Parameters &parms) const
SolenoidParametrization & operator=(const SolenoidParametrization &)=delete
void printResidualForEtaLine(double eta, double zOrigin, MsgStream &msg) const
int r
Definition globals.cxx:22
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
@ z
global position (cartesian)
Definition ParamDefs.h:57
MsgStream & msg
Definition testRead.cxx:32