Project
Loading...
Searching...
No Matches
Spline1DSpec.cxx
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#include "Spline1DSpec.h"
18
19#if !defined(GPUCA_GPUCODE)
20#include <iostream>
21#include <algorithm>
22#endif
23
24#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) // code invisible on GPU and in the standalone compilation
25#include "Spline1DHelper.h"
26#include "TFile.h"
27#include "GPUCommonMath.h"
30#endif
31
32using namespace std;
33using namespace o2::gpu;
34
35#if !defined(GPUCA_GPUCODE)
36
37template <class DataT>
38void Spline1DContainer<DataT>::recreate(int32_t nYdim, int32_t numberOfKnots)
39{
42
43 if (numberOfKnots < 2) {
44 numberOfKnots = 2;
45 }
46
47 std::vector<int32_t> knots(numberOfKnots);
48 for (int32_t i = 0; i < numberOfKnots; i++) {
49 knots[i] = i;
50 }
51 recreate(nYdim, numberOfKnots, knots.data());
52}
53
54template <class DataT>
55void Spline1DContainer<DataT>::recreate(int32_t nYdim, int32_t numberOfKnots, const int32_t inputKnots[])
56{
66
68
69 mYdim = (nYdim >= 0) ? nYdim : 0;
70
71 std::vector<int32_t> knotU;
72
73 { // sort knots
74 std::vector<int32_t> tmp;
75 for (int32_t i = 0; i < numberOfKnots; i++) {
76 tmp.push_back(inputKnots[i]);
77 }
78 std::sort(tmp.begin(), tmp.end());
79
80 knotU.push_back(0); // first knot at 0
81
82 for (uint32_t i = 1; i < tmp.size(); ++i) {
83 int32_t u = tmp[i] - tmp[0];
84 if (knotU.back() < u) { // remove duplicated knots
85 knotU.push_back(u);
86 }
87 }
88 if (knotU.back() < 1) { // there is only one knot at u=0, add the second one at u=1
89 knotU.push_back(1);
90 }
91 }
92
93 mNumberOfKnots = knotU.size();
94 mUmax = knotU.back();
95 mXmin = 0.;
96 mXtoUscale = 1.;
97
98 const int32_t uToKnotMapOffset = mNumberOfKnots * sizeof(Knot);
99 int32_t parametersOffset = uToKnotMapOffset + (mUmax + 1) * sizeof(int32_t);
100 int32_t bufferSize = parametersOffset;
101 if (mYdim > 0) {
102 parametersOffset = alignSize(bufferSize, getParameterAlignmentBytes());
103 bufferSize = parametersOffset + getSizeOfParameters();
104 }
105
107
108 mUtoKnotMap = reinterpret_cast<int32_t*>(mFlatBufferPtr + uToKnotMapOffset);
109 mParameters = reinterpret_cast<DataT*>(mFlatBufferPtr + parametersOffset);
110
111 for (int32_t i = 0; i < getNumberOfParameters(); i++) {
112 mParameters[i] = 0;
113 }
114
115 Knot* s = getKnots();
116
117 for (int32_t i = 0; i < mNumberOfKnots; i++) {
118 s[i].u = knotU[i];
119 }
120
121 for (int32_t i = 0; i < mNumberOfKnots - 1; i++) {
122 s[i].Li = 1. / (s[i + 1].u - s[i].u); // do division in double
123 }
124
125 s[mNumberOfKnots - 1].Li = 0.; // the value will not be used, we define it for consistency
126
127 // Set up the map (integer U) -> (knot index)
128
129 int32_t* map = getUtoKnotMap();
130
131 const int32_t iKnotMax = mNumberOfKnots - 2;
132
133 //
134 // With iKnotMax=nKnots-2 we map the U==Umax coordinate to the last [nKnots-2, nKnots-1] segment.
135 // This trick allows one to avoid a special condition for this edge case.
136 // Any U from [0,Umax] is mapped to some knot_i such, that the next knot_i+1 always exist
137 //
138
139 for (int32_t u = 0, iKnot = 0; u <= mUmax; u++) {
140 if ((knotU[iKnot + 1] == u) && (iKnot < iKnotMax)) {
141 iKnot = iKnot + 1;
142 }
143 map[u] = iKnot;
144 }
145}
146
147#endif //GPUCA_GPUCODE
148
149template <class DataT>
151{
152 printf(" Spline 1D: \n");
153 printf(" mNumberOfKnots = %d \n", mNumberOfKnots);
154 printf(" mUmax = %d\n", mUmax);
155 printf(" mUtoKnotMap = %p \n", (void*)mUtoKnotMap);
156 printf(" knots: ");
157 for (int32_t i = 0; i < mNumberOfKnots; i++) {
158 printf("%d ", (int32_t)getKnot(i).u);
159 }
160 printf("\n");
161}
162
163#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
164
165template <class DataT>
167 double xMin, double xMax,
168 std::function<void(double x, double f[])> F,
169 int32_t nAxiliaryDataPoints)
170{
173 helper.approximateFunction(*reinterpret_cast<Spline1D<DataT>*>(this), xMin, xMax, F, nAxiliaryDataPoints);
174}
175
176template <class DataT>
177int32_t Spline1DContainer<DataT>::writeToFile(TFile& outf, const char* name)
178{
180 return FlatObject::writeToFile(*this, outf, name);
181}
182
183template <class DataT>
185 TFile& inpf, const char* name)
186{
188 return FlatObject::readFromFile<Spline1DContainer<DataT>>(inpf, name);
189}
190
191#endif
192
193#if !defined(GPUCA_GPUCODE)
194
195template <class DataT>
197{
199
200 const char* oldFlatBufferPtr = obj.mFlatBufferPtr;
201 FlatObject::cloneFromObject(obj, newFlatBufferPtr);
202 mYdim = obj.mYdim;
203 mNumberOfKnots = obj.mNumberOfKnots;
204 mUmax = obj.mUmax;
205 mXmin = obj.mXmin;
206 mXtoUscale = obj.mXtoUscale;
207 mUtoKnotMap = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mUtoKnotMap);
208 mParameters = FlatObject::relocatePointer(oldFlatBufferPtr, mFlatBufferPtr, obj.mParameters);
209}
210
211template <class DataT>
212void Spline1DContainer<DataT>::moveBufferTo(char* newFlatBufferPtr)
213{
215 char* oldFlatBufferPtr = mFlatBufferPtr;
216 FlatObject::moveBufferTo(newFlatBufferPtr);
217 char* currFlatBufferPtr = mFlatBufferPtr;
218 mFlatBufferPtr = oldFlatBufferPtr;
219 setActualBufferAddress(currFlatBufferPtr);
220}
221#endif // GPUCA_GPUCODE
222
223template <class DataT>
225{
227 mNumberOfKnots = 0;
228 mUmax = 0;
229 mYdim = 0;
230 mXmin = 0.;
231 mXtoUscale = 1.;
232 mUtoKnotMap = nullptr;
233 mParameters = nullptr;
235}
236
237template <class DataT>
239{
241
242 FlatObject::setActualBufferAddress(actualFlatBufferPtr);
243
244 const int32_t uToKnotMapOffset = mNumberOfKnots * sizeof(Knot);
245 mUtoKnotMap = reinterpret_cast<int32_t*>(mFlatBufferPtr + uToKnotMapOffset);
246 int32_t parametersOffset = uToKnotMapOffset + (mUmax + 1) * sizeof(int32_t);
247 if (mYdim > 0) {
248 parametersOffset = alignSize(parametersOffset, getParameterAlignmentBytes());
249 }
250 mParameters = reinterpret_cast<DataT*>(mFlatBufferPtr + parametersOffset);
251}
252
253template <class DataT>
255{
257 mUtoKnotMap = FlatObject::relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mUtoKnotMap);
258 mParameters = relocatePointer(mFlatBufferPtr, futureFlatBufferPtr, mParameters);
259 FlatObject::setFutureBufferAddress(futureFlatBufferPtr);
260}
261
262#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
263template <class DataT>
264int32_t Spline1DContainer<DataT>::test(const bool draw, const bool drawDataPoints)
265{
266 return Spline1DHelper<DataT>::test(draw, drawDataPoints);
267}
268#endif // GPUCA_GPUCODE
269
int32_t i
Definition of Spline1DHelper class.
templateClassImp(o2::gpu::Spline1DContainer)
Definition of Spline1DSpec class.
void setFutureBufferAddress(char *futureFlatBufferPtr)
Definition FlatObject.h:557
void destroy()
_______________ Utilities _______________________________________________
Definition FlatObject.h:349
static T * relocatePointer(const char *oldBase, char *newBase, const T *ptr)
Relocates a pointer inside a buffer to the new buffer address.
Definition FlatObject.h:285
void setActualBufferAddress(char *actualFlatBufferPtr)
_____________ Methods for moving the class with its external buffer to another location _____________...
Definition FlatObject.h:547
static int32_t writeToFile(T &obj, TFile &outf, const char *name)
write a child class object to the file
Definition FlatObject.h:480
void startConstruction()
_____________ Construction _________
Definition FlatObject.h:342
void moveBufferTo(char *newBufferPtr)
Definition FlatObject.h:396
void finishConstruction(int32_t flatBufferSize)
Definition FlatObject.h:358
void cloneFromObject(const FlatObject &obj, char *newFlatBufferPtr)
Definition FlatObject.h:373
void cloneFromObject(const Spline1DContainer &obj, char *newFlatBufferPtr)
void setFutureBufferAddress(char *futureFlatBufferPtr)
int32_t mUmax
U of the last knot.
int32_t mYdim
_____________ Data members ____________
void setActualBufferAddress(char *actualFlatBufferPtr)
void approximateFunction(double xMin, double xMax, std::function< void(double x, double f[])> F, int32_t nAuxiliaryDataPoints=4)
_______________ Construction interface ________________________
DataT mXtoUscale
a scaling factor to convert X to U
void print() const
Print method.
DataT * mParameters
(transient!!) pointer to (integer U -> knot index) map inside the mFlatBufferPtr array
void recreate(int32_t nYdim, int32_t numberOfKnots)
Constructor for a regular spline.
DataT mXmin
X of the first knot.
static int32_t test(const bool draw=0, const bool drawDataPoints=1)
_______________ Test tools _______________
void moveBufferTo(char *newBufferPtr)
int32_t writeToFile(TFile &outf, const char *name)
_______________ IO ________________________
int32_t mNumberOfKnots
n knots on the grid
static Spline1DContainer * readFromFile(TFile &inpf, const char *name)
read a class object from the file
void approximateFunction(Spline1DContainer< DataT > &spline, double xMin, double xMax, std::function< void(double x, double f[])> F, int32_t nAuxiliaryDataPoints=4)
Create best-fit spline parameters for a function F.
static int32_t test(const bool draw=0, const bool drawDataPoints=1)
Test the Spline1D class functionality.
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
Defining DataPointCompositeObject explicitly as copiable.