]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCTrackHits.cxx
Merging the VirtualMC branch to the main development branch (HEAD)
[u/mrichter/AliRoot.git] / TPC / AliTPCTrackHits.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.4.10.1  2002/08/28 15:06:52  alibrary
19 Updating to v3-09-01
20
21 Revision 1.5  2002/08/25 15:54:29  kowal2
22 Protection against overflows in TMath::Nint.
23
24 Revision 1.4  2001/01/10 09:35:27  kowal2
25 Changes to obey the coding rules.
26
27 Revision 1.3  2000/11/02 10:22:50  kowal2
28 Logs added
29
30 */
31 ///////////////////////////////////////////////////////////////////////////////
32 //                                                                           //
33 //  Time Projection Chamber  track hits object                                //
34 //
35 //  Origin: Marian Ivanov , GSI Darmstadt
36 //
37 //  Class for storing simulated AliTPCHits  for given track                  //
38 //             -average compression comparing to classical ClonesArray is    //
39 //              around 5-7 (depending on the required hit precision)       //
40 //                                                                           //
41 //Begin_Html
42 /*
43 <img src="gif/AliTPCTrackHits.gif">
44 */
45 //End_Html
46 //                                                                           //
47 //                                                                          //
48 ///////////////////////////////////////////////////////////////////////////////
49
50 #include "TVector3.h"
51 #include "TClonesArray.h"    
52 #include "AliTPCTrackHits.h"
53 #include "AliTPC.h"
54
55 #include <iostream.h>
56
57
58
59 ClassImp(AliTPCTrackHits) 
60 LClassImp(AliTrackHitsInfo) 
61 LClassImp(AliTrackHitsParam)  
62 LClassImp(AliHitInfo)
63
64 Int_t AliTrackHitsInfo::fgCounter1 =0;
65 Int_t AliTrackHitsInfo::fgCounter2 =0;
66 Int_t AliTrackHitsParam::fgCounter1 =0;
67 Int_t AliTrackHitsParam::fgCounter2 =0;
68 Int_t AliHitInfo::fgCounter1 =0;
69 Int_t AliHitInfo::fgCounter2 =0;
70 Int_t AliTPCTrackHits::fgCounter1 =0;
71 Int_t AliTPCTrackHits::fgCounter2 =0;
72 const Double_t AliTPCTrackHits::fgkPrecision=1e-6;  //precision 
73 const Double_t AliTPCTrackHits::fgkPrecision2=1e-20;  //precision
74
75
76 /************************************************************/
77 //           Interface classes                              // 
78 #include "AliTPCTrackHitsInterfaces.h"
79
80
81
82
83 struct AliTPCCurrentHit {
84   AliTPChit fHit;
85   UInt_t   fInfoIndex;//   - current info pointer 
86   UInt_t   fParamIndex;//  - current param pointer
87   UInt_t   fStackIndex; // - current hit stack index
88   Double_t fR;   //current Radius
89   Bool_t  fStatus; //current status    
90 };   
91
92
93 struct  AliTPCTempHitInfo {
94   enum    { fkStackSize = 10000};
95   AliTPCTempHitInfo();   
96   void     NewParam(Double_t r, Double_t z, Double_t fi, Int_t q);
97   void     SetHit(Double_t r, Double_t z, Double_t fi, Int_t q);
98   Double_t * GetPosition(Int_t index){return &fPositionStack[index*3];}
99   void    UpdateParam(Double_t maxdelta); //recal
100   void   Fit2(Double_t fSumY, Double_t fSumYX, Double_t fSumYX2,
101             Double_t fSumX,  Double_t fSumX2, Double_t fSumX3, 
102             Double_t fSumX4, Int_t n,
103               Double_t &a, Double_t &b, Double_t &c);
104   void  Fit(AliTrackHitsParam * param);
105   Double_t fSumDr;    //
106   Double_t fSumDr2;   //
107   Double_t fSumDr3;   //  
108   Double_t fSumDr4;   //
109   Double_t fSumDFi;  //
110   Double_t fSumDFiDr; //  
111   Double_t fSumDFiDr2;//
112   Double_t fSumDZ;     //
113   Double_t fSumDZDr;  //
114   Double_t fSumDZDr2;  //
115   Double_t fOldR;     //previos r
116   Double_t fPositionStack[3*fkStackSize];  //position stack 
117   UInt_t   fQStack[fkStackSize];           //Q stack
118   UInt_t fStackIndex;   //current stack index 
119   UInt_t fInfoIndex;    //current track info index
120   UInt_t fParamIndex;   //current track parameters index
121   AliTrackHitsInfo  * fInfo; //current track info
122   AliTrackHitsParam * fParam; //current track param
123 };
124
125
126 AliTPCTempHitInfo::AliTPCTempHitInfo()
127 {
128   //
129   //set to default value
130   fSumDr=fSumDr2=fSumDr3=fSumDr4=
131     fSumDFi=fSumDFiDr=fSumDFiDr2=
132     fSumDZ=fSumDZDr=fSumDZDr2=0;  
133   fStackIndex = 0;
134   fInfoIndex  = 0;
135   fParamIndex = 0;
136 }
137
138
139 void AliTPCTempHitInfo::NewParam(Double_t r, Double_t z, Double_t fi, Int_t q)
140 {
141   //
142   //reset stack and sum parameters
143   //store line initial point
144   fSumDr=fSumDr2=fSumDr3=fSumDr4=
145     fSumDFi=fSumDFiDr=fSumDFiDr2=
146     fSumDZ=fSumDZDr=fSumDZDr2=0;  
147   fStackIndex=0;
148   fParam->fR = r;
149   fOldR = r;
150   fParam->fZ = z;
151   fParam->fFi = fi;
152   fParam->fAn = 0.;
153   fParam->fAd = 0.;
154   fParam->fTheta =0.;
155   fParam->fThetaD =0.;
156   SetHit(r,z,fi,q);
157 }
158
159 void AliTPCTempHitInfo::SetHit(Double_t r, Double_t z, Double_t fi, Int_t q)
160 {
161   //
162   //add hit to the stack
163   //recalculate new estimete of line parameters
164   Double_t *f = GetPosition(fStackIndex);  
165   f[0] = r;
166   f[1] = z;
167   f[2] = fi;
168   fQStack[fStackIndex]=q;
169   if (fStackIndex==0) return;
170   Double_t dr  = (r-fParam->fR);
171   if (TMath::Abs(dr)<AliTPCTrackHits::fgkPrecision) dr =AliTPCTrackHits::fgkPrecision;
172   Double_t dfi = fi-fParam->fFi;
173   Double_t dz  = z -fParam->fZ; 
174   Double_t dr2 =dr*dr;
175   Double_t dr3 =dr2*dr;
176   Double_t dr4 =dr3*dr;
177   fSumDr +=dr;
178   fSumDr2+=dr2;
179   fSumDr3+=dr3;
180   fSumDr4+=dr4;
181   fSumDFi +=dfi;
182   fSumDFiDr+=dfi*dr;
183   fSumDFiDr2+=dfi*dr2;
184   fSumDZ +=dz;
185   fSumDZDr+=dz*dr;
186   fSumDZDr2+=dz*dr2;
187   
188   //update fit parameters
189   //
190   Double_t det = fSumDr2*fSumDr4-fSumDr3*fSumDr3;
191   if (TMath::Abs(det)<AliTPCTrackHits::fgkPrecision2) return;
192   if ( ( fStackIndex>1 )  ){
193     fParam->fAn = (fSumDr4*fSumDFiDr-fSumDr3*fSumDFiDr2)/det;
194     fParam->fAd = (fSumDr2*fSumDFiDr2-fSumDr3*fSumDFiDr)/det;
195   }
196   else
197     fParam->fAn = fSumDFiDr/fSumDr2;
198   if ( ( fStackIndex>1 )  ){
199     fParam->fTheta = (fSumDr4*fSumDZDr-fSumDr3*fSumDZDr2)/det;
200     fParam->fThetaD= (fSumDr2*fSumDZDr2-fSumDr3*fSumDZDr)/det;
201   }
202   else
203     fParam->fTheta = fSumDZDr/fSumDr2; 
204 }
205
206
207 void   AliTPCTempHitInfo::UpdateParam(Double_t maxdelta)
208 {
209   //recalc parameters not fixing origin point
210   if (fStackIndex>5){ 
211     Double_t a,b,c;
212     a=b=c=0;
213     Fit2(fSumDFi, fSumDFiDr, fSumDFiDr2, fSumDr,fSumDr2,fSumDr3,fSumDr4,
214          fStackIndex, a,b,c);
215     if (TMath::Abs(a)<maxdelta){
216       fParam->fFi +=a/fParam->fR;    
217       fParam->fAn = b;    
218       fParam->fAd = c;                  
219     }
220     Fit2(fSumDZ, fSumDZDr, fSumDZDr2, fSumDr,fSumDr2,fSumDr3,fSumDr4,
221          fStackIndex, a,b,c) ;   
222     if (TMath::Abs(a)<maxdelta){
223       fParam->fZ +=a;    
224       fParam->fTheta = b;    
225       fParam->fThetaD = c;   
226     }                         
227   }
228       
229 }
230 void   AliTPCTempHitInfo::Fit2(Double_t fSumY, Double_t fSumYX, Double_t fSumYX2,
231             Double_t fSumX,  Double_t fSumX2, Double_t fSumX3, 
232             Double_t fSumX4, Int_t n,
233             Double_t &a, Double_t &b, Double_t &c)
234 {
235   //fit of second order
236   Double_t det = 
237     n* (fSumX2*fSumX4-fSumX3*fSumX3) -
238     fSumX*      (fSumX*fSumX4-fSumX3*fSumX2)+
239     fSumX2*     (fSumX*fSumX3-fSumX2*fSumX2);
240     
241   if (TMath::Abs(det)> AliTPCTrackHits::fgkPrecision) {    
242     a = 
243       (fSumY * (fSumX2*fSumX4-fSumX3*fSumX3)-
244        fSumX *(fSumYX*fSumX4-fSumYX2*fSumX3)+
245        fSumX2*(fSumYX*fSumX3-fSumYX2*fSumX2))/det; 
246     b=
247       (n*(fSumYX*fSumX4-fSumX3*fSumYX2)-
248       fSumY*(fSumX*fSumX4-fSumX3*fSumX2)+
249       fSumX2*(fSumX*fSumYX2-fSumYX*fSumX2))/det;
250     c=
251       (n*(fSumX2*fSumYX2-fSumYX*fSumX3)-
252        fSumX*(fSumX*fSumYX2-fSumYX*fSumX2)+
253        fSumY*(fSumX*fSumX3-fSumX2*fSumX2))/det;  
254   }
255 }
256
257 void   AliTPCTempHitInfo::Fit(AliTrackHitsParam * param)
258 {
259   // fit fixing first and the last point 
260   //result stored in new param
261   Double_t dx2  = (GetPosition(fStackIndex))[0]-fParam->fR;
262   Double_t det = fSumDr4+dx2*fSumDr2-2*dx2*fSumDr3;
263   if ( (TMath::Abs(det)> AliTPCTrackHits::fgkPrecision) &&
264        ((TMath::Abs(dx2)> AliTPCTrackHits::fgkPrecision))){
265     Double_t dfi2 = (GetPosition(fStackIndex))[1]-fParam->fFi;
266     param->fAd = (fSumDFiDr2+dfi2*fSumDr-dx2*fSumDFiDr-dfi2*fSumDr3/dx2)/det;
267     param->fAn  = (dfi2-param->fAd*dx2*dx2)/dx2;
268     
269     Double_t dz2 = (GetPosition(fStackIndex))[1]-fParam->fZ;
270     param->fTheta = (fSumDZDr2+dz2*fSumDr-dx2*fSumDZDr-dz2*fSumDr3/dx2)/det;
271     param->fTheta  = (dz2-param->fAd*dx2*dx2)/dx2;
272   }
273   
274 }
275
276
277
278
279 AliTPCTrackHits::AliTPCTrackHits()
280 {
281   //
282   //default constructor
283   //
284   const Float_t kHitPrecision=0.002; //default precision for hit position in cm
285   const Float_t kStep =0.003;  //30 mum step 
286   const UShort_t kMaxDistance =100;  //maximum distance 100  
287
288   fPrecision=kHitPrecision; //precision in cm
289   fStep = kStep; //step size
290   fMaxDistance = kMaxDistance; //maximum distance
291   fTempInfo =0;
292   fTrackHitsInfo = new AliObjectArray("AliTrackHitsInfo"); 
293   fTrackHitsParam = new AliObjectArray("AliTrackHitsParam");
294   fHitsPosAndQ = new TArrayOfArrayVStack("AliHitInfo");
295   fCurrentHit = new AliTPCCurrentHit;
296   fgCounter1++;
297   fgCounter2++;
298
299
300
301 AliTPCTrackHits::~AliTPCTrackHits()
302 {
303   //
304   //default destructor
305   //
306   if (fTrackHitsInfo) delete fTrackHitsInfo;
307   if (fTrackHitsParam) delete fTrackHitsParam;
308   if (fHitsPosAndQ) delete fHitsPosAndQ;
309   if (fCurrentHit) delete fCurrentHit;
310   if (fTempInfo) delete fTempInfo;
311   fgCounter1--;
312 }
313
314 void AliTPCTrackHits::Clear()
315 {
316   //
317   //clear object 
318   fTrackHitsInfo->Clear();
319   fTrackHitsParam->Clear();  
320   //fTrackHitsInfo->Resize(0);
321   //fTrackHitsParam->Resize(0);
322   fHitsPosAndQ->Clear();
323
324   if (fTempInfo){
325     delete fTempInfo; 
326     fTempInfo =0;
327   } 
328 }
329
330
331 void AliTPCTrackHits::AddHitKartez(Int_t volumeID, Int_t trackID, Double_t x, 
332               Double_t y, Double_t z,Int_t q)
333 {
334   Double_t r = TMath::Sqrt(x*x+y*y);
335   Double_t fi = TMath::ACos(x/r);
336   if (y<0) fi*=-1.;
337     AddHit(volumeID,trackID,r,z,fi,q);
338 }
339
340 void AliTPCTrackHits::AddHit(Int_t volumeID, Int_t trackID, 
341                              Double_t r, Double_t z, Double_t fi, Int_t q)
342 {
343   //
344   Bool_t diff=kFALSE;
345   if (!fTempInfo) { //initialsation of track
346     fTempInfo = new AliTPCTempHitInfo;
347     //
348     if (fTrackHitsInfo->GetCapacity()<10) fTrackHitsInfo->Reserve(10);
349     fTrackHitsInfo->Resize(1);
350     fTempInfo->fInfoIndex =0;
351     if (fTrackHitsParam->GetCapacity()<100) fTrackHitsParam->Reserve(100);    
352     fTrackHitsParam->Resize(1);
353     //
354     fTempInfo->fInfo = 
355       (AliTrackHitsInfo*) (fTrackHitsInfo->At(0));
356     fTempInfo->fInfo->fVolumeID = volumeID;
357     fTempInfo->fInfo->fTrackID = trackID;
358     fTempInfo->fInfo->fHitParamIndex =0;     
359     fTempInfo->fInfoIndex = 0;
360     //
361     fTempInfo->fParam = 
362       (AliTrackHitsParam*) (fTrackHitsParam->At(0));
363     fTempInfo->fParamIndex = 0;
364     fTempInfo->NewParam(r,z,fi,q);
365     return;
366   }
367   
368   Int_t size = fHitsPosAndQ->GetSize();
369   if (size>(Int_t)fTempInfo->fParamIndex) {
370     fTempInfo->fParamIndex++;
371     if (fTempInfo->fParamIndex+1>fTrackHitsParam->GetSize()) 
372       fTrackHitsParam->Resize(fTempInfo->fParamIndex+1);    
373     fTempInfo->fParam = 
374       (AliTrackHitsParam*) (fTrackHitsParam->At(fTempInfo->fParamIndex));  
375     fTempInfo->NewParam(r,z,fi,q);
376     return;
377   }
378   
379
380   // if new volume or new trackID  
381   if ( (volumeID!=fTempInfo->fInfo->fVolumeID) || 
382        (trackID!=fTempInfo->fInfo->fTrackID)){
383     diff=kTRUE;
384
385     FlushHitStack(kTRUE);
386       
387     fTempInfo->fInfoIndex++;
388     if (fTempInfo->fInfoIndex+1>fTrackHitsInfo->GetSize()) 
389       fTrackHitsInfo->Resize(fTempInfo->fInfoIndex+1);
390     fTempInfo->fInfo = 
391       (AliTrackHitsInfo*) (fTrackHitsInfo->At(fTempInfo->fInfoIndex));      
392     fTempInfo->fInfo->fVolumeID = volumeID;
393     fTempInfo->fInfo->fTrackID = trackID;
394     fTempInfo->fInfo->fHitParamIndex =fTempInfo->fParamIndex+1;  
395     // FlushHitStack(kTRUE);
396
397     fTempInfo->fParamIndex++;
398     if (fTempInfo->fParamIndex+1>fTrackHitsParam->GetSize()) 
399       fTrackHitsParam->Resize(fTempInfo->fParamIndex+1);    
400     fTempInfo->fParam = 
401       (AliTrackHitsParam*) (fTrackHitsParam->At(fTempInfo->fParamIndex));  
402     fTempInfo->NewParam(r,z,fi,q);
403     return;
404   }
405      
406   //calculate current fit precission to next point
407   AliTrackHitsParam &param = *(fTempInfo->fParam);
408   Double_t dd=0;
409   Double_t dl=0;
410   Double_t ratio=0;
411   Double_t dr,dz,dfi,ddz,ddfi;
412   Double_t drhit,ddl;
413   dr=dz=dfi=ddz=ddfi=0;
414   drhit = r-fTempInfo->fOldR;
415   { 
416     //Double_t dfi2 = param.fAn+2*param.fAd*(r-param.fR); 
417     Double_t dfi2 = param.fAn;
418     dfi2*=dfi2*fTempInfo->fOldR*fTempInfo->fOldR;
419     //Double_t ddz2 =  param.fTheta+2*param.fThetaD*(r-param.fR);
420     Double_t ddz2 =  param.fTheta;
421     ddz2*=ddz2;
422     ratio = TMath::Sqrt(1.+ dfi2+ ddz2);  
423   }
424   //
425  
426
427   dl = (TMath::Abs(drhit*ratio/fStep)<32000) ?  fStep * Short_t(TMath::Nint(drhit*ratio/fStep)):0;
428   ddl = dl - drhit*ratio; 
429   fTempInfo->fOldR += dl/ratio; 
430
431   if (fTempInfo->fStackIndex>2){     
432     dr = r-param.fR;        
433     dz =  z-param.fZ;  
434     dfi = fi-param.fFi;
435     ddz = dr*param.fTheta+dr*dr*param.fThetaD-dz;
436     ddfi= dr*param.fAn+dr*dr*param.fAd-dfi;    
437     dd  = TMath::Sqrt(ddz*ddz+r*r*ddfi*ddfi+ddl*ddl); 
438     //
439   }        
440   //safety factor 1.25
441   if ( ( (dd*1.25>fPrecision) ) ||  
442        (fTempInfo->fStackIndex+4>fTempInfo->fkStackSize) || 
443        (TMath::Abs(dl/fStep)>fMaxDistance)  ) 
444     diff=kTRUE;
445   else{
446     fTempInfo->fStackIndex++;   
447     fTempInfo->SetHit(r,z,fi,q);
448     return;
449   }  
450   //if parameter changed 
451   if (FlushHitStack(kFALSE)){   //if full buffer flushed
452     fTempInfo->fParamIndex++;
453     if (fTempInfo->fParamIndex+1>fTrackHitsParam->GetSize()) 
454       fTrackHitsParam->Resize(fTempInfo->fParamIndex+1);    
455     fTempInfo->fParam = 
456       (AliTrackHitsParam*) (fTrackHitsParam->At(fTempInfo->fParamIndex));  
457     fTempInfo->NewParam(r,z,fi,q);
458   }
459   else{
460     fTempInfo->fStackIndex++;
461     fTempInfo->SetHit(r,z,fi,q);              
462   }
463 }   
464
465 Bool_t AliTPCTrackHits::FlushHitStack(Bool_t force)
466 {
467   //
468   //write fHitsPosAndQ information from the stack to te arrays
469   if (!fTempInfo) return kFALSE; 
470   Int_t size = fHitsPosAndQ->GetSize();
471
472   if ( (size>0)&&(size!=(Int_t)fTempInfo->fParamIndex)) return kFALSE;  
473
474   if (fHitsPosAndQ->Push(fTempInfo->fStackIndex+1)!=fTempInfo->fParamIndex){
475     cout<<"internal error - contact MI\n";
476     return kFALSE;
477   }
478   AliHitInfo * info;
479  
480   AliTrackHitsParam & param = *(fTempInfo->fParam);
481   //recalculate track parameter not fixing first point
482   fTempInfo->UpdateParam(fStep/4.);
483   //fTempInfo->Fit(fTempInfo->fParam);  //- fixing the first and the last point
484
485   Double_t oldr = param.fR; 
486   //cout<<"C3"<<fTempInfo->fStackIndex<<"\n"<<flush;
487   UInt_t i;
488   Double_t dd;
489   for (i=0; i <= fTempInfo->fStackIndex; i++){
490     Double_t * position = fTempInfo->GetPosition(i);
491     Double_t   dr = position[0]-oldr;
492     Double_t   ratio; 
493     { 
494       //Double_t dfi2 = param.fAn+2*param.fAd*(position[0]-param.fR);
495       Double_t dfi2 = param.fAn;
496       dfi2*=dfi2*oldr*oldr;
497       //Double_t ddz2 =  param.fTheta+2*param.fThetaD*(position[0]-param.fR);
498       Double_t ddz2 =  param.fTheta;
499       ddz2*=ddz2;
500       ratio = TMath::Sqrt(1.+ dfi2+ ddz2);  
501     }
502
503     Double_t dl = (TMath::Abs(dr*ratio/fStep)<32000) ? fStep*(Short_t)TMath::Nint(dr*ratio/fStep):0;  
504     dr = dl/ratio; 
505     oldr+=dr;
506     //calculate precission
507     AliTrackHitsParam &param = *(fTempInfo->fParam);    
508     //real deltas
509     Double_t dr1=  position[0]-param.fR;
510     Double_t dz =  position[1]-param.fZ;
511
512     Double_t dfi = position[2]-param.fFi;
513     //extrapolated deltas
514     Double_t dr2 = oldr-param.fR; 
515     Double_t ddr = dr2-dr1;
516     Double_t ddz = dr2*param.fTheta+dr2*dr2*param.fThetaD-dz;
517     Double_t ddfi= dr2*param.fAn+dr2*dr2*param.fAd-dfi;    
518     dd = TMath::Sqrt(ddz*ddz+oldr*oldr*ddfi*ddfi+ddr*ddr); 
519
520     if ( (dd>fPrecision) ){ 
521       if (i==0){
522         param.fAn = 0;
523         param.fAd = 0;
524         param.fTheta =0;
525         param.fThetaD =0;
526         Double_t ddz = dr2*param.fTheta+dr2*dr2*param.fThetaD-dz;
527         Double_t ddfi= dr2*param.fAn+dr2*dr2*param.fAd-dfi;    
528         dl = 0;
529         dd = TMath::Sqrt(ddz*ddz+oldr*oldr*ddfi*ddfi+ddr*ddr); 
530       }
531       else
532         break;
533     }
534
535     info = (AliHitInfo*)(fHitsPosAndQ->At(fTempInfo->fParamIndex,i));
536     info->fHitDistance = (TMath::Abs(dl/fStep)<32000) ?Short_t(TMath::Nint(dl/fStep)):0;
537     info->fCharge = Short_t(fTempInfo->fQStack[i]);
538     /*
539     cout<<"C2";
540     cout<<" "<<fTempInfo->fStackIndex<<" \t";
541     cout<<" "<<i<<" \t";
542     cout<<position[0]<<"\t";
543     cout<<position[1]<<"\t"; 
544     cout<<position[2]<<"\t";
545     cout<<param.fAn<<"\t";
546     cout<<param.fTheta<<"\t";
547     cout<<dr1<<"\t"<<ddr<<"\t"<<ddz<<"\t"<<ddfi<<"\t"<<dd<<"\n"<<flush;    
548     */
549   }    
550   
551   if (i<=fTempInfo->fStackIndex){ //if previous iteration not succesfull 
552     fHitsPosAndQ->Resize(fTempInfo->fParamIndex,i);
553     //
554     fTempInfo->fParamIndex++;
555     if (fTempInfo->fParamIndex+1>fTrackHitsParam->GetSize()) 
556       fTrackHitsParam->Resize(fTempInfo->fParamIndex+1);    
557     fTempInfo->fParam = 
558         (AliTrackHitsParam*) (fTrackHitsParam->At(fTempInfo->fParamIndex));    
559     Double_t * p = fTempInfo->GetPosition(i);
560     UInt_t index2 = fTempInfo->fStackIndex;
561     fTempInfo->NewParam(p[0],p[1],p[2],fTempInfo->fQStack[i]);        
562     if (i+1<=index2) FlushHitStack2(i+1,index2);
563
564     if (force) return      FlushHitStack(kTRUE);      
565     return kFALSE;
566   }  
567   return kTRUE;
568
569  
570
571 void AliTPCTrackHits::FlushHitStack2(Int_t index1, Int_t index2)
572 {
573   //
574   // second iteration flush stack
575   // call only for hits where first iteration were not succesfully interpolated  
576   Double_t * positionstack = new Double_t[3*(index2-index1+1)];
577   UInt_t   * qstack        = new UInt_t[index2-index1+1];
578   memcpy(positionstack, &fTempInfo->fPositionStack[3*index1],
579          (3*(index2-index1+1))*sizeof(Double_t));
580   memcpy(qstack, &fTempInfo->fQStack[index1],(index2-index1+1)*sizeof(UInt_t));
581   Double_t *p = positionstack;
582   for (Int_t j=0; j<=index2-index1;j++){ 
583     fTempInfo->fStackIndex++;
584     fTempInfo->SetHit(p[3*j+0],p[3*j+1],p[3*j+2],qstack[j]);
585   }  
586   delete []positionstack;
587   delete []qstack;
588 }
589
590
591    
592
593
594
595
596   
597
598 Bool_t AliTPCTrackHits::First()
599 {
600   //
601   //set Current hit for the first hit
602   //
603   AliTrackHitsInfo *info = (AliTrackHitsInfo *)fTrackHitsInfo->At(0);
604   AliTrackHitsParam *param = (AliTrackHitsParam *)fTrackHitsParam->At(0);
605   AliHitInfo * hinfo = (AliHitInfo *)fHitsPosAndQ->At(0,0);
606
607   if (!(info) || !(param) || !(hinfo) ) {
608     fCurrentHit->fStatus = kFALSE;
609     return kFALSE;
610   }
611
612   fCurrentHit->fInfoIndex  = 0;
613   fCurrentHit->fParamIndex = 0;
614   fCurrentHit->fStackIndex = 0;
615
616   fCurrentHit->fHit.fSector = info->fVolumeID;
617   fCurrentHit->fHit.SetTrack(info->fTrackID);
618   fCurrentHit->fHit.SetX(param->fR*TMath::Cos(param->fFi));
619   fCurrentHit->fHit.SetY(param->fR*TMath::Sin(param->fFi));
620   fCurrentHit->fHit.SetZ(param->fZ); 
621   fCurrentHit->fHit.fQ = hinfo->fCharge;
622    
623   fCurrentHit->fR = param->fR;
624   
625   return fCurrentHit->fStatus = kTRUE;
626 }
627
628 Bool_t AliTPCTrackHits::Next()
629 {
630   //
631   //  
632   if (!(fCurrentHit->fStatus)) 
633     return kFALSE;
634
635   fCurrentHit->fStackIndex++;
636   AliHitInfo * hinfo = (AliHitInfo *)fHitsPosAndQ->At(fCurrentHit->fParamIndex,
637                                                       fCurrentHit->fStackIndex);
638   AliTrackHitsInfo *info = (AliTrackHitsInfo *)fTrackHitsInfo->At(fCurrentHit->fInfoIndex);
639   AliTrackHitsParam *param =  (AliTrackHitsParam *)fTrackHitsParam->At(fCurrentHit->fParamIndex);
640
641   if (!hinfo) {
642     hinfo = (AliHitInfo *)fHitsPosAndQ->At(fCurrentHit->fParamIndex+1, 0);
643     if (!hinfo) 
644       return fCurrentHit->fStatus = kFALSE;
645     if (hinfo){ 
646       fCurrentHit->fParamIndex++;
647       fCurrentHit->fStackIndex = 0;
648       param = (AliTrackHitsParam *)fTrackHitsParam->At(fCurrentHit->fParamIndex);
649       if (!param) 
650         return fCurrentHit->fStatus = kFALSE;     
651       fCurrentHit->fR = param->fR;
652
653       if ((fCurrentHit->fInfoIndex+1<fTrackHitsInfo->GetSize())
654         &&((info+1)->fHitParamIndex<=fCurrentHit->fParamIndex)){
655         fCurrentHit->fInfoIndex++;
656         info = (AliTrackHitsInfo *)fTrackHitsInfo->At(fCurrentHit->fInfoIndex);
657         if (!info) 
658           return fCurrentHit->fStatus = kFALSE;
659         fCurrentHit->fHit.fSector = info->fVolumeID;
660         fCurrentHit->fHit.SetTrack(info->fTrackID);
661       }
662     }  
663   } 
664   Double_t ratio;
665   { 
666     //    Double_t dfi2 = param->fAn+2*param->fAd*(fCurrentHit->fR-param->fR);
667     Double_t dfi2 = param->fAn;
668     dfi2*=dfi2*fCurrentHit->fR*fCurrentHit->fR;
669     //    Double_t ddz2 = param->fTheta+2*param->fThetaD*(fCurrentHit->fR-param->fR);
670     Double_t ddz2 =  param->fTheta;
671     ddz2*=ddz2;
672     ratio = TMath::Sqrt(1.+ dfi2+ ddz2);  
673   }
674
675   fCurrentHit->fHit.fQ = hinfo->fCharge;
676   fCurrentHit->fR += fStep*hinfo->fHitDistance/ratio;
677   Double_t dR = fCurrentHit->fR - param->fR;
678   //Double_t dR =0;
679   Double_t fi = param->fFi + (param->fAn*dR+param->fAd*dR*dR);
680   Double_t z  = param->fZ + (param->fTheta*dR+param->fThetaD*dR*dR);
681   
682   fCurrentHit->fHit.SetX(fCurrentHit->fR*TMath::Cos(fi));
683   fCurrentHit->fHit.SetY(fCurrentHit->fR*TMath::Sin(fi));
684   fCurrentHit->fHit.SetZ(z);  
685   return kTRUE;
686 }
687   
688 AliTPChit * AliTPCTrackHits::GetHit()
689 {
690   //
691    return (fCurrentHit->fStatus)? &fCurrentHit->fHit:0;
692   //return &fCurrentHit->fHit;
693
694 }  
695
696 AliTrackHitsParam * AliTPCTrackHits::GetParam()
697 {
698   //
699   return (fCurrentHit->fStatus)? (AliTrackHitsParam *)fTrackHitsParam->At(fCurrentHit->fParamIndex) :0;
700
701
702 AliHitInfo * AliTPCTrackHits::GetHitInfo()
703 {
704   //
705   return (fCurrentHit->fStatus)? 
706     (AliHitInfo *)fHitsPosAndQ->At(fCurrentHit->fParamIndex,fCurrentHit->fStackIndex) :0;
707
708
709
710