]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/hough/AliL3Hough.cxx
f8c301c813c197418dd36af98a3e4994cf9b2041
[u/mrichter/AliRoot.git] / HLT / hough / AliL3Hough.cxx
1 // @(#) $Id$
2
3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright &copy ALICE HLT Group
5
6 #include "AliL3StandardIncludes.h"
7 #include <sys/time.h>
8
9 #include "AliL3Logging.h"
10 #include "AliL3HoughMerger.h"
11 #include "AliL3HoughIntMerger.h"
12 #include "AliL3HoughGlobalMerger.h"
13 #include "AliL3Histogram.h"
14 #include "AliL3Hough.h"
15 #include "AliL3HoughTransformer.h"
16 #include "AliL3HoughClusterTransformer.h"
17 #include "AliL3HoughTransformerLUT.h"
18 #include "AliL3HoughTransformerVhdl.h"
19 #include "AliL3HoughMaxFinder.h"
20 #include "AliL3Benchmark.h"
21 #ifdef use_aliroot
22 #include "AliL3FileHandler.h"
23 #else
24 #include "AliL3MemHandler.h"
25 #endif
26 #include "AliL3DataHandler.h"
27 #include "AliL3DigitData.h"
28 #include "AliL3HoughEval.h"
29 #include "AliL3Transform.h"
30 #include "AliL3TrackArray.h"
31 #include "AliL3HoughTrack.h"
32 #include "AliL3DDLDataFileHandler.h"
33
34 #if GCCVERSION == 3
35 using namespace std;
36 #endif
37
38 /** /class AliL3Hough
39 //<pre>
40 //_____________________________________________________________
41 // AliL3Hough
42 //
43 // Interface class for the Hough transform
44 //
45 // Example how to use:
46 //
47 // AliL3Hough *hough = new AliL3Hough(path,kTRUE,NumberOfEtaSegments);
48 // hough->ReadData(slice);
49 // hough->Transform();
50 // hough->FindTrackCandidates();
51 // 
52 // AliL3TrackArray *tracks = hough->GetTracks(patch);
53 //</pre>
54 */
55
56 ClassImp(AliL3Hough)
57
58 AliL3Hough::AliL3Hough()
59 {
60   //Constructor
61   
62   fBinary        = kFALSE;
63   fAddHistograms = kFALSE;
64   fDoIterative   = kFALSE; 
65   fWriteDigits   = kFALSE;
66   fUse8bits      = kFALSE;
67
68   fMemHandler       = 0;
69   fHoughTransformer = 0;
70   fEval             = 0;
71   fPeakFinder       = 0;
72   fTracks           = 0;
73   fGlobalTracks     = 0;
74   fMerger           = 0;
75   fInterMerger      = 0;
76   fGlobalMerger     = 0;
77   fBenchmark        = 0;
78   
79   fNEtaSegments     = 0;
80   fNPatches         = 0;
81   fVersion          = 0;
82   fCurrentSlice     = 0;
83   fEvent            = 0;
84
85   SetTransformerParams();
86   SetThreshold();
87   SetNSaveIterations();
88   SetPeakThreshold();
89 #ifdef use_aliroot
90   //just be sure that index is empty for new event
91     AliL3FileHandler::CleanStaticIndex(); 
92 #endif
93 }
94
95 AliL3Hough::AliL3Hough(Char_t *path,Bool_t binary,Int_t n_eta_segments,Bool_t bit8,Int_t tv,Char_t *infile)
96 {
97   fBinary = binary;
98   strcpy(fPath,path);
99   fNEtaSegments  = n_eta_segments;
100   fAddHistograms = kFALSE;
101   fDoIterative   = kFALSE; 
102   fWriteDigits   = kFALSE;
103   fUse8bits      = bit8;
104   fVersion       = tv;
105   if(!fBinary)
106     fInputFile = infile;
107   else
108     fInputFile = 0;
109
110 #ifdef use_aliroot
111   //just be sure that index is empty for new event
112     AliL3FileHandler::CleanStaticIndex(); 
113 #endif
114 }
115
116 AliL3Hough::~AliL3Hough()
117 {
118   //dtor
119
120   CleanUp();
121   if(fMerger)
122     delete fMerger;
123   //cout << "Cleaned class merger " << endl;
124   if(fInterMerger)
125     delete fInterMerger;
126   //cout << "Cleaned class inter " << endl;
127   if(fPeakFinder)
128     delete fPeakFinder;
129   //cout << "Cleaned class peak " << endl;
130   if(fGlobalMerger)
131     delete fGlobalMerger;
132   //cout << "Cleaned class global " << endl;
133   if(fBenchmark)
134     delete fBenchmark;
135   //cout << "Cleaned class bench " << endl;
136   if(fGlobalTracks)
137     delete fGlobalTracks;
138   //cout << "Cleaned class globaltracks " << endl;
139 }
140
141 void AliL3Hough::CleanUp()
142 {
143   //Cleanup memory
144   
145   for(Int_t i=0; i<fNPatches; i++)
146     {
147       if(fTracks[i]) delete fTracks[i];
148       //cout << "Cleaned tracks " << i << endl;
149       if(fEval[i]) delete fEval[i];
150       //cout << "Cleaned eval " << i << endl;
151       if(fHoughTransformer[i]) delete fHoughTransformer[i];
152       //cout << "Cleaned traf " << i << endl;
153       if(fMemHandler[i]) delete fMemHandler[i];
154       //cout << "Cleaned mem " << i << endl;
155     }
156   
157   if(fTracks) delete [] fTracks;
158   //cout << "Cleaned class tracks " << endl;
159   if(fEval) delete [] fEval;
160   //cout << "Cleaned class eval " << endl;
161   if(fHoughTransformer) delete [] fHoughTransformer;
162   //cout << "Cleaned cleass trafo " << endl;
163   if(fMemHandler) delete [] fMemHandler;
164   //cout << "Cleaned class mem " << endl;
165 }
166
167 void AliL3Hough::Init(Char_t *path,Bool_t binary,Int_t n_eta_segments,Bool_t bit8,Int_t tv,Char_t *infile)
168 {
169   fBinary = binary;
170   strcpy(fPath,path);
171   fNEtaSegments = n_eta_segments;
172   fWriteDigits  = kFALSE;
173   fUse8bits     = bit8;
174   fVersion      = tv;
175   if(!fBinary)
176     fInputFile = infile;
177   else
178     fInputFile = 0;
179
180   Init(); //do the rest
181 }
182
183 void AliL3Hough::Init(Bool_t doit, Bool_t addhists)
184 {
185   fDoIterative   = doit; 
186   fAddHistograms = addhists;
187
188   fNPatches = AliL3Transform::GetNPatches();
189   
190   fHoughTransformer = new AliL3HoughBaseTransformer*[fNPatches];
191   fMemHandler = new AliL3MemHandler*[fNPatches];
192
193   fTracks = new AliL3TrackArray*[fNPatches];
194   fEval = new AliL3HoughEval*[fNPatches];
195   
196   fGlobalTracks = new AliL3TrackArray("AliL3HoughTrack");
197   
198   for(Int_t i=0; i<fNPatches; i++)
199     {
200       switch (fVersion){ //choose Transformer
201       case 1: 
202         fHoughTransformer[i] = new AliL3HoughTransformerLUT(0,i,fNEtaSegments);
203         break;
204       case 2:
205         fHoughTransformer[i] = new AliL3HoughClusterTransformer(0,i,fNEtaSegments);
206         break;
207       case 3:
208         fHoughTransformer[i] = new AliL3HoughTransformerVhdl(0,i,fNEtaSegments,fNSaveIterations);
209         break;
210       default:
211         fHoughTransformer[i] = new AliL3HoughTransformer(0,i,fNEtaSegments,kFALSE,kFALSE);
212       }
213
214       fHoughTransformer[i]->CreateHistograms(fNBinX[i],fLowPt[i],fNBinY[i],-fPhi[i],fPhi[i]);
215       //fHoughTransformer[i]->CreateHistograms(fLowPt[i],fUpperPt[i],fPtRes[i],fNBinY[i],fPhi[i]);
216
217       fHoughTransformer[i]->SetLowerThreshold(fThreshold[i]);
218       fHoughTransformer[i]->SetUpperThreshold(100);
219
220       LOG(AliL3Log::kInformational,"AliL3Hough::Init","Version")
221         <<"Initializing Hough transformer version "<<fVersion<<ENDLOG;
222       
223       fEval[i] = new AliL3HoughEval();
224       fTracks[i] = new AliL3TrackArray("AliL3HoughTrack");
225       if(fUse8bits)
226         fMemHandler[i] = new AliL3DataHandler();
227       else
228 #ifdef use_aliroot
229         {
230           if(!fInputFile) {
231             /* In case of reading digits file */
232             fMemHandler[i] = new AliL3FileHandler(kTRUE); //use static index
233             if(!fBinary) {
234               Char_t filename[1024];
235               sprintf(filename,"%s/digitfile.root",fPath);
236               fMemHandler[i]->SetAliInput(filename);
237             }
238           }
239           else {
240             /* In case of reading rawdata from ROOT file */
241             fMemHandler[i] = new AliL3DDLDataFileHandler();
242             fMemHandler[i]->SetReaderInput(fInputFile);
243           }
244         }
245 #else
246       fMemHandler[i] = new AliL3MemHandler();
247 #endif
248     }
249
250   fPeakFinder = new AliL3HoughMaxFinder("KappaPhi",1000);
251   fMerger = new AliL3HoughMerger(fNPatches);
252   fInterMerger = new AliL3HoughIntMerger();
253   fGlobalMerger = 0;
254   fBenchmark = new AliL3Benchmark();
255 }
256
257 void AliL3Hough::SetTransformerParams(Float_t ptres,Float_t ptmin,Float_t ptmax,Int_t ny,Int_t patch)
258 {
259
260   Int_t mrow;
261   Float_t psi=0;
262   if(patch==-1)
263     mrow = 80;
264   else
265     mrow = AliL3Transform::GetLastRow(patch);
266   if(ptmin)
267     {
268       Double_t lineradius = sqrt(pow(AliL3Transform::Row2X(mrow),2) + pow(AliL3Transform::GetMaxY(mrow),2));
269       Double_t kappa = -1*AliL3Transform::GetBField()*AliL3Transform::GetBFact()/ptmin;
270       psi = AliL3Transform::Deg2Rad(10) - asin(lineradius*kappa/2);
271       cout<<"Calculated psi range "<<psi<<" in patch "<<patch<<endl;
272     }
273
274   if(patch==-1)
275     {
276       Int_t i=0;
277       while(i < 6)
278         {
279           fPtRes[i] = ptres;
280           fLowPt[i] = ptmin;
281           fUpperPt[i] = ptmax;
282           fNBinY[i] = ny;
283           fPhi[i] = psi;
284           fNBinX[i]=0;
285           i++;
286         }
287       return;
288     }
289
290   fPtRes[patch] = ptres;
291   fLowPt[patch] = ptmin;
292   fUpperPt[patch] = ptmax;
293   fNBinY[patch] = ny;
294   fPhi[patch] = psi;
295 }
296
297 void AliL3Hough::SetTransformerParams(Int_t nx,Int_t ny,Float_t ptmin,Int_t patch)
298 {
299
300   Int_t mrow=80;
301   Double_t lineradius = sqrt(pow(AliL3Transform::Row2X(mrow),2) + pow(AliL3Transform::GetMaxY(mrow),2));
302   Double_t kappa = -1*AliL3Transform::GetBField()*AliL3Transform::GetBFact()/ptmin;
303   Double_t psi = AliL3Transform::Deg2Rad(10) - asin(lineradius*kappa/2);
304   cout<<"Calculated psi range "<<psi<<" in patch "<<patch<<endl;
305   
306   Int_t i=0;
307   while(i < 6)
308     {
309       fLowPt[i] = ptmin;
310       fNBinY[i] = ny;
311       fNBinX[i] = nx;
312       fPhi[i] = psi;
313       i++;
314     }
315 }
316
317 void AliL3Hough::SetTransformerParams(Int_t nx,Int_t ny,Float_t lpt,Float_t phi)
318 {
319   Int_t i=0;
320   while(i < 6)
321     {
322       fLowPt[i] = lpt;
323       fNBinY[i] = ny;
324       fNBinX[i] = nx;
325       fPhi[i] = phi;
326       i++;
327     }
328 }
329
330 void AliL3Hough::SetThreshold(Int_t t3,Int_t patch)
331 {
332   if(patch==-1)
333     {
334       Int_t i=0;
335       while(i < 6)
336         fThreshold[i++]=t3;
337       return;
338     }
339   fThreshold[patch]=t3;
340 }
341
342 void AliL3Hough::SetPeakThreshold(Int_t threshold,Int_t patch)
343 {
344   if(patch==-1)
345     {
346       Int_t i=0;
347       while(i < 6)
348         fPeakThreshold[i++]=threshold;
349       return;
350     }
351   fPeakThreshold[patch]=threshold;
352 }
353
354 void AliL3Hough::DoBench(Char_t *name)
355 {
356   fBenchmark->Analyze(name);
357 }
358
359 void AliL3Hough::Process(Int_t minslice,Int_t maxslice)
360 {
361   //Process all slices [minslice,maxslice].
362   fGlobalMerger = new AliL3HoughGlobalMerger(minslice,maxslice);
363   
364   for(Int_t i=minslice; i<=maxslice; i++)
365     {
366       ReadData(i);
367       Transform();
368       if(fAddHistograms)
369         AddAllHistograms();
370       FindTrackCandidates();
371       //Evaluate();
372       //fGlobalMerger->FillTracks(fTracks[0],i);
373     }
374 }
375
376 void AliL3Hough::ReadData(Int_t slice,Int_t eventnr)
377 {
378   //Read data from files, binary or root.
379   
380 #ifdef use_aliroot
381   if(fEvent!=eventnr) //just be sure that index is empty for new event
382     AliL3FileHandler::CleanStaticIndex(); 
383 #endif
384   fEvent=eventnr;
385   fCurrentSlice = slice;
386
387   for(Int_t i=0; i<fNPatches; i++)
388     {
389       fMemHandler[i]->Free();
390       UInt_t ndigits=0;
391       AliL3DigitRowData *digits =0;
392       Char_t name[256];
393       fMemHandler[i]->Init(slice,i);
394       if(fBinary)//take input data from binary files
395         {
396           if(fUse8bits)
397             sprintf(name,"%s/binaries/digits_c8_%d_%d_%d.raw",fPath,eventnr,slice,i);
398           else
399             sprintf(name,"%s/binaries/digits_%d_%d_%d.raw",fPath,eventnr,slice,i);
400
401           fMemHandler[i]->SetBinaryInput(name);
402           digits = (AliL3DigitRowData *)fMemHandler[i]->CompBinary2Memory(ndigits);
403           fMemHandler[i]->CloseBinaryInput();
404         }
405       else //read data from root file
406         {
407 #ifdef use_aliroot
408           digits=(AliL3DigitRowData *)fMemHandler[i]->AliAltroDigits2Memory(ndigits,eventnr);
409 #else
410           cerr<<"You cannot read from rootfile now"<<endl;
411 #endif
412         }
413
414       //set input data and init transformer
415       fHoughTransformer[i]->SetInputData(ndigits,digits);
416       fHoughTransformer[i]->Init(slice,i,fNEtaSegments);
417     }
418 }
419
420 void AliL3Hough::Transform(Int_t *row_range)
421 {
422   //Transform all data given to the transformer within the given slice
423   //(after ReadData(slice))
424   
425   Double_t initTime,cpuTime;
426   initTime = GetCpuTime();
427   for(Int_t i=0; i<fNPatches; i++)
428     {
429       fHoughTransformer[i]->Reset();//Reset the histograms
430       fBenchmark->Start("Hough Transform");
431       if(!row_range)
432         fHoughTransformer[i]->TransformCircle();
433       else
434         fHoughTransformer[i]->TransformCircleC(row_range,1);
435       fBenchmark->Stop("Hough Transform");
436     }
437   cpuTime = GetCpuTime() - initTime;
438   LOG(AliL3Log::kInformational,"AliL3Hough::Transform()","Timing")
439     <<"Transform done in average per patch of "<<cpuTime*1000/fNPatches<<" ms"<<ENDLOG;
440 }
441
442 void AliL3Hough::MergePatches()
443 {
444   if(fAddHistograms) //Nothing to merge here
445     return;
446   fMerger->MergePatches(kTRUE);
447 }
448
449 void AliL3Hough::MergeInternally()
450 {
451   if(fAddHistograms)
452     fInterMerger->FillTracks(fTracks[0]);
453   else
454     fInterMerger->FillTracks(fMerger->GetOutTracks());
455   
456   fInterMerger->MMerge();
457 }
458
459 void AliL3Hough::ProcessSliceIter()
460 {
461   //Process current slice (after ReadData(slice)) iteratively.
462   
463   if(!fAddHistograms)
464     {
465       for(Int_t i=0; i<fNPatches; i++)
466         {
467           ProcessPatchIter(i);
468           fMerger->FillTracks(fTracks[i],i); //Copy tracks to merger
469         }
470     }
471   else
472     {
473       for(Int_t i=0; i<10; i++)
474         {
475           Transform();
476           AddAllHistograms();
477           InitEvaluate();
478           AliL3HoughBaseTransformer *tr = fHoughTransformer[0];
479           for(Int_t j=0; j<fNEtaSegments; j++)
480             {
481               AliL3Histogram *hist = tr->GetHistogram(j);
482               if(hist->GetNEntries()==0) continue;
483               fPeakFinder->Reset();
484               fPeakFinder->SetHistogram(hist);
485               fPeakFinder->FindAbsMaxima();
486               AliL3HoughTrack *track = (AliL3HoughTrack*)fTracks[0]->NextTrack();
487               track->SetTrackParameters(fPeakFinder->GetXPeak(0),fPeakFinder->GetYPeak(0),fPeakFinder->GetWeight(0));
488               track->SetEtaIndex(j);
489               track->SetEta(tr->GetEta(j,fCurrentSlice));
490               for(Int_t k=0; k<fNPatches; k++)
491                 {
492                   fEval[i]->SetNumOfPadsToLook(2);
493                   fEval[i]->SetNumOfRowsToMiss(2);
494                   fEval[i]->RemoveFoundTracks();
495                   /*
496                   Int_t nrows=0;
497                   if(!fEval[i]->LookInsideRoad(track,nrows))
498                     {
499                       fTracks[0]->Remove(fTracks[0]->GetNTracks()-1);
500                       fTracks[0]->Compress();
501                     }
502                   */
503                 }
504             }
505           
506         }
507       
508     }
509 }
510
511 void AliL3Hough::ProcessPatchIter(Int_t patch)
512 {
513   //Process patch in a iterative way. 
514   //transform + peakfinding + evaluation + transform +...
515
516   Int_t num_of_tries = 5;
517   AliL3HoughBaseTransformer *tr = fHoughTransformer[patch];
518   AliL3TrackArray *tracks = fTracks[patch];
519   tracks->Reset();
520   AliL3HoughEval *ev = fEval[patch];
521   ev->InitTransformer(tr);
522   //ev->RemoveFoundTracks();
523   ev->SetNumOfRowsToMiss(3);
524   ev->SetNumOfPadsToLook(2);
525   AliL3Histogram *hist;
526   for(Int_t t=0; t<num_of_tries; t++)
527     {
528       tr->Reset();
529       tr->TransformCircle();
530       for(Int_t i=0; i<fNEtaSegments; i++)
531         {
532           hist = tr->GetHistogram(i);
533           if(hist->GetNEntries()==0) continue;
534           fPeakFinder->Reset();
535           fPeakFinder->SetHistogram(hist);
536           fPeakFinder->FindAbsMaxima();
537           //fPeakFinder->FindPeak1();
538           AliL3HoughTrack *track = (AliL3HoughTrack*)tracks->NextTrack();
539           track->SetTrackParameters(fPeakFinder->GetXPeak(0),fPeakFinder->GetYPeak(0),fPeakFinder->GetWeight(0));
540           track->SetEtaIndex(i);
541           track->SetEta(tr->GetEta(i,fCurrentSlice));
542           /*
543           Int_t nrows=0;
544           if(!ev->LookInsideRoad(track,nrows))
545             {   
546               tracks->Remove(tracks->GetNTracks()-1);
547               tracks->Compress();
548             }
549           */
550         }
551     }
552   fTracks[0]->QSort();
553   LOG(AliL3Log::kInformational,"AliL3Hough::ProcessPatch","NTracks")
554     <<AliL3Log::kDec<<"Found "<<tracks->GetNTracks()<<" tracks in patch "<<patch<<ENDLOG;
555 }
556
557 void AliL3Hough::AddAllHistograms()
558 {
559   //Add the histograms within one etaslice.
560   //Resulting histogram are in patch=0.
561
562   Double_t initTime,cpuTime;
563   initTime = GetCpuTime();
564   fBenchmark->Start("Add Histograms");
565   for(Int_t i=0; i<fNEtaSegments; i++)
566     {
567       AliL3Histogram *hist0 = fHoughTransformer[0]->GetHistogram(i);
568       for(Int_t j=1; j<fNPatches; j++)
569         {
570           AliL3Histogram *hist = fHoughTransformer[j]->GetHistogram(i);
571           hist0->Add(hist);
572         }
573     }
574   fBenchmark->Stop("Add Histograms");
575   fAddHistograms = kTRUE;
576   cpuTime = GetCpuTime() - initTime;
577   LOG(AliL3Log::kInformational,"AliL3Hough::AddAllHistograms()","Timing")
578     <<"Adding histograms in "<<cpuTime*1000<<" ms"<<ENDLOG;
579 }
580
581 void AliL3Hough::AddTracks()
582 {
583   if(!fTracks[0])
584     {
585       cerr<<"AliL3Hough::AddTracks : No tracks"<<endl;
586       return;
587     }
588   AliL3TrackArray *tracks = fTracks[0];
589   for(Int_t i=0; i<tracks->GetNTracks(); i++)
590     {
591       AliL3Track *track = tracks->GetCheckedTrack(i);
592       if(!track) continue;
593       if(track->GetNHits()!=1) cerr<<"NHITS "<<track->GetNHits()<<endl;
594       UInt_t *ids = track->GetHitNumbers();
595       ids[0] = (fCurrentSlice&0x7f)<<25;
596     }
597   
598   fGlobalTracks->AddTracks(fTracks[0],0,fCurrentSlice);
599 }
600
601 void AliL3Hough::FindTrackCandidates()
602 {
603   //Look for peaks in histograms, and find the track candidates
604   
605   Int_t n_patches;
606   if(fAddHistograms)
607     n_patches = 1; //Histograms have been added.
608   else
609     n_patches = fNPatches;
610   
611   Double_t initTime,cpuTime;
612   initTime = GetCpuTime();
613   fBenchmark->Start("Find Maxima");
614   for(Int_t i=0; i<n_patches; i++)
615     {
616       AliL3HoughBaseTransformer *tr = fHoughTransformer[i];
617       fTracks[i]->Reset();
618       
619       for(Int_t j=0; j<fNEtaSegments; j++)
620         {
621           AliL3Histogram *hist = tr->GetHistogram(j);
622           if(hist->GetNEntries()==0) continue;
623           fPeakFinder->Reset();
624           fPeakFinder->SetHistogram(hist);
625
626           fPeakFinder->SetThreshold(fPeakThreshold[i]);
627           fPeakFinder->FindAdaptedPeaks(6,0.5);
628
629           //fPeakFinder->FindMaxima(fPeakThreshold[i]); //Simple maxima finder
630           
631           for(Int_t k=0; k<fPeakFinder->GetEntries(); k++)
632             {
633               AliL3HoughTrack *track = (AliL3HoughTrack*)fTracks[i]->NextTrack();
634               track->SetTrackParameters(fPeakFinder->GetXPeak(k),fPeakFinder->GetYPeak(k),fPeakFinder->GetWeight(k));
635               track->SetEtaIndex(j);
636               track->SetEta(tr->GetEta(j,fCurrentSlice));
637               track->SetRowRange(AliL3Transform::GetFirstRow(0),AliL3Transform::GetLastRow(5));
638             }
639         }
640       cout<<"Found "<<fTracks[i]->GetNTracks()<<" tracks in patch "<<i<<endl;
641       fTracks[i]->QSort();
642     }
643   fBenchmark->Stop("Find Maxima");
644   cpuTime = GetCpuTime() - initTime;
645   LOG(AliL3Log::kInformational,"AliL3Hough::FindTrackCandidates()","Timing")
646     <<"Maxima finding done in "<<cpuTime*1000<<" ms"<<ENDLOG;
647 }
648
649 void AliL3Hough::InitEvaluate()
650 {
651   //Pass the transformer objects to the AliL3HoughEval objects:
652   //This will provide the evaluation objects with all the necessary
653   //data and parameters it needs.
654   
655   for(Int_t i=0; i<fNPatches; i++) 
656     fEval[i]->InitTransformer(fHoughTransformer[i]);
657 }
658
659 Int_t AliL3Hough::Evaluate(Int_t road_width,Int_t nrowstomiss)
660 {
661   //Evaluate the tracks, by looking along the road in the raw data.
662   //If track does not cross all padrows - rows2miss, it is removed from the arrray.
663   //If histograms were not added, the check is done locally in patch,
664   //meaning that nrowstomiss is the number of padrows the road can miss with respect
665   //to the number of rows in the patch.
666   //If the histograms were added, the comparison is done globally in the _slice_, 
667   //meaing that nrowstomiss is the number of padrows the road can miss with
668   //respect to the total number of padrows in the slice.
669   //
670   //Return value = number of tracks which were removed (only in case of fAddHistograms)
671   
672   if(!fTracks[0])
673     {
674       LOG(AliL3Log::kError,"AliL3Hough::Evaluate","Track Array")
675         <<"No tracks to work with..."<<ENDLOG;
676       return 0;
677     }
678   
679   Int_t removed_tracks=0;
680   AliL3TrackArray *tracks=0;
681
682   if(fAddHistograms)
683     {
684       tracks = fTracks[0];
685       for(Int_t i=0; i<tracks->GetNTracks(); i++)
686         {
687           AliL3Track *track = tracks->GetCheckedTrack(i);
688           if(!track) continue;
689           track->SetNHits(0);
690         }
691     }
692   
693   for(Int_t i=0; i<fNPatches; i++)
694     EvaluatePatch(i,road_width,nrowstomiss);
695   
696   //Here we check the tracks globally; 
697   //how many good rows (padrows with signal) 
698   //did it cross in the slice
699   if(fAddHistograms) 
700     {
701       for(Int_t j=0; j<tracks->GetNTracks(); j++)
702         {
703           AliL3HoughTrack *track = (AliL3HoughTrack*)tracks->GetCheckedTrack(j);
704           
705           if(track->GetNHits() < AliL3Transform::GetNRows() - nrowstomiss)
706             {
707               tracks->Remove(j);
708               removed_tracks++;
709             }
710         }
711       tracks->Compress();
712       tracks->QSort();
713     }
714     
715   return removed_tracks;
716 }
717
718 void AliL3Hough::EvaluatePatch(Int_t i,Int_t road_width,Int_t nrowstomiss)
719 {
720   //Evaluate patch i.
721   
722   fEval[i]->InitTransformer(fHoughTransformer[i]);
723   fEval[i]->SetNumOfPadsToLook(road_width);
724   fEval[i]->SetNumOfRowsToMiss(nrowstomiss);
725   //fEval[i]->RemoveFoundTracks();
726   
727   AliL3TrackArray *tracks=0;
728   
729   if(!fAddHistograms)
730     tracks = fTracks[i];
731   else
732     tracks = fTracks[0];
733   
734   Int_t nrows=0;
735   for(Int_t j=0; j<tracks->GetNTracks(); j++)
736     {
737       AliL3HoughTrack *track = (AliL3HoughTrack*)tracks->GetCheckedTrack(j);
738       if(!track)
739         {
740           LOG(AliL3Log::kWarning,"AliL3Hough::EvaluatePatch","Track array")
741             <<"Track object missing!"<<ENDLOG;
742           continue;
743         } 
744       nrows=0;
745       Int_t rowrange[2] = {AliL3Transform::GetFirstRow(i),AliL3Transform::GetLastRow(i)};
746       Bool_t result = fEval[i]->LookInsideRoad(track,nrows,rowrange);
747       if(fAddHistograms)
748         {
749           Int_t pre=track->GetNHits();
750           track->SetNHits(pre+nrows);
751         }
752       else//the track crossed too few good padrows (padrows with signal) in the patch, so remove it
753         {
754           if(result == kFALSE)
755             tracks->Remove(j);
756         }
757     }
758   
759   tracks->Compress();
760
761 }
762
763 void AliL3Hough::MergeEtaSlices()
764 {
765   //Merge tracks found in neighbouring eta slices.
766   //Removes the track with the lower weight.
767   
768   fBenchmark->Start("Merge Eta-slices");
769   AliL3TrackArray *tracks = fTracks[0];
770   if(!tracks)
771     {
772       cerr<<"AliL3Hough::MergeEtaSlices : No tracks "<<endl;
773       return;
774     }
775   for(Int_t j=0; j<tracks->GetNTracks(); j++)
776     {
777       AliL3HoughTrack *track1 = (AliL3HoughTrack*)tracks->GetCheckedTrack(j);
778       if(!track1) continue;
779       for(Int_t k=j+1; k<tracks->GetNTracks(); k++)
780         {
781           AliL3HoughTrack *track2 = (AliL3HoughTrack*)tracks->GetCheckedTrack(k);
782           if(!track2) continue;
783           if(abs(track1->GetEtaIndex() - track2->GetEtaIndex()) != 1) continue;
784           if(fabs(track1->GetKappa()-track2->GetKappa()) < 0.006 && 
785              fabs(track1->GetPsi()- track2->GetPsi()) < 0.1)
786             {
787               //cout<<"Merging track in slices "<<track1->GetEtaIndex()<<" "<<track2->GetEtaIndex()<<endl;
788               if(track1->GetWeight() > track2->GetWeight())
789                 tracks->Remove(k);
790               else
791                 tracks->Remove(j);
792             }
793         }
794     }
795   fBenchmark->Stop("Merge Eta-slices");
796   tracks->Compress();
797 }
798
799 void AliL3Hough::WriteTracks(Char_t *path)
800 {
801   //cout<<"AliL3Hough::WriteTracks : Sorting the tracsk"<<endl;
802   //fGlobalTracks->QSort();
803   
804   Char_t filename[1024];
805   sprintf(filename,"%s/tracks_%d.raw",path,fEvent);
806   AliL3MemHandler mem;
807   mem.SetBinaryOutput(filename);
808   mem.TrackArray2Binary(fGlobalTracks);
809   mem.CloseBinaryOutput();
810   fGlobalTracks->Reset();
811 }
812
813 void AliL3Hough::WriteTracks(Int_t slice,Char_t *path)
814 {
815   
816   AliL3MemHandler mem;
817   Char_t fname[100];
818   if(fAddHistograms)
819     {
820       sprintf(fname,"%s/tracks_ho_%d_%d.raw",path,fEvent,slice);
821       mem.SetBinaryOutput(fname);
822       mem.TrackArray2Binary(fTracks[0]);
823       mem.CloseBinaryOutput();
824     }
825   else 
826     {
827       for(Int_t i=0; i<fNPatches; i++)
828         {
829           sprintf(fname,"%s/tracks_ho_%d_%d_%d.raw",path,fEvent,slice,i);
830           mem.SetBinaryOutput(fname);
831           mem.TrackArray2Binary(fTracks[i]);
832           mem.CloseBinaryOutput();
833         }
834     }
835 }
836
837 void AliL3Hough::WriteDigits(Char_t *outfile)
838 {
839 #ifdef use_aliroot  
840   //Write the current data to a new rootfile.
841
842   for(Int_t i=0; i<fNPatches; i++)
843     {
844       AliL3DigitRowData *tempPt = (AliL3DigitRowData*)fHoughTransformer[i]->GetDataPointer();
845       fMemHandler[i]->AliDigits2RootFile(tempPt,outfile);
846     }
847 #else
848   cerr<<"AliL3Hough::WriteDigits : You need to compile with AliROOT!"<<endl;
849   return;
850 #endif  
851 }
852
853 Double_t AliL3Hough::GetCpuTime()
854 {
855   //Return the Cputime in seconds.
856  struct timeval tv;
857  gettimeofday( &tv, NULL );
858  return tv.tv_sec+(((Double_t)tv.tv_usec)/1000000.);
859 }
860