Project
Loading...
Searching...
No Matches
IrregularSpline1D.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_IRREGULARSPLINE1D_H
18#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_IRREGULARSPLINE1D_H
19
20#include "GPUCommonDef.h"
21#include "FlatObject.h"
22#include "GPUCommonDef.h"
23
24#ifndef __OPENCL__
25#include <cstddef>
26#include <memory>
27#include <cstring>
28#endif
29
30namespace o2
31{
32namespace gpu
33{
34
113{
114 public:
118 struct Knot {
119 float u;
120
122
123 float scale;
124 float scaleL0;
125 float scaleL2;
126 float scaleR2;
127 float scaleR3;
128 };
129
131
134
137
140
143
145
147
150
152
153 void cloneFromObject(const IrregularSpline1D& obj, char* newFlatBufferPtr);
154 void destroy();
155
157
159#ifndef GPUCA_GPUCODE
161#endif
162
164
167
169
184 void construct(int32_t numberOfKnots, const float knots[], int32_t numberOfAxisBins);
185
187 void constructRegular(int32_t numberOfKnotsU);
188
190
196 template <typename T>
197 GPUd() void correctEdges(T* data) const;
198
200 template <typename T>
201 GPUd() static T getSpline(const IrregularSpline1D::Knot& knot1, T f0, T f1, T f2, T f3, float u);
202
204 template <typename T>
205 GPUd() T getSpline(const T correctedData[], float u) const;
206
208 GPUd() int32_t getNumberOfKnots() const { return mNumberOfKnots; }
209
215 GPUd() int32_t getKnotIndex(float u) const;
216
218 GPUd() const IrregularSpline1D::Knot& getKnot(int32_t i) const { return getKnots()[i]; }
219
221 GPUd() const IrregularSpline1D::Knot* getKnots() const { return reinterpret_cast<const IrregularSpline1D::Knot*>(mFlatBufferPtr); }
222
224 static constexpr size_t getClassAlignmentBytes() { return 8; }
225
227 static constexpr size_t getBufferAlignmentBytes() { return 8; }
228
230 static constexpr size_t getDataAlignmentBytes() { return 8; }
231
233
235 GPUd() const int32_t* getBin2KnotMap() const { return reinterpret_cast<const int32_t*>(mFlatBufferPtr + mBin2KnotMapOffset); }
236
238 int32_t getNumberOfAxisBins() const { return mNumberOfAxisBins; }
239
249 GPUd() static void getEdgeCorrectionCoefficients(double u0, double u1, double u2, double u3, double& c0, double& c1, double& c2, double& c3);
250
252 void print() const;
253
254 private:
256 IrregularSpline1D::Knot* getKnotsNonConst() { return reinterpret_cast<IrregularSpline1D::Knot*>(mFlatBufferPtr); }
257
259 int32_t* getBin2KnotMapNonConst() { return reinterpret_cast<int32_t*>(mFlatBufferPtr + mBin2KnotMapOffset); }
260
264
265 int32_t mNumberOfKnots;
266 int32_t mNumberOfAxisBins;
267 uint32_t mBin2KnotMapOffset;
268
269 ClassDefNV(IrregularSpline1D, 1);
270};
271
275
276template <typename T>
277GPUdi() T IrregularSpline1D::getSpline(const IrregularSpline1D::Knot& knot1, T f0, T f1, T f2, T f3, float u)
278{
281
282 f0 -= f1;
283 f2 -= f1;
284 f3 -= f1;
285
286 T x = T((u - knot1.u) * knot1.scale); // scaled u
287 T z1 = T(f0 * knot1.scaleL0 + f2 * knot1.scaleL2); // scaled u derivative at the knot 1
288 T z2 = T(f2 * knot1.scaleR2 + f3 * knot1.scaleR3); // scaled u derivative at the knot 2
289
290 T x2 = x * x;
291
292 // f(x) = ax^3 + bx^2 + cx + d
293 //
294 // f(0) = f1
295 // f(1) = f2
296 // f'(0) = z1
297 // f'(1) = z2
298 //
299
300 // T d = f1;
301 // T c = z1;
302 T a = -f2 - f2 + z1 + z2;
303 T b = f2 - z1 - a;
304 return a * x * x2 + b * x2 + z1 * x + f1;
305}
306
307template <typename T>
308GPUdi() T IrregularSpline1D::getSpline(const T correctedData[], float u) const
309{
311 int32_t iknot = getKnotIndex(u);
312 const IrregularSpline1D::Knot& knot = getKnot(iknot);
313 const T* f = correctedData + iknot - 1;
314 return getSpline(knot, f[0], f[1], f[2], f[3], u);
315}
316
317GPUdi() int32_t IrregularSpline1D::getKnotIndex(float u) const
318{
320 int32_t ibin = (int32_t)(u * mNumberOfAxisBins);
321 if (ibin < 0) {
322 ibin = 0;
323 }
324 if (ibin > mNumberOfAxisBins - 1) {
325 ibin = mNumberOfAxisBins - 1;
326 }
327 return getBin2KnotMap()[ibin];
328}
329
330GPUdi() void IrregularSpline1D::getEdgeCorrectionCoefficients(double u0, double u1, double u2, double u3, double& c0, double& c1, double& c2, double& c3)
331{
335
336 double du = u2 - u1;
337 double x0 = (u0 - u1) / du;
338 // double x1 = ( u1 - u1 )/du = 0
339 // double x2 = ( u2 - u1 )/du = 1
340 double x3 = (u3 - u1) / du;
341
342 double cL0 = -1. / (x0 * (x0 - 1.));
343 double cL2 = x0 / (x0 - 1.);
344 double cR2 = (x3 - 2.) / (x3 - 1.);
345 double cR3 = 1. / (x3 * (x3 - 1.));
346
347 // Fi = fi - f1
348
349 // z1 = F0corr*cL0 + F2*cL2; // scaled u derivative at the knot 1
350 // z2 = F2*cR2 + F3*cR3; // scaled u derivative at the knot 2
351
352 // a = -2F2 + z1 + z2
353 // b = 3F2 - 2*z1 - z2 ;
354 // c = z1
355 // d = 0
356
357 // F(x) = ax^3 + bx^2 + cx + d
358 // F(x) = (-2*x^3+3*x^2)*F2 + (x^3-2*x^2+x)*z1 + (x^3-x^2)*z2
359 // F(x) = (-2*x^3+3*x^2)*F2 + (x^3-2*x^2+x)*z1 + (x^3-x^2)*(cR2*F2 + cR3*F3)
360 // F(x) = (-2*x^3+3*x^2+(x^3-x^2)*cR2)*F2 + (x^3-2*x^2+x)*z1 + (x^3-x^2)*cR3*F3
361 // F(x) = x^2(-2*x+3+(x-1)*cR2)*F2 + x*(x-1)^2*z1 + x^2(x-1)*cR3*F3
362
363 // z1*x*(x-1)^2 = F(x) - x^2(-2*x+3+(x-1)*cR2)*F2 - x^2(x-1)*cR3*F3
364 // z1*x0*(x0-1)^2 = F0 - x0^2(-2*x0+3+(x0-1)*cR2)*F2 - x0^2(x0-1)*cR3*F3
365
366 double x01 = x0 - 1.;
367
368 // coeff. for z1 at F0, F1, F2, F3:
369
370 c0 = 1. / (x0 * x01 * x01);
371 c1 = 0;
372 c2 = -(-2 * x0 + 3. + x01 * cR2) * x0 / (x01 * x01);
373 c3 = -x0 * cR3 / x01;
374
375 // F0corr = (z1 - F2*cL2)/cL0;
376
377 c0 = c0 / cL0;
378 c1 = c1 / cL0;
379 c2 = (c2 - cL2) / cL0;
380 c3 = c3 / cL0;
381
382 // F0corr = c0*F0 + c1*F1 + C2*F2 + c3*F3;
383 // f0corr-f1 = c0*(f0-f1) + c1*(f1-f1) + c2*(f2-f1) + c3*(f3-f1);
384 // f0corr-f1 = c0*(f0-f1) + c2*(f2-f1) + c3*(f3-f1);
385 // f0corr = c0*f0 + c2*f2 + c3*f3 + (1-c0-c2-c3)*f1;
386
387 c1 = 1. - c0 - c2 - c3;
388}
389
390template <typename T>
391GPUdi() void IrregularSpline1D::correctEdges(T* data) const
392{
393 const IrregularSpline1D::Knot* s = getKnots();
394 double c0, c1, c2, c3;
395 getEdgeCorrectionCoefficients(s[0].u, s[1].u, s[2].u, s[3].u, c0, c1, c2, c3);
396 data[0] = c0 * data[0] + c1 * data[1] + c2 * data[2] + c3 * data[3];
397 int32_t i = mNumberOfKnots - 1;
398 getEdgeCorrectionCoefficients(s[i - 0].u, s[i - 1].u, s[i - 2].u, s[i - 3].u, c0, c1, c2, c3);
399 data[i] = c0 * data[i - 0] + c1 * data[i - 1] + c2 * data[i - 2] + c3 * data[i - 3];
400}
401} // namespace gpu
402} // namespace o2
403
404#endif
Definition of FlatObject class.
int32_t i
bool const GPUTPCGMMerger::trackCluster * c1
bool const GPUTPCGMMerger::trackCluster const clcomparestruct * c2
GPUCA_GPUCODE.
Definition FlatObject.h:176
char * releaseInternalBuffer()
_____________ Methods for making the data buffer external __________________________
Definition FlatObject.h:526
void setFutureBufferAddress(char *futureFlatBufferPtr)
Definition FlatObject.h:557
static constexpr size_t getBufferAlignmentBytes()
Gives minimal alignment in bytes required for the flat buffer.
Definition FlatObject.h:197
void setActualBufferAddress(char *actualFlatBufferPtr)
_____________ Methods for moving the class with its external buffer to another location _____________...
Definition FlatObject.h:547
void moveBufferTo(char *newBufferPtr)
Definition FlatObject.h:396
static constexpr size_t getClassAlignmentBytes()
_____________ Memory alignment __________________________
Definition FlatObject.h:194
static constexpr size_t getDataAlignmentBytes()
Get minimal required alignment for the spline data.
GPUd() static T getSpline(const IrregularSpline1D float u const
void print() const
Print method.
int32_t getNumberOfAxisBins() const
Get number of axis bins.
double double double double double double & c2
void construct(int32_t numberOfKnots, const float knots[], int32_t numberOfAxisBins)
_______________ Construction interface ________________________
~IrregularSpline1D()=default
Destructor.
double double double double double & c1
void cloneFromObject(const IrregularSpline1D &obj, char *newFlatBufferPtr)
Construction interface.
double double double double double double double & c3
GPUd() void correctEdges(T *data) const
_______________ Main functionality ________________________
GPUd() const int32_t *getBin2KnotMap() const
technical stuff
static constexpr size_t getClassAlignmentBytes()
_____________ Memory alignment __________________________
Definition FlatObject.h:194
double double double double & c0
IrregularSpline1D()
_____________ Constructors / destructors __________________________
static constexpr size_t getBufferAlignmentBytes()
Get minimal required alignment for the flat buffer.
IrregularSpline1D(const IrregularSpline1D &)=delete
Copy constructor: disabled to avoid ambiguity. Use cloneFromObject instead.
GPUd() int32_t getKnotIndex(float u) const
void constructRegular(int32_t numberOfKnotsU)
Constructor for a regular spline.
IrregularSpline1D & operator=(const IrregularSpline1D &)=delete
Assignment operator: disabled to avoid ambiguity. Use cloneFromObject instead.
GLint GLenum GLint x
Definition glcorearb.h:403
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean * data
Definition glcorearb.h:298
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLuint GLfloat x0
Definition glcorearb.h:5034
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GPUdi() o2
Definition TrackTRD.h:38
const float3 float float float float x3
Definition MathUtils.h:42
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
The struct represents a knot(i) and interval [ knot(i), knot(i+1) ].
float scaleL2
a coefficient at f(i+1) for f'(i) calculation
float scale
some useful values for spline calculation:
float scaleR3
a coefficient at f(i+2) for f'(i+1) calculation
float u
u coordinate of the knot i
float scaleR2
a coefficient at f(i+1) for f'(i+1) calculation
float scaleL0
a coefficient at f(i-1) for f'(i) calculation