15#include "GaudiKernel/SystemOfUnits.h"
17#include "GaudiKernel/MsgStream.h"
25 explicit RestoreIOSFlags (std::ostream &os)
27 m_precision(m_os->precision())
30 m_os->precision(m_precision);
34 std::streamsize m_precision;
62 const double cotTheta)
80 const double cotTheta)
114 double smallOffset = 0.0000000000001;
119 constexpr int n = 200;
123 double cotTheta = smallOffset;
124 for (
int binTheta = 0; binTheta <
s_maxBinTheta - 1; ++binTheta) {
133 derivative.setZero();
134 for (
int k = 0; k < n; ++k){
137 double w = (n - k)*(n - k);
138 double zLocal =
z - zAtAxis;
141 derivative(k,4) = w*zLocal*zLocal;
142 derivative(k,5) = w*zLocal*zLocal*zLocal;
145 derivative(k,1) = w*zLocal*zLocal;
146 derivative(k,2) = w*zLocal*zLocal*zLocal;
151 Amg::VectorX solution = derivative.colPivHouseholderQr().solve(difference);
211 msg << __func__<<
"\n"
212 << std::setiosflags(std::ios::fixed)
213 <<
" eta rEnd mean(Bz) max(dBz/dR) mean(Bt) max(dBt/dR) "
214 <<
"min(Bt) max(Bt) reverse-bend(z) integrals: Bt.dR Bl.dR"
222 double maxR = 1000.*Gaudi::Units::mm;
223 double maxZ = 2650.*Gaudi::Units::mm;
231 for (
int i = 0; i != 31; ++i)
234 double cotTheta = std::sinh(
eta);
237 if (std::abs(cotTheta) > maxZ/maxR) rEnd = maxZ/direction.z();
238 double step = rEnd/
static_cast<double>(numSteps);
244 double minBT = 9999.;
245 double maxGradBT = 0.;
246 double maxGradBZ = 0.;
249 double reverseZ = 0.;
252 for (
int j = 0; j != numSteps; ++j)
254 position += 0.5*step*direction;
256 fieldCache.
getField(position.data(),field.data());
258 position += 0.5*step*direction;
259 double BZ = field.z();
260 double BT = vCrossB.x()*direction.y() - vCrossB.y()*direction.x();
261 double BL = std::sqrt(vCrossB.mag2() - BT*BT);
265 if (BT > maxBT) maxBT = BT;
266 if (BT < minBT) minBT = BT;
269 if (BT*prevBT < 0.) reverseZ = position.z() - step*direction.z();
270 double grad = std::abs(BT - prevBT);
271 if (grad > maxGradBT) maxGradBT = grad;
272 grad = std::abs(BZ - prevBZ);
273 if (grad > maxGradBZ) maxGradBZ = grad;
280 maxGradBT *=
static_cast<double>(numSteps)/step;
281 maxGradBZ *=
static_cast<double>(numSteps)/step;
282 meanBL /=
static_cast<double>(numSteps);
283 meanBT /=
static_cast<double>(numSteps);
284 meanBZ /=
static_cast<double>(numSteps);
285 double integralBL = meanBL*rEnd;
286 double integralBT = meanBT*rEnd;
288 msg << std::setw(6) << std::setprecision(2) <<
eta
289 << std::setw(8) << std::setprecision(3) << rEnd /Gaudi::Units::meter
290 << std::setw(11) << std::setprecision(4) << meanBZ /Gaudi::Units::tesla
291 << std::setw(12) << std::setprecision(3) << maxGradBZ /Gaudi::Units::tesla
292 << std::setw(13) << std::setprecision(4) << meanBT /Gaudi::Units::tesla
293 << std::setw(12) << std::setprecision(3) << maxGradBT /Gaudi::Units::tesla
294 << std::setw(13) << std::setprecision(4) << minBT /Gaudi::Units::tesla
295 << std::setw(8) << std::setprecision(4) << maxBT /Gaudi::Units::tesla;
298 msg << std::setw(17) << std::setprecision(2) << reverseZ /Gaudi::Units::meter
299 << std::setw(18) << std::setprecision(4) << integralBT /(Gaudi::Units::tesla*Gaudi::Units::meter)
300 << std::setw(8) << std::setprecision(4) << integralBL /(Gaudi::Units::tesla*Gaudi::Units::meter)
305 msg << std::setw(35) << std::setprecision(4) << integralBT /(Gaudi::Units::tesla*Gaudi::Units::meter)
306 << std::setw(8) << std::setprecision(4) << integralBL /(Gaudi::Units::tesla*Gaudi::Units::meter)
311 for (
int k = 0; k != 3; ++k)
319 for (
int j = 0; j != numSteps; ++j)
321 position += 0.5*step*direction;
323 fieldCache.
getField(position.data(),field.data());
325 position += 0.5*step*direction;
326 double BT = vCrossB.x()*direction.y() - vCrossB.y()*direction.x();
329 asymm = asymm/
static_cast<double>(numSteps) - meanBT;
330 msg << std::setw(9) << std::setprecision(4) << asymm /Gaudi::Units::tesla;
340 double cotTheta = 1./std::tan(2.*std::atan(1./std::exp(
eta)));
353 << std::setiosflags(std::ios::fixed)
354 <<
"SolenoidParametrization: line with eta " << std::setw(6) << std::setprecision(2) <<
eta
355 <<
" from (r,z) 0.0," << std::setw(6) << std::setprecision(1) << z_origin
356 <<
" inner terms: z0 "<< std::setw(6) << std::setprecision(2)
358 <<
" z^2 "<< std::setw(6) << std::setprecision(3)
360 <<
" z^3 " << std::setw(6) << std::setprecision(3)
362 <<
" outer terms: z0 "<< std::setw(6) << std::setprecision(3)
364 <<
" z^2 "<< std::setw(6) << std::setprecision(3)
366 <<
" z^3 " << std::setw(6) << std::setprecision(3)
368 << std::resetiosflags(std::ios::fixed) <<
"\n";
374 double cotTheta = 1./std::tan(2.*std::atan(1./std::exp(std::abs(
eta))));
387 double chiSquareIn = 0.;
388 double chiSquareOut = 0.;
391 double worstBCalc = 0.;
392 double worstBTrue = 0.;
393 double worstDiff = -1.;
398 for (
int k = 0; k < n; ++k)
415 if (std::abs(
diff) > worstDiff)
417 worstDiff = std::abs(
diff);
428 << std::setiosflags(std::ios::fixed)
429 <<
"SolenoidParametrization: line with eta " << std::setw(6) << std::setprecision(2) <<
eta
430 <<
" from (r,z) 0.0, " << std::setw(6) << std::setprecision(1) << zOrigin
431 <<
" rms diff inner/outer " << std::setw(6) << std::setprecision(3)
432 << std::sqrt(chiSquareIn/nIn) /Gaudi::Units::tesla <<
" " << std::setw(6) << std::setprecision(3)
433 << std::sqrt(chiSquareOut/nOut) /Gaudi::Units::tesla << std::endl
434 <<
" worst residual at: (r,z) "
435 << std::setw(6) << std::setprecision(1) << worstR
436 <<
", " << std::setw(6) << std::setprecision(1) << worstZ
437 <<
" with B true/calc " << std::setw(6) << std::setprecision(3)
439 <<
" " << std::setw(6) << std::setprecision(3) << worstBCalc/
s_lightSpeed /Gaudi::Units::tesla
440 << std::resetiosflags(std::ios::fixed) <<
"\n";
Scalar eta() const
pseudorapidity method
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
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 const double s_binInvSizeZ
double m_parameters[14688]
static const double s_binZeroZ
static int fieldKey(BinParameters &parms)
static const int s_maxBinZ
void parametrizeSolenoid()
static const double s_zOuter
void printParametersForEtaLine(double eta, double z_origin, MsgStream &msg) const
static const double s_lightSpeed
static const double s_rOuter
static const double s_rInner
static const double s_zInner
static const int s_maxBinTheta
static const double s_binZeroTheta
static const int s_numberParameters
static const double s_maximumImpactAtOrigin
static const double s_maximumZatOrigin
void setTerms(int, Parameters &parms) const
SolenoidParametrization(const AtlasFieldCacheCondObj &field_cond_obj)
const AtlasFieldCacheCondObj * m_fieldCondObj
void printFieldIntegrals(MsgStream &m) const
static const double s_binInvSizeTheta
double fieldComponent(double z, const Parameters &parms) const
void printResidualForEtaLine(double eta, double zOrigin, MsgStream &msg) const
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
Ensure that the ATLAS eigen extensions are properly loaded.
@ z
global position (cartesian)