Project
Loading...
Searching...
No Matches
NDPiecewisePolynomials.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#ifndef ALICEO2_TPC_NDPIECEWISEPOLYNOMIALS
16#define ALICEO2_TPC_NDPIECEWISEPOLYNOMIALS
17
18#include "GPUCommonLogger.h"
19#include "FlatObject.h"
21#include "GPUCommonMath.h"
22
23#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
24#include <vector>
25#include <functional>
26#endif
27
28class TFile;
29
30namespace o2::gpu
31{
32
33#if !defined(GPUCA_GPUCODE)
36
46 NDPiecewisePolynomialContainer(const uint32_t dim, const uint32_t degree, const uint32_t nParameters, const float params[/* nParameters*/], const bool interactionOnly, const float xMin[/* Dim*/], const float xMax[/* Dim*/], const uint32_t nVertices[/* Dim*/]) : mDim{dim}, mDegree{degree}, mParams{params, params + nParameters}, mInteractionOnly{interactionOnly}, mMin{xMin, xMin + dim}, mMax{xMax, xMax + dim}, mN{nVertices, nVertices + dim} {};
47
50
51 const uint32_t mDim{};
52 const uint32_t mDegree{};
53 const std::vector<float> mParams{};
54 const bool mInteractionOnly{};
55 const std::vector<float> mMin{};
56 const std::vector<float> mMax{};
57 const std::vector<uint32_t> mN{};
58};
59#endif
60
76template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
78{
79 public:
80#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
85 NDPiecewisePolynomials(const float min[/* Dim */], const float max[/* Dim */], const uint32_t n[/* Dim */]) { init(min, max, n); }
89 NDPiecewisePolynomials(const char* fileName, const char* name)
90 {
91 loadFromFile(fileName, name);
92 };
93#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
95 NDPiecewisePolynomials() = default;
96
99
102
104#if !defined(GPUCA_GPUCODE)
106 void cloneFromObject(const NDPiecewisePolynomials& obj, char* newFlatBufferPtr);
107
110 void moveBufferTo(char* newBufferPtr);
111#endif // !defined(GPUCA_GPUCODE)
112
114 void destroy();
115
117 void setActualBufferAddress(char* actualFlatBufferPtr);
118
120 void setFutureBufferAddress(char* futureFlatBufferPtr);
121
124 GPUd() float eval(float x[/* Dim */]) const
125 {
126 int32_t index[Dim];
127 setIndex<Dim - 1>(x, index);
128 clamp<Dim - 1>(x, index);
130 }
131
134 GPUd() float evalUnsafe(const float x[/* Dim */]) const
135 {
136 int32_t index[Dim];
137 setIndex<Dim - 1>(x, index);
139 }
140
144 GPUd() float evalPol(const float x[/* Dim */], const int32_t index[/* Dim */]) const
145 {
147 }
148
150 GPUd() float getXMin(const uint32_t dim) const { return mMin[dim]; }
151
153 GPUd() float getXMax(const uint32_t dim) const { return mMax[dim]; }
154
156 GPUd() float getInvSpacing(const uint32_t dim) const { return mInvSpacing[dim]; }
157
159 GPUd() uint32_t getNVertices(const uint32_t dim) const { return mN[dim]; }
160
162 GPUd() uint32_t getNPolynomials(const uint32_t dim) const { return mN[dim] - 1; }
163
165 GPUd() const float* getParams() const { return mParams; }
166
171 void init(const float min[/* Dim */], const float max[/* Dim */], const uint32_t n[/* Dim */]);
172
173#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
175 void setParams(const float params[/* getNParameters() */]) { std::copy(params, params + getNParameters(), mParams); }
176
180 void performFits(const std::function<double(const double x[/* Dim */])>& func, const uint32_t nAuxiliaryPoints[/* Dim */]);
181
185 void performFits(const std::vector<float>& x, const std::vector<float>& y);
186
190 void loadFromFile(TFile& inpf, const char* name);
191
192 void loadFromFile(const char* fileName, const char* name);
193
197 void writeToFile(TFile& outf, const char* name) const;
198
201
207 void dumpToTree(const uint32_t nSamplingPoints[/* Dim */], const char* outName = "debug.root", const char* treeName = "tree", const bool recreateFile = true) const;
208
210 uint32_t getNPolynomials() const;
211
213 NDPiecewisePolynomialContainer getContainer() const { return NDPiecewisePolynomialContainer{Dim, Degree, getNParameters(), mParams, InteractionOnly, mMin, mMax, mN}; }
214
218#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
219
221 uint32_t getNParameters() const { return getNPolynomials() * MultivariatePolynomialParametersHelper::getNParameters<Degree, Dim, InteractionOnly>(); }
222
224 GPUd() static constexpr uint32_t getDim() { return Dim; }
225
227 GPUd() static constexpr uint32_t getDegree() { return Degree; }
228
230 GPUd() static constexpr bool isInteractionOnly() { return InteractionOnly; }
231
232 private:
233 using DataTParams = float;
234 float mMin[Dim]{};
235 float mMax[Dim]{};
236 float mInvSpacing[Dim]{};
237 uint32_t mN[Dim]{};
238 DataTParams* mParams{nullptr};
239
243 GPUd() int32_t getVertex(const float x, const uint32_t dim) const { return ((x - mMin[dim]) * mInvSpacing[dim]); }
244
247 template <uint32_t TermDim>
248 GPUd() uint32_t getTerms() const
249 {
250 if constexpr (TermDim == 0) {
251 return 1;
252 } else {
253 return (mN[TermDim - 1] - 1) * getTerms<TermDim - 1>();
254 }
255 }
256
259 GPUd() uint32_t getDataIndex(const int32_t ix[/* Dim */]) const { return getDataIndex<Dim - 1>(ix) * MultivariatePolynomialParametersHelper::getNParameters<Degree, Dim, InteractionOnly>(); }
260
262 template <uint32_t DimTmp>
263 GPUd() uint32_t getDataIndex(const int32_t ix[/* Dim */]) const;
264
267 GPUd() const float* getParameters(const int32_t index[/* Dim */]) const { return &mParams[getDataIndex(index)]; }
268
270 template <uint32_t DimTmp>
271 GPUd() void setIndex(const float x[/* Dim */], int32_t index[/* Dim */]) const;
272
274 template <uint32_t DimTmp>
275 GPUd() void clamp(float x[/* Dim */], int32_t index[/* Dim */]) const;
276
277#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
285 void fitInnerGrid(const std::function<double(const double x[/* Dim */])>& func, const uint32_t nAuxiliaryPoints[/* Dim */], const int32_t currentIndex[/* Dim */], TLinearFitter& fitter, std::vector<double>& xCords, std::vector<double>& response);
286
288 void checkPos(const uint32_t iMax[/* Dim */], int32_t pos[/* Dim */]) const;
289
293 double getStepWidth(const uint32_t dim, const int32_t nAuxiliaryPoints) const { return 1 / (static_cast<double>(mInvSpacing[dim]) * (nAuxiliaryPoints - 1)); }
294
298 double getVertexPosition(const uint32_t ix, const int32_t dim) const { return ix / static_cast<double>(mInvSpacing[dim]) + mMin[dim]; }
299#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
300
301#if !defined(GPUCA_GPUCODE)
303 std::size_t sizeOfParameters() const { return getNParameters() * sizeof(DataTParams); }
304#endif // #if !defined(GPUCA_GPUCODE)
305
306 // construct the object (flatbuffer)
307 void construct();
308
309 ClassDefNV(NDPiecewisePolynomials, 1);
310};
311
312//=================================================================================
313//============================ inline implementations =============================
314//=================================================================================
315
316#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
317template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
319{
320 if (Dim != container.mDim) {
321 LOGP(info, "wrong number of dimensions! this {} container {}", Dim, container.mDim);
322 return;
323 }
324 if (Degree != container.mDegree) {
325 LOGP(info, "wrong number of degrees! this {} container {}", Degree, container.mDegree);
326 return;
327 }
328 if (InteractionOnly != container.mInteractionOnly) {
329 LOGP(info, "InteractionOnly is set for this object to {}, but stored as {} in the container", InteractionOnly, container.mInteractionOnly);
330 return;
331 }
332 init(container.mMin.data(), container.mMax.data(), container.mN.data());
333 setParams(container.mParams.data());
334}
335
336template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
338{
339 const auto nParamsPerPol = MultivariatePolynomialParametersHelper::getNParameters<Degree, Dim, InteractionOnly>();
340 const auto nPols = getNPolynomials();
341 std::vector<float> params(nParamsPerPol);
342 params.front() = 1;
343 for (auto i = 0; i < nPols; ++i) {
344 std::copy(params.begin(), params.end(), &mParams[i * nParamsPerPol]);
345 }
346}
347
348template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
350{
351 uint32_t nP = getNPolynomials(0);
352 for (uint32_t i = 1; i < Dim; ++i) {
353 nP *= getNPolynomials(i);
354 }
355 return nP;
356}
357
358template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
359void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::checkPos(const uint32_t iMax[/* Dim */], int32_t pos[/* Dim */]) const
360{
361 for (uint32_t i = 0; i < Dim; ++i) {
362 if (pos[i] == int32_t(iMax[i])) {
363 ++pos[i + 1];
364 std::fill_n(pos, i + 1, 0);
365 }
366 }
367}
368
369#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
370
371#ifndef GPUCA_GPUCODE
372template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
374{
375 const char* oldFlatBufferPtr = obj.mFlatBufferPtr;
376 FlatObject::cloneFromObject(obj, newFlatBufferPtr);
377 for (uint32_t i = 0; i < Dim; ++i) {
378 mMin[i] = obj.mMin[i];
379 mMax[i] = obj.mMax[i];
380 mInvSpacing[i] = obj.mInvSpacing[i];
381 mN[i] = obj.mN[i];
382 }
383 if (obj.mParams) {
384 mParams = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mParams);
385 }
386}
387
388template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
390{
391 char* oldFlatBufferPtr = mFlatBufferPtr;
392 FlatObject::moveBufferTo(newFlatBufferPtr);
393 char* currFlatBufferPtr = mFlatBufferPtr;
394 mFlatBufferPtr = oldFlatBufferPtr;
395 setActualBufferAddress(currFlatBufferPtr);
396}
397
398template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
400{
402 const std::size_t flatbufferSize = sizeOfParameters();
403 FlatObject::finishConstruction(flatbufferSize);
404 mParams = reinterpret_cast<DataTParams*>(mFlatBufferPtr);
405}
406
407template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
408void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::init(const float min[], const float max[], const uint32_t n[])
409{
410 for (uint32_t i = 0; i < Dim; ++i) {
411 mMin[i] = min[i];
412 mMax[i] = max[i];
413 mN[i] = n[i];
414 mInvSpacing[i] = (mN[i] - 1) / (mMax[i] - mMin[i]);
415 }
416 construct();
417}
418#endif // !GPUCA_GPUCODE
419
420template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
426
427template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
429{
430 FlatObject::setActualBufferAddress(actualFlatBufferPtr);
431 mParams = reinterpret_cast<DataTParams*>(mFlatBufferPtr);
432}
433
434template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
436{
437 mParams = FlatObject::relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mParams);
438 FlatObject::setFutureBufferAddress(futureFlatBufferPtr);
439}
440
441template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
442template <uint32_t DimTmp>
443GPUd() uint32_t NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::getDataIndex(const int32_t ix[/* Dim */]) const
444{
445 if constexpr (DimTmp > 0) {
446 return ix[DimTmp] * getTerms<DimTmp>() + getDataIndex<DimTmp - 1>(ix);
447 }
448 return ix[DimTmp];
449}
450
451template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
452template <uint32_t DimTmp>
453GPUdi() void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::setIndex(const float x[/* Dim */], int32_t index[/* Dim */]) const
454{
455 index[DimTmp] = getVertex(x[DimTmp], DimTmp);
456 if constexpr (DimTmp > 0) {
457 return setIndex<DimTmp - 1>(x, index);
458 }
459 return;
460}
461
462template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
463template <uint32_t DimTmp>
464GPUdi() void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::clamp(float x[/* Dim */], int32_t index[/* Dim */]) const
465{
466 if (index[DimTmp] <= 0) {
467 index[DimTmp] = 0;
468
469 if (x[DimTmp] < mMin[DimTmp]) {
470 x[DimTmp] = mMin[DimTmp];
471 }
472
473 } else {
474 if (index[DimTmp] >= int32_t(mN[DimTmp] - 1)) {
475 index[DimTmp] = mN[DimTmp] - 2;
476 x[DimTmp] = mMax[DimTmp];
477 }
478 }
479
480 if constexpr (DimTmp > 0) {
481 return clamp<DimTmp - 1>(x, index);
482 }
483}
484
485} // namespace o2::gpu
486
487#endif
Definition of FlatObject class.
int32_t i
uint16_t pos
Definition RawData.h:3
GPUCA_GPUCODE.
Definition FlatObject.h:176
void setFutureBufferAddress(char *futureFlatBufferPtr)
Definition FlatObject.h:557
void destroy()
_______________ Utilities _______________________________________________
Definition FlatObject.h:349
static T * relocatePointer(const char *oldBase, char *newBase, const T *ptr)
Relocates a pointer inside a buffer to the new buffer address.
Definition FlatObject.h:285
void setActualBufferAddress(char *actualFlatBufferPtr)
_____________ Methods for moving the class with its external buffer to another location _____________...
Definition FlatObject.h:547
void startConstruction()
_____________ Construction _________
Definition FlatObject.h:342
void moveBufferTo(char *newBufferPtr)
Definition FlatObject.h:396
void finishConstruction(int32_t flatBufferSize)
Definition FlatObject.h:358
void cloneFromObject(const FlatObject &obj, char *newFlatBufferPtr)
Definition FlatObject.h:373
void performFits(const std::vector< float > &x, const std::vector< float > &y)
void setActualBufferAddress(char *actualFlatBufferPtr)
set location of external flat buffer
~NDPiecewisePolynomials()=default
default destructor
GPUd() static const expr uint32_t getDim()
void writeToFile(TFile &outf, const char *name) const
void cloneFromObject(const NDPiecewisePolynomials &obj, char *newFlatBufferPtr)
========== FlatObject functionality, see FlatObject class for description =================
void setParams(const float params[])
Setting directly the parameters of the polynomials.
GPUd() static const expr bool isInteractionOnly()
void loadFromFile(const char *fileName, const char *name)
GPUd() float getXMin(const uint32_t dim) const
void setDefault()
setting default polynomials which just returns 1
void dumpToTree(const uint32_t nSamplingPoints[], const char *outName="debug.root", const char *treeName="tree", const bool recreateFile=true) const
void init(const float min[], const float max[], const uint32_t n[])
GPUd() uint32_t getNPolynomials(const uint32_t dim) const
NDPiecewisePolynomials(const NDPiecewisePolynomials &obj)
Copy constructor.
NDPiecewisePolynomialContainer getContainer() const
converts the class to a container which can be written to a root file
void performFits(const std::function< double(const double x[])> &func, const uint32_t nAuxiliaryPoints[])
void destroy()
destroy the object (release internal flat buffer)
GPUd() static const expr uint32_t getDegree()
void loadFromFile(TFile &inpf, const char *name)
GPUd() float getInvSpacing(const uint32_t dim) const
GPUd() float eval(float x[]) const
GPUd() const float *getParams() const
void setFromContainer(const NDPiecewisePolynomialContainer &container)
NDPiecewisePolynomials(const char *fileName, const char *name)
GPUd() float evalUnsafe(const float x[]) const
NDPiecewisePolynomials()=default
default constructor
GPUd() float getXMax(const uint32_t dim) const
GPUd() uint32_t getNVertices(const uint32_t dim) const
NDPiecewisePolynomials(const float min[], const float max[], const uint32_t n[])
void setFutureBufferAddress(char *futureFlatBufferPtr)
set future location of the flat buffer
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum func
Definition glcorearb.h:778
GLuint index
Definition glcorearb.h:781
GLuint const GLchar * name
Definition glcorearb.h:781
GLenum const GLfloat * params
Definition glcorearb.h:272
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLenum clamp
Definition glcorearb.h:1245
GPUdi() o2
Definition TrackTRD.h:38
GPUd() const expr uint32_t MultivariatePolynomialHelper< Dim
const int ix
Definition TrackUtils.h:69
simple struct to enable writing the NDPiecewisePolynomials to file
const std::vector< float > mMax
max vertices positions of the grid
NDPiecewisePolynomialContainer()=default
for ROOT I/O
const std::vector< float > mMin
min vertices positions of the grid
const bool mInteractionOnly
consider only interaction terms
NDPiecewisePolynomialContainer(const uint32_t dim, const uint32_t degree, const uint32_t nParameters, const float params[], const bool interactionOnly, const float xMin[], const float xMax[], const uint32_t nVertices[])
const std::vector< float > mParams
parameters of the polynomial
const uint32_t mDim
number of dimensions of the polynomial
const uint32_t mDegree
degree of the polynomials
const std::vector< uint32_t > mN
number of vertices for each dimension
constexpr size_t min
constexpr size_t max