LCOV - code coverage report
Current view: top level - HLT/TPCLib/HWCFemulator - AliHLTTPCHWClusterMerger.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 232 0.4 %
Date: 2016-06-14 17:26:59 Functions: 1 12 8.3 %

          Line data    Source code
       1             : // $Id$
       2             : 
       3             : //**************************************************************************
       4             : //* This file is property of and copyright by the ALICE HLT Project        * 
       5             : //* ALICE Experiment at CERN, All rights reserved.                         *
       6             : //*                                                                        *
       7             : //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
       8             : //*                  Sergey Gorbunov                                       *
       9             : //*                  for The ALICE HLT Project.                            *
      10             : //*                                                                        *
      11             : //* Permission to use, copy, modify and distribute this software and its   *
      12             : //* documentation strictly for non-commercial purposes is hereby granted   *
      13             : //* without fee, provided that the above copyright notice appears in all   *
      14             : //* copies and that both the copyright notice and this permission notice   *
      15             : //* appear in the supporting documentation. The authors make no claims     *
      16             : //* about the suitability of this software for any purpose. It is          *
      17             : //* provided "as is" without express or implied warranty.                  *
      18             : //**************************************************************************
      19             : 
      20             : //  @file   AliHLTTPCHWClusterMerger.cxx
      21             : //  @author Matthias Richter, Sergey Gorbunov
      22             : //  @date   2011-11-25
      23             : //  @brief  Merger class for HLT TPC Hardware clusters
      24             : //          Handles merging of branch border clusters
      25             : 
      26             : #include <algorithm>
      27             : 
      28             : #include "AliHLTTPCHWClusterMerger.h"
      29             : #include "AliHLTTPCGeometry.h"
      30             : #include "AliHLTTPCSpacePointData.h"
      31             : #include "AliHLTTPCHWCFSupport.h"
      32             : 
      33             : /** ROOT macro for the implementation of ROOT specific class methods */
      34           6 : ClassImp(AliHLTTPCHWClusterMerger)
      35             : 
      36             : AliHLTTPCHWClusterMerger::AliHLTTPCHWClusterMerger()
      37           0 :   : AliHLTLogging()
      38           0 :   , fMapping(0)
      39           0 :   , fNRows(0)
      40           0 :   , fNRowPads(0)
      41           0 :   , fNBorders(0)
      42           0 :   , fBorders(0)
      43           0 :   , fBorderNClusters(0)
      44           0 :   , fBorderFirstCluster(0)
      45           0 :   , fBorderClusters(0)
      46           0 :   , fBorderNClustersTotal(0)
      47           0 :   , fClusters()
      48           0 :   , fRemovedClusterIds()
      49           0 :   , fIter()
      50           0 :   , fEnd()
      51           0 : {
      52             :   // see header file for class documentation
      53             :   // or
      54             :   // refer to README to build package
      55             :   // or
      56             :   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
      57             :   // constructor
      58           0 : }
      59             : 
      60             : AliHLTTPCHWClusterMerger::~AliHLTTPCHWClusterMerger()
      61           0 : {
      62             :   // destructor
      63           0 :   delete[] fMapping;
      64           0 :   delete [] fBorders;
      65           0 :   delete[] fBorderNClusters;
      66           0 :   delete[] fBorderFirstCluster;
      67           0 :   delete[] fBorderClusters;
      68           0 : }
      69             : 
      70             : void AliHLTTPCHWClusterMerger::Init()
      71             : {
      72             :   // initialisation
      73             :   
      74           0 :   delete[] fMapping;
      75           0 :   delete[] fBorders;
      76           0 :   delete[] fBorderNClusters;
      77           0 :   delete[] fBorderFirstCluster;
      78           0 :   delete[] fBorderClusters;
      79           0 :   fMapping = 0;
      80           0 :   fBorders = 0;
      81           0 :   fBorderNClusters = 0;
      82           0 :   fBorderFirstCluster = 0;
      83           0 :   fBorderClusters = 0;
      84           0 :   fBorderNClustersTotal = 0;
      85           0 :   fNRows = AliHLTTPCGeometry::GetNRows();
      86           0 :   fNRowPads = 0;  
      87           0 :   fNBorders = 0;
      88           0 :   for( int i=0; i<fNRows; i++ ){
      89           0 :     int nPads = AliHLTTPCGeometry::GetNPads(i); 
      90           0 :     if( fNRowPads<nPads ) fNRowPads = nPads;
      91             :   }
      92           0 :   int nPadsTotal = fNRows*fNRowPads;
      93           0 :   fMapping = new AliHLTInt16_t [nPadsTotal];
      94             : 
      95           0 :   if( !fMapping ){
      96           0 :     HLTError("Can not allocate memory: %d bytes", nPadsTotal*sizeof(AliHLTInt16_t));
      97           0 :     return;
      98             :   }
      99           0 :   for( int i=0; i<nPadsTotal; i++ ){
     100           0 :     fMapping[i] = -1;
     101             :   }
     102             : 
     103           0 :   AliHLTTPCHWCFSupport support; 
     104             : 
     105           0 :   for( int iPart=0; iPart<6; iPart++ ){
     106           0 :     const AliHLTUInt32_t *m = support.GetMapping(0,iPart);
     107           0 :     int nHWAddress=m[0];
     108           0 :     for( int iHW=0; iHW<nHWAddress; iHW++ ){
     109           0 :       AliHLTUInt32_t configWord = m[iHW+1];
     110           0 :       int row = (configWord>>8) & 0x3F;
     111           0 :       int pad =  configWord & 0xFF;
     112           0 :       bool border = (configWord>>14) & 0x1;
     113           0 :       if( !border ) continue;
     114           0 :       row+=AliHLTTPCGeometry::GetFirstRow(iPart);
     115           0 :       if( row>=fNRows ) continue;
     116           0 :       if( pad>=AliHLTTPCGeometry::GetNPads(row) ) continue;
     117           0 :       fMapping[row*fNRowPads + pad] = -2;
     118           0 :     }
     119             :   }
     120             : 
     121           0 :   std::vector<AliHLTFloat32_t> vBorders;
     122           0 :   for( int row=0; row<fNRows; row++ ){
     123           0 :     for( int pad=0; pad<fNRowPads-1; pad++ ){
     124           0 :       AliHLTInt16_t *m = fMapping + row*fNRowPads;
     125           0 :       if( m[pad]==-2 && m[pad+1]==-2 ){ 
     126           0 :         m[pad] = fNBorders;     
     127           0 :         for( int i=1; i<fkMergeWidth; i++ ){   
     128           0 :           if( pad-i<0 || m[pad-i]!=-1 ) break;
     129           0 :           m[pad-i] = fNBorders;
     130             :         }
     131           0 :         m[pad+1] = fNBorders+1;
     132           0 :         for( int i=1; i<fkMergeWidth; i++ ){   
     133           0 :           if( pad+1+i>=fNRowPads || m[pad+1+i]!=-1 ) break;
     134           0 :           m[pad+1+i] = fNBorders+1;     
     135             :         }       
     136           0 :         fNBorders+=2;
     137           0 :         vBorders.push_back(pad+1.);
     138           0 :         vBorders.push_back(pad+1.);
     139             :       }
     140             :     }
     141             :   } 
     142             : 
     143             :   //cout<<" NBorders = "<<fNBorders/2<<endl;
     144             : 
     145             :   /*  
     146             :   cout<<"Borders:"<<endl;
     147             :   for( int row=0; row<fNRows; row++ ){
     148             :     for( int pad=0; pad<fNRowPads; pad++ ){
     149             :       AliHLTInt16_t *m = fMapping + row*fNRowPads;
     150             :       if( m[pad]>=0 ) {
     151             :         cout<<row<<" "<<pad<<" "<<m[pad]%2<<endl;
     152             :       }
     153             :     }
     154             :   }
     155             :   */
     156             : 
     157           0 :   fBorders = new AliHLTFloat32_t [fNBorders];
     158           0 :   if( !fBorders ){
     159           0 :     HLTError("Can not allocate memory: %d bytes", fNBorders*sizeof(AliHLTFloat32_t));
     160           0 :     fNBorders = 0;
     161           0 :     return;
     162             :   }
     163           0 :   for( int i=0; i<fNBorders; i++ ){
     164           0 :     fBorders[i] = vBorders[i];
     165             :   }
     166           0 :   fBorderNClusters = new int[fkNSlices*fNBorders];
     167           0 :   if( !fBorderNClusters ){
     168           0 :     HLTError("Can not allocate memory: %d bytes", fkNSlices*fNBorders*sizeof(int));    
     169           0 :     return;
     170             :   }
     171             : 
     172           0 :   fBorderFirstCluster = new int[fkNSlices*fNBorders];
     173           0 :   if( !fBorderFirstCluster ){
     174           0 :     HLTError("Can not allocate memory: %d bytes", fkNSlices*fNBorders*sizeof(int));    
     175           0 :     return;
     176             :   }
     177             : 
     178           0 :   for( int i=0; i<fkNSlices*fNBorders; i++){
     179           0 :     fBorderNClusters[i] = 0;  
     180           0 :     fBorderFirstCluster[i] = 0;  
     181             :   }
     182           0 : }
     183             : 
     184             : bool AliHLTTPCHWClusterMerger::CheckCandidate(int /*slice*/, int partition, int partitionrow, float pad, float /*time*/, float sigmaPad2
     185             : ) 
     186             : {
     187             :   /// check cluster if it is a candidate for merging
     188           0 :   int slicerow=partitionrow+AliHLTTPCGeometry::GetFirstRow(partition);
     189             :   
     190           0 :   if( !fMapping ) Init();
     191           0 :   if( !fMapping ) return 0;
     192           0 :   if( slicerow <0 || slicerow>= fNRows ) return 0;
     193           0 :   int iPad = (int) pad;
     194           0 :   if( iPad<0 || iPad>=fNRowPads ) return 0;
     195           0 :   int atBorder = fMapping[slicerow*fNRowPads+iPad];    
     196           0 :   if( atBorder<0 ) return 0;
     197           0 :   float dPad = pad - fBorders[atBorder];
     198           0 :   if( sigmaPad2>1.e-4 ){
     199           0 :     if( dPad*dPad > 12.*sigmaPad2 ) return 0;
     200             :   } else {
     201           0 :     if( fabs(dPad)>1. ) return 0;
     202             :   }
     203           0 :   return 1;
     204           0 : }
     205             : 
     206             : int AliHLTTPCHWClusterMerger::AddCandidate(int slice,
     207             :                                            int partition,
     208             :                                            short partitionrow,
     209             :                                            float pad,
     210             :                                            float time,
     211             :                                            float sigmaPad2,
     212             :                                            float sigmaTime2,
     213             :                                            unsigned short charge,
     214             :                                            unsigned short qmax,
     215             :                                            unsigned short flags,
     216             :                                            AliHLTUInt32_t id,
     217             :                                            const AliHLTTPCClusterMCLabel *mc 
     218             :                                            )
     219             : {
     220             :   /// add a candidate for merging and register in the index grid
     221             :     
     222             :   int iBorder = -1;
     223           0 :   int iPad = (int) pad;
     224           0 :   if( !fMapping ) Init();
     225             :  
     226           0 :   int slicerow=partitionrow+AliHLTTPCGeometry::GetFirstRow(partition);
     227             :  
     228           0 :   if (id!=~AliHLTUInt32_t(0)) {
     229           0 :     if (slice<0) {
     230           0 :       slice=AliHLTTPCSpacePointData::GetSlice(id);
     231           0 :     } else if ((unsigned)slice!=AliHLTTPCSpacePointData::GetSlice(id)) {
     232           0 :       HLTError("cluster id 0x%08x is not consistent with specified slice %d", id, slice);
     233             :     }
     234           0 :     if (partition<0) {
     235           0 :       partition=AliHLTTPCSpacePointData::GetPatch(id);
     236           0 :     } else if ((unsigned)partition!=AliHLTTPCSpacePointData::GetPatch(id)) {
     237           0 :       HLTError("cluster id 0x%08x is not consistent with specified partition %d", id, partition);
     238             :     }
     239             :   }
     240             : 
     241           0 :   if( slice<0 || slice>=fkNSlices ){
     242           0 :     HLTError("cluster id 0x%08x has wrong slice number %d", id, slice);    
     243             :   }
     244             :   
     245           0 :   if( partition<0 || partition>=6 ){
     246           0 :     HLTError("cluster id 0x%08x has wrong partition number %d", id, partition);
     247             :   }
     248             :   
     249           0 :   if( slice>=0 && slice<fkNSlices && slicerow>=0 && slicerow <fNRows && fMapping && iPad>=0 && iPad < fNRowPads ){
     250           0 :     iBorder = fMapping[slicerow*fNRowPads+iPad];
     251             :     
     252           0 :     if( iBorder>=0 ){
     253           0 :       float dPad = pad - fBorders[iBorder];
     254           0 :       if( sigmaPad2>1.e-4 ){
     255           0 :         if( dPad*dPad > 12.*sigmaPad2 ) iBorder = -1;
     256             :       } else {
     257           0 :         if( fabs(dPad)>1. ) iBorder = -1;
     258             :       }    
     259           0 :     }
     260           0 :     if( iBorder>=0 ) iBorder = slice*fNBorders + iBorder;
     261             :   }
     262             : 
     263           0 :   fClusters.push_back(AliClusterRecord(slice, partition, iBorder, -1, id,
     264           0 :                                        AliHLTTPCRawCluster(partitionrow, pad, time, sigmaPad2, sigmaTime2, charge, qmax, flags),
     265           0 :                                        mc!=NULL?*mc:AliHLTTPCClusterMCLabel() ));
     266             : 
     267           0 :   if( iBorder>=0 ){
     268           0 :     fBorderNClusters[iBorder]++;
     269           0 :     fBorderNClustersTotal++;
     270           0 :   }
     271           0 :   return fClusters.size()-1;
     272           0 : }
     273             : 
     274             : int AliHLTTPCHWClusterMerger::FillIndex()
     275             : {
     276             :   /// loop over cached raw clusters and fill index
     277             : 
     278           0 :   delete[] fBorderClusters;
     279           0 :   fBorderClusters = 0;
     280           0 :   fBorderClusters = new AliBorderRecord[fBorderNClustersTotal];
     281             :   
     282           0 :   fBorderFirstCluster[0] = 0;
     283           0 :   for(int i=1; i<fkNSlices*fNBorders; i++ ){
     284           0 :     fBorderFirstCluster[i] = fBorderFirstCluster[i-1] + fBorderNClusters[i-1];
     285           0 :     fBorderNClusters[i-1] = 0;
     286             :   }
     287           0 :   fBorderNClusters[fkNSlices*fNBorders-1]=0;
     288           0 :   for (AliHLTUInt32_t pos=0; pos<fClusters.size(); pos++) {
     289           0 :     int iBorder = fClusters[pos].GetBorder();
     290           0 :     if( iBorder<0 ) continue;
     291           0 :     AliBorderRecord &b = fBorderClusters[fBorderFirstCluster[iBorder]+fBorderNClusters[iBorder]];
     292           0 :     b.fClusterRecordID = pos;
     293           0 :     b.fTimeBin = (int)fClusters[pos].GetCluster().GetTime();
     294           0 :     fBorderNClusters[iBorder]++;
     295           0 :   }
     296             :   /*
     297             :   cout<<"Border clusters: "<<endl;
     298             :   for( int iSlice=0; iSlice<fkNSlices; iSlice++){
     299             :     for( int ib = 0; ib<fNBorders; ib++ ){
     300             :       int ind = iSlice*fNBorders+ib;
     301             :       cout<<iSlice<<" "<<ib<<" :"<<fBorderFirstCluster[ind]<<", "<<fBorderNClusters[ind]<<endl;    
     302             :     }
     303             :   }
     304             :   */
     305             :   /*
     306             :   for( int ib=1; ib<fkNSlices*fNBorders; ib++ ){
     307             :     if( fBorderFirstCluster[ib] != fBorderFirstCluster[ib-1]+fBorderNClusters[ib-1] ){
     308             :       cout<<"Something wrong with cluster borders !!! "<<endl;
     309             :     }
     310             :   }
     311             :   */
     312           0 :   return 0;
     313             : }
     314             : 
     315             : void AliHLTTPCHWClusterMerger::Clear()
     316             : {
     317             :   /// cleanup
     318           0 :   fClusters.clear();
     319           0 :   fRemovedClusterIds.clear();
     320             :   
     321           0 :   delete[] fBorderClusters;
     322           0 :   fBorderClusters = 0;
     323           0 :   for( int i=0; i<fkNSlices*fNBorders; i++){
     324           0 :     fBorderNClusters[i] = 0;  
     325           0 :     fBorderFirstCluster[i] = 0; 
     326             :   }
     327           0 :   fBorderNClustersTotal = 0;
     328           0 : }
     329             : 
     330             : 
     331             : int AliHLTTPCHWClusterMerger::Merge()
     332             : {
     333             :   /// merge clusters
     334             :   /// first all candidates are filled into the index grid, looping over all clusters
     335             :   /// in the grid automatically results in time ordered clusters per row (ordering with
     336             :   /// respect to cells, within a cell two clusters can be reversed)
     337             :   
     338           0 :   if( !fMapping ) Init();
     339           0 :   if( !fMapping ) return 0;
     340             :   //static int sLeft = 0, sRight = 0, sMerged = 0;
     341             :   int iResult=0;
     342             :   int count=0;
     343           0 :   if ((iResult=FillIndex())<0) {
     344           0 :     return iResult;
     345             :   }
     346             :   // sort 
     347           0 :   for( int i=0; i<fkNSlices*fNBorders; i++){
     348           0 :     std::sort(fBorderClusters+fBorderFirstCluster[i],fBorderClusters+fBorderFirstCluster[i]+fBorderNClusters[i], CompareTime);
     349             :   }
     350             : 
     351           0 :   for( int iBorder=0; iBorder<fkNSlices*fNBorders; iBorder+=2){
     352           0 :     AliBorderRecord *border1 = fBorderClusters+fBorderFirstCluster[iBorder];
     353           0 :     AliBorderRecord *border2 = fBorderClusters+fBorderFirstCluster[iBorder+1];
     354           0 :     int n1 = fBorderNClusters[iBorder];
     355           0 :     int n2 = fBorderNClusters[iBorder+1];
     356             :     /*
     357             : sLeft+=n1;
     358             :     sRight+=n2;
     359             :     bool prn = (n1>0) && (n2>0);
     360             :     if( prn ){
     361             :       cout<<"Border "<<iBorder/2<<", left: "<<n1<<" clusters :"<<endl;
     362             :       for( int ib=0; ib<n1; ib++ ){
     363             :         cout<<ib<<": "<<border1[ib].fTimeBin<<endl;
     364             :       }
     365             :       cout<<"Border "<<iBorder/2<<", right: "<<n2<<" clusters :"<<endl;
     366             :       for( int ib=0; ib<n2; ib++ ){
     367             :         cout<<ib<<": "<<border2[ib].fTimeBin<<endl;
     368             :       }
     369             :     }
     370             :     */
     371             :     int ib1 = 0;
     372           0 :     for( int ib2 = 0; (ib1<n1) && (ib2<n2); ib2++ ){
     373             :       // search first cluster at border1 to merge
     374             :       
     375           0 :       while( ib1<n1 && border1[ib1].fTimeBin>border2[ib2].fTimeBin+fkMergeTimeWindow ){
     376           0 :         ib1++;
     377             :       }
     378             :       
     379           0 :       if( ib1>= n1 ) break;
     380           0 :       if( border1[ib1].fTimeBin < border2[ib2].fTimeBin-fkMergeTimeWindow) continue;
     381             : 
     382             :       // merge c2->c1 
     383             :       //if( prn ) cout<<"merge "<<ib2<<"->"<<ib1<<endl;
     384           0 :       AliClusterRecord &c1 = fClusters[border1[ib1].fClusterRecordID];
     385           0 :       AliClusterRecord &c2 = fClusters[border2[ib2].fClusterRecordID];
     386             :       
     387           0 :       float w1 = c1.Cluster().fCharge;
     388           0 :       float w2 = c2.Cluster().fCharge;
     389           0 :       if( w1<=0 ) w1 = 1;
     390           0 :       if( w2<=0 ) w2 = 1;
     391           0 :       float w = 1./(w1+w2);
     392           0 :       w1*=w;
     393           0 :       w2*=w;
     394             :       
     395           0 :       c1.Cluster().fCharge += c2.Cluster().fCharge;
     396           0 :       if( c1.Cluster().fQMax < c2.Cluster().fQMax ) c1.Cluster().fQMax = c2.Cluster().fQMax;
     397             :       
     398           0 :       c1.Cluster().fSigmaPad2 = 
     399           0 :         w1*c1.Cluster().fSigmaPad2 + w2*c2.Cluster().fSigmaPad2
     400           0 :         + (c1.Cluster().fPad - c2.Cluster().fPad)*(c1.Cluster().fPad - c2.Cluster().fPad)*w1*w2;
     401             :       
     402           0 :       c1.Cluster().fSigmaTime2 = 
     403           0 :         w1*c1.Cluster().fSigmaTime2 + w2*c2.Cluster().fSigmaTime2
     404           0 :         + (c1.Cluster().fTime - c2.Cluster().fTime)*(c1.Cluster().fTime - c2.Cluster().fTime)*w1*w2;
     405             :       
     406           0 :       c1.Cluster().fPad  = w1*c1.Cluster().fPad + w2*c2.Cluster().fPad;
     407           0 :       c1.Cluster().fTime = w1*c1.Cluster().fTime + w2*c2.Cluster().fTime;
     408             :       
     409           0 :       c1.Cluster().fFlags |= c2.Cluster().fFlags;
     410             :       
     411             :       // merge MC labels
     412             :       
     413           0 :       AliHLTTPCClusterMCWeight labels[6] = {
     414           0 :         c1.GetMCLabel().fClusterID[0],
     415           0 :         c1.GetMCLabel().fClusterID[1],
     416           0 :         c1.GetMCLabel().fClusterID[2],
     417           0 :         c2.GetMCLabel().fClusterID[0],
     418           0 :         c2.GetMCLabel().fClusterID[1],
     419           0 :         c2.GetMCLabel().fClusterID[2]
     420             :       };
     421             : 
     422           0 :       sort(labels, labels+6, CompareMCLabels);
     423           0 :       for( unsigned int i=1; i<6; i++ ){
     424           0 :         if(labels[i-1].fMCID==labels[i].fMCID ){
     425           0 :           labels[i].fWeight+=labels[i-1].fWeight;
     426           0 :           labels[i-1].fWeight = 0;
     427           0 :         }
     428             :       }
     429             : 
     430           0 :       sort(labels, labels+6, CompareMCWeights );
     431             :     
     432           0 :       for( unsigned int i=0; i<3; i++ ){
     433           0 :         c1.MCLabel().fClusterID[i] = labels[i];
     434             :       }
     435             : 
     436             :       // wipe c2
     437           0 :       fRemovedClusterIds.push_back(c2.GetId());
     438             :       HLTDebug("merging %d into %d", border2[ib2].fClusterRecordID, border1[ib1].fClusterRecordID);
     439             :       //cout<<"Set merged flag at position "<<border2[ib2].fClusterRecordID<<endl;
     440           0 :       c2.SetMergedTo(border1[ib1].fClusterRecordID);      
     441           0 :       count++;
     442             :       // do not merge c1 anymore
     443           0 :       ib1++;    
     444           0 :     }    
     445             :   } // iBorder
     446             :   
     447             :   //cout<<"Merged "<<count<<" clusters "<<" out of "<<fClusters.size()<<endl;
     448             :   //sMerged+= count;
     449             :   // cout<<"L "<<sLeft<<" r "<<sRight<<" m "<<sMerged<<endl;
     450           0 :   if (iResult<0) return iResult;
     451           0 :   return count;
     452           0 : }
     453             : 

Generated by: LCOV version 1.11