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#include <iostream>
20#include <algorithm>
21
22#if !defined(GPUCA_STANDALONE) // code invisible on GPU and in the standalone compilation
23#include "Spline1DHelper.h"
24#include "TFile.h"
25#include "GPUCommonMath.h"
27#endif
28
29using namespace std;
30using namespace o2::gpu;
31
32template <class DataT>
33void Spline1DContainer<DataT, FlatObject>::recreate(int32_t nYdim, int32_t numberOfKnots)
34{
37
38 if (numberOfKnots < 2) {
39 numberOfKnots = 2;
40 }
41
42 std::vector<int32_t> knots(numberOfKnots);
43 for (int32_t i = 0; i < numberOfKnots; i++) {
44 knots[i] = i;
45 }
46 recreate(nYdim, numberOfKnots, knots.data());
47}
48
49template <class DataT>
50void Spline1DContainer<DataT, FlatObject>::recreate(int32_t nYdim, int32_t numberOfKnots, const int32_t inputKnots[])
51{
62
63 this->mYdim = (nYdim >= 0) ? nYdim : 0;
64
65 std::vector<int32_t> knotU;
66
67 { // sort knots
68 std::vector<int32_t> tmp;
69 for (int32_t i = 0; i < numberOfKnots; i++) {
70 tmp.push_back(inputKnots[i]);
71 }
72 std::sort(tmp.begin(), tmp.end());
73
74 knotU.push_back(0); // first knot at 0
75
76 for (uint32_t i = 1; i < tmp.size(); ++i) {
77 int32_t u = tmp[i] - tmp[0];
78 if (knotU.back() < u) { // remove duplicated knots
79 knotU.push_back(u);
80 }
81 }
82 if (knotU.back() < 1) { // there is only one knot at u=0, add the second one at u=1
83 knotU.push_back(1);
84 }
85 }
86
87 this->mNumberOfKnots = knotU.size();
88 this->mUmax = knotU.back();
89 this->mXmin = 0.;
90 this->mXtoUscale = 1.;
91
92 const int32_t uToKnotMapOffset = this->mNumberOfKnots * sizeof(Knot<DataT>);
93 int32_t parametersOffset = uToKnotMapOffset + (this->mUmax + 1) * sizeof(int32_t);
94 int32_t bufferSize = parametersOffset;
95 if (this->mYdim > 0) {
96 parametersOffset = this->alignSize(bufferSize, this->getParameterAlignmentBytes());
97 bufferSize = parametersOffset + this->getSizeOfParameters();
98 }
99
101
102 this->mUtoKnotMap = reinterpret_cast<int32_t*>(this->mFlatBufferPtr + uToKnotMapOffset);
103 this->mParameters = reinterpret_cast<DataT*>(this->mFlatBufferPtr + parametersOffset);
104
105 for (int32_t i = 0; i < this->getNumberOfParameters(); i++) {
106 this->mParameters[i] = 0;
107 }
108
109 Knot<DataT>* s = getKnots();
110
111 for (int32_t i = 0; i < this->mNumberOfKnots; i++) {
112 s[i].u = knotU[i];
113 }
114
115 for (int32_t i = 0; i < this->mNumberOfKnots - 1; i++) {
116 s[i].Li = 1. / (s[i + 1].u - s[i].u); // do division in double
117 }
118
119 s[this->mNumberOfKnots - 1].Li = 0.; // the value will not be used, we define it for consistency
120
121 // Set up the map (integer U) -> (knot index)
122
123 int32_t* map = getUtoKnotMap();
124
125 const int32_t iKnotMax = this->mNumberOfKnots - 2;
126
127 //
128 // With iKnotMax=nKnots-2 we map the U==Umax coordinate to the last [nKnots-2, nKnots-1] segment.
129 // This trick allows one to avoid a special condition for this edge case.
130 // Any U from [0,Umax] is mapped to some knot_i such, that the next knot_i+1 always exist
131 //
132
133 for (int32_t u = 0, iKnot = 0; u <= this->mUmax; u++) {
134 if ((knotU[iKnot + 1] == u) && (iKnot < iKnotMax)) {
135 iKnot = iKnot + 1;
136 }
137 map[u] = iKnot;
138 }
139}
140
141template <class DataT>
143{
144 printf(" Spline 1D: \n");
145 printf(" mNumberOfKnots = %d \n", this->mNumberOfKnots);
146 printf(" mUmax = %d\n", this->mUmax);
147 printf(" mUtoKnotMap = %p \n", (void*)this->mUtoKnotMap);
148 printf(" knots: ");
149 for (int32_t i = 0; i < this->mNumberOfKnots; i++) {
150 printf("%d ", (int32_t)getKnot(i).u);
151 }
152 printf("\n");
153}
154
155#if !defined(GPUCA_STANDALONE)
156
157template <class DataT>
159 double xMin, double xMax,
160 std::function<void(double x, double f[])> F,
161 int32_t nAxiliaryDataPoints)
162{
165 helper.approximateFunction(*this, xMin, xMax, F, nAxiliaryDataPoints);
166}
167
168template <class DataT>
169int32_t Spline1DContainer<DataT, FlatObject>::writeToFile(TFile& outf, const char* name)
170{
172 return FlatObject::writeToFile(*this, outf, name);
173}
174
175template <class DataT>
177{
179 return FlatObject::readFromFile<Spline1DContainer<DataT, FlatObject>>(inpf, name);
180}
181
182template <class DataT>
183int32_t Spline1DContainer<DataT, FlatObject>::test(const bool draw, const bool drawDataPoints)
184{
186}
187
188#endif
189
190template <class DataT>
192{
194 const char* oldFlatBufferPtr = obj.mFlatBufferPtr;
195 FlatObject::cloneFromObject(obj, newFlatBufferPtr);
196 this->mYdim = obj.mYdim;
197 this->mNumberOfKnots = obj.mNumberOfKnots;
198 this->mUmax = obj.mUmax;
199 this->mXmin = obj.mXmin;
200 this->mXtoUscale = obj.mXtoUscale;
201 this->mUtoKnotMap = FlatObject::relocatePointer(oldFlatBufferPtr, this->mFlatBufferPtr, obj.mUtoKnotMap);
202 this->mParameters = FlatObject::relocatePointer(oldFlatBufferPtr, this->mFlatBufferPtr, obj.mParameters);
203}
204
205template <class DataT>
207{
209 char* oldFlatBufferPtr = this->mFlatBufferPtr;
210 FlatObject::moveBufferTo(newFlatBufferPtr);
211 char* currFlatBufferPtr = this->mFlatBufferPtr;
212 this->mFlatBufferPtr = oldFlatBufferPtr;
213 setActualBufferAddress(currFlatBufferPtr);
214}
215
216template <class DataT>
217template <class OtherFlatBase>
219{
222 this->mYdim = src.getYdimensions();
223 this->mNumberOfKnots = src.getNumberOfKnots();
224 this->mUmax = src.getUmax();
225 this->mXmin = src.getXmin();
226 this->mXtoUscale = src.getXtoUscale();
227 this->mFlatBufferSize = src.getFlatBufferSize();
228 this->mUtoKnotMap = nullptr;
229 this->mParameters = nullptr;
230}
231
232template <class DataT>
234{
235 this->mNumberOfKnots = 0;
236 this->mUmax = 0;
237 this->mYdim = 0;
238 this->mXmin = 0.;
239 this->mXtoUscale = 1.;
240 this->mUtoKnotMap = nullptr;
241 this->mParameters = nullptr;
243}
244
245template <class DataT>
247{
249 FlatObject::setActualBufferAddress(actualFlatBufferPtr);
250
251 const int32_t uToKnotMapOffset = this->mNumberOfKnots * sizeof(Knot<DataT>);
252 this->mUtoKnotMap = reinterpret_cast<int32_t*>(this->mFlatBufferPtr + uToKnotMapOffset);
253 int32_t parametersOffset = uToKnotMapOffset + (this->mUmax + 1) * sizeof(int32_t);
254 if (this->mYdim > 0) {
255 parametersOffset = this->alignSize(parametersOffset, this->getParameterAlignmentBytes());
256 }
257 mParameters = reinterpret_cast<DataT*>(this->mFlatBufferPtr + parametersOffset);
258}
259
260template <class DataT>
262{
264 this->mUtoKnotMap = FlatObject::relocatePointer(this->mFlatBufferPtr, futureFlatBufferPtr, this->mUtoKnotMap);
265 this->mParameters = FlatObject::relocatePointer(this->mFlatBufferPtr, futureFlatBufferPtr, this->mParameters);
266 FlatObject::setFutureBufferAddress(futureFlatBufferPtr);
267}
268
275
276// Explicit instantiations for NoFlatObject (used by TPCFastTransformPOD)
281// importFrom instantiation for the FlatObject -> NoFlatObject conversion used in create()
284// importFrom for FlatObject container (FlatObject -> FlatObject, e.g. when using as a copy tool)
int32_t i
Definition of Spline1DHelper class.
templateClassImp(o2::gpu::Spline1DContainer)
Definition of Spline1DSpec class.
void setFutureBufferAddress(char *futureFlatBufferPtr)
Definition FlatObject.h:569
void destroy()
_______________ Utilities _______________________________________________
Definition FlatObject.h:361
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:283
void setActualBufferAddress(char *actualFlatBufferPtr)
_____________ Methods for moving the class with its external buffer to another location _____________...
Definition FlatObject.h:559
static int32_t writeToFile(T &obj, TFile &outf, const char *name)
write a child class object to the file
Definition FlatObject.h:492
void startConstruction()
_____________ Construction _________
Definition FlatObject.h:354
void moveBufferTo(char *newBufferPtr)
Definition FlatObject.h:408
void finishConstruction(int32_t flatBufferSize)
Definition FlatObject.h:370
void cloneFromObject(const FlatObject &obj, char *newFlatBufferPtr)
Definition FlatObject.h:385
void approximateFunction(Spline1DContainer< DataT, FlatObject > &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
GLenum src
Definition glcorearb.h:1767
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
size_t alignSize(size_t sizeBytes)
align size to given diven number of bytes
TCanvas * drawDataPoints(TMultiGraph *mg, double min, double max)