4 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
5 //*-- Copyright © ALICE HLT Group
7 #include "AliL3StandardIncludes.h"
9 #include "AliL3Logging.h"
10 #include "AliL3MemHandler.h"
11 #include "AliL3Transform.h"
12 #include "AliL3DigitData.h"
13 #include "AliL3HistogramAdaptive.h"
14 #include "AliL3HoughTrack.h"
15 #include "AliL3HoughTransformerRow.h"
21 //_____________________________________________________________
22 // AliL3HoughTransformerRow
24 // TPC rows Hough transformation class
27 ClassImp(AliL3HoughTransformerRow)
29 Float_t AliL3HoughTransformerRow::fgBeta1 = 1.0/AliL3Transform::Row2X(79);
30 Float_t AliL3HoughTransformerRow::fgBeta2 = 1.0/(AliL3Transform::Row2X(158)*(1.0+tan(AliL3Transform::Pi()*10/180)*tan(AliL3Transform::Pi()*10/180)));
32 AliL3HoughTransformerRow::AliL3HoughTransformerRow()
61 AliL3HoughTransformerRow::AliL3HoughTransformerRow(Int_t slice,Int_t patch,Int_t netasegments,Bool_t /*DoMC*/,Float_t zvertex) : AliL3HoughBaseTransformer(slice,patch,netasegments,zvertex)
91 AliL3HoughTransformerRow::~AliL3HoughTransformerRow()
95 if(fLastTransformer) return;
99 for(Int_t i=0; i<GetNEtaSegments(); i++)
101 if(!fTrackID[i]) continue;
111 for(Int_t i=0; i<GetNEtaSegments(); i++)
113 if(!fGapCount[i]) continue;
114 delete [] fGapCount[i];
121 for(Int_t i=0; i<GetNEtaSegments(); i++)
123 if(fCurrentRowCount[i])
124 delete [] fCurrentRowCount[i];
126 delete [] fCurrentRowCount;
127 fCurrentRowCount = 0;
131 delete [] fTrackNRows;
136 delete [] fTrackFirstRow;
141 delete [] fTrackLastRow;
146 delete [] fInitialGapCount;
147 fInitialGapCount = 0;
151 for(Int_t i=0; i<GetNEtaSegments(); i++)
153 if(!fPrevBin[i]) continue;
154 delete [] fPrevBin[i];
161 for(Int_t i=0; i<GetNEtaSegments(); i++)
163 if(!fNextBin[i]) continue;
164 delete [] fNextBin[i];
171 for(Int_t i=0; i<GetNEtaSegments(); i++)
173 if(!fNextRow[i]) continue;
174 delete [] fNextRow[i];
181 for(Int_t i = AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
183 if(!fStartPadParams[i]) continue;
184 delete [] fStartPadParams[i];
186 delete [] fStartPadParams;
191 for(Int_t i = AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
193 if(!fEndPadParams[i]) continue;
194 delete [] fEndPadParams[i];
196 delete [] fEndPadParams;
201 for(Int_t i = AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
203 if(!fLUTr2[i]) continue;
211 delete[] fLUTforwardZ;
216 delete[] fLUTforwardZ2;
221 delete[] fLUTbackwardZ;
226 delete[] fLUTbackwardZ2;
231 void AliL3HoughTransformerRow::DeleteHistograms()
236 for(Int_t i=0; i<GetNEtaSegments(); i++)
238 if(!fParamSpace[i]) continue;
239 delete fParamSpace[i];
241 delete [] fParamSpace;
244 struct AliL3TrackLength {
251 void AliL3HoughTransformerRow::CreateHistograms(Int_t nxbin,Float_t xmin,Float_t xmax,
252 Int_t nybin,Float_t ymin,Float_t ymax)
254 //Create the histograms (parameter space)
257 //xmin xmax ymin ymax = histogram limits in X and Y
258 fParamSpace = new AliL3Histogram*[GetNEtaSegments()];
260 Char_t histname[256];
261 for(Int_t i=0; i<GetNEtaSegments(); i++)
263 sprintf(histname,"paramspace_%d",i);
264 fParamSpace[i] = new AliL3Histogram(histname,"",nxbin,xmin,xmax,nybin,ymin,ymax);
267 if(fLastTransformer) {
269 fGapCount = ((AliL3HoughTransformerRow *)fLastTransformer)->fGapCount;
270 fCurrentRowCount = ((AliL3HoughTransformerRow *)fLastTransformer)->fCurrentRowCount;
272 fTrackID = ((AliL3HoughTransformerRow *)fLastTransformer)->fTrackID;
274 fTrackNRows = ((AliL3HoughTransformerRow *)fLastTransformer)->fTrackNRows;
275 fTrackFirstRow = ((AliL3HoughTransformerRow *)fLastTransformer)->fTrackFirstRow;
276 fTrackLastRow = ((AliL3HoughTransformerRow *)fLastTransformer)->fTrackLastRow;
277 fInitialGapCount = ((AliL3HoughTransformerRow *)fLastTransformer)->fInitialGapCount;
279 fPrevBin = ((AliL3HoughTransformerRow *)fLastTransformer)->fPrevBin;
280 fNextBin = ((AliL3HoughTransformerRow *)fLastTransformer)->fNextBin;
281 fNextRow = ((AliL3HoughTransformerRow *)fLastTransformer)->fNextRow;
283 fStartPadParams = ((AliL3HoughTransformerRow *)fLastTransformer)->fStartPadParams;
284 fEndPadParams = ((AliL3HoughTransformerRow *)fLastTransformer)->fEndPadParams;
285 fLUTr2 = ((AliL3HoughTransformerRow *)fLastTransformer)->fLUTr2;
286 fLUTforwardZ = ((AliL3HoughTransformerRow *)fLastTransformer)->fLUTforwardZ;
287 fLUTforwardZ2 = ((AliL3HoughTransformerRow *)fLastTransformer)->fLUTforwardZ2;
288 fLUTbackwardZ = ((AliL3HoughTransformerRow *)fLastTransformer)->fLUTbackwardZ;
289 fLUTbackwardZ2 = ((AliL3HoughTransformerRow *)fLastTransformer)->fLUTbackwardZ2;
295 AliL3Histogram *hist = fParamSpace[0];
296 Int_t ncellsx = (hist->GetNbinsX()+3)/2;
297 Int_t ncellsy = (hist->GetNbinsY()+3)/2;
298 Int_t ncells = ncellsx*ncellsy;
301 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
302 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(AliL3TrackIndex)<<" bytes to fTrackID"<<ENDLOG;
303 fTrackID = new AliL3TrackIndex*[GetNEtaSegments()];
304 for(Int_t i=0; i<GetNEtaSegments(); i++)
305 fTrackID[i] = new AliL3TrackIndex[ncells];
309 AliL3Histogram *hist = fParamSpace[0];
310 Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2);
313 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
314 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fGapCount"<<ENDLOG;
315 fGapCount = new UChar_t*[GetNEtaSegments()];
316 for(Int_t i=0; i<GetNEtaSegments(); i++)
317 fGapCount[i] = new UChar_t[ncells];
319 if(!fCurrentRowCount)
321 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
322 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fCurrentRowCount"<<ENDLOG;
323 fCurrentRowCount = new UChar_t*[GetNEtaSegments()];
324 for(Int_t i=0; i<GetNEtaSegments(); i++)
325 fCurrentRowCount[i] = new UChar_t[ncells];
329 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
330 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fPrevBin"<<ENDLOG;
331 fPrevBin = new UChar_t*[GetNEtaSegments()];
332 for(Int_t i=0; i<GetNEtaSegments(); i++)
333 fPrevBin[i] = new UChar_t[ncells];
337 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
338 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fNextBin"<<ENDLOG;
339 fNextBin = new UChar_t*[GetNEtaSegments()];
340 for(Int_t i=0; i<GetNEtaSegments(); i++)
341 fNextBin[i] = new UChar_t[ncells];
343 Int_t ncellsy = hist->GetNbinsY()+2;
346 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
347 <<"Transformer: Allocating "<<GetNEtaSegments()*ncellsy*sizeof(UChar_t)<<" bytes to fNextRow"<<ENDLOG;
348 fNextRow = new UChar_t*[GetNEtaSegments()];
349 for(Int_t i=0; i<GetNEtaSegments(); i++)
350 fNextRow[i] = new UChar_t[ncellsy];
355 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
356 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fTrackNRows"<<ENDLOG;
357 fTrackNRows = new UChar_t[ncells];
358 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
359 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fTrackFirstRow"<<ENDLOG;
360 fTrackFirstRow = new UChar_t[ncells];
361 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
362 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fTrackLastRow"<<ENDLOG;
363 fTrackLastRow = new UChar_t[ncells];
364 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
365 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fInitialGapCount"<<ENDLOG;
366 fInitialGapCount = new UChar_t[ncells];
369 AliL3HoughTrack track;
370 Int_t xmin = hist->GetFirstXbin();
371 Int_t xmax = hist->GetLastXbin();
372 Int_t xmiddle = (hist->GetNbinsX()+1)/2;
373 Int_t ymin = hist->GetFirstYbin();
374 Int_t ymax = hist->GetLastYbin();
375 Int_t nxbins = hist->GetNbinsX()+2;
376 Int_t nxgrid = (hist->GetNbinsX()+3)/2+1;
377 Int_t nygrid = hist->GetNbinsY()+3;
379 AliL3TrackLength *tracklength = new AliL3TrackLength[nxgrid*nygrid];
380 memset(tracklength,0,nxgrid*nygrid*sizeof(AliL3TrackLength));
382 for(Int_t ybin=ymin-1; ybin<=(ymax+1); ybin++)
384 for(Int_t xbin=xmin-1; xbin<=xmiddle; xbin++)
386 fTrackNRows[xbin + ybin*nxbins] = 255;
387 for(Int_t deltay = 0; deltay <= 1; deltay++) {
388 for(Int_t deltax = 0; deltax <= 1; deltax++) {
390 AliL3TrackLength *curtracklength = &tracklength[(xbin + deltax) + (ybin + deltay)*nxgrid];
391 UInt_t maxfirstrow = 0;
392 UInt_t maxlastrow = 0;
393 Float_t maxtrackpt = 0;
394 if(curtracklength->fIsFilled) {
395 maxfirstrow = curtracklength->fFirstRow;
396 maxlastrow = curtracklength->fLastRow;
397 maxtrackpt = curtracklength->fTrackPt;
400 Float_t xtrack = hist->GetPreciseBinCenterX((Float_t)xbin+0.5*(Float_t)(2*deltax-1));
401 Float_t ytrack = hist->GetPreciseBinCenterY((Float_t)ybin+0.5*(Float_t)(2*deltay-1));
403 Float_t psi = atan((xtrack-ytrack)/(fgBeta1-fgBeta2));
404 Float_t kappa = 2.0*(xtrack*cos(psi)-fgBeta1*sin(psi));
405 track.SetTrackParameters(kappa,psi,1);
406 Bool_t firstrow = kFALSE;
407 UInt_t curfirstrow = 0;
408 UInt_t curlastrow = 0;
410 Double_t centerx = track.GetCenterX();
411 Double_t centery = track.GetCenterY();
412 Double_t radius = track.GetRadius();
414 for(Int_t j=AliL3Transform::GetFirstRow(0); j<=AliL3Transform::GetLastRow(5); j++)
417 // if(!track.GetCrossingPoint(j,hit)) continue;
418 hit[0] = AliL3Transform::Row2X(j);
419 Double_t aa = (hit[0] - centerx)*(hit[0] - centerx);
420 Double_t r2 = radius*radius;
424 Double_t aa2 = sqrt(r2 - aa);
425 Double_t y1 = centery + aa2;
426 Double_t y2 = centery - aa2;
428 if(fabs(y2) < fabs(y1)) hit[1] = y2;
432 AliL3Transform::LocHLT2Raw(hit,0,j);
434 if(hit[1]>=0 && hit[1]<AliL3Transform::GetNPads(j))
445 if((curlastrow-curfirstrow) >= (maxlastrow-maxfirstrow)) {
446 maxfirstrow = curfirstrow;
447 maxlastrow = curlastrow;
452 if((curlastrow-curfirstrow) >= (maxlastrow-maxfirstrow)) {
453 maxfirstrow = curfirstrow;
454 maxlastrow = curlastrow;
457 maxtrackpt = track.GetPt();
459 curtracklength->fIsFilled = kTRUE;
460 curtracklength->fFirstRow = maxfirstrow;
461 curtracklength->fLastRow = maxlastrow;
462 curtracklength->fTrackPt = maxtrackpt;
465 if((maxlastrow-maxfirstrow) < fTrackNRows[xbin + ybin*nxbins]) {
466 fTrackNRows[xbin + ybin*nxbins] = maxlastrow-maxfirstrow;
467 fInitialGapCount[xbin + ybin*nxbins] = 1;
468 if((maxlastrow-maxfirstrow+1)<MIN_TRACK_LENGTH)
469 fInitialGapCount[xbin + ybin*nxbins] = MAX_N_GAPS+1;
470 if(maxtrackpt < 0.9*0.1*AliL3Transform::GetSolenoidField())
471 fInitialGapCount[xbin + ybin*nxbins] = MAX_N_GAPS;
472 fTrackFirstRow[xbin + ybin*nxbins] = maxfirstrow;
473 fTrackLastRow[xbin + ybin*nxbins] = maxlastrow;
475 Int_t xmirror = xmax - xbin + 1;
476 Int_t ymirror = ymax - ybin + 1;
477 fTrackNRows[xmirror + ymirror*nxbins] = fTrackNRows[xbin + ybin*nxbins];
478 fInitialGapCount[xmirror + ymirror*nxbins] = fInitialGapCount[xbin + ybin*nxbins];
479 fTrackFirstRow[xmirror + ymirror*nxbins] = fTrackFirstRow[xbin + ybin*nxbins];
480 fTrackLastRow[xmirror + ymirror*nxbins] = fTrackLastRow[xbin + ybin*nxbins];
484 // cout<<" fTrackNRows "<<(Int_t)fInitialGapCount[xbin + ybin*nxbins]<<" "<<xbin<<" "<<ybin<<" "<<(Int_t)fTrackNRows[xbin + ybin*nxbins]<<" "<<(Int_t)fTrackFirstRow[xbin + ybin*nxbins]<<" "<<(Int_t)fTrackLastRow[xbin + ybin*nxbins]<<" "<<endl;
492 Int_t nrows = AliL3Transform::GetLastRow(5) - AliL3Transform::GetFirstRow(0) + 1;
493 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
494 <<"Transformer: Allocating about "<<nrows*100*sizeof(AliL3PadHoughParams)<<" bytes to fStartPadParams"<<ENDLOG;
495 fStartPadParams = new AliL3PadHoughParams*[nrows];
496 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
497 <<"Transformer: Allocating about "<<nrows*100*sizeof(AliL3PadHoughParams)<<" bytes to fEndPadParams"<<ENDLOG;
498 fEndPadParams = new AliL3PadHoughParams*[nrows];
499 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
500 <<"Transformer: Allocating about "<<nrows*100*sizeof(Float_t)<<" bytes to fLUTr2"<<ENDLOG;
501 fLUTr2 = new Float_t*[nrows];
503 Float_t beta1 = fgBeta1;
504 Float_t beta2 = fgBeta2;
505 Float_t beta1minusbeta2 = fgBeta1 - fgBeta2;
506 Float_t ymin = hist->GetYmin();
507 Float_t histbin = hist->GetBinWidthY();
508 Float_t xmin = hist->GetXmin();
509 Float_t xmax = hist->GetXmax();
510 Float_t xbin = (xmax-xmin)/hist->GetNbinsX();
511 Int_t firstbinx = hist->GetFirstXbin();
512 Int_t lastbinx = hist->GetLastXbin();
513 Int_t nbinx = hist->GetNbinsX()+2;
514 Int_t firstbin = hist->GetFirstYbin();
515 Int_t lastbin = hist->GetLastYbin();
516 for(Int_t i=AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
518 Int_t npads = AliL3Transform::GetNPads(i);
519 Int_t ipatch = AliL3Transform::GetPatch(i);
520 Double_t padpitch = AliL3Transform::GetPadPitchWidth(ipatch);
521 Float_t x = AliL3Transform::Row2X(i);
524 fStartPadParams[i] = new AliL3PadHoughParams[npads];
525 fEndPadParams[i] = new AliL3PadHoughParams[npads];
526 fLUTr2[i] = new Float_t[npads];
527 for(Int_t pad=0; pad<npads; pad++)
529 Float_t y = (pad-0.5*(npads-1))*padpitch;
530 fLUTr2[i][pad] = x2 + y*y;
531 Float_t starty = (pad-0.5*npads)*padpitch;
532 Float_t r1 = x2 + starty*starty;
533 Float_t xoverr1 = x/r1;
534 Float_t startyoverr1 = starty/r1;
535 Float_t endy = (pad-0.5*(npads-2))*padpitch;
536 Float_t r2 = x2 + endy*endy;
537 Float_t xoverr2 = x/r2;
538 Float_t endyoverr2 = endy/r2;
539 Float_t a1 = beta1minusbeta2/(xoverr1-beta2);
540 Float_t b1 = (xoverr1-beta1)/(xoverr1-beta2);
541 Float_t a2 = beta1minusbeta2/(xoverr2-beta2);
542 Float_t b2 = (xoverr2-beta1)/(xoverr2-beta2);
544 Float_t alpha1 = (a1*startyoverr1+b1*ymin-xmin)/xbin;
545 Float_t deltaalpha1 = b1*histbin/xbin;
547 alpha1 += deltaalpha1;
548 Float_t alpha2 = (a2*endyoverr2+b2*ymin-xmin)/xbin;
549 Float_t deltaalpha2 = b2*histbin/xbin;
551 alpha2 += deltaalpha2;
553 fStartPadParams[i][pad].fAlpha = alpha1;
554 fStartPadParams[i][pad].fDeltaAlpha = deltaalpha1;
555 fEndPadParams[i][pad].fAlpha = alpha2;
556 fEndPadParams[i][pad].fDeltaAlpha = deltaalpha2;
558 //Find the first and last bin rows to be filled
559 Bool_t binfound1 = kFALSE;
560 Bool_t binfound2 = kFALSE;
561 Int_t firstbin1 = lastbin;
562 Int_t firstbin2 = lastbin;
563 Int_t lastbin1 = firstbin;
564 Int_t lastbin2 = firstbin;
565 for(Int_t b=firstbin; b<=lastbin; b++, alpha1 += deltaalpha1, alpha2 += deltaalpha2)
567 Int_t binx1 = 1 + (Int_t)alpha1;
568 if(binx1<=lastbinx) {
569 UChar_t initialgapcount;
571 initialgapcount = fInitialGapCount[binx1 + b*nbinx];
573 initialgapcount = fInitialGapCount[firstbinx + b*nbinx];
574 if(initialgapcount != MAX_N_GAPS) {
582 Int_t binx2 = 1 + (Int_t)alpha2;
583 if(binx2>=firstbin) {
584 UChar_t initialgapcount;
586 initialgapcount = fInitialGapCount[binx2 + b*nbinx];
588 initialgapcount = fInitialGapCount[lastbinx + b*nbinx];
589 if(initialgapcount != MAX_N_GAPS) {
598 fStartPadParams[i][pad].fFirstBin=firstbin1;
599 fStartPadParams[i][pad].fLastBin=lastbin1;
600 fEndPadParams[i][pad].fFirstBin=firstbin2;
601 fEndPadParams[i][pad].fLastBin=lastbin2;
606 //create lookup table for z of the digits
609 Int_t ntimebins = AliL3Transform::GetNTimeBins();
610 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
611 <<"Transformer: Allocating "<<ntimebins*sizeof(Float_t)<<" bytes to fLUTforwardZ"<<ENDLOG;
612 fLUTforwardZ = new Float_t[ntimebins];
613 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
614 <<"Transformer: Allocating "<<ntimebins*sizeof(Float_t)<<" bytes to fLUTforwardZ2"<<ENDLOG;
615 fLUTforwardZ2 = new Float_t[ntimebins];
616 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
617 <<"Transformer: Allocating "<<ntimebins*sizeof(Float_t)<<" bytes to fLUTbackwardZ"<<ENDLOG;
618 fLUTbackwardZ = new Float_t[ntimebins];
619 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
620 <<"Transformer: Allocating "<<ntimebins*sizeof(Float_t)<<" bytes to fLUTbackwardZ2"<<ENDLOG;
621 fLUTbackwardZ2 = new Float_t[ntimebins];
622 for(Int_t i=0; i<ntimebins; i++){
624 z=AliL3Transform::GetZFast(0,i,GetZVertex());
626 fLUTforwardZ2[i]=z*z;
627 z=AliL3Transform::GetZFast(18,i,GetZVertex());
629 fLUTbackwardZ2[i]=z*z;
634 void AliL3HoughTransformerRow::Reset()
636 //Reset all the histograms. Should be done when processing new slice
640 LOG(AliL3Log::kWarning,"AliL3HoughTransformer::Reset","Histograms")
641 <<"No histograms to reset"<<ENDLOG;
645 for(Int_t i=0; i<GetNEtaSegments(); i++)
646 fParamSpace[i]->Reset();
650 AliL3Histogram *hist = fParamSpace[0];
651 Int_t ncellsx = (hist->GetNbinsX()+3)/2;
652 Int_t ncellsy = (hist->GetNbinsY()+3)/2;
653 Int_t ncells = ncellsx*ncellsy;
654 for(Int_t i=0; i<GetNEtaSegments(); i++)
655 memset(fTrackID[i],0,ncells*sizeof(AliL3TrackIndex));
658 AliL3Histogram *hist = fParamSpace[0];
659 Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2);
660 for(Int_t i=0; i<GetNEtaSegments(); i++)
662 memcpy(fGapCount[i],fInitialGapCount,ncells*sizeof(UChar_t));
663 memcpy(fCurrentRowCount[i],fTrackFirstRow,ncells*sizeof(UChar_t));
667 Int_t AliL3HoughTransformerRow::GetEtaIndex(Double_t eta) const
669 //Return the histogram index of the corresponding eta.
671 Double_t etaslice = (GetEtaMax() - GetEtaMin())/GetNEtaSegments();
672 Double_t index = (eta-GetEtaMin())/etaslice;
676 inline AliL3Histogram *AliL3HoughTransformerRow::GetHistogram(Int_t etaindex)
678 // Return a pointer to the histogram which contains etaindex eta slice
679 if(!fParamSpace || etaindex >= GetNEtaSegments() || etaindex < 0)
681 if(!fParamSpace[etaindex])
683 return fParamSpace[etaindex];
686 Double_t AliL3HoughTransformerRow::GetEta(Int_t etaindex,Int_t /*slice*/) const
688 // Return eta calculated in the middle of the eta slice
689 Double_t etaslice = (GetEtaMax()-GetEtaMin())/GetNEtaSegments();
691 eta=(Double_t)((etaindex+0.5)*etaslice);
695 void AliL3HoughTransformerRow::TransformCircle()
698 TransformCircleFromDigitArray();
699 else if(fTPCRawStream)
700 TransformCircleFromRawStream();
702 void AliL3HoughTransformerRow::TransformCircleFromDigitArray()
704 //Do the Hough Transform
706 Int_t netasegments = GetNEtaSegments();
707 Double_t etamin = GetEtaMin();
708 Double_t etaslice = (GetEtaMax() - etamin)/netasegments;
710 Int_t lowerthreshold = GetLowerThreshold();
712 //Assumes that all the etaslice histos are the same!
713 AliL3Histogram *h = fParamSpace[0];
714 Int_t firstbiny = h->GetFirstYbin();
715 Int_t firstbinx = h->GetFirstXbin();
716 Int_t lastbinx = h->GetLastXbin();
717 Int_t nbinx = h->GetNbinsX()+2;
721 AliL3EtaRow *etaclust = new AliL3EtaRow[netasegments];
723 AliL3DigitRowData *tempPt = GetDataPointer();
726 LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformCircle","Data")
727 <<"No input data "<<ENDLOG;
731 Int_t ipatch = GetPatch();
732 Int_t ilastpatch = GetLastPatch();
733 Int_t islice = GetSlice();
738 lutz2 = fLUTforwardZ2;
741 lutz = fLUTbackwardZ;
742 lutz2 = fLUTbackwardZ2;
745 //Loop over the padrows:
746 for(UChar_t i=AliL3Transform::GetFirstRow(ipatch); i<=AliL3Transform::GetLastRow(ipatch); i++)
749 //Flush eta clusters array
750 memset(etaclust,0,netasegments*sizeof(AliL3EtaRow));
752 Float_t x = AliL3Transform::Row2X((Int_t)i);
756 //Get the data on this padrow:
757 AliL3DigitData *digPt = tempPt->fDigitData;
758 if((Int_t)i != (Int_t)tempPt->fRow)
760 LOG(AliL3Log::kError,"AliL3HoughTransformerRow::TransformCircle","Data")
761 <<"AliL3HoughTransform::TransformCircle : Mismatching padrow numbering "<<(Int_t)i<<" "<<(Int_t)tempPt->fRow<<ENDLOG;
764 // cout<<" Starting row "<<i<<endl;
765 //Loop over the data on this padrow:
766 for(UInt_t j=0; j<tempPt->fNDigit; j++)
768 UShort_t charge = digPt[j].fCharge;
769 if((Int_t)charge <= lowerthreshold)
771 UChar_t pad = digPt[j].fPad;
772 UShort_t time = digPt[j].fTime;
776 radius2 = fLUTr2[(Int_t)i][(Int_t)pad];
780 //Transform data to local cartesian coordinates:
781 Float_t z = lutz[(Int_t)time];
782 Float_t z2 = lutz2[(Int_t)time];
783 // Acceptance cut : to be verified
784 // if(radius2<0.72406166*z2) continue;
785 if(x2<0.8464*z2) continue;
787 Double_t r = sqrt(radius2+z2);
788 Double_t eta = 0.5 * log((r+z)/(r-z));
789 //Get the corresponding index, which determines which histogram to fill:
790 Int_t etaindex = (Int_t)((eta-etamin)/etaslice);
793 if(etaindex == lastetaindex) continue;
795 // cout<<" Digit at patch "<<ipatch<<" row "<<i<<" pad "<<(Int_t)pad<<" time "<<time<<" etaslice "<<etaindex<<endl;
797 if(etaindex < 0 || etaindex >= netasegments)
800 if(!etaclust[etaindex].fIsFound)
802 etaclust[etaindex].fStartPad = pad;
803 etaclust[etaindex].fEndPad = pad;
804 etaclust[etaindex].fIsFound = 1;
806 FillClusterMCLabels(digPt[j],etaclust[etaindex]);
812 if(pad <= (etaclust[etaindex].fEndPad + 1))
814 etaclust[etaindex].fEndPad = pad;
816 FillClusterMCLabels(digPt[j],etaclust[etaindex]);
821 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
823 etaclust[etaindex].fStartPad = pad;
824 etaclust[etaindex].fEndPad = pad;
827 memset(etaclust[etaindex].fMcLabels,0,MaxTrack);
828 FillClusterMCLabels(digPt[j],etaclust[etaindex]);
833 lastetaindex = etaindex;
835 //Write remaining clusters
836 for(Int_t etaindex = 0;etaindex < netasegments;etaindex++)
838 //Check for empty row
839 if((etaclust[etaindex].fStartPad == 0) && (etaclust[etaindex].fEndPad == 0)) continue;
841 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
844 //Move the data pointer to the next padrow:
845 AliL3MemHandler::UpdateRowPointer(tempPt);
851 void AliL3HoughTransformerRow::TransformCircleFromRawStream()
853 //Do the Hough Transform
855 Int_t netasegments = GetNEtaSegments();
856 Double_t etamin = GetEtaMin();
857 Double_t etaslice = (GetEtaMax() - etamin)/netasegments;
859 Int_t lowerthreshold = GetLowerThreshold();
861 //Assumes that all the etaslice histos are the same!
862 AliL3Histogram *h = fParamSpace[0];
863 Int_t firstbiny = h->GetFirstYbin();
864 Int_t firstbinx = h->GetFirstXbin();
865 Int_t lastbinx = h->GetLastXbin();
866 Int_t nbinx = h->GetNbinsX()+2;
869 AliL3EtaRow *etaclust = new AliL3EtaRow[netasegments];
873 LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformCircle","Data")
874 <<"No input data "<<ENDLOG;
878 Int_t ipatch = GetPatch();
879 UChar_t rowmin = AliL3Transform::GetFirstRowOnDDL(ipatch);
880 UChar_t rowmax = AliL3Transform::GetLastRowOnDDL(ipatch);
881 // Int_t ntimebins = AliL3Transform::GetNTimeBins();
882 Int_t ilastpatch = GetLastPatch();
883 Int_t islice = GetSlice();
888 lutz2 = fLUTforwardZ2;
891 lutz = fLUTbackwardZ;
892 lutz2 = fLUTbackwardZ2;
895 //Flush eta clusters array
896 memset(etaclust,0,netasegments*sizeof(AliL3EtaRow));
905 //Loop over the rawdata:
906 while (fTPCRawStream->Next()) {
908 if(fTPCRawStream->IsNewSector() || fTPCRawStream->IsNewRow()) {
910 //Write remaining clusters
911 for(Int_t etaindex = 0;etaindex < netasegments;etaindex++)
913 //Check for empty row
914 if((etaclust[etaindex].fStartPad == 0) && (etaclust[etaindex].fEndPad == 0)) continue;
916 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
919 Int_t sector=fTPCRawStream->GetSector();
920 Int_t row=fTPCRawStream->GetRow();
922 AliL3Transform::Sector2Slice(slice,srow,sector,row);
924 LOG(AliL3Log::kError,"AliL3DDLDataFileHandler::DDLDigits2Memory","Slice")
925 <<AliL3Log::kDec<<"Found slice "<<slice<<", expected "<<islice<<ENDLOG;
930 npads = AliL3Transform::GetNPads(srow)-1;
932 //Flush eta clusters array
933 memset(etaclust,0,netasegments*sizeof(AliL3EtaRow));
935 x = AliL3Transform::Row2X((Int_t)i);
941 if((i<rowmin)||(i>rowmax))continue;
943 // cout<<" Starting row "<<(UInt_t)i<<endl;
944 //Loop over the data on this padrow:
945 if(fTPCRawStream->IsNewRow() || fTPCRawStream->IsNewPad()) {
946 pad=fTPCRawStream->GetPad();
948 if((pad<0)||(pad>=(npads+1))){
949 LOG(AliL3Log::kError,"AliL3DDLDataFileHandler::DDLDigits2Memory","Pad")
950 <<AliL3Log::kDec<<"Pad value out of bounds "<<pad<<" "
955 radius2 = fLUTr2[(Int_t)i][(Int_t)pad];
959 UShort_t time=fTPCRawStream->GetTime();
961 if((time<0)||(time>=ntimebins)){
962 LOG(AliL3Log::kError,"AliL3DDLDataFileHandler::DDLDigits2Memory","Time")
963 <<AliL3Log::kDec<<"Time out of bounds "<<time<<" "
964 <<AliL3Transform::GetNTimeBins()<<ENDLOG;
969 if(fTPCRawStream->GetSignal() <= lowerthreshold)
972 //Transform data to local cartesian coordinates:
973 Float_t z = lutz[(Int_t)time];
974 Float_t z2 = lutz2[(Int_t)time];
975 // if(radius2<0.72406166*z2) continue;
976 if(x2<0.8464*z2) continue;
978 Double_t r = sqrt(radius2+z2);
979 Double_t eta = 0.5 * log((r+z)/(r-z));
980 //Get the corresponding index, which determines which histogram to fill:
981 Int_t etaindex = (Int_t)((eta-etamin)/etaslice);
984 if(etaindex == lastetaindex) continue;
986 // cout<<" Digit at patch "<<ipatch<<" row "<<i<<" pad "<<(Int_t)pad<<" time "<<time<<" etaslice "<<etaindex<<endl;
988 if(etaindex < 0 || etaindex >= netasegments)
991 if(!etaclust[etaindex].fIsFound)
993 etaclust[etaindex].fStartPad = pad;
994 etaclust[etaindex].fEndPad = pad;
995 etaclust[etaindex].fIsFound = 1;
1000 if(pad <= (etaclust[etaindex].fEndPad + 1))
1002 etaclust[etaindex].fEndPad = pad;
1006 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
1008 etaclust[etaindex].fStartPad = pad;
1009 etaclust[etaindex].fEndPad = pad;
1013 lastetaindex = etaindex;
1016 //Write remaining clusters
1017 for(Int_t etaindex = 0;etaindex < netasegments;etaindex++)
1019 //Check for empty row
1020 if((etaclust[etaindex].fStartPad == 0) && (etaclust[etaindex].fEndPad == 0)) continue;
1022 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
1028 Int_t AliL3HoughTransformerRow::GetTrackID(Int_t etaindex,Double_t alpha1,Double_t alpha2) const
1030 // Returns the MC label for a given peak found in the Hough space
1032 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackID","Data")
1033 <<"Flag switched off"<<ENDLOG;
1036 if(etaindex < 0 || etaindex > GetNEtaSegments())
1038 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackID","Data")
1039 <<"Wrong etaindex "<<etaindex<<ENDLOG;
1042 AliL3Histogram *hist = fParamSpace[etaindex];
1043 Int_t bin = hist->FindLabelBin(alpha1,alpha2);
1045 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackID()","")
1046 <<"Track candidate outside Hough space boundaries: "<<alpha1<<" "<<alpha2<<ENDLOG;
1051 for(UInt_t i=0; i<(MaxTrack-1); i++)
1053 Int_t nhits=fTrackID[etaindex][bin].fNHits[i];
1054 if(nhits == 0) break;
1058 label = fTrackID[etaindex][bin].fLabel[i];
1063 for(UInt_t i=0; i<(MaxTrack-1); i++)
1065 Int_t nhits=fTrackID[etaindex][bin].fNHits[i];
1066 if(nhits == 0) break;
1069 if(fTrackID[etaindex][bin].fLabel[i]!=label) {
1071 label2 = fTrackID[etaindex][bin].fLabel[i];
1076 LOG(AliL3Log::kDebug,"AliL3HoughTransformerRow::GetTrackID()","")
1077 <<" TrackID"<<" label "<<label<<" max "<<max<<" label2 "<<label2<<" max2 "<<max2<<" "<<(Float_t)max2/(Float_t)max<<" "<<fTrackID[etaindex][bin].fLabel[MaxTrack-1]<<" "<<(Int_t)fTrackID[etaindex][bin].fNHits[MaxTrack-1]<<ENDLOG;
1081 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackID()","")
1082 <<"Compile with do_mc flag!"<<ENDLOG;
1086 UChar_t *AliL3HoughTransformerRow::GetGapCount(Int_t etaindex)
1088 return fGapCount[etaindex];
1091 UChar_t *AliL3HoughTransformerRow::GetCurrentRowCount(Int_t etaindex)
1093 return fCurrentRowCount[etaindex];
1096 UChar_t *AliL3HoughTransformerRow::GetTrackNRows()
1102 UChar_t *AliL3HoughTransformerRow::GetTrackFirstRow()
1104 return fTrackFirstRow;
1107 UChar_t *AliL3HoughTransformerRow::GetTrackLastRow()
1109 return fTrackLastRow;
1112 UChar_t *AliL3HoughTransformerRow::GetPrevBin(Int_t etaindex)
1114 return fPrevBin[etaindex];
1117 UChar_t *AliL3HoughTransformerRow::GetNextBin(Int_t etaindex)
1119 return fNextBin[etaindex];
1122 UChar_t *AliL3HoughTransformerRow::GetNextRow(Int_t etaindex)
1124 return fNextRow[etaindex];
1127 inline void AliL3HoughTransformerRow::FillClusterRow(UChar_t i,Int_t binx1,Int_t binx2,UChar_t *ngaps2,UChar_t *currentrow2,UChar_t *lastrow2
1129 ,AliL3EtaRow etaclust,AliL3TrackIndex *trackid
1133 for(Int_t bin=binx1;bin<=binx2;bin++)
1135 if(ngaps2[bin] < MAX_N_GAPS) {
1136 if(i < lastrow2[bin] && i > currentrow2[bin]) {
1137 ngaps2[bin] += (i-currentrow2[bin]-1);
1141 if(i < lastrow2[bin] && i >= currentrow2[bin]) {
1142 for(UInt_t t=0;t<(MaxTrack-1); t++)
1144 Int_t label = etaclust.fMcLabels[t];
1145 if(label == 0) break;
1147 Int_t tempbin2 = (Int_t)(bin/2);
1148 for(c=0; c<(MaxTrack-1); c++)
1149 if(trackid[tempbin2].fLabel[c] == label || trackid[tempbin2].fNHits[c] == 0)
1151 trackid[tempbin2].fLabel[c] = label;
1152 if(trackid[tempbin2].fCurrentRow[c] != i) {
1153 trackid[tempbin2].fNHits[c]++;
1154 trackid[tempbin2].fCurrentRow[c] = i;
1164 inline void AliL3HoughTransformerRow::FillCluster(UChar_t i,Int_t etaindex,AliL3EtaRow *etaclust,Int_t ilastpatch,Int_t firstbinx,Int_t lastbinx,Int_t nbinx,Int_t firstbiny)
1166 UChar_t *ngaps = fGapCount[etaindex];
1167 UChar_t *currentrow = fCurrentRowCount[etaindex];
1168 UChar_t *lastrow = fTrackLastRow;
1169 UChar_t *prevbin = fPrevBin[etaindex];
1170 UChar_t *nextbin = fNextBin[etaindex];
1171 UChar_t *nextrow = fNextRow[etaindex];
1173 AliL3TrackIndex *trackid = fTrackID[etaindex];
1176 //Do the transformation:
1177 AliL3PadHoughParams *startparams = &fStartPadParams[(Int_t)i][etaclust[etaindex].fStartPad];
1178 AliL3PadHoughParams *endparams = &fEndPadParams[(Int_t)i][etaclust[etaindex].fEndPad];
1180 Float_t alpha1 = startparams->fAlpha;
1181 Float_t deltaalpha1 = startparams->fDeltaAlpha;
1182 Float_t alpha2 = endparams->fAlpha;
1183 Float_t deltaalpha2 = endparams->fDeltaAlpha;
1185 Int_t firstbin1 = startparams->fFirstBin;
1186 Int_t firstbin2 = endparams->fFirstBin;
1187 Int_t firstbin = firstbin1;
1188 if(firstbin>firstbin2) firstbin = firstbin2;
1190 Int_t lastbin1 = startparams->fLastBin;
1191 Int_t lastbin2 = endparams->fLastBin;
1192 Int_t lastbin = lastbin1;
1193 if(lastbin<lastbin2) lastbin = lastbin2;
1195 alpha1 += (firstbin-firstbiny)*deltaalpha1;
1196 alpha2 += (firstbin-firstbiny)*deltaalpha2;
1198 //Fill the histogram along the alpha2 range
1199 if(ilastpatch == -1) {
1200 for(Int_t b=firstbin; b<=lastbin; b++, alpha1 += deltaalpha1, alpha2 += deltaalpha2)
1202 Int_t binx1 = 1 + (Int_t)alpha1;
1203 if(binx1>lastbinx) continue;
1204 if(binx1<firstbinx) binx1 = firstbinx;
1205 Int_t binx2 = 1 + (Int_t)alpha2;
1206 if(binx2<firstbinx) continue;
1207 if(binx2>lastbinx) binx2 = lastbinx;
1210 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::TransformCircle()","")
1211 <<"Wrong filling "<<binx1<<" "<<binx2<<" "<<i<<" "<<etaclust[etaindex].fStartPad<<" "<<etaclust[etaindex].fEndPad<<ENDLOG;
1214 Int_t tempbin = b*nbinx;
1215 UChar_t *ngaps2 = ngaps + tempbin;
1216 UChar_t *currentrow2 = currentrow + tempbin;
1217 UChar_t *lastrow2 = lastrow + tempbin;
1219 Int_t tempbin2 = ((Int_t)(b/2))*((Int_t)((nbinx+1)/2));
1220 AliL3TrackIndex *trackid2 = trackid + tempbin2;
1222 FillClusterRow(i,binx1,binx2,ngaps2,currentrow2,lastrow2
1224 ,etaclust[etaindex],trackid2
1230 for(Int_t b=firstbin; b<=lastbin; b++, alpha1 += deltaalpha1, alpha2 += deltaalpha2)
1232 Int_t binx1 = 1 + (Int_t)alpha1;
1233 if(binx1>lastbinx) continue;
1234 if(binx1<firstbinx) binx1 = firstbinx;
1235 Int_t binx2 = 1 + (Int_t)alpha2;
1236 if(binx2<firstbinx) continue;
1237 if(binx2>lastbinx) binx2 = lastbinx;
1240 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::TransformCircle()","")
1241 <<"Wrong filling "<<binx1<<" "<<binx2<<" "<<i<<" "<<etaclust[etaindex].fStartPad<<" "<<etaclust[etaindex].fEndPad<<ENDLOG;
1244 if(nextrow[b] > (b + 1)) {
1245 Int_t deltab = (nextrow[b] - b - 1);
1247 alpha1 += deltaalpha1*deltab;
1248 alpha2 += deltaalpha2*deltab;
1251 Int_t tempbin = b*nbinx;
1252 binx1 = (UInt_t)nextbin[binx1 + tempbin];
1253 binx2 = (UInt_t)prevbin[binx2 + tempbin];
1254 if(binx2<binx1) continue;
1255 UChar_t *ngaps2 = ngaps + tempbin;
1256 UChar_t *currentrow2 = currentrow + tempbin;
1257 UChar_t *lastrow2 = lastrow + tempbin;
1259 Int_t tempbin2 = ((Int_t)(b/2))*((Int_t)((nbinx+1)/2));
1260 AliL3TrackIndex *trackid2 = trackid + tempbin2;
1262 FillClusterRow(i,binx1,binx2,ngaps2,currentrow2,lastrow2
1264 ,etaclust[etaindex],trackid2
1272 inline void AliL3HoughTransformerRow::FillClusterMCLabels(AliL3DigitData digpt,AliL3EtaRow etaclust)
1274 for(Int_t t=0; t<3; t++)
1276 Int_t label = digpt.fTrackID[t];
1277 if(label < 0) break;
1279 for(c=0; c<(MaxTrack-1); c++)
1280 if(etaclust.fMcLabels[c] == label || etaclust.fMcLabels[c] == 0)
1283 etaclust.fMcLabels[c] = label;