-// Author: ruben.shahoyan@cern.ch 09/09/2006
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// AliCheb3D produces the interpolation of the user 3D->NDimOut arbitrary //
-// function supplied in "void (*fcn)(float* inp,float* out)" format //
-// either in a separate macro file or as a function pointer. //
-// Only coefficients needed to guarantee the requested precision are kept. //
-// //
-// The user-callable methods are: //
-// To create the interpolation use: //
-// AliCheb3D(const char* funName, // name of the file with user function //
-// or //
-// AliCheb3D(void (*ptr)(float*,float*),// pointer on the user function //
-// Int_t DimOut, // dimensionality of the function's output //
-// Float_t *bmin, // lower 3D bounds of interpolation domain //
-// Float_t *bmax, // upper 3D bounds of interpolation domain //
-// Int_t *npoints, // number of points in each of 3 input //
-// // dimension, defining the interpolation grid //
-// Float_t prec=1E-6); // requested max.absolute difference between //
-// // the interpolation and any point on grid //
-// //
-// To test obtained parameterization use the method //
-// TH1* TestRMS(int idim,int npoints = 1000,TH1* histo=0); //
-// it will compare the user output of the user function and interpolation //
-// for idim-th output dimension and fill the difference in the supplied //
-// histogram. If no histogram is supplied, it will be created. //
-// //
-// To save the interpolation data: //
-// SaveData(const char* filename, Bool_t append ) //
-// write text file with data. If append is kTRUE and the output file already //
-// exists, data will be added in the end of the file. //
-// Alternatively, SaveData(FILE* stream) will write the data to //
-// already existing stream. //
-// //
-// To read back already stored interpolation use either the constructor //
-// AliCheb3D(const char* inpFile); //
-// or the default constructor AliCheb3D() followed by //
-// AliCheb3D::LoadData(const char* inpFile); //
-// //
-// To compute the interpolation use Eval(float* par,float *res) method, with //
-// par being 3D vector of arguments (inside the validity region) and res is //
-// the array of DimOut elements for the output. //
-// //
-// If only one component (say, idim-th) of the output is needed, use faster //
-// Float_t Eval(Float_t *par,int idim) method. //
-// //
-// void Print(option="") will print the name, the ranges of validity and //
-// the absolute precision of the parameterization. Option "l" will also print //
-// the information about the number of coefficients for each output //
-// dimension. //
-// //
-// NOTE: during the evaluation no check is done for parameter vector being //
-// outside the interpolation region. If there is such a risk, use //
-// Bool_t IsInside(float *par) method. Chebyshev parameterization is not //
-// good for extrapolation! //
-// //
-// For the properties of Chebyshev parameterization see: //
-// H.Wind, CERN EP Internal Report, 81-12/Rev. //
-// //
-////////////////////////////////////////////////////////////////////////////////
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
#include <TString.h>
#include <TSystem.h>
#include <TROOT.h>
#include <TRandom.h>
+#include <stdio.h>
+#include <TMethodCall.h>
+#include <TMath.h>
+#include <TH1.h>
#include "AliCheb3D.h"
-
-
+#include "AliCheb3DCalc.h"
ClassImp(AliCheb3D)
//__________________________________________________________________________________________
AliCheb3D& AliCheb3D::operator=(const AliCheb3D& rhs)
{
+ // assignment operator
+ //
if (this != &rhs) {
Clear();
fDimOut = rhs.fDimOut;
}
//__________________________________________________________________________________________
-void AliCheb3D::Clear(Option_t*)
+void AliCheb3D::Clear(const Option_t*)
{
+ // clear all dynamic structures
+ //
if (fResTmp) { delete[] fResTmp; fResTmp = 0; }
if (fGrid) { delete[] fGrid; fGrid = 0; }
if (fUsrMacro) { delete fUsrMacro; fUsrMacro = 0;}
}
//__________________________________________________________________________________________
-void AliCheb3D::Print(Option_t* opt) const
+void AliCheb3D::Print(const Option_t* opt) const
{
+ // print info
+ //
printf("%s: Chebyshev parameterization for 3D->%dD function. Precision: %e\n",GetName(),fDimOut,fPrec);
printf("Region of validity: [%+.5e:%+.5e] [%+.5e:%+.5e] [%+.5e:%+.5e]\n",fBMin[0],fBMax[0],fBMin[1],fBMax[1],fBMin[2],fBMax[2]);
TString opts = opt; opts.ToLower();
}
//__________________________________________________________________________________________
-void AliCheb3D::PrepareBoundaries(Float_t *bmin,Float_t *bmax)
+void AliCheb3D::PrepareBoundaries(const Float_t *bmin, const Float_t *bmax)
{
// Set and check boundaries defined by user, prepare coefficients for their conversion to [-1:1] interval
//
#ifdef _INC_CREATION_ALICHEB3D_
void AliCheb3D::SetUsrFunction(void (*ptr)(float*,float*))
{
+ // assign user training function
+ //
if (fUsrMacro) delete fUsrMacro;
fUsrMacro = 0;
fUsrFunName = "";
//__________________________________________________________________________________________
#ifdef _INC_CREATION_ALICHEB3D_
-void AliCheb3D::EvalUsrFunction(Float_t *x, Float_t *res) {
+void AliCheb3D::EvalUsrFunction(const Float_t *x, const Float_t *res)
+{
+ // evaluate user function value
+ //
for (int i=3;i--;) fArgsTmp[i] = x[i];
if (gUsrFunAliCheb3D) gUsrFunAliCheb3D(fArgsTmp,fResTmp);
else fUsrMacro->Execute();
//__________________________________________________________________________________________
#ifdef _INC_CREATION_ALICHEB3D_
-Int_t AliCheb3D::CalcChebCoefs(Float_t *funval,int np, Float_t *outCoefs, Float_t prec)
+Int_t AliCheb3D::CalcChebCoefs(const Float_t *funval,int np, Float_t *outCoefs, Float_t prec)
{
// Calculate Chebyshev coeffs using precomputed function values at np roots.
// If prec>0, estimate the highest coeff number providing the needed precision
Float_t *tmpCoef2D = new Float_t [ fNPoints[0]*fNPoints[1] ];
Float_t *tmpCoef1D = new Float_t [ maxDim ];
//
- Float_t RTiny = fPrec/Float_t(maxDim); // neglect coefficient below this threshold
+ Float_t rTiny = fPrec/Float_t(maxDim); // neglect coefficient below this threshold
//
// 1D Cheb.fit for 0-th dimension at current steps of remaining dimensions
int ncmax = 0;
for (int id2=fNPoints[2];id2--;) {
int id = id2 + fNPoints[2]*(id1+id0*fNPoints[1]);
Float_t cfa = TMath::Abs(tmpCoef3D[id]);
- if (cfa < RTiny) {tmpCoef3D[id] = 0; continue;} // neglect coefs below the threshold
+ if (cfa < rTiny) {tmpCoef3D[id] = 0; continue;} // neglect coefs below the threshold
resid += cfa;
if (resid<fPrec) continue; // this coeff is negligible
// otherwise go back 1 step
}
*/
// see if there are rows to reject, find max.significant column at each row
- int NRows = fNPoints[0];
- int *tmpCols = new int[NRows];
+ int nRows = fNPoints[0];
+ int *tmpCols = new int[nRows];
for (int id0=fNPoints[0];id0--;) {
int id1 = fNPoints[1];
while (id1>0 && tmpCoefSurf[(id1-1)+id0*fNPoints[1]]==0) id1--;
tmpCols[id0] = id1;
}
// find max significant row
- for (int id0=NRows;id0--;) {if (tmpCols[id0]>0) break; NRows--;}
+ for (int id0=nRows;id0--;) {if (tmpCols[id0]>0) break; nRows--;}
// find max significant column and fill the permanent storage for the max sigificant column of each row
- cheb->InitRows(NRows); // create needed arrays;
- int *NColsAtRow = cheb->GetNColsAtRow();
- int *ColAtRowBg = cheb->GetColAtRowBg();
- int NCols = 0;
+ cheb->InitRows(nRows); // create needed arrays;
+ int *nColsAtRow = cheb->GetNColsAtRow();
+ int *colAtRowBg = cheb->GetColAtRowBg();
+ int nCols = 0;
int NElemBound2D = 0;
- for (int id0=0;id0<NRows;id0++) {
- NColsAtRow[id0] = tmpCols[id0]; // number of columns to store for this row
- ColAtRowBg[id0] = NElemBound2D; // begining of this row in 2D boundary surface
+ for (int id0=0;id0<nRows;id0++) {
+ nColsAtRow[id0] = tmpCols[id0]; // number of columns to store for this row
+ colAtRowBg[id0] = NElemBound2D; // begining of this row in 2D boundary surface
NElemBound2D += tmpCols[id0];
- if (NCols<NColsAtRow[id0]) NCols = NColsAtRow[id0];
+ if (nCols<nColsAtRow[id0]) nCols = nColsAtRow[id0];
}
- cheb->InitCols(NCols);
+ cheb->InitCols(nCols);
delete[] tmpCols;
//
// create the 2D matrix defining the boundary of significance for 3D coeffs.matrix
// and count the number of siginifacnt coefficients
//
cheb->InitElemBound2D(NElemBound2D);
- int *CoefBound2D0 = cheb->GetCoefBound2D0();
- int *CoefBound2D1 = cheb->GetCoefBound2D1();
+ int *coefBound2D0 = cheb->GetCoefBound2D0();
+ int *coefBound2D1 = cheb->GetCoefBound2D1();
fMaxCoefs = 0; // redefine number of coeffs
- for (int id0=0;id0<NRows;id0++) {
- int nCLoc = NColsAtRow[id0];
- int Col0 = ColAtRowBg[id0];
+ for (int id0=0;id0<nRows;id0++) {
+ int nCLoc = nColsAtRow[id0];
+ int col0 = colAtRowBg[id0];
for (int id1=0;id1<nCLoc;id1++) {
- CoefBound2D0[Col0 + id1] = tmpCoefSurf[id1+id0*fNPoints[1]]; // number of coefs to store for 3-d dimension
- CoefBound2D1[Col0 + id1] = fMaxCoefs;
- fMaxCoefs += CoefBound2D0[Col0 + id1];
+ coefBound2D0[col0 + id1] = tmpCoefSurf[id1+id0*fNPoints[1]]; // number of coefs to store for 3-d dimension
+ coefBound2D1[col0 + id1] = fMaxCoefs;
+ fMaxCoefs += coefBound2D0[col0 + id1];
}
}
//
// create final compressed 3D matrix for significant coeffs
cheb->InitCoefs(fMaxCoefs);
- Float_t *Coefs = cheb->GetCoefs();
+ Float_t *coefs = cheb->GetCoefs();
int count = 0;
- for (int id0=0;id0<NRows;id0++) {
- int ncLoc = NColsAtRow[id0];
- int Col0 = ColAtRowBg[id0];
+ for (int id0=0;id0<nRows;id0++) {
+ int ncLoc = nColsAtRow[id0];
+ int col0 = colAtRowBg[id0];
for (int id1=0;id1<ncLoc;id1++) {
- int ncf2 = CoefBound2D0[Col0 + id1];
+ int ncf2 = coefBound2D0[col0 + id1];
for (int id2=0;id2<ncf2;id2++) {
- Coefs[count++] = tmpCoef3D[id2 + fNPoints[2]*(id1+id0*fNPoints[1])];
+ coefs[count++] = tmpCoef3D[id2 + fNPoints[2]*(id1+id0*fNPoints[1])];
}
}
}
//_______________________________________________
void AliCheb3D::LoadData(const char* inpFile)
{
+ // load coefficients data from txt file
+ //
TString strf = inpFile;
gSystem->ExpandPathName(strf);
FILE* stream = fopen(strf.Data(),"r");
//_______________________________________________
void AliCheb3D::LoadData(FILE* stream)
{
+ // load coefficients data from stream
+ //
if (!stream) {Error("LoadData","No stream provided.\nStop"); exit(1);}
TString buffs;
Clear();
}
//_______________________________________________
-void AliCheb3D::SetDimOut(int d)
+void AliCheb3D::SetDimOut(const int d)
{
+ // init output dimensions
fDimOut = d;
if (fResTmp) delete fResTmp;
fResTmp = new Float_t[fDimOut];
//_______________________________________________
void AliCheb3D::ShiftBound(int id,float dif)
{
+ // modify the bounds of the grid
+ //
if (id<0||id>2) {printf("Maximum 3 dimensions are supported\n"); return;}
fBMin[id] += dif;
fBMax[id] += dif;
#ifdef _INC_CREATION_ALICHEB3D_
void AliCheb3D::EstimateNPoints(float Prec, int gridBC[3][3])
{
+ // Estimate number of points to generate a training data
+ //
const float sclA[9] = {0.1, 0.5, 0.9, 0.1, 0.5, 0.9, 0.1, 0.5, 0.9} ;
const float sclB[9] = {0.1, 0.1, 0.1, 0.5, 0.5, 0.5, 0.9, 0.9, 0.9} ;
const float sclDim[2] = {0.01,0.99};
////////////////////////////////////////////////////////////////////////////////
-#ifndef _ALICHEB3D_
-#define _ALICHEB3D_
-#include <stdio.h>
+#ifndef ALICHEB3D_H
+#define ALICHEB3D_H
+
#include <TNamed.h>
-#include <TMethodCall.h>
-#include <TMath.h>
-#include <TH1.h>
#include <TObjArray.h>
#include "AliCheb3DCalc.h"
class TString;
class TSystem;
class TRandom;
+class TH1;
+class TMethodCall;
+class TRandom;
+class TROOT;
+class stdio;
+
class AliCheb3D: public TNamed
~AliCheb3D() {Clear();}
//
AliCheb3D& operator=(const AliCheb3D& rhs);
- void Eval(Float_t *par,Float_t *res);
- Float_t Eval(Float_t *par,int idim);
+ void Eval(const Float_t *par,Float_t *res);
+ Float_t Eval(const Float_t *par,int idim);
//
- void EvalDeriv(int dimd, Float_t *par,Float_t *res);
- void EvalDeriv2(int dimd1, int dimd2,Float_t *par,Float_t *res);
- Float_t EvalDeriv(int dimd,Float_t *par, int idim);
- Float_t EvalDeriv2(int dimd1,int dimd2, Float_t *par, int idim);
- void EvalDeriv3D(Float_t *par, Float_t dbdr[3][3]);
- void EvalDeriv3D2(Float_t *par, Float_t dbdrdr[3][3][3]);
- void Print(Option_t* opt="") const;
- Bool_t IsInside(Float_t *par) const;
- Bool_t IsInside(Double_t *par) const;
+ void EvalDeriv(int dimd, const Float_t *par, Float_t *res);
+ void EvalDeriv2(int dimd1, int dimd2, const Float_t *par,Float_t *res);
+ Float_t EvalDeriv(int dimd, const Float_t *par, int idim);
+ Float_t EvalDeriv2(int dimd1,int dimd2, const Float_t *par, int idim);
+ void EvalDeriv3D(const Float_t *par, Float_t dbdr[3][3]);
+ void EvalDeriv3D2(const Float_t *par, Float_t dbdrdr[3][3][3]);
+ void Print(const Option_t* opt="") const;
+ Bool_t IsInside(const Float_t *par) const;
+ Bool_t IsInside(const Double_t *par) const;
AliCheb3DCalc* GetChebCalc(int i) const {return (AliCheb3DCalc*)fChebCalc.UncheckedAt(i);}
Float_t GetBoundMin(int i) const {return fBMin[i];}
Float_t GetBoundMax(int i) const {return fBMax[i];}
//
void SetUsrFunction(const char* name);
void SetUsrFunction(void (*ptr)(float*,float*));
- void EvalUsrFunction(Float_t *x, Float_t *res);
+ void EvalUsrFunction(const Float_t *x, const Float_t *res);
TH1* TestRMS(int idim,int npoints = 1000,TH1* histo=0);
- static Int_t CalcChebCoefs(Float_t *funval,int np, Float_t *outCoefs, Float_t prec=-1);
+ static Int_t CalcChebCoefs(const Float_t *funval,int np, Float_t *outCoefs, Float_t prec=-1);
#endif
//
protected:
- void Clear(Option_t* option = "");
- void SetDimOut(int d);
- void PrepareBoundaries(Float_t *bmin,Float_t *bmax);
+ void Clear(const Option_t* option = "");
+ void SetDimOut(const int d);
+ void PrepareBoundaries(const Float_t *bmin,const Float_t *bmax);
//
#ifdef _INC_CREATION_ALICHEB3D_
void EvalUsrFunction();
};
//__________________________________________________________________________________________
-inline Bool_t AliCheb3D::IsInside(Float_t *par) const
+inline Bool_t AliCheb3D::IsInside(const Float_t *par) const
{
// check if the point is inside of the fitted box
const float kTol = 1.e-4;
}
//__________________________________________________________________________________________
-inline Bool_t AliCheb3D::IsInside(Double_t *par) const
+inline Bool_t AliCheb3D::IsInside(const Double_t *par) const
{
// check if the point is inside of the fitted box
const float kTol = 1.e-4;
}
//__________________________________________________________________________________________
-inline void AliCheb3D::Eval(Float_t *par, Float_t *res)
+inline void AliCheb3D::Eval(const Float_t *par, Float_t *res)
{
// evaluate Chebyshev parameterization for 3d->DimOut function
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
}
//__________________________________________________________________________________________
-inline Float_t AliCheb3D::Eval(Float_t *par, int idim)
+inline Float_t AliCheb3D::Eval(const Float_t *par, int idim)
{
// evaluate Chebyshev parameterization for idim-th output dimension of 3d->DimOut function
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
}
//__________________________________________________________________________________________
-inline void AliCheb3D::EvalDeriv3D(Float_t *par, Float_t dbdr[3][3])
+inline void AliCheb3D::EvalDeriv3D(const Float_t *par, Float_t dbdr[3][3])
{
// return gradient matrix
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
}
//__________________________________________________________________________________________
-inline void AliCheb3D::EvalDeriv3D2(Float_t *par, Float_t dbdrdr[3][3][3])
+inline void AliCheb3D::EvalDeriv3D2(const Float_t *par, Float_t dbdrdr[3][3][3])
{
// return gradient matrix
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
}
//__________________________________________________________________________________________
-inline void AliCheb3D::EvalDeriv(int dimd,Float_t *par, Float_t *res)
+inline void AliCheb3D::EvalDeriv(int dimd, const Float_t *par, Float_t *res)
{
// evaluate Chebyshev parameterization derivative for 3d->DimOut function
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
}
//__________________________________________________________________________________________
-inline void AliCheb3D::EvalDeriv2(int dimd1,int dimd2,Float_t *par, Float_t *res)
+inline void AliCheb3D::EvalDeriv2(int dimd1,int dimd2, const Float_t *par, Float_t *res)
{
// evaluate Chebyshev parameterization 2nd derivative over dimd1 and dimd2 dimensions for 3d->DimOut function
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
}
//__________________________________________________________________________________________
-inline Float_t AliCheb3D::EvalDeriv(int dimd,Float_t *par, int idim)
+inline Float_t AliCheb3D::EvalDeriv(int dimd, const Float_t *par, int idim)
{
// evaluate Chebyshev parameterization derivative over dimd dimention for idim-th output dimension of 3d->DimOut function
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
}
//__________________________________________________________________________________________
-inline Float_t AliCheb3D::EvalDeriv2(int dimd1,int dimd2,Float_t *par, int idim)
+inline Float_t AliCheb3D::EvalDeriv2(int dimd1,int dimd2, const Float_t *par, int idim)
{
// evaluate Chebyshev parameterization 2ns derivative over dimd1 and dimd2 dimensions for idim-th output dimension of 3d->DimOut function
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
* provided "as is" without express or implied warranty. *
**************************************************************************/
-
-// Author: ruben.shahoyan@cern.ch 09/09/2006
-//
#include <cstdlib>
#include "AliCheb3DCalc.h"
+#include <TSystem.h>
ClassImp(AliCheb3DCalc)
fCoefs(0),
fTmpCf1(0),
fTmpCf0(0)
-{}
+{
+ // default constructor
+}
//__________________________________________________________________________________________
AliCheb3DCalc::AliCheb3DCalc(const AliCheb3DCalc& src) :
fTmpCf1(0),
fTmpCf0(0)
{
+ // copy constructor
+ //
if (src.fNColsAtRow) {
fNColsAtRow = new Int_t[fNRows];
for (int i=fNRows;i--;) fNColsAtRow[i] = src.fNColsAtRow[i];
fTmpCf1(0),
fTmpCf0(0)
{
+ // constructor from coeffs. streem
LoadData(stream);
}
//__________________________________________________________________________________________
AliCheb3DCalc& AliCheb3DCalc::operator=(const AliCheb3DCalc& rhs)
{
+ // assignment operator
if (this != &rhs) {
Clear();
SetName(rhs.GetName());
}
//__________________________________________________________________________________________
-void AliCheb3DCalc::Clear(Option_t*)
+void AliCheb3DCalc::Clear(const Option_t*)
{
// delete all dynamycally allocated structures
if (fTmpCf1) { delete[] fTmpCf1; fTmpCf1 = 0;}
}
//__________________________________________________________________________________________
-void AliCheb3DCalc::Print(Option_t* ) const
+void AliCheb3DCalc::Print(const Option_t* ) const
{
+ // print info
printf("Chebyshev parameterization data %s for 3D->1 function.\n",GetName());
int nmax3d = 0;
for (int i=fNElemBound2D;i--;) if (fCoefBound2D0[i]>nmax3d) nmax3d = fCoefBound2D0[i];
}
//__________________________________________________________________________________________
-Float_t AliCheb3DCalc::Eval(Float_t *par) const
+Float_t AliCheb3DCalc::Eval(const Float_t *par) const
{
// evaluate Chebyshev parameterization for 3D function.
// VERY IMPORTANT: par must contain the function arguments ALREADY MAPPED to [-1:1] interval
- Float_t &z = par[2];
- Float_t &y = par[1];
- Float_t &x = par[0];
+ const Float_t &z = par[2];
+ const Float_t &y = par[1];
+ const Float_t &x = par[0];
//
int ncfRC;
for (int id0=fNRows;id0--;) {
int nCLoc = fNColsAtRow[id0]; // number of significant coefs on this row
- int Col0 = fColAtRowBg[id0]; // beginning of local column in the 2D boundary matrix
+ int col0 = fColAtRowBg[id0]; // beginning of local column in the 2D boundary matrix
for (int id1=nCLoc;id1--;) {
- int id = id1+Col0;
+ int id = id1+col0;
fTmpCf1[id1] = (ncfRC=fCoefBound2D0[id]) ? ChebEval1D(z,fCoefs + fCoefBound2D1[id], ncfRC) : 0.0;
}
fTmpCf0[id0] = nCLoc>0 ? ChebEval1D(y,fTmpCf1,nCLoc):0.0;
}
//__________________________________________________________________________________________
-Float_t AliCheb3DCalc::EvalDeriv(int dim, Float_t *par) const
+Float_t AliCheb3DCalc::EvalDeriv(int dim, const Float_t *par) const
{
// evaluate Chebyshev parameterization derivative in given dimension for 3D function.
// VERY IMPORTANT: par must contain the function arguments ALREADY MAPPED to [-1:1] interval
- Float_t &z = par[2];
- Float_t &y = par[1];
- Float_t &x = par[0];
+ const Float_t &z = par[2];
+ const Float_t &y = par[1];
+ const Float_t &x = par[0];
//
int ncfRC;
for (int id0=fNRows;id0--;) {
int nCLoc = fNColsAtRow[id0]; // number of significant coefs on this row
if (!nCLoc) {fTmpCf0[id0]=0; continue;}
//
- int Col0 = fColAtRowBg[id0]; // beginning of local column in the 2D boundary matrix
+ int col0 = fColAtRowBg[id0]; // beginning of local column in the 2D boundary matrix
for (int id1=nCLoc;id1--;) {
- int id = id1+Col0;
+ int id = id1+col0;
if (!(ncfRC=fCoefBound2D0[id])) { fTmpCf1[id1]=0; continue;}
if (dim==2) fTmpCf1[id1] = ChebEval1Deriv(z,fCoefs + fCoefBound2D1[id], ncfRC);
else fTmpCf1[id1] = ChebEval1D(z,fCoefs + fCoefBound2D1[id], ncfRC);
}
//__________________________________________________________________________________________
-Float_t AliCheb3DCalc::EvalDeriv2(int dim1,int dim2, Float_t *par) const
+Float_t AliCheb3DCalc::EvalDeriv2(int dim1,int dim2, const Float_t *par) const
{
// evaluate Chebyshev parameterization 2n derivative in given dimensions for 3D function.
// VERY IMPORTANT: par must contain the function arguments ALREADY MAPPED to [-1:1] interval
- Float_t &z = par[2];
- Float_t &y = par[1];
- Float_t &x = par[0];
+ const Float_t &z = par[2];
+ const Float_t &y = par[1];
+ const Float_t &x = par[0];
//
Bool_t same = dim1==dim2;
int ncfRC;
int nCLoc = fNColsAtRow[id0]; // number of significant coefs on this row
if (!nCLoc) {fTmpCf0[id0]=0; continue;}
//
- int Col0 = fColAtRowBg[id0]; // beginning of local column in the 2D boundary matrix
+ int col0 = fColAtRowBg[id0]; // beginning of local column in the 2D boundary matrix
for (int id1=nCLoc;id1--;) {
- int id = id1+Col0;
+ int id = id1+col0;
if (!(ncfRC=fCoefBound2D0[id])) { fTmpCf1[id1]=0; continue;}
if (dim1==2||dim2==2) fTmpCf1[id1] = same ? ChebEval1Deriv2(z,fCoefs + fCoefBound2D1[id], ncfRC)
: ChebEval1Deriv(z,fCoefs + fCoefBound2D1[id], ncfRC);
/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
* See cxx source for full Copyright notice */
#include <TNamed.h>
-#include <TSystem.h>
+class TSystem;
//
// Author: Ruben Shahoyan
// ruben.shahoyan@cern.ch 09/09/2006
~AliCheb3DCalc() {Clear();}
//
AliCheb3DCalc& operator=(const AliCheb3DCalc& rhs);
- void Print(Option_t* opt="") const;
+ void Print(const Option_t* opt="") const;
void LoadData(FILE* stream);
- Float_t Eval(Float_t *par) const;
- Float_t EvalDeriv(int dim, Float_t *par) const;
- Float_t EvalDeriv2(int dim1,int dim2, Float_t *par) const;
+ Float_t Eval(const Float_t *par) const;
+ Float_t EvalDeriv(int dim, const Float_t *par) const;
+ Float_t EvalDeriv2(int dim1,int dim2, const Float_t *par) const;
//
#ifdef _INC_CREATION_ALICHEB3D_
- void SaveData(const char* outfile,Bool_t append=kFALSE) const;
- void SaveData(FILE* stream=stdout) const;
+ void SaveData(const char* outfile,Bool_t append=kFALSE) const;
+ void SaveData(FILE* stream=stdout) const;
#endif
//
void InitRows(int nr);
void InitElemBound2D(int ne);
Int_t* GetCoefBound2D0() const {return fCoefBound2D0;}
Int_t* GetCoefBound2D1() const {return fCoefBound2D1;}
- void Clear(Option_t* option = "");
+ void Clear(const Option_t* option = "");
static Float_t ChebEval1D(Float_t x, const Float_t * array, int ncf);
static Float_t ChebEval1Deriv(Float_t x, const Float_t * array, int ncf);
static Float_t ChebEval1Deriv2(Float_t x, const Float_t * array, int ncf);
-///////////////////////////////////////////////////////////////////////////////////
-// //
-// Wrapper for the set of mag.field parameterizations by Chebyshev polinomials //
-// To obtain the field in cartesian coordinates/components use //
-// Field(float* xyz, float* bxyz); //
-// For cylindrical coordinates/components: //
-// FieldCyl(float* rphiz, float* brphiz) //
-// //
-// The solenoid part is parameterized in the volume R<500, -550<Z<550 cm //
-// //
-// The region R<423 cm, -343.3<Z<481.3 for 30kA and -343.3<Z<481.3 for 12kA //
-// is parameterized using measured data while outside the Tosca calculation //
-// is used (matched to data on the boundary of the measurements) //
-// //
-// Two options are possible: //
-// 1) _BRING_TO_BOUNDARY_ is defined in the AliCheb3D: //
-// If the querried point is outside of the validity region then the field //
-// at the closest point on the fitted surface is returned. //
-// 2) _BRING_TO_BOUNDARY_ is not defined in the AliCheb3D: //
-// If the querried point is outside of the validity region the return //
-// value for the field components are set to 0. //
-// //
-// To obtain the field integral in the TPC region from given point to nearest //
-// cathod plane (+- 250 cm) use: //
-// GetTPCInt(float* xyz, float* bxyz); for Cartesian frame //
-// or //
-// GetTPCIntCyl(Float_t *rphiz, Float_t *b); for Cylindrical frame //
-// //
-// //
-// The units are kiloGauss and cm. //
-// //
-///////////////////////////////////////////////////////////////////////////////////
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
#include "AliMagFCheb.h"
+#include <TSystem.h>
ClassImp(AliMagFCheb)
fParamsDip(0),
fParamsTPCInt(0)
//
-{}
+{
+ // default constructor
+}
//__________________________________________________________________________________________
AliMagFCheb::AliMagFCheb(const AliMagFCheb& src) :
fParamsDip(0),
fParamsTPCInt(0)
{
+ // copy constructor
CopyFrom(src);
- //
}
//__________________________________________________________________________________________
void AliMagFCheb::CopyFrom(const AliMagFCheb& src)
{
+ // copy method
Clear();
SetName(src.GetName());
SetTitle(src.GetTitle());
//__________________________________________________________________________________________
AliMagFCheb& AliMagFCheb::operator=(const AliMagFCheb& rhs)
{
+ // assignment
if (this != &rhs) {
Clear();
CopyFrom(rhs);
}
//__________________________________________________________________________________________
-void AliMagFCheb::Clear(Option_t *)
+void AliMagFCheb::Clear(const Option_t *)
{
+ // clear all dynamic parts
if (fNParamsSol) {
delete fParamsSol;
delete[] fSegZSol;
}
//__________________________________________________________________________________________
-void AliMagFCheb::FieldCylSol(Float_t *rphiz, Float_t *b) const
+void AliMagFCheb::FieldCylSol(const Float_t *rphiz, Float_t *b) const
{
// compute Solenoid field in Cylindircal coordinates
// note: if the point is outside the volume get the field in closest parameterized point
- float &r = rphiz[0];
- float &z = rphiz[2];
+ const float &r = rphiz[0];
+ const float &z = rphiz[2];
int SolZId = 0;
while (z>fSegZSol[SolZId] && SolZId<fNSegZSol-1) ++SolZId; // find Z segment
int SolRId = fSegZIdSol[SolZId]; // first R segment for this Z
{
// compute field integral in TPC region in Cylindircal coordinates
// note: the check for the point being inside the parameterized region is done outside
- float &r = rphiz[0];
- float &z = rphiz[2];
- int TPCIntZId = 0;
- while (z>fSegZTPCInt[TPCIntZId] && TPCIntZId<fNSegZTPCInt) ++TPCIntZId; // find Z segment
- int TPCIntRId = fSegZIdTPCInt[TPCIntZId]; // first R segment for this Z
- int TPCIntRIdMax = TPCIntRId + fNSegRTPCInt[TPCIntZId];
- while (r>fSegRTPCInt[TPCIntRId] && TPCIntRId<TPCIntRIdMax) ++TPCIntRId; // find R segment
- GetParamTPCInt( TPCIntRId )->Eval(rphiz,b);
+ const float &r = rphiz[0];
+ const float &z = rphiz[2];
+ int tpcIntZId = 0;
+ while (z>fSegZTPCInt[tpcIntZId] && tpcIntZId<fNSegZTPCInt) ++tpcIntZId; // find Z segment
+ int tpcIntRId = fSegZIdTPCInt[tpcIntZId]; // first R segment for this Z
+ int tpcIntRIdMax = tpcIntRId + fNSegRTPCInt[tpcIntZId];
+ while (r>fSegRTPCInt[tpcIntRId] && tpcIntRId<tpcIntRIdMax) ++tpcIntRId; // find R segment
+ GetParamTPCInt( tpcIntRId )->Eval(rphiz,b);
//
}
//__________________________________________________________________________________________
void AliMagFCheb::Print(Option_t *) const
{
+ // print info
printf("Alice magnetic field parameterized by Chebyshev polynomials\n");
printf("Segmentation for Solenoid (%+.2f<Z<%+.2f cm | R<%.2f cm)\n",fMinZSol,fMaxZSol,fMaxRSol);
//
#endif
//_________________________________________________________________________
-Int_t AliMagFCheb::FindDipSegment(float *xyz) const
+Int_t AliMagFCheb::FindDipSegment(const float *xyz) const
{
// find the segment containing point xyz. If it is outside find the closest segment
int xid,yid,zid = TMath::BinarySearch(fNZSegDip,fSegZDip,xyz[2]); // find zsegment
//
//
{
+ // construct from coeffs from the text file
LoadData(inputFile);
}
//__________________________________________________________________________________________
-void AliMagFCheb::AddParamSol(AliCheb3D* param)
+void AliMagFCheb::AddParamSol(const AliCheb3D* param)
{
// adds new parameterization piece for Sol
// NOTE: pieces must be added strictly in increasing R then increasing Z order
}
//__________________________________________________________________________________________
-void AliMagFCheb::AddParamTPCInt(AliCheb3D* param)
+void AliMagFCheb::AddParamTPCInt(const AliCheb3D* param)
{
// adds new parameterization piece for TPCInt
// NOTE: pieces must be added strictly in increasing R then increasing Z order
}
//__________________________________________________________________________________________
-void AliMagFCheb::AddParamDip(AliCheb3D* param)
+void AliMagFCheb::AddParamDip(const AliCheb3D* param)
{
// adds new parameterization piece for Dipole
//
//__________________________________________________
void AliMagFCheb::BuildTableDip()
{
+ // build lookup table for dipole
//
TArrayF segY,segX;
TArrayI begSegYDip,begSegXDip;
// is parameterized using measured data while outside the Tosca calculation //
// is used (matched to data on the boundary of the measurements) //
// //
-// If the querried point is outside the validity region no the return values //
-// for the field components are set to 0. //
+// Two options are possible: //
+// 1) _BRING_TO_BOUNDARY_ is defined in the AliCheb3D: //
+// If the querried point is outside of the validity region then the field //
+// at the closest point on the fitted surface is returned. //
+// 2) _BRING_TO_BOUNDARY_ is not defined in the AliCheb3D: //
+// If the querried point is outside of the validity region the return //
+// value for the field components are set to 0. //
// //
// To obtain the field integral in the TPC region from given point to nearest //
// cathod plane (+- 250 cm) use: //
// The units are kiloGauss and cm. //
// //
///////////////////////////////////////////////////////////////////////////////////
-#ifndef _ALIMAGFCHEB_
-#define _ALIMAGFCHEB_
+#ifndef ALIMAGFCHEB_H
+#define ALIMAGFCHEB_H
+
+#include <TMath.h>
#include <TNamed.h>
-#include <TSystem.h>
#include "AliCheb3D.h"
+class TSystem;
+
class AliMagFCheb: public TNamed
{
public:
//
void CopyFrom(const AliMagFCheb& src);
AliMagFCheb& operator=(const AliMagFCheb& rhs);
- virtual void Clear(Option_t * = "");
+ virtual void Clear(const Option_t * = "");
//
Int_t GetNParamsSol() const {return fNParamsSol;}
Int_t GetNSegZSol() const {return fNSegZSol;}
+ float* GetSegZSol() const {return fSegZSol;}
//
Int_t GetNParamsTPCInt() const {return fNParamsTPCInt;}
Int_t GetNSegZTPCInt() const {return fNSegZTPCInt;}
Float_t GetMaxZTPCInt() const {return fMaxZTPCInt;}
Float_t GetMaxRTPCInt() const {return fMaxRTPCInt;}
//
- Int_t FindDipSegment(float *xyz) const;
+ Int_t FindDipSegment(const float *xyz) const;
AliCheb3D* GetParamSol(Int_t ipar) const {return (AliCheb3D*)fParamsSol->UncheckedAt(ipar);}
AliCheb3D* GetParamTPCInt(Int_t ipar) const {return (AliCheb3D*)fParamsTPCInt->UncheckedAt(ipar);}
AliCheb3D* GetParamDip(Int_t ipar) const {return (AliCheb3D*)fParamsDip->UncheckedAt(ipar);}
virtual void Print(Option_t * = "") const;
//
virtual void Field(Float_t *xyz, Float_t *b) const;
- virtual void FieldCyl(Float_t *rphiz, Float_t *b) const;
+ virtual void FieldCyl(const Float_t *rphiz, Float_t *b) const;
//
virtual void GetTPCInt(Float_t *xyz, Float_t *b) const;
virtual void GetTPCIntCyl(Float_t *rphiz, Float_t *b) const;
//
- static void CylToCartCylB(float *rphiz, float *brphiz,float *bxyz);
- static void CylToCartCartB(float *xyz, float *brphiz,float *bxyz);
- static void CartToCylCartB(float *xyz, float *bxyz, float *brphiz);
- static void CartToCylCylB(float *rphiz, float *bxyz, float *brphiz);
- static void CartToCyl(float *xyz, float *rphiz);
- static void CylToCart(float *rphiz,float *xyz);
+ static void CylToCartCylB(const float *rphiz, const float *brphiz,float *bxyz);
+ static void CylToCartCartB(const float *xyz, const float *brphiz,float *bxyz);
+ static void CartToCylCartB(const float *xyz, const float *bxyz, float *brphiz);
+ static void CartToCylCylB(const float *rphiz, const float *bxyz, float *brphiz);
+ static void CartToCyl(const float *xyz, float *rphiz);
+ static void CylToCart(const float *rphiz,float *xyz);
//
#ifdef _INC_CREATION_ALICHEB3D_ // see AliCheb3D.h for explanation
void LoadData(const char* inpfile);
Int_t SegmentDipDimension(float** seg,const TObjArray* par,int npar, int dim,
float xmn,float xmx,float ymn,float ymx,float zmn,float zmx);
//
- void AddParamSol(AliCheb3D* param);
- void AddParamTPCInt(AliCheb3D* param);
- void AddParamDip(AliCheb3D* param);
+ void AddParamSol(const AliCheb3D* param);
+ void AddParamTPCInt(const AliCheb3D* param);
+ void AddParamDip(const AliCheb3D* param);
void BuildTableDip();
void BuildTableSol();
void BuildTableTPCInt();
#endif
//
protected:
- virtual void FieldCylSol(Float_t *rphiz, Float_t *b) const;
+ virtual void FieldCylSol(const Float_t *rphiz, Float_t *b) const;
//
protected:
//
//__________________________________________________________________________________________
-inline void AliMagFCheb::FieldCyl(Float_t *rphiz, Float_t *b) const
+inline void AliMagFCheb::FieldCyl(const Float_t *rphiz, Float_t *b) const
{
// compute field in Cylindircal coordinates
// if (rphiz[2]<GetMinZSol() || rphiz[2]>GetMaxZSol() || rphiz[0]>GetMaxRSol()) {for (int i=3;i--;) b[i]=0; return;}
}
//__________________________________________________________________________________________________
-inline void AliMagFCheb::CylToCartCylB(float *rphiz, float *brphiz,float *bxyz)
+inline void AliMagFCheb::CylToCartCylB(const float *rphiz, const float *brphiz,float *bxyz)
{
// convert field in cylindrical coordinates to cartesian system, point is in cyl.system
float btr = TMath::Sqrt(brphiz[0]*brphiz[0]+brphiz[1]*brphiz[1]);
}
//__________________________________________________________________________________________________
-inline void AliMagFCheb::CylToCartCartB(float *xyz, float *brphiz,float *bxyz)
+inline void AliMagFCheb::CylToCartCartB(const float *xyz, const float *brphiz,float *bxyz)
{
// convert field in cylindrical coordinates to cartesian system, point is in cart.system
float btr = TMath::Sqrt(brphiz[0]*brphiz[0]+brphiz[1]*brphiz[1]);
}
//__________________________________________________________________________________________________
-inline void AliMagFCheb::CartToCylCartB(float *xyz ,float *bxyz, float *brphiz)
+inline void AliMagFCheb::CartToCylCartB(const float *xyz, const float *bxyz, float *brphiz)
{
// convert field in cylindrical coordinates to cartesian system, poin is in cart.system
float btr = TMath::Sqrt(bxyz[0]*bxyz[0]+bxyz[1]*bxyz[1]);
}
//__________________________________________________________________________________________________
-inline void AliMagFCheb::CartToCylCylB(float *rphiz,float *bxyz, float *brphiz)
+inline void AliMagFCheb::CartToCylCylB(const float *rphiz, const float *bxyz, float *brphiz)
{
// convert field in cylindrical coordinates to cartesian system, point is in cyl.system
float btr = TMath::Sqrt(bxyz[0]*bxyz[0]+bxyz[1]*bxyz[1]);
}
//__________________________________________________________________________________________________
-inline void AliMagFCheb::CartToCyl(float *xyz,float *rphiz)
+inline void AliMagFCheb::CartToCyl(const float *xyz,float *rphiz)
{
rphiz[0] = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
rphiz[1] = TMath::ATan2(xyz[1],xyz[0]);
}
//__________________________________________________________________________________________________
-inline void AliMagFCheb::CylToCart(float *rphiz,float *xyz)
+inline void AliMagFCheb::CylToCart(const float *rphiz, float *xyz)
{
xyz[0] = rphiz[0]*TMath::Cos(rphiz[1]);
xyz[1] = rphiz[0]*TMath::Sin(rphiz[1]);
AliMagWrapCheb& operator=(const AliMagWrapCheb& maps);
virtual ~AliMagWrapCheb();
//
- virtual void Field(Float_t *x, Float_t *b) const;
- virtual void GetTPCInt(Float_t *xyz, Float_t *b) const;
- virtual void GetTPCIntCyl(Float_t *rphiz, Float_t *b) const;
+ virtual void Field(Float_t *x, Float_t *b) const;
+ virtual void GetTPCInt(Float_t *xyz, Float_t *b) const;
+ virtual void GetTPCIntCyl(Float_t *rphiz, Float_t *b) const;
//
- AliMagFCheb* GetMeasuredMap() const {return fMeasuredMap;}
- void SetMeasuredMap(AliMagFCheb* parm) {if (parm) delete parm; fMeasuredMap = parm;}
- virtual Float_t SolenoidField() const {return -Factor()*fSolenoid;}
+ AliMagFCheb* GetMeasuredMap() const {return fMeasuredMap;}
+ void SetMeasuredMap(AliMagFCheb* parm) {if (fMeasuredMap) delete fMeasuredMap; fMeasuredMap = parm;}
+ virtual Float_t SolenoidField() const {return -Factor()*fSolenoid;}
//
protected:
AliMagFCheb* fMeasuredMap; // Measured part of the field map