18#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SEMIREGULARSPLINE2D3D_H
19#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SEMIREGULARSPLINE2D3D_H
26#if !defined(__ROOTCLING__) && !defined(GPUCA_GPUCODE) && !defined(GPUCA_NO_VC)
28#include <Vc/SimdArray>
95 void construct(
const int32_t numberOfRows,
const int32_t numbersOfKnots[]);
104 template <
typename T>
108 template <
typename T>
109 void getSpline(
const T* correctedData,
float u,
float v, T&
x, T&
y, T&
z)
const;
113 void getSplineVec(
const float* correctedData,
float u,
float v,
float&
x,
float&
y,
float&
z)
const;
129 void getKnotUV(int32_t iKnot,
float& u,
float&
v)
const;
161 return reinterpret_cast<const int32_t*
>(
mFlatBufferPtr + mDataIndexMapOffset);
165 void relocateBufferPointers(
const char* oldBuffer,
char* newBuffer);
172 int32_t* getDataIndexMapNonConst()
174 return reinterpret_cast<int32_t*
>(
mFlatBufferPtr + mDataIndexMapOffset);
181 RegularSpline1D mGridV;
182 int32_t mNumberOfRows;
183 int32_t mNumberOfKnots;
184 int32_t mDataIndexMapOffset;
207 for (int32_t
i = 0;
i < mNumberOfRows;
i++) {
213 if (iKnot <= nk - 1) {
235 int32_t nv = mNumberOfRows;
242 for (int32_t iv = 1; iv < mNumberOfRows - 1; iv++) {
247 for (int32_t idim = 0; idim < 3; idim++) {
248 f0[idim] = (T)(0.5 * f0[idim] + 1.5 * f1[idim] - 1.5 * f2[idim] + 0.5 * f3[idim]);
255 for (int32_t iv = 1; iv < mNumberOfRows - 1; iv++) {
262 for (int32_t idim = 0; idim < 3; idim++) {
263 f3[idim] = (T)(0.5 * f0[idim] - 1.5 * f1[idim] + 1.5 * f2[idim] + 0.5 * f3[idim]);
272 for (int32_t iu = 0; iu < nu; iu++) {
278 float x1 = 0,
y1 = 0, z1 = 0, x2 = 0, y2 = 0, z2 = 0, x3 = 0, y3 = 0, z3 = 0;
283 T f1[3] = {
x1,
y1, z1};
284 T f2[3] = {x2, y2, z2};
285 T f3[3] = {x3, y3, z3};
286 for (int32_t idim = 0; idim < 3; idim++) {
287 f0[idim] = (T)(0.5 * f0[idim] + 1.5 * f1[idim] - 1.5 * f2[idim] + 0.5 * f3[idim]);
295 for (int32_t iu = 0; iu < nu; iu++) {
299 float x1 = 0,
y1 = 0, z1 = 0, x2 = 0, y2 = 0, z2 = 0, x3 = 0, y3 = 0, z3 = 0;
304 T f0[3] = {
x1,
y1, z1};
305 T f1[3] = {x2, y2, z2};
306 T f2[3] = {x3, y3, z3};
308 for (int32_t idim = 0; idim < 3; idim++) {
309 f3[idim] = (T)(0.5 * f0[idim] - 1.5 * f1[idim] + 1.5 * f2[idim] + 0.5 * f3[idim]);
321 for (int32_t idim = 0; idim < 3; idim++) {
322 f0[idim] = (T)(0.5 * f0[idim] + 1.5 * f1[idim] - 1.5 * f2[idim] + 0.5 * f3[idim]);
334 for (int32_t idim = 0; idim < 3; idim++) {
335 f3[idim] = (T)(0.5 * f0[idim] - 1.5 * f1[idim] + 1.5 * f2[idim] + 0.5 * f3[idim]);
344 for (int32_t idim = 0; idim < 3; idim++) {
345 f0[idim] = (T)(0.5 * f0[idim] + 1.5 * f1[idim] - 1.5 * f2[idim] + 0.5 * f3[idim]);
356 for (int32_t idim = 0; idim < 3; idim++) {
357 f3[idim] = (T)(0.5 * f0[idim] - 1.5 * f1[idim] + 1.5 * f2[idim] + 0.5 * f3[idim]);
376 for (int32_t vi = 0; vi < 4; vi++, vxIndex += 3) {
378 const int32_t vDelta = iknotv + vi - 1;
383 const int32_t dataOffset =
getDataIndex(ui - 1, vDelta);
385 dataVx[vxIndex + 0] = gridU.
getSpline(ui, correctedData[dataOffset], correctedData[dataOffset + 3], correctedData[dataOffset + 6], correctedData[dataOffset + 9], u);
386 dataVx[vxIndex + 1] = gridU.
getSpline(ui, correctedData[dataOffset + 1], correctedData[dataOffset + 4], correctedData[dataOffset + 7], correctedData[dataOffset + 10], u);
387 dataVx[vxIndex + 2] = gridU.
getSpline(ui, correctedData[dataOffset + 2], correctedData[dataOffset + 5], correctedData[dataOffset + 8], correctedData[dataOffset + 11], u);
391 x = mGridV.
getSpline(iknotv, dataVx[0], dataVx[3], dataVx[6], dataVx[9],
v);
392 y = mGridV.
getSpline(iknotv, dataVx[1], dataVx[4], dataVx[7], dataVx[10],
v);
393 z = mGridV.
getSpline(iknotv, dataVx[2], dataVx[5], dataVx[8], dataVx[11],
v);
401#if !defined(__ROOTCLING__) && !defined(GPUCA_GPUCODE) && !defined(GPUCA_NO_VC)
434 for (int32_t vi = 0; vi < 4; vi++, vOffset += 3) {
442 const float* dataU0 = correctedData +
getDataIndex(ui - 1, vGridi + vi - 1);
444 Vc::float_v dt0(dataU0 + 0);
445 Vc::float_v dt1(dataU0 + 3);
446 Vc::float_v dt2(dataU0 + 6);
447 Vc::float_v dt3(dataU0 + 9);
449 Vc::float_v resU = gridU.
getSpline(ui, dt0, dt1, dt2, dt3, u);
452 dataU[vOffset + 0] = resU[0];
453 dataU[vOffset + 1] = resU[1];
454 dataU[vOffset + 2] = resU[2];
457 Vc::float_v dataV0(dataU + 0);
458 Vc::float_v dataV1(dataU + 3);
459 Vc::float_v dataV2(dataU + 6);
460 Vc::float_v dataV3(dataU + 9);
462 Vc::float_v
res = mGridV.
getSpline(vGridi, dataV0, dataV1, dataV2, dataV3,
v);
Definition of FlatObject class.
Definition of IrregularSpline1D class.
char * releaseInternalBuffer()
_____________ Methods for making the data buffer external __________________________
int32_t mFlatBufferSize
size of the flat buffer
static constexpr size_t getBufferAlignmentBytes()
Gives minimal alignment in bytes required for the flat buffer.
static constexpr size_t getClassAlignmentBytes()
_____________ Memory alignment __________________________
T getSpline(const int32_t iknot, T f0, T f1, T f2, T f3, float u) const
Get interpolated value for f(u) using spline at knot "knot_1" and function values at knots {knot_0,...
int32_t getKnotIndex(float u) const
int32_t getNumberOfKnots() const
Get number of knots.
double knotIndexToU(int32_t index) const
Get the U-Coordinate depending on the given knot-Index.
const RegularSpline1D & getGridV() const
Get 1-D grid for U coordinate.
void setFutureBufferAddress(char *futureFlatBufferPtr)
SemiregularSpline2D3D(const SemiregularSpline2D3D &)=delete
Copy constructor: disabled to avoid ambiguity. Use cloneFromObject() instead.
void cloneFromObject(const SemiregularSpline2D3D &obj, char *newFlatBufferPtr)
Construction interface.
int32_t getNumberOfKnots() const
Get number total of knots: UxV.
const RegularSpline1D * getSplineArray() const
void getSplineVec(const float *correctedData, float u, float v, float &x, float &y, float &z) const
int32_t getDataIndex(int32_t i, int32_t j) const
Gets the knot index which is the i-th knot in v-space and the j-th knot in u-space.
const int32_t * getDataIndexMap() const
~SemiregularSpline2D3D()=default
Destructor.
int32_t getNumberOfRows() const
Get number of rows. Always the same as gridV's number of knots.
void construct(const int32_t numberOfRows, const int32_t numbersOfKnots[])
_______________ Construction interface ________________________
void getKnotUV(int32_t iKnot, float &u, float &v) const
Get u,v of i-th knot.
int32_t getDataIndex0(int32_t i, int32_t j) const
void getSpline(const T *correctedData, float u, float v, T &x, T &y, T &z) const
Get interpolated value for f(u,v) using data array correctedData[getNumberOfKnots()] with corrected e...
size_t getFlatBufferSize() const
Get size of the mFlatBuffer data.
int32_t getDataIndexMapOffset() const
Gets the offset for the data index map inside the flat buffer.
static constexpr size_t getClassAlignmentBytes()
Get minimal required alignment for the class.
static constexpr size_t getBufferAlignmentBytes()
Get minimal required alignment for the flat buffer.
const RegularSpline1D & getGridU(const int32_t i) const
Get 1-D grid for V coordinate.
void setActualBufferAddress(char *actualFlatBufferPtr)
Moving the class with its external buffer to another location.
void correctEdges(T *data) const
_______________ Main functionality ________________________
SemiregularSpline2D3D & operator=(const SemiregularSpline2D3D &)=delete
Assignment operator: disabled to avoid ambiguity. Use cloneFromObject() instead.
SemiregularSpline2D3D()
_____________ Constructors / destructors __________________________
const char * getFlatBufferPtr() const
Get pointer to the flat buffer.
static constexpr size_t getDataAlignmentBytes()
Get minimal required alignment for the spline data.
void moveBufferTo(char *newBufferPtr)
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLuint GLfloat GLfloat GLfloat x1
GLdouble GLdouble GLdouble z
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...