1 //**************************************************************************
2 //* This file is property of and copyright by the ALICE HLT Project *
3 //* ALICE Experiment at CERN, All rights reserved. *
5 //* Primary Authors: Sergey Gorbunov <sergey.gorbunov@cern.ch> *
6 //* for The ALICE HLT Project. *
8 //* Permission to use, copy, modify and distribute this software and its *
9 //* documentation strictly for non-commercial purposes is hereby granted *
10 //* without fee, provided that the above copyright notice appears in all *
11 //* copies and that both the copyright notice and this permission notice *
12 //* appear in the supporting documentation. The authors make no claims *
13 //* about the suitability of this software for any purpose. It is *
14 //* provided "as is" without express or implied warranty. *
15 //**************************************************************************
17 /** @file AliHLTTPCFastTransform.cxx
18 @author Sergey Gorbubnov
24 #include "AliHLTTPCFastTransform.h"
25 #include "AliTPCTransform.h"
26 #include "AliTPCParam.h"
27 #include "AliTPCRecoParam.h"
28 #include "AliTPCcalibDB.h"
35 ClassImp(AliHLTTPCFastTransform); //ROOT macro for the implementation of ROOT specific class methods
38 AliHLTTPCFastTransform::AliHLTTPCFastTransform()
48 // see header file for class documentation
50 // refer to README to build package
52 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
53 for( Int_t i=0; i<fkNSec; i++)
54 for( Int_t j=0; j<fkNRows; j++ ) fRows[i][j] = NULL;
57 AliHLTTPCFastTransform::~AliHLTTPCFastTransform()
59 // see header file for class documentation
63 void AliHLTTPCFastTransform::DeInit()
67 for( Int_t i=0; i<fkNSec; i++){
68 for( Int_t j=0; j<fkNRows; j++ ){
73 fOrigTransform = NULL;
81 Int_t AliHLTTPCFastTransform::Init( AliTPCTransform *transform, Long_t TimeStamp )
87 AliTPCcalibDB* pCalib=AliTPCcalibDB::Instance();
88 if(!pCalib ) return Error( -1, "AliHLTTPCFastTransform::Init: No TPC calibration instance found");
90 AliTPCParam *tpcParam = pCalib->GetParameters();
91 if( !tpcParam ) return Error( -2, "AliHLTTPCFastTransform::Init: No TPCParam object found");
93 if( !transform ) transform = pCalib->GetTransform();
94 if( !transform ) return Error( -3, "AliHLTTPCFastTransform::Init: No TPC transformation found");
97 tpcParam->ReadGeoMatrices();
100 // at the moment initialise all the rows
102 int nSec = tpcParam->GetNSector();
103 if( nSec>fkNSec ) nSec = fkNSec;
105 for( Int_t i=0; i<nSec; i++ ){
106 int nRows = tpcParam->GetNRow(i);
107 if( nRows>fkNRows ) nRows = fkNRows;
108 for( int j=0; j<nRows; j++){
109 if( !fRows[i][j] ) fRows[i][j] = new AliHLTTPCFastTransform::AliRowTransform;
110 if( !fRows[i][j] ) return Error( -4, "AliHLTTPCFastTransform::Init: Not enough memory");
114 const AliTPCRecoParam *rec = transform->GetCurrentRecoParam();
116 if( !rec ) return Error( -5, "AliHLTTPCFastTransform::Init: No TPC Reco Param set in transformation");
118 fOrigTransform = transform;
120 if( rec->GetUseSectorAlignment() && (!pCalib->HasAlignmentOCDB()) ){
122 fAlignment = new Float_t [fkNSec*21];
123 for( Int_t iSec=0; iSec<fkNSec; iSec++ ){
124 Float_t *t = fAlignment + iSec*21, *r = t+3, *v = t+12;
125 for( int i=0; i<21; i++ ) t[i]=0.f;
126 r[0] = r[4] = r[8] = 1.f;
127 v[0] = v[4] = v[8] = 1.f;
130 for( Int_t iSec=0; iSec<nSec; iSec++ ){
131 Float_t *t = fAlignment + iSec*21, *r = t+3, *v = t+12;
132 TGeoHMatrix *alignment = tpcParam->GetClusterMatrix( iSec );
134 const Double_t *tr = alignment->GetTranslation();
135 const Double_t *rot = alignment->GetRotationMatrix();
137 for( int i=0; i<3; i++ ) t[i] = tr[i];
138 for( int i=0; i<9; i++ ) r[i] = rot[i];
139 CalcAdjugateRotation(r,v,1);
145 return SetCurrentTimeStamp( TimeStamp );
149 bool AliHLTTPCFastTransform::CalcAdjugateRotation(const Float_t *mA, Float_t *mB, bool bCheck)
151 // check rotation matrix and adjugate for consistency
153 // ( for a rotation matrix inverse == transpose )
169 for (int r=0; r<3; r++) {
170 for (int c=0; c<3; c++) {
173 if (r==c) expected=1.;
174 for (int i=0; i<3; i++) {
175 a+=mA[3*r+i]*mB[c+(3*i)];
177 if (TMath::Abs(a-expected)>0.00001) {
178 std::cout << "inconsistent adjugate at " << r << c << ": " << a << " " << expected << std::endl;
179 for( int i=0; i<9; i++ ) mB[i] = 0;
180 mB[0] = mB[4] = mB[8] = 1;
191 Int_t AliHLTTPCFastTransform::SetCurrentTimeStamp( Long_t TimeStamp )
193 // Set the current time stamp
196 Long_t lastTS = fLastTimeStamp;
197 fLastTimeStamp = -1; // deinitialise
199 if( !fOrigTransform ) return Error( -1, "AliHLTTPCFastTransform::SetCurrentTimeStamp: TPC transformation has not been set properly");
201 AliTPCcalibDB* pCalib=AliTPCcalibDB::Instance();
202 if(!pCalib ) return Error( -2, "AliHLTTPCFastTransform::SetCurrentTimeStamp: No TPC calibration found");
204 AliTPCParam *tpcParam = pCalib->GetParameters();
205 if( !tpcParam ) return Error( -3, "AliHLTTPCFastTransform::SetCurrentTimeStamp: No TPCParam object found");
208 if( TimeStamp<0 ) return 0;
210 fLastTimeStamp = lastTS;
212 if( fLastTimeStamp>=0 && TMath::Abs(fLastTimeStamp - TimeStamp ) <60 ) return 0;
215 fOrigTransform->SetCurrentTimeStamp( static_cast<UInt_t>(TimeStamp) );
216 fLastTimeStamp = TimeStamp;
218 // find last calibrated time bin
220 Int_t nTimeBins = tpcParam->GetMaxTBin();
223 for( fLastTimeBin=0; fLastTimeBin<nTimeBins; fLastTimeBin++){
224 // static cast is okay since fLastTimeBin has limited value range
225 Double_t xx[]={0,0,static_cast<Double_t>(fLastTimeBin)};
226 fOrigTransform->Transform(xx,is,0,1);
228 if( fLastTimeBin==0 ) sign = s;
235 fTimeBorder2 = fLastTimeBin - 100;
237 int nSec = tpcParam->GetNSector();
238 if( nSec>fkNSec ) nSec = fkNSec;
240 for( Int_t i=0; i<nSec; i++ ){
241 int nRows = tpcParam->GetNRow(i);
242 if( nRows>fkNRows ) nRows = fkNRows;
243 for( int j=0; j<nRows; j++){
245 int err = InitRow(i,j);
246 if( err!=0 ) return err;
254 Int_t AliHLTTPCFastTransform::InitRow( Int_t iSector, Int_t iRow )
256 // see header file for class documentation
258 AliTPCcalibDB* pCalib=AliTPCcalibDB::Instance();
260 if( iSector<0 || iSector>=fkNSec || iRow<0 || iRow>=fkNRows || !fOrigTransform || (fLastTimeStamp<0) ||
261 !fRows[iSector][iRow] || !pCalib || !pCalib->GetParameters() ){
262 return Error( -1, "AliHLTTPCFastTransform::InitRow: Internal error");
265 AliTPCParam *tpcParam = pCalib->GetParameters();
267 Int_t nPads = tpcParam->GetNPads(iSector,iRow);
270 return Error( -2, Form("AliHLTTPCFastTransform::InitRow: Wrong NPads=%d for sector %d row %d",nPads,iSector,iRow ));
273 fRows[iSector][iRow]->fSpline[0].Init( 0.5, nPads-1+0.5, 15, 0, fTimeBorder1, 5);
274 fRows[iSector][iRow]->fSpline[1].Init( 0.5, nPads-1+0.5, 15, fTimeBorder1, fTimeBorder2, 10);
275 fRows[iSector][iRow]->fSpline[2].Init( 0.5, nPads-1+0.5, 15, fTimeBorder2, fLastTimeBin, 5);
277 for( Int_t i=0; i<3; i++){
278 Int_t is[]={iSector};
279 for( Int_t j=0; j<fRows[iSector][iRow]->fSpline[i].GetNPoints(); j++){
281 fRows[iSector][iRow]->fSpline[i].GetAB(j,pad,time);
282 Double_t xx[]={static_cast<Double_t>(iRow),pad,time};
283 fOrigTransform->Transform(xx,is,0,1);
284 fRows[iSector][iRow]->fSpline[i].Fill(j,xx);
286 fRows[iSector][iRow]->fSpline[i].Consolidate();
293 Int_t AliHLTTPCFastTransform::GetRowSize( Int_t iSec, Int_t iRow ) const
295 // see header file for class documentation
296 Int_t s = sizeof(AliHLTTPCFastTransform::AliRowTransform);
297 if( fRows[iSec][iRow] ) for( Int_t i=0; i<3; i++) s+=fRows[iSec][iRow]->fSpline[i].GetMapSize();
301 Int_t AliHLTTPCFastTransform::GetSize() const
303 // see header file for class documentation
304 Int_t s = sizeof(AliHLTTPCFastTransform);
305 for( Int_t i=0; i<fkNSec; i++ )
306 for( Int_t j=0; j<fkNRows; j++ ) if( fRows[i][j] ){
307 s+= sizeof(AliHLTTPCFastTransform::AliRowTransform);
308 for( Int_t k=0; k<3; k++) fRows[i][j]->fSpline[k].GetMapSize();
314 void AliHLTTPCFastTransform::Print(const char* /*option*/) const
317 ios::fmtflags coutflags=std::cout.flags(); // backup cout status flags
320 std::cout << "AliHLTTPCFastTransform: no alignment transformation";
322 for( int iSec=0; iSec<fkNSec; iSec++ ){
323 std::cout << "AliHLTTPCClusterTransformation for sector " << iSec << std::endl;
325 const Float_t *mT = fAlignment + iSec*21;
326 const Float_t *mR = mT + 3;
327 const Float_t *mV = mT + 3+9;
329 std::cout.setf(ios_base::showpos|ios_base::showpos|ios::right);
330 std::cout << " translation: " << std::endl;
332 for (r=0; r<3; r++) {
333 std::cout << setw(7) << fixed << setprecision(2);
334 cout << " " << mT[r] << std::endl;
336 std::cout << " rotation and adjugated rotation: " << std::endl;
337 for (r=0; r<3; r++) {
339 std::cout << setw(7) << fixed << setprecision(2);
340 for (c=0; c<3; c++) std::cout << " " << mR[3*r+c];
342 for (c=0; c<3; c++) std::cout << " " << mV[3*r+c];
347 std::cout.flags(coutflags); // restore the original flags