LCOV - code coverage report
Current view: top level - TRD/TRDbase - AliTRDtrackletOflHelper.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 210 401 52.4 %
Date: 2016-06-14 17:26:59 Functions: 16 24 66.7 %

          Line data    Source code
       1             : #include "TObjArray.h"
       2             : #include "TMath.h"
       3             : 
       4             : #include "AliLog.h"
       5             : #include "AliMathBase.h"
       6             : 
       7             : #include "AliTRDseedV1.h"
       8             : #include "AliTRDcluster.h"
       9             : #include "AliTRDpadPlane.h"
      10             : #include "AliTRDtrackletOflHelper.h"
      11             : 
      12          48 : ClassImp(AliTRDtrackletOflHelper)
      13             : //___________________________________________________________________
      14             : AliTRDtrackletOflHelper::AliTRDtrackletOflHelper() 
      15         458 :   :TObject()
      16         458 :   ,fRow(-1)
      17         458 :   ,fClusters(NULL)
      18         458 :   ,fPadPlane(NULL)
      19        2290 : {
      20             : // Default constructor
      21         458 :   fCol[0]=144; fCol[1]=0;
      22         458 :   fTBrange[0]=1; fTBrange[1]=21;
      23         916 : }
      24             : 
      25             : //___________________________________________________________________
      26             : AliTRDtrackletOflHelper::AliTRDtrackletOflHelper(const AliTRDtrackletOflHelper &ref) 
      27           0 :   :TObject(ref)
      28           0 :   ,fRow(-1)
      29           0 :   ,fClusters(NULL)
      30           0 :   ,fPadPlane(ref.fPadPlane)
      31           0 : {
      32             : // Copy constructor
      33           0 :   fRow = ref.fRow; fCol[0]=ref.fCol[0]; fCol[1]=ref.fCol[1];
      34           0 :   fTBrange[0] = ref.fTBrange[0];fTBrange[1] = ref.fTBrange[1];
      35             :   Int_t n(0);
      36           0 :   if(ref.fClusters){
      37           0 :     if((n = ref.fClusters->GetEntriesFast())) {
      38           0 :       fClusters = new TObjArray(n);
      39           0 :       for(Int_t ic(n); ic--;) fClusters->AddAt(ref.fClusters->At(ic), ic);
      40           0 :     }
      41             :   }
      42           0 : }
      43             : 
      44             : //___________________________________________________________________
      45             : AliTRDtrackletOflHelper& AliTRDtrackletOflHelper::operator=(const AliTRDtrackletOflHelper &rhs)
      46             : {
      47          80 :   if(this != &rhs){
      48          40 :     TObject::operator=(rhs);
      49          40 :     fPadPlane  = rhs.fPadPlane;
      50          40 :     fRow       = rhs.fRow;
      51          40 :     fCol[0]    = rhs.fCol[0];
      52          40 :     fCol[1]    = rhs.fCol[1];
      53          40 :     fTBrange[0]= rhs.fTBrange[0];
      54          40 :     fTBrange[1]= rhs.fTBrange[1];
      55          40 :     if(rhs.fClusters){ 
      56          40 :       Int_t n(rhs.fClusters->GetEntriesFast());
      57          96 :       if(!fClusters) fClusters = new TObjArray(n);
      58          40 :       if(fClusters->GetEntriesFast() != n){ 
      59          30 :         fClusters->Clear();
      60          30 :         fClusters->Expand(n);
      61          30 :       }
      62        1668 :       for(Int_t ic(n); ic--;)  fClusters->AddAt(rhs.fClusters->At(ic), ic);
      63          40 :     } else {
      64           0 :       if(fClusters) delete fClusters;
      65             :     }
      66             :   }
      67          40 :   return *this;
      68           0 : }
      69             : 
      70             : //___________________________________________________________________
      71             : AliTRDtrackletOflHelper::~AliTRDtrackletOflHelper()
      72        1832 : {
      73             : // Clean helper  
      74         914 :   if(fClusters) fClusters->Clear();
      75         716 :   delete fClusters;
      76         916 : }
      77             : 
      78             : //___________________________________________________________________
      79             : Int_t AliTRDtrackletOflHelper::Expand(TObjArray *cls, Int_t *mark, Int_t groupId)
      80             : {
      81             : // Allocate new clusters for this helper.  If a subset of clusters is to be allocated 
      82             : // this can be specified via the identifier "groupId" which have to be compared 
      83             : // with individual elements in the array "mark".
      84             : // 
      85             : // Return total no. of clusters in helper
      86             : 
      87         216 :   if(!fPadPlane || !fClusters ){
      88           0 :     AliError("Helper not initialized."); 
      89           0 :     return 0;
      90             :   }
      91          72 :   Int_t ncl(fClusters->GetEntriesFast());
      92          72 :   Int_t mcl(cls->GetEntriesFast());
      93          72 :   fClusters->Expand(mcl + ncl);
      94          72 :   fCol[0]=144; fCol[1]=0;
      95             :   AliTRDcluster *c(NULL);
      96        4612 :   for(Int_t icl(0), jcl(ncl); icl<mcl; icl++){
      97        2234 :     if(!(c=(AliTRDcluster*)cls->At(icl))) continue;
      98        4468 :     if(mark && mark[icl]!=groupId) continue;
      99         796 :     fClusters->AddAt(c, jcl++);
     100         796 :     Int_t col(c->GetPadCol());
     101         796 :     Short_t *sig(c->GetSignals());
     102       12736 :     for(Int_t icol(0), jcol(col-3); icol<7; icol++, jcol++){
     103        5572 :       if(sig[icol]==0) continue;
     104        4812 :       if(jcol<fCol[0]) fCol[0]=jcol;
     105        5112 :       if(jcol>fCol[1]) fCol[1]=jcol;
     106             :     }
     107         796 :   }
     108             : 
     109         216 :   AliDebug(1, Form("Segment[%d] Clusters[%2d] pad[%3d %3d].", groupId, fClusters->GetEntriesFast(), fCol[0], fCol[1]));
     110          72 :   return fClusters->GetEntriesFast();
     111          72 : }
     112             : 
     113             : 
     114             : //___________________________________________________________________
     115             : Int_t AliTRDtrackletOflHelper::Init(AliTRDpadPlane *p, TObjArray *cls, Int_t *mark, Int_t groupId)
     116             : {
     117             : // Allocate clusters for this helper.  If a subset of clusters is to be allocated 
     118             : // this can be specified via the identifier "groupId" which have to be compared 
     119             : // with individual elements in the array "mark".
     120             : // 
     121             : // Return no. of clusters allocated
     122             : 
     123         994 :   if(!p){
     124           0 :     AliError("PadPlane not initialized."); return 0;
     125             :   }
     126         497 :   if(!cls){
     127           0 :     AliError("Cluster array not initialized."); return 0;
     128             :   }
     129         497 :   Int_t ncl(cls->GetEntriesFast());
     130         497 :   if(ncl<2){ 
     131           0 :     AliDebug(1, Form("Segment[%d] failed n[%d].", groupId, ncl)); return 0;
     132             :   }
     133             :   Int_t mcl(ncl);
     134         497 :   if(mark){
     135             :     mcl = 0;
     136        6061 :     for(Int_t icl(ncl); icl--;) 
     137       16189 :       if(cls->At(icl) && mark[icl]==groupId) mcl++;
     138         267 :   }  
     139         497 :   if(mcl<2){ 
     140           0 :     AliDebug(1, Form("Segment[%d] failed n[%d] in group.", groupId, mcl)); return 0;
     141             :   }
     142         957 :   if(!fClusters) fClusters = new TObjArray(mcl);
     143             :   else{ 
     144         267 :     fClusters->Clear();
     145         267 :     fClusters->Expand(mcl);
     146             :   }
     147         497 :   fCol[0]=144; fCol[1]=0; fRow=-1;
     148             :   AliTRDcluster *c(NULL);
     149       22202 :   for(Int_t icl(0), jcl(0); icl<ncl; icl++){
     150       10604 :     if(!(c=(AliTRDcluster*)cls->At(icl))) continue;
     151       16131 :     if(mark && mark[icl]!=groupId) continue;
     152       10212 :     fClusters->AddAt(c, jcl++);
     153       10709 :     if(fRow<0) fRow = c->GetPadRow();
     154       10212 :     Int_t col(c->GetPadCol());
     155       10212 :     Short_t *sig(c->GetSignals());
     156      163392 :     for(Int_t icol(0), jcol(col-3); icol<7; icol++, jcol++){
     157       71484 :       if(sig[icol]==0) continue;
     158       58336 :       if(jcol<fCol[0]) fCol[0]=jcol;
     159       60478 :       if(jcol>fCol[1]) fCol[1]=jcol;
     160             :     }
     161       10212 :   }
     162         497 :   fPadPlane = p;
     163             :   
     164        1491 :   AliDebug(1, Form("Segment[%d] Clusters[%2d] pad[%3d %3d].", groupId, fClusters->GetEntriesFast(), fCol[0], fCol[1]));
     165         497 :   return fClusters->GetEntriesFast();
     166         497 : }
     167             : 
     168             : //___________________________________________________________________
     169             : Int_t AliTRDtrackletOflHelper::ClassifyTopology()
     170             : {
     171             : // Classify topology and return classification code
     172             : // 0 - normal tracklet
     173             : // 1 - delta ray candidate
     174             : // 2 - secondary candidate
     175             : // 3 - "elephant" candidate
     176             : // 4 - unknown topology
     177             : 
     178         460 :   if(!fClusters){ 
     179           0 :     AliError("Helper not initialized. Missing clusters.");
     180           0 :     return kUnknown;
     181             :   }
     182         230 :   Int_t ncl(fClusters->GetEntries());
     183         230 :   if(!ncl){ 
     184           0 :     AliError("Helper not initialized. No cluster allocated.");
     185           0 :     return kUnknown;
     186             :   }
     187             :   const Int_t kRange(22); // DEFINE based on vd 
     188             :   
     189             :   // compute local occupancy
     190         230 :   Int_t localOccupancy[AliTRDseedV1::kNtb]; memset(localOccupancy, 0, AliTRDseedV1::kNtb*sizeof(Int_t));
     191             :   AliTRDcluster *c(NULL);
     192         230 :   Double_t sy[kNcls]; Int_t mcl(0);
     193       10024 :   for(Int_t icl(ncl), time; icl--;){
     194        5077 :     c = (AliTRDcluster*)fClusters->At(icl);
     195        5077 :     time = c->GetPadTime();
     196        5077 :     if(time==0 || time>=kRange){
     197         590 :       sy[icl] = -1; // mark clusters outsde drift volume
     198         590 :       continue;
     199             :     }
     200             :     // protect against wrong error param.
     201        4487 :     if(c->GetSigmaY2() < 1.e-5) sy[icl] = 0.02;
     202        4487 :     else sy[icl] = TMath::Min(TMath::Sqrt(c->GetSigmaY2()), 0.04);
     203        4487 :     localOccupancy[time]++;
     204        4487 :     mcl++;
     205             :   }
     206         230 :   if(!mcl){
     207           0 :     AliWarning("No clusters in the active area.");
     208           0 :     return kUnknown;
     209             :   } 
     210             :   //compute number of 0 bins and high occupancy
     211             :   Int_t goodOccupancy(0), highOccupancy(0), lowOccupancy(0);
     212       10120 :   for(Int_t itb(1); itb<kRange; itb++){
     213        4830 :     switch(localOccupancy[itb]){ 
     214         559 :       case 0: lowOccupancy++; break;
     215        4083 :       case 1: goodOccupancy++; break;
     216         188 :       default: highOccupancy++; break;
     217             :     }
     218             :   }
     219         690 :   AliDebug(2, Form("H[%2d | %5.2f%%] L[%2d | %5.2f%%] N[%2d | %5.2f%% | %5.2f%%]",
     220             :           highOccupancy, 100.*highOccupancy/kRange, 
     221             :           lowOccupancy, 100.*lowOccupancy/kRange, 
     222             :           goodOccupancy, 100.*goodOccupancy/kRange, 100.*goodOccupancy/mcl));
     223             :   
     224             :   // filter
     225         230 :   Double_t dy[kNcls];
     226         446 :   if(goodOccupancy==mcl) return kNormal;
     227          14 :   else if(Double_t(goodOccupancy)/kRange > 0.9){
     228           0 :     if(highOccupancy == 0 ) {
     229           0 :       if(!FitPSR(dy)) return kUnknown;
     230             :       Int_t nin(0);
     231           0 :       for(Int_t idy(ncl); idy--;){
     232           0 :         if(sy[idy]<0.) continue;
     233           0 :         if(dy[idy] > 3*sy[idy]) continue;
     234           0 :         nin ++;
     235             :       }
     236           0 :       if(Double_t(nin)/mcl > 0.8) return kNormal;
     237           0 :       else return kUnknown;
     238           0 :     } else return kDeltaRay;
     239          14 :   } else return kUnknown;
     240         690 : }
     241             : 
     242             : 
     243             : //___________________________________________________________________
     244             : void AliTRDtrackletOflHelper::FindSolidCls(Bool_t *mark, Int_t *q)
     245             : {
     246             : //  Find clusters produced by large fluctuations of energy deposits
     247             : //  Largest charge and well separation from neighbors
     248             : 
     249             :   Int_t ntb(AliTRDseedV1::kNtb);
     250           0 :   Int_t idx[ntb+1];
     251           0 :   TMath::Sort(ntb, q, idx, kTRUE);
     252           0 :   Int_t qmax = Int_t(0.3*q[idx[0]]);
     253           0 :   mark[0] = kFALSE;
     254           0 :   for(Int_t icl(ntb-5); icl<ntb; icl++) mark[icl] = kFALSE;
     255           0 :   for(Int_t icl(0); icl<ntb; icl++){
     256           0 :     Int_t jcl(idx[icl]);
     257           0 :     if(!mark[jcl]) continue;
     258           0 :     if(q[jcl-1]>q[jcl] || q[jcl+1]>q[jcl]){
     259           0 :       mark[jcl] = kFALSE;
     260           0 :       continue;
     261             :     }
     262           0 :     if(q[jcl] < qmax){
     263           0 :       mark[jcl] = kFALSE;
     264           0 :       continue;
     265             :     }
     266           0 :     for(Int_t kcl=TMath::Max(0, jcl-2); kcl<jcl+3; kcl++){
     267           0 :       if(kcl==jcl) continue;
     268           0 :       mark[kcl] = kFALSE;
     269           0 :     }
     270           0 :   }
     271           0 : }
     272             : 
     273             : //___________________________________________________________________
     274             : Bool_t AliTRDtrackletOflHelper::FitPSR(Double_t dy[200], Bool_t useSolid)
     275             : {
     276             : // Fit tracklet in Pad System of Reference [PSR] to avoid uncertainty related to 
     277             : // Lorentz angle correction
     278             : 
     279           0 :   Bool_t mark[200]; memset(mark, 0, 200*sizeof(Bool_t));
     280           0 :   Int_t q[200]; memset(q, 0, 200*sizeof(Int_t));
     281           0 :   Int_t ncl(fClusters->GetEntries());
     282             :   AliTRDcluster *c(NULL);
     283           0 :   for(Int_t icl(ncl); icl--;){
     284           0 :     c = (AliTRDcluster*)fClusters->At(icl);
     285           0 :     if(c->GetPadRow() != fRow) continue;
     286           0 :     Int_t time(c->GetPadTime());
     287           0 :     mark[time] = kTRUE; q[time] = Int_t(c->GetQ());
     288             :   }
     289           0 :   if(useSolid) FindSolidCls(mark, q);
     290             :   
     291           0 :   Double_t 
     292             :     x[AliTRDseedV1::kNtb], y[AliTRDseedV1::kNtb], sy[AliTRDseedV1::kNtb], 
     293             :     xf[AliTRDseedV1::kNtb], yf[AliTRDseedV1::kNtb], syf[AliTRDseedV1::kNtb], 
     294             :     par[3];
     295             :   Int_t jcl(0), kcl(0);
     296           0 :   for(Int_t icl(0); icl<ncl; icl++){
     297           0 :     c = (AliTRDcluster*)fClusters->At(icl);
     298           0 :     if(c->GetPadRow() != fRow) continue;
     299           0 :     Int_t col(c->GetPadCol());
     300           0 :     Int_t time(c->GetPadTime());
     301           0 :     Double_t center(c->GetCenter());
     302           0 :     Double_t cw(fPadPlane->GetColSize(col));
     303             :     //Double_t corr = AliTRDcluster::GetYcorr(AliTRDgeometry::GetLayer(det), center);
     304           0 :     y[jcl] = fPadPlane->GetColPos(col) + (.5 + center)*cw /*+ corr*/;
     305           0 :     x[jcl] = c->GetX();
     306           0 :     sy[jcl]= TMath::Sqrt(c->GetSigmaY2());
     307           0 :     if(mark[time]){
     308           0 :       yf[kcl] = y[jcl];
     309           0 :       xf[kcl] = x[jcl];
     310           0 :       syf[kcl]= useSolid ? 0.5/time:sy[jcl];
     311           0 :       kcl++;
     312           0 :     } 
     313           0 :     jcl++;
     314           0 :   }
     315           0 :   Fit(kcl, xf, yf, syf, par);
     316             : 
     317           0 :   for(Int_t icl(0); icl<jcl; icl++){
     318           0 :     Double_t dx(x[icl] - par[2]);
     319           0 :     dy[icl] = y[icl] - (par[0] + par[1]*dx);
     320             :   }
     321           0 :   return kTRUE;
     322           0 : }
     323             : 
     324             : //___________________________________________________________________
     325             : Bool_t AliTRDtrackletOflHelper::Fit(Int_t n, Double_t *x, Double_t *y, Double_t *sy, Double_t *par, Double_t sCut,  Double_t *cov)
     326             : {
     327             : // Iterative robust tracklet fit 
     328        1120 :   if(n<3) return kFALSE;
     329             :   //select reference radial position
     330         557 :   if(par[2]<0.){ //compute reference radial position as <x>
     331           0 :     par[2] = 0.; for(Int_t ic(n); ic--;) par[2] += x[ic]; par[2] /= n;
     332           0 :   }
     333         557 :   AliTRDtrackerV1::AliTRDLeastSquare &f=Fitter();
     334        4456 :   for(Int_t iter(0); iter<3; iter++){
     335        1671 :     f.Reset();
     336             :     Int_t jp(0);
     337       74730 :     for(Int_t ip(0); ip<n; ip++){
     338       35694 :       Double_t dx(x[ip]-par[2]);
     339       35694 :       Double_t dy(y[ip] - (par[0] + par[1]*dx));
     340       68277 :       if(iter && TMath::Abs(dy)>sCut*sy[ip]) continue;
     341       26907 :       f.AddPoint(&dx, y[ip], sy[ip]);
     342       26907 :       jp++;
     343       62601 :     }
     344        1787 :     if(jp<3) continue;
     345        1555 :     if(!f.Eval()) continue;
     346        1555 :     par[0]=f.GetFunctionParameter(0);
     347        1555 :     par[1]=f.GetFunctionParameter(1);
     348        2231 :     if(cov) f.GetCovarianceMatrix(cov);
     349        4665 :     AliDebugGeneral("AliTRDtrackletOflHelper::Fit()", 2, Form("Iter[%d] Ncl[%2d/%2d] par[%f %f %f]", iter, jp, n, par[0], par[1], par[2]));
     350        1555 :   }
     351             :   return kTRUE;
     352         559 : }
     353             : 
     354             : //___________________________________________________________________
     355             : Bool_t AliTRDtrackletOflHelper::Fit(Double_t *par, Double_t sCut) const
     356             : {
     357             : // Wrapper for clusters attach to this for static Fit function  
     358             : //
     359         662 :   Int_t n(fClusters->GetEntriesFast()), jc(0), dr(0);
     360         662 :   Double_t corr = TMath::Tan(TMath::DegToRad()*fPadPlane->GetTiltingAngle())*
     361         331 :                   fPadPlane->GetLengthIPad();
     362         331 :   Double_t x[kNcls], y[kNcls], sy[kNcls];
     363             :   AliTRDcluster *c(NULL);
     364       16224 :   for(Int_t ic(0); ic<n; ic++){
     365        7781 :     c = (AliTRDcluster*)fClusters->At(ic);
     366        7781 :     if(!c->IsInChamber()) continue;
     367        7258 :     dr = c->GetPadRow() - fRow;
     368        7258 :     x[jc] = c->GetX();
     369        7258 :     y[jc] = c->GetY()+corr*dr;
     370       21774 :     sy[jc]= c->GetSigmaY2()>0?(TMath::Min(TMath::Sqrt(c->GetSigmaY2()), 0.08)):0.08;
     371        7258 :     jc++;
     372        7258 :   }
     373         662 :   return Fit(jc, x, y, sy, par, sCut);
     374         331 : }
     375             : 
     376             : //___________________________________________________________________
     377             : void AliTRDtrackletOflHelper::GetColSignals(Int_t col, Int_t adc[32], Bool_t mainRow) const
     378             : {
     379           0 :   memset(adc, 0, 32*sizeof(Int_t));
     380           0 :   if(col<fCol[0] || col>fCol[1]) return;
     381             :   
     382             :   AliTRDcluster *cc(NULL);
     383           0 :   for(Int_t ic(fClusters->GetEntriesFast()); ic--;){
     384           0 :     cc = (AliTRDcluster*)fClusters->At(ic);
     385           0 :     if((mainRow && cc->GetPadRow()!=fRow) ||
     386           0 :        (!mainRow && cc->GetPadRow()==fRow)) continue;
     387           0 :     Short_t *sig = cc->GetSignals();
     388           0 :     Int_t padcol(cc->GetPadCol());
     389           0 :     Int_t time(cc->GetPadTime());
     390           0 :     for(Int_t icol(0), jcol(padcol-3); icol<7; icol++, jcol++){
     391           0 :       if(jcol!=col) continue;
     392           0 :       adc[time]+=sig[icol];
     393           0 :     }
     394             :   }
     395           0 : }
     396             : 
     397             : //___________________________________________________________________
     398             : Int_t AliTRDtrackletOflHelper::GetRMS(Double_t &r, Double_t &m, Double_t &s, Double_t xm) const
     399             : {
     400             : // Calculate Rotation[r], Mean y[m] (at radial position [xm]) and Sigma[s] (of a gaussian distribution in the tracklet [SR])
     401             : // for clusters attach to this helper. The Rotation and Mean are calculated without tilt correction option.
     402             : // It returns the number of clusters in 1 sigma cut.
     403             :   
     404         662 :   Int_t n(fClusters->GetEntriesFast());
     405         331 :   if(n<=2) return n;
     406         331 :   Double_t par[3] = {0., 0., -1.};
     407         662 :   if(xm>0.) par[2] = xm; // select reference radial position from outside 
     408         331 :   Fit(par);
     409         331 :   m = par[0];
     410         331 :   r = par[1];
     411         331 :   xm= par[2];
     412             : 
     413         662 :   Double_t corr = TMath::Tan(TMath::DegToRad()*fPadPlane->GetTiltingAngle())*
     414         331 :                   fPadPlane->GetLengthIPad();
     415         331 :   Double_t y[kNcls];
     416             :   AliTRDcluster *c(NULL);
     417       16224 :   for(Int_t ic(n); ic--;){
     418        7781 :     c = (AliTRDcluster*)fClusters->At(ic);
     419        7781 :     Double_t x(c->GetX() - xm);
     420        7781 :     Int_t dr(c->GetPadRow() - fRow);
     421        7781 :     y[ic] = c->GetY()+corr*dr - (par[0] + par[1]*x);
     422             :   }
     423         331 :   Double_t m1(0.);
     424         331 :   AliMathBase::EvaluateUni(n, y, m1, s, 0);
     425             :   Int_t n0(0);
     426       16224 :   for(Int_t ic(n); ic--;){
     427        7781 :     c = (AliTRDcluster*)fClusters->At(ic);
     428       23343 :     Double_t sy = c->GetSigmaY2()>0?(TMath::Min(TMath::Sqrt(c->GetSigmaY2()), 0.08)):0.08;
     429       11076 :     if(TMath::Abs(y[ic]-m1) <= sy) n0++;
     430             :   }
     431             :   return n0;
     432         662 : }
     433             : 
     434             : //___________________________________________________________________
     435             : Double_t AliTRDtrackletOflHelper::GetQ() const
     436             : {
     437             : // Calculate total charge NOT normalized to inclination
     438             : 
     439             :   Double_t q(0.);
     440         662 :   Int_t n(fClusters->GetEntriesFast());
     441             :   AliTRDcluster *c(NULL);
     442       16224 :   for(Int_t ic(n); ic--;){
     443        7781 :     c = (AliTRDcluster*)fClusters->At(ic);
     444        7781 :     q += TMath::Abs(c->GetQ());
     445             :   }
     446         331 :   return q;
     447             : }
     448             : 
     449             : //___________________________________________________________________
     450             : Double_t AliTRDtrackletOflHelper::GetSyMean() const
     451             : {
     452             : // Calculate mean uncertainty of clusters
     453             : 
     454             :   Double_t sym(0.);
     455         662 :   Int_t n(fClusters->GetEntriesFast());
     456             :   AliTRDcluster *c(NULL);
     457       16224 :   for(Int_t ic(n); ic--;){
     458        7781 :     c = (AliTRDcluster*)fClusters->At(ic);
     459       23343 :     sym += c->GetSigmaY2()>0?(TMath::Min(TMath::Sqrt(c->GetSigmaY2()), 0.08)):0.08;
     460             :   }
     461         331 :   return sym/=n;
     462             : }
     463             : 
     464             : //___________________________________________________________________
     465             : Int_t AliTRDtrackletOflHelper::Segmentation(Int_t n, Double_t *x, Double_t *y, Int_t *Index)
     466             : {
     467             : // Segmentation of clusters in the tracklet roads
     468             : //
     469             : // The user supply the coordinates of the clusters (x,y) and their number "n". Also
     470             : // The array "Index" has to be allocated by the user with a size equal or larger than "n".
     471             : // On return the function returns the number of segments found and the array "Index" i-th element 
     472             : // is filled with the index of the tracklet segment to which the i-th cluster was assigned too.
     473             : // 
     474             : // Observation
     475             : // The parameter which controls the segmentation is set inside the function "kGapSize" and it is used 
     476             : // for both "x" and "y" segmentations. An improvement can be a parametrization as function of angle of 
     477             : // incidence.
     478             : //
     479             : // author:
     480             : // Alex Bercuci <a.bercuci@gsi.de>
     481             : 
     482          94 :   if(!n || !x || !y || !Index){
     483           0 :     AliErrorGeneral("AliTRDtrackletOflHelper::Segmentation()", "One of the input arrays non initialized.");
     484           0 :     return 0;
     485             :   }
     486             :   const Int_t kBuffer = 200;
     487          47 :   if(n>kBuffer){
     488           0 :     AliWarningGeneral("AliTRDtrackletOflHelper::Segmentation()", Form("Input array size %d exceed buffer %d. Truncate.", n, kBuffer));
     489             :     n = kBuffer;
     490           0 :   }
     491             :   const Double_t kGapSize(0.2); // cm
     492             :   Int_t ng(0),
     493             :         nc(0);
     494          47 :   Double_t xx[kBuffer], dy;
     495          47 :   Int_t idx[kBuffer+1], jdx[kBuffer], kdx[kBuffer];
     496          47 :   TMath::Sort(n, y, idx);
     497        1978 :   for(Int_t iy(0); iy<n; iy++){
     498        2779 :     dy = iy>0?(TMath::Abs(y[idx[iy-1]]-y[idx[iy]])):0.;
     499         942 :     if(dy>kGapSize){
     500          30 :       TMath::Sort(nc, xx, jdx);
     501         864 :       for(Int_t ic(0), jc0, jc1; ic<nc; ic++){
     502        1176 :         jc0 = ic>0?kdx[jdx[ic-1]]:0;
     503         402 :         jc1 = kdx[jdx[ic]];
     504         402 :         dy = TMath::Abs(y[jc0] - y[jc1]);
     505         412 :         if(ic && dy>kGapSize) ng++;
     506         402 :         Index[jc1] = ng;
     507        1206 :         AliDebugGeneral("AliTRDtrackletOflHelper::Segmentation()", 4, Form("  y[%2d]=%+f x[%+f] %2d -> %2d -> %2d ng[%2d]", jc1, y[jc1], x[jc1], ic, jdx[ic], jc1, ng));
     508             :       }
     509          30 :       ng++;
     510             :       nc=0;
     511          30 :     }
     512         942 :     xx[nc] = x[idx[iy]];
     513         942 :     kdx[nc]= idx[iy];
     514        2826 :     AliDebugGeneral("AliTRDtrackletOflHelper::Segmentation()", 4, Form("y[%2d]=%+f -> %2d", idx[iy], y[idx[iy]], nc));
     515         942 :     nc++;
     516             :   }
     517          47 :   if(nc){
     518          47 :     TMath::Sort(nc, xx, jdx);
     519        1174 :     for(Int_t ic(0), jc0, jc1; ic<nc; ic++){
     520        1573 :       jc0 = ic>0?kdx[jdx[ic-1]]:0;
     521         540 :       jc1 = kdx[jdx[ic]];
     522         540 :       dy = TMath::Abs(y[jc0] - y[jc1]);
     523         548 :       if(ic && dy>kGapSize) ng++;
     524         540 :       Index[jc1] = ng;
     525        1620 :       AliDebugGeneral("AliTRDtrackletOflHelper::Segmentation()", 4, Form("  y[%2d]=%+f x[%+f|%+f] %2d -> %2d -> %2d ng[%2d]\n", jc1, y[jc1], xx[jdx[ic]], x[jc1], ic, jdx[ic], jc1, ng));
     526             :     }
     527          47 :     ng++;
     528          47 :   }
     529             :   return ng;
     530          94 : }
     531             : 
     532             : //___________________________________________________________________
     533             : void AliTRDtrackletOflHelper::SetTbRange(Float_t t0, Float_t vd)
     534             : {
     535             : // Set first time bin and total number of time bins corresponding to clusters 
     536             : // in chamber based on the calibrated info "t0" and drift velocity "vd"
     537             : 
     538             :   // TO CHECK
     539           0 :   fTBrange[0] = Int_t(t0*0.1);
     540           0 :   fTBrange[1] = Int_t(vd*0.1);
     541           0 : }
     542             : 
     543             : #include "TH2.h"
     544             : #include "TGraph.h"
     545             : #include "TGraphErrors.h"
     546             : #include "TCanvas.h"
     547             : #include "TLegend.h"
     548             : #include "TGaxis.h"
     549             : //___________________________________________________________________
     550             : void AliTRDtrackletOflHelper::View(TVirtualPad *vpad)
     551             : {
     552             : // Visualization support. Draw this tracklet segment  
     553             : 
     554             : 
     555             :   Int_t row(-1), det(-1);
     556           0 :   Int_t n(fClusters->GetEntriesFast());
     557           0 :   AliInfo(Form("Processing Clusters[%2d] Class[%d].", n ,ClassifyTopology()));
     558             :   
     559             :   // prepare drawing objects
     560           0 :   Int_t ncols(fPadPlane->GetNcols());
     561           0 :   Double_t cw(fPadPlane->GetColSize(1));
     562           0 :   TH2 *h2 = new TH2I("h2pm", ";y_{Local} [cm]; pad time;Charge", ncols, fPadPlane->GetColPos(1)-cw, fPadPlane->GetColPos(ncols-1)+cw, 31, -30.5, 0.5);
     563           0 :   h2->SetMarkerColor(kWhite);h2->SetMarkerSize(2.);
     564           0 :   h2->SetFillColor(9);
     565             :   
     566           0 :   TGraph *gcls = new TGraph(n);
     567           0 :   gcls->SetMarkerColor(kBlack);gcls->SetMarkerStyle(20);
     568           0 :   TGraph *gclsLC = new TGraph(n);
     569           0 :   gclsLC->SetMarkerColor(kBlack);gclsLC->SetMarkerStyle(28);
     570           0 :   TGraph *gclsSC = new TGraph(n);
     571           0 :   gclsSC->SetMarkerColor(kBlack);gclsSC->SetMarkerStyle(4);gclsSC->SetMarkerSize(1.5);
     572           0 :   TGraph *gFP = new TGraph(n);
     573           0 :   gFP->SetMarkerColor(kBlack);gFP->SetLineWidth(2);
     574             :   
     575             :   // fill signal data
     576           0 :   Bool_t map[200]; memset(map, 0, 200*sizeof(Bool_t));
     577           0 :   Int_t qa[200]; memset(qa, 0, 200*sizeof(Int_t));
     578             :   AliTRDcluster *cc(NULL); Int_t tm = 30; Double_t ym=0.;
     579           0 :   for(Int_t ic(n); ic--;){
     580           0 :     cc = (AliTRDcluster*)fClusters->At(ic);
     581           0 :     if(cc->GetPadRow() != fRow) continue; //TODO extend for 2 pad rows
     582           0 :     Short_t *sig = cc->GetSignals();
     583           0 :     Int_t col(cc->GetPadCol());
     584           0 :     det = cc->GetDetector();
     585           0 :     row = cc->GetPadRow();
     586           0 :     Int_t time(cc->GetPadTime());
     587           0 :     map[time] = kTRUE; qa[time] = (Int_t)cc->GetQ();
     588           0 :     for(Int_t ipad(0), jpad(col-2); ipad<7; ipad++, jpad++){
     589           0 :       Int_t q = (Int_t)h2->GetBinContent(jpad, 31-time);
     590           0 :       h2->SetBinContent(jpad, 31-time, q+sig[ipad]);
     591             :     }
     592           0 :     Double_t y0 = fPadPlane->GetColPos(col) + (.5 + cc->GetCenter())*cw;
     593             :     //h2->GetXaxis()->GetBinCenter(pad)+cc->GetCenter();
     594           0 :     gcls->SetPoint(ic, y0, -time);
     595           0 :     if(time <= tm) {ym = cc->GetY() - y0; tm = time;}
     596             :   }
     597             : 
     598             :   // draw special clusters (solid and Lorentz corrected and fit) 
     599           0 :   FindSolidCls(map, qa);
     600           0 :   Double_t ddy[200]; FitPSR(ddy, kTRUE);
     601           0 :   Double_t dt, dy;
     602           0 :   for(Int_t ic(0), jc(0); ic<n; ic++){
     603           0 :     cc = (AliTRDcluster*)fClusters->At(ic);
     604           0 :     if(cc->GetPadRow() != fRow) continue; //TODO extend for 2 pad rows
     605           0 :     gcls->GetPoint(ic, dy, dt);
     606           0 :     gclsLC->SetPoint(ic, cc->GetY()-ym, dt);
     607           0 :     gFP->SetPoint(ic, dy-ddy[ic], dt);
     608           0 :     if(map[cc->GetPadTime()]) gclsSC->SetPoint(jc++, dy, dt);
     609             :   }
     610             :   
     611             :   
     612             :   // prepare frame histo
     613           0 :   h2->SetName(Form("h2s%03d%02d", det, row));
     614           0 :   Int_t binSrt(fCol[0]+1), binSop(fCol[1]+1);
     615             :   TH1 *h1(NULL);
     616             :   
     617             :   // show everything
     618           0 :   if(!vpad){ 
     619           0 :     vpad = new TCanvas(Form("c%03d%02d", det, row), Form("D %03d [%02d_%d_%d] R[%02d]", det, AliTRDgeometry::GetSector(det), AliTRDgeometry::GetStack(det), AliTRDgeometry::GetLayer(det), row), 700, 500);
     620           0 :   }
     621             :   TVirtualPad *pp(NULL);
     622           0 :   vpad->Divide(2,1,2.e-5,2.e-5);
     623           0 :   pp = vpad->cd(1); pp->SetRightMargin(0.0001);pp->SetTopMargin(0.1);pp->SetBorderMode(0); pp->SetFillColor(kWhite);
     624           0 :   h1 = h2->ProjectionY(); h1->GetYaxis()->SetTitle("Total Charge");
     625           0 :   h1->SetTitle(Form("D%03d[%02d_%d_%d] R[%02d]", 
     626           0 :     det,AliTRDgeometry::GetSector(det), AliTRDgeometry::GetStack(det), AliTRDgeometry::GetLayer(det), row));
     627           0 :   TAxis *ax(h1->GetXaxis()); for(Int_t ib(0), jb(1); ib<ax->GetNbins(); ib++, jb++) ax->SetBinLabel(jb, Form("%d", -Int_t(ax->GetBinCenter(jb))));
     628           0 :   h1->Draw("hbar3");
     629             : 
     630           0 :   pp = vpad->cd(2);
     631           0 :   pp->SetRightMargin(0.15);pp->SetLeftMargin(0.0001);pp->SetTopMargin(0.1);
     632           0 :   pp->SetBorderMode(0); pp->SetFillColor(kWhite);
     633           0 :   ax=h2->GetXaxis();
     634           0 :   ax->SetRange(TMath::Max(1, binSrt-1), TMath::Min(ncols, binSop+1));
     635           0 :   h2->Draw("coltextz");
     636           0 :   gPad->Update();
     637           0 :   TGaxis *axis = new TGaxis(gPad->GetUxmin(),
     638           0 :                     gPad->GetUymax(),
     639           0 :                     gPad->GetUxmax(),
     640           0 :                     gPad->GetUymax(),
     641           0 :                     TMath::Max(0, binSrt-2)-0.5, TMath::Min(ncols-1, binSop)+0.5, 510,"-L");
     642             : 
     643           0 :   axis->SetNdivisions(103+binSop-binSrt);
     644           0 :   axis->SetTitle("pad col");
     645           0 :   axis->Draw();
     646             : 
     647           0 :   TLegend *leg = new TLegend(0.01, 0.1, 0.84, 0.21);
     648           0 :   leg->SetBorderSize(1); leg->SetFillColor(kYellow-9);leg->SetTextSize(0.04);
     649           0 :   gcls->Draw("p");  leg->AddEntry(gcls, "Cls. in Pad [SR]", "p");
     650           0 :   gclsLC->Draw("p"); leg->AddEntry(gclsLC, "Lorentz Corr. Cls.", "p");
     651           0 :   gclsSC->Draw("p"); leg->AddEntry(gclsSC, "Solid Cls.", "p");
     652           0 :   gFP->Draw("l"); leg->AddEntry(gFP, "Fit in Pad [SR]", "l");
     653           0 :   leg->Draw();
     654           0 : }
     655             : 
     656             : //___________________________________________________________________
     657             : AliTRDtrackerV1::AliTRDLeastSquare& AliTRDtrackletOflHelper::Fitter()
     658             : {
     659        1120 :   static AliTRDtrackerV1::AliTRDLeastSquare f;
     660         557 :   return f;
     661           0 : }

Generated by: LCOV version 1.11