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
175
176#ifndef GPUCA_GPUCODE
178 void setParams(const float params[/* getNParameters() */]) { std::copy(params, params + getNParameters(), mParams); }
179#endif
180
181#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
185 void performFits(const std::function<double(const double x[/* Dim */])>& func, const uint32_t nAuxiliaryPoints[/* Dim */]);
186
190 void performFits(const std::vector<float>& x, const std::vector<float>& y);
191
195 void loadFromFile(TFile& inpf, const char* name);
196
197 void loadFromFile(const char* fileName, const char* name);
198
202 void writeToFile(TFile& outf, const char* name) const;
203
209 void dumpToTree(const uint32_t nSamplingPoints[/* Dim */], const char* outName = "debug.root", const char* treeName = "tree", const bool recreateFile = true) const;
210
211#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
212#ifndef GPUCA_GPUCODE
213
217
219 uint32_t getNPolynomials() const;
220
222 NDPiecewisePolynomialContainer getContainer() const { return NDPiecewisePolynomialContainer{Dim, Degree, getNParameters(), mParams, InteractionOnly, mMin, mMax, mN}; }
223#endif
224
226 uint32_t getNParameters() const { return getNPolynomials() * MultivariatePolynomialParametersHelper::getNParameters<Degree, Dim, InteractionOnly>(); }
227
229 GPUd() static constexpr uint32_t getDim() { return Dim; }
230
232 GPUd() static constexpr uint32_t getDegree() { return Degree; }
233
235 GPUd() static constexpr bool isInteractionOnly() { return InteractionOnly; }
236
237 private:
238 using DataTParams = float;
239 float mMin[Dim]{};
240 float mMax[Dim]{};
241 float mInvSpacing[Dim]{};
242 uint32_t mN[Dim]{};
243 DataTParams* mParams{nullptr};
244
248 GPUd() int32_t getVertex(const float x, const uint32_t dim) const { return ((x - mMin[dim]) * mInvSpacing[dim]); }
249
252 template <uint32_t TermDim>
253 GPUd() uint32_t getTerms() const
254 {
255 if constexpr (TermDim == 0) {
256 return 1;
257 } else {
258 return (mN[TermDim - 1] - 1) * getTerms<TermDim - 1>();
259 }
260 }
261
264 GPUd() uint32_t getDataIndex(const int32_t ix[/* Dim */]) const { return getDataIndex<Dim - 1>(ix) * MultivariatePolynomialParametersHelper::getNParameters<Degree, Dim, InteractionOnly>(); }
265
267 template <uint32_t DimTmp>
268 GPUd() uint32_t getDataIndex(const int32_t ix[/* Dim */]) const;
269
272 GPUd() const float* getParameters(const int32_t index[/* Dim */]) const { return &mParams[getDataIndex(index)]; }
273
275 template <uint32_t DimTmp>
276 GPUd() void setIndex(const float x[/* Dim */], int32_t index[/* Dim */]) const;
277
279 template <uint32_t DimTmp>
280 GPUd() void clamp(float x[/* Dim */], int32_t index[/* Dim */]) const;
281
282#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
290 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);
291#endif
292
294 void checkPos(const uint32_t iMax[/* Dim */], int32_t pos[/* Dim */]) const;
295
299 double getStepWidth(const uint32_t dim, const int32_t nAuxiliaryPoints) const { return 1 / (static_cast<double>(mInvSpacing[dim]) * (nAuxiliaryPoints - 1)); }
300
304 double getVertexPosition(const uint32_t ix, const int32_t dim) const { return ix / static_cast<double>(mInvSpacing[dim]) + mMin[dim]; }
305
306#if !defined(GPUCA_GPUCODE)
308 std::size_t sizeOfParameters() const { return getNParameters() * sizeof(DataTParams); }
309#endif // #if !defined(GPUCA_GPUCODE)
310
311 // construct the object (flatbuffer)
312 void construct();
313
314 ClassDefNV(NDPiecewisePolynomials, 1);
315};
316
317//=================================================================================
318//============================ inline implementations =============================
319//=================================================================================
320
321#if !defined(GPUCA_GPUCODE)
322template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
324{
325 if (Dim != container.mDim) {
326 LOGP(info, "wrong number of dimensions! this {} container {}", Dim, container.mDim);
327 return;
328 }
329 if (Degree != container.mDegree) {
330 LOGP(info, "wrong number of degrees! this {} container {}", Degree, container.mDegree);
331 return;
332 }
333 if (InteractionOnly != container.mInteractionOnly) {
334 LOGP(info, "InteractionOnly is set for this object to {}, but stored as {} in the container", InteractionOnly, container.mInteractionOnly);
335 return;
336 }
337 init(container.mMin.data(), container.mMax.data(), container.mN.data());
338 setParams(container.mParams.data());
339}
340
341template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
343{
344 const auto nParamsPerPol = MultivariatePolynomialParametersHelper::getNParameters<Degree, Dim, InteractionOnly>();
345 const auto nPols = getNPolynomials();
346 std::vector<float> params(nParamsPerPol);
347 params.front() = 1;
348 for (unsigned int i = 0; i < nPols; ++i) {
349 std::copy(params.begin(), params.end(), &mParams[i * nParamsPerPol]);
350 }
351}
352
353template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
355{
356 uint32_t nP = getNPolynomials(0);
357 for (uint32_t i = 1; i < Dim; ++i) {
358 nP *= getNPolynomials(i);
359 }
360 return nP;
361}
362
363template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
364void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::checkPos(const uint32_t iMax[/* Dim */], int32_t pos[/* Dim */]) const
365{
366 for (uint32_t i = 0; i < Dim; ++i) {
367 if (pos[i] == int32_t(iMax[i])) {
368 ++pos[i + 1];
369 std::fill_n(pos, i + 1, 0);
370 }
371 }
372}
373
374#endif // !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
375
376#ifndef GPUCA_GPUCODE
377template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
379{
380 const char* oldFlatBufferPtr = obj.mFlatBufferPtr;
381 FlatObject::cloneFromObject(obj, newFlatBufferPtr);
382 for (uint32_t i = 0; i < Dim; ++i) {
383 mMin[i] = obj.mMin[i];
384 mMax[i] = obj.mMax[i];
385 mInvSpacing[i] = obj.mInvSpacing[i];
386 mN[i] = obj.mN[i];
387 }
388 if (obj.mParams) {
389 mParams = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mParams);
390 }
391}
392
393template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
395{
396 char* oldFlatBufferPtr = mFlatBufferPtr;
397 FlatObject::moveBufferTo(newFlatBufferPtr);
398 char* currFlatBufferPtr = mFlatBufferPtr;
399 mFlatBufferPtr = oldFlatBufferPtr;
400 setActualBufferAddress(currFlatBufferPtr);
401}
402
403template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
405{
407 const std::size_t flatbufferSize = sizeOfParameters();
408 FlatObject::finishConstruction(flatbufferSize);
409 mParams = reinterpret_cast<DataTParams*>(mFlatBufferPtr);
410}
411
412template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
413void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::init(const float min[], const float max[], const uint32_t n[])
414{
415 for (uint32_t i = 0; i < Dim; ++i) {
416 mMin[i] = min[i];
417 mMax[i] = max[i];
418 mN[i] = n[i];
419 mInvSpacing[i] = (mN[i] - 1) / (mMax[i] - mMin[i]);
420 }
421 construct();
422}
423#endif // !GPUCA_GPUCODE
424
425template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
431
432template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
434{
435 FlatObject::setActualBufferAddress(actualFlatBufferPtr);
436 mParams = reinterpret_cast<DataTParams*>(mFlatBufferPtr);
437}
438
439template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
441{
442 mParams = FlatObject::relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mParams);
443 FlatObject::setFutureBufferAddress(futureFlatBufferPtr);
444}
445
446template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
447template <uint32_t DimTmp>
448GPUd() uint32_t NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::getDataIndex(const int32_t ix[/* Dim */]) const
449{
450 if constexpr (DimTmp > 0) {
451 return ix[DimTmp] * getTerms<DimTmp>() + getDataIndex<DimTmp - 1>(ix);
452 }
453 return ix[DimTmp];
454}
455
456template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
457template <uint32_t DimTmp>
458GPUdi() void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::setIndex(const float x[/* Dim */], int32_t index[/* Dim */]) const
459{
460 index[DimTmp] = getVertex(x[DimTmp], DimTmp);
461 if constexpr (DimTmp > 0) {
462 return setIndex<DimTmp - 1>(x, index);
463 }
464 return;
465}
466
467template <uint32_t Dim, uint32_t Degree, bool InteractionOnly>
468template <uint32_t DimTmp>
469GPUdi() void NDPiecewisePolynomials<Dim, Degree, InteractionOnly>::clamp(float x[/* Dim */], int32_t index[/* Dim */]) const
470{
471 if (index[DimTmp] <= 0) {
472 index[DimTmp] = 0;
473
474 if (x[DimTmp] < mMin[DimTmp]) {
475 x[DimTmp] = mMin[DimTmp];
476 }
477
478 } else {
479 if (index[DimTmp] >= int32_t(mN[DimTmp] - 1)) {
480 index[DimTmp] = mN[DimTmp] - 2;
481 x[DimTmp] = mMax[DimTmp];
482 }
483 }
484
485 if constexpr (DimTmp > 0) {
486 return clamp<DimTmp - 1>(x, index);
487 }
488}
489
490} // namespace o2::gpu
491
492#endif
Definition of FlatObject class.
int32_t i
uint16_t pos
Definition RawData.h:3
void setFutureBufferAddress(char *futureFlatBufferPtr)
Definition FlatObject.h:569
void destroy()
_______________ Utilities _______________________________________________
Definition FlatObject.h:361
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:283
void setActualBufferAddress(char *actualFlatBufferPtr)
_____________ Methods for moving the class with its external buffer to another location _____________...
Definition FlatObject.h:559
void startConstruction()
_____________ Construction _________
Definition FlatObject.h:354
void moveBufferTo(char *newBufferPtr)
Definition FlatObject.h:408
void finishConstruction(int32_t flatBufferSize)
Definition FlatObject.h:370
void cloneFromObject(const FlatObject &obj, char *newFlatBufferPtr)
Definition FlatObject.h:385
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:39
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