17#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINE2DSPEC_H 
   18#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINE2DSPEC_H 
   25#if !defined(__CLING__) && !defined(G__ROOT) && !defined(GPUCA_GPUCODE) && !defined(GPUCA_NO_VC) 
   27#include <Vc/SimdArray> 
   46template <
typename DataT>
 
   71#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) 
   74                           std::function<
void(
double x1, 
double x2, 
double f[])> F,
 
   75                           int32_t nAuxiliaryDataPointsU1 = 4, int32_t nAuxiliaryDataPointsU2 = 4);
 
   78                                        std::function<
void(
double x1, 
double x2, 
double f[])> F,
 
   79                                        int32_t nAuxiliaryDataPointsX1, int32_t nAuxiliaryDataPointsX2);
 
   84#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) 
   95  GPUd() int32_t getYdimensions()
 const { 
return mYdim; }
 
   98  GPUd() static constexpr 
size_t getParameterAlignmentBytes() { 
return 16; }
 
  101  GPUd() int32_t getNumberOfParameters()
 const { 
return this->calcNumberOfParameters(
mYdim); }
 
  104  GPUd() size_t getSizeOfParameters()
 const { 
return sizeof(DataT) * this->getNumberOfParameters(); }
 
  107  GPUd() int32_t getNumberOfKnots()
 const { 
return mGridX1.getNumberOfKnots() * 
mGridX2.getNumberOfKnots(); }
 
  126  GPUd() int32_t getKnotIndex(int32_t iKnotX1, int32_t iKnotX2)
 const 
  128    return mGridX1.getNumberOfKnots() * iKnotX2 + iKnotX1;
 
  158  GPUd() int32_t calcNumberOfParameters(int32_t nYdim)
 const { 
return (4 * nYdim) * getNumberOfKnots(); }
 
  162#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)  
  164  static int32_t test(const bool draw = 0, const bool drawDataPoints = 1);
 
  172#if !defined(GPUCA_GPUCODE) 
  184#if !defined(GPUCA_GPUCODE) 
  186  void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2);
 
  189  void recreate(int32_t nYdim, int32_t nKnotsX1, 
const int32_t knotU1[], int32_t nKnotsX2, 
const int32_t knotU2[]);
 
 
  220template <
typename DataT, 
int32_t YdimT, 
int32_t SpecT>
 
  227template <
typename DataT, 
int32_t YdimT>
 
  242    interpolateU<SafetyLevel::kSafe>(mYdim, mParameters, mGridX1.convXtoU(
x1), mGridX2.convXtoU(x2), 
S);
 
  246  template <SafetyLevel SafeT = SafetyLevel::kSafe>
 
  251    const auto nYdimTmp = SplineUtil::getNdim<YdimT>(inpYdim);
 
  252    const int32_t nYdim = nYdimTmp.get();
 
  254    const auto maxYdim = SplineUtil::getMaxNdim<YdimT>(inpYdim);
 
  255    const int32_t maxYdim4 = 4 * maxYdim.get();
 
  257    const auto nYdim2 = nYdim * 2;
 
  258    const auto nYdim4 = nYdim * 4;
 
  262    int32_t nu = mGridX1.getNumberOfKnots();
 
  263    int32_t iu = mGridX1.template getLeftKnotIndexForU<SafeT>(u);
 
  264    int32_t iv = mGridX2.template getLeftKnotIndexForU<SafeT>(
v);
 
  266    const typename TBase::Knot& knotU = mGridX1.template getKnot<SafetyLevel::kNotSafe>(iu);
 
  267    const typename TBase::Knot& knotV = mGridX2.template getKnot<SafetyLevel::kNotSafe>(iv);
 
  269    const DataT* par00 = 
