LCOV - code coverage report
Current view: top level - HLT/TPCLib/HWCFemulator - AliHLTTPCHWClusterMergerV1.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 229 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 9 0.0 %

          Line data    Source code
       1             : // $Id: AliHLTTPCHWClusterMergerV1.cxx 53494 2011-12-09 06:24:43Z sgorbuno $
       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   AliHLTTPCHWClusterMergerV1.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             : 
      27             : #include "AliHLTTPCHWClusterMergerV1.h"
      28             : #include "AliHLTTPCHWCFSupport.h"
      29             : #include "AliHLTTPCDefinitions.h"
      30             : #include "AliHLTTPCGeometry.h"
      31             : #include "AliHLTTPCRawCluster.h"
      32             : #include <algorithm>
      33             : 
      34             : /** ROOT macro for the implementation of ROOT specific class methods */
      35             : 
      36             : AliHLTTPCHWClusterMergerV1::AliHLTTPCHWClusterMergerV1()
      37           0 :   : AliHLTLogging()
      38           0 :   , fNRows(0)
      39           0 :   , fNRowPads(0)
      40           0 :   , fNBorders(0)
      41           0 :   , fMapping(0)
      42           0 :   , fBorders()
      43           0 :   , fpData(NULL)
      44           0 :   , fRawClusterBlocks(NULL)
      45           0 :   , fMCBlocks(NULL)
      46           0 : {
      47             :   // see header file for class documentation
      48             :   // or
      49             :   // refer to README to build package
      50             :   // or
      51             :   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
      52             :   // constructor
      53             :   
      54             :   const int kNPatchesTotal = fkNSlices*fkNPatches;
      55             : 
      56           0 :   fRawClusterBlocks = new AliHLTComponentBlockData* [kNPatchesTotal];
      57           0 :   fMCBlocks = new AliHLTComponentBlockData* [kNPatchesTotal];
      58           0 :   for( int i=0; i<kNPatchesTotal; i++){
      59           0 :     fRawClusterBlocks[i] = NULL;
      60           0 :     fMCBlocks[i] = NULL;
      61             :   }
      62           0 : }
      63             : 
      64             : AliHLTTPCHWClusterMergerV1::~AliHLTTPCHWClusterMergerV1()
      65           0 : {
      66             :   // destructor
      67           0 :   delete[] fMapping;
      68           0 :   delete[] fRawClusterBlocks;
      69           0 :   delete[] fMCBlocks;
      70           0 : }
      71             : 
      72             : Int_t AliHLTTPCHWClusterMergerV1::Init( Bool_t processingRCU2Data )
      73             : {
      74             :   // initialisation
      75             :   
      76             :   Int_t iResult=0;
      77             : 
      78           0 :   delete[] fMapping;
      79           0 :   fMapping = 0;
      80           0 :   fNRows = AliHLTTPCGeometry::GetNRows();
      81           0 :   fNRowPads = 0;  
      82           0 :   fNBorders = 0;
      83           0 :   for( int i=0; i<fNRows; i++ ){
      84           0 :     int nPads = AliHLTTPCGeometry::GetNPads(i); 
      85           0 :     if( fNRowPads<nPads ) fNRowPads = nPads;
      86             :   }
      87           0 :   int nPadsTotal = fNRows*fNRowPads;
      88           0 :   fMapping = new AliHLTInt16_t [nPadsTotal];
      89             : 
      90           0 :   if( !fMapping ){
      91           0 :     HLTError("Can not allocate memory: %d bytes", nPadsTotal*sizeof(AliHLTInt16_t));
      92           0 :     return -ENOMEM;
      93             :   }
      94           0 :   for( int i=0; i<nPadsTotal; i++ ){
      95           0 :     fMapping[i] = -1;
      96             :   }
      97             : 
      98           0 :   AliHLTTPCHWCFSupport support; 
      99           0 :   support.SetProcessingRCU2Data( processingRCU2Data );
     100             : 
     101           0 :   for( int iPart=0; iPart<6; iPart++ ){
     102           0 :     const AliHLTUInt32_t *m = support.GetMapping(0,iPart);
     103           0 :     if( !m ){
     104           0 :       HLTError("Can not get mapping for partition %d", iPart);
     105             :       iResult = -1;
     106           0 :       continue;
     107             :     }
     108           0 :     int nHWAddress=m[0];
     109           0 :     for( int iHW=0; iHW<nHWAddress; iHW++ ){
     110           0 :       AliHLTUInt32_t configWord = m[iHW+1];
     111           0 :       int row = (configWord>>8) & 0x3F;
     112           0 :       int pad =  configWord & 0xFF;
     113           0 :       bool border = (configWord>>14) & 0x1;
     114           0 :       if( !border ) continue;
     115           0 :       row+=AliHLTTPCGeometry::GetFirstRow(iPart);
     116           0 :       if( row>=fNRows ) continue;
     117           0 :       if( pad>=AliHLTTPCGeometry::GetNPads(row) ) continue;
     118           0 :       fMapping[row*fNRowPads + pad] = -2-iPart;
     119           0 :     }
     120           0 :   }
     121             : 
     122           0 :   fBorders.clear();
     123           0 :   for( int row=0; row<fNRows; row++ ){
     124           0 :     for( int pad=0; pad<fNRowPads-1; pad++ ){
     125           0 :       AliHLTInt16_t *m = fMapping + row*fNRowPads;
     126           0 :       if( m[pad]<-1 && m[pad+1]<-1 ){             
     127           0 :         fBorders.push_back( AliBorderParam( pad+1., -m[pad]-2) ); // pad, patch
     128           0 :         fBorders.push_back( AliBorderParam( pad+1., -m[pad+1]-2) ); // pad, patch
     129             : 
     130           0 :         m[pad] = fNBorders;     
     131           0 :         for( int i=1; i<fkMergeWidth; i++ ){   
     132           0 :           if( pad-i<0 || m[pad-i]!=-1 ) break;
     133           0 :           m[pad-i] = fNBorders;
     134             :         }
     135           0 :         m[pad+1] = fNBorders+1;
     136           0 :         for( int i=1; i<fkMergeWidth; i++ ){   
     137           0 :           if( pad+1+i>=fNRowPads || m[pad+1+i]!=-1 ) break;
     138           0 :           m[pad+1+i] = fNBorders+1;     
     139             :         }       
     140           0 :         fNBorders+=2;
     141           0 :       }
     142             :     }
     143             :   } 
     144             : 
     145           0 :   Clear();
     146             : 
     147             :   return iResult;
     148           0 : }
     149             : 
     150             : 
     151             : 
     152             : Int_t AliHLTTPCHWClusterMergerV1::SetDataBlock(  AliHLTComponentBlockData *block)
     153             : {
     154             :   //
     155             :   // set block of clusters or MC labels
     156             :   //
     157             : 
     158           0 :   if( !block ){    
     159           0 :     HLTError("Input NULL pointer to data block");
     160           0 :     return -1;
     161             :   }
     162             :   
     163             :   Int_t blockType=0;
     164             :   
     165           0 :   if( block->fDataType == (AliHLTTPCDefinitions::fgkRawClustersDataType | kAliHLTDataOriginTPC) ) blockType=1;
     166           0 :   else if( block->fDataType == (AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC) ) blockType=2;
     167             :   
     168           0 :   if( blockType==0 ){
     169           0 :     HLTError("Unexpected type of input block:  %d", block->fDataType);
     170           0 :     return -1;
     171             :   }
     172             :   
     173           0 :   UInt_t minSlice     = AliHLTTPCDefinitions::GetMinSliceNr(*block); 
     174           0 :   UInt_t minPartition = AliHLTTPCDefinitions::GetMinPatchNr(*block);
     175           0 :   UInt_t maxSlice     = AliHLTTPCDefinitions::GetMaxSliceNr(*block); 
     176           0 :   UInt_t maxPartition = AliHLTTPCDefinitions::GetMaxPatchNr(*block);
     177           0 :   if( maxSlice!=minSlice || maxPartition!=minPartition ){
     178           0 :     HLTError("Unexpected input block (slices %d-%d, patches %d-%d): only one TPC partition per block is expected", minSlice, maxSlice, minPartition, maxPartition );
     179           0 :     return -1;
     180             :   }
     181             : 
     182           0 :   if( minSlice>=(UInt_t)fkNSlices || minPartition >=(UInt_t)fkNPatches ){
     183           0 :     HLTError("Wrong Slice/Patch number of input block: slice %d, patch %d", minSlice, minPartition );
     184           0 :     return -1;
     185             :   }
     186             : 
     187           0 :   Int_t iSlicePatch = minSlice*fkNPatches + minPartition;
     188             :   
     189           0 :   if( blockType == 1 ) fRawClusterBlocks[iSlicePatch] = block;
     190           0 :   else if( blockType == 2 )  fMCBlocks[iSlicePatch] = block;
     191             : 
     192             :   return 0;
     193           0 : }
     194             : 
     195             : 
     196             : void AliHLTTPCHWClusterMergerV1::Clear()
     197             : {
     198             :   /// cleanup
     199             :   
     200             :   //  fClusters.~vector<AliClusterRecord>();
     201             :   // new(&fClusters) vector<AliClusterRecord>;
     202             : 
     203           0 :   fpData = NULL;
     204           0 :   for( int i=0; i<fkNSlices*fkNPatches; i++){
     205           0 :     fRawClusterBlocks[i] = NULL;
     206           0 :     fMCBlocks[i] = NULL;
     207             :   }
     208           0 : }
     209             : 
     210             : 
     211             : int AliHLTTPCHWClusterMergerV1::Merge()
     212             : {
     213             :   /// merge clusters
     214             :    
     215           0 :   if( !fMapping ){
     216           0 :     HLTError("Mapping is not initialised");
     217           0 :     return 0;
     218             :   }
     219             : 
     220           0 :   if( !fpData ){    
     221           0 :     HLTError("Pointer to input data is not set");
     222           0 :     return -1;
     223             :   }
     224             : 
     225             :   
     226             :   int iResult = 0;
     227             :   int count = 0;
     228             : 
     229           0 :   vector<AliBorderRecord> *fBorderClusters = new vector<AliBorderRecord> [fNBorders];
     230             : 
     231           0 :   for( int iSlice=0; iSlice<fkNSlices; iSlice++){
     232             :     
     233           0 :     for( int iBorder=0; iBorder<fNBorders; iBorder++) fBorderClusters[iBorder].clear();
     234             :     
     235           0 :     for( int iPatch=0; iPatch<fkNPatches; iPatch++){
     236           0 :       int iSlicePatch =  iSlice*fkNPatches+iPatch;
     237           0 :       AliHLTComponentBlockData *block = fRawClusterBlocks[iSlicePatch];
     238           0 :       if( !block ) continue;
     239           0 :       AliHLTTPCRawClusterData* clusters= (AliHLTTPCRawClusterData*)( fpData + block->fOffset);
     240           0 :       if(!clusters) continue;
     241             :   
     242           0 :       AliHLTComponentBlockData *mcblock = fMCBlocks[iSlicePatch];
     243             :       AliHLTTPCClusterMCData* mclabels = 0;
     244           0 :       if( mcblock ) mclabels = (AliHLTTPCClusterMCData*)(fpData + mcblock->fOffset );
     245           0 :       if( mclabels && mclabels->fCount != clusters->fCount ){
     246           0 :         HLTError("Slice %d, patch %d: Number of MC labels (%d) not equal to N clusters (%d)", iSlice, iPatch,  mclabels->fCount, clusters->fCount );
     247           0 :         mclabels->fCount = 0;
     248           0 :         mcblock->fSize = sizeof(AliHLTTPCClusterMCData);
     249             :         mclabels = 0;
     250           0 :         fMCBlocks[iSlicePatch] = 0;
     251           0 :       }
     252             :       
     253           0 :       for( UInt_t iCluster=0; iCluster<clusters->fCount; iCluster++){
     254           0 :         AliHLTTPCRawCluster &cluster = clusters->fClusters[iCluster];
     255             : 
     256             :         // check if the cluster is at the branch border    
     257           0 :         Int_t patchRow = cluster.GetPadRow();   
     258           0 :         int sliceRow=patchRow+AliHLTTPCGeometry::GetFirstRow(iPatch);
     259           0 :         float pad = cluster.GetPad();
     260           0 :         int iPad = (int) pad;
     261             : 
     262             :         int iBorder = -1;
     263             : 
     264           0 :         if( sliceRow>=0 && sliceRow <fNRows && iPad>=0 && iPad < fNRowPads ){
     265           0 :           iBorder = fMapping[sliceRow*fNRowPads+iPad];    
     266           0 :           if( iBorder>=0 ){
     267           0 :             float dPad = pad - fBorders[iBorder].fPadPosition;
     268           0 :             if( cluster.GetSigmaPad2()>1.e-4 ){
     269           0 :               if( dPad*dPad > 12.*cluster.GetSigmaPad2() ) iBorder = -1;
     270             :             } else {
     271           0 :               if( fabs(dPad)>1. ) iBorder = -1;
     272             :             }    
     273           0 :           }
     274             :         }
     275           0 :         if( iBorder>=0 ){
     276             :           AliHLTTPCClusterMCLabel *mc=0;
     277           0 :           if( mclabels ) mc = &( mclabels->fLabels[iCluster] );
     278           0 :           fBorderClusters[iBorder].push_back( AliBorderRecord( &cluster, mc, (int)cluster.GetTime()) );
     279           0 :         }
     280             :       }
     281           0 :     } // patches
     282             :   
     283             :     
     284           0 :     for( int iBorder=0; iBorder<fNBorders; iBorder+=2){      
     285           0 :       vector<AliBorderRecord> &border1 = fBorderClusters[iBorder];
     286           0 :       vector<AliBorderRecord> &border2 = fBorderClusters[iBorder+1];
     287           0 :       UInt_t n1 = border1.size();
     288           0 :       UInt_t n2 = border2.size();      
     289           0 :       if( n1==0 || n2==0 ) continue;
     290             : 
     291             :       // sort 
     292             :       
     293           0 :       std::sort(border1.begin(),border1.end(), CompareTime);
     294           0 :       std::sort(border2.begin(),border2.end(), CompareTime);
     295             :       
     296             :       // merge
     297             : 
     298             :       UInt_t ib1 = 0;
     299           0 :       for( UInt_t ib2 = 0; (ib1<n1) && (ib2<n2); ib2++ ){
     300             :         
     301             :         // search first cluster at border1 to merge
     302             :         
     303           0 :         while( ib1<n1 && border1[ib1].fTimeBin>border2[ib2].fTimeBin+fkMergeTimeWindow ){
     304           0 :           ib1++;
     305             :         }
     306             :         
     307           0 :         if( ib1>= n1 ) break;
     308           0 :         if( border1[ib1].fTimeBin < border2[ib2].fTimeBin-fkMergeTimeWindow) continue;
     309             :       
     310             :         // merge c2->c1 
     311             :         
     312           0 :         AliHLTTPCRawCluster *c1 = border1[ib1].fCluster;
     313           0 :         AliHLTTPCRawCluster *c2 = border2[ib2].fCluster;
     314           0 :         AliHLTTPCClusterMCLabel *mc1 = border1[ib1].fMC;
     315           0 :         AliHLTTPCClusterMCLabel *mc2 = border2[ib2].fMC;
     316             : 
     317             : 
     318           0 :         if( c1->GetPad()<-1 || c2->GetPad()<-1 ) continue;
     319             : 
     320           0 :         float w1 = c1->GetCharge();
     321           0 :         float w2 = c2->GetCharge();
     322           0 :         if( w1<=0 ) w1 = 1;
     323           0 :         if( w2<=0 ) w2 = 1;
     324           0 :         float w = 1./(w1+w2);
     325           0 :         w1*=w;
     326           0 :         w2*=w;
     327             :         
     328           0 :         c1->SetCharge( c1->GetCharge() + c2->GetCharge() );
     329           0 :         if( c1->GetQMax() < c2->GetQMax() ) c1->SetQMax( c2->GetQMax() );
     330             :         
     331           0 :         c1->SetSigmaPad2(  w1*c1->GetSigmaPad2() + w2*c2->GetSigmaPad2()
     332           0 :                          + (c1->GetPad() - c2->GetPad())*(c1->GetPad() - c2->GetPad())*w1*w2 );
     333             :         
     334           0 :         c1->SetSigmaTime2( w1*c1->GetSigmaTime2() + w2*c2->GetSigmaTime2()
     335           0 :                         + (c1->GetTime() - c2->GetTime())*(c1->GetTime() - c2->GetTime())*w1*w2 );
     336             :       
     337           0 :         c1->SetPad( w1*c1->GetPad() + w2*c2->GetPad() );
     338           0 :         c1->SetTime( w1*c1->GetTime() + w2*c2->GetTime() );
     339             :       
     340             :         // merge MC labels
     341           0 :         if( mc1 && mc2 ){
     342             : 
     343           0 :           AliHLTTPCClusterMCWeight labels[6] = {
     344           0 :             mc1->fClusterID[0],
     345           0 :             mc1->fClusterID[1],
     346           0 :             mc1->fClusterID[2],
     347           0 :             mc2->fClusterID[0],
     348           0 :             mc2->fClusterID[1],
     349           0 :             mc2->fClusterID[2]
     350             :           };
     351             : 
     352           0 :           sort(labels, labels+6, CompareMCLabels);
     353           0 :           for( unsigned int i=1; i<6; i++ ){
     354           0 :             if(labels[i-1].fMCID==labels[i].fMCID ){
     355           0 :               labels[i].fWeight+=labels[i-1].fWeight;
     356           0 :               labels[i-1].fWeight = 0;
     357           0 :             }
     358             :           }
     359             :         
     360           0 :           sort(labels, labels+6, CompareMCWeights );
     361             :           
     362           0 :           for( unsigned int i=0; i<3; i++ ){
     363           0 :             mc1->fClusterID[i] = labels[i];
     364             :           }
     365             : 
     366           0 :         } // MC labels
     367             : 
     368             :         // wipe c2
     369           0 :         c2->SetPad(-10);
     370             : 
     371           0 :         count++;
     372             :         // do not merge to c1 anymore
     373           0 :         ib1++;
     374           0 :       }    
     375           0 :     } // iBorder
     376             :     
     377             : 
     378             :     // remove merged clusters from data
     379             : 
     380           0 :     for( int iPatch=0; iPatch<fkNPatches; iPatch++){
     381           0 :       int iSlicePatch =  iSlice*fkNPatches+iPatch;
     382           0 :       AliHLTComponentBlockData *block = fRawClusterBlocks[iSlicePatch];
     383           0 :       if( !block ) continue;
     384           0 :       AliHLTTPCRawClusterData* clusters= (AliHLTTPCRawClusterData*)(fpData + block->fOffset);
     385           0 :       if(!clusters) continue;
     386           0 :       AliHLTUInt32_t nClustersOrig = clusters->fCount;
     387             :       
     388           0 :       AliHLTComponentBlockData *mcblock = fMCBlocks[iSlicePatch];
     389             :       AliHLTTPCClusterMCData* mclabels = 0;
     390           0 :       if( mcblock ) mclabels = (AliHLTTPCClusterMCData*)(fpData + mcblock->fOffset);
     391           0 :       if( mclabels && mclabels->fCount != nClustersOrig ) mclabels = 0;      
     392             : 
     393           0 :       clusters->fCount=0;
     394           0 :       for( UInt_t  iCluster=0; iCluster<nClustersOrig; iCluster++){
     395           0 :         AliHLTTPCRawCluster &cluster = clusters->fClusters[iCluster];
     396           0 :         if( cluster.GetPad()<-1 ) continue; // the cluster has been merged
     397           0 :         if( clusters->fCount != iCluster ){
     398           0 :           clusters->fClusters[clusters->fCount] = cluster;
     399           0 :           if( mclabels ) mclabels->fLabels[clusters->fCount] = mclabels->fLabels[iCluster];
     400             :         }
     401           0 :         clusters->fCount++;
     402           0 :       }
     403             :       
     404           0 :       block->fSize = sizeof(AliHLTTPCRawClusterData) + clusters->fCount*sizeof(AliHLTTPCRawCluster);
     405           0 :       if( mclabels ){
     406           0 :         mclabels->fCount = clusters->fCount;
     407           0 :         mcblock->fSize = sizeof(AliHLTTPCClusterMCData) + mclabels->fCount*sizeof(AliHLTTPCClusterMCLabel);       
     408           0 :       }
     409           0 :     }
     410             : 
     411             :   } // iSlice
     412             : 
     413           0 :   delete[] fBorderClusters;
     414             : 
     415           0 :   if (iResult<0) return iResult;
     416           0 :   return count;
     417           0 : }
     418             : 

Generated by: LCOV version 1.11