]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDtrackingChamber.cxx
improved verbosity in the tracking sector
[u/mrichter/AliRoot.git] / TRD / AliTRDtrackingChamber.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 /* $Id: AliTRDtrackingChamber.cxx 23810 2008-02-08 09:00:27Z hristov $ */
17
18 ////////////////////////////////////////////////////////////////////////////
19 //                                                                        //
20 //  Tracking in one chamber                                               //
21 //                                                                        //
22 //  Authors:                                                              //
23 //    Alex Bercuci <A.Bercuci@gsi.de>                                     //
24 //    Markus Fasel <M.Fasel@gsi.de>                                       //
25 //                                                                        //
26 ////////////////////////////////////////////////////////////////////////////
27
28 #include "AliTRDtrackingChamber.h"
29
30 #include "TMath.h"
31 #include "TMatrixTBase.h"
32 #include <TTreeStream.h>
33
34 #include "AliTRDReconstructor.h"
35 #include "AliTRDrecoParam.h"
36 #include "AliTRDtrackerV1.h"
37 #include "AliTRDgeometry.h"
38 #include "AliTRDpadPlane.h"
39 #include "AliTRDcalibDB.h"
40 #include "Cal/AliTRDCalDet.h"
41 #include "Cal/AliTRDCalROC.h"
42
43 ClassImp(AliTRDtrackingChamber)
44
45 //_______________________________________________________
46 AliTRDtrackingChamber::AliTRDtrackingChamber() 
47   :TObject()
48   ,fDetector(-1)
49   ,fX0(0.)
50 {}  
51
52 //_______________________________________________________
53 void AliTRDtrackingChamber::Clear(const Option_t *opt)
54 {
55   for(Int_t itb=0; itb<kNTimeBins; itb++) fTB[itb].Clear(opt);
56 }
57
58 //_______________________________________________________
59 void AliTRDtrackingChamber::InsertCluster(AliTRDcluster *c, Int_t index)
60 {
61   fTB[c->GetPadTime()].InsertCluster(c, index);
62 }
63
64 //_______________________________________________________
65 Bool_t AliTRDtrackingChamber::Build(AliTRDgeometry *geo, const AliTRDCalDet *cal, Bool_t hlt)
66 {
67 // Init chamber and all time bins (AliTRDchamberTimeBin)
68 // Calculates radial position of the chamber based on 
69 // radial positions of the time bins (calibration/alignment aware)
70 //
71   if(fDetector < 0 || fDetector >= AliTRDgeometry::kNdet){
72     AliWarning(Form("Detector index not set correctly to %d", fDetector));
73     return kFALSE;
74   }
75
76   Int_t stack = geo->GetStack(fDetector);
77   Int_t layer = geo->GetLayer(fDetector);
78   AliTRDpadPlane *pp = geo->GetPadPlane(layer, stack);
79   Double_t zl = pp->GetRow0ROC() - pp->GetRowEndROC();
80   Double_t z0 = geo->GetRow0(layer, stack, 0) - zl;
81   Int_t nrows = pp->GetNrows();
82   
83   Int_t index[50], jtb = 0;
84   for(Int_t itb=0; itb<kNTimeBins; itb++){ 
85     if(!fTB[itb]) continue;
86     fTB[itb].SetRange(z0, zl);
87     fTB[itb].SetNRows(nrows);
88     fTB[itb].BuildIndices();
89     index[jtb++] = itb;
90   }     
91   if(jtb<2) return kFALSE;
92   
93   
94   // ESTIMATE POSITION OF PAD PLANE FOR THIS CHAMBER
95   Double_t x0 = fTB[index[0]].GetX();
96   Double_t x1 = fTB[index[1]].GetX();
97   Double_t dx = (x0 - x1)/(index[1] - index[0]); 
98
99   Int_t t0 = (Int_t)cal->GetValue(fDetector);
100   if(!hlt){
101     Double_t mean = 0.0;
102     AliTRDCalROC *roc = AliTRDcalibDB::Instance()->GetT0ROC(fDetector);
103     for(Int_t k = 0; k<roc->GetNchannels(); k++) mean += roc->GetValue(k); 
104     mean /= roc->GetNchannels();
105     t0 = (Int_t)(cal->GetValue(fDetector) + mean);
106   }
107
108   fX0 = x0 + dx*(index[0] - t0);        
109   return kTRUE;
110 }
111   
112 //_______________________________________________________       
113 Int_t AliTRDtrackingChamber::GetNClusters() const
114 {
115 // Returns number of clusters in chamber
116 //
117   Int_t n = 0;
118   for(Int_t itb=0; itb<kNTimeBins; itb++){ 
119     n += Int_t(fTB[itb]);
120   }
121   return n;     
122 }       
123
124 //_______________________________________________________
125 Double_t AliTRDtrackingChamber::GetQuality()
126 {
127   //
128   // Calculate chamber quality for seeding.
129   // 
130   //
131   // Parameters :
132   //   layers : Array of propagation layers for this plane.
133   //
134   // Output :
135   //   plane quality factor for seeding
136   // 
137   // Detailed description
138   //
139   // The quality of the plane for seeding is higher if:
140   //  1. the average timebin population is closer to an integer number
141   //  2. the distribution of clusters/timebin is closer to a uniform distribution.
142   //    - the slope of the first derivative of a parabolic fit is small or
143   //    - the slope of a linear fit is small
144   //
145
146   Int_t ncl   = 0;
147   Int_t nused = 0;
148   Int_t nClLayer;
149   for(int itb=0; itb<kNTimeBins; itb++){
150     if(!(nClLayer = fTB[itb].GetNClusters())) continue;
151     ncl += nClLayer;
152     for(Int_t incl = 0; incl < nClLayer; incl++){
153       if((fTB[itb].GetCluster(incl))->IsUsed()) nused++;
154     }
155   }
156   
157   // calculate the deviation of the mean number of clusters from the
158   // closest integer values
159   Float_t nclMed = float(ncl-nused)/AliTRDtrackerV1::GetNTimeBins();
160   Int_t ncli = Int_t(nclMed);
161   Float_t nclDev = TMath::Abs(nclMed - TMath::Max(ncli, 1));
162   nclDev -= (nclDev>.5) && ncli ? 1. : 0.;
163   return TMath::Exp(-5.*TMath::Abs(nclDev));
164
165 //      // get slope of the derivative
166 //      if(!fitter.Eval()) return quality;
167 //      fitter.PrintResults(3);
168 //      Double_t a = fitter.GetParameter(1);
169 // 
170 //      printf("ncl_dev(%f)  a(%f)\n", ncl_dev, a);
171 //      return quality*TMath::Exp(-a);
172
173 }
174
175
176 //_______________________________________________________
177 Bool_t AliTRDtrackingChamber::GetSeedingLayer(AliTRDchamberTimeBin *&fakeLayer, AliTRDgeometry *geo, const AliTRDReconstructor *rec)
178 {
179   //
180   // Creates a seeding layer
181   //
182   
183   // constants
184   const Int_t kMaxRows = 16;
185   const Int_t kMaxCols = 144;
186   const Int_t kMaxPads = 2304;
187   Int_t timeBinMin = rec->GetRecoParam()->GetNumberOfPresamples();
188   Int_t timeBinMax = rec->GetRecoParam()->GetNumberOfPostsamples();
189
190   // Get the geometrical data of the chamber
191   Int_t layer = geo->GetLayer(fDetector);
192   Int_t stack = geo->GetStack(fDetector);
193   Int_t sector= geo->GetSector(fDetector);
194   AliTRDpadPlane *pp = geo->GetPadPlane(layer, stack);
195   Int_t nCols = pp->GetNcols();
196   Float_t ymin = TMath::Min(pp->GetCol0(), pp->GetColEnd());
197   Float_t ymax = TMath::Max(pp->GetCol0(), pp->GetColEnd());
198   Float_t zmin = TMath::Min(pp->GetRow0(), pp->GetRowEnd());
199   Float_t zmax = TMath::Max(pp->GetRow0(), pp->GetRowEnd());
200   Float_t z0 = -1., zl = -1.;
201   Int_t nRows = pp->GetNrows();
202   Float_t binlength = (ymax - ymin)/nCols; 
203   //AliInfo(Form("ymin(%f) ymax(%f) zmin(%f) zmax(%f) nRows(%d) binlength(%f)", ymin, ymax, zmin, zmax, nRows, binlength));
204   
205   // Fill the histogram
206   Int_t nClusters;      
207   Int_t *histogram[kMaxRows];                                                                                   // 2D-Histogram
208   Int_t hvals[kMaxPads + 1];    memset(hvals, 0, sizeof(Int_t)*kMaxPads);        // one entry in addition for termination flag
209   Float_t *sigmas[kMaxRows];
210   Float_t svals[kMaxPads];      memset(svals, 0, sizeof(Float_t)*kMaxPads);     
211   AliTRDcluster *c = 0x0;
212   for(Int_t irs = 0; irs < kMaxRows; irs++){
213     histogram[irs] = &hvals[irs*kMaxCols];
214     sigmas[irs] = &svals[irs*kMaxCols];
215   }
216   for(Int_t iTime = timeBinMin; iTime < kNTimeBins-timeBinMax; iTime++){
217     if(!(nClusters = fTB[iTime].GetNClusters())) continue;
218     z0 = fTB[iTime].GetZ0();
219     zl = fTB[iTime].GetDZ0();
220     for(Int_t incl = 0; incl < nClusters; incl++){
221       c = fTB[iTime].GetCluster(incl);  
222       histogram[c->GetPadRow()][c->GetPadCol()]++;
223       sigmas[c->GetPadRow()][c->GetPadCol()] += c->GetSigmaZ2();
224     }
225   }
226   
227 // Now I have everything in the histogram, do the selection
228   //Int_t nPads = nCols * nRows;
229   // This is what we are interested in: The center of gravity of the best candidates
230   Float_t cogyvals[kMaxPads]; memset(cogyvals, 0, sizeof(Float_t)*kMaxPads);
231   Float_t cogzvals[kMaxPads]; memset(cogzvals, 0, sizeof(Float_t)*kMaxPads);
232   Float_t *cogy[kMaxRows];
233   Float_t *cogz[kMaxRows];
234   
235   // Lookup-Table storing coordinates according to the bins
236   Float_t yLengths[kMaxCols];
237   Float_t zLengths[kMaxRows];
238   for(Int_t icnt = 0; icnt < nCols; icnt++){
239     yLengths[icnt] = pp->GetColPos(nCols - 1 - icnt) + binlength/2;
240   }
241   for(Int_t icnt = 0; icnt < nRows; icnt++){
242     zLengths[icnt] = pp->GetRowPos(icnt) - pp->GetRowSize(icnt)/2;
243   }
244
245   // A bitfield is used to mask the pads as usable
246   Short_t mask[kMaxCols]; memset(mask, 0 ,sizeof(Short_t) * kMaxCols);//bool mvals[kMaxPads];
247   for(UChar_t icount = 0; icount < nRows; icount++){
248     cogy[icount] = &cogyvals[icount*kMaxCols];
249     cogz[icount] = &cogzvals[icount*kMaxCols];
250   }
251   // In this array the array position of the best candidates will be stored
252   Int_t   cand[AliTRDtrackerV1::kMaxTracksStack];
253   Float_t sigcands[AliTRDtrackerV1::kMaxTracksStack];
254   
255   // helper variables
256   Int_t indices[kMaxPads]; memset(indices, -1, sizeof(Int_t)*kMaxPads);
257   Int_t nCandidates = 0;
258   Float_t norm, cogv;
259   // histogram filled -> Select best bins
260   Int_t nPads = nCols * nRows;
261   // take out all the bins which have less than 3 entries (faster sorting)
262   Int_t content[kMaxPads], dictionary[kMaxPads], nCont = 0, padnumber = 0;
263   Int_t *iter = &hvals[0], *citer = &content[0], *diter =  &dictionary[0]; // iterators for preselection
264   const Int_t threshold = 2;
265   hvals[nPads] = -1; // termination for iterator
266   do{
267     if(*iter > threshold){
268       *(citer++) = *iter;
269       *(diter++) = padnumber;
270       nCont++;
271     }
272     padnumber++;
273   }while(*(++iter) != -1);
274   TMath::Sort(nCont, content, indices);         
275
276   Int_t col, row, lower, lower1, upper, upper1;
277   for(Int_t ib = 0; ib < nCont; ib++){
278     if(nCandidates >= AliTRDtrackerV1::kMaxTracksStack){
279       printf("Number of seed candidates %d exceeded maximum allowed per stack %d", nCandidates, AliTRDtrackerV1::kMaxTracksStack);
280       break;
281     }
282     // Positions
283     row = dictionary[indices[ib]]/nCols;
284     col = dictionary[indices[ib]]%nCols;
285     // here will be the threshold condition:
286     if((mask[col] & (1 << row)) != 0) continue;         // Pad is masked: continue
287     //  if(histogram[row][col] < TMath::Max(threshold, 1)){     // of course at least one cluster is needed
288     //          break;                  // number of clusters below threshold: break;
289     //  } 
290     // passing: Mark the neighbors
291     lower  = TMath::Max(col - 1, 0); upper  = TMath::Min(col + 2, nCols);
292     lower1 = TMath::Max(row - 1, 0); upper1 = TMath::Min(row + 2, nCols);
293     for(Int_t ic = lower; ic < upper; ++ic)
294       for(Int_t ir = lower1; ir < upper1; ++ir){
295         if(ic == col && ir == row) continue;
296         mask[ic] |= (1 << ir);
297       }
298     // Storing the position in an array
299     // testing for neigboring
300     cogv = 0;
301     norm = 0;
302     lower = TMath::Max(col - 1, 0);
303     upper = TMath::Min(col + 2, nCols);
304     for(Int_t inb = lower; inb < upper; ++inb){
305       cogv += yLengths[inb] * histogram[row][inb];
306       norm += histogram[row][inb];
307     }
308     cogy[row][col] = cogv / norm;
309     cogv = 0; norm = 0;
310     lower = TMath::Max(row - 1, 0);
311     upper = TMath::Min(row + 2, nRows);
312     for(Int_t inb = lower; inb < upper; ++inb){
313       cogv += zLengths[inb] * histogram[inb][col];
314       norm += histogram[inb][col];
315     }
316     cogz[row][col] = Float_t(cogv) /  norm;
317     // passed the filter
318     cand[nCandidates] = row*nCols + col;        // store the position of a passig candidate into an Array
319     sigcands[nCandidates] = sigmas[row][col] / histogram[row][col]; // never be a floating point exeption
320     // Analysis output
321     nCandidates++;
322   }
323   if(!nCandidates) return kFALSE;
324   
325   Float_t pos[3], sig[2];
326   Short_t signal[7]; memset(&signal[0], 0, 7*sizeof(Short_t));
327   
328   new(fakeLayer) AliTRDchamberTimeBin(layer, stack, sector, z0, zl);
329   fakeLayer->SetReconstructor(rec);
330   AliTRDcluster *cluster = 0x0;
331   if(nCandidates){
332     UInt_t fakeIndex = 0;
333     for(Int_t ican = 0; ican < nCandidates; ican++){
334       row = cand[ican] / nCols;
335       col = cand[ican] % nCols;
336       //temporary
337       Int_t n = 0; Double_t x = 0., y = 0., z = 0.;
338       for(int itb=0; itb<kNTimeBins; itb++){
339         if(!(nClusters = fTB[itb].GetNClusters())) continue;
340         for(Int_t incl = 0; incl < nClusters; incl++){
341           c = fTB[itb].GetCluster(incl);        
342           if(c->GetPadRow() != row) continue;
343           if(TMath::Abs(c->GetPadCol() - col) > 2) continue;
344           x += c->GetX();
345           y += c->GetY();
346           z += c->GetZ();
347           n++;
348         }
349       }
350       pos[0] = x/n;
351       pos[1] = y/n;
352       pos[2] = z/n;
353       sig[0] = .02;
354       sig[1] = sigcands[ican];
355       cluster = new AliTRDcluster(fDetector, 0., pos, sig, 0x0, 3, signal, col, row, 0, 0, 0., 0);
356       fakeLayer->InsertCluster(cluster, fakeIndex++);
357     }
358   }
359   fakeLayer->SetNRows(nRows);
360   fakeLayer->SetOwner();
361   fakeLayer->BuildIndices();
362   //fakeLayer->PrintClusters();
363   
364   if(rec->GetStreamLevel(AliTRDReconstructor::kTracker) >= 3){
365     //TMatrixD hist(nRows, nCols);
366     //for(Int_t i = 0; i < nRows; i++)
367     //  for(Int_t j = 0; j < nCols; j++)
368     //          hist(i,j) = histogram[i][j];
369     TTreeSRedirector &cstreamer = *AliTRDtrackerV1::DebugStreamer();
370     cstreamer << "GetSeedingLayer"
371     << "layer="      << layer
372     << "ymin="       << ymin
373     << "ymax="       << ymax
374     << "zmin="       << zmin
375     << "zmax="       << zmax
376     << "L.="         << fakeLayer
377     //<< "Histogram.=" << &hist
378     << "\n";
379   }
380   
381   return kTRUE;
382 }
383
384
385 //_______________________________________________________
386 void AliTRDtrackingChamber::Print(Option_t *opt) const
387 {
388   if(!GetNClusters()) return;
389   AliInfo(Form("fDetector   = %d", fDetector));
390   AliInfo(Form("fX0         = %7.3f", fX0));
391   const AliTRDchamberTimeBin *itb = &fTB[0];
392   for(Int_t jtb=0; jtb<kNTimeBins; jtb++, itb++) (*itb).Print(opt);
393 }