]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliCheb3D.h
First version of the SDD DA calibration classes. AliITSOnlineSDDBase - for measuremen...
[u/mrichter/AliRoot.git] / STEER / AliCheb3D.h
CommitLineData
0eea9d4d 1#ifndef ALICHEB3D_H
2#define ALICHEB3D_H
3/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * See cxx source for full Copyright notice */
5
6/* $Id$ */
7
8// Author: ruben.shahoyan@cern.ch 09/09/2006
9//
10////////////////////////////////////////////////////////////////////////////////
11// //
12// AliCheb3D produces the interpolation of the user 3D->NDimOut arbitrary //
13// function supplied in "void (*fcn)(float* inp,float* out)" format //
14// either in a separate macro file or as a function pointer. //
15// Only coefficients needed to guarantee the requested precision are kept. //
16// //
17// The user-callable methods are: //
18// To create the interpolation use: //
19// AliCheb3D(const char* funName, // name of the file with user function //
20// or //
21// AliCheb3D(void (*ptr)(float*,float*),// pointer on the user function //
22// Int_t DimOut, // dimensionality of the function's output //
23// Float_t *bmin, // lower 3D bounds of interpolation domain //
24// Float_t *bmax, // upper 3D bounds of interpolation domain //
25// Int_t *npoints, // number of points in each of 3 input //
26// // dimension, defining the interpolation grid //
27// Float_t prec=1E-6); // requested max.absolute difference between //
28// // the interpolation and any point on grid //
29// //
30// To test obtained parameterization use the method //
31// TH1* TestRMS(int idim,int npoints = 1000,TH1* histo=0); //
32// it will compare the user output of the user function and interpolation //
33// for idim-th output dimension and fill the difference in the supplied //
34// histogram. If no histogram is supplied, it will be created. //
35// //
36// To save the interpolation data: //
37// SaveData(const char* filename, Bool_t append ) //
38// write text file with data. If append is kTRUE and the output file already //
39// exists, data will be added in the end of the file. //
40// Alternatively, SaveData(FILE* stream) will write the data to //
41// already existing stream. //
42// //
43// To read back already stored interpolation use either the constructor //
44// AliCheb3D(const char* inpFile); //
45// or the default constructor AliCheb3D() followed by //
46// AliCheb3D::LoadData(const char* inpFile); //
47// //
48// To compute the interpolation use Eval(float* par,float *res) method, with //
49// par being 3D vector of arguments (inside the validity region) and res is //
50// the array of DimOut elements for the output. //
51// //
52// If only one component (say, idim-th) of the output is needed, use faster //
53// Float_t Eval(Float_t *par,int idim) method. //
54// //
55// void Print(option="") will print the name, the ranges of validity and //
56// the absolute precision of the parameterization. Option "l" will also print //
57// the information about the number of coefficients for each output //
58// dimension. //
59// //
60// NOTE: during the evaluation no check is done for parameter vector being //
61// outside the interpolation region. If there is such a risk, use //
62// Bool_t IsInside(float *par) method. Chebyshev parameterization is not //
63// good for extrapolation! //
64// //
65// For the properties of Chebyshev parameterization see: //
66// H.Wind, CERN EP Internal Report, 81-12/Rev. //
67// //
68////////////////////////////////////////////////////////////////////////////////
69
70
71#include <stdio.h>
72#include <TNamed.h>
73#include <TMethodCall.h>
74#include <TMath.h>
75#include <TH1.h>
76#include <TObjArray.h>
77
78class TString;
79class TSystem;
80class TRandom;
81
82
83// to decrease the compilable code size comment this define. This will exclude the routines
84// used for the calculation and saving of the coefficients.
85// #define _INC_CREATION_ALICHEB3D_
86
87class AliCheb3DCalc: public TNamed
88{
89 public:
90 AliCheb3DCalc();
91 AliCheb3DCalc(FILE* stream); // read coefs from text file
0bc7b414 92 AliCheb3DCalc(const AliCheb3DCalc &cheb);
93 AliCheb3DCalc& operator= (const AliCheb3DCalc &cheb) {
94 // Assignment operator
95 cheb.Copy(*this);
96 return *this;
97 }
98
0eea9d4d 99 ~AliCheb3DCalc() {Clear();}
100 //
101 void Print(Option_t* opt="") const;
102 void LoadData(FILE* stream);
103 Float_t Eval(Float_t *par) const;
104 //
105#ifdef _INC_CREATION_ALICHEB3D_
106 void SaveData(const char* outfile,Bool_t append=kFALSE) const;
107 void SaveData(FILE* stream=stdout) const;
108#endif
109 //
110 static void ReadLine(TString& str,FILE* stream);
0bc7b414 111 private:
112 void Copy (TObject &mc) const;
0eea9d4d 113 //
114 protected:
115 //
116 void Clear(Option_t* option = "");
117 void Init0();
118 Float_t ChebEval1D(Float_t x, const Float_t * array, int ncf) const;
119 void InitRows(int nr);
120 void InitCols(int nc);
121 void InitElemBound2D(int ne);
122 void InitCoefs(int nc);
123 Int_t* GetNColsAtRow() const {return fNColsAtRow;}
124 Int_t* GetColAtRowBg() const {return fColAtRowBg;}
125 Int_t* GetCoefBound2D0() const {return fCoefBound2D0;}
126 Int_t* GetCoefBound2D1() const {return fCoefBound2D1;}
127 Float_t * GetCoefs() const {return fCoefs;}
128 //
129 protected:
130 Int_t fNCoefs; // total number of coeeficients
131 Int_t fNRows; // number of significant rows in the 3D coeffs matrix
132 Int_t fNCols; // max number of significant cols in the 3D coeffs matrix
133 Int_t fNElemBound2D; // number of elements (fNRows*fNCols) to store for the 2D boundary of significant coeffs
134 Int_t* fNColsAtRow; //[fNRows] number of sighificant columns (2nd dim) at each row of 3D coefs matrix
135 Int_t* fColAtRowBg; //[fNRows] beginnig of significant columns (2nd dim) for row in the 2D boundary matrix
136 Int_t* fCoefBound2D0; //[fNElemBound2D] 2D matrix defining the boundary of significance for 3D coeffs.matrix (Ncoefs for col/row)
137 Int_t* fCoefBound2D1; //[fNElemBound2D] 2D matrix defining the start beginnig of significant coeffs for col/row
138 Float_t * fCoefs; //[fNCoefs] array of Chebyshev coefficients
139 //
140 Float_t * fTmpCf1; //[fNCols] temp. coeffs for 2d summation
141 Float_t * fTmpCf0; //[fNRows] temp. coeffs for 1d summation
142 //
143 ClassDef(AliCheb3DCalc,1) // Class for interpolation of 3D->1 function by Chebyshev parametrization
144};
145
146
147class AliCheb3D: public TNamed
148{
149 public:
150 AliCheb3D();
151 AliCheb3D(const char* inpFile); // read coefs from text file
152 AliCheb3D(FILE*); // read coefs from stream
0bc7b414 153 AliCheb3D(const AliCheb3D &cheb);
154 AliCheb3D& operator= (const AliCheb3D &cheb) {
155 // Assignment operator
156 cheb.Copy(*this);
157 return *this;
158 }
159
0eea9d4d 160 //
161#ifdef _INC_CREATION_ALICHEB3D_
162 AliCheb3D(const char* funName, Int_t DimOut, Float_t *bmin,Float_t *bmax, Int_t *npoints, Float_t prec=1E-6);
163 AliCheb3D(void (*ptr)(float*,float*), Int_t DimOut, Float_t *bmin,Float_t *bmax, Int_t *npoints, Float_t prec=1E-6);
164#endif
165 //
166 ~AliCheb3D() {Clear();}
167 //
168 void Eval(Float_t *par,Float_t *res);
169 Float_t Eval(Float_t *par,int idim);
170 void Print(Option_t* opt="") const;
171 Bool_t IsInside(Float_t *par) const;
172 AliCheb3DCalc* GetChebCalc(int i) const {return (AliCheb3DCalc*)fChebCalc.UncheckedAt(i);}
173 Float_t GetBoundMin(int i) const {return fBMin[i];}
174 Float_t GetBoundMax(int i) const {return fBMax[i];}
175 Float_t GetPrecision() const {return fPrec;}
176 void ShiftBound(int id,float dif);
177 //
178 void LoadData(const char* inpFile);
179 void LoadData(FILE* stream);
180 //
181#ifdef _INC_CREATION_ALICHEB3D_
182 void SaveData(const char* outfile,Bool_t append=kFALSE) const;
183 void SaveData(FILE* stream=stdout) const;
184 //
185 void SetUsrFunction(const char* name);
186 void SetUsrFunction(void (*ptr)(float*,float*));
187 void EvalUsrFunction(Float_t *x, Float_t *res);
188 TH1* TestRMS(int idim,int npoints = 1000,TH1* histo=0);
189#endif
190 //
191 protected:
192 void Init0();
193 void Clear(Option_t* option = "");
194 void SetDimOut(int d);
195 void PrepareBoundaries(Float_t *bmin,Float_t *bmax);
196 //
197#ifdef _INC_CREATION_ALICHEB3D_
198 void EvalUsrFunction();
199 void DefineGrid(Int_t* npoints);
200 Int_t ChebFit(); // fit all output dimensions
201 Int_t ChebFit(int dmOut);
202 Int_t CalcChebCoefs(Float_t *funval,int np, Float_t *outCoefs, Float_t prec=-1);
203#endif
204 //
205 void Cyl2CartCyl(float *rphiz, float *b) const;
206 void Cart2Cyl(float *xyz,float *rphiz) const;
207 //
208 Float_t MapToInternal(Float_t x,Int_t d) const {return (x-fBOffset[d])*fBScale[d];} // map x to [-1:1]
209 Float_t MapToExternal(Float_t x,Int_t d) const {return x/fBScale[d]+fBOffset[d];} // map from [-1:1] to x
0bc7b414 210 //
211 private:
212 void Copy (TObject &mc) const;
0eea9d4d 213 protected:
214 Int_t fDimOut; // dimension of the ouput array
215 Float_t fPrec; // requested precision
216 Float_t fBMin[3]; // min boundaries in each dimension
217 Float_t fBMax[3]; // max boundaries in each dimension
218 Float_t fBScale[3]; // scale for boundary mapping to [-1:1] interval
219 Float_t fBOffset[3]; // offset for boundary mapping to [-1:1] interval
220 TObjArray fChebCalc; // Chebyshev parameterization for each output dimension
221 //
222 Int_t fMaxCoefs; //! max possible number of coefs per parameterization
223 Int_t fNPoints[3]; //! number of used points in each dimension
224 Float_t fArgsTmp[3]; //! temporary vector for coefs caluclation
225 Float_t fBuff[6]; //! buffer for coordinate transformations
226 Float_t * fResTmp; //! temporary vector for results of user function caluclation
227 Float_t * fGrid; //! temporary buffer for Chebyshef roots grid
228 Int_t fGridOffs[3]; //! start of grid for each dimension
229 TString fUsrFunName; //! name of user macro containing the function of "void (*fcn)(float*,float*)" format
230 TMethodCall* fUsrMacro; //! Pointer to MethodCall for function from user macro
231 //
232 ClassDef(AliCheb3D,1) // Chebyshev parametrization for 3D->N function
233};
234
235// Pointer on user function (faster altrnative to TMethodCall)
236#ifdef _INC_CREATION_ALICHEB3D_
237void (*gUsrFunAliCheb3D) (float* ,float* );
238#endif
239
240//__________________________________________________________________________________________
241#ifdef _INC_CREATION_ALICHEB3D_
242inline void AliCheb3D::EvalUsrFunction()
243{
244 // call user supplied function
245 if (gUsrFunAliCheb3D) gUsrFunAliCheb3D(fArgsTmp,fResTmp);
246 else fUsrMacro->Execute();
247}
248#endif
249
250//__________________________________________________________________________________________
251inline Bool_t AliCheb3D::IsInside(Float_t *par) const
252{
253 // check if the point is inside of the fitted box
254 for (int i=3;i--;) if(par[i]<fBMin[i]||par[i]>fBMax[i]) return kFALSE;
255 return kTRUE;
256}
257
258//__________________________________________________________________________________________
259inline Float_t AliCheb3DCalc::ChebEval1D(Float_t x, const Float_t * array, int ncf ) const
260{
261 // evaluate 1D Chebyshev parameterization. x is the argument mapped to [-1:1] interval
262 Float_t b0, b1, b2;
263 Float_t x2 = x+x;
264 b0 = array[--ncf];
265 b1 = b2 = 0;
266 for (int i=ncf;i--;) {
267 b2 = b1;
268 b1 = b0;
269 b0 = array[i] + x2*b1 -b2;
270 }
271 return b0 - x*b1;
272}
273
274//__________________________________________________________________________________________
275inline void AliCheb3D::Eval(Float_t *par, Float_t *res)
276{
277 // evaluate Chebyshev parameterization for 3d->DimOut function
278 for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
279 for (int i=fDimOut;i--;) res[i] = GetChebCalc(i)->Eval(fArgsTmp);
280 //
281}
282
283//__________________________________________________________________________________________
284inline Float_t AliCheb3D::Eval(Float_t *par, int idim)
285{
286 // evaluate Chebyshev parameterization for idim-th output dimension of 3d->DimOut function
287 for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
288 return GetChebCalc(idim)->Eval(fArgsTmp);
289 //
290}
291
292//__________________________________________________________________________________________________
293inline void AliCheb3D::Cyl2CartCyl(float *rphiz, float *b) const
294{
295 // convert field in cylindrical coordinates to cartesian system, point is in cyl.system
296 float btr = TMath::Sqrt(b[0]*b[0]+b[1]*b[1]);
297 float ang = TMath::ATan2(b[1],b[0]) + rphiz[1];
298 b[0] = btr*TMath::Cos(ang);
299 b[1] = btr*TMath::Sin(ang);
300 //
301}
302
303//__________________________________________________________________________________________________
304inline void AliCheb3D::Cart2Cyl(float *xyz,float *rphiz) const
305{
306 // convert cartesian coordinate to cylindrical one
307 rphiz[0] = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
308 rphiz[1] = TMath::ATan2(xyz[1],xyz[0]);
309 rphiz[2] = xyz[2];
310}
311
312#endif