17#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINESPEC_H 
   18#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINESPEC_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(
const double x[], 
double f[])> F,
 
   75                           const int32_t nAuxiliaryDataPoints[] = 
nullptr);
 
   80#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) 
   91  GPUd() int32_t getXdimensions()
 const { 
return mXdim; }
 
   94  GPUd() int32_t getYdimensions()
 const { 
return mYdim; }
 
   97  GPUd() static constexpr 
size_t getParameterAlignmentBytes() { 
return 16; }
 
  100  GPUd() int32_t getNumberOfParameters()
 const { 
return this->calcNumberOfParameters(
mYdim); }
 
  103  GPUd() size_t getSizeOfParameters()
 const { 
return sizeof(DataT) * this->getNumberOfParameters(); }
 
  109  GPUd() int32_t getNumberOfParametersPerKnot()
 const { 
return calcNumberOfParametersPerKnot(
mYdim); }
 
  140  GPUd() int32_t calcNumberOfParameters(int32_t nYdim)
 const 
  142    return calcNumberOfParametersPerKnot(nYdim) * getNumberOfKnots();
 
 
  146  GPUd() int32_t calcNumberOfParametersPerKnot(int32_t nYdim)
 const 
  148    return (1 << 
mXdim) * nYdim; 
 
 
  153#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)  
  155  static int32_t test(const bool draw = 0, const bool drawDataPoints = 1);
 
  163#if !defined(GPUCA_GPUCODE) 
  175#if !defined(GPUCA_GPUCODE) 
  177  void recreate(int32_t nXdim, int32_t nYdim, 
const int32_t nKnots[]);
 
  180  void recreate(int32_t nXdim, int32_t nYdim, 
const int32_t nKnots[], 
const int32_t* 
const knotU[]);
 
 
  195template <
