4 // Author: Cvetan Cheshkov <mailto:cvetan.cheshkov@cern.ch>
6 #include "AliL3StandardIncludes.h"
8 #include "AliL3Logging.h"
9 #include "AliL3MemHandler.h"
10 #include "AliL3Transform.h"
11 #include "AliL3DigitData.h"
12 #include "AliL3HistogramAdaptive.h"
13 #include "AliL3HoughTrack.h"
14 #include "AliL3HoughTransformerRow.h"
20 //_____________________________________________________________
21 // AliL3HoughTransformerRow
23 // Impelementation of the so called "TPC rows Hough transformation" class
25 // Transforms the TPC data into the hough space and counts the missed TPC
26 // rows corresponding to each track cnadidate - hough space bin
28 ClassImp(AliL3HoughTransformerRow)
30 Float_t AliL3HoughTransformerRow::fgBeta1 = 1.0/AliL3Transform::Row2X(84);
31 Float_t AliL3HoughTransformerRow::fgBeta2 = 1.0/(AliL3Transform::Row2X(158)*(1.0+tan(AliL3Transform::Pi()*10/180)*tan(AliL3Transform::Pi()*10/180)));
33 AliL3HoughTransformerRow::AliL3HoughTransformerRow()
62 AliL3HoughTransformerRow::AliL3HoughTransformerRow(Int_t slice,Int_t patch,Int_t netasegments,Bool_t /*DoMC*/,Float_t zvertex) : AliL3HoughBaseTransformer(slice,patch,netasegments,zvertex)
92 AliL3HoughTransformerRow::~AliL3HoughTransformerRow()
95 if(fLastTransformer) return;
100 for(Int_t i=0; i<GetNEtaSegments(); i++)
102 if(!fTrackID[i]) continue;
112 for(Int_t i=0; i<GetNEtaSegments(); i++)
114 if(!fGapCount[i]) continue;
115 delete [] fGapCount[i];
122 for(Int_t i=0; i<GetNEtaSegments(); i++)
124 if(fCurrentRowCount[i])
125 delete [] fCurrentRowCount[i];
127 delete [] fCurrentRowCount;
128 fCurrentRowCount = 0;
132 delete [] fTrackNRows;
137 delete [] fTrackFirstRow;
142 delete [] fTrackLastRow;
147 delete [] fInitialGapCount;
148 fInitialGapCount = 0;
152 for(Int_t i=0; i<GetNEtaSegments(); i++)
154 if(!fPrevBin[i]) continue;
155 delete [] fPrevBin[i];
162 for(Int_t i=0; i<GetNEtaSegments(); i++)
164 if(!fNextBin[i]) continue;
165 delete [] fNextBin[i];
172 for(Int_t i=0; i<GetNEtaSegments(); i++)
174 if(!fNextRow[i]) continue;
175 delete [] fNextRow[i];
182 for(Int_t i = AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
184 if(!fStartPadParams[i]) continue;
185 delete [] fStartPadParams[i];
187 delete [] fStartPadParams;
192 for(Int_t i = AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
194 if(!fEndPadParams[i]) continue;
195 delete [] fEndPadParams[i];
197 delete [] fEndPadParams;
202 for(Int_t i = AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
204 if(!fLUTr2[i]) continue;
212 delete[] fLUTforwardZ;
217 delete[] fLUTforwardZ2;
222 delete[] fLUTbackwardZ;
227 delete[] fLUTbackwardZ2;
232 void AliL3HoughTransformerRow::DeleteHistograms()
237 for(Int_t i=0; i<GetNEtaSegments(); i++)
239 if(!fParamSpace[i]) continue;
240 delete fParamSpace[i];
242 delete [] fParamSpace;
245 struct AliL3TrackLength {
246 // Structure is used for temporarely storage of the LUT
247 // which contains the track lengths associated to each hough
249 Bool_t fIsFilled; // Is bin already filled?
250 UInt_t fFirstRow; // First TPC row crossed by the track
251 UInt_t fLastRow; // Last TPC row crossed by the track
252 Float_t fTrackPt; // Pt of the track
255 void AliL3HoughTransformerRow::CreateHistograms(Int_t nxbin,Float_t xmin,Float_t xmax,
256 Int_t nybin,Float_t ymin,Float_t ymax)
258 //Create the histograms (parameter space)
261 //xmin xmax ymin ymax = histogram limits in X and Y
262 if(fLastTransformer) {
263 SetTransformerArrays((AliL3HoughTransformerRow *)fLastTransformer);
266 fParamSpace = new AliL3Histogram*[GetNEtaSegments()];
268 Char_t histname[256];
269 for(Int_t i=0; i<GetNEtaSegments(); i++)
271 sprintf(histname,"paramspace_%d",i);
272 fParamSpace[i] = new AliL3Histogram(histname,"",nxbin,xmin,xmax,nybin,ymin,ymax);
276 AliL3Histogram *hist = fParamSpace[0];
277 Int_t ncellsx = (hist->GetNbinsX()+3)/2;
278 Int_t ncellsy = (hist->GetNbinsY()+3)/2;
279 Int_t ncells = ncellsx*ncellsy;
282 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
283 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(AliL3TrackIndex)<<" bytes to fTrackID"<<ENDLOG;
284 fTrackID = new AliL3TrackIndex*[GetNEtaSegments()];
285 for(Int_t i=0; i<GetNEtaSegments(); i++)
286 fTrackID[i] = new AliL3TrackIndex[ncells];
290 AliL3Histogram *hist = fParamSpace[0];
291 Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2);
294 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
295 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fGapCount"<<ENDLOG;
296 fGapCount = new UChar_t*[GetNEtaSegments()];
297 for(Int_t i=0; i<GetNEtaSegments(); i++)
298 fGapCount[i] = new UChar_t[ncells];
300 if(!fCurrentRowCount)
302 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
303 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fCurrentRowCount"<<ENDLOG;
304 fCurrentRowCount = new UChar_t*[GetNEtaSegments()];
305 for(Int_t i=0; i<GetNEtaSegments(); i++)
306 fCurrentRowCount[i] = new UChar_t[ncells];
310 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
311 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fPrevBin"<<ENDLOG;
312 fPrevBin = new UChar_t*[GetNEtaSegments()];
313 for(Int_t i=0; i<GetNEtaSegments(); i++)
314 fPrevBin[i] = new UChar_t[ncells];
318 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
319 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fNextBin"<<ENDLOG;
320 fNextBin = new UChar_t*[GetNEtaSegments()];
321 for(Int_t i=0; i<GetNEtaSegments(); i++)
322 fNextBin[i] = new UChar_t[ncells];
324 Int_t ncellsy = hist->GetNbinsY()+2;
327 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
328 <<"Transformer: Allocating "<<GetNEtaSegments()*ncellsy*sizeof(UChar_t)<<" bytes to fNextRow"<<ENDLOG;
329 fNextRow = new UChar_t*[GetNEtaSegments()];
330 for(Int_t i=0; i<GetNEtaSegments(); i++)
331 fNextRow[i] = new UChar_t[ncellsy];
336 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
337 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fTrackNRows"<<ENDLOG;
338 fTrackNRows = new UChar_t[ncells];
339 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
340 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fTrackFirstRow"<<ENDLOG;
341 fTrackFirstRow = new UChar_t[ncells];
342 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
343 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fTrackLastRow"<<ENDLOG;
344 fTrackLastRow = new UChar_t[ncells];
345 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
346 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fInitialGapCount"<<ENDLOG;
347 fInitialGapCount = new UChar_t[ncells];
350 AliL3HoughTrack track;
351 Int_t xmin = hist->GetFirstXbin();
352 Int_t xmax = hist->GetLastXbin();
353 Int_t xmiddle = (hist->GetNbinsX()+1)/2;
354 Int_t ymin = hist->GetFirstYbin();
355 Int_t ymax = hist->GetLastYbin();
356 Int_t nxbins = hist->GetNbinsX()+2;
357 Int_t nxgrid = (hist->GetNbinsX()+3)/2+1;
358 Int_t nygrid = hist->GetNbinsY()+3;
360 AliL3TrackLength *tracklength = new AliL3TrackLength[nxgrid*nygrid];
361 memset(tracklength,0,nxgrid*nygrid*sizeof(AliL3TrackLength));
363 for(Int_t ybin=ymin-1; ybin<=(ymax+1); ybin++)
365 for(Int_t xbin=xmin-1; xbin<=xmiddle; xbin++)
367 fTrackNRows[xbin + ybin*nxbins] = 255;
368 for(Int_t deltay = 0; deltay <= 1; deltay++) {
369 for(Int_t deltax = 0; deltax <= 1; deltax++) {
371 AliL3TrackLength *curtracklength = &tracklength[(xbin + deltax) + (ybin + deltay)*nxgrid];
372 UInt_t maxfirstrow = 0;
373 UInt_t maxlastrow = 0;
374 Float_t maxtrackpt = 0;
375 if(curtracklength->fIsFilled) {
376 maxfirstrow = curtracklength->fFirstRow;
377 maxlastrow = curtracklength->fLastRow;
378 maxtrackpt = curtracklength->fTrackPt;
381 Float_t xtrack = hist->GetPreciseBinCenterX((Float_t)xbin+0.5*(Float_t)(2*deltax-1));
382 Float_t ytrack = hist->GetPreciseBinCenterY((Float_t)ybin+0.5*(Float_t)(2*deltay-1));
384 Float_t psi = atan((xtrack-ytrack)/(fgBeta1-fgBeta2));
385 Float_t kappa = 2.0*(xtrack*cos(psi)-fgBeta1*sin(psi));
386 track.SetTrackParameters(kappa,psi,1);
387 maxtrackpt = track.GetPt();
388 if(maxtrackpt < 0.9*0.1*AliL3Transform::GetSolenoidField())
390 maxfirstrow = maxlastrow = 0;
391 curtracklength->fIsFilled = kTRUE;
392 curtracklength->fFirstRow = maxfirstrow;
393 curtracklength->fLastRow = maxlastrow;
394 curtracklength->fTrackPt = maxtrackpt;
398 Bool_t firstrow = kFALSE;
399 UInt_t curfirstrow = 0;
400 UInt_t curlastrow = 0;
402 Double_t centerx = track.GetCenterX();
403 Double_t centery = track.GetCenterY();
404 Double_t radius = track.GetRadius();
406 for(Int_t j=AliL3Transform::GetFirstRow(0); j<=AliL3Transform::GetLastRow(5); j++)
409 // if(!track.GetCrossingPoint(j,hit)) continue;
410 hit[0] = AliL3Transform::Row2X(j);
411 Double_t aa = (hit[0] - centerx)*(hit[0] - centerx);
412 Double_t r2 = radius*radius;
416 Double_t aa2 = sqrt(r2 - aa);
417 Double_t y1 = centery + aa2;
418 Double_t y2 = centery - aa2;
420 if(fabs(y2) < fabs(y1)) hit[1] = y2;
424 AliL3Transform::LocHLT2Raw(hit,0,j);
426 if(hit[1]>=0 && hit[1]<AliL3Transform::GetNPads(j))
437 if((curlastrow-curfirstrow) >= (maxlastrow-maxfirstrow)) {
438 maxfirstrow = curfirstrow;
439 maxlastrow = curlastrow;
444 if((curlastrow-curfirstrow) >= (maxlastrow-maxfirstrow)) {
445 maxfirstrow = curfirstrow;
446 maxlastrow = curlastrow;
449 curtracklength->fIsFilled = kTRUE;
450 curtracklength->fFirstRow = maxfirstrow;
451 curtracklength->fLastRow = maxlastrow;
452 curtracklength->fTrackPt = maxtrackpt;
455 if((maxlastrow-maxfirstrow) < fTrackNRows[xbin + ybin*nxbins]) {
456 fTrackNRows[xbin + ybin*nxbins] = maxlastrow-maxfirstrow;
457 fInitialGapCount[xbin + ybin*nxbins] = 1;
458 if((maxlastrow-maxfirstrow+1)<MIN_TRACK_LENGTH)
459 fInitialGapCount[xbin + ybin*nxbins] = MAX_N_GAPS+1;
460 if(maxtrackpt < 0.9*0.1*AliL3Transform::GetSolenoidField())
461 fInitialGapCount[xbin + ybin*nxbins] = MAX_N_GAPS;
462 fTrackFirstRow[xbin + ybin*nxbins] = maxfirstrow;
463 fTrackLastRow[xbin + ybin*nxbins] = maxlastrow;
465 Int_t xmirror = xmax - xbin + 1;
466 Int_t ymirror = ymax - ybin + 1;
467 fTrackNRows[xmirror + ymirror*nxbins] = fTrackNRows[xbin + ybin*nxbins];
468 fInitialGapCount[xmirror + ymirror*nxbins] = fInitialGapCount[xbin + ybin*nxbins];
469 fTrackFirstRow[xmirror + ymirror*nxbins] = fTrackFirstRow[xbin + ybin*nxbins];
470 fTrackLastRow[xmirror + ymirror*nxbins] = fTrackLastRow[xbin + ybin*nxbins];
474 // 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;
477 delete [] tracklength;
482 Int_t nrows = AliL3Transform::GetLastRow(5) - AliL3Transform::GetFirstRow(0) + 1;
483 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
484 <<"Transformer: Allocating about "<<nrows*100*sizeof(AliL3PadHoughParams)<<" bytes to fStartPadParams"<<ENDLOG;
485 fStartPadParams = new AliL3PadHoughParams*[nrows];
486 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
487 <<"Transformer: Allocating about "<<nrows*100*sizeof(AliL3PadHoughParams)<<" bytes to fEndPadParams"<<ENDLOG;
488 fEndPadParams = new AliL3PadHoughParams*[nrows];
489 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
490 <<"Transformer: Allocating about "<<nrows*100*sizeof(Float_t)<<" bytes to fLUTr2"<<ENDLOG;
491 fLUTr2 = new Float_t*[nrows];
493 Float_t beta1 = fgBeta1;
494 Float_t beta2 = fgBeta2;
495 Float_t beta1minusbeta2 = fgBeta1 - fgBeta2;
496 Float_t ymin = hist->GetYmin();
497 Float_t histbin = hist->GetBinWidthY();
498 Float_t xmin = hist->GetXmin();
499 Float_t xmax = hist->GetXmax();
500 Float_t xbin = (xmax-xmin)/hist->GetNbinsX();
501 Int_t firstbinx = hist->GetFirstXbin();
502 Int_t lastbinx = hist->GetLastXbin();
503 Int_t nbinx = hist->GetNbinsX()+2;
504 Int_t firstbin = hist->GetFirstYbin();
505 Int_t lastbin = hist->GetLastYbin();
506 for(Int_t i=AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
508 Int_t npads = AliL3Transform::GetNPads(i);
509 Int_t ipatch = AliL3Transform::GetPatch(i);
510 Double_t padpitch = AliL3Transform::GetPadPitchWidth(ipatch);
511 Float_t x = AliL3Transform::Row2X(i);
514 fStartPadParams[i] = new AliL3PadHoughParams[npads];
515 fEndPadParams[i] = new AliL3PadHoughParams[npads];
516 fLUTr2[i] = new Float_t[npads];
517 for(Int_t pad=0; pad<npads; pad++)
519 Float_t y = (pad-0.5*(npads-1))*padpitch;
520 fLUTr2[i][pad] = x2 + y*y;
521 Float_t starty = (pad-0.5*npads)*padpitch;
522 Float_t r1 = x2 + starty*starty;
523 Float_t xoverr1 = x/r1;
524 Float_t startyoverr1 = starty/r1;
525 Float_t endy = (pad-0.5*(npads-2))*padpitch;
526 Float_t r2 = x2 + endy*endy;
527 Float_t xoverr2 = x/r2;
528 Float_t endyoverr2 = endy/r2;
529 Float_t a1 = beta1minusbeta2/(xoverr1-beta2);
530 Float_t b1 = (xoverr1-beta1)/(xoverr1-beta2);
531 Float_t a2 = beta1minusbeta2/(xoverr2-beta2);
532 Float_t b2 = (xoverr2-beta1)/(xoverr2-beta2);
534 Float_t alpha1 = (a1*startyoverr1+b1*ymin-xmin)/xbin;
535 Float_t deltaalpha1 = b1*histbin/xbin;
537 alpha1 += deltaalpha1;
538 Float_t alpha2 = (a2*endyoverr2+b2*ymin-xmin)/xbin;
539 Float_t deltaalpha2 = b2*histbin/xbin;
541 alpha2 += deltaalpha2;
543 fStartPadParams[i][pad].fAlpha = alpha1;
544 fStartPadParams[i][pad].fDeltaAlpha = deltaalpha1;
545 fEndPadParams[i][pad].fAlpha = alpha2;
546 fEndPadParams[i][pad].fDeltaAlpha = deltaalpha2;
548 //Find the first and last bin rows to be filled
549 Bool_t binfound1 = kFALSE;
550 Bool_t binfound2 = kFALSE;
551 Int_t firstbin1 = lastbin;
552 Int_t firstbin2 = lastbin;
553 Int_t lastbin1 = firstbin;
554 Int_t lastbin2 = firstbin;
555 for(Int_t b=firstbin; b<=lastbin; b++, alpha1 += deltaalpha1, alpha2 += deltaalpha2)
557 Int_t binx1 = 1 + (Int_t)alpha1;
558 if(binx1<=lastbinx) {
559 UChar_t initialgapcount;
561 initialgapcount = fInitialGapCount[binx1 + b*nbinx];
563 initialgapcount = fInitialGapCount[firstbinx + b*nbinx];
564 if(initialgapcount != MAX_N_GAPS) {
572 Int_t binx2 = 1 + (Int_t)alpha2;
573 if(binx2>=firstbin) {
574 UChar_t initialgapcount;
576 initialgapcount = fInitialGapCount[binx2 + b*nbinx];
578 initialgapcount = fInitialGapCount[lastbinx + b*nbinx];
579 if(initialgapcount != MAX_N_GAPS) {
588 fStartPadParams[i][pad].fFirstBin=firstbin1;
589 fStartPadParams[i][pad].fLastBin=lastbin1;
590 fEndPadParams[i][pad].fFirstBin=firstbin2;
591 fEndPadParams[i][pad].fLastBin=lastbin2;
596 //create lookup table for z of the digits
599 Int_t ntimebins = AliL3Transform::GetNTimeBins();
600 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
601 <<"Transformer: Allocating "<<ntimebins*sizeof(Float_t)<<" bytes to fLUTforwardZ"<<ENDLOG;
602 fLUTforwardZ = new Float_t[ntimebins];
603 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
604 <<"Transformer: Allocating "<<ntimebins*sizeof(Float_t)<<" bytes to fLUTforwardZ2"<<ENDLOG;
605 fLUTforwardZ2 = new Float_t[ntimebins];
606 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
607 <<"Transformer: Allocating "<<ntimebins*sizeof(Float_t)<<" bytes to fLUTbackwardZ"<<ENDLOG;
608 fLUTbackwardZ = new Float_t[ntimebins];
609 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
610 <<"Transformer: Allocating "<<ntimebins*sizeof(Float_t)<<" bytes to fLUTbackwardZ2"<<ENDLOG;
611 fLUTbackwardZ2 = new Float_t[ntimebins];
612 for(Int_t i=0; i<ntimebins; i++){
614 z=AliL3Transform::GetZFast(0,i,GetZVertex());
616 fLUTforwardZ2[i]=z*z;
617 z=AliL3Transform::GetZFast(18,i,GetZVertex());
619 fLUTbackwardZ2[i]=z*z;
624 void AliL3HoughTransformerRow::Reset()
626 //Reset all the histograms. Should be done when processing new slice
627 if(fLastTransformer) return;
630 LOG(AliL3Log::kWarning,"AliL3HoughTransformer::Reset","Histograms")
631 <<"No histograms to reset"<<ENDLOG;
635 for(Int_t i=0; i<GetNEtaSegments(); i++)
636 fParamSpace[i]->Reset();
640 AliL3Histogram *hist = fParamSpace[0];
641 Int_t ncellsx = (hist->GetNbinsX()+3)/2;
642 Int_t ncellsy = (hist->GetNbinsY()+3)/2;
643 Int_t ncells = ncellsx*ncellsy;
644 for(Int_t i=0; i<GetNEtaSegments(); i++)
645 memset(fTrackID[i],0,ncells*sizeof(AliL3TrackIndex));
648 AliL3Histogram *hist = fParamSpace[0];
649 Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2);
650 for(Int_t i=0; i<GetNEtaSegments(); i++)
652 memcpy(fGapCount[i],fInitialGapCount,ncells*sizeof(UChar_t));
653 memcpy(fCurrentRowCount[i],fTrackFirstRow,ncells*sizeof(UChar_t));
657 Int_t AliL3HoughTransformerRow::GetEtaIndex(Double_t eta) const
659 //Return the histogram index of the corresponding eta.
661 Double_t etaslice = (GetEtaMax() - GetEtaMin())/GetNEtaSegments();
662 Double_t index = (eta-GetEtaMin())/etaslice;
666 inline AliL3Histogram *AliL3HoughTransformerRow::GetHistogram(Int_t etaindex)
668 // Return a pointer to the histogram which contains etaindex eta slice
669 if(!fParamSpace || etaindex >= GetNEtaSegments() || etaindex < 0)
671 if(!fParamSpace[etaindex])
673 return fParamSpace[etaindex];
676 Double_t AliL3HoughTransformerRow::GetEta(Int_t etaindex,Int_t /*slice*/) const
678 // Return eta calculated in the middle of the eta slice
679 Double_t etaslice = (GetEtaMax()-GetEtaMin())/GetNEtaSegments();
681 eta=(Double_t)((etaindex+0.5)*etaslice);
685 void AliL3HoughTransformerRow::TransformCircle()
687 // This method contains the hough transformation
688 // Depending on the option selected, it reads as an input
689 // either the preloaded array with digits or directly raw
690 // data stream (option fast_raw)
692 TransformCircleFromDigitArray();
693 else if(fTPCRawStream)
694 TransformCircleFromRawStream();
696 void AliL3HoughTransformerRow::TransformCircleFromDigitArray()
698 //Do the Hough Transform
700 Int_t netasegments = GetNEtaSegments();
701 Double_t etamin = GetEtaMin();
702 Double_t etaslice = (GetEtaMax() - etamin)/netasegments;
704 Int_t lowerthreshold = GetLowerThreshold();
706 //Assumes that all the etaslice histos are the same!
707 AliL3Histogram *h = fParamSpace[0];
708 Int_t firstbiny = h->GetFirstYbin();
709 Int_t firstbinx = h->GetFirstXbin();
710 Int_t lastbinx = h->GetLastXbin();
711 Int_t nbinx = h->GetNbinsX()+2;
714 Int_t lastetaindex=-1;
715 AliL3EtaRow *etaclust = new AliL3EtaRow[netasegments];
717 AliL3DigitRowData *tempPt = GetDataPointer();
720 LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformCircle","Data")
721 <<"No input data "<<ENDLOG;
725 Int_t ipatch = GetPatch();
726 Int_t ilastpatch = GetLastPatch();
727 Int_t islice = GetSlice();
732 lutz2 = fLUTforwardZ2;
735 lutz = fLUTbackwardZ;
736 lutz2 = fLUTbackwardZ2;
739 //Loop over the padrows:
740 for(UChar_t i=AliL3Transform::GetFirstRow(ipatch); i<=AliL3Transform::GetLastRow(ipatch); i++)
743 //Flush eta clusters array
744 memset(etaclust,0,netasegments*sizeof(AliL3EtaRow));
746 Float_t x = AliL3Transform::Row2X((Int_t)i);
750 //Get the data on this padrow:
751 AliL3DigitData *digPt = tempPt->fDigitData;
752 if((Int_t)i != (Int_t)tempPt->fRow)
754 LOG(AliL3Log::kError,"AliL3HoughTransformerRow::TransformCircle","Data")
755 <<"AliL3HoughTransform::TransformCircle : Mismatching padrow numbering "<<(Int_t)i<<" "<<(Int_t)tempPt->fRow<<ENDLOG;
758 // cout<<" Starting row "<<i<<endl;
759 //Loop over the data on this padrow:
760 for(UInt_t j=0; j<tempPt->fNDigit; j++)
762 UShort_t charge = digPt[j].fCharge;
763 if((Int_t)charge <= lowerthreshold)
765 UChar_t pad = digPt[j].fPad;
766 UShort_t time = digPt[j].fTime;
770 radius2 = fLUTr2[(Int_t)i][(Int_t)pad];
774 //Transform data to local cartesian coordinates:
775 Float_t z = lutz[(Int_t)time];
776 Float_t z2 = lutz2[(Int_t)time];
777 // Acceptance cut : to be verified
778 // if(radius2<0.72406166*z2) continue;
779 if(x2<0.8464*z2) continue;
781 Double_t r = sqrt(radius2+z2);
782 Double_t eta = 0.5 * log((r+z)/(r-z));
783 //Get the corresponding index, which determines which histogram to fill:
784 Int_t etaindex = (Int_t)((eta-etamin)/etaslice);
787 if(etaindex == lastetaindex) continue;
789 // cout<<" Digit at patch "<<ipatch<<" row "<<i<<" pad "<<(Int_t)pad<<" time "<<time<<" etaslice "<<etaindex<<endl;
791 if(etaindex < 0 || etaindex >= netasegments)
794 if(!etaclust[etaindex].fIsFound)
796 etaclust[etaindex].fStartPad = pad;
797 etaclust[etaindex].fEndPad = pad;
798 etaclust[etaindex].fIsFound = 1;
800 FillClusterMCLabels(digPt[j],&etaclust[etaindex]);
806 if(pad <= (etaclust[etaindex].fEndPad + 1))
808 etaclust[etaindex].fEndPad = pad;
810 FillClusterMCLabels(digPt[j],&etaclust[etaindex]);
815 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
817 etaclust[etaindex].fStartPad = pad;
818 etaclust[etaindex].fEndPad = pad;
821 memset(etaclust[etaindex].fMcLabels,0,MaxTrack);
822 FillClusterMCLabels(digPt[j],&etaclust[etaindex]);
827 lastetaindex = etaindex;
829 //Write remaining clusters
830 for(Int_t etaindex = 0;etaindex < netasegments;etaindex++)
832 //Check for empty row
833 if((etaclust[etaindex].fStartPad == 0) && (etaclust[etaindex].fEndPad == 0)) continue;
835 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
838 //Move the data pointer to the next padrow:
839 AliL3MemHandler::UpdateRowPointer(tempPt);
845 void AliL3HoughTransformerRow::TransformCircleFromRawStream()
847 //Do the Hough Transform
849 Int_t netasegments = GetNEtaSegments();
850 Double_t etamin = GetEtaMin();
851 Double_t etaslice = (GetEtaMax() - etamin)/netasegments;
853 Int_t lowerthreshold = GetLowerThreshold();
855 //Assumes that all the etaslice histos are the same!
856 AliL3Histogram *h = fParamSpace[0];
857 Int_t firstbiny = h->GetFirstYbin();
858 Int_t firstbinx = h->GetFirstXbin();
859 Int_t lastbinx = h->GetLastXbin();
860 Int_t nbinx = h->GetNbinsX()+2;
862 Int_t lastetaindex = -1;
863 AliL3EtaRow *etaclust = new AliL3EtaRow[netasegments];
867 LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformCircle","Data")
868 <<"No input data "<<ENDLOG;
872 Int_t ipatch = GetPatch();
873 UChar_t rowmin = AliL3Transform::GetFirstRowOnDDL(ipatch);
874 UChar_t rowmax = AliL3Transform::GetLastRowOnDDL(ipatch);
875 // Int_t ntimebins = AliL3Transform::GetNTimeBins();
876 Int_t ilastpatch = GetLastPatch();
877 Int_t islice = GetSlice();
882 lutz2 = fLUTforwardZ2;
885 lutz = fLUTbackwardZ;
886 lutz2 = fLUTbackwardZ2;
889 //Flush eta clusters array
890 memset(etaclust,0,netasegments*sizeof(AliL3EtaRow));
899 //Loop over the rawdata:
900 while (fTPCRawStream->Next()) {
902 if(fTPCRawStream->IsNewSector() || fTPCRawStream->IsNewRow()) {
904 //Write remaining clusters
905 for(Int_t etaindex = 0;etaindex < netasegments;etaindex++)
907 //Check for empty row
908 if((etaclust[etaindex].fStartPad == 0) && (etaclust[etaindex].fEndPad == 0)) continue;
910 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
913 Int_t sector=fTPCRawStream->GetSector();
914 Int_t row=fTPCRawStream->GetRow();
916 AliL3Transform::Sector2Slice(slice,srow,sector,row);
918 LOG(AliL3Log::kError,"AliL3DDLDataFileHandler::DDLDigits2Memory","Slice")
919 <<AliL3Log::kDec<<"Found slice "<<slice<<", expected "<<islice<<ENDLOG;
924 npads = AliL3Transform::GetNPads(srow)-1;
926 //Flush eta clusters array
927 memset(etaclust,0,netasegments*sizeof(AliL3EtaRow));
929 x = AliL3Transform::Row2X((Int_t)i);
935 if((i<rowmin)||(i>rowmax))continue;
937 // cout<<" Starting row "<<(UInt_t)i<<endl;
938 //Loop over the data on this padrow:
939 if(fTPCRawStream->IsNewRow() || fTPCRawStream->IsNewPad()) {
940 pad=fTPCRawStream->GetPad();
942 if((pad<0)||(pad>=(npads+1))){
943 LOG(AliL3Log::kError,"AliL3DDLDataFileHandler::DDLDigits2Memory","Pad")
944 <<AliL3Log::kDec<<"Pad value out of bounds "<<pad<<" "
949 radius2 = fLUTr2[(Int_t)i][(Int_t)pad];
953 UShort_t time=fTPCRawStream->GetTime();
955 if((time<0)||(time>=ntimebins)){
956 LOG(AliL3Log::kError,"AliL3DDLDataFileHandler::DDLDigits2Memory","Time")
957 <<AliL3Log::kDec<<"Time out of bounds "<<time<<" "
958 <<AliL3Transform::GetNTimeBins()<<ENDLOG;
963 if(fTPCRawStream->GetSignal() <= lowerthreshold)
966 //Transform data to local cartesian coordinates:
967 Float_t z = lutz[(Int_t)time];
968 Float_t z2 = lutz2[(Int_t)time];
969 // if(radius2<0.72406166*z2) continue;
970 if(x2<0.8464*z2) continue;
972 Double_t r = sqrt(radius2+z2);
973 Double_t eta = 0.5 * log((r+z)/(r-z));
974 //Get the corresponding index, which determines which histogram to fill:
975 Int_t etaindex = (Int_t)((eta-etamin)/etaslice);
978 if(etaindex == lastetaindex) continue;
980 // cout<<" Digit at patch "<<ipatch<<" row "<<i<<" pad "<<(Int_t)pad<<" time "<<time<<" etaslice "<<etaindex<<endl;
982 if(etaindex < 0 || etaindex >= netasegments)
985 if(!etaclust[etaindex].fIsFound)
987 etaclust[etaindex].fStartPad = pad;
988 etaclust[etaindex].fEndPad = pad;
989 etaclust[etaindex].fIsFound = 1;
994 if(pad <= (etaclust[etaindex].fEndPad + 1))
996 etaclust[etaindex].fEndPad = pad;
1000 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
1002 etaclust[etaindex].fStartPad = pad;
1003 etaclust[etaindex].fEndPad = pad;
1007 lastetaindex = etaindex;
1010 //Write remaining clusters
1011 for(Int_t etaindex = 0;etaindex < netasegments;etaindex++)
1013 //Check for empty row
1014 if((etaclust[etaindex].fStartPad == 0) && (etaclust[etaindex].fEndPad == 0)) continue;
1016 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
1023 Int_t AliL3HoughTransformerRow::GetTrackID(Int_t /*etaindex*/,Double_t /*alpha1*/,Double_t /*alpha2*/) const
1025 // Does nothing if do_mc undefined
1026 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackID","Data")
1027 <<"Flag switched off"<<ENDLOG;
1030 Int_t AliL3HoughTransformerRow::GetTrackID(Int_t etaindex,Double_t alpha1,Double_t alpha2) const
1032 // Returns the MC label for a given peak found in the Hough space
1033 if(etaindex < 0 || etaindex > GetNEtaSegments())
1035 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackID","Data")
1036 <<"Wrong etaindex "<<etaindex<<ENDLOG;
1039 AliL3Histogram *hist = fParamSpace[etaindex];
1040 Int_t bin = hist->FindLabelBin(alpha1,alpha2);
1042 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackID()","")
1043 <<"Track candidate outside Hough space boundaries: "<<alpha1<<" "<<alpha2<<ENDLOG;
1048 for(UInt_t i=0; i<(MaxTrack-1); i++)
1050 Int_t nhits=fTrackID[etaindex][bin].fNHits[i];
1051 if(nhits == 0) break;
1055 label = fTrackID[etaindex][bin].fLabel[i];
1060 for(UInt_t i=0; i<(MaxTrack-1); i++)
1062 Int_t nhits=fTrackID[etaindex][bin].fNHits[i];
1063 if(nhits == 0) break;
1066 if(fTrackID[etaindex][bin].fLabel[i]!=label) {
1068 label2 = fTrackID[etaindex][bin].fLabel[i];
1073 LOG(AliL3Log::kDebug,"AliL3HoughTransformerRow::GetTrackID()","")
1074 <<" 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;
1080 inline void AliL3HoughTransformerRow::FillClusterRow(UChar_t i,Int_t binx1,Int_t binx2,UChar_t *ngaps2,UChar_t *currentrow2,UChar_t *lastrow2
1082 ,AliL3EtaRow etaclust,AliL3TrackIndex *trackid
1086 // The method is a part of the fast hough transform.
1087 // It fills one row of the hough space.
1088 // It is called by FillCluster() method inside the
1089 // loop over alpha2 bins
1091 for(Int_t bin=binx1;bin<=binx2;bin++)
1093 if(ngaps2[bin] < MAX_N_GAPS) {
1094 if(i < lastrow2[bin] && i > currentrow2[bin]) {
1095 ngaps2[bin] += (i-currentrow2[bin]-1);
1099 if(i < lastrow2[bin] && i >= currentrow2[bin]) {
1100 for(UInt_t t=0;t<(MaxTrack-1); t++)
1102 Int_t label = etaclust.fMcLabels[t];
1103 if(label == 0) break;
1105 Int_t tempbin2 = (Int_t)(bin/2);
1106 for(c=0; c<(MaxTrack-1); c++)
1107 if(trackid[tempbin2].fLabel[c] == label || trackid[tempbin2].fNHits[c] == 0)
1109 trackid[tempbin2].fLabel[c] = label;
1110 if(trackid[tempbin2].fCurrentRow[c] != i) {
1111 trackid[tempbin2].fNHits[c]++;
1112 trackid[tempbin2].fCurrentRow[c] = i;
1122 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)
1124 // The method is a part of the fast hough transform.
1125 // It fills a TPC cluster into the hough space.
1127 UChar_t *ngaps = fGapCount[etaindex];
1128 UChar_t *currentrow = fCurrentRowCount[etaindex];
1129 UChar_t *lastrow = fTrackLastRow;
1130 UChar_t *prevbin = fPrevBin[etaindex];
1131 UChar_t *nextbin = fNextBin[etaindex];
1132 UChar_t *nextrow = fNextRow[etaindex];
1134 AliL3TrackIndex *trackid = fTrackID[etaindex];
1137 //Do the transformation:
1138 AliL3PadHoughParams *startparams = &fStartPadParams[(Int_t)i][etaclust[etaindex].fStartPad];
1139 AliL3PadHoughParams *endparams = &fEndPadParams[(Int_t)i][etaclust[etaindex].fEndPad];
1141 Float_t alpha1 = startparams->fAlpha;
1142 Float_t deltaalpha1 = startparams->fDeltaAlpha;
1143 Float_t alpha2 = endparams->fAlpha;
1144 Float_t deltaalpha2 = endparams->fDeltaAlpha;
1146 Int_t firstbin1 = startparams->fFirstBin;
1147 Int_t firstbin2 = endparams->fFirstBin;
1148 Int_t firstbin = firstbin1;
1149 if(firstbin>firstbin2) firstbin = firstbin2;
1151 Int_t lastbin1 = startparams->fLastBin;
1152 Int_t lastbin2 = endparams->fLastBin;
1153 Int_t lastbin = lastbin1;
1154 if(lastbin<lastbin2) lastbin = lastbin2;
1156 alpha1 += (firstbin-firstbiny)*deltaalpha1;
1157 alpha2 += (firstbin-firstbiny)*deltaalpha2;
1159 //Fill the histogram along the alpha2 range
1160 if(ilastpatch == -1) {
1161 for(Int_t b=firstbin; b<=lastbin; b++, alpha1 += deltaalpha1, alpha2 += deltaalpha2)
1163 Int_t binx1 = 1 + (Int_t)alpha1;
1164 if(binx1>lastbinx) continue;
1165 if(binx1<firstbinx) binx1 = firstbinx;
1166 Int_t binx2 = 1 + (Int_t)alpha2;
1167 if(binx2<firstbinx) continue;
1168 if(binx2>lastbinx) binx2 = lastbinx;
1171 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::TransformCircle()","")
1172 <<"Wrong filling "<<binx1<<" "<<binx2<<" "<<i<<" "<<etaclust[etaindex].fStartPad<<" "<<etaclust[etaindex].fEndPad<<ENDLOG;
1175 Int_t tempbin = b*nbinx;
1176 UChar_t *ngaps2 = ngaps + tempbin;
1177 UChar_t *currentrow2 = currentrow + tempbin;
1178 UChar_t *lastrow2 = lastrow + tempbin;
1180 Int_t tempbin2 = ((Int_t)(b/2))*((Int_t)((nbinx+1)/2));
1181 AliL3TrackIndex *trackid2 = trackid + tempbin2;
1183 FillClusterRow(i,binx1,binx2,ngaps2,currentrow2,lastrow2
1185 ,etaclust[etaindex],trackid2
1191 for(Int_t b=firstbin; b<=lastbin; b++, alpha1 += deltaalpha1, alpha2 += deltaalpha2)
1193 Int_t binx1 = 1 + (Int_t)alpha1;
1194 if(binx1>lastbinx) continue;
1195 if(binx1<firstbinx) binx1 = firstbinx;
1196 Int_t binx2 = 1 + (Int_t)alpha2;
1197 if(binx2<firstbinx) continue;
1198 if(binx2>lastbinx) binx2 = lastbinx;
1201 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::TransformCircle()","")
1202 <<"Wrong filling "<<binx1<<" "<<binx2<<" "<<i<<" "<<etaclust[etaindex].fStartPad<<" "<<etaclust[etaindex].fEndPad<<ENDLOG;
1205 if(nextrow[b] > b) {
1206 Int_t deltab = (nextrow[b] - b - 1);
1208 alpha1 += deltaalpha1*deltab;
1209 alpha2 += deltaalpha2*deltab;
1212 Int_t tempbin = b*nbinx;
1213 binx1 = (UInt_t)nextbin[binx1 + tempbin];
1214 binx2 = (UInt_t)prevbin[binx2 + tempbin];
1215 if(binx2<binx1) continue;
1216 UChar_t *ngaps2 = ngaps + tempbin;
1217 UChar_t *currentrow2 = currentrow + tempbin;
1218 UChar_t *lastrow2 = lastrow + tempbin;
1220 Int_t tempbin2 = ((Int_t)(b/2))*((Int_t)((nbinx+1)/2));
1221 AliL3TrackIndex *trackid2 = trackid + tempbin2;
1223 FillClusterRow(i,binx1,binx2,ngaps2,currentrow2,lastrow2
1225 ,etaclust[etaindex],trackid2
1233 inline void AliL3HoughTransformerRow::FillClusterMCLabels(AliL3DigitData digpt,AliL3EtaRow *etaclust)
1235 // The method is a part of the fast hough transform.
1236 // It fills the MC labels of a TPC cluster into a
1237 // special hough space array.
1238 for(Int_t t=0; t<3; t++)
1240 Int_t label = digpt.fTrackID[t];
1241 if(label < 0) break;
1243 for(c=0; c<(MaxTrack-1); c++)
1244 if(etaclust->fMcLabels[c] == label || etaclust->fMcLabels[c] == 0)
1247 etaclust->fMcLabels[c] = label;
1252 void AliL3HoughTransformerRow::SetTransformerArrays(AliL3HoughTransformerRow *tr)
1254 // In case of sequential filling of the hough space, the method is used to
1255 // transmit the pointers to the hough arrays from one transformer to the
1258 fGapCount = tr->fGapCount;
1259 fCurrentRowCount = tr->fCurrentRowCount;
1261 fTrackID = tr->fTrackID;
1263 fTrackNRows = tr->fTrackNRows;
1264 fTrackFirstRow = tr->fTrackFirstRow;
1265 fTrackLastRow = tr->fTrackLastRow;
1266 fInitialGapCount = tr->fInitialGapCount;
1268 fPrevBin = tr->fPrevBin;
1269 fNextBin = tr->fNextBin;
1270 fNextRow = tr->fNextRow;
1272 fStartPadParams = tr->fStartPadParams;
1273 fEndPadParams = tr->fEndPadParams;
1274 fLUTr2 = tr->fLUTr2;
1275 fLUTforwardZ = tr->fLUTforwardZ;
1276 fLUTforwardZ2 = tr->fLUTforwardZ2;
1277 fLUTbackwardZ = tr->fLUTbackwardZ;
1278 fLUTbackwardZ2 = tr->fLUTbackwardZ2;
1280 fParamSpace = tr->fParamSpace;