LCOV - code coverage report
Current view: top level - TRD/TRDbase - AliTRDchamberTimeBin.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 129 279 46.2 %
Date: 2016-06-14 17:26:59 Functions: 12 24 50.0 %

          Line data    Source code
       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: AliTRDchamberTimeBin.cxx 23313 2008-01-11 14:56:43Z cblume $ */
      17             : 
      18             : ///////////////////////////////////////////////////////////////////////////////
      19             : //                                                                           //
      20             : //  Organization of clusters at the level of 1 TRD chamber.                  //
      21             : //  The data structure is used for tracking at the stack level.              //
      22             : //                                                                           //
      23             : //  Functionalities:                                                         //
      24             : //   1. cluster organization and sorting                                     //
      25             : //   2. fast data navigation                                                 //
      26             : //                                                                           //
      27             : //  Authors:                                                                 //
      28             : //    Alex Bercuci <A.Bercuci@gsi.de>                                        //
      29             : //    Markus Fasel <M.Fasel@gsi.de>                                          //
      30             : //                                                                           //
      31             : ///////////////////////////////////////////////////////////////////////////////
      32             : 
      33             : #include <TObject.h>
      34             : #include <TMath.h>
      35             : #include <TTreeStream.h>
      36             : 
      37             : #include "AliLog.h"
      38             : #include "AliTRDcluster.h"
      39             : #include "AliTRDgeometry.h"
      40             : #include "AliTRDpadPlane.h"
      41             : #include "AliTRDchamberTimeBin.h"
      42             : #include "AliTRDrecoParam.h"
      43             : #include "AliTRDReconstructor.h"
      44             : 
      45          48 : ClassImp(AliTRDchamberTimeBin)
      46             : 
      47             : //_____________________________________________________________________________
      48             : AliTRDchamberTimeBin::AliTRDchamberTimeBin(Int_t plane, Int_t stack, Int_t sector, Double_t z0, Double_t zLength)
      49       10819 :   :TObject()
      50       10819 :   ,fkReconstructor(NULL)
      51       10819 :   ,fPlane(plane)
      52       10819 :   ,fStack(stack)
      53       10819 :   ,fSector(sector)
      54       10819 :   ,fNRows(kMaxRows)
      55       10819 :   ,fN(0)
      56       10819 :   ,fX(0.)
      57       10819 :   ,fZ0(z0)
      58       10819 :   ,fZLength(zLength)
      59       54095 : {
      60             :   //
      61             :   // Default constructor (Only provided to use AliTRDchamberTimeBin with arrays)
      62             :   //
      63       10819 :   SetBit(kT0, kFALSE);
      64       10819 :   SetBit(kOwner, kFALSE);
      65       10819 :   memset(fPositions, 1, kMaxRows*sizeof(UChar_t));
      66       10819 :   memset(fClusters, 0, kMaxClustersLayer*sizeof(AliTRDcluster*));
      67       10819 :   memset(fIndex, 1, kMaxClustersLayer*sizeof(UInt_t));
      68       21638 : }
      69             : 
      70             : 
      71             : //_____________________________________________________________________________
      72             : AliTRDchamberTimeBin::AliTRDchamberTimeBin(const AliTRDchamberTimeBin &layer):
      73           0 :   TObject()
      74           0 :   ,fkReconstructor(layer.fkReconstructor)
      75           0 :   ,fPlane(layer.fPlane)
      76           0 :   ,fStack(layer.fStack)
      77           0 :   ,fSector(layer.fSector)
      78           0 :   ,fNRows(layer.fNRows)
      79           0 :   ,fN(layer.fN)
      80           0 :   ,fX(layer.fX)
      81           0 :   ,fZ0(layer.fZ0)
      82           0 :   ,fZLength(layer.fZLength)
      83           0 : {
      84             : // Copy Constructor 
      85             :   
      86           0 :   SetBit(kT0, layer.IsT0());
      87           0 :   SetBit(kOwner, kFALSE);
      88           0 :   for(int i=0; i<kMaxRows; i++) fPositions[i] = layer.fPositions[i];
      89           0 :   memcpy(&fClusters[0], &layer.fClusters[0], kMaxClustersLayer*sizeof(AliTRDcluster*));
      90           0 :   memcpy(&fIndex[0], &layer.fIndex[0], kMaxClustersLayer*sizeof(UInt_t));
      91             : 
      92             : 
      93             : //      BuildIndices();
      94           0 : }
      95             : 
      96             : //_____________________________________________________________________________
      97             : AliTRDchamberTimeBin &AliTRDchamberTimeBin::operator=(const AliTRDchamberTimeBin &layer)
      98             : {
      99             : // Assignment operator
     100             : 
     101           0 :   if (this != &layer) layer.Copy(*this);
     102           0 :   return *this;
     103             : }
     104             : 
     105             : //_____________________________________________________________________________
     106             : void AliTRDchamberTimeBin::Clear(const Option_t *) 
     107             : { 
     108             :   // Reset the Chamber Timebin
     109       21638 :   if(IsOwner())
     110           0 :     for(Int_t it = 0; it<kMaxClustersLayer; it++)
     111           0 :       delete fClusters[it];
     112       10819 :   memset(fClusters,0,kMaxClustersLayer*sizeof(fClusters[0]));
     113       10819 :   fN = 0; 
     114       10819 : }
     115             : 
     116             : //_____________________________________________________________________________
     117             : void AliTRDchamberTimeBin::Copy(TObject &o) const
     118             : {
     119             : // Copy method. Performs a deep copy of all data from this object to object o.
     120             :   
     121           0 :   AliTRDchamberTimeBin &layer = (AliTRDchamberTimeBin &)o;
     122           0 :   layer.fkReconstructor = fkReconstructor;
     123           0 :   layer.fPlane       = fPlane;
     124           0 :   layer.fStack       = fStack;
     125           0 :   layer.fSector      = fSector;
     126           0 :   layer.fNRows       = fNRows;
     127           0 :   layer.fN           = fN;
     128           0 :   layer.fX           = fX;
     129           0 :   layer.fZ0          = fZ0;
     130           0 :   layer.fZLength     = fZLength;
     131           0 :   layer.SetT0(IsT0());
     132           0 :   layer.SetBit(kOwner, kFALSE);
     133             :   
     134           0 :   for(int i=0; i<kMaxRows; i++) layer.fPositions[i] = fPositions[i];
     135           0 :   memcpy(&layer.fClusters[0], &fClusters[0], kMaxClustersLayer*sizeof(AliTRDcluster*));
     136           0 :   memcpy(&layer.fIndex[0], &fIndex[0], kMaxClustersLayer*sizeof(UInt_t));
     137             :   
     138           0 :   TObject::Copy(layer); // copies everything into layer
     139             :   
     140             : //      layer.BuildIndices();
     141           0 : }
     142             : 
     143             : //_____________________________________________________________________________
     144             : AliTRDchamberTimeBin::~AliTRDchamberTimeBin()
     145       43276 : {
     146             : // Destructor
     147       10819 :   if(IsOwner()){ 
     148           0 :     for(AliTRDcluster **cit = &fClusters[0]; (*cit); cit++) delete (*cit);
     149           0 :   }
     150       21638 : }
     151             : 
     152             : //_____________________________________________________________________________
     153             : void  AliTRDchamberTimeBin::SetOwner(Bool_t copy) 
     154             : {
     155             : // Sets the ownership of the clusters to this 
     156             : // If option "copy" is kTRUE [default] the clusters 
     157             : // are also copied otherwise only the ownership bit 
     158             : // is flipped.
     159             : 
     160           0 :   SetBit(kOwner, kTRUE);
     161           0 :   if(!copy) return;
     162           0 :   for(AliTRDcluster **cit = &fClusters[0]; (*cit); ++cit){
     163           0 :     (*cit) = new AliTRDcluster(*(*cit)); 
     164             :   }
     165           0 : }
     166             : 
     167             : //_____________________________________________________________________________
     168             : void AliTRDchamberTimeBin::SetRange(Float_t z0, Float_t zLength)
     169             : {
     170             : // Sets the range in z-direction
     171             : //
     172             : // Parameters:
     173             : //   z0      : starting position of layer in the z direction
     174             : //   zLength : length of layer in the z direction 
     175             : 
     176       15594 :   fZ0 = (z0 <= z0 + zLength) ? z0 : z0 + zLength;
     177        7797 :   fZLength = TMath::Abs(zLength);
     178        7797 : }
     179             : 
     180             : //_____________________________________________________________________________
     181             : void AliTRDchamberTimeBin::InsertCluster(AliTRDcluster *c, UInt_t index) 
     182             : {
     183             :   //
     184             :   // Insert cluster in cluster array.
     185             :   // Clusters are sorted according to Y coordinate.  
     186             :   //
     187             : 
     188             :   //if (fTimeBinIndex < 0) { 
     189             :     //AliWarning("Attempt to insert cluster into non-sensitive time bin!\n");
     190             :     //return;
     191             :   //}
     192             : 
     193       36904 :   if (fN == (Int_t) kMaxClustersLayer) {
     194             :     //AliWarning("Too many clusters !\n"); 
     195             :     return;
     196             :   }
     197             : 
     198       18452 :   if (fN == 0) {
     199        7797 :     fIndex[0]       = index; 
     200        7797 :     fClusters[fN++] = c; 
     201        7797 :     return;
     202             :   }
     203             : 
     204       10655 :   Int_t i = Find(c->GetY());
     205       10655 :   memmove(fClusters+i+1,fClusters+i,(fN-i)*sizeof(AliTRDcluster*));
     206       10655 :   memmove(fIndex   +i+1,fIndex   +i,(fN-i)*sizeof(UInt_t)); 
     207       10655 :   fIndex[i]    = index; 
     208       10655 :   fClusters[i] = c; 
     209       10655 :   fN++;
     210       29107 : }
     211             : 
     212             : //___________________________________________________
     213             : void AliTRDchamberTimeBin::Bootstrap(const AliTRDReconstructor *rec, Int_t det)
     214             : {
     215             : // Reinitialize all data members from the clusters array
     216             : // It has to be used after reading from disk
     217             : 
     218           0 :   fkReconstructor = rec;
     219           0 :   fPlane  = AliTRDgeometry::GetLayer(det);
     220           0 :   fStack  = AliTRDgeometry::GetStack(det);
     221           0 :   fSector = AliTRDgeometry::GetSector(det);
     222           0 :   AliTRDgeometry g;
     223           0 :   fNRows  = g.GetPadPlane(fPlane, fStack)->GetNrows();
     224           0 :   fN = 0;
     225           0 :   for(AliTRDcluster **cit = &fClusters[0]; (*cit); cit++) fN++;
     226           0 :   BuildIndices();
     227           0 : }
     228             : 
     229             : //_____________________________________________________________________________
     230             : void AliTRDchamberTimeBin::BuildIndices(Int_t iter)
     231             : {
     232             : // Rearrangement of the clusters belonging to the propagation layer for the stack.
     233             : //
     234             : // Detailed description
     235             : //
     236             : // The array indices of all clusters in one PropagationLayer are stored in
     237             : // array. The array is divided into several bins.
     238             : // The clusters are sorted in increasing order of their y coordinate.
     239             : //
     240             : // Sorting algorithm: TreeSearch
     241             : //
     242             : 
     243        7797 :   if(!fN) return;
     244             : 
     245             :   // Select clusters that belong to the Stack
     246             :   Int_t nClStack = 0;                                   // Internal counter
     247       52498 :   for(Int_t i = 0; i < fN; i++){
     248       36904 :     if(fClusters[i]->IsUsed() || fClusters[i]->IsShared()){
     249           0 :       fClusters[i] = NULL;
     250           0 :       fIndex[i] = 0xffff;
     251       18452 :     } else nClStack++;
     252             :   }
     253        7797 :   if(nClStack > kMaxClustersLayer) AliInfo(Form("Number of clusters in stack %d exceed buffer size %d. Truncating.", nClStack, kMaxClustersLayer));
     254             :     
     255             :   // Nothing in this time bin. Reset indexes 
     256        7797 :   if(!nClStack){
     257           0 :     fN = 0;
     258           0 :     memset(&fPositions[0], 0, sizeof(UChar_t) * kMaxRows);
     259           0 :     memset(&fClusters[0], 0, sizeof(AliTRDcluster*) * kMaxClustersLayer);
     260           0 :     memset(&fIndex[0], 0, sizeof(UInt_t) * kMaxClustersLayer);
     261           0 :     return;
     262             :   }
     263             :   
     264             :   // Make a copy
     265        7797 :   AliTRDcluster *helpCL[kMaxClustersLayer];
     266        7797 :   UInt_t helpInd[kMaxClustersLayer];
     267             :   nClStack = 0;
     268             :   // Defining iterators
     269        7797 :   AliTRDcluster **fcliter = &fClusters[0], **hcliter = &helpCL[0]; UInt_t *finditer = &fIndex[0], *hinditer = &helpInd[0];
     270             :   AliTRDcluster *tmpcl = NULL;
     271       52498 :   for(Int_t i = 0; i < TMath::Min(fN, kMaxClustersLayer); i++){
     272       18452 :     if(!(tmpcl = *(fcliter++))){
     273           0 :         finditer++;
     274           0 :         continue;
     275             :     }
     276       18452 :     *(hcliter++)  = tmpcl;
     277       18452 :     *(hinditer++) = *finditer;
     278             :     tmpcl = NULL;
     279       18452 :     *(finditer++) = 0xffff;
     280       18452 :     nClStack++;
     281       18452 :   }
     282             :   
     283             :   // do clusters arrangement
     284        7797 :   fX = 0.;
     285        7797 :   fN =  nClStack;
     286             :   nClStack = 0;
     287             :   // Reset Positions array
     288        7797 :   memset(fPositions, 0, sizeof(UChar_t)*kMaxRows);
     289             :   AliTRDcluster **cliter = &helpCL[0]; // Declare iterator running over the whole array
     290        7797 :   const AliTRDrecoParam* const recoParam = fkReconstructor->GetRecoParam(); //the dynamic cast in GetRecoParam is slow, so caching the pointer to it
     291             :   Int_t tb(-1);
     292       52498 :   for(Int_t i = 0; i < fN; i++){
     293             :     // boundary check
     294       18452 :     AliTRDcluster *cl = *(cliter++);
     295       18452 :     UChar_t rowIndex = cl->GetPadRow();
     296       26249 :     if(tb<0) tb=cl->GetLocalTimeBin();
     297             :     // Insert Leaf
     298       18452 :     Int_t pos = FindYPosition(cl->GetY(), rowIndex, nClStack);
     299       18452 :     if(pos == -2) continue;   // zbin error;
     300       18452 :     else if(pos == -1) {    // zbin is empty;
     301       34185 :       Int_t upper = (rowIndex == fNRows - 1) ? nClStack : fPositions[rowIndex + 1];
     302       11395 :       memmove(fClusters + upper + 1, fClusters + upper, (sizeof(AliTRDcluster *))*(nClStack-upper));
     303       11395 :       memmove(fIndex + upper + 1, fIndex + upper, (sizeof(UInt_t))*(nClStack-upper));
     304       11395 :       fClusters[upper] = cl;
     305       11395 :       fIndex[upper] = helpInd[i]; 
     306             :       // Move All pointer one position back
     307      172288 :       for(UChar_t j = rowIndex + 1; j < fNRows; j++) fPositions[j]++;
     308       11395 :       nClStack++;
     309       11395 :     } else {            // zbin not empty
     310        7057 :       memmove(fClusters + pos + 2, fClusters + pos+1, (sizeof(AliTRDcluster *))*(nClStack-(pos+1)));
     311        7057 :       memmove(fIndex + pos + 2, fIndex + pos+1, (sizeof(UInt_t))*(nClStack-(pos+1)));
     312        7057 :       fClusters[pos + 1] = cl;  //fIndex[i];
     313        7057 :       fIndex[pos + 1] = helpInd[i];
     314             :       // Move All pointer one position back
     315       86068 :       for(UChar_t j = rowIndex + 1; j < fNRows; j++) fPositions[j]++;        
     316        7057 :       nClStack++;
     317             :     }
     318             : 
     319             :     // calculate mean x
     320       18452 :     fX += cl->GetX(); 
     321             :     
     322             :     // Debug Streaming
     323       18452 :     if(recoParam->GetStreamLevel(AliTRDrecoParam::kTracker) >= 3){
     324           0 :       AliTRDcluster dcl(*cl);
     325           0 :       TTreeSRedirector &cstream = *fkReconstructor->GetDebugStream(AliTRDrecoParam::kTracker);
     326           0 :       cstream << "BuildIndices"
     327           0 :       << "Plane="    << fPlane
     328           0 :       << "Stack="    << fStack
     329           0 :       << "Sector="   << fSector
     330           0 :       << "Iter="     << iter
     331           0 :       << "C.="       << &dcl
     332           0 :       << "rowIndex=" << rowIndex
     333           0 :       << "\n";
     334           0 :     }
     335       36904 :   }
     336             : 
     337             : //      AliInfo("Positions");
     338             : //      for(int ir=0; ir<fNRows; ir++) printf("pos[%d] %d\n", ir, fPositions[ir]);
     339        7797 :   if(nClStack < fN){
     340           0 :     AliWarning(Form("Found %d out of %d clusters outside in ChamberTimeBin[%02d_%d_%d|%2d]", fN-nClStack, fN, fSector, fStack, fPlane, tb));
     341           0 :     fN =  nClStack;
     342           0 :     if(!fN){ // Nothing left in this time bin. Reset indexes
     343           0 :       memset(&fPositions[0], 0, sizeof(UChar_t) * kMaxRows);
     344           0 :       memset(&fClusters[0], 0, sizeof(AliTRDcluster*) * kMaxClustersLayer);
     345           0 :       memset(&fIndex[0], 0, sizeof(UInt_t) * kMaxClustersLayer);
     346           0 :       return;
     347             :     }
     348             :   }
     349       15594 :   if(fN) fX /= fN;
     350       23391 : }
     351             : 
     352             : //_____________________________________________________________________________
     353             : Int_t AliTRDchamberTimeBin::Find(Float_t y) const
     354             : {
     355             :   //
     356             :   // Returns index of the cluster nearest in Y    
     357             :   //
     358             : 
     359       21310 :   if (fN <= 0) return 0;
     360             :   
     361       15205 :   if (y <= fClusters[0]->GetY()) return 0;
     362             :   
     363        7871 :   if (y >  fClusters[fN-1]->GetY()) return fN;
     364             :   
     365             : 
     366             :   Int_t b = 0;
     367        4339 :   Int_t e = fN - 1;
     368        4339 :   Int_t m = (b + e) / 2;
     369             : 
     370       34356 :   for ( ; b < e; m = (b + e) / 2) {
     371       19554 :     if (y > fClusters[m]->GetY()) b = m + 1;
     372             :     else e = m;
     373             :   }
     374             : 
     375             :   return m;
     376       10655 : }    
     377             : 
     378             : //_____________________________________________________________________________
     379             : Int_t AliTRDchamberTimeBin::FindYPosition(Double_t y, UChar_t z, Int_t nClusters) const
     380             : {
     381             : //
     382             : // Tree search Algorithm to find the nearest left cluster for a given
     383             : // y-position in a certain z-bin (in fact AVL-tree). 
     384             : // Making use of the fact that clusters are sorted in y-direction.
     385             : //
     386             : // Parameters:
     387             : //   y : y position of the reference point in tracking coordinates
     388             : //   z : z reference bin.
     389             : //   nClusters : 
     390             : //
     391             : // Output :
     392             : // Index of the nearest left cluster in the StackLayer indexing (-1 if no clusters are found)
     393             : //
     394             : 
     395       36904 :   if(z>=fNRows){ // check pad row of cluster
     396           0 :     AliDebug(1, Form("Row[%2d] outside range [0 %2d] in %02d_%d_%d.", z, fNRows, fSector, fStack, fPlane));
     397           0 :     return -2;
     398             :   }
     399       18452 :   Int_t start = fPositions[z];          // starting Position of the bin
     400       55356 :   Int_t upper = (Int_t)((z != fNRows - 1) ? fPositions[z+1] : nClusters); // ending Position of the bin 
     401       18452 :   Int_t end = upper - 1; // ending Position of the bin 
     402       29847 :   if(end < start) return -1; // Bin is empty
     403        7057 :   Int_t middle = static_cast<Int_t>((start + end)/2);
     404             :   // 1st Part: climb down the tree: get the next cluster BEFORE ypos
     405       23942 :   while(start + 1 < end){
     406        9828 :     if(y >= fClusters[middle]->GetY()) start = middle;
     407             :     else end = middle;
     408        4914 :     middle = static_cast<Int_t>((start + end)/2);
     409             :   }
     410       14114 :   if(y > fClusters[end]->GetY()) return end;
     411           0 :   return start;
     412       18452 : }
     413             : 
     414             : //_____________________________________________________________________________
     415             : Int_t AliTRDchamberTimeBin::FindNearestYCluster(Double_t y, UChar_t z) const
     416             : {
     417             : //
     418             : // Tree search Algorithm to find the nearest cluster for a given
     419             : // y-position in a certain z-bin (in fact AVL-tree). 
     420             : // Making use of the fact that clusters are sorted in y-direction.
     421             : //
     422             : // Parameters:
     423             : //   y : y position of the reference point in tracking coordinates
     424             : //   z : z reference bin.
     425             : //
     426             : // Output 
     427             : // Index of the nearest cluster in the StackLayer indexing (-1 if no clusters are found)
     428             : //
     429             : 
     430           0 :   Int_t position = FindYPosition(y, z, fN);
     431           0 :   if(position == -2 || position == -1) return position; // bin empty
     432             :   // FindYPosition always returns the left Neighbor. We don't know if the left or the right Neighbor is nearest
     433             :   // to the Reference y-position, so test both
     434           0 :   Int_t upper = (Int_t)((z < fNRows-1) ? fPositions[z+1] : fN); // ending Position of the bin
     435           0 :   if((position + 1) < (upper)){
     436           0 :     if(TMath::Abs(y - fClusters[position + 1]->GetY()) < TMath::Abs(y - fClusters[position]->GetY())) return position + 1;
     437           0 :     else return position;
     438             :   }
     439           0 :   return position;
     440           0 : }
     441             : 
     442             : //_____________________________________________________________________________
     443             : Int_t AliTRDchamberTimeBin::SearchNearestCluster(Double_t y, Double_t z, Double_t maxroady, Double_t maxroadz) const
     444             : {
     445             : //
     446             : // Finds the nearest cluster from a given point in a defined range.
     447             : // Distance is determined in a 2D space by the 2-Norm.
     448             : //
     449             : // Parameters :
     450             : //   y : y position of the reference point in tracking coordinates
     451             : //   z : z reference bin.
     452             : //   maxroady : maximum searching distance in y direction
     453             : //   maxroadz : maximum searching distance in z direction
     454             : //
     455             : // Output 
     456             : // Index of the nearest cluster in the StackLayer indexing (-1 if no cluster is found).
     457             : // Cluster can be accessed with the operator[] or GetCluster(Int_t index)
     458             : //
     459             : // Detail description
     460             : //
     461             : // The following steps are perfomed:
     462             : // 1. Get the expected z bins inside maxroadz.
     463             : // 2. For each z bin find nearest y cluster.
     464             : // 3. Select best candidate
     465             : //
     466             :   Int_t   index   = -1;
     467             :   // initial minimal distance will be represented as ellipse: semi-major = z-direction
     468             :   // later 2-Norm will be used  
     469             : //      Float_t nExcentricity = TMath::Sqrt(maxroadz*maxroadz - maxroad*maxroad)/maxroadz;
     470           0 :   Float_t mindist = maxroadz;
     471             :   
     472             :   // not very nice but unfortunately neccessarry: we have ho check the neighbors in both directions (+ and -) too. How 
     473             :   // much neighbors depends on the Quotient maxroadz/fZLength   
     474             :   UChar_t maxRows = 3;
     475           0 :   UChar_t zpos[kMaxRows];
     476             :   // Float_t mindist = TMath::Sqrt(maxroad*maxroad + maxroadz*maxroadz);
     477             : //      UChar_t myZbin = FindTreePosition(z, fZ0 + fZLength/2, fZLength/4, 8, 8, kFALSE);
     478           0 :   UChar_t myZbin = fNRows - 1 - (UChar_t)(TMath::Abs(fZ0 - z)/fZLength * fNRows);
     479           0 :   if(z < fZ0) myZbin = fNRows - 1;
     480           0 :   if(z > fZ0 + fZLength) myZbin = 0;
     481             :   //printf("\n%f < %f < %f [%d]\n", fZ0, z, fZ0 + fZLength, myZbin);
     482             :   //for(int ic=0; ic<fN; ic++) printf("%d z = %f row %d\n", ic, fClusters[ic]->GetZ(), fClusters[ic]->GetPadRow());
     483             : 
     484             :   UChar_t nNeighbors = 0;
     485           0 :   for(UChar_t i = 0; i < maxRows; i++){
     486           0 :     if((myZbin - 1 + i) < 0) continue;
     487           0 :     if((myZbin - 1 + i) > fNRows - 1) break;
     488           0 :     zpos[nNeighbors] = myZbin - 1 + i;
     489           0 :     nNeighbors++;
     490           0 :   }
     491             :   Float_t ycl = 0, zcl = 0;
     492           0 :   for(UChar_t neighbor = 0; neighbor < nNeighbors; neighbor++){      // Always test the neighbors too
     493           0 :     Int_t pos = FindNearestYCluster(y, zpos[neighbor]);
     494           0 :     if(pos == -1) continue;     // No cluster in bin
     495           0 :     AliTRDcluster *c = (AliTRDcluster *) (fClusters[pos]);
     496           0 :     if(c->IsUsed()) continue;                // we are only interested in unused clusters
     497           0 :     ycl = c->GetY();
     498             :     // Too far away in y-direction (Prearrangement)
     499           0 :     if (TMath::Abs(ycl - y) > maxroady){ 
     500             :       //printf("y[%f] ycl[%f] roady[%f]\n", y, ycl, maxroady);
     501           0 :       continue;
     502             :     }
     503           0 :     zcl = c->GetZ();
     504             :     // Too far away in z-Direction
     505             :     // (Prearrangement since we have not so many bins to test)
     506           0 :     if (TMath::Abs(zcl - z) > maxroadz) continue;
     507             :     
     508             :     Float_t dist;               // distance defined as 2-Norm   
     509             :     // if we havent found a Particle that is in the ellipse around (y,z) with maxroad as semi-minor and
     510             :     // maxroadz as semi-major, we take the radius of the ellipse concerning the cluster as mindist, later we 
     511             :     // take the 2-Norm when we found a cluster inside the ellipse (The value 10000 is taken because it is surely
     512             :     // large enough to be usable as an indicator whether we have found a nearer cluster or not)
     513             : //              if(mindist > 10000.){
     514             : //                      Float_t phi = ((zcl - z) == 0) ? TMath::Pi()/2 : TMath::ATan((ycl - y)/(zcl - z));
     515             : //                      mindist = maxroad/TMath::Sqrt(1 - nExcentricity*nExcentricity * (TMath::Cos(phi))*(TMath::Cos(phi)));
     516             : //              }
     517           0 :     dist = TMath::Max(TMath::Abs(y-ycl),TMath::Abs(z-zcl));     // infinity Norm
     518             : //              dist = TMath::Sqrt((ycl - y)*(ycl - y) + (zcl - z)*(zcl - z));
     519           0 :     if((Int_t)(dist * 100000) < (Int_t)(mindist * 100000)){
     520             :     //if((dist = TMath::Sqrt((ycl - y)*(ycl - y) + (zcl - z)*(zcl - z))) < mindist){
     521             :       mindist = dist;
     522             :       index   = pos;
     523           0 :     }   
     524           0 :   }
     525             :   // This is the Array Position in fIndex2D of the Nearest cluster: if a
     526             :   // cluster is called, then the function has to retrieve the Information
     527             :   // which is Stored in the Array called, the function
     528           0 :   return index;
     529           0 : }
     530             : 
     531             : //_____________________________________________________________________________
     532             : void AliTRDchamberTimeBin::BuildCond(AliTRDcluster * const cl, Double_t *cond, UChar_t Layer, Double_t theta, Double_t phi)
     533             : {
     534             : // Helper function to calculate the area where to expect a cluster in THIS
     535             : // layer. 
     536             : //
     537             : // Parameters :
     538             : //   cl    : 
     539             : //   cond  :
     540             : //   Layer : 
     541             : //   theta : 
     542             : //   phi   : 
     543             : //
     544             : // Detail description
     545             : //
     546             : // Helper function to calculate the area where to expect a cluster in THIS
     547             : // layer. by using the information of a former cluster in another layer
     548             : // and the angle in theta- and phi-direction between layer 0 and layer 3.
     549             : // If the layer is zero, initial conditions are calculated. Otherwise a
     550             : // linear interpolation is performed. 
     551             : //Begin_Html
     552             : //<img src="gif/build_cond.gif">
     553             : //End_Html
     554             : //
     555             : 
     556           0 :   if(!fkReconstructor){
     557           0 :     AliError("Reconstructor not set.");
     558           0 :     return;
     559             :   }
     560             :   
     561           0 :   if(Layer == 0){
     562           0 :     cond[0] = cl->GetY();                    // center: y-Direction
     563           0 :     cond[1] = cl->GetZ();                    // center: z-Direction
     564           0 :     cond[2] = fkReconstructor->GetRecoParam()->GetMaxPhi()   * (cl->GetX() - GetX()) + 1.0;                    // deviation: y-Direction
     565           0 :     cond[3] = fkReconstructor->GetRecoParam()->GetMaxTheta() * (cl->GetX() - GetX()) + 1.0;                    // deviation: z-Direction
     566           0 :   } else {
     567           0 :     cond[0] = cl->GetY() + phi   * (GetX() - cl->GetX()); 
     568           0 :     cond[1] = cl->GetZ() + theta * (GetX() - cl->GetX());
     569           0 :     cond[2] = fkReconstructor->GetRecoParam()->GetRoad0y() + phi;
     570           0 :     cond[3] = fkReconstructor->GetRecoParam()->GetRoad0z();
     571             :   }
     572           0 : }
     573             : 
     574             : //_____________________________________________________________________________
     575             : void AliTRDchamberTimeBin::GetClusters(const Double_t * const cond, Int_t *index, Int_t& ncl, Int_t BufferSize)
     576             : {
     577             : // Finds all clusters situated in this layer inside a rectangle  given by the center an ranges.
     578             : //
     579             : // Parameters :
     580             : //   cond  :
     581             : //   index : 
     582             : //   ncl :
     583             : //   BufferSize   :
     584             : //
     585             : // Output :
     586             : //
     587             : // Detail description
     588             : //
     589             : // Function returs an array containing the indices in the stacklayer of
     590             : // the clusters found an  the number of found clusters in the stacklayer
     591             : 
     592       11790 :   ncl = 0;
     593        5895 :   memset(index, 0, BufferSize*sizeof(Int_t));
     594        5895 :   if(fN == 0) return;
     595             :     
     596             :   //Boundary checks
     597             :   Double_t zvals[2];
     598       11790 :   if(((cond[1] - cond[3]) >= (fZ0 + fZLength)) || (cond[1] + cond[3]) <= fZ0) return; // We are outside of the chamvber
     599       17685 :   zvals[0] = ((cond[1] - cond[3]) < fZ0) ? fZ0 : (cond[1] - cond[3]);
     600       17685 :   zvals[1] = ((cond[1] + cond[3]) < fZ0 + fZLength) ? (cond[1] + cond[3]) : fZ0 + fZLength - 1.E-3;
     601             : 
     602        5895 :   UChar_t zhi = fNRows - 1 - (UChar_t)(TMath::Abs(fZ0 - zvals[0])/fZLength * fNRows);
     603        5895 :   UChar_t zlo = fNRows - 1 - (UChar_t)(TMath::Abs(fZ0 - zvals[1])/fZLength * fNRows);
     604             : 
     605             : /*      AliInfo(Form("yc[%f] zc[%f] dy[%f] dz[%f]", cond[0], cond[1], cond[2], cond[3]));
     606             :   PrintClusters();
     607             :   AliInfo(Form("zlo[%f] zhi[%f]", zvals[0], zvals[1]));
     608             :   AliInfo(Form("zlo[%d] zhi[%d]", zlo, zhi));*/
     609             : 
     610        5895 :   Double_t ylo = cond[0] - cond[2],
     611        5895 :            yhi = cond[0] + cond[2];
     612             :   //printf("CTB : ylo[%f] yhi[%f]\n", ylo, yhi);
     613             :   //Preordering in Direction z saves a lot of loops (boundary checked)
     614       99835 :   for(UChar_t z = zlo; z <= zhi; z++){
     615      123225 :     UInt_t upper = (z < fNRows-1) ? fPositions[z+1] : fN;
     616             :     //AliInfo(Form("z[%d] y [%d %d]", z, fPositions[z], upper));
     617      138135 :     for(Int_t y = fPositions[z]; y < (Int_t)upper; y++){
     618        8496 :       if(ncl == BufferSize){
     619           0 :         AliDebug(1, Form("Buffer size [%d] riched. Some clusters may be lost.", BufferSize));
     620           0 :         return; //Buffer filled
     621             :       }
     622             :       
     623        9190 :       if(fClusters[y]->GetY() > yhi) break;                       // Abbortion conditions!!!
     624        7802 :       if(fClusters[y]->GetY() < ylo) continue;    // Too small
     625       11062 :       if(((Int_t)((fClusters[y]->GetZ())*1000) < (Int_t)(zvals[0]*1000)) || ((Int_t)((fClusters[y]->GetZ())*1000) > (Int_t)(zvals[1]*1000))){/*printf("exit z\n"); TODO*/ continue;}
     626        5487 :       index[ncl] = y;
     627        5487 :       ncl++;
     628        5487 :     }
     629       41075 :   }
     630        5895 :   if(ncl>fN) AliError(Form("Clusters found %d > %d (clusters in layer)", ncl, fN));
     631       11790 : }
     632             : 
     633             : //_____________________________________________________________________________
     634             : AliTRDcluster *AliTRDchamberTimeBin::GetNearestCluster(Double_t *cond)
     635             : {
     636             : // Function returning a pointer to the nearest cluster (nullpointer if not successfull).
     637             : //
     638             : // Parameters :
     639             : //   cond  :
     640             : //
     641             : // Output :
     642             : //   pointer to the nearest cluster (nullpointer if not successfull).
     643             : // 
     644             : // Detail description
     645             : //
     646             : // returns a pointer to the nearest cluster (nullpointer if not
     647             : // successfull) by the help of the method FindNearestCluster
     648             :   
     649             :   
     650           0 :   Double_t maxroad  = fkReconstructor->GetRecoParam()->GetRoad2y();
     651           0 :   Double_t maxroadz = fkReconstructor->GetRecoParam()->GetRoad2z();
     652             :   
     653           0 :   Int_t index = SearchNearestCluster(cond[0],cond[1],maxroad,maxroadz);
     654             :   AliTRDcluster *returnCluster = NULL;
     655           0 :   if(index != -1) returnCluster = (AliTRDcluster *) fClusters[index];
     656           0 :   return returnCluster;
     657             : }
     658             : 
     659             : //_____________________________________________________________________________
     660             : void AliTRDchamberTimeBin::Print(Option_t *) const
     661             : {
     662             : // Prints the position of each cluster in the stacklayer on the stdout
     663             : //
     664           0 :   if(!fN) return;
     665           0 :   AliInfo(Form("Layer[%d] Stack[%d] Sector[%2d] nRows[%2d]", fPlane, fStack, fSector, fNRows));
     666           0 :   AliInfo(Form("Z0[%7.3f] Z1[%7.3f]", fZ0, fZ0+fZLength));
     667           0 :   AliTRDcluster* const* icl = &fClusters[0];
     668           0 :   for(Int_t jcl = 0; jcl < fN; jcl++, icl++){
     669           0 :     AliInfo(Form("%2d X[%7.3f] Y[%7.3f] Z[%7.3f] tb[%2d] col[%3d] row[%2d] used[%s]", jcl,  (*icl)->GetX(), (*icl)->GetY(), (*icl)->GetZ(), (*icl)->GetLocalTimeBin(), (*icl)->GetPadCol(), (*icl)->GetPadRow(),
     670             :     (*icl)->IsUsed() ? "y" : "n"));
     671             :   }
     672             :   Int_t irow = 0;
     673           0 :   for(UChar_t const* pos = &fPositions[0]; irow<fNRows; pos++, irow++){ 
     674           0 :     if((*pos) != 0xff) AliInfo(Form("r[%2d] pos[%d]", irow, (*pos)));
     675             :   }
     676           0 : }

Generated by: LCOV version 1.11