Parameters + (nu * iv + iu) * nYdim4; 
 
  270    const DataT* par10 = par00 + nYdim4;                       
 
  271    const DataT* par01 = par00 + nYdim4 * nu;                  
 
  272    const DataT* par11 = par01 + nYdim4;                       
 
  279    for (int32_t 
i = 0; 
i < nYdim2; 
i++) {
 
  281      Su0[nYdim2 + 
i] = par01[
i];
 
  283      Du0[
i] = par00[nYdim2 + 
i];
 
  284      Du0[nYdim2 + 
i] = par01[nYdim2 + 
i];
 
  287      Su1[nYdim2 + 
i] = par11[
i];
 
  289      Du1[
i] = par10[nYdim2 + 
i];
 
  290      Du1[nYdim2 + 
i] = par11[nYdim2 + 
i];
 
  293    DataT parU[maxYdim4]; 
 
  296    const TGridX1& gridX1 = 
reinterpret_cast<const TGridX1&
>(mGridX1);
 
  298    gridX1.interpolateU(nYdim4, knotU, Su0, Du0, Su1, Du1, u, parU);
 
  300    const DataT* Sv0 = parU + 0;
 
  301    const DataT* Dv0 = parU + nYdim;
 
  302    const DataT* Sv1 = parU + nYdim2;
 
  303    const DataT* Dv1 = parU + nYdim2 + nYdim;
 
  306    const TGridX2& gridX2 = 
reinterpret_cast<const TGridX2&
>(mGridX2);
 
  307    gridX2.interpolateU(nYdim, knotV, Sv0, Dv0, Sv1, Dv1, 
v, 
S);
 
 
  311  template <SafetyLevel SafeT = SafetyLevel::kSafe>
 
  316    const auto nYdimTmp = SplineUtil::getNdim<YdimT>(inpYdim);
 
  317    const int32_t nYdim = nYdimTmp.get();
 
  323    const auto nYdim4 = nYdim * 4;
 
  327    int32_t nu = mGridX1.getNumberOfKnots();
 
  328    int32_t iu = mGridX1.template getLeftKnotIndexForU<SafeT>(u);
 
  329    int32_t iv = mGridX2.template getLeftKnotIndexForU<SafeT>(
v);
 
  331    const typename TBase::Knot& knotU = mGridX1.template getKnot<SafetyLevel::kNotSafe>(iu);
 
  332    const typename TBase::Knot& knotV = mGridX2.template getKnot<SafetyLevel::kNotSafe>(iv);
 
  334    const DataT* 
A = 
Parameters + (nu * iv + iu) * nYdim4; 
 
  335    const DataT* 
B = 
A + nYdim4 * nu;                      
 
  337    DataT dSl, dDl, dSr, dDr;
 
  338    mGridX1.getUderivatives(knotU, u, dSl, dDl, dSr, dDr);
 
  339    DataT dSd, dDd, dSu, dDu;
 
  340    mGridX2.getUderivatives(knotV, 
v, dSd, dDd, dSu, dDu);
 
  348    DataT 
a[8] = {dSl * dSd, dSl * dDd, dDl * dSd, dDl * dDd,
 
  349                  dSr * dSd, dSr * dDd, dDr * dSd, dDr * dDd};
 
  350    DataT 
b[8] = {dSl * dSu, dSl * dDu, dDl * dSu, dDl * dDu,
 
  351                  dSr * dSu, dSr * dDu, dDr * dSu, dDr * dDu};
 
  355    for (int32_t dim = 0; dim < nYdim; dim++) {
 
  357      for (int32_t 
i = 0; 
i < 8; 
i++) {
 
  358        S[dim] += 
a[
i] * 
A[nYdim * 
i + dim] + 
b[
i] * 
B[nYdim * 
i + dim];
 
 
  364  using TBase::mGridX1;
 
  365  using TBase::mGridX2;
 
  366  using TBase::mParameters;
 
 
  375template <
typename DataT, 
int32_t YdimT>
 
  385#if !defined(GPUCA_GPUCODE) 
  392    recreate(nKnotsX1, nKnotsX2);
 
 
  396               int32_t nKnotsX2, 
const int32_t knotU2[])
 
  399    recreate(nKnotsX1, knotU1, nKnotsX2, knotU2);
 
 
  404    TBase::cloneFromObject(
v, 
nullptr);
 
 
  409    TBase::recreate(YdimT, nKnotsX1, nKnotsX2);
 
 
  413  void recreate(int32_t nKnotsX1, 
const int32_t knotU1[],
 
  414                int32_t nKnotsX2, 
const int32_t knotU2[])
 
  416    TBase::recreate(YdimT, nKnotsX1, knotU1, nKnotsX2, knotU2);
 
 
  421  GPUd() constexpr int32_t getYdimensions()
 const { 
return YdimT; }
 
  424  GPUd() int32_t getNumberOfParameters()
 const { 
return (4 * YdimT) * getNumberOfKnots(); }
 
  427  GPUd() size_t getSizeOfParameters()
 const { 
return (
sizeof(DataT) * 4 * YdimT) * getNumberOfKnots(); }
 
  432  template <SafetyLevel SafeT = SafetyLevel::kSafe>
 
  436    TBase::template interpolateU<SafeT>(YdimT, 
Parameters, u1, u2, 
S);
 
 
  440  template <SafetyLevel SafeT = SafetyLevel::kSafe>
 
  444    TBase::template interpolateUold<SafeT>(YdimT, 
Parameters, u1, u2, 
S);
 
 
  447  using TBase::getNumberOfKnots;
 
  451#if !defined(GPUCA_GPUCODE) 
  452  using TBase::recreate;
 
  454  using TBase::interpolateU;
 
 
  461template <
typename DataT, 
int32_t YdimT>
 
  471#if !defined(GPUCA_GPUCODE) 
  478    TBase::recreate(nYdim, nKnotsX1, nKnotsX2);
 
 
  483               int32_t nKnotsX2, 
const int32_t knotU2[]) : 
TBase()
 
  485    TBase::recreate(nYdim, nKnotsX1, knotU1, nKnotsX2, knotU2);
 
 
  491    cloneFromObject(
v, 
nullptr);
 
 
  495  void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
 
  497    TBase::recreate(nYdim, nKnotsX1, nKnotsX2);
 
 
  501  void recreate(int32_t nYdim, int32_t nKnotsX1, 
const int32_t knotU1[],
 
  502                int32_t nKnotsX2, 
const int32_t knotU2[])
 
  504    TBase::recreate(nYdim, nKnotsX1, knotU1, nKnotsX2, knotU2);
 
 
  510  using TBase::interpolateU;
 
 
  516template <
typename DataT>
 
  518  : 
public Spline2DSpec<DataT, 1, SplineUtil::getSpec(999)>
 
  526  GPUd() DataT interpolate(DataT 
x1, DataT x2)
 const 
  529    TBase::interpolate(
x1, x2, &
S);
 
  535  using TBase::interpolate;
 
 
Definition of FlatObject class.
Definition of Spline1D class.
char * releaseInternalBuffer()
_____________ Methods for making the data buffer external __________________________
static constexpr size_t getBufferAlignmentBytes()
Gives minimal alignment in bytes required for the flat buffer.
static constexpr size_t getClassAlignmentBytes()
_____________ Memory alignment __________________________
SafetyLevel
Named enumeration for the safety level used by some methods.
int32_t int32_t &u2 const
mGridX2 setXrange(x2Min, x2Max)
GPUd() DataT *getParameters()
Get spline parameters.
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
void cloneFromObject(const Spline2DContainer &obj, char *newFlatBufferPtr)
void approximateFunction(double x1Min, double x1Max, double x2Min, double x2Max, std::function< void(double x1, double x2, double f[])> F, int32_t nAuxiliaryDataPointsU1=4, int32_t nAuxiliaryDataPointsU2=4)
_______________ Construction interface ________________________
Spline1D< DataT >::Knot Knot
void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
void setActualBufferAddress(char *actualFlatBufferPtr)
void print() const
Print method.
GPUd() int32_t getNumberOfKnots() const
Get a number of knots.
GPUd() size_t getGridX2Offset() const
Get offset of GridX2 flat data in the flat buffer.
GPUd() size_t getGridX1Offset() const
_______________ Technical stuff ________________________
Spline2DContainer()=default
_____________ C++ constructors / destructors __________________________
GPUd() static const expr int32_t getVersion()
_____________ Version control __________________________
GPUd() const Spline1D< DataT > &getGrid(int32_t ix) const
Get 1-D grid for X1 or X2 coordinate.
Spline1D< DataT > mGridX2
grid for V axis
Spline1D< DataT >::SafetyLevel SafetyLevel
int32_t mYdim
_____________ Data members ____________
~Spline2DContainer()=default
Destructor.
ClassDefNV(Spline2DContainer, 1)
(transient!!) F-dependent parameters of the spline
GPUd() int32_t calcNumberOfParameters(int32_t nYdim) const
_______________ Expert tools _______________
GPUd() void setXrange(DataT x1Min
Set X range.
GPUd() static const expr size_t getParameterAlignmentBytes()
Get minimal required alignment for the spline parameters.
void moveBufferTo(char *newBufferPtr)
GPUd() const DataT *getParameters() const
Get spline parameters const.
GPUd() int32_t getYdimensions() const
_______________ Getters ________________________
int32_t writeToFile(TFile &outf, const char *name)
_______________ IO ________________________
GPUd() const Spline1D< DataT > &getGridX1() const
Get 1-D grid for the X1 coordinate.
static Spline2DContainer * readFromFile(TFile &inpf, const char *name)
read a class object from the file
Spline1D< DataT > mGridX1
grid for U axis
Spline2DContainer(const Spline2DContainer &)=delete
Disable all other constructors.
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
void setFutureBufferAddress(char *futureFlatBufferPtr)
void approximateFunctionViaDataPoints(double x1Min, double x1Max, double x2Min, double x2Max, std::function< void(double x1, double x2, double f[])> F, int32_t nAuxiliaryDataPointsX1, int32_t nAuxiliaryDataPointsX2)
GPUd() const Spline1D< DataT > &getGridX2() const
Get 1-D grid for the X2 coordinate.
GPUd() void interpolateU(int32_t inpYdim
Get interpolated value for an inpYdim-dimensional S(u1,u2) using spline parameters Parameters.
TBase::SafetyLevel SafetyLevel
GPUd() void interpolateUold(int32_t inpYdim
Get interpolated value for an inpYdim-dimensional S(u1,u2) using spline parameters Parameters.
GPUd() void interpolate(DataT x1
_______________ Interpolation math ________________________
Spline2DSpec(int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
Spline2DSpec(const Spline2DSpec &v)
Copy constructor.
Spline2DSpec(int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
GPUd() const expr int32_t getYdimensions() const
Get number of Y dimensions.
TVeryBase::SafetyLevel SafetyLevel
Spline2DSpec()
Default constructor.
GPUd() void interpolateU(GPUgeneric() const DataT Parameters[]
_______ Expert tools: interpolation with given nYdim and external Parameters _______
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
void recreate(int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
void recreate(int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
GPUd() void interpolateUold(GPUgeneric() const DataT Parameters[]
Get interpolated value for an YdimT-dimensional S(u1,u2) using spline parameters Parameters.
Spline2DSpec(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
Spline2DSpec(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
Spline2DSpec()
Default constructor.
Spline2DSpec(const Spline2DSpec &v)
Copy constructor.
void recreate(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
TVeryBase::SafetyLevel SafetyLevel
static constexpr int32_t getSpec(int32_t nXdim, int32_t nYdim)
GLuint GLfloat GLfloat GLfloat x1
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean GLboolean GLboolean GLboolean a
GPUd() const expr uint32_t MultivariatePolynomialHelper< Dim
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...