3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ASV
10 #include "AliL3HoughMerger.h"
11 #include "AliL3HoughIntMerger.h"
12 #include "AliL3HoughGlobalMerger.h"
13 #include "AliL3Logging.h"
14 #include "AliL3Histogram.h"
15 #include "AliL3Hough.h"
16 #include "AliL3HoughTransformer.h"
17 #include "AliL3HoughTransformerVhdl.h"
18 #include "AliL3HoughMaxFinder.h"
20 #include "AliL3FileHandler.h"
22 #include "AliL3MemHandler.h"
24 #include "AliL3DataHandler.h"
25 #include "AliL3DigitData.h"
26 #include "AliL3HoughEval.h"
27 #include "AliL3Transform.h"
28 #include "AliL3TrackArray.h"
29 #include "AliL3HoughTrack.h"
32 //_____________________________________________________________
35 // Interface class for the Hough transform
37 // Example how to use:
39 // AliL3Hough *hough = new AliL3Hough(path,kTRUE,NumberOfEtaSegments);
40 // hough->ReadData(slice);
41 // hough->Transform();
42 // hough->FindTrackCandidates();
44 // AliL3TrackArray *tracks = hough->GetTracks(patch);
48 AliL3Hough::AliL3Hough()
53 fAddHistograms = kFALSE;
54 fDoIterative = kFALSE;
55 fWriteDigits = kFALSE;
59 fHoughTransformer = 0;
72 SetTransformerParams();
76 AliL3Hough::AliL3Hough(Char_t *path,Bool_t binary,Int_t n_eta_segments,Bool_t bit8=kFALSE,Int_t tv=0)
82 fNEtaSegments = n_eta_segments;
83 fAddHistograms = kFALSE;
84 fDoIterative = kFALSE;
85 fWriteDigits = kFALSE;
90 AliL3Hough::~AliL3Hough()
102 delete fGlobalMerger;
105 void AliL3Hough::CleanUp()
109 for(Int_t i=0; i<fNPatches; i++)
111 if(fTracks[i]) delete fTracks[i];
112 if(fEval[i]) delete fEval[i];
113 if(fHoughTransformer[i]) delete fHoughTransformer[i];
114 if(fMemHandler[i]) delete fMemHandler[i];
118 if(fTracks) delete [] fTracks;
119 if(fEval) delete [] fEval;
120 if(fHoughTransformer) delete [] fHoughTransformer;
121 if(fMemHandler) delete [] fMemHandler;
125 void AliL3Hough::Init(Char_t *path,Bool_t binary,Int_t n_eta_segments,Bool_t bit8=kFALSE,Int_t tv=0)
129 fNEtaSegments = n_eta_segments;
130 fWriteDigits = kFALSE;
134 Init(); //do the rest
137 void AliL3Hough::Init(Bool_t doit=kFALSE, Bool_t addhists=kFALSE){
139 fAddHistograms = addhists;
141 AliL3Transform::Init(fPath);
142 fNPatches = AliL3Transform::GetNPatches();
144 fHoughTransformer = new AliL3HoughBaseTransformer*[fNPatches];
145 fMemHandler = new AliL3MemHandler*[fNPatches];
146 fTracks = new AliL3TrackArray*[fNPatches];
147 fEval = new AliL3HoughEval*[fNPatches];
149 for(Int_t i=0; i<fNPatches; i++)
151 switch (fVersion){ //choose Transformer
153 fHoughTransformer[i] = new AliL3HoughTransformerVhdl(1,i,fNEtaSegments);
156 fHoughTransformer[i] = new AliL3HoughTransformer(1,i,fNEtaSegments);
159 fHoughTransformer[i]->CreateHistograms(fNBinX,fLowPt,fNBinY,-fPhi,fPhi);
160 fHoughTransformer[i]->SetLowerThreshold(fThreshold);
162 LOG(AliL3Log::kInformational,"AliL3Hough::Init","Version")
163 <<"Initializing Hough transformer version "<<fVersion<<ENDLOG;
165 fEval[i] = new AliL3HoughEval();
166 fTracks[i] = new AliL3TrackArray("AliL3HoughTrack");
168 fMemHandler[i] = new AliL3DataHandler();
172 fMemHandler[i] = new AliL3FileHandler();
175 Char_t filename[100];
176 sprintf(filename,"%s/digitfile",fPath);
177 fMemHandler[i]->SetAliInput(filename);
181 fMemHandler[i] = new AliL3MemHandler();
185 fPeakFinder = new AliL3HoughMaxFinder("KappaPhi",100);
186 fMerger = new AliL3HoughMerger(fNPatches);
187 fInterMerger = new AliL3HoughIntMerger();
191 void AliL3Hough::Process(Int_t minslice,Int_t maxslice)
193 //Process all slices [minslice,maxslice].
194 fGlobalMerger = new AliL3HoughGlobalMerger(minslice,maxslice);
196 for(Int_t i=minslice; i<=maxslice; i++)
202 FindTrackCandidates();
204 fGlobalMerger->FillTracks(fTracks[0],i);
208 void AliL3Hough::ReadData(Int_t slice,Int_t eventnr=0)
210 //Read data from files, binary or root.
212 fCurrentSlice = slice;
213 for(Int_t i=0; i<fNPatches; i++)
215 fMemHandler[i]->Free();
217 AliL3DigitRowData *digits =0;
219 fMemHandler[i]->Init(slice,i);
220 if(fBinary)//take input data from binary files
223 sprintf(name,"%sdigits_c8_%d_%d.raw",fPath,slice,i);
225 sprintf(name,"%sdigits_%d_%d.raw",fPath,slice,i);
226 fMemHandler[i]->SetBinaryInput(name);
227 digits = (AliL3DigitRowData *)fMemHandler[i]->CompBinary2Memory(ndigits);
228 fMemHandler[i]->CloseBinaryInput();
230 else //read data from root file
233 digits=(AliL3DigitRowData *)fMemHandler[i]->AliDigits2Memory(ndigits,eventnr);
234 fMemHandler[i]->FreeDigitsTree();
236 cerr<<"You cannot read from rootfile now"<<endl;
239 fHoughTransformer[i]->SetInputData(ndigits,digits);
243 void AliL3Hough::Transform(Int_t row_range=-1)
245 //Transform all data given to the transformer within the given slice
246 //(after ReadData(slice))
248 Double_t initTime,cpuTime;
249 initTime = GetCpuTime();
250 for(Int_t i=0; i<fNPatches; i++)
252 fHoughTransformer[i]->Reset();//Reset the histograms
254 fHoughTransformer[i]->TransformCircle();
256 fHoughTransformer[i]->TransformCircleC(row_range);
258 cpuTime = GetCpuTime() - initTime;
259 LOG(AliL3Log::kInformational,"AliL3Hough::Transform()","Timing")
260 <<"Transform done in average per patch of "<<cpuTime*1000/fNPatches<<" ms"<<ENDLOG;
263 void AliL3Hough::MergePatches()
265 if(fAddHistograms) //Nothing to merge here
267 fMerger->MergePatches(kTRUE);
270 void AliL3Hough::MergeInternally()
273 fInterMerger->FillTracks(fTracks[0]);
275 fInterMerger->FillTracks(fMerger->GetOutTracks());
277 fInterMerger->MMerge();
280 void AliL3Hough::ProcessSliceIter()
282 //Process current slice (after ReadData(slice)) iteratively.
284 for(Int_t i=0; i<fNPatches; i++)
287 fMerger->FillTracks(fTracks[i],i); //Copy tracks to merger
291 void AliL3Hough::ProcessPatchIter(Int_t patch)
293 //Process patch in a iterative way.
294 //transform + peakfinding + evaluation + transform +...
296 Int_t num_of_tries = 10;
297 AliL3HoughBaseTransformer *tr = fHoughTransformer[patch];
298 AliL3TrackArray *tracks = fTracks[patch];
300 AliL3HoughEval *ev = fEval[patch];
301 ev->InitTransformer(tr);
302 ev->RemoveFoundTracks();
303 ev->SetNumOfRowsToMiss(2);
304 ev->SetNumOfPadsToLook(2);
305 AliL3Histogram *hist;
306 for(Int_t t=0; t<num_of_tries; t++)
309 tr->TransformCircle();
310 for(Int_t i=0; i<fNEtaSegments; i++)
312 hist = tr->GetHistogram(i);
313 if(hist->GetNEntries()==0) continue;
314 fPeakFinder->SetHistogram(hist);
317 //fPeakFinder->FindAbsMaxima(*x,*y);
318 fPeakFinder->FindPeak(3,0.95,5,x,y);
319 AliL3HoughTrack *track = (AliL3HoughTrack*)tracks->NextTrack();
320 track->SetTrackParameters(x,y,1);
321 if(!ev->LookInsideRoad(track,i))
323 tracks->Remove(tracks->GetNTracks()-1);
328 LOG(AliL3Log::kInformational,"AliL3Hough::ProcessPatch","NTracks")
329 <<AliL3Log::kDec<<"Found "<<tracks->GetNTracks()<<" tracks in patch "<<patch<<ENDLOG;
332 void AliL3Hough::AddAllHistograms()
334 //Add the histograms within one etaslice.
335 //Resulting histogram are in patch=0.
337 Double_t initTime,cpuTime;
338 initTime = GetCpuTime();
339 for(Int_t i=0; i<fNEtaSegments; i++)
341 AliL3Histogram *hist0 = fHoughTransformer[0]->GetHistogram(i);
342 for(Int_t j=1; j<fNPatches; j++)
344 AliL3Histogram *hist = fHoughTransformer[j]->GetHistogram(i);
348 fAddHistograms = kTRUE;
349 cpuTime = GetCpuTime() - initTime;
350 LOG(AliL3Log::kInformational,"AliL3Hough::AddAllHistograms()","Timing")
351 <<"Adding histograms in "<<cpuTime*1000<<" ms"<<ENDLOG;
354 void AliL3Hough::FindTrackCandidates()
356 //Look for peaks in histograms, and find the track candidates
360 n_patches = 1; //Histograms have been added.
362 n_patches = fNPatches;
364 Double_t initTime,cpuTime;
365 initTime = GetCpuTime();
367 for(Int_t i=0; i<n_patches; i++)
369 AliL3HoughBaseTransformer *tr = fHoughTransformer[i];
370 Double_t eta_slice = (tr->GetEtaMax()-tr->GetEtaMin())/tr->GetNEtaSegments();
373 for(Int_t j=0; j<fNEtaSegments; j++)
375 AliL3Histogram *hist = tr->GetHistogram(j);
376 if(hist->GetNEntries()==0) continue;
377 fPeakFinder->Reset();
378 fPeakFinder->SetHistogram(hist);
379 fPeakFinder->FindMaxima(0,0); //Simple maxima finder
380 //fPeakFinder->FindAbsMaxima();
382 for(Int_t k=0; k<fPeakFinder->GetEntries(); k++)
384 if(fPeakFinder->GetWeight(k) == 0) continue;
385 AliL3HoughTrack *track = (AliL3HoughTrack*)fTracks[i]->NextTrack();
386 track->SetTrackParameters(fPeakFinder->GetXPeak(k),fPeakFinder->GetYPeak(k),fPeakFinder->GetWeight(k));
387 track->SetEtaIndex(j);
388 Double_t eta = (Double_t)((j+0.5)*eta_slice);
389 if(fCurrentSlice > 17) eta*=-1;
391 track->SetRowRange(AliL3Transform::GetFirstRow(0),AliL3Transform::GetLastRow(5));
396 cpuTime = GetCpuTime() - initTime;
397 LOG(AliL3Log::kInformational,"AliL3Hough::FindTrackCandidates()","Timing")
398 <<"Maxima finding done in "<<cpuTime*1000<<" ms"<<ENDLOG;
401 void AliL3Hough::InitEvaluate()
403 //Pass the transformer objects to the AliL3HoughEval objects:
404 //This will provide the evaluation objects with all the necessary
405 //data and parameters it needs.
407 for(Int_t i=0; i<fNPatches; i++)
408 fEval[i]->InitTransformer(fHoughTransformer[i]);
411 Int_t AliL3Hough::Evaluate(Int_t road_width,Int_t nrowstomiss)
413 //Evaluate the tracks, by looking along the road in the raw data.
414 //If track does not cross all padrows - rows2miss, it is removed from the arrray.
415 //If histograms were not added, the check is done locally in patch,
416 //meaning that nrowstomiss is the number of padrows the road can miss with respect
417 //to the number of rows in the patch.
418 //If the histograms were added, the comparison is done globally in the _slice_,
419 //meaing that nrowstomiss is the number of padrows the road can miss with
420 //respect to the total number of padrows in the slice.
422 //Return value = number of tracks which were removed (only in case of fAddHistograms)
426 LOG(AliL3Log::kError,"AliL3Hough::Evaluate","Track Array")
427 <<"No tracks to work with..."<<ENDLOG;
433 Int_t removed_tracks=0;
434 AliL3TrackArray *tracks=0;
439 total_rows = new Int_t[tracks->GetNTracks()];
440 for(Int_t i=0; i<tracks->GetNTracks(); i++)
444 for(Int_t i=0; i<fNPatches; i++)
446 fEval[i]->InitTransformer(fHoughTransformer[i]);
447 fEval[i]->SetNumOfPadsToLook(road_width);
448 fEval[i]->SetNumOfRowsToMiss(nrowstomiss);
452 for(Int_t j=0; j<tracks->GetNTracks(); j++)
454 AliL3HoughTrack *track = (AliL3HoughTrack*)tracks->GetCheckedTrack(j);
457 LOG(AliL3Log::kWarning,"AliL3Hough::Evaluate","Track array")
458 <<"Track object missing!"<<ENDLOG;
462 Bool_t result = fEval[i]->LookInsideRoad(track,total_rows[j]);
463 if(!fAddHistograms)//the track crossed too few good padrows (padrows with signal) in the patch, so remove it
473 fMerger->FillTracks(tracks,i); //Copy tracks to the track merger
477 if(fAddHistograms) //Here we check the tracks globally; how many good rows (padrows with signal) did it cross in the slice
479 for(Int_t j=0; j<tracks->GetNTracks(); j++)
481 if(total_rows[j] < AliL3Transform::GetNRows() - nrowstomiss)
492 delete [] total_rows;
494 return removed_tracks;
497 void AliL3Hough::EvaluateWithEta()
503 printf("AliL3Hough::EvaluateWithEta: NO TRACKS\n");
506 printf("Number of tracks before evaluation %d\n",fTracks[0]->GetNTracks());
508 for(Int_t i=0; i<fNPatches; i++)
510 fEval[i]->InitTransformer(fHoughTransformer[i]);
511 fEval[i]->FindEta(fTracks[0]);
513 fMerger->FillTracks(fTracks[0],0);
516 void AliL3Hough::WriteTracks(Int_t slice,Char_t *path)
518 //Write the tracks in slice
520 AliL3MemHandler *mem = new AliL3MemHandler();
524 sprintf(fname,"%s/tracks_ho_%d.raw",path,slice);
525 mem->SetBinaryOutput(fname);
526 mem->TrackArray2Binary(fTracks[0]);
527 mem->CloseBinaryOutput();
531 for(Int_t i=0; i<fNPatches; i++)
533 sprintf(fname,"%s/tracks_ho_%d_%d.raw",path,slice,i);
534 mem->SetBinaryOutput(fname);
535 mem->TrackArray2Binary(fTracks[i]);
536 mem->CloseBinaryOutput();
543 void AliL3Hough::WriteDigits(Char_t *outfile)
546 //Write the current data to a new rootfile.
548 for(Int_t i=0; i<fNPatches; i++)
550 AliL3DigitRowData *tempPt = (AliL3DigitRowData*)fHoughTransformer[i]->GetDataPointer();
551 fMemHandler[i]->AliDigits2RootFile(tempPt,outfile);
554 cerr<<"AliL3Hough::WriteDigits : You need to compile with AliROOT!"<<endl;
559 Double_t AliL3Hough::GetCpuTime()
561 //Return the Cputime in seconds.
563 gettimeofday( &tv, NULL );
564 return tv.tv_sec+(((Double_t)tv.tv_usec)/1000000.);
565 //return (Double_t)(clock()) / CLOCKS_PER_SEC;