Fast transformation of TPC clusters with 3-rd order splines
authorsgorbuno <sgorbuno@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 10 Jun 2012 18:35:17 +0000 (18:35 +0000)
committersgorbuno <sgorbuno@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 10 Jun 2012 18:35:17 +0000 (18:35 +0000)
HLT/CMakelibAliHLTTPC.pkg
HLT/TPCLib/AliHLTTPCClusterTransformation.cxx
HLT/TPCLib/transform/AliHLTTPCFastTransform.cxx [new file with mode: 0644]
HLT/TPCLib/transform/AliHLTTPCFastTransform.h [new file with mode: 0644]
HLT/TPCLib/transform/AliHLTTPCSpline2D3D.cxx [new file with mode: 0644]
HLT/TPCLib/transform/AliHLTTPCSpline2D3D.h [new file with mode: 0644]

index b7b9115..662b1f9 100644 (file)
@@ -29,6 +29,8 @@
 
 set ( CLASS_HDRS
     AliHLTTPCTransform.h
+    transform/AliHLTTPCSpline2D3D.h
+    transform/AliHLTTPCFastTransform.h
     AliHLTTPCClusterTransformation.h
     AliHLTTPCAgent.h
     AliHLTTPCMemHandler.h
@@ -134,7 +136,7 @@ set ( MODULE_HDRS
 
 set ( MODULE_DHDR )
 
-set ( EINCLUDE  HLT/TPCLib HLT/TPCLib/tracking HLT/TPCLib/comp HLT/TPCLib/tracking-ca HLT/TPCLib/merger-ca HLT/TPCLib/offline HLT/TPCLib/HWCFemulator HLT/BASE HLT/BASE/util HLT/RCU TPC RAW STEER/STEER STEER/ESD STEER/STEERBase)
+set ( EINCLUDE  HLT/TPCLib HLT/TPCLib/tracking HLT/TPCLib/comp HLT/TPCLib/tracking-ca HLT/TPCLib/merger-ca HLT/TPCLib/offline HLT/TPCLib/HWCFemulator HLT/TPCLib/transform HLT/BASE HLT/BASE/util HLT/RCU TPC RAW STEER/STEER STEER/ESD STEER/STEERBase)
 set ( ELIBS  dl)
 
 set ( ELIBS  "HLTbase AliHLTRCU AliHLTUtil CDB ESD STEER STEERBase TPCrec TPCcalib TPCbase RAWDatarec RAWDatabase -lEG")
index 3002fea..71820ad 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "AliHLTTPCClusterTransformation.h"
 #include "AliHLTTPCTransform.h"
+#include "AliHLTTPCFastTransform.h"
 
 #include "AliTPCcalibDB.h"
 #include "AliTPCTransform.h"
@@ -40,7 +41,6 @@ ClassImp(AliHLTTPCClusterTransformation) //ROOT macro for the implementation of
 
 AliHLTTPCClusterTransformation::AliHLTTPCClusterTransformation()
 :
-  fOfflineTransform(NULL),
   fOfflineTPCParam( NULL ),
   fLastSector(-1)
 {
@@ -57,7 +57,7 @@ AliHLTTPCClusterTransformation::AliHLTTPCClusterTransformation()
 AliHLTTPCClusterTransformation::~AliHLTTPCClusterTransformation() 
 { 
   // see header file for class documentation
-  //delete fOfflineTransform;
+  AliHLTTPCFastTransform::Terminate();
 }
 
 
@@ -65,8 +65,6 @@ int  AliHLTTPCClusterTransformation::Init( double FieldBz, UInt_t TimeStamp )
 {
   // Initialisation
 
-  //delete fOfflineTransform;
-  fOfflineTransform = 0;
   fOfflineTPCParam = 0;
 
   AliTPCcalibDB* pCalib=AliTPCcalibDB::Instance();
@@ -81,10 +79,6 @@ int  AliHLTTPCClusterTransformation::Init( double FieldBz, UInt_t TimeStamp )
 
   if( !pCalib->GetTransform() ) return -2; 
 
-  //fOfflineTransform = new AliTPCTransform (*pCalib->GetTransform());
-  fOfflineTransform = pCalib->GetTransform();
-  fOfflineTransform->SetCurrentRecoParam( AliTPCRecoParam::GetHLTParam() );
-  fOfflineTransform->SetCurrentTimeStamp( TimeStamp );
   fOfflineTPCParam = pCalib->GetParameters(); 
   if( !fOfflineTPCParam ) return -3;
 
@@ -97,7 +91,7 @@ int  AliHLTTPCClusterTransformation::Init( double FieldBz, UInt_t TimeStamp )
   fAliT[1] = 0.;
   fAliT[2] = 0.;
   SetRotationMatrix();
-
+  SetCurrentTimeStamp( TimeStamp );
   return 0;
 }
 
@@ -105,7 +99,7 @@ int  AliHLTTPCClusterTransformation::Init( double FieldBz, UInt_t TimeStamp )
 void AliHLTTPCClusterTransformation::SetCurrentTimeStamp( UInt_t TimeStamp )
 {
   // Set the current time stamp
-  if( fOfflineTransform ) fOfflineTransform->SetCurrentTimeStamp( TimeStamp );
+  AliHLTTPCFastTransform::Instance()->SetCurrentTimeStamp( TimeStamp );
 }
 
 
@@ -113,19 +107,11 @@ int  AliHLTTPCClusterTransformation::Transform( int Slice, int Row, float Pad, f
 {
   // Convert row, pad, time to X Y Z
           
-  Int_t sector=-99, thisrow=-99;
+  Int_t sector=-99, thisrow=-99;  
   AliHLTTPCTransform::Slice2Sector( Slice, Row, sector, thisrow);
+  Double_t x[3] = {0,0,0}; 
+  AliHLTTPCFastTransform::Instance()->Transform(sector, thisrow, Pad, Time, x);
 
-  if( !fOfflineTransform ){               
-    AliHLTTPCTransform::Raw2Local( XYZ, sector, thisrow, Pad, Time); 
-    if(Slice>17) XYZ[1]= - XYZ[1];        
-    return 0;
-  }
-
-  Int_t iSector[1]= {sector};   
-  Double_t x[3] = { thisrow, Pad, Time }; 
-  fOfflineTransform->Transform(x,iSector,0,1);
-         
   if( sector!= fLastSector ){
     if( fOfflineTPCParam && sector<fOfflineTPCParam->GetNSector() ){
       TGeoHMatrix  *alignment = fOfflineTPCParam->GetClusterMatrix( sector );
diff --git a/HLT/TPCLib/transform/AliHLTTPCFastTransform.cxx b/HLT/TPCLib/transform/AliHLTTPCFastTransform.cxx
new file mode 100644 (file)
index 0000000..0f8d8e6
--- /dev/null
@@ -0,0 +1,197 @@
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project        *
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Primary Authors: Sergey Gorbunov <sergey.gorbunov@cern.ch>             *
+//*                  for The ALICE HLT Project.                            *
+//*                                                                        *
+//* 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.                  *
+//**************************************************************************
+
+/** @file   AliHLTTPCFastTransform.cxx
+    @author Sergey Gorbubnov
+    @date   
+    @brief 
+*/
+
+
+#include "AliHLTTPCFastTransform.h"
+#include "AliTPCTransform.h"
+#include "AliTPCParam.h"
+#include "AliTPCcalibDB.h"
+#include <iostream>
+#include <iomanip>
+
+using namespace std;
+
+ClassImp(AliHLTTPCFastTransform); //ROOT macro for the implementation of ROOT specific class methods
+
+AliHLTTPCFastTransform* AliHLTTPCFastTransform::fgInstance = 0;
+
+
+void AliHLTTPCFastTransform::Terminate()
+{
+  //
+  // Singleton implementation
+  // Deletes the instance of this class and sets the terminated flag, instances cannot be requested anymore
+  // This function can be called several times.
+  //
+  
+  if( fgInstance ){
+    delete fgInstance;
+    fgInstance = 0;
+  }
+}
+
+AliHLTTPCFastTransform::AliHLTTPCFastTransform()
+:
+  fOrigTransform(0),
+  fLastTimeStamp(-1),
+  fLastTimeBin(600),
+  fTimeBorder1(100),
+  fTimeBorder2(500)
+{
+  // see header file for class documentation
+  // or
+  // refer to README to build package
+  // or
+  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt    
+  for( Int_t i=0; i<72; i++)
+    for( Int_t j=0; j<100; j++ ) fRows[i][j] = 0;
+  Init();
+}
+
+AliHLTTPCFastTransform::~AliHLTTPCFastTransform() 
+{ 
+  // see header file for class documentation
+  for( Int_t i=0; i<72; i++)
+    for( Int_t j=0; j<100; j++ ) delete fRows[i][j]; 
+
+  if( fgInstance == this ) fgInstance = 0;
+}
+
+
+Int_t  AliHLTTPCFastTransform::Init( AliTPCTransform *transform, Int_t TimeStamp )
+{
+  // Initialisation
+
+  if( !transform ){
+    AliTPCcalibDB* pCalib=AliTPCcalibDB::Instance();  
+    if(!pCalib ) return 1;
+    transform = pCalib->GetTransform();
+  }
+
+  if( fOrigTransform != transform ){
+    fOrigTransform = transform;
+    fLastTimeStamp = -1;
+  }
+
+  SetCurrentTimeStamp( TimeStamp );
+  return 0;
+}
+
+
+void AliHLTTPCFastTransform::SetCurrentTimeStamp( Int_t TimeStamp )
+{
+  // Set the current time stamp
+  if( fLastTimeStamp>=0 && TMath::Abs(fLastTimeStamp - TimeStamp ) <60 ) return;
+
+  if( !fOrigTransform ) return;
+  
+  if( TimeStamp>=0 ){
+    fOrigTransform->SetCurrentTimeStamp( TimeStamp );
+    fLastTimeStamp = TimeStamp;
+  } else fLastTimeStamp = fOrigTransform->GetCurrentTimeStamp();
+
+
+  AliTPCcalibDB* pCalib=AliTPCcalibDB::Instance();  
+  if(!pCalib ) return ;   
+
+  AliTPCParam *par = pCalib->GetParameters(); 
+  if( !par ) return ;
+
+  // find last calibrated time bin
+  
+  Int_t nTimeBins = par->GetMaxTBin();
+  Int_t is[]={0};
+  bool sign = 0;
+  for( fLastTimeBin=0; fLastTimeBin<nTimeBins; fLastTimeBin++){  
+    Double_t xx[]={0,0,fLastTimeBin};
+    fOrigTransform->Transform(xx,is,0,1);
+    bool s = (xx[2]>=0);
+    if( fLastTimeBin==0 ) sign = s;
+    else if( sign!=s ){
+      fLastTimeBin--;
+      break;    
+    }
+  }
+  fTimeBorder1 = 60;
+  fTimeBorder2 = fLastTimeBin - 100;
+
+  for( Int_t i=0; i<72; i++ )
+    for( Int_t j=0; j<100; j++ ) if( fRows[i][j] ) InitRow(i,j);
+}
+
+Int_t AliHLTTPCFastTransform::InitRow( Int_t iSector, Int_t iRow )
+{
+  // see header file for class documentation
+  
+  if( iSector<0 || iSector>=72 || iRow<0 || iRow>=100 || !fOrigTransform) return 1;
+
+  AliTPCcalibDB* pCalib=AliTPCcalibDB::Instance();  
+  if(!pCalib ) return 1;   
+
+  AliTPCParam *par = pCalib->GetParameters(); 
+  if( !par ) return 1;
+
+  Int_t nPads = par->GetNPads(iSector,iRow);
+
+  if( !fRows[iSector][iRow] ){
+    fRows[iSector][iRow] = new AliHLTTPCFastTransform::AliRowTransform;
+  }
+
+  fRows[iSector][iRow]->fSpline[0].Init(         0.5, nPads-1+0.5, 15, 0,  fTimeBorder1,         5);
+  fRows[iSector][iRow]->fSpline[1].Init(         0.5, nPads-1+0.5, 15, fTimeBorder1, fTimeBorder2,         10);
+  fRows[iSector][iRow]->fSpline[2].Init(         0.5, nPads-1+0.5, 15, fTimeBorder2, fLastTimeBin,         5);
+
+  for( Int_t i=0; i<3; i++){    
+    Int_t is[]={iSector};
+    for( Int_t j=0; j<fRows[iSector][iRow]->fSpline[i].GetNPoints(); j++){
+      Float_t pad, time;
+      fRows[iSector][iRow]->fSpline[i].GetAB(j,pad,time);
+      Double_t xx[]={iRow,pad,time};
+      fOrigTransform->Transform(xx,is,0,1);
+      fRows[iSector][iRow]->fSpline[i].Fill(j,xx);    
+    }
+  }
+  return 0;
+}
+
+
+
+Int_t AliHLTTPCFastTransform::GetRowSize( Int_t iSec, Int_t iRow ) const 
+{ 
+  // see header file for class documentation
+  Int_t s = sizeof(AliHLTTPCFastTransform::AliRowTransform);
+  if( fRows[iSec][iRow] ) for( Int_t i=0; i<3; i++) s+=fRows[iSec][iRow]->fSpline[i].GetMapSize();
+  return s;
+}
+
+Int_t AliHLTTPCFastTransform::GetSize() const
+{ 
+  // see header file for class documentation
+  Int_t s = sizeof(AliHLTTPCFastTransform);
+  for( Int_t i=0; i<72; i++ )
+    for( Int_t j=0; j<100; j++ ) if( fRows[i][j] ){
+       s+= sizeof(AliHLTTPCFastTransform::AliRowTransform);
+       for( Int_t k=0; k<3; k++) fRows[i][j]->fSpline[i].GetMapSize();
+      }
+  return s;
+}
diff --git a/HLT/TPCLib/transform/AliHLTTPCFastTransform.h b/HLT/TPCLib/transform/AliHLTTPCFastTransform.h
new file mode 100644 (file)
index 0000000..45d9a58
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef ALIHLTTPCFASTTRANSFORM_H
+#define ALIHLTTPCFASTTRANSFORM_H
+
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+/** @file   AliHLTTPCFastTransform.h
+    @author Sergey Gorbunov
+    @date   
+    @brief
+*/
+
+// see below for class documentation
+// or
+// refer to README to build package
+// or
+// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+
+#include"Rtypes.h"
+#include"AliHLTTPCSpline2D3D.h"
+
+class AliTPCTransform;
+
+/**
+ * @class AliHLTTPCFastTransform
+ *
+ * The class transforms internal TPC coordinates (pad,time) to XYZ. 
+ * 
+ * @ingroup alihlt_tpc_components
+ */
+
+
+
+class AliHLTTPCFastTransform{
+    
+ public:
+
+  static AliHLTTPCFastTransform* Instance();
+  static void Terminate();
+
+  /** standard constructor */    
+  AliHLTTPCFastTransform();           
+  /** destructor */
+  virtual ~AliHLTTPCFastTransform();
+  
+  /** initialization */
+  Int_t  Init( AliTPCTransform *transform=0, Int_t TimeStamp=-1 );
+  
+  /** set the time stamp */
+  void SetCurrentTimeStamp( Int_t TimeStamp );
+
+  /** Transformation */
+  Int_t  Transform( Int_t Sector, Int_t Row, Float_t Pad, Float_t Time, Float_t XYZ[] );
+
+  /** Transformation in double*/
+  Int_t Transform( Int_t Sector, Int_t Row, Float_t Pad, Float_t Time, Double_t XYZ[] );
+
+  /** Initialisation of splines for a particular row */
+  Int_t InitRow( Int_t iSector, Int_t iRow );
+
+  /** total size of the object*/
+  Int_t GetSize() const ;
+  
+  /** size of a particular row*/
+  Int_t GetRowSize( Int_t iSec, Int_t iRow ) const;
+
+  /** last calibrated time bin */
+  Int_t GetLastTimeBin() const { return fLastTimeBin; }
+
+ private:
+
+  /** copy constructor prohibited */
+  AliHLTTPCFastTransform(const AliHLTTPCFastTransform&);
+  /** assignment operator prohibited */
+  AliHLTTPCFastTransform& operator=(const AliHLTTPCFastTransform&);
+
+  static AliHLTTPCFastTransform* fgInstance;  // singleton control
+
+  struct AliRowTransform{
+    AliHLTTPCSpline2D3D fSpline[3];
+  };
+
+  AliTPCTransform * fOrigTransform;                             //! transient
+  Int_t fLastTimeStamp; // last time stamp
+  Int_t fLastTimeBin; // last calibrated time bin
+  Float_t fTimeBorder1; //! transient
+  Float_t fTimeBorder2; //! transient
+
+  AliHLTTPCFastTransform::AliRowTransform *fRows[72][100]; //! transient
+
+  ClassDef(AliHLTTPCFastTransform,0)
+};
+
+inline Int_t AliHLTTPCFastTransform::Transform( Int_t iSec, Int_t iRow, Float_t Pad, Float_t Time, Float_t XYZ[] ){
+  if( !fOrigTransform || iSec<0 || iSec>=72 || iRow<0 || iRow>=100 ) return 1;
+  if( !fRows[iSec][iRow] && InitRow(iSec, iRow) ) return 1;
+  Int_t iTime = ( Time>=fTimeBorder2 ) ?2 :( ( Time>fTimeBorder1 ) ?1 :0 );
+  fRows[iSec][iRow]->fSpline[iTime].GetValue(Pad, Time, XYZ);              
+  return 0; 
+}
+
+inline Int_t  AliHLTTPCFastTransform::Transform( Int_t iSec, Int_t iRow, Float_t Pad, Float_t Time, Double_t XYZ[] ){
+  if( !fOrigTransform || iSec<0 || iSec>=72 || iRow<0 || iRow>=100 ) return 1;
+  if( !fRows[iSec][iRow] && InitRow(iSec, iRow) ) return 1;
+  Int_t iTime = ( Time>=fTimeBorder2 ) ?2 :( ( Time>fTimeBorder1 ) ?1 :0 );
+  fRows[iSec][iRow]->fSpline[iTime].GetValue(Pad, Time, XYZ);              
+  return 0; 
+}
+
+
+inline AliHLTTPCFastTransform* AliHLTTPCFastTransform::Instance(){ // Singleton implementation
+  if( !fgInstance ) fgInstance = new AliHLTTPCFastTransform();  
+  return fgInstance;
+}
+
+#endif
diff --git a/HLT/TPCLib/transform/AliHLTTPCSpline2D3D.cxx b/HLT/TPCLib/transform/AliHLTTPCSpline2D3D.cxx
new file mode 100644 (file)
index 0000000..6e8d6c3
--- /dev/null
@@ -0,0 +1,136 @@
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project        *
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Primary Authors: Sergey Gorbunov <sergey.gorbunov@cern.ch>             *
+//*                  for The ALICE HLT Project.                            *
+//*                                                                        *
+//* 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.                  *
+//**************************************************************************
+
+/** @file   AliHLTTPCSpline2D3D.cxx
+    @author Sergey Gorbubnov
+    @date   
+    @brief 
+*/
+
+
+#include "AliHLTTPCFastTransform.h"
+#include "AliTPCTransform.h"
+#include "AliTPCParam.h"
+#include "AliTPCcalibDB.h"
+#include <iostream>
+#include <iomanip>
+
+using namespace std;
+
+
+
+
+
+void AliHLTTPCSpline2D3D::Init(Float_t minA,Float_t  maxA, Int_t  nBinsA, Float_t  minB,Float_t  maxB, Int_t  nBinsB)
+{
+  //
+  // Initialisation
+  //
+
+  if( maxA<= minA ) maxA = minA+1;
+  if( maxB<= minB ) maxB = minB+1;
+  if( nBinsA <3 ) nBinsA = 3;
+  if( nBinsB <3 ) nBinsB = 3;
+
+  fNA = nBinsA;
+  fNB = nBinsB;
+  fN = fNA*fNB;
+  fMinA = minA;
+  fMinB = minB;
+
+  fStepA = (maxA-minA)/(nBinsA-1);
+  fStepB = (maxB-minB)/(nBinsB-1);
+  fScaleA = 1./fStepA;
+  fScaleB = 1./fStepB;
+
+  delete[] fX;
+  delete[] fY;
+  delete[] fZ;
+  fX = new Float_t [fN];
+  fY = new Float_t [fN];
+  fZ = new Float_t [fN];
+  memset ( fX, 0, fN*sizeof(Float_t) );
+  memset ( fY, 0, fN*sizeof(Float_t) );
+  memset ( fZ, 0, fN*sizeof(Float_t) );
+}
+
+void AliHLTTPCSpline2D3D::Fill(void (*func)(Float_t a, Float_t b, Float_t xyz[]) )
+{
+  //
+  // Filling
+  //
+
+  for( Int_t i=0; i<GetNPoints(); i++){
+    Float_t a, b, xyz[3];
+    GetAB(i,a,b);
+    (*func)(a,b,xyz);
+    Fill(i,xyz);
+  }
+}
+
+
+
+
+
+void AliHLTTPCSpline2D3D::GetValue(Float_t A, Float_t B, Float_t XYZ[] ) const
+{
+  //
+  //  Get Interpolated value at A,B 
+  //
+
+  Float_t lA = (A-fMinA)*fScaleA;
+  Int_t iA = ((int) lA)-1;
+  bool splineA3 = 0;
+  if( iA<0 ) iA=0;
+  else if( iA>fNA-4 ) iA = fNA-3;
+  else splineA3 = 1;
+
+  Float_t lB = (B-fMinB)*fScaleB;
+  Int_t iB = ((int) lB)-1;
+  bool splineB3 = 0;
+  if( iB<0 ) iB=0;
+  else if( iB>fNB-4 ) iB = fNB-3;
+  else splineB3 = 1;
+
+  Float_t da = lA-iA-1;
+  Float_t db = lB-iB-1;
+
+  
+  Float_t v[3][4];
+  Int_t ind = iA*fNB  + iB;
+  for( Int_t i=0; i<3+splineA3; i++ ){
+    if( splineB3 ){
+      v[0][i] = GetSpline3(fX+ind,db); 
+      v[1][i] = GetSpline3(fY+ind,db); 
+      v[2][i] = GetSpline3(fZ+ind,db); 
+    } else {
+      v[0][i] = GetSpline2(fX+ind,db); 
+      v[1][i] = GetSpline2(fY+ind,db); 
+      v[2][i] = GetSpline2(fZ+ind,db); 
+    }
+    ind+=fNB;
+  } 
+  if( splineA3 ){
+    XYZ[0] =  GetSpline3(v[0],da);
+    XYZ[1] =  GetSpline3(v[1],da);
+    XYZ[2] =  GetSpline3(v[2],da);
+  } else {
+    XYZ[0] =  GetSpline2(v[0],da);
+    XYZ[1] =  GetSpline2(v[1],da);
+    XYZ[2] =  GetSpline2(v[2],da);
+  }
+}
diff --git a/HLT/TPCLib/transform/AliHLTTPCSpline2D3D.h b/HLT/TPCLib/transform/AliHLTTPCSpline2D3D.h
new file mode 100644 (file)
index 0000000..d450802
--- /dev/null
@@ -0,0 +1,169 @@
+#ifndef ALIHLTTPCSPLINE2D3D_H
+#define ALIHLTTPCSPLINE2D3D_H
+
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+/** @file   AliHLTTPCSpline2D3D.h
+    @author Sergey Gorbunov
+    @date   
+    @brief
+*/
+
+// see below for class documentation
+// or
+// refer to README to build package
+// or
+// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+
+#include"Rtypes.h"
+
+class AliTPCParam;
+class AliTPCTransform;
+
+/**
+ * @class AliHLTTPCSpline2D3D
+ *
+ * The class presents spline interpolation for 2D->3D function (a,b)->(x,y,z)
+ * 
+ * @ingroup alihlt_tpc_components
+ */
+
+class AliHLTTPCSpline2D3D{
+ public:
+  /** standard constructor */    
+  AliHLTTPCSpline2D3D();           
+
+  /** constructor */    
+  AliHLTTPCSpline2D3D(Float_t minA, Float_t  maxA, Int_t  nBinsA, Float_t  minB, Float_t  maxB,  Int_t  nBinsB);
+
+  /** destructor */
+  ~AliHLTTPCSpline2D3D();
+  /** initialisation */
+  void Init(Float_t minA, Float_t  maxA, Int_t  nBinsA, Float_t  minB, Float_t  maxB,  Int_t  nBinsB);
+  
+  /**  Filling of points */
+  void Fill(void (*func)(Float_t a, Float_t b, Float_t xyz[] ) );
+  /**  Filling of points */
+  void Fill(Int_t ind, Float_t x, Float_t y, Float_t z);    
+  /**  Filling of points */
+  void Fill(Int_t ind, Float_t XYZ[]);    
+  /**  Filling of points */
+  void Fill(Int_t ind, Double_t  XYZ[]);    
+
+  /**  Get A,B by the point index */
+  void GetAB(Int_t ind, Float_t &A, Float_t &B) const ;
+  
+  /**  Get Interpolated value at A,B */
+  void GetValue(Float_t A, Float_t B, Float_t XYZ[]) const ;  
+  /**  Get Interpolated value at A,B */
+  void GetValue(Float_t A, Float_t B, Double_t XYZ[]) const ;  
+
+  /**  Get size of the grid */
+  Int_t  GetMapSize() const ;
+
+  /**  Get N of point on the grid */
+  Int_t GetNPoints() const ;
+
+ private:
+
+  /** copy constructor prohibited */
+  AliHLTTPCSpline2D3D(const AliHLTTPCSpline2D3D&);
+  /** assignment operator prohibited */
+  AliHLTTPCSpline2D3D& operator=(const AliHLTTPCSpline2D3D&);
+
+  /** spline 3-st order,  4 points, da = a - point 1 */
+  static  Float_t GetSpline3(Float_t *v, Float_t da);
+
+ /** spline 2-nd order, 3 points, da = a - point 1 */
+  static  Float_t GetSpline2(Float_t *v, Float_t da);
+
+  Int_t fNA; // N points A axis
+  Int_t fNB; // N points A axis
+  Int_t fN;  // N points total
+  Float_t fMinA; // min A axis
+  Float_t fMinB; // min B axis
+  Float_t fStepA; // step between points A axis
+  Float_t fStepB; // step between points B axis
+  Float_t fScaleA; // scale A axis
+  Float_t fScaleB; // scale B axis
+  Float_t *fX; // array of points, X values
+  Float_t *fY; // array of points, Y values
+  Float_t *fZ; // array of points, Z values
+};
+
+inline AliHLTTPCSpline2D3D::AliHLTTPCSpline2D3D()
+: fNA(0), fNB(0), fN(0), fMinA(0), fMinB(0), fStepA(0), fStepB(0), fScaleA(0), fScaleB(0), fX(0), fY(0),fZ(0)
+{
+}
+
+inline AliHLTTPCSpline2D3D::AliHLTTPCSpline2D3D(Float_t minA, Float_t  maxA, Int_t  nBinsA, Float_t  minB, Float_t  maxB,  Int_t  nBinsB)
+: fNA(0), fNB(0), fN(0), fMinA(0), fMinB(0), fStepA(0), fStepB(0), fScaleA(0), fScaleB(0), fX(0), fY(0),fZ(0)
+{
+  Init(minA, maxA, nBinsA, minB, maxB, nBinsB);
+}
+
+inline AliHLTTPCSpline2D3D::~AliHLTTPCSpline2D3D()
+{
+  delete[] fX;
+  delete[] fY;
+  delete[] fZ;
+}
+
+inline void AliHLTTPCSpline2D3D::Fill(Int_t ind, Float_t x, Float_t y, Float_t z)
+{
+  fX[ind] = x;
+  fY[ind] = y;
+  fZ[ind] = z;
+}
+
+inline void AliHLTTPCSpline2D3D::Fill(Int_t ind, Float_t XYZ[] )
+{
+  Fill( ind, XYZ[0], XYZ[1], XYZ[2] );
+}
+
+inline void AliHLTTPCSpline2D3D::Fill(Int_t ind, Double_t  XYZ[] )
+{
+  Fill( ind, XYZ[0], XYZ[1], XYZ[2] );
+}
+
+inline void AliHLTTPCSpline2D3D::GetAB(Int_t ind, Float_t &A, Float_t &B) const 
+{
+  A = fMinA + (ind / fNB)*fStepA;
+  B = fMinB + (ind % fNB)*fStepB;
+}
+
+inline Int_t AliHLTTPCSpline2D3D::GetMapSize() const 
+{
+  return 3*sizeof(float)*fN; 
+}
+
+inline Int_t AliHLTTPCSpline2D3D::GetNPoints() const 
+{ 
+  return fN; 
+}
+
+inline Float_t AliHLTTPCSpline2D3D::GetSpline3(Float_t *v, Float_t x)
+{
+  Float_t dv = v[2]-v[1];  
+  Float_t z0 = 0.5*(v[2]-v[0]);
+  Float_t z1 = 0.5*(v[3]-v[1]);
+  return x*x*( (z1-dv + z0-dv)*(x-1) - (z0-dv) ) + z0*x + v[1]; 
+}
+
+inline Float_t AliHLTTPCSpline2D3D::GetSpline2(Float_t *v, Float_t x)
+{
+  return 0.5*x*( ( v[0]+v[2] -v[1] -v[1] )*x + v[2]-v[0]) + v[1]; 
+}
+
+inline void AliHLTTPCSpline2D3D::GetValue(Float_t A, Float_t B, Double_t XYZ[]) const 
+{
+  float fxyz[3];
+  GetValue(A,B,fxyz);
+  for( Int_t i=0; i<3; i++ ) XYZ[i] = fxyz[i];
+}
+
+#endif