Skip to content

Commit b2366a5

Browse files
authored
Merge branch 'dev' into its/capcatiy
2 parents 434a3c3 + 68bd709 commit b2366a5

63 files changed

Lines changed: 3375 additions & 160 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Common/DCAFitter/GPU/cuda/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ o2_add_library(DCAFitterCUDA
2020
O2::DetectorsBase
2121
PRIVATE_LINK_LIBRARIES O2::GPUTrackingCUDAExternalProvider)
2222
set_property(TARGET ${targetName} PROPERTY CUDA_SEPARABLE_COMPILATION ON)
23+
# Device LTO, so that the device link can inline across the
24+
# O2::GPUTrackingCUDAExternalProvider objects, which are compiled to LTO IR.
25+
set_property(TARGET ${targetName} PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
2326
# add_compile_options(-lineinfo)
2427

2528
#o2_add_test(DCAFitterNCUDA

Common/Field/include/Field/MagneticField.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,8 @@ class MagneticField : public FairField
262262

263263
Int_t mDefaultIntegration; ///< Default integration method as indicated in Geant
264264
Int_t mPrecisionInteg; ///< Alternative integration method, e.g. for higher precision
265-
Double_t mMultipicativeFactorSolenoid; ///< Multiplicative factor for solenoid
266-
Double_t mMultipicativeFactorDipole; ///< Multiplicative factor for dipole
265+
Double_t mMultipicativeFactorSolenoid; ///< Multiplicative factor for solenoid, polarity convention applied
266+
Double_t mMultipicativeFactorDipole; ///< Multiplicative factor for dipole, polarity convention applied
267267
Double_t mMaxField; ///< Max Field as indicated in Geant
268268
Bool_t mDipoleOnOffFlag; ///< Dipole ON/OFF flag
269269

Common/Field/src/MagneticField.cxx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ MagneticField::MagneticField(const char* name, const char* title, Double_t facto
108108
mBeamEnergy(be),
109109
mDefaultIntegration(integ),
110110
mPrecisionInteg(1),
111-
mMultipicativeFactorSolenoid(factorSol),
112-
mMultipicativeFactorDipole(factorDip),
111+
mMultipicativeFactorSolenoid(1.),
112+
mMultipicativeFactorDipole(1.),
113113
mMaxField(fmax),
114114
mDipoleOnOffFlag(factorDip == 0.),
115115
mQuadrupoleGradient(0),
@@ -122,6 +122,8 @@ MagneticField::MagneticField(const char* name, const char* title, Double_t facto
122122
/*
123123
* Constructor for human readable params
124124
*/
125+
setFactorSolenoid(factorSol);
126+
setFactorDipole(factorDip);
125127
setDataFileName(path.c_str());
126128
if (!gOriginBias) {
127129
checkOriginBias();
@@ -139,8 +141,8 @@ MagneticField::MagneticField(const MagFieldParam& param)
139141
mBeamEnergy(param.GetBeamEnergy()),
140142
mDefaultIntegration(param.GetDefInt()),
141143
mPrecisionInteg(1),
142-
mMultipicativeFactorSolenoid(param.GetFactorSol()), // temporary
143-
mMultipicativeFactorDipole(param.GetFactorDip()), // temporary
144+
mMultipicativeFactorSolenoid(1.),
145+
mMultipicativeFactorDipole(1.),
144146
mMaxField(param.GetMaxField()),
145147
mDipoleOnOffFlag(param.GetFactorDip() == 0.),
146148
mQuadrupoleGradient(0),
@@ -153,6 +155,8 @@ MagneticField::MagneticField(const MagFieldParam& param)
153155
/*
154156
* Constructor for FairParam derived params
155157
*/
158+
setFactorSolenoid(param.GetFactorSol());
159+
setFactorDipole(param.GetFactorDip());
156160
setDataFileName(param.GetMapPath());
157161
if (!gOriginBias) {
158162
checkOriginBias();
@@ -235,8 +239,11 @@ void MagneticField::CreateField()
235239

236240
loadParameterization();
237241
initializeMachineField(mBeamType, mBeamEnergy);
238-
setFactorSolenoid(mMultipicativeFactorSolenoid);
239-
setFactorDipole(mMultipicativeFactorDipole);
242+
// The scaling factors are left alone: they already carry the polarity convention, and
243+
// re-applying it would invert a field re-initialized after being read back from a file.
244+
if (mFastField) {
245+
mFastField->setFactorSol(getFactorSolenoid());
246+
}
240247
double xyz[3] = {0., 0., 0.};
241248
mSolenoid = getBz(xyz);
242249
Print("a");

Common/Field/test/testMagneticField.cxx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "Field/MagFieldFast.h"
1919
#include <memory>
2020
#include <fairlogger/Logger.h> // for FairLogger
21+
#include <TFile.h>
2122
#include <TStopwatch.h>
2223
#include <TRandom.h>
2324

@@ -98,3 +99,48 @@ BOOST_AUTO_TEST_CASE(MagneticField_test)
9899
BOOST_CHECK(TMath::Abs(rms[i] / nomBz) < 1.e-3);
99100
}
100101
}
102+
103+
BOOST_AUTO_TEST_CASE(MagneticField_reinitialization_test)
104+
{
105+
// The measured map is transient, so a MagneticField read back from a file has to be
106+
// re-created before it can be used. That must reproduce the field vectors, not merely
107+
// their magnitude: a sign flip leaves |B| untouched.
108+
const double points[][3] = {
109+
{0., 0., 0.}, // solenoid, on axis
110+
{100., 50., 100.}, // solenoid, off axis
111+
{10., 10., -900.}, // muon dipole
112+
{0., 0., 1000.}, // compensator 1A, side A
113+
{0., 0., -2049.}, // compensator 2C, side C
114+
{0., 0., 2049.} // compensator 2A, side A
115+
};
116+
const int npoints = sizeof(points) / sizeof(points[0]);
117+
const double tolerance = 1.e-9; // kGauss
118+
119+
std::unique_ptr<MagneticField> fld = std::make_unique<MagneticField>("Maps", "Maps", 1., 1., MagFieldParam::k5kG);
120+
const double facSol = fld->getFactorSolenoid(), facDip = fld->getFactorDipole();
121+
double bref[npoints][3] = {};
122+
for (int ip = 0; ip < npoints; ip++) {
123+
fld->Field(points[ip], bref[ip]);
124+
// a point where the field vanishes would make the comparisons below vacuous
125+
BOOST_CHECK(TMath::Abs(bref[ip][0]) + TMath::Abs(bref[ip][1]) + TMath::Abs(bref[ip][2]) > tolerance);
126+
}
127+
128+
const char* fname = "testMagneticFieldReinitialization.root";
129+
{
130+
TFile fout(fname, "recreate");
131+
fout.WriteObject(fld.get(), "field");
132+
}
133+
TFile fin(fname);
134+
auto* fldRead = fin.Get<MagneticField>("field");
135+
BOOST_REQUIRE(fldRead != nullptr);
136+
fldRead->CreateField();
137+
BOOST_CHECK_EQUAL(fldRead->getFactorSolenoid(), facSol);
138+
BOOST_CHECK_EQUAL(fldRead->getFactorDipole(), facDip);
139+
for (int ip = 0; ip < npoints; ip++) {
140+
double b[3] = {};
141+
fldRead->Field(points[ip], b);
142+
for (int i = 0; i < 3; i++) {
143+
BOOST_CHECK_SMALL(b[i] - bref[ip][i], tolerance);
144+
}
145+
}
146+
}

Common/MathUtils/include/MathUtils/Cartesian.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include "GPUROOTCartesianFwd.h"
4040
#include "GPUROOTSMatrixFwd.h"
41+
#include "MathUtils/detail/trigonometric.h"
4142

4243
namespace o2
4344
{
@@ -68,7 +69,7 @@ class Rotation2D
6869

6970
Rotation2D() = default;
7071
Rotation2D(value_t cs, value_t sn) : mCos(cs), mSin(sn) {}
71-
Rotation2D(value_t phiZ) : mCos(cos(phiZ)), mSin(sin(phiZ)) {}
72+
Rotation2D(value_t phiZ) { detail::sincos<value_t>(phiZ, mSin, mCos); }
7273
~Rotation2D() = default;
7374
Rotation2D(const Rotation2D& src) = default;
7475
Rotation2D(Rotation2D&& src) = default;
@@ -77,8 +78,7 @@ class Rotation2D
7778

7879
void set(value_t phiZ)
7980
{
80-
mCos = cos(phiZ);
81-
mSin = sin(phiZ);
81+
detail::sincos<value_t>(phiZ, mSin, mCos);
8282
}
8383

8484
void set(value_t cs, value_t sn)

Common/SimConfig/include/SimConfig/SimParams.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace conf
2323
// (mostly used in O2MCApplication stepping)
2424
struct SimCutParams : public o2::conf::ConfigurableParamHelper<SimCutParams> {
2525
bool stepFiltering = true; // if we activate the step filtering in O2BaseMCApplication
26+
std::string stepFilteringMacro = ""; // ROOT macro providing keepStep(); empty = built-in z/R cut
2627
bool stepTrackRefHook = false; // if we create track references during generic stepping
2728
std::string stepTrackRefHookFile = "${O2_ROOT}/share/Detectors/gconfig/StandardSteppingTrackRefHook.macro"; // the standard code holding the TrackRef callback
2829

DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrization.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ GPUdi() void TrackParametrization<value_T>::getLineParams(o2::math_utils::Interv
548548
template <typename value_T>
549549
GPUdi() auto TrackParametrization<value_T>::getCurvature(value_t b) const -> value_t
550550
{
551-
return mAbsCharge ? mP[kQ2Pt] * b * o2::constants::math::B2C : 0.;
551+
return mAbsCharge ? mP[kQ2Pt] * b * o2::constants::math::B2C : value_T(0);
552552
}
553553

554554
//____________________________________________________________

DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrizationWithError.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class TrackParametrizationWithError : public TrackParametrization<value_T>
114114
GPUd() void buildCombinedCovMatrix(const TrackParametrizationWithError& rhs, MatrixDSym5& cov) const;
115115
GPUd() value_t getPredictedChi2(const TrackParametrizationWithError& rhs, MatrixDSym5& covToSet) const;
116116
GPUd() value_t getPredictedChi2(const TrackParametrizationWithError& rhs) const;
117+
GPUd() value_t getPredictedChi2Fast(const TrackParametrizationWithError& rhs) const;
117118
GPUd() value_t getPredictedChi2Quiet(const TrackParametrizationWithError& rhs) const;
118119
GPUd() bool update(const TrackParametrizationWithError& rhs, const MatrixDSym5& covInv);
119120
GPUd() bool update(const TrackParametrizationWithError& rhs);

DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackUtils.h

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,26 @@ GPUd() void g3helx3(value_T qfield, value_T step, std::array<value_T, 7>& vect)
6666
static_assert(std::is_floating_point_v<value_T>);
6767
#endif
6868

69-
const int ix = 0, iy = 1, iz = 2, ipx = 3, ipy = 4, ipz = 5, ipp = 6;
70-
constexpr value_T kOvSqSix = 0.408248f; // std::sqrt(1./6.);
69+
constexpr int ix = 0, iy = 1, iz = 2, ipx = 3, ipy = 4, ipz = 5, ipp = 6;
70+
constexpr value_T kOvSqSix = value_T(0.408248); // std::sqrt(1./6.);
7171

7272
value_T cosx = vect[ipx], cosy = vect[ipy], cosz = vect[ipz];
7373

7474
value_T rho = qfield * constants::math::B2C / vect[ipp];
7575
value_T tet = rho * step;
7676

7777
value_T tsint, sintt, sint, cos1t;
78-
if (gpu::CAMath::Abs(tet) > 0.03f) {
78+
if (gpu::CAMath::Abs(tet) > value_T(0.03)) {
7979
sint = gpu::CAMath::Sin(tet);
8080
sintt = sint / tet;
8181
tsint = (tet - sint) / tet;
82-
value_T t = gpu::CAMath::Sin(0.5f * tet);
83-
cos1t = 2 * t * t / tet;
82+
value_T t = gpu::CAMath::Sin(value_T(0.5) * tet);
83+
cos1t = value_T(2) * t * t / tet;
8484
} else {
85-
tsint = tet * tet / 6.f;
86-
sintt = (1.f - tet * kOvSqSix) * (1.f + tet * kOvSqSix); // 1.- tsint;
85+
tsint = tet * tet / value_T(6);
86+
sintt = (value_T(1) - tet * kOvSqSix) * (value_T(1) + tet * kOvSqSix); // 1.- tsint;
8787
sint = tet * sintt;
88-
cos1t = 0.5f * tet;
88+
cos1t = value_T(0.5) * tet;
8989
}
9090

9191
value_T f1 = step * sintt;
@@ -124,25 +124,25 @@ GPUd() value_T BetheBlochSolid(value_T bg, value_T rho, value_T kp1, value_T kp2
124124
static_assert(std::is_floating_point_v<value_T>);
125125
#endif
126126

127-
constexpr value_T mK = 0.307075e-3; // [GeV*cm^2/g]
128-
constexpr value_T me = 0.511e-3; // [GeV/c^2]
129-
kp1 *= 2.303f;
130-
kp2 *= 2.303f;
131-
value_T bg2 = bg * bg, beta2 = bg2 / (1 + bg2);
132-
value_T maxT = 2.f * me * bg2; // neglecting the electron mass
127+
constexpr value_T mK = value_T(0.307075e-3); // [GeV*cm^2/g]
128+
constexpr value_T me = value_T(0.511e-3); // [GeV/c^2]
129+
kp1 *= value_T(2.303);
130+
kp2 *= value_T(2.303);
131+
value_T bg2 = bg * bg, beta2 = bg2 / (value_T(1) + bg2);
132+
value_T maxT = value_T(2) * me * bg2; // neglecting the electron mass
133133

134134
//*** Density effect
135-
value_T d2 = 0.;
135+
value_T d2 = value_T(0);
136136
const value_T x = gpu::CAMath::Log(bg);
137-
const value_T lhwI = gpu::CAMath::Log(28.816f * 1e-9f * gpu::CAMath::Sqrt(rho * meanZA) / meanI);
137+
const value_T lhwI = gpu::CAMath::Log(value_T(28.816e-9) * gpu::CAMath::Sqrt(rho * meanZA) / meanI);
138138
if (x > kp2) {
139-
d2 = lhwI + x - 0.5f;
139+
d2 = lhwI + x - value_T(0.5);
140140
} else if (x > kp1) {
141141
double r = (kp2 - x) / (kp2 - kp1);
142-
d2 = lhwI + x - 0.5f + (0.5f - lhwI - kp1) * r * r * r;
142+
d2 = lhwI + x - value_T(0.5) + (value_T(0.5) - lhwI - kp1) * r * r * r;
143143
}
144-
auto dedx = mK * meanZA / beta2 * (0.5f * gpu::CAMath::Log(2 * me * bg2 * maxT / (meanI * meanI)) - beta2 - d2);
145-
return dedx > 0. ? dedx : 0.;
144+
auto dedx = mK * meanZA / beta2 * (value_T(0.5) * gpu::CAMath::Log(value_T(2) * me * bg2 * maxT / (meanI * meanI)) - beta2 - d2);
145+
return dedx > value_T(0) ? dedx : value_T(0);
146146
}
147147

148148
//____________________________________________________
@@ -166,26 +166,26 @@ GPUd() value_T BetheBlochSolidOpt(value_T bg)
166166
// constexpr value_T meanI = 173e-9;
167167
// constexpr value_T me = 0.511e-3; // [GeV/c^2]
168168

169-
constexpr value_T mK = 0.307075e-3; // [GeV*cm^2/g]
170-
constexpr value_T kp1 = 0.20 * 2.303;
171-
constexpr value_T kp2 = 3.00 * 2.303;
172-
constexpr value_T meanZA = 0.49848;
173-
constexpr value_T lhwI = -1.7175226; // gpu::CAMath::Log(28.816 * 1e-9 * gpu::CAMath::Sqrt(rho * meanZA) / meanI);
174-
constexpr value_T log2muTomeanI = 8.6839805; // gpu::CAMath::Log( 2. * me / meanI);
169+
constexpr value_T mK = value_T(0.307075e-3); // [GeV*cm^2/g]
170+
constexpr value_T kp1 = value_T(0.20 * 2.303);
171+
constexpr value_T kp2 = value_T(3.00 * 2.303);
172+
constexpr value_T meanZA = value_T(0.49848);
173+
constexpr value_T lhwI = value_T(-1.7175226); // gpu::CAMath::Log(28.816 * 1e-9 * gpu::CAMath::Sqrt(rho * meanZA) / meanI);
174+
constexpr value_T log2muTomeanI = value_T(8.6839805); // gpu::CAMath::Log( 2. * me / meanI);
175175

176-
value_T bg2 = bg * bg, beta2 = bg2 / (1. + bg2);
176+
value_T bg2 = bg * bg, beta2 = bg2 / (value_T(1) + bg2);
177177

178178
//*** Density effect
179-
value_T d2 = 0.;
179+
value_T d2 = value_T(0);
180180
const value_T x = gpu::CAMath::Log(bg);
181181
if (x > kp2) {
182-
d2 = lhwI - 0.5f + x;
182+
d2 = lhwI - value_T(0.5) + x;
183183
} else if (x > kp1) {
184184
value_T r = (kp2 - x) / (kp2 - kp1);
185-
d2 = lhwI - 0.5 + x + (0.5 - lhwI - kp1) * r * r * r;
185+
d2 = lhwI - value_T(0.5) + x + (value_T(0.5) - lhwI - kp1) * r * r * r;
186186
}
187187
auto dedx = mK * meanZA / beta2 * (log2muTomeanI + x + x - beta2 - d2);
188-
return dedx > 0. ? dedx : 0.;
188+
return dedx > value_T(0) ? dedx : value_T(0);
189189
}
190190

191191
//____________________________________________________
@@ -203,12 +203,12 @@ GPUdi() value_T BetheBlochSolidDerivative(value_T dedx, value_T bg)
203203
// dedx - precalculate dedx for bg
204204
// bg - beta*gamma
205205
//
206-
constexpr value_T mK = 0.307075e-3; // [GeV*cm^2/g]
207-
constexpr value_T meanZA = 0.49848;
206+
constexpr value_T mK = value_T(0.307075e-3); // [GeV*cm^2/g]
207+
constexpr value_T meanZA = value_T(0.49848);
208208
auto bg2 = bg * bg;
209-
auto t1 = 1 + bg2;
209+
auto t1 = value_T(1) + bg2;
210210
// auto derH = (mK * meanZA * (t1+bg2) - dedx*bg2)/(bg*t1);
211-
auto derH = (mK * meanZA * (t1 + 1. / bg2) - dedx) / (bg * t1);
211+
auto derH = (mK * meanZA * (t1 + value_T(1) / bg2) - dedx) / (bg * t1);
212212
return derH + derH;
213213
}
214214

DataFormats/Reconstruction/src/TrackParametrization.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ GPUd() bool TrackParametrization<value_T>::propagateParamTo(value_t xk, value_t
364364
if (gpu::CAMath::Abs(r2) < constants::math::Almost0) {
365365
return false;
366366
}
367-
double dy2dx = (f1 + f2) / (r1 + r2);
367+
value_t dy2dx = (f1 + f2) / (r1 + r2);
368368
bool arcz = gpu::CAMath::Abs(x2r) > 0.05f;
369369
if (arcz) {
370370
// for small dx/R the linear apporximation of the arc by the segment is OK,

0 commit comments

Comments
 (0)