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 { return MultivariatePolynomialHelper<Dim, Degree, InteractionOnly>::evalPol(getParameters(index), x); }
145
147 GPUd() float getXMin(const uint32_t dim) const { return mMin[dim]; }
148
150 GPUd() float getXMax(const uint32_t dim) const { return mMax[dim]; }
151
153 GPUd() float getInvSpacing(const uint32_t dim) const { return mInvSpacing[dim]; }
154
156 GPUd() uint32_t getNVertices(const uint32_t dim) const { return mN[dim]; }
157
159 GPUd() uint32_t getNPolynomials(const uint32_t dim) const { return mN[dim] - 1; }
160
162 GPUd() const float* getParams() const { return mParams; }
163
168 void init(const float min[/* Dim */], const float max[/* Dim */], const uint32_t n[/* Dim */]);
169
170#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
172 void setParams(const float params[/* getNParameters() */]) { std::copy(params, params + getNParameters(), mParams); }
173
177 void performFits(const std::function<double(const double x[/* Dim */])>& func, const uint32_t nAuxiliaryPoints[/* Dim */]);
178
182 void performFits(const std::vector<float>& x, const std::vector<float>& y);
183
187 void loadFromFile(TFile& inpf, const char* name);
188
189 void loadFromFile(const char* fileName, const char* name);
190
194 void writeToFile(TFile& outf, const char* name) const;
195
198
204 void dumpToTree(const uint32_t nSamplingPoints[/* Dim */], const char* outName = "debug.root", const char* treeName = "tree", const bool recreateFile = true) const;
205
207 uint32_t getNPolynomials() const;
208
210 NDPiecewisePolynomialContainer getContainer() const { return NDPiecewisePolynomialContainer{Dim, Degree, getNParameters(), mParams, InteractionOnly, mMin, mMax, mN}; }
211
215#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
216
218 uint32_t getNParameters() const { return getNPolynomials() * MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); }
219
221 GPUd() static constexpr uint32_t getDim() { return Dim; }
222
224 GPUd() static constexpr uint32_t getDegree() { return Degree; }
225
227 GPUd() static constexpr bool isInteractionOnly() { return InteractionOnly; }
228
229 private:
230 using DataTParams = float;
231 float mMin[Dim]{};
232 float mMax[Dim]{};
233 float mInvSpacing[Dim]{};
234 uint32_t mN[Dim]{};
235 DataTParams* mParams{nullptr};
236
240 GPUd() int32_t getVertex(const float x, const uint32_t dim) const { return ((x - mMin[dim]) * mInvSpacing[dim]); }
241
244 GPUd() uint32_t getTerms(const uint32_t dim) const { return (dim == 0) ? 1 : (mN[dim - 1] - 1) * getTerms(dim - 1); }
245
248 GPUd() uint32_t getDataIndex(const int32_t ix[/* Dim */]) const { return getDataIndex<Dim - 1>(ix) * MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly); }
249
251 template <uint32_t DimTmp>
252 GPUd() uint32_t getDataIndex(const int32_t ix[/* Dim */]) const;
253
256 GPUd() const float* getParameters(const int32_t index[/* Dim */]) const { return &mParams[getDataIndex(index)]; }
257
259 template <uint32_t DimTmp>
260 GPUd() void setIndex(const float x[/* Dim */], int32_t index[/* Dim */]) const;
261
263 template <uint32_t DimTmp>
264 GPUd() void clamp(float x[/* Dim */], int32_t index[/* Dim */]) const;
265
266#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
274 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);
275
277 void checkPos(const uint32_t iMax[/* Dim */], int32_t pos[/* Dim */]) const;
278
282 double getStepWidth(const uint32_t dim, const int32_t nAuxiliaryPoints) const { return 1 / (static_cast<double>(mInvSpacing[dim]) * (nAuxiliaryPoints - 1)); }
283
287 double getVertexPosition(const uint32_t ix, const int32_t dim) const { return ix / static_cast<double>(mInvSpacing[dim]) + mMin[dim]; }
288#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
289
290#if !defined(GPUCA_GPUCODE)
292 std::size_t sizeOfParameters() const { return getNParameters() * sizeof(DataTParams); }
293#endif // #if !defined(GPUCA_GPUCODE)
294
295 // construct the object (flatbuffer)
296 void construct();
297
298 ClassDefNV(NDPiecewisePolynomials, 1);
299};
300
301//=================================================================================
302//============================ inline implementations =============================
303//=================================================================================
304
305#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
306template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
308{
309 if (Dim != container.mDim) {
310 LOGP(info, "wrong number of dimensions! this {} container {}", Dim, container.mDim);
311 return;
312 }
313 if (Degree != container.mDegree) {
314 LOGP(info, "wrong number of degrees! this {} container {}", Degree, container.mDegree);
315 return;
316 }
317 if (InteractionOnly != container.mInteractionOnly) {
318 LOGP(info, "InteractionOnly is set for this object to {}, but stored as {} in the container", InteractionOnly, container.mInteractionOnly);
319 return;
320 }
321 init(container.mMin.data(), container.mMax.data(), container.mN.data());
322 setParams(container.mParams.data());
323}
324
325template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
327{
328 const auto nParamsPerPol = MultivariatePolynomialParametersHelper::getNParameters(Degree, Dim, InteractionOnly);
329 const auto nPols = getNPolynomials();
330 std::vector<float> params(nParamsPerPol);
331 params.front() = 1;
332 for (auto i = 0; i < nPols; ++i) {
333 std::copy(params.begin(), params.end(), &mParams[i * nParamsPerPol]);
334 }
335}
336
337template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
339{
340 uint32_t nP = getNPolynomials(0);
341 for (uint32_t i = 1; i < Dim; ++i) {
342 nP *= getNPolynomials(i);
343 }
344 return nP;
345}
346
347template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
348void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::checkPos(const uint32_t iMax[/* Dim */], int32_t pos[/* Dim */]) const
349{
350 for (uint32_t i = 0; i < Dim; ++i) {
351 if (pos[i] == int32_t(iMax[i])) {
352 ++pos[i + 1];
353 std::fill_n(pos, i + 1, 0);
354 }
355 }
356}
357
358#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
359
360#ifndef GPUCA_GPUCODE
361template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
363{
364 const char* oldFlatBufferPtr = obj.mFlatBufferPtr;
365 FlatObject::cloneFromObject(obj, newFlatBufferPtr);
366 for (uint32_t i = 0; i < Dim; ++i) {
367 mMin[i] = obj.mMin[i];
368 mMax[i] = obj.mMax[i];
369 mInvSpacing[i] = obj.mInvSpacing[i];
370 mN[i] = obj.mN[i];
371 }
372 if (obj.mParams) {
373 mParams = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mParams);
374 }
375}
376
377template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
379{
380 char* oldFlatBufferPtr = mFlatBufferPtr;
381 FlatObject::moveBufferTo(newFlatBufferPtr);
382 char* currFlatBufferPtr = mFlatBufferPtr;
383 mFlatBufferPtr = oldFlatBufferPtr;
384 setActualBufferAddress(currFlatBufferPtr);
385}
386
387template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
389{
391 const std::size_t flatbufferSize = sizeOfParameters();
392 FlatObject::finishConstruction(flatbufferSize);
393 mParams = reinterpret_cast<DataTParams*>(mFlatBufferPtr);
394}
395
396template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
397void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::init(const float min[], const float max[], const uint32_t n[])
398{
399 for (uint32_t i = 0; i < Dim; ++i) {
400 mMin[i] = min[i];
401 mMax[i] = max[i];
402 mN[i] = n[i];
403 mInvSpacing[i] = (mN[i] - 1) / (mMax[i] - mMin[i]);
404 }
405 construct();
406}
407#endif // !GPUCA_GPUCODE
408
409template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
415
416template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
418{
419 FlatObject::setActualBufferAddress(actualFlatBufferPtr);
420 mParams = reinterpret_cast<DataTParams*>(mFlatBufferPtr);
421}
422
423template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
425{
426 mParams = FlatObject::relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mParams);
427 FlatObject::setFutureBufferAddress(futureFlatBufferPtr);
428}
429
430template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
431template <uint32_t DimTmp>
432GPUdi() uint32_t NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::getDataIndex(const int32_t ix[/* Dim */]) const
433{
434 if constexpr (DimTmp > 0) {
435 return ix[DimTmp] * getTerms(DimTmp) + getDataIndex<DimTmp - 1>(ix);
436 }
437 return ix[DimTmp];
438}
439
440template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
441template <uint32_t DimTmp>
442GPUdi() void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::setIndex(const float x[/* Dim */], int32_t index[/* Dim */]) const
443{
444 index[DimTmp] = getVertex(x[DimTmp], DimTmp);
445 if constexpr (DimTmp > 0) {
446 return setIndex<DimTmp - 1>(x, index);
447 }
448 return;
449}
450
451template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
452template <uint32_t DimTmp>
453GPUdi() void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::clamp(float x[/* Dim */], int32_t index[/* Dim */]) const
454{
455 if (index[DimTmp] <= 0) {
456 index[DimTmp] = 0;
457
458 if (x[DimTmp] < mMin[DimTmp]) {
459 x[DimTmp] = mMin[DimTmp];
460 }
461
462 } else {
463 if (index[DimTmp] >= int32_t(mN[DimTmp] - 1)) {
464 index[DimTmp] = mN[DimTmp] - 2;
465 x[DimTmp] = mMax[DimTmp];
466 }
467 }
468
469 if constexpr (DimTmp > 0) {
470 return clamp<DimTmp - 1>(x, index);
471 }
472}
473
474} // namespace o2::gpu
475
476#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
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