typename DataT>
 
  199  for (int32_t dim = 0; dim < mXdim; dim++) {
 
  200    int32_t 
n = mGrid[dim].getNumberOfKnots();
 
  201    u[dim] = mGrid[dim].getKnot(iKnot % 
n).getU();
 
  206template <
typename DataT>
 
  207GPUdi() int32_t SplineContainer<DataT>::getKnotIndex(const int32_t iKnot[])
 const 
  210  int32_t ind = iKnot[0];
 
  212  for (int32_t dim = 1; dim < mXdim; dim++) {
 
  213    n *= mGrid[dim - 1].getNumberOfKnots();
 
  214    ind += 
n * iKnot[dim];
 
  219template <
typename DataT>
 
  221  setXrange(const DataT xMin[], const DataT xMax[])
 
  224  for (int32_t 
i = 0; 
i < mXdim; 
i++) {
 
  225    mGrid[
i].setXrange(xMin[
i], xMax[
i]);
 
  251template <
typename DataT, 
int32_t XdimT, 
int32_t YdimT, 
int32_t SpecT>
 
  258template <
typename DataT, 
int32_t XdimT, 
int32_t YdimT>
 
  272    const auto nXdimTmp = SplineUtil::getNdim<XdimT>(mXdim);
 
  273    const auto nXdim = nXdimTmp.get();
 
  274    const auto maxXdimTmp = SplineUtil::getMaxNdim<XdimT>(mXdim);
 
  275    DataT u[maxXdimTmp.get()];
 
  276    for (int32_t 
i = 0; 
i < nXdim; 
i++) {
 
  277      u[
i] = mGrid[
i].convXtoU(
x[
i]);
 
  279    interpolateU<SafetyLevel::kSafe>(mXdim, mYdim, mParameters, u, 
S);
 
  283  template <SafetyLevel SafeT = SafetyLevel::kSafe>
 
  287    const auto nXdimTmp = SplineUtil::getNdim<XdimT>(mXdim);
 
  288    const auto nXdim = nXdimTmp.get();
 
  289    const auto maxXdimTmp = SplineUtil::getMaxNdim<XdimT>(mXdim);
 
  290    const auto maxXdim = maxXdimTmp.get();
 
  291    const auto nYdimTmp = SplineUtil::getNdim<YdimT>(mYdim);
 
  292    const auto nYdim = nYdimTmp.get();
 
  293    const auto maxYdimTmp = SplineUtil::getMaxNdim<XdimT>(mYdim);
 
  294    const auto maxYdim = maxYdimTmp.get();
 
  297    const auto nKnotParametersPerY = 1 << nXdim;       
 
  298    const auto nKnotParameters = (1 << nXdim) * nYdim; 
 
  300    DataT iParameters[(1 << (2 * maxXdim)) * maxYdim]; 
 
  305    for (int32_t 
i = 0; 
i < nXdim; 
i++) {
 
  306      indices[
i] = mGrid[
i].getLeftKnotIndexForU(u[
i]);
 
  309    int32_t indicestmp[maxXdim];
 
  310    for (int32_t 
i = 0; 
i < nKnotParametersPerY; 
i++) { 
 
  311      for (int32_t k = 0; k < nXdim; k++) {
 
  312        indicestmp[k] = 
indices[k] + (
i / (1 << k)) % 2; 
 
  314      int32_t 
index = TBase::getKnotIndex(indicestmp); 
 
  316      for (int32_t 
j = 0; 
j < nKnotParameters; 
j++) { 
 
  322    constexpr auto maxInterpolations = (1 << (2 * maxXdim - 2)) * maxYdim;
 
  324    DataT S0[maxInterpolations];
 
  325    DataT D0[maxInterpolations];
 
  326    DataT S1[maxInterpolations];
 
  327    DataT D1[maxInterpolations];
 
  329    int32_t nInterpolations = (1 << (2 * nXdim - 2)) * nYdim;
 
  330    int32_t nKnots = 1 << (nXdim);
 
  332    for (int32_t d = 0; d < nXdim; d++) {            
 
  333      DataT* 
pointer[4] = {S0, D0, S1, D1};          
 
  334      for (int32_t 
i = 0; 
i < nKnots; 
i++) {         
 
  335        for (int32_t 
j = 0; 
j < nKnots; 
j++) {       
 
  336          int32_t pointernr = 2 * (
i % 2) + (
j % 2); 
 
  337          for (int32_t k = 0; k < nYdim; k++) {
 
  338            pointer[pointernr][0] = iParameters[(
i * nKnots + 
j) * nYdim + k];
 
  345      DataT coordinate = u[d];
 
  347      const TGridX& gridX = *((
const TGridX*)&(mGrid[d]));
 
  348      gridX.interpolateU(nInterpolations, knotL, S0, D0, S1, D1, coordinate, iParameters);
 
  349      nInterpolations /= 4;
 
  353    for (int32_t 
i = 0; 
i < nYdim; 
i++) {
 
  354      S[
i] = iParameters[
i]; 
 
 
  361  using TBase::mParameters;
 
 
  371template <
typename DataT, 
int32_t XdimT, 
int32_t YdimT>
 
  381#if !defined(GPUCA_GPUCODE) 
  391  SplineSpec(
const int32_t nKnots[], 
const int32_t* 
const knotU[])
 
  394    recreate(nKnots, knotU);
 
 
  399    TBase::cloneFromObject(
v, 
nullptr);
 
 
  404    TBase::recreate(XdimT, YdimT, nKnots);
 
 
  408  void recreate(
const int32_t nKnots[], 
const int32_t* 
const knotU[])
 
  410    TBase::recreate(XdimT, YdimT, nKnots, knotU);
 
 
  415  GPUd() constexpr int32_t getXdimensions()
 const { 
return XdimT; }
 
  418  GPUd() constexpr int32_t getYdimensions()
 const { 
return YdimT; }
 
  423  template <SafetyLevel SafeT = SafetyLevel::kSafe>
 
  427    TBase::template interpolateU<SafeT>(XdimT, YdimT, 
Parameters, u, 
S);
 
 
  432#if !defined(GPUCA_GPUCODE) 
  433  using TBase::recreate;
 
  435  using TBase::interpolateU;
 
 
  442template <
typename DataT, 
int32_t XdimT, 
int32_t YdimT>
 
  452#if !defined(GPUCA_GPUCODE) 
  459    this->recreate(nXdim, nYdim, nKnots);
 
 
  463  SplineSpec(int32_t nXdim, int32_t nYdim, 
const int32_t nKnots[], 
const int32_t* 
const knotU[])
 
  466    this->recreate(nXdim, nYdim, nKnots, knotU);
 
 
  472    cloneFromObject(
v, 
nullptr);
 
 
  476  void recreate(int32_t nXdim, int32_t nYdim, 
const int32_t nKnots[])
 
  478    checkDimensions(nXdim, nYdim);
 
  479    TBase::recreate(nXdim, nYdim, nKnots);
 
 
  483  void recreate(int32_t nXdim, int32_t nYdim, 
const int32_t nKnots[], 
const int32_t* 
const knotU[])
 
  485    checkDimensions(nXdim, nYdim);
 
  486    TBase::recreate(nXdim, nYdim, nKnots, knotU);
 
 
  493  using TBase::interpolateU;
 
  498    if (XdimT > 0 && nXdim != XdimT) {
 
  502    if (XdimT < 0 && nXdim > abs(XdimT)) {
 
  510    if (YdimT > 0 && nYdim != YdimT) {
 
  514    if (YdimT < 0 && nYdim > abs(YdimT)) {
 
 
 
  528template <
typename DataT, 
int32_t XdimT>
 
  530  : 
public SplineSpec<DataT, XdimT, 1, SplineUtil::getSpec(XdimT, 999)>
 
  538  GPUd() DataT interpolate(const DataT 
x[])
 const 
  541    TBase::interpolate(
x, &
S);
 
 
  547  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.
 
GPUd() void setXrange(const DataT xMin[]
Set X range.
 
SplineContainer()=default
_____________ C++ constructors / destructors __________________________
 
GPUd() int32_t getXdimensions() const
_______________ Getters ________________________
 
int32_t mYdim
dimentionality of Y
 
GPUd() size_t getGridOffset(int32_t dimX) const
_______________ Technical stuff ________________________
 
~SplineContainer()=default
Destructor.
 
GPUd() int32_t getNumberOfKnots() const
Get a number of knots.
 
int32_t mNknots
number of spline knots
 
Spline1D< DataT >::SafetyLevel SafetyLevel
 
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
 
int32_t writeToFile(TFile &outf, const char *name)
_______________ IO ________________________
 
void cloneFromObject(const SplineContainer &obj, char *newFlatBufferPtr)
 
static SplineContainer * readFromFile(TFile &inpf, const char *name)
read a class object from the file
 
ClassDefNV(SplineContainer, 1)
(transient!!) F-dependent parameters of the spline
 
void moveBufferTo(char *newBufferPtr)
 
GPUd() static const expr int32_t getVersion()
_____________ Version control __________________________
 
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
 
Spline1D< DataT > * mGrid
 
void setActualBufferAddress(char *actualFlatBufferPtr)
 
void setFutureBufferAddress(char *futureFlatBufferPtr)
 
GPUd() int32_t getNumberOfParametersPerKnot() const
Number of parameters per knot.
 
int32_t mXdim
_____________ Data members ____________
 
GPUd() const Spline1D< DataT > &getGrid(int32_t dimX) const
Get 1-D grid for dimX dimension.
 
DataT * mParameters
(transient!!) mXdim grids
 
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
 
void print() const
Print method.
 
GPUd() int32_t getYdimensions() const
Get number of Y dimensions.
 
SplineContainer(const SplineContainer &)=delete
Disable all other constructors.
 
void approximateFunction(const double xMin[], const double xMax[], std::function< void(const double x[], double f[])> F, const int32_t nAuxiliaryDataPoints[]=nullptr)
_______________ Construction interface ________________________
 
GPUd() const DataT *getParameters() const
Get spline parameters const.
 
Spline1D< DataT >::Knot Knot
 
GPUd() int32_t calcNumberOfParametersPerKnot(int32_t nYdim) const
Number of parameters per knot.
 
GPUd() static const expr size_t getParameterAlignmentBytes()
Get minimal required alignment for the spline parameters.
 
GPUd() DataT interpolate(const DataT x[]) const
Simplified interface for 1D: return the interpolated value.
 
GPUd() void interpolate(const DataT x[]
_______________ Interpolation math ________________________
 
GPUd() void interpolateU(int32_t inpXdim
Get interpolated value for S(u):inpXdim->inpYdim using spline parameters Parameters.
 
TBase::SafetyLevel SafetyLevel
 
GPUd() const expr int32_t getYdimensions() const
Get number of Y dimensions.
 
GPUd() void interpolateU(GPUgeneric() const DataT Parameters[]
_______ Expert tools: interpolation with given nYdim and external Parameters _______
 
void recreate(const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
 
SplineSpec()
Default constructor.
 
TVeryBase::SafetyLevel SafetyLevel
 
GPUd() const expr int32_t getXdimensions() const
Get number of X dimensions.
 
SplineSpec(const int32_t nKnots[])
Constructor for a regular spline.
 
SplineSpec(const SplineSpec &v)
Copy constructor.
 
void recreate(const int32_t nKnots[])
Constructor for a regular spline.
 
SplineSpec(const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
 
SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
 
SplineSpec(const SplineSpec &v)
Copy constructor.
 
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
 
SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
 
SplineSpec()
Default constructor.
 
TVeryBase::SafetyLevel SafetyLevel
 
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
 
void checkDimensions(int32_t &nXdim, int32_t &nYdim)
Check dimensions.
 
static constexpr int32_t getSpec(int32_t nXdim, int32_t nYdim)
 
GLuint const GLchar * name
 
GLsizei GLenum const void * indices
 
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
 
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...