23#include <TGeoGlobalMagField.h>
25#if !defined(GPUCA_NO_ROOT) && defined(GPUCA_O2_LIB)
41 initializeUniformsFromField(field);
47 std::mt19937 rng(0xDEADBEEF);
50 std::uniform_int_distribution<int32_t> generator_x(-512, 512);
51 std::uniform_int_distribution<int32_t> generator_y(-512, 512);
52 std::uniform_int_distribution<int32_t> generator_z(-455 - 1312, -455 + 1312);
56 for (std::size_t
i = 0;
i <
count; ++
i) {
61template <std::
size_t MAX_DIM1_SEGMENTS, std::
size_t MAX_DIM2_SEGMENTS, std::
size_t MAX_DIM3_SEGMENTS>
66 file.read(
reinterpret_cast<char*
>(&
segments.MultiplicativeFactor),
sizeof(
segments.MultiplicativeFactor));
68 std::size_t NSegDim1, NSegDim2, NSegDim3;
70 file.read(
reinterpret_cast<char*
>(&NSegDim1),
sizeof(std::int32_t));
71 assert(NSegDim1 <= MAX_DIM1_SEGMENTS);
77 file.read(
reinterpret_cast<char*
>(
segments.BegSegDim2), NSegDim1 *
sizeof(
segments.BegSegDim2[0]));
80 file.read(
reinterpret_cast<char*
>(&NSegDim2),
sizeof(std::int32_t));
81 assert(NSegDim2 <= MAX_DIM2_SEGMENTS);
85 file.read(
reinterpret_cast<char*
>(
segments.BegSegDim3), NSegDim2 *
sizeof(
segments.BegSegDim3[0]));
88 file.read(
reinterpret_cast<char*
>(&NSegDim3),
sizeof(std::int32_t));
89 assert(NSegDim3 <= MAX_DIM3_SEGMENTS);
94 return std::make_tuple(NSegDim1, NSegDim2, NSegDim3);
97template <std::
size_t DIMENSIONS, std::
size_t MAX_PARAMETERIZATIONS, std::
size_t MAX_ROWS, std::
size_t MAX_COLUMNS, std::
size_t MAX_COEFFICIENTS>
100 std::size_t NParams, NRows, NColumns, NCoefficients;
101 file.read(
reinterpret_cast<char*
>(&NParams),
sizeof(std::int32_t));
102 assert(NParams <= (MAX_PARAMETERIZATIONS / DIMENSIONS));
104 file.read(
reinterpret_cast<char*
>(parametrizations.
BOffsets), DIMENSIONS * NParams *
sizeof(parametrizations.
BOffsets[0]));
105 file.read(
reinterpret_cast<char*
>(parametrizations.
BScales), DIMENSIONS * NParams *
sizeof(parametrizations.
BScales[0]));
106 file.read(
reinterpret_cast<char*
>(parametrizations.
BMin), DIMENSIONS * NParams *
sizeof(parametrizations.
BMin[0]));
107 file.read(
reinterpret_cast<char*
>(parametrizations.
BMax), DIMENSIONS * NParams *
sizeof(parametrizations.
BMax[0]));
109 file.read(
reinterpret_cast<char*
>(parametrizations.
NRows), DIMENSIONS * NParams *
sizeof(parametrizations.
NRows[0]));
113 file.read(
reinterpret_cast<char*
>(&NRows),
sizeof(std::int32_t));
114 assert(NRows <= MAX_ROWS);
119 file.read(
reinterpret_cast<char*
>(&NColumns),
sizeof(std::int32_t));
120 assert(NColumns <= MAX_COLUMNS);
125 file.read(
reinterpret_cast<char*
>(&NCoefficients),
sizeof(std::int32_t));
126 assert(NCoefficients <= MAX_COEFFICIENTS);
128 file.read(
reinterpret_cast<char*
>(parametrizations.
Coeffs), NCoefficients *
sizeof(parametrizations.
Coeffs[0]));
130 return std::make_tuple(NParams, NRows, NColumns, NCoefficients);
143 file.open(
"field.uniform", std::ifstream::binary);
146 GPUError(
"Cannot load field file \"field.uniform\" from the working directory.");
179#if !defined(GPUCA_NO_ROOT) && defined(GPUCA_O2_LIB)
194 GPUError(
"Error loading magnetic field data");
198 return initializeUniformsFromField(field);
208 GPUError(
"Model has too many Solenoid parametrization regions to fit in the designated uniform");
212 const auto numberOfParameterizationDipole = chebMap->getNumberOfParametersDip();
215 GPUError(
"Model has too many Dipole parametrization regions to fit in the designated uniform");
222 Int_t numberOfDistinctDim1Segments;
223 Int_t numberOfDistinctDim2Segments;
224 Int_t numberOfDistinctDim3Segments;
225 Float_t* coordinatesSegmentsDim1;
226 Float_t* coordinatesSegmentsDim2;
227 Float_t* coordinatesSegmentsDim3;
228 Int_t* beginningOfSegmentsDim2;
229 Int_t* beginningOfSegmentsDim3;
230 Int_t* numberOfSegmentsDim2;
231 Int_t* numberOfSegmentsDim3;
236 delete[] coordinatesSegmentsDim1;
237 delete[] coordinatesSegmentsDim2;
238 delete[] coordinatesSegmentsDim3;
239 delete[] beginningOfSegmentsDim2;
240 delete[] beginningOfSegmentsDim3;
241 delete[] numberOfSegmentsDim2;
242 delete[] numberOfSegmentsDim3;
247 TableInfo solenoidTableInfo, dipoleTableInfo;
249 const auto parameterizationSolenoid = std::make_unique<TObjArray>();
251 for (
auto i = 0;
i < numberOfParameterizationSolenoid; ++
i) {
252 parameterizationSolenoid->Add(chebMap->getParameterSolenoid(
i));
255 chebMap->buildTable(numberOfParameterizationSolenoid, parameterizationSolenoid.get(), solenoidTableInfo.numberOfDistinctDim1Segments,
256 solenoidTableInfo.numberOfDistinctDim2Segments, solenoidTableInfo.numberOfDistinctDim3Segments, solenoidTableInfo.minZ, solenoidTableInfo.maxZ,
257 &solenoidTableInfo.coordinatesSegmentsDim1, &solenoidTableInfo.coordinatesSegmentsDim2, &solenoidTableInfo.coordinatesSegmentsDim3,
258 &solenoidTableInfo.beginningOfSegmentsDim2, &solenoidTableInfo.numberOfSegmentsDim2, &solenoidTableInfo.beginningOfSegmentsDim3,
259 &solenoidTableInfo.numberOfSegmentsDim3, &solenoidTableInfo.segmentId);
261 LOGF(info,
"Solenoid minZ: %f maxZ: %f", solenoidTableInfo.minZ, solenoidTableInfo.maxZ);
262 LOGF(info,
"Solenoid segment count: Z %d P %d R %d", solenoidTableInfo.numberOfDistinctDim1Segments, solenoidTableInfo.numberOfDistinctDim2Segments, solenoidTableInfo.numberOfDistinctDim3Segments);
264 const auto parameterizationDipole = std::make_unique<TObjArray>();
266 for (
auto i = 0;
i < numberOfParameterizationDipole; ++
i) {
267 parameterizationDipole->Add(chebMap->getParameterDipole(
i));
270 chebMap->buildTable(numberOfParameterizationDipole, parameterizationDipole.get(), dipoleTableInfo.numberOfDistinctDim1Segments,
271 dipoleTableInfo.numberOfDistinctDim2Segments, dipoleTableInfo.numberOfDistinctDim3Segments, dipoleTableInfo.minZ, dipoleTableInfo.maxZ,
272 &dipoleTableInfo.coordinatesSegmentsDim1, &dipoleTableInfo.coordinatesSegmentsDim2, &dipoleTableInfo.coordinatesSegmentsDim3,
273 &dipoleTableInfo.beginningOfSegmentsDim2, &dipoleTableInfo.numberOfSegmentsDim2, &dipoleTableInfo.beginningOfSegmentsDim3,
274 &dipoleTableInfo.numberOfSegmentsDim3, &dipoleTableInfo.segmentId);
276 LOGF(info,
"Dipole minZ: %f maxZ: %f", dipoleTableInfo.minZ, dipoleTableInfo.maxZ);
277 LOGF(info,
"Dipole segment count: Z %d Y %d X %d", dipoleTableInfo.numberOfDistinctDim1Segments, dipoleTableInfo.numberOfDistinctDim2Segments, dipoleTableInfo.numberOfDistinctDim3Segments);
279 const auto getParameterSolenoid = [chebMap](Int_t
i) {
return chebMap->getParameterSolenoid(
i); };
280 const auto getParameterDipole = [chebMap](Int_t
i) {
return chebMap->getParameterDipole(
i); };
282 auto countArraySizes = [](int32_t numberOfParametrization,
auto& getParameter) {
283 int32_t TotalRows = 0, TotalColumns = 0, TotalCoefficients = 0;
284 UShort_t MaxChebyshevOrder = 0;
286 for (
auto i = 0;
i < numberOfParametrization; ++
i) {
287 const auto param = getParameter(
i);
290 const auto calc =
param->getChebyshevCalc(
j);
292 const auto NRows = calc->getNumberOfRows();
295 const auto colsAtRow = calc->getNumberOfColumnsAtRow();
298 const auto NCols = colsAtRow[
row];
299 TotalColumns += NCols;
301 const auto col0 = calc->getColAtRowBg()[
row];
304 const auto ncoffs = calc->getCoefficientBound2D0()[col0 +
col];
305 MaxChebyshevOrder = std::max(MaxChebyshevOrder, ncoffs);
309 TotalCoefficients += calc->getNumberOfCoefficients();
313 return std::make_tuple(TotalRows, TotalColumns, TotalCoefficients, MaxChebyshevOrder);
316 const auto [TotalRowsSolenoid, TotalColumnsSolenoid, TotalCoefficientsSolenoid, MaxChebyshevOrderSolenoid] = countArraySizes(numberOfParameterizationSolenoid, getParameterSolenoid);
317 const auto [TotalRowsDipole, TotalColumnsDipole, TotalCoefficientsDipole, MaxChebyshevOrderDipole] = countArraySizes(numberOfParameterizationDipole, getParameterDipole);
319 LOGF(info,
"Solenoid Params: %d Rows %d Columns %d Coefficients %d MaxChebOrder: %d", numberOfParameterizationSolenoid, TotalRowsSolenoid, TotalColumnsSolenoid, TotalCoefficientsSolenoid, MaxChebyshevOrderSolenoid);
320 LOGF(info,
"Dipole Params: %d Rows %d Columns %d Coefficients %d MaxChebOrder: %d", numberOfParameterizationDipole, TotalRowsDipole, TotalColumnsDipole, TotalCoefficientsDipole, MaxChebyshevOrderDipole);
327 reason =
"Solenoid Z segment";
330 reason =
"Solenoid P segment";
333 reason =
"Solenoid R segment";
336 reason =
"Dipole Z Segment";
339 reason =
"Dipole Y Segment";
342 reason =
"Dipole X Segment";
345 reason =
"Solenoid Rows";
348 reason =
"Solenoid Columns";
351 reason =
"Solenoid Coefficients";
354 reason =
"Dipole Rows";
357 reason =
"Dipole Columns";
360 reason =
"Dipole Coefficients";
361 }
else if (std::max(MaxChebyshevOrderSolenoid, MaxChebyshevOrderDipole) >
MAX_CHEBYSHEV_ORDER) {
363 reason =
"Chebyshev Polynomial order";
367 GPUError(
"Model has too large %s to fit in the designated uniform", reason);
372 std::copy(info.coordinatesSegmentsDim1, info.coordinatesSegmentsDim1 + info.numberOfDistinctDim1Segments,
segments.SegDim1);
374 std::copy(info.beginningOfSegmentsDim2, info.beginningOfSegmentsDim2 + info.numberOfDistinctDim1Segments,
segments.BegSegDim2);
375 std::copy(info.numberOfSegmentsDim2, info.numberOfSegmentsDim2 + info.numberOfDistinctDim1Segments,
segments.NSegDim2);
377 std::copy(info.coordinatesSegmentsDim2, info.coordinatesSegmentsDim2 + info.numberOfDistinctDim2Segments,
segments.SegDim2);
379 std::copy(info.beginningOfSegmentsDim3, info.beginningOfSegmentsDim3 + info.numberOfDistinctDim2Segments,
segments.BegSegDim3);
380 std::copy(info.numberOfSegmentsDim3, info.numberOfSegmentsDim3 + info.numberOfDistinctDim2Segments,
segments.NSegDim3);
381 std::copy(info.coordinatesSegmentsDim3, info.coordinatesSegmentsDim3 + info.numberOfDistinctDim3Segments,
segments.SegDim3);
383 std::copy(info.segmentId, info.segmentId + info.numberOfDistinctDim3Segments,
segments.SegID);
392 auto initParametrization = [](int32_t numberOfParametrization,
auto& getParameter,
auto& parametrizationUniform) {
393 int32_t ColsAtRowOffset = 0, CofsAtRowOffset = 0, CofsAtColOffset = 0, Coeffs = 0;
395 for (
auto i = 0;
i < numberOfParametrization; ++
i) {
396 const auto param = getParameter(
i);
403 const auto calc =
param->getChebyshevCalc(
j);
405 const auto NRows = calc->getNumberOfRows();
407 parametrizationUniform->NRows[
i *
DIMENSIONS +
j] = NRows;
408 parametrizationUniform->ColsAtRowOffset[
i *
DIMENSIONS +
j] = ColsAtRowOffset;
409 parametrizationUniform->CofsAtRowOffset[
i *
DIMENSIONS +
j] = CofsAtRowOffset;
411 const auto colsAtRow = calc->getNumberOfColumnsAtRow();
414 const auto NCols = colsAtRow[
row];
415 parametrizationUniform->NColsAtRow[ColsAtRowOffset +
row] = NCols;
416 parametrizationUniform->CofsAtColOffset[ColsAtRowOffset +
row] = CofsAtColOffset;
418 const auto col0 = calc->getColAtRowBg()[
row];
421 const auto ncoffs = calc->getCoefficientBound2D0()[col0 +
col];
422 const auto offset = calc->getCoefficientBound2D1()[col0 +
col];
424 parametrizationUniform->NCofsAtCol[CofsAtColOffset +
col] = ncoffs;
425 parametrizationUniform->AtColCoefOffset[CofsAtColOffset +
col] =
offset;
427 CofsAtColOffset += NCols;
430 ColsAtRowOffset += NRows;
431 CofsAtRowOffset += calc->getNumberOfCoefficients();
433 std::copy(calc->getCoefficients(), calc->getCoefficients() + calc->getNumberOfCoefficients(), ¶metrizationUniform->Coeffs[Coeffs]);
435 Coeffs += calc->getNumberOfCoefficients();
439 return std::make_tuple(ColsAtRowOffset, CofsAtColOffset, Coeffs);
445 const auto [SRows, SCols, SCoeffs] = initParametrization(numberOfParameterizationSolenoid, getParameterSolenoid,
mSolenoidParameterization);
446 const auto [DRows, DCols, DCoeffs] = initParametrization(numberOfParameterizationDipole, getParameterDipole,
mDipoleParameterization);
448 assert(TotalRowsSolenoid == SRows);
449 assert(TotalColumnsSolenoid == SCols);
450 assert(TotalCoefficientsSolenoid == SCoeffs);
451 assert(TotalRowsDipole == DRows);
452 assert(TotalColumnsDipole == DCols);
453 assert(TotalCoefficientsDipole == DCoeffs);
463 mDipoleSegments->ZSegments = dipoleTableInfo.numberOfDistinctDim1Segments;
465 mSolSegDim1 = solenoidTableInfo.numberOfDistinctDim1Segments;
466 mSolSegDim2 = solenoidTableInfo.numberOfDistinctDim2Segments;
467 mSolSegDim3 = solenoidTableInfo.numberOfDistinctDim3Segments;
474 mDipSegDim1 = dipoleTableInfo.numberOfDistinctDim1Segments;
475 mDipSegDim2 = dipoleTableInfo.numberOfDistinctDim2Segments;
476 mDipSegDim3 = dipoleTableInfo.numberOfDistinctDim3Segments;
Definition of the GeometryManager class.
std::tuple< std::size_t, std::size_t, std::size_t, std::size_t > loadParams(std::ifstream &file, GPUDisplayMagneticField::ParametrizationUniform< MAX_PARAMETERIZATIONS, MAX_ROWS, MAX_COLUMNS, MAX_COEFFICIENTS > ¶metrizations)
std::tuple< std::size_t, std::size_t, std::size_t > loadSegments(std::ifstream &file, GPUDisplayMagneticField::SegmentsUniform< MAX_DIM1_SEGMENTS, MAX_DIM2_SEGMENTS, MAX_DIM3_SEGMENTS > &segments)
Header of the General Run Parameters object.
static void loadGeometry(std::string_view geomFilePath="", bool applyMisalignment=false, bool preferAlignedFile=true)
static int initFieldFromGRP(const o2::parameters::GRPMagField *grp, bool verbose=false)
Double_t getFactorDipole() const
Return the sign*scale of the current in the Dipole according to sPolarityConventionthe.
Double_t getFactorSolenoid() const
Returns the sign*scale of the current in the Dipole according to sPolarityConventionthe.
MagneticWrapperChebyshev * getMeasuredMap() const
Int_t getNumberOfParametersSol() const
std::unique_ptr< RenderConstantsUniform > mRenderConstantsUniform
std::unique_ptr< SolenoidSegmentsUniform > mSolenoidSegments
static constexpr std::size_t MAX_SOLENOID_R_SEGMENTS
static constexpr std::size_t MAX_DIPOLE_ROWS
static constexpr std::size_t MAX_CHEBYSHEV_ORDER
static constexpr std::size_t MAX_SOLENOID_COEFFICIENTS
std::unique_ptr< DipoleParameterizationUniform > mDipoleParameterization
static constexpr std::size_t MAX_DIPOLE_Y_SEGMENTS
static constexpr std::size_t MAX_DIPOLE_PARAMETERIZATIONS
static constexpr std::size_t MAX_DIPOLE_X_SEGMENTS
static constexpr std::size_t DIMENSIONS
static constexpr std::size_t MAX_DIPOLE_Z_SEGMENTS
std::vector< vtx > mFieldLineSeedPoints
std::size_t mSolParametrizations
std::size_t mDipParametrizations
GPUDisplayMagneticField()
static constexpr std::size_t MAX_DIPOLE_COLUMNS
std::size_t mSolCoefficients
void generateSeedPoints(std::size_t count)
static constexpr std::size_t MAX_SOLENOID_COLUMNS
static constexpr std::size_t MAX_SOLENOID_P_SEGMENTS
std::unique_ptr< SolenoidParameterizationUniform > mSolenoidParameterization
static constexpr std::size_t MAX_SOLENOID_Z_SEGMENTS
static constexpr std::size_t MAX_SOLENOID_PARAMETERIZATIONS
static constexpr std::size_t MAX_DIPOLE_COEFFICIENTS
std::unique_ptr< DipoleSegmentsUniform > mDipoleSegments
int32_t initializeUniforms()
std::size_t mDipCoefficients
static constexpr std::size_t MAX_SOLENOID_ROWS
static GRPObject * loadFrom(const std::string &grpFileName="")
GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat maxZ