Project
Loading...
Searching...
No Matches
Spline1DSpec.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
16
17#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINE1DSPEC_H
18#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINE1DSPEC_H
19
20#include "GPUCommonDef.h"
21#include "FlatObject.h"
22#include "SplineUtil.h"
23
24#if !defined(GPUCA_GPUCODE)
25#include <functional>
26#endif
27
28class TFile;
29
30namespace o2
31{
32namespace gpu
33{
34
44template <typename DataT>
46{
47 public:
51
54 struct Knot {
55 DataT u;
56 DataT Li;
58 GPUd() int32_t getU() const { return (int32_t)(u + 0.1f); }
59 };
60
62
64 GPUd() static constexpr int32_t getVersion() { return 1; }
65
67
69 Spline1DContainer() = default;
70
73
75 ~Spline1DContainer() = default;
76
78
79#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
81 void approximateFunction(double xMin, double xMax,
82 std::function<void(double x, double f[/*mYdim*/])> F,
83 int32_t nAuxiliaryDataPoints = 4);
84#endif
85
87
88#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
90 int32_t writeToFile(TFile& outf, const char* name);
91
93 static Spline1DContainer* readFromFile(TFile& inpf, const char* name);
94#endif
95
97
99 GPUd() int32_t getUmax() const { return mUmax; }
100
102 GPUd() int32_t getYdimensions() const { return mYdim; }
103
105 GPUd() size_t getParameterAlignmentBytes() const
106 {
107 size_t s = 2 * sizeof(DataT) * mYdim;
108 return (s < 16) ? s : 16;
109 }
110
112 GPUd() int32_t getNumberOfParameters() const { return calcNumberOfParameters(mYdim); }
113
115 GPUd() size_t getSizeOfParameters() const { return sizeof(DataT) * getNumberOfParameters(); }
116
118 GPUd() int32_t getNumberOfKnots() const { return mNumberOfKnots; }
119
121 GPUd() const Knot* getKnots() const { return reinterpret_cast<const Knot*>(mFlatBufferPtr); }
122
124 template <SafetyLevel SafeT = SafetyLevel::kSafe>
125 GPUd() const Knot& getKnot(int32_t i) const
126 {
127 if (SafeT == SafetyLevel::kSafe) {
128 i = (i < 0) ? 0 : (i >= mNumberOfKnots ? mNumberOfKnots - 1 : i);
129 }
130 return getKnots()[i];
131 }
132
134 template <SafetyLevel SafeT = SafetyLevel::kSafe>
135 GPUd() int32_t getLeftKnotIndexForU(DataT u) const;
136
138 GPUd() DataT* getParameters() { return mParameters; }
139
141 GPUd() const DataT* getParameters() const { return mParameters; }
142
144
146 GPUd() const int32_t* getUtoKnotMap() const { return mUtoKnotMap; }
147
149 GPUd() DataT convXtoU(DataT x) const { return (x - mXmin) * mXtoUscale; }
150
152 GPUd() DataT convUtoX(DataT u) const { return mXmin + u / mXtoUscale; }
153
155 GPUd() DataT getXmin() const { return mXmin; }
156
158 GPUd() DataT getXmax() const { return mXmin + mUmax / mXtoUscale; }
159
161 GPUd() DataT getXtoUscale() const { return mXtoUscale; }
162
164 GPUd() void setXrange(DataT xMin, DataT xMax);
165
167 void print() const;
168
170
172 GPUd() int32_t calcNumberOfParameters(int32_t nYdim) const { return (2 * nYdim) * getNumberOfKnots(); }
173
175
176#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) // code invisible on GPU and in the standalone compilation
178 static int32_t test(const bool draw = 0, const bool drawDataPoints = 1);
179#endif
180
182
185
186#if !defined(GPUCA_GPUCODE)
187 void cloneFromObject(const Spline1DContainer& obj, char* newFlatBufferPtr);
188 void moveBufferTo(char* newBufferPtr);
189#endif
190
192
193 void destroy();
194 void setActualBufferAddress(char* actualFlatBufferPtr);
195 void setFutureBufferAddress(char* futureFlatBufferPtr);
196
197 protected:
199 Knot* getKnots() { return reinterpret_cast<Knot*>(mFlatBufferPtr); }
200
202 int32_t* getUtoKnotMap() { return mUtoKnotMap; }
203
204#if !defined(GPUCA_GPUCODE)
206 void recreate(int32_t nYdim, int32_t numberOfKnots);
207
209 void recreate(int32_t nYdim, int32_t numberOfKnots, const int32_t knotU[]);
210#endif
211
213
214 int32_t mYdim = 0;
215 int32_t mNumberOfKnots = 0;
216 int32_t mUmax = 0;
217 DataT mXmin = 0;
218 DataT mXtoUscale = 0;
219 int32_t* mUtoKnotMap = nullptr;
220 DataT* mParameters = nullptr;
221
223};
224
225template <typename DataT>
226template <typename Spline1DContainer<DataT>::SafetyLevel SafeT>
227GPUdi() int32_t Spline1DContainer<DataT>::getLeftKnotIndexForU(DataT u) const
228{
231 int32_t iu = u < 0 ? 0 : (u > (float)mUmax ? mUmax : (int32_t)u);
232 if (SafeT == SafetyLevel::kSafe) {
233 iu = (iu < 0) ? 0 : (iu > mUmax ? mUmax : iu);
234 }
235 return getUtoKnotMap()[iu];
236}
237
238template <typename DataT>
239GPUdi() void Spline1DContainer<DataT>::setXrange(DataT xMin, DataT xMax)
240{
241 mXmin = xMin;
242 double l = ((double)xMax) - xMin;
243 if (l < 1.e-8) {
244 l = 1.e-8;
245 }
246 mXtoUscale = mUmax / l;
247}
248
269template <typename DataT, int32_t YdimT, int32_t SpecT>
271
276template <typename DataT, int32_t YdimT>
277class Spline1DSpec<DataT, YdimT, 0> : public Spline1DContainer<DataT>
278{
280
281 public:
283 typedef typename TBase::Knot Knot;
284
286
288 GPUd() void interpolate(DataT x, GPUgeneric() DataT S[/*mYdim*/]) const
289 {
290 interpolateU<SafetyLevel::kSafe>(mYdim, mParameters, convXtoU(x), S);
291 }
292
294 template <SafetyLevel SafeT = SafetyLevel::kSafe>
295 GPUd() void interpolateU(int32_t inpYdim, GPUgeneric() const DataT Parameters[],
296 DataT u, GPUgeneric() DataT S[/*nYdim*/]) const
297 {
298 const auto nYdimTmp = SplineUtil::getNdim<YdimT>(inpYdim);
299 const auto nYdim = nYdimTmp.get();
300 int32_t iknot = TBase::template getLeftKnotIndexForU<SafeT>(u);
301 const DataT* d = Parameters + (2 * nYdim) * iknot;
302 interpolateU(nYdim, getKnots()[iknot], &(d[0]), &(d[nYdim]), &(d[2 * nYdim]), &(d[3 * nYdim]), u, S);
303 }
304
308 template <typename T>
309 GPUd() void interpolateU(int32_t inpYdim, const Knot& knotL,
310 GPUgeneric() const T Sl[/*mYdim*/], GPUgeneric() const T Dl[/*mYdim*/],
311 GPUgeneric() const T Sr[/*mYdim*/], GPUgeneric() const T Dr[/*mYdim*/],
312 DataT u, GPUgeneric() T S[/*mYdim*/]) const
313 {
314 const auto nYdimTmp = SplineUtil::getNdim<YdimT>(inpYdim);
315 const auto nYdim = nYdimTmp.get();
316 T uu = T(u - knotL.u);
317 T li = T(knotL.Li);
318 T v = uu * li; // scaled u
319 for (int32_t dim = 0; dim < nYdim; ++dim) {
320 T df = (Sr[dim] - Sl[dim]) * li;
321 T a = Dl[dim] + Dr[dim] - df - df;
322 T b = df - Dl[dim] - a;
323 S[dim] = ((a * v + b) * v + Dl[dim]) * uu + Sl[dim];
324 }
325 /*
326 another way to calculate f(u):
327 T uu = T(u - knotL.u);
328 T v = uu * T(knotL.Li); // scaled u
329 T vm1 = v-1;
330 T v2 = v * v;
331 float cSr = v2*(3-2*v);
332 float cSl = 1-cSr;
333 float cDl = v*vm1*vm1*knotL.L;
334 float cDr = v2*vm1*knotL.L;
335 return cSl*Sl + cSr*Sr + cDl*Dl + cDr*Dr;
336 */
337 }
338
339 template <typename T>
340 GPUd() static void getUderivatives(const Knot& knotL, DataT u,
341 T& dSl, T& dDl, T& dSr, T& dDr)
342 {
345 u = u - knotL.u;
346 T v = u * T(knotL.Li); // scaled u
347 T vm1 = v - 1.;
348 T a = u * vm1;
349 T v2 = v * v;
350 dSr = v2 * (3. - 2 * v);
351 dSl = 1. - dSr;
352 dDl = vm1 * a;
353 dDr = v * a;
354 // F(u) = dSl * Sl + dSr * Sr + dDl * Dl + dDr * Dr;
355 }
356
357 using TBase::convXtoU;
358 using TBase::getKnot;
359 using TBase::getKnots;
360 using TBase::getNumberOfKnots;
361
362 protected:
363 using TBase::mParameters;
364 using TBase::mYdim;
365 using TBase::TBase; // inherit constructors and hide them
367};
368
373template <typename DataT, int32_t YdimT>
374class Spline1DSpec<DataT, YdimT, 1>
375 : public Spline1DSpec<DataT, YdimT, 0>
376{
379
380 public:
382
383#if !defined(GPUCA_GPUCODE)
386
388 Spline1DSpec(int32_t numberOfKnots) : TBase()
389 {
390 recreate(numberOfKnots);
391 }
393 Spline1DSpec(int32_t numberOfKnots, const int32_t knotU[])
394 : TBase()
395 {
396 recreate(numberOfKnots, knotU);
397 }
400 {
401 TBase::cloneFromObject(v, nullptr);
402 }
404 void recreate(int32_t numberOfKnots) { TBase::recreate(YdimT, numberOfKnots); }
405
407 void recreate(int32_t numberOfKnots, const int32_t knotU[])
408 {
409 TBase::recreate(YdimT, numberOfKnots, knotU);
410 }
411#endif
412
414 GPUd() constexpr int32_t getYdimensions() const { return YdimT; }
415
417 GPUd() constexpr size_t getParameterAlignmentBytes() const
418 {
419 size_t s = 2 * sizeof(DataT) * YdimT;
420 return (s < 16) ? s : 16;
421 }
422
424 GPUd() int32_t getNumberOfParameters() const { return (2 * YdimT) * getNumberOfKnots(); }
425
427 GPUd() size_t getSizeOfParameters() const { return (sizeof(DataT) * 2 * YdimT) * getNumberOfKnots(); }
428
430
432 template <SafetyLevel SafeT = SafetyLevel::kSafe>
433 GPUd() void interpolateU(GPUgeneric() const DataT Parameters[],
434 DataT u, GPUgeneric() DataT S[/*nYdim*/]) const
435 {
436 TBase::template interpolateU<SafeT>(YdimT, Parameters, u, S);
437 }
438
441 template <typename T>
442 GPUd() void interpolateU(const typename TBase::Knot& knotL,
443 GPUgeneric() const T Sl[/*mYdim*/], GPUgeneric() const T Dl[/*mYdim*/],
444 GPUgeneric() const T Sr[/*mYdim*/], GPUgeneric() const T Dr[/*mYdim*/],
445 DataT u, GPUgeneric() T S[/*mYdim*/]) const
446 {
447 TBase::interpolateU(YdimT, knotL, Sl, Dl, Sr, Dr, u, S);
448 }
449
450 using TBase::getNumberOfKnots;
451
453 private:
454#if !defined(GPUCA_GPUCODE)
455 using TBase::recreate;
456#endif
457 using TBase::interpolateU;
458};
459
464template <typename DataT, int32_t YdimT>
465class Spline1DSpec<DataT, YdimT, 2>
466 : public Spline1DSpec<DataT, YdimT, 0>
467{
470
471 public:
473
474#if !defined(GPUCA_GPUCODE)
477
479 Spline1DSpec(int32_t nYdim, int32_t numberOfKnots) : TBase()
480 {
481 TBase::recreate(nYdim, numberOfKnots);
482 }
484 Spline1DSpec(int32_t nYdim, int32_t numberOfKnots, const int32_t knotU[]) : TBase()
485 {
486 TBase::recreate(nYdim, numberOfKnots, knotU);
487 }
490 {
491 TVeryBase::cloneFromObject(v, nullptr);
492 }
494 void recreate(int32_t nYdim, int32_t numberOfKnots) { TBase::recreate(nYdim, numberOfKnots); }
495
497 void recreate(int32_t nYdim, int32_t numberOfKnots, const int32_t knotU[])
498 {
499 TBase::recreate(nYdim, numberOfKnots, knotU);
500 }
501#endif
502
504
505 using TBase::interpolateU;
507};
508
512template <typename DataT>
513class Spline1DSpec<DataT, 1, 3>
514 : public Spline1DSpec<DataT, 1, SplineUtil::getSpec(999)>
515{
516 typedef Spline1DSpec<DataT, 1, SplineUtil::getSpec(999)> TBase;
517
518 public:
519 using TBase::TBase; // inherit constructors
520
522 GPUd() DataT interpolate(DataT x) const
523 {
524 DataT S = 0.;
525 TBase::interpolate(x, &S);
526 return S;
527 }
528};
529
530} // namespace gpu
531} // namespace o2
532
533#endif
Definition of FlatObject class.
int32_t i
#define GPUgeneric()
GPUCA_GPUCODE.
Definition FlatObject.h:176
char * releaseInternalBuffer()
_____________ Methods for making the data buffer external __________________________
Definition FlatObject.h:526
static constexpr size_t getBufferAlignmentBytes()
Gives minimal alignment in bytes required for the flat buffer.
Definition FlatObject.h:197
static constexpr size_t getClassAlignmentBytes()
_____________ Memory alignment __________________________
Definition FlatObject.h:194
void cloneFromObject(const Spline1DContainer &obj, char *newFlatBufferPtr)
void setFutureBufferAddress(char *futureFlatBufferPtr)
Knot * getKnots()
Non-const accessor to the knots array.
int32_t mUmax
U of the last knot.
GPUd() static const expr int32_t getVersion()
_____________ Version control __________________________
int32_t mYdim
_____________ Data members ____________
GPUd() const Knot *getKnots() const
Get the array of knots.
~Spline1DContainer()=default
Destructor.
GPUd() size_t getParameterAlignmentBytes() const
Get minimal required alignment for the spline parameters.
void setActualBufferAddress(char *actualFlatBufferPtr)
void approximateFunction(double xMin, double xMax, std::function< void(double x, double f[])> F, int32_t nAuxiliaryDataPoints=4)
_______________ Construction interface ________________________
GPUd() DataT getXtoUscale() const
Get XtoUscale.
DataT mXtoUscale
a scaling factor to convert X to U
GPUd() int32_t getYdimensions() const
Get number of Y dimensions.
ClassDefNV(Spline1DContainer, 1)
(transient!!) pointer to F-dependent parameters inside the mFlatBufferPtr array
SafetyLevel
Named enumeration for the safety level used by some methods.
Spline1DContainer(const Spline1DContainer &)=delete
Disable all other constructors.
GPUd() const Knot &getKnot(int32_t i) const
Get i-th knot.
Spline1DContainer()=default
_____________ C++ constructors / destructors __________________________
GPUd() const DataT *getParameters() const
Get spline parameters const.
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
GPUd() int32_t getLeftKnotIndexForU(DataT u) const
Get index of an associated knot for a given U coordinate. Performs a boundary check.
void print() const
Print method.
GPUd() int32_t getNumberOfKnots() const
Get a number of knots.
DataT * mParameters
(transient!!) pointer to (integer U -> knot index) map inside the mFlatBufferPtr array
GPUd() const int32_t *getUtoKnotMap() const
_______________ Technical stuff ________________________
void recreate(int32_t nYdim, int32_t numberOfKnots)
Constructor for a regular spline.
GPUd() DataT convUtoX(DataT u) const
Convert U coordinate to X.
GPUd() DataT convXtoU(DataT x) const
Convert X coordinate to U.
GPUd() int32_t getUmax() const
_______________ Getters ________________________
GPUd() DataT getXmin() const
Get Xmin.
DataT mXmin
X of the first knot.
GPUd() DataT getXmax() const
Get Xmax.
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
GPUd() void setXrange(DataT xMin
Set X range.
void moveBufferTo(char *newBufferPtr)
int32_t writeToFile(TFile &outf, const char *name)
_______________ IO ________________________
int32_t * getUtoKnotMap()
Non-const accessor to U->knots map.
int32_t mNumberOfKnots
n knots on the grid
static Spline1DContainer * readFromFile(TFile &inpf, const char *name)
read a class object from the file
GPUd() DataT interpolate(DataT x) const
Simplified interface for 1D: return the interpolated value.
GPUd() static void getUderivatives(const Knot &knotL
GPUd() void interpolate(DataT x
_______________ Interpolation math ________________________
GPUd() void interpolateU(int32_t inpYdim
Get interpolated value for an nYdim-dimensional S(u) using spline parameters Parameters.
GPUd() const expr size_t getParameterAlignmentBytes() const
Get minimal required alignment for the spline parameters.
Spline1DSpec(int32_t numberOfKnots)
Constructor for a regular spline.
GPUd() void interpolateU(GPUgeneric() const DataT Parameters[]
_______ Expert tools: interpolation with given nYdim and external Parameters _______
Spline1DSpec(int32_t numberOfKnots, const int32_t knotU[])
Constructor for an irregular spline.
Spline1DSpec(const Spline1DSpec &v)
Copy constructor.
void recreate(int32_t numberOfKnots, const int32_t knotU[])
Constructor for an irregular spline.
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
GPUd() const expr int32_t getYdimensions() const
Get number of Y dimensions.
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
void recreate(int32_t numberOfKnots)
Constructor for a regular spline.
void recreate(int32_t nYdim, int32_t numberOfKnots)
Constructor for a regular spline.
void recreate(int32_t nYdim, int32_t numberOfKnots, const int32_t knotU[])
Constructor for an irregular spline.
Spline1DSpec(int32_t nYdim, int32_t numberOfKnots)
Constructor for a regular spline.
Spline1DSpec(int32_t nYdim, int32_t numberOfKnots, const int32_t knotU[])
Constructor for an irregular spline.
Spline1DSpec(const Spline1DSpec &v)
Copy constructor.
static constexpr int32_t getSpec(int32_t nXdim, int32_t nYdim)
Definition SplineUtil.h:33
GLint GLenum GLint x
Definition glcorearb.h:403
const GLdouble * v
Definition glcorearb.h:832
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLfloat GLfloat GLfloat v2
Definition glcorearb.h:813
GPUdi() o2
Definition TrackTRD.h:38
GPUd() const expr uint32_t MultivariatePolynomialHelper< Dim
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
GPUd() int32_t getU() const
Get u as an integer.
DataT u
u coordinate of the knot i (an integer number in float format)