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)));
32 Float_t AliL3HoughTransformerRow::fgDAlpha = 0.22;
33 Float_t AliL3HoughTransformerRow::fgDEta = 0.40;
34 Double_t AliL3HoughTransformerRow::fgEtaCalcParam1 = 1.0289;
35 Double_t AliL3HoughTransformerRow::fgEtaCalcParam2 = 0.15192;
36 Double_t AliL3HoughTransformerRow::fgEtaCalcParam3 = 1./(32.*600.*600.);
38 AliL3HoughTransformerRow::AliL3HoughTransformerRow()
65 AliL3HoughTransformerRow::AliL3HoughTransformerRow(Int_t slice,Int_t patch,Int_t netasegments,Bool_t /*DoMC*/,Float_t zvertex) : AliL3HoughBaseTransformer(slice,patch,netasegments,zvertex)
93 AliL3HoughTransformerRow::~AliL3HoughTransformerRow()
96 if(fLastTransformer) return;
101 for(Int_t i=0; i<GetNEtaSegments(); i++)
103 if(!fTrackID[i]) continue;
113 for(Int_t i=0; i<GetNEtaSegments(); i++)
115 if(!fGapCount[i]) continue;
116 delete [] fGapCount[i];
123 for(Int_t i=0; i<GetNEtaSegments(); i++)
125 if(fCurrentRowCount[i])
126 delete [] fCurrentRowCount[i];
128 delete [] fCurrentRowCount;
129 fCurrentRowCount = 0;
133 delete [] fTrackNRows;
138 delete [] fTrackFirstRow;
143 delete [] fTrackLastRow;
148 delete [] fInitialGapCount;
149 fInitialGapCount = 0;
153 for(Int_t i=0; i<GetNEtaSegments(); i++)
155 if(!fPrevBin[i]) continue;
156 delete [] fPrevBin[i];
163 for(Int_t i=0; i<GetNEtaSegments(); i++)
165 if(!fNextBin[i]) continue;
166 delete [] fNextBin[i];
173 for(Int_t i=0; i<GetNEtaSegments(); i++)
175 if(!fNextRow[i]) continue;
176 delete [] fNextRow[i];
183 for(Int_t i = AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
185 if(!fStartPadParams[i]) continue;
186 delete [] fStartPadParams[i];
188 delete [] fStartPadParams;
193 for(Int_t i = AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
195 if(!fEndPadParams[i]) continue;
196 delete [] fEndPadParams[i];
198 delete [] fEndPadParams;
203 for(Int_t i = AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
205 if(!fLUTr[i]) continue;
213 delete[] fLUTforwardZ;
218 delete[] fLUTbackwardZ;
223 void AliL3HoughTransformerRow::DeleteHistograms()
228 for(Int_t i=0; i<GetNEtaSegments(); i++)
230 if(!fParamSpace[i]) continue;
231 delete fParamSpace[i];
233 delete [] fParamSpace;
236 struct AliL3TrackLength {
237 // Structure is used for temporarely storage of the LUT
238 // which contains the track lengths associated to each hough
240 Bool_t fIsFilled; // Is bin already filled?
241 UInt_t fFirstRow; // First TPC row crossed by the track
242 UInt_t fLastRow; // Last TPC row crossed by the track
243 Float_t fTrackPt; // Pt of the track
246 void AliL3HoughTransformerRow::CreateHistograms(Int_t nxbin,Float_t xmin,Float_t xmax,
247 Int_t nybin,Float_t ymin,Float_t ymax)
249 //Create the histograms (parameter space)
252 //xmin xmax ymin ymax = histogram limits in X and Y
253 if(fLastTransformer) {
254 SetTransformerArrays((AliL3HoughTransformerRow *)fLastTransformer);
257 fParamSpace = new AliL3Histogram*[GetNEtaSegments()];
259 Char_t histname[256];
260 for(Int_t i=0; i<GetNEtaSegments(); i++)
262 sprintf(histname,"paramspace_%d",i);
263 fParamSpace[i] = new AliL3Histogram(histname,"",nxbin,xmin,xmax,nybin,ymin,ymax);
267 AliL3Histogram *hist = fParamSpace[0];
268 Int_t ncellsx = (hist->GetNbinsX()+3)/2;
269 Int_t ncellsy = (hist->GetNbinsY()+3)/2;
270 Int_t ncells = ncellsx*ncellsy;
273 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
274 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(AliL3TrackIndex)<<" bytes to fTrackID"<<ENDLOG;
275 fTrackID = new AliL3TrackIndex*[GetNEtaSegments()];
276 for(Int_t i=0; i<GetNEtaSegments(); i++)
277 fTrackID[i] = new AliL3TrackIndex[ncells];
281 AliL3Histogram *hist = fParamSpace[0];
282 Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2);
285 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
286 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fGapCount"<<ENDLOG;
287 fGapCount = new UChar_t*[GetNEtaSegments()];
288 for(Int_t i=0; i<GetNEtaSegments(); i++)
289 fGapCount[i] = new UChar_t[ncells];
291 if(!fCurrentRowCount)
293 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
294 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fCurrentRowCount"<<ENDLOG;
295 fCurrentRowCount = new UChar_t*[GetNEtaSegments()];
296 for(Int_t i=0; i<GetNEtaSegments(); i++)
297 fCurrentRowCount[i] = new UChar_t[ncells];
301 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
302 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fPrevBin"<<ENDLOG;
303 fPrevBin = new UChar_t*[GetNEtaSegments()];
304 for(Int_t i=0; i<GetNEtaSegments(); i++)
305 fPrevBin[i] = new UChar_t[ncells];
309 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
310 <<"Transformer: Allocating "<<GetNEtaSegments()*ncells*sizeof(UChar_t)<<" bytes to fNextBin"<<ENDLOG;
311 fNextBin = new UChar_t*[GetNEtaSegments()];
312 for(Int_t i=0; i<GetNEtaSegments(); i++)
313 fNextBin[i] = new UChar_t[ncells];
315 Int_t ncellsy = hist->GetNbinsY()+2;
318 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
319 <<"Transformer: Allocating "<<GetNEtaSegments()*ncellsy*sizeof(UChar_t)<<" bytes to fNextRow"<<ENDLOG;
320 fNextRow = new UChar_t*[GetNEtaSegments()];
321 for(Int_t i=0; i<GetNEtaSegments(); i++)
322 fNextRow[i] = new UChar_t[ncellsy];
327 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
328 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fTrackNRows"<<ENDLOG;
329 fTrackNRows = new UChar_t[ncells];
330 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
331 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fTrackFirstRow"<<ENDLOG;
332 fTrackFirstRow = new UChar_t[ncells];
333 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
334 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fTrackLastRow"<<ENDLOG;
335 fTrackLastRow = new UChar_t[ncells];
336 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
337 <<"Transformer: Allocating "<<ncells*sizeof(UChar_t)<<" bytes to fInitialGapCount"<<ENDLOG;
338 fInitialGapCount = new UChar_t[ncells];
341 AliL3HoughTrack track;
342 Int_t xmin = hist->GetFirstXbin();
343 Int_t xmax = hist->GetLastXbin();
344 Int_t xmiddle = (hist->GetNbinsX()+1)/2;
345 Int_t ymin = hist->GetFirstYbin();
346 Int_t ymax = hist->GetLastYbin();
347 Int_t nxbins = hist->GetNbinsX()+2;
348 Int_t nxgrid = (hist->GetNbinsX()+3)/2+1;
349 Int_t nygrid = hist->GetNbinsY()+3;
351 AliL3TrackLength *tracklength = new AliL3TrackLength[nxgrid*nygrid];
352 memset(tracklength,0,nxgrid*nygrid*sizeof(AliL3TrackLength));
354 for(Int_t ybin=ymin-1; ybin<=(ymax+1); ybin++)
356 for(Int_t xbin=xmin-1; xbin<=xmiddle; xbin++)
358 fTrackNRows[xbin + ybin*nxbins] = 255;
359 for(Int_t deltay = 0; deltay <= 1; deltay++) {
360 for(Int_t deltax = 0; deltax <= 1; deltax++) {
362 AliL3TrackLength *curtracklength = &tracklength[(xbin + deltax) + (ybin + deltay)*nxgrid];
363 UInt_t maxfirstrow = 0;
364 UInt_t maxlastrow = 0;
365 Float_t maxtrackpt = 0;
366 if(curtracklength->fIsFilled) {
367 maxfirstrow = curtracklength->fFirstRow;
368 maxlastrow = curtracklength->fLastRow;
369 maxtrackpt = curtracklength->fTrackPt;
372 Float_t xtrack = hist->GetPreciseBinCenterX((Float_t)xbin+0.5*(Float_t)(2*deltax-1));
373 Float_t ytrack = hist->GetPreciseBinCenterY((Float_t)ybin+0.5*(Float_t)(2*deltay-1));
375 Float_t psi = atan((xtrack-ytrack)/(fgBeta1-fgBeta2));
376 Float_t kappa = 2.0*(xtrack*cos(psi)-fgBeta1*sin(psi));
377 track.SetTrackParameters(kappa,psi,1);
378 maxtrackpt = track.GetPt();
379 if(maxtrackpt < 0.9*0.1*AliL3Transform::GetSolenoidField())
381 maxfirstrow = maxlastrow = 0;
382 curtracklength->fIsFilled = kTRUE;
383 curtracklength->fFirstRow = maxfirstrow;
384 curtracklength->fLastRow = maxlastrow;
385 curtracklength->fTrackPt = maxtrackpt;
389 Bool_t firstrow = kFALSE;
390 UInt_t curfirstrow = 0;
391 UInt_t curlastrow = 0;
393 Double_t centerx = track.GetCenterX();
394 Double_t centery = track.GetCenterY();
395 Double_t radius = track.GetRadius();
397 for(Int_t j=AliL3Transform::GetFirstRow(0); j<=AliL3Transform::GetLastRow(5); j++)
400 // if(!track.GetCrossingPoint(j,hit)) continue;
401 hit[0] = AliL3Transform::Row2X(j);
402 Double_t aa = (hit[0] - centerx)*(hit[0] - centerx);
403 Double_t r2 = radius*radius;
407 Double_t aa2 = sqrt(r2 - aa);
408 Double_t y1 = centery + aa2;
409 Double_t y2 = centery - aa2;
411 if(fabs(y2) < fabs(y1)) hit[1] = y2;
415 AliL3Transform::LocHLT2Raw(hit,0,j);
417 if(hit[1]>=0 && hit[1]<AliL3Transform::GetNPads(j))
428 if((curlastrow-curfirstrow) >= (maxlastrow-maxfirstrow)) {
429 maxfirstrow = curfirstrow;
430 maxlastrow = curlastrow;
435 if((curlastrow-curfirstrow) >= (maxlastrow-maxfirstrow)) {
436 maxfirstrow = curfirstrow;
437 maxlastrow = curlastrow;
440 curtracklength->fIsFilled = kTRUE;
441 curtracklength->fFirstRow = maxfirstrow;
442 curtracklength->fLastRow = maxlastrow;
443 curtracklength->fTrackPt = maxtrackpt;
446 if((maxlastrow-maxfirstrow) < fTrackNRows[xbin + ybin*nxbins]) {
447 fTrackNRows[xbin + ybin*nxbins] = maxlastrow-maxfirstrow;
448 fInitialGapCount[xbin + ybin*nxbins] = 1;
449 if((maxlastrow-maxfirstrow+1)<MIN_TRACK_LENGTH)
450 fInitialGapCount[xbin + ybin*nxbins] = MAX_N_GAPS+1;
451 if(maxtrackpt < 0.9*0.1*AliL3Transform::GetSolenoidField())
452 fInitialGapCount[xbin + ybin*nxbins] = MAX_N_GAPS;
453 fTrackFirstRow[xbin + ybin*nxbins] = maxfirstrow;
454 fTrackLastRow[xbin + ybin*nxbins] = maxlastrow;
456 Int_t xmirror = xmax - xbin + 1;
457 Int_t ymirror = ymax - ybin + 1;
458 fTrackNRows[xmirror + ymirror*nxbins] = fTrackNRows[xbin + ybin*nxbins];
459 fInitialGapCount[xmirror + ymirror*nxbins] = fInitialGapCount[xbin + ybin*nxbins];
460 fTrackFirstRow[xmirror + ymirror*nxbins] = fTrackFirstRow[xbin + ybin*nxbins];
461 fTrackLastRow[xmirror + ymirror*nxbins] = fTrackLastRow[xbin + ybin*nxbins];
465 // 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;
468 delete [] tracklength;
473 Int_t nrows = AliL3Transform::GetLastRow(5) - AliL3Transform::GetFirstRow(0) + 1;
474 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
475 <<"Transformer: Allocating about "<<nrows*100*sizeof(AliL3PadHoughParams)<<" bytes to fStartPadParams"<<ENDLOG;
476 fStartPadParams = new AliL3PadHoughParams*[nrows];
477 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
478 <<"Transformer: Allocating about "<<nrows*100*sizeof(AliL3PadHoughParams)<<" bytes to fEndPadParams"<<ENDLOG;
479 fEndPadParams = new AliL3PadHoughParams*[nrows];
480 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
481 <<"Transformer: Allocating about "<<nrows*100*sizeof(Float_t)<<" bytes to fLUTr"<<ENDLOG;
482 fLUTr = new Float_t*[nrows];
484 Float_t beta1 = fgBeta1;
485 Float_t beta2 = fgBeta2;
486 Float_t beta1minusbeta2 = fgBeta1 - fgBeta2;
487 Float_t ymin = hist->GetYmin();
488 Float_t histbin = hist->GetBinWidthY();
489 Float_t xmin = hist->GetXmin();
490 Float_t xmax = hist->GetXmax();
491 Float_t xbin = (xmax-xmin)/hist->GetNbinsX();
492 Int_t firstbinx = hist->GetFirstXbin();
493 Int_t lastbinx = hist->GetLastXbin();
494 Int_t nbinx = hist->GetNbinsX()+2;
495 Int_t firstbin = hist->GetFirstYbin();
496 Int_t lastbin = hist->GetLastYbin();
497 for(Int_t i=AliL3Transform::GetFirstRow(0); i<=AliL3Transform::GetLastRow(5); i++)
499 Int_t npads = AliL3Transform::GetNPads(i);
500 Int_t ipatch = AliL3Transform::GetPatch(i);
501 Double_t padpitch = AliL3Transform::GetPadPitchWidth(ipatch);
502 Float_t x = AliL3Transform::Row2X(i);
505 fStartPadParams[i] = new AliL3PadHoughParams[npads];
506 fEndPadParams[i] = new AliL3PadHoughParams[npads];
507 fLUTr[i] = new Float_t[npads];
508 for(Int_t pad=0; pad<npads; pad++)
510 Float_t y = (pad-0.5*(npads-1))*padpitch;
511 fLUTr[i][pad] = sqrt(x2 + y*y);
512 Float_t starty = (pad-0.5*npads)*padpitch;
513 Float_t r1 = x2 + starty*starty;
514 Float_t xoverr1 = x/r1;
515 Float_t startyoverr1 = starty/r1;
516 Float_t endy = (pad-0.5*(npads-2))*padpitch;
517 Float_t r2 = x2 + endy*endy;
518 Float_t xoverr2 = x/r2;
519 Float_t endyoverr2 = endy/r2;
520 Float_t a1 = beta1minusbeta2/(xoverr1-beta2);
521 Float_t b1 = (xoverr1-beta1)/(xoverr1-beta2);
522 Float_t a2 = beta1minusbeta2/(xoverr2-beta2);
523 Float_t b2 = (xoverr2-beta1)/(xoverr2-beta2);
525 Float_t alpha1 = (a1*startyoverr1+b1*ymin-xmin)/xbin;
526 Float_t deltaalpha1 = b1*histbin/xbin;
528 alpha1 += deltaalpha1;
529 Float_t alpha2 = (a2*endyoverr2+b2*ymin-xmin)/xbin;
530 Float_t deltaalpha2 = b2*histbin/xbin;
532 alpha2 += deltaalpha2;
534 fStartPadParams[i][pad].fAlpha = alpha1;
535 fStartPadParams[i][pad].fDeltaAlpha = deltaalpha1;
536 fEndPadParams[i][pad].fAlpha = alpha2;
537 fEndPadParams[i][pad].fDeltaAlpha = deltaalpha2;
539 //Find the first and last bin rows to be filled
540 Bool_t binfound1 = kFALSE;
541 Bool_t binfound2 = kFALSE;
542 Int_t firstbin1 = lastbin;
543 Int_t firstbin2 = lastbin;
544 Int_t lastbin1 = firstbin;
545 Int_t lastbin2 = firstbin;
546 for(Int_t b=firstbin; b<=lastbin; b++, alpha1 += deltaalpha1, alpha2 += deltaalpha2)
548 Int_t binx1 = 1 + (Int_t)alpha1;
549 if(binx1<=lastbinx) {
550 UChar_t initialgapcount;
552 initialgapcount = fInitialGapCount[binx1 + b*nbinx];
554 initialgapcount = fInitialGapCount[firstbinx + b*nbinx];
555 if(initialgapcount != MAX_N_GAPS) {
563 Int_t binx2 = 1 + (Int_t)alpha2;
564 if(binx2>=firstbin) {
565 UChar_t initialgapcount;
567 initialgapcount = fInitialGapCount[binx2 + b*nbinx];
569 initialgapcount = fInitialGapCount[lastbinx + b*nbinx];
570 if(initialgapcount != MAX_N_GAPS) {
579 fStartPadParams[i][pad].fFirstBin=firstbin1;
580 fStartPadParams[i][pad].fLastBin=lastbin1;
581 fEndPadParams[i][pad].fFirstBin=firstbin2;
582 fEndPadParams[i][pad].fLastBin=lastbin2;
587 //create lookup table for z of the digits
590 Int_t ntimebins = AliL3Transform::GetNTimeBins();
591 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
592 <<"Transformer: Allocating "<<ntimebins*sizeof(Float_t)<<" bytes to fLUTforwardZ"<<ENDLOG;
593 fLUTforwardZ = new Float_t[ntimebins];
594 LOG(AliL3Log::kInformational,"AliL3HoughTransformerRow::CreateHistograms()","")
595 <<"Transformer: Allocating "<<ntimebins*sizeof(Float_t)<<" bytes to fLUTbackwardZ"<<ENDLOG;
596 fLUTbackwardZ = new Float_t[ntimebins];
597 for(Int_t i=0; i<ntimebins; i++){
599 z=AliL3Transform::GetZFast(0,i,GetZVertex());
601 z=AliL3Transform::GetZFast(18,i,GetZVertex());
607 void AliL3HoughTransformerRow::Reset()
609 //Reset all the histograms. Should be done when processing new slice
610 if(fLastTransformer) return;
613 LOG(AliL3Log::kWarning,"AliL3HoughTransformer::Reset","Histograms")
614 <<"No histograms to reset"<<ENDLOG;
618 for(Int_t i=0; i<GetNEtaSegments(); i++)
619 fParamSpace[i]->Reset();
623 AliL3Histogram *hist = fParamSpace[0];
624 Int_t ncellsx = (hist->GetNbinsX()+3)/2;
625 Int_t ncellsy = (hist->GetNbinsY()+3)/2;
626 Int_t ncells = ncellsx*ncellsy;
627 for(Int_t i=0; i<GetNEtaSegments(); i++)
628 memset(fTrackID[i],0,ncells*sizeof(AliL3TrackIndex));
631 AliL3Histogram *hist = fParamSpace[0];
632 Int_t ncells = (hist->GetNbinsX()+2)*(hist->GetNbinsY()+2);
633 for(Int_t i=0; i<GetNEtaSegments(); i++)
635 memcpy(fGapCount[i],fInitialGapCount,ncells*sizeof(UChar_t));
636 memcpy(fCurrentRowCount[i],fTrackFirstRow,ncells*sizeof(UChar_t));
640 Int_t AliL3HoughTransformerRow::GetEtaIndex(Double_t eta) const
642 //Return the histogram index of the corresponding eta.
644 Double_t etaslice = (GetEtaMax() - GetEtaMin())/GetNEtaSegments();
645 Double_t index = (eta-GetEtaMin())/etaslice;
649 inline AliL3Histogram *AliL3HoughTransformerRow::GetHistogram(Int_t etaindex)
651 // Return a pointer to the histogram which contains etaindex eta slice
652 if(!fParamSpace || etaindex >= GetNEtaSegments() || etaindex < 0)
654 if(!fParamSpace[etaindex])
656 return fParamSpace[etaindex];
659 Double_t AliL3HoughTransformerRow::GetEta(Int_t etaindex,Int_t /*slice*/) const
661 // Return eta calculated in the middle of the eta slice
662 Double_t etaslice = (GetEtaMax()-GetEtaMin())/GetNEtaSegments();
664 eta=(Double_t)((etaindex+0.5)*etaslice);
668 void AliL3HoughTransformerRow::TransformCircle()
670 // This method contains the hough transformation
671 // Depending on the option selected, it reads as an input
672 // either the preloaded array with digits or directly raw
673 // data stream (option fast_raw)
675 TransformCircleFromDigitArray();
676 else if(fTPCRawStream)
677 TransformCircleFromRawStream();
679 void AliL3HoughTransformerRow::TransformCircleFromDigitArray()
681 //Do the Hough Transform
683 //Load the parameters used by the fast calculation of eta
684 Double_t etaparam1 = GetEtaCalcParam1();
685 Double_t etaparam2 = GetEtaCalcParam2();
686 Double_t etaparam3 = GetEtaCalcParam3();
688 Int_t netasegments = GetNEtaSegments();
689 Double_t etamin = GetEtaMin();
690 Double_t etaslice = (GetEtaMax() - etamin)/netasegments;
692 Int_t lowerthreshold = GetLowerThreshold();
694 //Assumes that all the etaslice histos are the same!
695 AliL3Histogram *h = fParamSpace[0];
696 Int_t firstbiny = h->GetFirstYbin();
697 Int_t firstbinx = h->GetFirstXbin();
698 Int_t lastbinx = h->GetLastXbin();
699 Int_t nbinx = h->GetNbinsX()+2;
702 Int_t lastetaindex=-1;
703 AliL3EtaRow *etaclust = new AliL3EtaRow[netasegments];
705 AliL3DigitRowData *tempPt = GetDataPointer();
708 LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformCircle","Data")
709 <<"No input data "<<ENDLOG;
713 Int_t ipatch = GetPatch();
714 Int_t ilastpatch = GetLastPatch();
715 Int_t islice = GetSlice();
720 lutz = fLUTbackwardZ;
722 //Loop over the padrows:
723 for(UChar_t i=AliL3Transform::GetFirstRow(ipatch); i<=AliL3Transform::GetLastRow(ipatch); i++)
726 //Flush eta clusters array
727 memset(etaclust,0,netasegments*sizeof(AliL3EtaRow));
731 //Get the data on this padrow:
732 AliL3DigitData *digPt = tempPt->fDigitData;
733 if((Int_t)i != (Int_t)tempPt->fRow)
735 LOG(AliL3Log::kError,"AliL3HoughTransformerRow::TransformCircle","Data")
736 <<"AliL3HoughTransform::TransformCircle : Mismatching padrow numbering "<<(Int_t)i<<" "<<(Int_t)tempPt->fRow<<ENDLOG;
739 // cout<<" Starting row "<<i<<endl;
740 //Loop over the data on this padrow:
741 for(UInt_t j=0; j<tempPt->fNDigit; j++)
743 UShort_t charge = digPt[j].fCharge;
744 if((Int_t)charge <= lowerthreshold)
746 UChar_t pad = digPt[j].fPad;
747 UShort_t time = digPt[j].fTime;
751 radius = fLUTr[(Int_t)i][(Int_t)pad];
755 Float_t z = lutz[(Int_t)time];
756 Double_t radiuscorr = radius*(1.+etaparam3*radius*radius);
757 Double_t zovr = z/radiuscorr;
758 Double_t eta = (etaparam1-etaparam2*fabs(zovr))*zovr;
759 //Get the corresponding index, which determines which histogram to fill:
760 Int_t etaindex = (Int_t)((eta-etamin)/etaslice);
763 if(etaindex == lastetaindex) continue;
765 // cout<<" Digit at patch "<<ipatch<<" row "<<i<<" pad "<<(Int_t)pad<<" time "<<time<<" etaslice "<<etaindex<<endl;
767 if(etaindex < 0 || etaindex >= netasegments)
770 if(!etaclust[etaindex].fIsFound)
772 etaclust[etaindex].fStartPad = pad;
773 etaclust[etaindex].fEndPad = pad;
774 etaclust[etaindex].fIsFound = 1;
776 FillClusterMCLabels(digPt[j],&etaclust[etaindex]);
782 if(pad <= (etaclust[etaindex].fEndPad + 1))
784 etaclust[etaindex].fEndPad = pad;
786 FillClusterMCLabels(digPt[j],&etaclust[etaindex]);
791 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
793 etaclust[etaindex].fStartPad = pad;
794 etaclust[etaindex].fEndPad = pad;
797 memset(etaclust[etaindex].fMcLabels,0,MaxTrack);
798 FillClusterMCLabels(digPt[j],&etaclust[etaindex]);
803 lastetaindex = etaindex;
805 //Write remaining clusters
806 for(Int_t etaindex = 0;etaindex < netasegments;etaindex++)
808 //Check for empty row
809 if((etaclust[etaindex].fStartPad == 0) && (etaclust[etaindex].fEndPad == 0)) continue;
811 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
814 //Move the data pointer to the next padrow:
815 AliL3MemHandler::UpdateRowPointer(tempPt);
821 void AliL3HoughTransformerRow::TransformCircleFromRawStream()
823 //Do the Hough Transform
825 //Load the parameters used by the fast calculation of eta
826 Double_t etaparam1 = GetEtaCalcParam1();
827 Double_t etaparam2 = GetEtaCalcParam2();
828 Double_t etaparam3 = GetEtaCalcParam3();
830 Int_t netasegments = GetNEtaSegments();
831 Double_t etamin = GetEtaMin();
832 Double_t etaslice = (GetEtaMax() - etamin)/netasegments;
834 Int_t lowerthreshold = GetLowerThreshold();
836 //Assumes that all the etaslice histos are the same!
837 AliL3Histogram *h = fParamSpace[0];
838 Int_t firstbiny = h->GetFirstYbin();
839 Int_t firstbinx = h->GetFirstXbin();
840 Int_t lastbinx = h->GetLastXbin();
841 Int_t nbinx = h->GetNbinsX()+2;
843 Int_t lastetaindex = -1;
844 AliL3EtaRow *etaclust = new AliL3EtaRow[netasegments];
848 LOG(AliL3Log::kError,"AliL3HoughTransformer::TransformCircle","Data")
849 <<"No input data "<<ENDLOG;
853 Int_t ipatch = GetPatch();
854 UChar_t rowmin = AliL3Transform::GetFirstRowOnDDL(ipatch);
855 UChar_t rowmax = AliL3Transform::GetLastRowOnDDL(ipatch);
856 // Int_t ntimebins = AliL3Transform::GetNTimeBins();
857 Int_t ilastpatch = GetLastPatch();
858 Int_t islice = GetSlice();
863 lutz = fLUTbackwardZ;
865 //Flush eta clusters array
866 memset(etaclust,0,netasegments*sizeof(AliL3EtaRow));
873 //Loop over the rawdata:
874 while (fTPCRawStream->Next()) {
876 if(fTPCRawStream->IsNewSector() || fTPCRawStream->IsNewRow()) {
878 //Write remaining clusters
879 for(Int_t etaindex = 0;etaindex < netasegments;etaindex++)
881 //Check for empty row
882 if((etaclust[etaindex].fStartPad == 0) && (etaclust[etaindex].fEndPad == 0)) continue;
884 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
887 Int_t sector=fTPCRawStream->GetSector();
888 Int_t row=fTPCRawStream->GetRow();
890 AliL3Transform::Sector2Slice(slice,srow,sector,row);
892 LOG(AliL3Log::kError,"AliL3DDLDataFileHandler::DDLDigits2Memory","Slice")
893 <<AliL3Log::kDec<<"Found slice "<<slice<<", expected "<<islice<<ENDLOG;
898 npads = AliL3Transform::GetNPads(srow)-1;
900 //Flush eta clusters array
901 memset(etaclust,0,netasegments*sizeof(AliL3EtaRow));
907 if((i<rowmin)||(i>rowmax))continue;
909 // cout<<" Starting row "<<(UInt_t)i<<endl;
910 //Loop over the data on this padrow:
911 if(fTPCRawStream->IsNewRow() || fTPCRawStream->IsNewPad()) {
912 pad=fTPCRawStream->GetPad();
914 if((pad<0)||(pad>=(npads+1))){
915 LOG(AliL3Log::kError,"AliL3DDLDataFileHandler::DDLDigits2Memory","Pad")
916 <<AliL3Log::kDec<<"Pad value out of bounds "<<pad<<" "
921 radius = fLUTr[(Int_t)i][(Int_t)pad];
925 UShort_t time=fTPCRawStream->GetTime();
927 if((time<0)||(time>=ntimebins)){
928 LOG(AliL3Log::kError,"AliL3DDLDataFileHandler::DDLDigits2Memory","Time")
929 <<AliL3Log::kDec<<"Time out of bounds "<<time<<" "
930 <<AliL3Transform::GetNTimeBins()<<ENDLOG;
935 if(fTPCRawStream->GetSignal() <= lowerthreshold)
938 Float_t z = lutz[(Int_t)time];
939 Double_t radiuscorr = radius*(1.+etaparam3*radius*radius);
940 Double_t zovr = z/radiuscorr;
941 Double_t eta = (etaparam1-etaparam2*fabs(zovr))*zovr;
942 //Get the corresponding index, which determines which histogram to fill:
943 Int_t etaindex = (Int_t)((eta-etamin)/etaslice);
946 if(etaindex == lastetaindex) continue;
948 // cout<<" Digit at patch "<<ipatch<<" row "<<i<<" pad "<<(Int_t)pad<<" time "<<time<<" etaslice "<<etaindex<<endl;
950 if(etaindex < 0 || etaindex >= netasegments)
953 if(!etaclust[etaindex].fIsFound)
955 etaclust[etaindex].fStartPad = pad;
956 etaclust[etaindex].fEndPad = pad;
957 etaclust[etaindex].fIsFound = 1;
962 if(pad <= (etaclust[etaindex].fEndPad + 1))
964 etaclust[etaindex].fEndPad = pad;
968 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
970 etaclust[etaindex].fStartPad = pad;
971 etaclust[etaindex].fEndPad = pad;
975 lastetaindex = etaindex;
978 //Write remaining clusters
979 for(Int_t etaindex = 0;etaindex < netasegments;etaindex++)
981 //Check for empty row
982 if((etaclust[etaindex].fStartPad == 0) && (etaclust[etaindex].fEndPad == 0)) continue;
984 FillCluster(i,etaindex,etaclust,ilastpatch,firstbinx,lastbinx,nbinx,firstbiny);
991 Int_t AliL3HoughTransformerRow::GetTrackID(Int_t /*etaindex*/,Double_t /*alpha1*/,Double_t /*alpha2*/) const
993 // Does nothing if do_mc undefined
994 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackID","Data")
995 <<"Flag switched off"<<ENDLOG;
998 Int_t AliL3HoughTransformerRow::GetTrackID(Int_t etaindex,Double_t alpha1,Double_t alpha2) const
1000 // Returns the MC label for a given peak found in the Hough space
1001 if(etaindex < 0 || etaindex > GetNEtaSegments())
1003 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackID","Data")
1004 <<"Wrong etaindex "<<etaindex<<ENDLOG;
1007 AliL3Histogram *hist = fParamSpace[etaindex];
1008 Int_t bin = hist->FindLabelBin(alpha1,alpha2);
1010 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackID()","")
1011 <<"Track candidate outside Hough space boundaries: "<<alpha1<<" "<<alpha2<<ENDLOG;
1016 for(UInt_t i=0; i<(MaxTrack-1); i++)
1018 Int_t nhits=fTrackID[etaindex][bin].fNHits[i];
1019 if(nhits == 0) break;
1023 label = fTrackID[etaindex][bin].fLabel[i];
1028 for(UInt_t i=0; i<(MaxTrack-1); i++)
1030 Int_t nhits=fTrackID[etaindex][bin].fNHits[i];
1031 if(nhits == 0) break;
1034 if(fTrackID[etaindex][bin].fLabel[i]!=label) {
1036 label2 = fTrackID[etaindex][bin].fLabel[i];
1041 LOG(AliL3Log::kDebug,"AliL3HoughTransformerRow::GetTrackID()","")
1042 <<" 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;
1048 Int_t AliL3HoughTransformerRow::GetTrackLength(Double_t alpha1,Double_t alpha2,Int_t *rows) const
1050 // Returns the track length for a given peak found in the Hough space
1052 AliL3Histogram *hist = fParamSpace[0];
1053 Int_t bin = hist->FindBin(alpha1,alpha2);
1055 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::GetTrackLength()","")
1056 <<"Track candidate outside Hough space boundaries: "<<alpha1<<" "<<alpha2<<ENDLOG;
1059 rows[0] = fTrackFirstRow[bin];
1060 rows[1] = fTrackLastRow[bin];
1065 inline void AliL3HoughTransformerRow::FillClusterRow(UChar_t i,Int_t binx1,Int_t binx2,UChar_t *ngaps2,UChar_t *currentrow2,UChar_t *lastrow2
1067 ,AliL3EtaRow etaclust,AliL3TrackIndex *trackid
1071 // The method is a part of the fast hough transform.
1072 // It fills one row of the hough space.
1073 // It is called by FillCluster() method inside the
1074 // loop over alpha2 bins
1076 for(Int_t bin=binx1;bin<=binx2;bin++)
1078 if(ngaps2[bin] < MAX_N_GAPS) {
1079 if(i < lastrow2[bin] && i > currentrow2[bin]) {
1080 ngaps2[bin] += (i-currentrow2[bin]-1);
1084 if(i < lastrow2[bin] && i >= currentrow2[bin]) {
1085 for(UInt_t t=0;t<(MaxTrack-1); t++)
1087 Int_t label = etaclust.fMcLabels[t];
1088 if(label == 0) break;
1090 Int_t tempbin2 = (Int_t)(bin/2);
1091 for(c=0; c<(MaxTrack-1); c++)
1092 if(trackid[tempbin2].fLabel[c] == label || trackid[tempbin2].fNHits[c] == 0)
1094 trackid[tempbin2].fLabel[c] = label;
1095 if(trackid[tempbin2].fCurrentRow[c] != i) {
1096 trackid[tempbin2].fNHits[c]++;
1097 trackid[tempbin2].fCurrentRow[c] = i;
1107 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)
1109 // The method is a part of the fast hough transform.
1110 // It fills a TPC cluster into the hough space.
1112 UChar_t *ngaps = fGapCount[etaindex];
1113 UChar_t *currentrow = fCurrentRowCount[etaindex];
1114 UChar_t *lastrow = fTrackLastRow;
1115 UChar_t *prevbin = fPrevBin[etaindex];
1116 UChar_t *nextbin = fNextBin[etaindex];
1117 UChar_t *nextrow = fNextRow[etaindex];
1119 AliL3TrackIndex *trackid = fTrackID[etaindex];
1122 //Do the transformation:
1123 AliL3PadHoughParams *startparams = &fStartPadParams[(Int_t)i][etaclust[etaindex].fStartPad];
1124 AliL3PadHoughParams *endparams = &fEndPadParams[(Int_t)i][etaclust[etaindex].fEndPad];
1126 Float_t alpha1 = startparams->fAlpha;
1127 Float_t deltaalpha1 = startparams->fDeltaAlpha;
1128 Float_t alpha2 = endparams->fAlpha;
1129 Float_t deltaalpha2 = endparams->fDeltaAlpha;
1131 Int_t firstbin1 = startparams->fFirstBin;
1132 Int_t firstbin2 = endparams->fFirstBin;
1133 Int_t firstbin = firstbin1;
1134 if(firstbin>firstbin2) firstbin = firstbin2;
1136 Int_t lastbin1 = startparams->fLastBin;
1137 Int_t lastbin2 = endparams->fLastBin;
1138 Int_t lastbin = lastbin1;
1139 if(lastbin<lastbin2) lastbin = lastbin2;
1141 alpha1 += (firstbin-firstbiny)*deltaalpha1;
1142 alpha2 += (firstbin-firstbiny)*deltaalpha2;
1144 //Fill the histogram along the alpha2 range
1145 if(ilastpatch == -1) {
1146 for(Int_t b=firstbin; b<=lastbin; b++, alpha1 += deltaalpha1, alpha2 += deltaalpha2)
1148 Int_t binx1 = 1 + (Int_t)alpha1;
1149 if(binx1>lastbinx) continue;
1150 if(binx1<firstbinx) binx1 = firstbinx;
1151 Int_t binx2 = 1 + (Int_t)alpha2;
1152 if(binx2<firstbinx) continue;
1153 if(binx2>lastbinx) binx2 = lastbinx;
1156 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::TransformCircle()","")
1157 <<"Wrong filling "<<binx1<<" "<<binx2<<" "<<i<<" "<<etaclust[etaindex].fStartPad<<" "<<etaclust[etaindex].fEndPad<<ENDLOG;
1160 Int_t tempbin = b*nbinx;
1161 UChar_t *ngaps2 = ngaps + tempbin;
1162 UChar_t *currentrow2 = currentrow + tempbin;
1163 UChar_t *lastrow2 = lastrow + tempbin;
1165 Int_t tempbin2 = ((Int_t)(b/2))*((Int_t)((nbinx+1)/2));
1166 AliL3TrackIndex *trackid2 = trackid + tempbin2;
1168 FillClusterRow(i,binx1,binx2,ngaps2,currentrow2,lastrow2
1170 ,etaclust[etaindex],trackid2
1176 for(Int_t b=firstbin; b<=lastbin; b++, alpha1 += deltaalpha1, alpha2 += deltaalpha2)
1178 Int_t binx1 = 1 + (Int_t)alpha1;
1179 if(binx1>lastbinx) continue;
1180 if(binx1<firstbinx) binx1 = firstbinx;
1181 Int_t binx2 = 1 + (Int_t)alpha2;
1182 if(binx2<firstbinx) continue;
1183 if(binx2>lastbinx) binx2 = lastbinx;
1186 LOG(AliL3Log::kWarning,"AliL3HoughTransformerRow::TransformCircle()","")
1187 <<"Wrong filling "<<binx1<<" "<<binx2<<" "<<i<<" "<<etaclust[etaindex].fStartPad<<" "<<etaclust[etaindex].fEndPad<<ENDLOG;
1190 if(nextrow[b] > b) {
1191 Int_t deltab = (nextrow[b] - b - 1);
1193 alpha1 += deltaalpha1*deltab;
1194 alpha2 += deltaalpha2*deltab;
1197 Int_t tempbin = b*nbinx;
1198 binx1 = (UInt_t)nextbin[binx1 + tempbin];
1199 binx2 = (UInt_t)prevbin[binx2 + tempbin];
1200 if(binx2<binx1) continue;
1201 UChar_t *ngaps2 = ngaps + tempbin;
1202 UChar_t *currentrow2 = currentrow + tempbin;
1203 UChar_t *lastrow2 = lastrow + tempbin;
1205 Int_t tempbin2 = ((Int_t)(b/2))*((Int_t)((nbinx+1)/2));
1206 AliL3TrackIndex *trackid2 = trackid + tempbin2;
1208 FillClusterRow(i,binx1,binx2,ngaps2,currentrow2,lastrow2
1210 ,etaclust[etaindex],trackid2
1218 inline void AliL3HoughTransformerRow::FillClusterMCLabels(AliL3DigitData digpt,AliL3EtaRow *etaclust)
1220 // The method is a part of the fast hough transform.
1221 // It fills the MC labels of a TPC cluster into a
1222 // special hough space array.
1223 for(Int_t t=0; t<3; t++)
1225 Int_t label = digpt.fTrackID[t];
1226 if(label < 0) break;
1228 for(c=0; c<(MaxTrack-1); c++)
1229 if(etaclust->fMcLabels[c] == label || etaclust->fMcLabels[c] == 0)
1232 etaclust->fMcLabels[c] = label;
1237 void AliL3HoughTransformerRow::SetTransformerArrays(AliL3HoughTransformerRow *tr)
1239 // In case of sequential filling of the hough space, the method is used to
1240 // transmit the pointers to the hough arrays from one transformer to the
1243 fGapCount = tr->fGapCount;
1244 fCurrentRowCount = tr->fCurrentRowCount;
1246 fTrackID = tr->fTrackID;
1248 fTrackNRows = tr->fTrackNRows;
1249 fTrackFirstRow = tr->fTrackFirstRow;
1250 fTrackLastRow = tr->fTrackLastRow;
1251 fInitialGapCount = tr->fInitialGapCount;
1253 fPrevBin = tr->fPrevBin;
1254 fNextBin = tr->fNextBin;
1255 fNextRow = tr->fNextRow;
1257 fStartPadParams = tr->fStartPadParams;
1258 fEndPadParams = tr->fEndPadParams;
1260 fLUTforwardZ = tr->fLUTforwardZ;
1261 fLUTbackwardZ = tr->fLUTbackwardZ;
1263 fParamSpace = tr->fParamSpace;