LCOV - code coverage report
Current view: top level - HLT/TPCLib - AliHLTTPCClusterFinder.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 791 0.1 %
Date: 2016-06-14 17:26:59 Functions: 1 24 4.2 %

          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: Anders Vestbo, Constantin Loizides                    *
       8             : //* Developers:      Kenneth Aamodt <kenneth.aamodt@student.uib.no>        *
       9             : //*                  Kalliopi Kanaki                                       *
      10             : //*                  for The ALICE HLT Project.                            *
      11             : //*                                                                        *
      12             : //* Permission to use, copy, modify and distribute this software and its   *
      13             : //* documentation strictly for non-commercial purposes is hereby granted   *
      14             : //* without fee, provided that the above copyright notice appears in all   *
      15             : //* copies and that both the copyright notice and this permission notice   *
      16             : //* appear in the supporting documentation. The authors make no claims     *
      17             : //* about the suitability of this software for any purpose. It is          *
      18             : //* provided "as is" without express or implied warranty.                  *
      19             : //**************************************************************************
      20             : 
      21             : //  @file   AliHLTTPCClusterFinder.cxx
      22             : //  @author Kenneth Aamodt, Kalliopi Kanaki
      23             : //  @date   
      24             : //  @brief  Cluster Finder for the TPC
      25             : //  @note 
      26             : 
      27             : #include "AliHLTTPCDigitReader.h"
      28             : #include "AliHLTTPCLogging.h"
      29             : #include "AliHLTTPCClusterFinder.h"
      30             : #include "AliHLTTPCSpacePointData.h"
      31             : #include "AliHLTTPCPad.h"
      32             : #include <sys/time.h>
      33             : #include <algorithm>
      34             : #include <cmath>
      35             : #include "AliTPCcalibDB.h"
      36             : #include "AliTPCTransform.h"
      37             : #include "AliTPCParam.h"
      38             : 
      39             : #if __GNUC__ >= 3
      40             : using namespace std;
      41             : #endif
      42             : 
      43           6 : ClassImp(AliHLTTPCClusterFinder)
      44             : 
      45           0 : AliHLTTPCClusterFinder::AliHLTTPCClusterFinder()
      46             :   :
      47           0 :   fClustersHWAddressVector(),
      48           0 :   fRowPadVector(),
      49           0 :   fSpacePointData(NULL),
      50           0 :   fDigitReader(NULL),
      51           0 :   fPtr(NULL),
      52           0 :   fSize(0),
      53           0 :   fDeconvTime(kFALSE),
      54           0 :   fDeconvPad(kFALSE),
      55           0 :   fStdout(kFALSE),
      56           0 :   fCalcerr(kTRUE),
      57           0 :   fFillRawClusters(kFALSE),
      58           0 :   fFirstRow(0),
      59           0 :   fLastRow(0),
      60           0 :   fCurrentRow(0),
      61           0 :   fCurrentSlice(0),
      62           0 :   fCurrentPatch(0),
      63           0 :   fMatch(1),
      64           0 :   fThreshold(10),
      65           0 :   fNClusters(0),
      66           0 :   fMaxNClusters(0),
      67           0 :   fXYErr(0.2),
      68           0 :   fZErr(0.3),
      69           0 :   fOccupancyLimit(1.0),
      70           0 :   fUnsorted(0),
      71           0 :   fVectorInitialized(kFALSE),
      72           0 :   fClusters(),
      73           0 :   fClustersMCInfo(),
      74           0 :   fMCDigits(),
      75           0 :   fRawClusters(),
      76           0 :   fNumberOfPadsInRow(NULL),
      77           0 :   fNumberOfRows(0),
      78           0 :   fRowOfFirstCandidate(0),
      79           0 :   fDoPadSelection(kFALSE),
      80           0 :   fFirstTimeBin(0),
      81           0 :   fLastTimeBin(AliHLTTPCGeometry::GetNTimeBins()),
      82           0 :   fTotalChargeOfPreviousClusterCandidate(0),
      83           0 :   fChargeOfCandidatesFalling(kFALSE),
      84           0 :   f32BitFormat(kFALSE),
      85           0 :   fDoMC(kFALSE),
      86           0 :   fClusterMCVector(),
      87           0 :   fOfflineTransform(NULL),
      88           0 :   fOfflineTPCParam( NULL ),
      89           0 :   fOfflineTPCRecoParam(*AliTPCRecoParam::GetHLTParam()),
      90           0 :   fTimeMeanDiff(2),
      91           0 :   fReleaseMemory(0)
      92           0 : {
      93             :   //constructor  
      94             : 
      95             :   //uptate the transform class
      96             : 
      97           0 :   fOfflineTransform = AliTPCcalibDB::Instance()->GetTransform(); 
      98           0 :   if(!fOfflineTransform){
      99           0 :     HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB::  Offline transform not in AliTPCcalibDB.");
     100             :   }
     101             :   else{
     102           0 :     fOfflineTransform->SetCurrentRecoParam(&fOfflineTPCRecoParam);
     103             :   }
     104             : 
     105           0 :   fOfflineTPCParam = AliTPCcalibDB::Instance()->GetParameters();
     106           0 :   if( !fOfflineTPCParam ){
     107           0 :     HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB::  Offline TPC parameters not in AliTPCcalibDB.");
     108             :   } else {
     109           0 :     fOfflineTPCParam->Update();
     110           0 :     fOfflineTPCParam->ReadGeoMatrices();
     111             :   }    
     112             : 
     113           0 : }
     114             : 
     115           0 : AliHLTTPCClusterFinder::~AliHLTTPCClusterFinder(){
     116             :   // see header file for class documentation
     117             :   
     118             :   //destructor
     119           0 :   if(fVectorInitialized){
     120           0 :     DeInitializePadArray();
     121             :   }
     122           0 :   if(fNumberOfPadsInRow){
     123           0 :     delete [] fNumberOfPadsInRow;
     124           0 :     fNumberOfPadsInRow=NULL;
     125           0 :   }
     126           0 : }
     127             : 
     128             : void AliHLTTPCClusterFinder::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints){
     129             :   // see header file for class documentation
     130             : 
     131             :   //init slice
     132           0 :   fNClusters = 0;
     133           0 :   fMaxNClusters = nmaxpoints;
     134           0 :   fCurrentSlice = slice;
     135           0 :   fCurrentPatch = patch;
     136           0 :   fFirstRow=AliHLTTPCGeometry::GetFirstRow(patch);
     137           0 :   fLastRow=AliHLTTPCGeometry::GetLastRow(patch);
     138             : 
     139           0 :   fClusters.clear();
     140           0 :   fClustersMCInfo.clear();
     141           0 :   fMCDigits.clear();
     142           0 :   fClusterMCVector.clear();   
     143           0 :   fRawClusters.clear();
     144           0 : }
     145             : 
     146             : void AliHLTTPCClusterFinder::InitializePadArray(){
     147             :   // see header file for class documentation
     148             :   
     149           0 :   if(fCurrentPatch>5||fCurrentPatch<0){
     150           0 :     HLTFatal("Patch is not set");
     151             :     return;
     152             :   }
     153             : 
     154             :   HLTDebug("Patch number=%d",fCurrentPatch);
     155             : 
     156           0 :   fFirstRow = AliHLTTPCGeometry::GetFirstRow(fCurrentPatch);
     157           0 :   fLastRow = AliHLTTPCGeometry::GetLastRow(fCurrentPatch);
     158             : 
     159           0 :   fNumberOfRows=fLastRow-fFirstRow+1;
     160           0 :   fNumberOfPadsInRow= new UInt_t[fNumberOfRows];
     161             : 
     162           0 :   memset( fNumberOfPadsInRow, 0, sizeof(Int_t)*(fNumberOfRows));
     163             : 
     164           0 :   fRowPadVector.clear();
     165             : 
     166           0 :   for(UInt_t i=0;i<fNumberOfRows;i++){
     167           0 :     fNumberOfPadsInRow[i]=AliHLTTPCGeometry::GetNPads(i+fFirstRow);
     168           0 :     AliHLTTPCPadVector tmpRow;
     169           0 :     for(UInt_t j=0;j<=fNumberOfPadsInRow[i];j++){
     170           0 :       AliHLTTPCPad *tmpPad = new AliHLTTPCPad(2);
     171           0 :       tmpPad->SetID(i,j);
     172           0 :       tmpRow.push_back(tmpPad);
     173           0 :     }
     174           0 :     fRowPadVector.push_back(tmpRow);
     175           0 :   }
     176           0 :   fVectorInitialized=kTRUE;
     177           0 : }
     178             : 
     179             : Int_t AliHLTTPCClusterFinder::DeInitializePadArray(){
     180             :   // see header file for class documentation
     181             : 
     182           0 :   if( fVectorInitialized ){
     183           0 :     for(UInt_t i=0;i<fNumberOfRows;i++){
     184           0 :       for(UInt_t j=0;j<=fNumberOfPadsInRow[i];j++){
     185           0 :         delete fRowPadVector[i][j];
     186           0 :         fRowPadVector[i][j]=NULL;
     187             :       }
     188           0 :       fRowPadVector[i].clear();
     189             :     }
     190           0 :     fRowPadVector.clear();
     191           0 :     delete[] fNumberOfPadsInRow;
     192           0 :     fNumberOfPadsInRow = 0;
     193           0 :   }
     194           0 :   fVectorInitialized=kFALSE;
     195           0 :   return 1;
     196             : }
     197             : 
     198             : 
     199             : void AliHLTTPCClusterFinder::SetOutputArray(AliHLTTPCSpacePointData *pt){
     200             :   // see header file for class documentation
     201             :   //set pointer to output
     202           0 :   fSpacePointData = pt;
     203           0 : }
     204             : 
     205             : 
     206             : void AliHLTTPCClusterFinder::ReadDataUnsorted(void* ptr,unsigned long size){
     207             :   // see header file for class documentation
     208             :   //set input pointer
     209           0 :   fPtr = (UChar_t*)ptr;
     210           0 :   fSize = size;
     211             : 
     212           0 :   if(!fVectorInitialized){
     213           0 :     InitializePadArray();
     214           0 :   }
     215             : 
     216           0 :   if (fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice)<0) {
     217           0 :     HLTError("failed setting up digit reader (InitBlock)");
     218             :     return;
     219             :   }
     220             :   
     221           0 :   while(fDigitReader->NextChannel()){
     222           0 :     UInt_t row=fDigitReader->GetRow();
     223           0 :     UInt_t pad=fDigitReader->GetPad();
     224             : 
     225           0 :     if(row>=fRowPadVector.size()){
     226           0 :       HLTError("Row number is to large: %d, max is %d",row,fRowPadVector.size()-1);
     227           0 :       continue;
     228             :     }
     229           0 :     if(pad>=fRowPadVector[row].size()){
     230           0 :       HLTError("Pad number is to large: %d, max is %d",pad,fRowPadVector[row].size());
     231           0 :       continue;
     232             :     }
     233             : 
     234           0 :     while(fDigitReader->NextBunch()){
     235           0 :       if(fDigitReader->GetBunchSize()>1){//to remove single timebin values, this will have to change at some point
     236           0 :         UInt_t time = fDigitReader->GetTime();
     237           0 :         if((Int_t)time>=fFirstTimeBin && (Int_t)time+fDigitReader->GetBunchSize()<=fLastTimeBin){
     238             :           // Kenneth: 20-04-09. The following if have been added because of inconsistency in the 40 bit decoder and the 32 bit decoder.
     239             :           // GetSignals() in the 40 bit decoder returns an array of UInt_t while the 32 bit one returns UShort_t
     240             :           // The same is true for the function ReadDataUnsortedDeconvoluteTime() below.
     241             :           // In addition the signals are organized in the opposite direction
     242           0 :           if(f32BitFormat){
     243           0 :             const UShort_t *bunchData= fDigitReader->GetSignalsShort();
     244           0 :             AliHLTTPCClusters candidate;
     245           0 :             for(Int_t i=fDigitReader->GetBunchSize()-1;i>=0;i--){
     246           0 :               candidate.fTotalCharge+=bunchData[i];     
     247           0 :               candidate.fTime += time*bunchData[i];
     248           0 :               candidate.fTime2 += time*time*bunchData[i];
     249           0 :               if(bunchData[i]>candidate.fQMax){
     250           0 :                 candidate.fQMax=bunchData[i];
     251           0 :               }
     252           0 :               time++;
     253             :             }
     254           0 :             if(candidate.fTotalCharge>0){
     255           0 :               candidate.fMean=candidate.fTime/candidate.fTotalCharge;
     256           0 :               candidate.fPad=candidate.fTotalCharge*pad;
     257           0 :               candidate.fPad2=candidate.fPad*pad;
     258           0 :               candidate.fLastMergedPad=pad;
     259           0 :               candidate.fRowNumber=row+fDigitReader->GetRowOffset();
     260           0 :             }
     261           0 :             if(fRowPadVector[row][pad] != NULL){
     262           0 :               fRowPadVector[row][pad]->AddClusterCandidate(candidate);
     263             :             }
     264           0 :           }
     265             :           else{
     266           0 :             const UInt_t *bunchData= fDigitReader->GetSignals();
     267           0 :             AliHLTTPCClusters candidate;
     268             :             const AliHLTTPCDigitData* digits = NULL;
     269           0 :             if(fDoMC && (digits = fDigitReader->GetBunchDigits())!=NULL){
     270           0 :               for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
     271           0 :                 candidate.fTotalCharge+=bunchData[i];   
     272           0 :                 candidate.fTime += time*bunchData[i];
     273           0 :                 candidate.fTime2 += time*time*bunchData[i];
     274           0 :                 if(bunchData[i]>candidate.fQMax){
     275           0 :                   candidate.fQMax=bunchData[i];
     276           0 :                 }
     277           0 :                 fMCDigits.push_back(digits[i]);
     278           0 :                 time++;
     279             :               }
     280           0 :             }
     281             :             else{
     282           0 :               for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
     283           0 :                 candidate.fTotalCharge+=bunchData[i];   
     284           0 :                 candidate.fTime += time*bunchData[i];
     285           0 :                 candidate.fTime2 += time*time*bunchData[i];
     286           0 :                 if(bunchData[i]>candidate.fQMax){
     287           0 :                   candidate.fQMax=bunchData[i];
     288           0 :                 }
     289           0 :                 time++;
     290             :               }
     291             :             }
     292           0 :             if(candidate.fTotalCharge>0){
     293           0 :               candidate.fMean=candidate.fTime/candidate.fTotalCharge;
     294           0 :               candidate.fPad=candidate.fTotalCharge*pad;
     295           0 :               candidate.fPad2=candidate.fPad*pad;
     296           0 :               candidate.fLastMergedPad=pad;
     297           0 :               candidate.fRowNumber=row+fDigitReader->GetRowOffset();
     298           0 :             }
     299           0 :             if(fRowPadVector[row][pad] != NULL){
     300           0 :               fRowPadVector[row][pad]->AddClusterCandidate(candidate);
     301           0 :               if(fDoMC){
     302           0 :                 fRowPadVector[row][pad]->AddCandidateDigits(fMCDigits);
     303           0 :                 fMCDigits.clear();
     304           0 :               }
     305             :             }
     306           0 :           }
     307             :         }
     308           0 :       }
     309             :     }
     310           0 :   }
     311           0 : }
     312             : 
     313             : void AliHLTTPCClusterFinder::ReadDataUnsortedDeconvoluteTime(void* ptr,unsigned long size){
     314             :   // see header file for class documentation
     315             : 
     316             :   //set input pointer
     317           0 :   fPtr = (UChar_t*)ptr;
     318           0 :   fSize = size;
     319             : 
     320           0 :   if(!fVectorInitialized){
     321           0 :     InitializePadArray();
     322           0 :   }
     323             : 
     324           0 :   if (fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice)<0) {
     325           0 :     HLTError("failed setting up digit reader (InitBlock)");
     326             :     return;
     327             :   }
     328             :   
     329           0 :   while(fDigitReader->NextChannel()){
     330           0 :     UInt_t row=fDigitReader->GetRow();
     331           0 :     UInt_t pad=fDigitReader->GetPad();
     332             : 
     333           0 :     while(fDigitReader->NextBunch()){
     334           0 :       if(fDigitReader->GetBunchSize()>1){//to remove single timebin values, this will have to change at some point
     335           0 :         UInt_t time = fDigitReader->GetTime();
     336           0 :         if((Int_t)time>=fFirstTimeBin && (Int_t)time+fDigitReader->GetBunchSize()<=fLastTimeBin){
     337             :           Int_t indexInBunchData=0;
     338             :           Bool_t moreDataInBunch=kFALSE;
     339             :           UInt_t prevSignal=0;
     340             :           Bool_t signalFalling=kFALSE;
     341             : 
     342             :           // Kenneth: 20-04-09. The following if have been added because of inconsistency in the 40 bit decoder and the 32 bit decoder.
     343             :           // GetSignals() in the 40 bit decoder returns an array of UInt_t while the 32 bit one returns UShort_t
     344             :           // The same is true for the function ReadDataUnsorted() above.
     345             :           // In addition the signals are organized in the opposite direction
     346           0 :           if(f32BitFormat){
     347           0 :             indexInBunchData = fDigitReader->GetBunchSize()-1;
     348           0 :             const UShort_t *bunchData= fDigitReader->GetSignalsShort();
     349             : 
     350           0 :             do{
     351           0 :               AliHLTTPCClusters candidate;
     352             :               //for(Int_t i=indexInBunchData;i<fDigitReader->GetBunchSize();i++){
     353           0 :               for(Int_t i=indexInBunchData;i>=0;i--){
     354             : 
     355             :                 // Checks if one need to deconvolute the signals
     356           0 :                 if(bunchData[i]>prevSignal && signalFalling==kTRUE){
     357           0 :                   if(i<fDigitReader->GetBunchSize()-1){ // means there are more than one signal left in the bunch
     358             :                     moreDataInBunch=kTRUE;
     359             :                     prevSignal=0;
     360           0 :                   }
     361           0 :                   break;
     362             :                 }
     363             :                 
     364             :                 // Checks if the signal is 0, then quit processing the data.
     365           0 :                 if(bunchData[i]==0 && i<fDigitReader->GetBunchSize()-1){//means we have 0 data fom the rcu, might happen depending on the configuration settings
     366             :                   moreDataInBunch=kTRUE;
     367             :                   prevSignal=0;
     368           0 :                   break;
     369             :                 }
     370             :                 
     371           0 :                 if(prevSignal>bunchData[i]){//means the peak of the signal has been reached and deconvolution will happen if the signal rise again.
     372             :                   signalFalling=kTRUE;
     373           0 :                 }
     374           0 :                 candidate.fTotalCharge+=bunchData[i];   
     375           0 :                 candidate.fTime += time*bunchData[i];
     376           0 :                 candidate.fTime2 += time*time*bunchData[i];
     377           0 :                 if(bunchData[i]>candidate.fQMax){
     378           0 :                   candidate.fQMax=bunchData[i];
     379           0 :                 }
     380           0 :                 prevSignal=bunchData[i];
     381           0 :                 time++;
     382           0 :                 indexInBunchData--;
     383             :               }
     384           0 :               if(candidate.fTotalCharge>0){
     385           0 :                 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
     386           0 :                 candidate.fPad=candidate.fTotalCharge*pad;
     387           0 :                 candidate.fPad2=candidate.fPad*pad;
     388           0 :                 candidate.fLastMergedPad=pad;
     389           0 :                 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
     390           0 :               }
     391           0 :               fRowPadVector[row][pad]->AddClusterCandidate(candidate);             
     392           0 :               if(indexInBunchData<fDigitReader->GetBunchSize()-1){
     393             :                 moreDataInBunch=kFALSE;
     394           0 :               }
     395           0 :             }while(moreDataInBunch);
     396           0 :           }
     397             :           else{
     398           0 :             const UInt_t *bunchData= fDigitReader->GetSignals();
     399           0 :             do{
     400           0 :               AliHLTTPCClusters candidate;
     401           0 :               const AliHLTTPCDigitData* digits = fDigitReader->GetBunchDigits();
     402           0 :               if(fDoMC) fMCDigits.clear();            
     403             : 
     404           0 :               for(Int_t i=indexInBunchData;i<fDigitReader->GetBunchSize();i++){
     405             :                 // Checks if one need to deconvolute the signals
     406           0 :                 if(bunchData[i]>prevSignal && signalFalling==kTRUE){
     407           0 :                   if(i<fDigitReader->GetBunchSize()-1){ // means there are more than one signal left in the bunch
     408             :                     moreDataInBunch=kTRUE;
     409             :                     prevSignal=0;
     410           0 :                   }
     411           0 :                   break;
     412             :                 }
     413             :                 
     414             :                 // Checks if the signal is 0, then quit processing the data.
     415           0 :                 if(bunchData[i]==0 && i<fDigitReader->GetBunchSize()-1){//means we have 0 data fom the rcu, might happen depending on the configuration settings
     416             :                   moreDataInBunch=kTRUE;
     417             :                   prevSignal=0;
     418           0 :                   break;
     419             :                 }
     420             :                 
     421           0 :                 if(prevSignal>bunchData[i]){//means the peak of the signal has been reached and deconvolution will happen if the signal rise again.
     422             :                   signalFalling=kTRUE;
     423           0 :                 }
     424           0 :                 candidate.fTotalCharge+=bunchData[i];   
     425           0 :                 candidate.fTime += time*bunchData[i];
     426           0 :                 candidate.fTime2 += time*time*bunchData[i];
     427           0 :                 if(bunchData[i]>candidate.fQMax){
     428           0 :                   candidate.fQMax=bunchData[i];
     429           0 :                 }
     430           0 :                 if( fDoMC ) fMCDigits.push_back(digits[i]);
     431             :                 
     432           0 :                 prevSignal=bunchData[i];
     433           0 :                 time++;
     434           0 :                 indexInBunchData++;
     435             :               }
     436           0 :               if(candidate.fTotalCharge>0){
     437           0 :                 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
     438           0 :                 candidate.fPad=candidate.fTotalCharge*pad;
     439           0 :                 candidate.fPad2=candidate.fPad*pad;
     440           0 :                 candidate.fLastMergedPad=pad;
     441           0 :                 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
     442           0 :               }
     443           0 :               fRowPadVector[row][pad]->AddClusterCandidate(candidate);
     444           0 :               if(fDoMC){
     445           0 :                 fRowPadVector[row][pad]->AddCandidateDigits(fMCDigits);
     446           0 :                 fMCDigits.clear();
     447           0 :               }
     448           0 :               if(indexInBunchData<fDigitReader->GetBunchSize()-1){
     449             :                 moreDataInBunch=kFALSE;
     450           0 :               }
     451           0 :             }while(moreDataInBunch);
     452             :           }
     453           0 :         }
     454           0 :       }
     455             :     }
     456             :   }
     457           0 : }
     458             : 
     459             : Bool_t AliHLTTPCClusterFinder::ComparePads(AliHLTTPCPad *nextPad,AliHLTTPCClusters* cluster,Int_t nextPadToRead){
     460             :   // see header file for class documentation
     461             : 
     462             :   //Checking if we have a match on the next pad
     463           0 :   for(UInt_t candidateNumber=0;candidateNumber<nextPad->fClusterCandidates.size();candidateNumber++){
     464           0 :     if(nextPad->fUsedClusterCandidates[candidateNumber] == 1){
     465             :       continue;
     466             :     }
     467           0 :     AliHLTTPCClusters *candidate =&nextPad->fClusterCandidates[candidateNumber]; 
     468             :     //    if(cluster->fMean-candidate->fMean==1 || candidate->fMean-cluster->fMean==1 || cluster->fMean-candidate->fMean==0){
     469             :     
     470           0 :     if( abs((Int_t)(cluster->fMean - candidate->fMean)) <= fTimeMeanDiff ){
     471           0 :       if(fDeconvPad){
     472           0 :         if(candidate->fTotalCharge<fTotalChargeOfPreviousClusterCandidate){//peak is reached
     473           0 :           fChargeOfCandidatesFalling=kTRUE;
     474           0 :         }
     475           0 :         if(candidate->fTotalCharge>fTotalChargeOfPreviousClusterCandidate && fChargeOfCandidatesFalling==kTRUE){//we have deconvolution
     476           0 :           return kFALSE;
     477             :         }
     478             :       }
     479           0 :       cluster->fMean=candidate->fMean;
     480           0 :       cluster->fTotalCharge+=candidate->fTotalCharge;
     481           0 :       cluster->fTime += candidate->fTime;
     482           0 :       cluster->fTime2 += candidate->fTime2;
     483           0 :       cluster->fPad+=candidate->fPad;
     484           0 :       cluster->fPad2+=candidate->fPad2;
     485           0 :       cluster->fLastMergedPad=candidate->fPad;
     486           0 :       if(candidate->fQMax>cluster->fQMax){
     487           0 :         cluster->fQMax=candidate->fQMax;
     488           0 :       }
     489           0 :       if(fDoMC){
     490           0 :         FillMCClusterVector(nextPad->GetCandidateDigits(candidateNumber));
     491           0 :       }
     492             : 
     493           0 :       if(fDoPadSelection){
     494           0 :         UInt_t rowNo = nextPad->GetRowNumber();
     495           0 :         UInt_t padNo = nextPad->GetPadNumber();
     496           0 :         if(padNo-1>0){
     497           0 :           fRowPadVector[rowNo][padNo-2]->fSelectedPad=kTRUE;
     498           0 :           fRowPadVector[rowNo][padNo-2]->fHWAddress=(AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(rowNo,padNo-2);
     499           0 :         }
     500           0 :         fRowPadVector[rowNo][padNo-1]->fSelectedPad=kTRUE;// quick solution to set the first pad to selected
     501           0 :         fRowPadVector[rowNo][padNo-1]->fHWAddress=(AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(rowNo,padNo-1);
     502           0 :         fRowPadVector[rowNo][padNo]->fSelectedPad=kTRUE;
     503           0 :         fRowPadVector[rowNo][padNo]->fHWAddress=(AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(rowNo,padNo);
     504           0 :       }
     505             : 
     506             :       //setting the matched pad to used
     507           0 :       nextPad->fUsedClusterCandidates[candidateNumber]=1;
     508           0 :       nextPadToRead++;
     509           0 :       if(nextPadToRead<(Int_t)fNumberOfPadsInRow[fRowOfFirstCandidate]){
     510           0 :         nextPad=fRowPadVector[fRowOfFirstCandidate][nextPadToRead];
     511           0 :         ComparePads(nextPad,cluster,nextPadToRead);
     512             :       }
     513             :       else{
     514           0 :         return kFALSE;
     515             :       }
     516           0 :     }
     517           0 :   }
     518           0 :   return kFALSE;
     519           0 : }
     520             : 
     521             : Int_t AliHLTTPCClusterFinder::FillHWAddressList(AliHLTUInt16_t *hwaddlist, Int_t maxHWadd){
     522             :   // see header file for class documentation
     523             : 
     524             :   Int_t counter=0;
     525           0 :   for(UInt_t row=0;row<fNumberOfRows;row++){
     526           0 :     for(UInt_t pad=0;pad<fNumberOfPadsInRow[row]-1;pad++){
     527           0 :       if(fRowPadVector[row][pad]->fSelectedPad){
     528           0 :        if(counter<maxHWadd){
     529           0 :          hwaddlist[counter]=(AliHLTUInt16_t)fRowPadVector[row][pad]->fHWAddress;
     530           0 :          counter++;
     531           0 :        }
     532             :        else{
     533           0 :          HLTWarning("To many hardwareaddresses, skip adding");
     534             :        }
     535             :        
     536             :       }
     537             :     }
     538             :   }  
     539           0 :   return counter;
     540             : }
     541             :  
     542             : 
     543             : Int_t AliHLTTPCClusterFinder::FillOutputMCInfo(AliHLTTPCClusterMCLabel * outputMCInfo, Int_t maxNumberOfClusterMCInfo){
     544             :   // see header file for class documentation
     545             :   
     546             :   Int_t counter=0;
     547             :  
     548           0 :   for(UInt_t mc=0;mc<fClustersMCInfo.size();mc++){
     549           0 :     if(counter<maxNumberOfClusterMCInfo){
     550           0 :       outputMCInfo[counter] = fClustersMCInfo[mc];
     551           0 :       counter++;
     552           0 :     }
     553             :     else{
     554           0 :       HLTWarning("To much MCInfo has been added (no more space), skip adding");
     555             :     }
     556             :   }
     557           0 :   return counter;
     558             : }
     559             : 
     560             : Int_t AliHLTTPCClusterFinder::FillOutputRaw(AliHLTTPCRawCluster* rawClusters, unsigned sizeInByte) const
     561             : {
     562             :   // fill the raw clusters
     563           0 :   if (fRawClusters.size()*sizeof(AliHLTTPCRawCluster)>sizeInByte) {
     564           0 :     HLTError("not enough space to write raw clusters");
     565           0 :     return 0;
     566             :   }
     567           0 :   memcpy(rawClusters, &fRawClusters[0], fRawClusters.size()*sizeof(AliHLTTPCRawCluster));
     568           0 :   return fRawClusters.size();
     569           0 : }
     570             : 
     571             : void AliHLTTPCClusterFinder::FindClusters(){
     572             :   // see header file for function documentation
     573             : 
     574             :   AliHLTTPCClusters* tmpCandidate=NULL;
     575           0 :   for(UInt_t row=0;row<fNumberOfRows;row++){
     576           0 :     fRowOfFirstCandidate=row;
     577           0 :     for(UInt_t pad=0;pad<fNumberOfPadsInRow[row];pad++){
     578           0 :       AliHLTTPCPad *tmpPad=fRowPadVector[row][pad];
     579           0 :       for(size_t candidate=0;candidate<tmpPad->fClusterCandidates.size();candidate++){
     580           0 :         if(tmpPad->fUsedClusterCandidates[candidate]){
     581             :           continue;
     582             :         }
     583           0 :         tmpCandidate=&tmpPad->fClusterCandidates[candidate];
     584           0 :         UInt_t tmpTotalCharge=tmpCandidate->fTotalCharge;
     585             : 
     586           0 :         if(fDoMC){
     587           0 :           fClusterMCVector.clear();
     588           0 :           FillMCClusterVector(tmpPad->GetCandidateDigits(candidate));
     589           0 :         }
     590             : 
     591           0 :         ComparePads(fRowPadVector[row][pad+1],tmpCandidate,pad+1);
     592           0 :         if(tmpCandidate->fTotalCharge>tmpTotalCharge){
     593             :           //we have a cluster
     594           0 :           fClusters.push_back(*tmpCandidate);
     595           0 :           if(fDoMC){
     596             :             //sort the vector (large->small) according to weight and remove elements above 2 (keep 0 1 and 2) 
     597           0 :             sort(fClusterMCVector.begin(),fClusterMCVector.end(), CompareWeights );
     598           0 :             AliHLTTPCClusterMCLabel tmpClusterMCInfo;
     599             : 
     600           0 :             AliHLTTPCClusterMCWeight zeroMC;
     601           0 :             zeroMC.fMCID=-1;
     602           0 :             zeroMC.fWeight=0;
     603             : 
     604           0 :             if(fClusterMCVector.size()>0){
     605           0 :               tmpClusterMCInfo.fClusterID[0]=fClusterMCVector.at(0);
     606           0 :             }
     607             :             else{
     608           0 :               tmpClusterMCInfo.fClusterID[0]=zeroMC;
     609             :             }
     610             : 
     611           0 :             if(fClusterMCVector.size()>1){
     612           0 :             tmpClusterMCInfo.fClusterID[1]=fClusterMCVector.at(1);
     613           0 :             }
     614             :             else{
     615           0 :               tmpClusterMCInfo.fClusterID[1]=zeroMC;
     616             :             }
     617             : 
     618           0 :             if(fClusterMCVector.size()>2){
     619           0 :             tmpClusterMCInfo.fClusterID[2]=fClusterMCVector.at(2);
     620           0 :             }
     621             :             else{
     622           0 :               tmpClusterMCInfo.fClusterID[2]=zeroMC;
     623             :             }
     624             : 
     625           0 :             fClustersMCInfo.push_back(tmpClusterMCInfo);
     626           0 :           }
     627             :           
     628             :         }
     629           0 :       }
     630           0 :       tmpPad->ClearCandidates();
     631             :     }
     632           0 :     fRowPadVector[row][fNumberOfPadsInRow[row]]->ClearCandidates();
     633             :   }
     634             : 
     635           0 :   HLTInfo("Found %d clusters.",fClusters.size());
     636             : 
     637             :   //TODO:  Change so it stores AliHLTTPCSpacePointData directly, instead of this copying
     638             :   
     639           0 :   AliClusterData * clusterlist = new AliClusterData[fClusters.size()]; //Clusterlist
     640           0 :   for(unsigned int i=0;i<fClusters.size();i++){
     641           0 :     clusterlist[i].fTotalCharge = fClusters[i].fTotalCharge;
     642           0 :     clusterlist[i].fPad = fClusters[i].fPad;
     643           0 :     clusterlist[i].fPad2 = fClusters[i].fPad2;
     644           0 :     clusterlist[i].fTime = fClusters[i].fTime;
     645           0 :     clusterlist[i].fTime2 = fClusters[i].fTime2;
     646           0 :     clusterlist[i].fMean = fClusters[i].fMean;
     647           0 :     clusterlist[i].fFlags = fClusters[i].fFlags;
     648           0 :     clusterlist[i].fChargeFalling = fClusters[i].fChargeFalling;
     649           0 :     clusterlist[i].fLastCharge = fClusters[i].fLastCharge;
     650           0 :     clusterlist[i].fLastMergedPad = fClusters[i].fLastMergedPad;
     651           0 :     clusterlist[i].fRow = fClusters[i].fRowNumber;
     652           0 :     clusterlist[i].fQMax = fClusters[i].fQMax;
     653             :   }
     654             : 
     655           0 :   WriteClusters(fClusters.size(),clusterlist);
     656           0 :   delete [] clusterlist;
     657           0 :   fClusters.clear();
     658           0 :   if( fReleaseMemory ) DeInitializePadArray();// call this when  the -releaseMemory flag is set
     659           0 : }
     660             : 
     661             : 
     662             : Bool_t AliHLTTPCClusterFinder::UpdateCalibDB(){
     663             :   
     664             :   //update the db
     665           0 :   AliTPCcalibDB::Instance()->Update();
     666             : 
     667             :   Bool_t ret = 1;
     668             : 
     669             :   //uptate the transform class
     670             : 
     671           0 :   fOfflineTransform = AliTPCcalibDB::Instance()->GetTransform(); 
     672           0 :   if(!fOfflineTransform){
     673           0 :     HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB::  Offline transform not in AliTPCcalibDB.");
     674             :     ret = 0;
     675           0 :   }
     676             :   else{
     677           0 :     fOfflineTransform->SetCurrentRecoParam(&fOfflineTPCRecoParam);
     678             :   }
     679             : 
     680           0 :   fOfflineTPCParam = AliTPCcalibDB::Instance()->GetParameters();
     681           0 :   if( !fOfflineTPCParam ){
     682           0 :     HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB::  Offline TPC parameters not in AliTPCcalibDB.");
     683             :     ret = 0;
     684           0 :   } else {
     685           0 :     fOfflineTPCParam->Update();
     686           0 :     fOfflineTPCParam->ReadGeoMatrices();
     687             :   }    
     688             : 
     689           0 :   return ret;
     690             : }
     691             : 
     692             : //---------------------------------- Under this line the old sorted clusterfinder functions can be found --------------------------------
     693             : 
     694             : 
     695             : void AliHLTTPCClusterFinder::PrintClusters(){
     696             :   // see header file for class documentation
     697             : 
     698           0 :   for(size_t i=0;i<fClusters.size();i++){
     699           0 :     HLTInfo("Cluster number: %d",i);
     700           0 :     HLTInfo("Row: %d \t Pad: %d",fClusters[i].fRowNumber,fClusters[i].fPad/fClusters[i].fTotalCharge);
     701           0 :     HLTInfo("Total Charge:   %d",fClusters[i].fTotalCharge);
     702           0 :     HLTInfo("fPad:           %d",fClusters[i].fPad);
     703           0 :     HLTInfo("PadError:       %d",fClusters[i].fPad2);
     704           0 :     HLTInfo("TimeMean:       %d",fClusters[i].fTime/fClusters[i].fTotalCharge);
     705           0 :     HLTInfo("TimeError:      %d",fClusters[i].fTime2);
     706           0 :     HLTInfo("EndOfCluster:");
     707             :   }
     708           0 : }
     709             : 
     710             : void AliHLTTPCClusterFinder::FillMCClusterVector(vector<AliHLTTPCDigitData> *digitData){
     711             :   // see header file for class documentation
     712           0 :   if( !digitData ) return;
     713           0 :   for(UInt_t d=0;d<digitData->size();d++){
     714           0 :     Int_t nIDsInDigit = (digitData->at(d).fTrackID[0]>=0) + (digitData->at(d).fTrackID[1]>=0) + (digitData->at(d).fTrackID[2]>=0);
     715           0 :     for(Int_t id=0; id<3; id++){
     716           0 :       if(digitData->at(d).fTrackID[id]>=0){
     717             :         Bool_t matchFound = kFALSE;
     718           0 :         AliHLTTPCClusterMCWeight mc;
     719           0 :         mc.fMCID = digitData->at(d).fTrackID[id];
     720           0 :         mc.fWeight = ((Float_t)digitData->at(d).fCharge)/nIDsInDigit;
     721           0 :         for(UInt_t i=0;i<fClusterMCVector.size();i++){
     722           0 :           if(mc.fMCID == fClusterMCVector.at(i).fMCID){
     723           0 :             fClusterMCVector.at(i).fWeight += mc.fWeight;
     724             :             matchFound = kTRUE;
     725           0 :           }
     726             :         }
     727           0 :         if(matchFound == kFALSE){
     728           0 :           fClusterMCVector.push_back(mc);
     729           0 :         }
     730           0 :       }
     731             :     }
     732             :   }
     733           0 : }
     734             : 
     735             : 
     736             : void AliHLTTPCClusterFinder::Read(void* ptr,unsigned long size){
     737             :   //set input pointer
     738           0 :   fPtr = (UChar_t*)ptr;
     739           0 :   fSize = size;
     740           0 : }
     741             : 
     742             : void AliHLTTPCClusterFinder::ProcessDigits(){
     743             :   // see header file for class documentation
     744             : 
     745             :   int iResult=0;
     746             :   bool readValue = true;
     747             :   Int_t newRow = 0;    
     748             :   Int_t rowOffset = 0;
     749             :   UShort_t time=0,newTime=0;
     750             :   UInt_t pad=0,newPad=0;
     751             :   AliHLTTPCSignal_t charge=0;
     752             : 
     753           0 :   fNClusters = 0;
     754             : 
     755             :   // initialize block for reading packed data
     756           0 :   iResult=fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice);
     757           0 :   if (iResult<0) return;
     758             : 
     759           0 :   readValue = fDigitReader->Next();
     760             : 
     761             :   // Matthias 08.11.2006 the following return would cause termination without writing the
     762             :   // ClusterData and thus would block the component. I just want to have the commented line
     763             :   // here for information
     764             :   //if (!readValue)return;
     765             : 
     766           0 :   pad = fDigitReader->GetPad();
     767           0 :   time = fDigitReader->GetTime();
     768           0 :   fCurrentRow = fDigitReader->GetRow();
     769             : 
     770           0 :   if ( fCurrentPatch >= 2 ) // Outer sector, patches 2, 3, 4, 5
     771           0 :     rowOffset = AliHLTTPCGeometry::GetFirstRow( 2 );
     772             : 
     773           0 :   fCurrentRow += rowOffset;
     774             : 
     775             :   UInt_t lastpad = 123456789;
     776             :   const UInt_t kPadArraySize=5000;
     777             :   const UInt_t kClusterListSize=10000;
     778           0 :   AliClusterData *pad1[kPadArraySize]; //2 lists for internal memory=2pads
     779           0 :   AliClusterData *pad2[kPadArraySize]; //2 lists for internal memory=2pads
     780           0 :   AliClusterData clusterlist[kClusterListSize]; //Clusterlist
     781             : 
     782             :   AliClusterData **currentPt;  //List of pointers to the current pad
     783             :   AliClusterData **previousPt; //List of pointers to the previous pad
     784           0 :   currentPt = pad2;
     785           0 :   previousPt = pad1;
     786             :   UInt_t nprevious=0,ncurrent=0,ntotal=0;
     787             : 
     788             :   /* quick implementation of baseline calculation and zero suppression
     789             :      open a pad object for each pad and delete it after processing.
     790             :      later a list of pad objects with base line history can be used
     791             :      The whole thing only works if we really get unprocessed raw data, if
     792             :      the data is already zero suppressed, there might be gaps in the time
     793             :      bins.
     794             :    */
     795             :   Int_t gatingGridOffset=50;
     796           0 :   if(fFirstTimeBin>0){
     797             :     gatingGridOffset=fFirstTimeBin;
     798           0 :   }
     799           0 :   AliHLTTPCPad baseline(gatingGridOffset, AliHLTTPCGeometry::GetNTimeBins());
     800             :   // just to make later conversion to a list of objects easier
     801             :   AliHLTTPCPad* pCurrentPad=NULL;
     802             :   /*
     803             :     if (fSignalThreshold>=0) {
     804             :     pCurrentPad=&baseline;
     805             :     baseline.SetThreshold(fSignalThreshold);
     806             :   }
     807             :   */
     808           0 :   while ( readValue!=0 && iResult>=0){   // Reads through all digits in block
     809             :     iResult=0;
     810             : 
     811           0 :     if(pad != lastpad){
     812             :       //This is a new pad
     813             :       
     814             :       //Switch the lists:
     815           0 :       if(currentPt == pad2){
     816             :         currentPt = pad1;
     817             :         previousPt = pad2;
     818           0 :       }
     819             :       else {
     820             :         currentPt = pad2;
     821             :         previousPt = pad1;
     822             :       }
     823             :       nprevious = ncurrent;
     824             :       ncurrent = 0;
     825           0 :       if(pad != lastpad+1){
     826             :         //this happens if there is a pad with no signal.
     827             :         nprevious = ncurrent = 0;
     828           0 :       }
     829             :       lastpad = pad;
     830           0 :     }
     831             : 
     832             :     Bool_t newcluster = kTRUE;
     833             :     UInt_t seqcharge=0,seqaverage=0,seqerror=0;
     834             :     AliHLTTPCSignal_t lastcharge=0;
     835             :     UInt_t bLastWasFalling=0;
     836             :     Int_t newbin=-1;
     837             : 
     838             : 
     839           0 :     if(fDeconvTime){
     840             :       redo: //This is a goto.
     841             :       
     842           0 :       if(newbin > -1){
     843             :         //bin = newbin;
     844             :         newbin = -1;
     845           0 :       }
     846             :           
     847             :       lastcharge=0;
     848             :       bLastWasFalling = 0;
     849           0 :     }
     850             : 
     851           0 :     while(iResult>=0){ //Loop over time bins of current pad
     852             :       // read all the values for one pad at once to calculate the base line
     853           0 :       if (pCurrentPad) {
     854           0 :         if (!pCurrentPad->IsStarted()) {
     855             :           //HLTDebug("reading data for pad %d, padrow %d", fDigitReader->GetPad(), fDigitReader->GetRow()+rowOffset);
     856           0 :           pCurrentPad->SetID(fDigitReader->GetRow()+rowOffset,fDigitReader->GetPad());
     857           0 :           if ((pCurrentPad->StartEvent())>=0) {
     858             :             do {
     859           0 :               if ((fDigitReader->GetRow()+rowOffset)!=pCurrentPad->GetRowNumber()) break;
     860           0 :               if (fDigitReader->GetPad()!=pCurrentPad->GetPadNumber()) break;
     861           0 :               pCurrentPad->SetRawData(fDigitReader->GetTime(), fDigitReader->GetSignal());
     862             :               //HLTDebug("set raw data to pad: bin %d charge %d", fDigitReader->GetTime(), fDigitReader->GetSignal());
     863           0 :             } while ((readValue = fDigitReader->Next())!=0);
     864             :           }
     865           0 :           pCurrentPad->CalculateBaseLine(AliHLTTPCGeometry::GetNTimeBins()/2);
     866           0 :           if (pCurrentPad->Next(kTRUE/*do zero suppression*/)==0) {
     867             :             //HLTDebug("no data available after zero suppression");
     868           0 :             pCurrentPad->StopEvent();
     869           0 :             pCurrentPad->ResetHistory();
     870             :             break;
     871             :           }
     872           0 :           time=pCurrentPad->GetCurrentPosition();
     873           0 :           if (time>pCurrentPad->GetSize()) {
     874           0 :             HLTError("invalid time bin for pad");
     875             :             break;
     876             :           }
     877             :         }
     878             :       }
     879           0 :       if (pCurrentPad) {
     880           0 :         Float_t occupancy=pCurrentPad->GetOccupancy();
     881             :         //HLTDebug("pad %d occupancy level: %f", pCurrentPad->GetPadNumber(), occupancy);
     882           0 :         if ( occupancy < fOccupancyLimit ) {
     883           0 :           charge = pCurrentPad->GetCorrectedData();
     884           0 :         } else {
     885             :           charge = 0;
     886             :           //HLTDebug("ignoring pad %d with occupancy level %f", pCurrentPad->GetPadNumber(), occupancy);
     887             :         }
     888           0 :       } else {
     889           0 :         charge = fDigitReader->GetSignal();
     890             :       }
     891             :       //HLTDebug("get next charge value: position %d charge %d", time, charge);
     892             : 
     893             : 
     894             :       // CHARGE DEBUG
     895           0 :       if (fDigitReader->GetRow() == 90){
     896             : /////     LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClusterFinder::Row","row90")  << "PAD=" <<  fDigitReader->GetPad() << "  TIME=" <<  fDigitReader->GetTime() 
     897             :           //                                       << "  SIGNAL=" <<  fDigitReader->GetSignal() << ENDLOG;
     898             : 
     899             :       }
     900             : 
     901           0 :       if(time >= AliHLTTPCGeometry::GetNTimeBins()){
     902           0 :         HLTWarning("Pad %d: Timebin (%d) out of range (%d)", pad, time, AliHLTTPCGeometry::GetNTimeBins());
     903             :         iResult=-ERANGE;
     904           0 :       }
     905             : 
     906             : 
     907             :       //Get the current ADC-value
     908           0 :       if(fDeconvTime){
     909             : 
     910             :         //Check if the last pixel in the sequence is smaller than this
     911           0 :         if(charge > lastcharge){
     912           0 :           if(bLastWasFalling){
     913             :             newbin = 1;
     914           0 :             break;
     915             :           }
     916             :         }
     917             :         else bLastWasFalling = 1; //last pixel was larger than this
     918             :         lastcharge = charge;
     919           0 :       }
     920             :           
     921             :       //Sum the total charge of this sequence
     922           0 :       seqcharge += charge;
     923           0 :       seqaverage += time*charge;
     924           0 :       seqerror += time*time*charge;
     925             :       
     926           0 :       if (pCurrentPad) {
     927             :         
     928           0 :         if((pCurrentPad->Next(kTRUE/*do zero suppression*/))==0) {
     929           0 :           pCurrentPad->StopEvent();
     930           0 :           pCurrentPad->ResetHistory();
     931           0 :           if(readValue) {
     932           0 :             newPad = fDigitReader->GetPad();
     933           0 :             newTime = fDigitReader->GetTime();
     934           0 :             newRow = fDigitReader->GetRow() + rowOffset;
     935           0 :           }
     936             :           break;
     937             :         }
     938             : 
     939           0 :         newPad=pCurrentPad->GetPadNumber();
     940           0 :         newTime=pCurrentPad->GetCurrentPosition();
     941           0 :         newRow=pCurrentPad->GetRowNumber();
     942           0 :       } else {
     943           0 :       readValue = fDigitReader->Next();
     944             :       //Check where to stop:
     945           0 :       if(!readValue) break; //No more value
     946             : 
     947           0 :       newPad = fDigitReader->GetPad();
     948           0 :       newTime = fDigitReader->GetTime();
     949           0 :       newRow = fDigitReader->GetRow() + rowOffset;
     950             :       }
     951             : 
     952           0 :       if(newPad != pad)break; //new pad
     953           0 :       if(newTime != time+1) break; //end of sequence
     954           0 :       if(iResult<0) break;
     955             : 
     956             :       // pad = newpad;    is equal
     957             :       time = newTime;
     958             : 
     959             :     }//end loop over sequence
     960             : 
     961             :     //HLTDebug("ended time bin sequence loop: seqcharge=%d readValue=%d", seqcharge, readValue);
     962             :     //HLTDebug("pad=%d newpad=%d current row=%d newrow=%d", pad, newPad, fCurrentRow, newRow);
     963           0 :     if (seqcharge<=0) {
     964             :       // with active zero suppression zero values are possible
     965           0 :       continue;
     966             :     }
     967             : 
     968             :     //Calculate mean of sequence:
     969             :     Int_t seqmean=0;
     970           0 :     if(seqcharge)
     971           0 :       seqmean = seqaverage/seqcharge;
     972             :     else{
     973           0 :       LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClusterFinder::ProcessRow","Data")
     974           0 :         <<"Error in data given to the cluster finder"<<ENDLOG;
     975             :       seqmean = 1;
     976             :       seqcharge = 1;
     977             :     }
     978             : 
     979             :     //Calculate mean in pad direction:
     980           0 :     Int_t padmean = seqcharge*pad;
     981           0 :     Int_t paderror = pad*padmean;
     982             : 
     983             :     //Compare with results on previous pad:
     984           0 :     for(UInt_t p=0; p<nprevious && p<kPadArraySize && ncurrent<kPadArraySize; p++){
     985             :       
     986             :       //dont merge sequences on the same pad twice
     987           0 :       if(previousPt[p]->fLastMergedPad==pad) continue;
     988             : 
     989           0 :       Int_t difference = seqmean - previousPt[p]->fMean;
     990           0 :       if(difference < -fMatch) break;
     991             : 
     992           0 :       if(difference <= fMatch){ //There is a match here!!
     993             :         AliClusterData *local = previousPt[p];
     994             :         
     995           0 :         if(fDeconvPad){
     996           0 :           if(seqcharge > local->fLastCharge){
     997           0 :             if(local->fChargeFalling){ //The previous pad was falling
     998           0 :               break; //create a new cluster
     999             :             }               
    1000             :           }
    1001           0 :           else local->fChargeFalling = 1;
    1002           0 :           local->fLastCharge = seqcharge;
    1003           0 :         }
    1004             :               
    1005             :         //Don't create a new cluster, because we found a match
    1006             :         newcluster = kFALSE;
    1007             :               
    1008             :         //Update cluster on current pad with the matching one:
    1009           0 :         local->fTotalCharge += seqcharge;
    1010           0 :         local->fPad += padmean;
    1011           0 :         local->fPad2 += paderror;
    1012           0 :         local->fTime += seqaverage;
    1013           0 :         local->fTime2 += seqerror;
    1014           0 :         local->fMean = seqmean;
    1015           0 :         local->fFlags++; //means we have more than one pad 
    1016           0 :         local->fLastMergedPad = pad;
    1017             : 
    1018           0 :         currentPt[ncurrent] = local;
    1019           0 :         ncurrent++;
    1020             :               
    1021           0 :         break;
    1022             :       } //Checking for match at previous pad
    1023           0 :     } //Loop over results on previous pad.
    1024             : 
    1025           0 :     if(newcluster && ncurrent<kPadArraySize){
    1026             :       //Start a new cluster. Add it to the clusterlist, and update
    1027             :       //the list of pointers to clusters in current pad.
    1028             :       //current pad will be previous pad on next pad.
    1029             : 
    1030             :       //Add to the clusterlist:
    1031           0 :       AliClusterData *tmp = &clusterlist[ntotal];
    1032           0 :       tmp->fTotalCharge = seqcharge;
    1033           0 :       tmp->fPad = padmean;
    1034           0 :       tmp->fPad2 = paderror;
    1035           0 :       tmp->fTime = seqaverage;
    1036           0 :       tmp->fTime2 = seqerror;
    1037           0 :       tmp->fMean = seqmean;
    1038           0 :       tmp->fFlags = 0;  //flags for single pad clusters
    1039           0 :       tmp->fLastMergedPad = pad;
    1040             : 
    1041           0 :       if(fDeconvPad){
    1042           0 :         tmp->fChargeFalling = 0;
    1043           0 :         tmp->fLastCharge = seqcharge;
    1044           0 :       }
    1045             : 
    1046             :       //Update list of pointers to previous pad:
    1047           0 :       currentPt[ncurrent] = &clusterlist[ntotal];
    1048           0 :       ntotal++;
    1049           0 :       ncurrent++;
    1050           0 :     }
    1051             : 
    1052           0 :     if(fDeconvTime)
    1053           0 :       if(newbin >= 0) goto redo;
    1054             :   
    1055             :     // to prevent endless loop  
    1056           0 :     if(time >= AliHLTTPCGeometry::GetNTimeBins()){
    1057           0 :       HLTWarning("Timebin (%d) out of range (%d)", time, AliHLTTPCGeometry::GetNTimeBins());
    1058           0 :       break;
    1059             :     }
    1060             : 
    1061             : 
    1062           0 :     if(!readValue) break; //No more value
    1063             :     
    1064           0 :     if (ntotal>=kClusterListSize || ncurrent>=kPadArraySize) {
    1065           0 :       HLTWarning("pad array size exceeded ntotal=%d ncurrent=%d, skip rest of the data", ntotal, ncurrent);
    1066           0 :       break;
    1067             :     }
    1068             : 
    1069           0 :     if(fCurrentRow != newRow){
    1070           0 :       WriteClusters(ntotal,clusterlist);
    1071             : 
    1072             :       lastpad = 123456789;
    1073             : 
    1074             :       currentPt = pad2;
    1075             :       previousPt = pad1;
    1076             :       nprevious=0;
    1077             :       ncurrent=0;
    1078             :       ntotal=0;
    1079             :       
    1080           0 :       fCurrentRow = newRow;
    1081           0 :     }
    1082             : 
    1083             :     pad = newPad;
    1084             :     time = newTime;
    1085             : 
    1086           0 :   } // END while(readValue)
    1087             : 
    1088           0 :   WriteClusters(ntotal,clusterlist);
    1089             : 
    1090           0 :   HLTInfo("ClusterFinder found %d clusters in slice %d patch %d", fNClusters, fCurrentSlice, fCurrentPatch);
    1091             : 
    1092           0 : } // ENDEND
    1093             : 
    1094             : void AliHLTTPCClusterFinder::WriteClusters(Int_t nclusters,AliClusterData *list){
    1095             :   // see header file for class documentation
    1096             : 
    1097             :   //write cluster to output pointer
    1098           0 :   Int_t thisrow=-1,thissector=-1;
    1099           0 :   UInt_t counter = fNClusters;
    1100             :   
    1101           0 :   if (fFillRawClusters) {
    1102           0 :     fRawClusters.resize(nclusters);
    1103           0 :   }
    1104             : 
    1105           0 :   for(int j=0; j<nclusters; j++)
    1106             :     {
    1107             : 
    1108             : 
    1109             : 
    1110           0 :       if(!list[j].fFlags){
    1111           0 :         if(fDoMC){
    1112           0 :           if(j+(Int_t)fClustersMCInfo.size()-nclusters >=0 && j+fClustersMCInfo.size()-nclusters < fClustersMCInfo.size()){
    1113           0 :             fClustersMCInfo.erase(fClustersMCInfo.begin()+j+fClustersMCInfo.size()-nclusters); // remove the mc info for this cluster since it is not taken into account 
    1114           0 :           }
    1115             :         }
    1116             :         continue; //discard single pad clusters
    1117             :       }
    1118           0 :       if(list[j].fTotalCharge < fThreshold){
    1119           0 :         if(fDoMC){
    1120           0 :           if(j+(Int_t)fClustersMCInfo.size()-nclusters >=0 && j+fClustersMCInfo.size()-nclusters < fClustersMCInfo.size()){
    1121           0 :             fClustersMCInfo.erase(fClustersMCInfo.begin()+j+fClustersMCInfo.size()-nclusters); // remove the mc info for this cluster since it is not taken into account 
    1122           0 :           }
    1123             :         }
    1124             :         continue; //noise cluster
    1125             :       }
    1126           0 :       Float_t xyz[3];      
    1127           0 :       Float_t fpad =(Float_t)list[j].fPad / list[j].fTotalCharge;
    1128           0 :       Float_t fpad2=fXYErr*fXYErr; //fixed given error
    1129           0 :       Float_t ftime =(Float_t)list[j].fTime / list[j].fTotalCharge;
    1130           0 :       Float_t ftime2=fZErr*fZErr;  //fixed given error
    1131             : 
    1132             : 
    1133             : 
    1134           0 :       if(fUnsorted){
    1135           0 :         fCurrentRow=list[j].fRow;
    1136           0 :       }
    1137             : 
    1138             :    
    1139           0 :       if(fCalcerr) { //calc the errors, otherwice take the fixed error 
    1140           0 :         Int_t patch = AliHLTTPCGeometry::GetPatch(fCurrentRow);
    1141           0 :         UInt_t q2=list[j].fTotalCharge*list[j].fTotalCharge;
    1142             :         //      Float_t sy2=list[j].fPad2 * list[j].fTotalCharge - list[j].fPad * list[j].fPad;
    1143           0 :         Float_t sy2=(Float_t)list[j].fPad2 * list[j].fTotalCharge - (Float_t)list[j].fPad * list[j].fPad;
    1144           0 :         if(q2 == 0) {
    1145           0 :           LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
    1146           0 :             <<"zero charge "<< list[j].fTotalCharge <<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
    1147           0 :           continue;
    1148             :         }
    1149           0 :         sy2/=q2;
    1150           0 :         if(sy2 < 0) {
    1151           0 :             LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
    1152           0 :               <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
    1153           0 :             continue;
    1154             :         } else {
    1155             :           {
    1156           0 :             fpad2 = (sy2 + 1./12)*AliHLTTPCGeometry::GetPadPitchWidth(patch)*AliHLTTPCGeometry::GetPadPitchWidth(patch);
    1157           0 :             if(sy2 != 0){
    1158           0 :               fpad2*=0.108; //constants are from offline studies
    1159           0 :               if(patch<2)
    1160           0 :                 fpad2*=2.07;
    1161             :             }
    1162             :           }
    1163             :         }
    1164             :         //      Float_t sz2=list[j].fTime2*list[j].fTotalCharge - list[j].fTime*list[j].fTime;
    1165           0 :         Float_t sz2=(Float_t)list[j].fTime2*list[j].fTotalCharge - (Float_t)list[j].fTime*list[j].fTime;
    1166           0 :         sz2/=q2;
    1167           0 :         if(sz2 < 0){
    1168           0 :           LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
    1169           0 :             <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
    1170           0 :           continue;
    1171             :         } else {
    1172             :           {
    1173           0 :             ftime2 = (sz2 + 1./12)*AliHLTTPCGeometry::GetZWidth()*AliHLTTPCGeometry::GetZWidth();
    1174           0 :             if(sz2 != 0) {
    1175           0 :               ftime2 *= 0.169; //constants are from offline studies
    1176           0 :               if(patch<2)
    1177           0 :                 ftime2 *= 1.77;
    1178             :             }
    1179             :           }
    1180             :         }
    1181           0 :       }
    1182           0 :       if(fStdout==kTRUE)
    1183           0 :         HLTInfo("WriteCluster: padrow %d pad %d +- %d time +- %d charge %d",fCurrentRow, fpad, fpad2, ftime, ftime2, list[j].fTotalCharge);
    1184             :       
    1185           0 :       if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
    1186           0 :         fRawClusters[counter].SetPadRow(fCurrentRow);
    1187           0 :         fRawClusters[counter].SetPad(fpad);  
    1188           0 :         fRawClusters[counter].SetTime(ftime);
    1189           0 :       }
    1190             :       {
    1191           0 :         AliHLTTPCGeometry::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
    1192             : 
    1193           0 :         if(fOfflineTransform == NULL){
    1194           0 :           AliHLTTPCGeometry::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
    1195             :           
    1196           0 :           if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
    1197           0 :                           <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
    1198           0 :           if(fNClusters >= fMaxNClusters)
    1199             :             {
    1200           0 :               LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
    1201           0 :                 <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
    1202           0 :               return;
    1203             :             }  
    1204             :         
    1205           0 :           fSpacePointData[counter].fX = xyz[0];
    1206             :           //    fSpacePointData[counter].fY = xyz[1];
    1207           0 :           if(fCurrentSlice<18){
    1208           0 :             fSpacePointData[counter].fY = xyz[1];
    1209           0 :           }
    1210             :           else{
    1211           0 :             fSpacePointData[counter].fY = -1*xyz[1];
    1212             :           }
    1213           0 :           fSpacePointData[counter].fZ = xyz[2];
    1214           0 :         }
    1215             :         else{
    1216           0 :           Double_t x[3]={static_cast<Double_t>(thisrow),fpad+.5,ftime}; 
    1217           0 :           Int_t iSector[1]={thissector};
    1218           0 :           fOfflineTransform->Transform(x,iSector,0,1);
    1219           0 :           double y[3] = {x[0], x[1], x[2] };      
    1220             :           
    1221           0 :           if( fOfflineTPCParam && thissector<fOfflineTPCParam->GetNSector() ){
    1222           0 :             TGeoHMatrix  *alignment = fOfflineTPCParam->GetClusterMatrix( thissector );
    1223           0 :             if ( alignment ) alignment->LocalToMaster( x, y);
    1224           0 :           }       
    1225             : 
    1226           0 :           fSpacePointData[counter].fX = y[0];
    1227           0 :           fSpacePointData[counter].fY = y[1];
    1228           0 :           fSpacePointData[counter].fZ = y[2];
    1229           0 :         }
    1230             : 
    1231             :       } 
    1232             :       
    1233           0 :       fSpacePointData[counter].fCharge = list[j].fTotalCharge;
    1234           0 :       fSpacePointData[counter].fPadRow = fCurrentRow;
    1235           0 :       fSpacePointData[counter].fSigmaY2 = fpad2;
    1236           0 :       fSpacePointData[counter].fSigmaZ2  = ftime2;
    1237             : 
    1238           0 :       fSpacePointData[counter].fQMax = list[j].fQMax;
    1239             : 
    1240           0 :       fSpacePointData[counter].SetUsed(kFALSE);         // only used / set in AliHLTTPCDisplay
    1241           0 :       fSpacePointData[counter].SetTrackNumber(-1);      // only used / set in AliHLTTPCDisplay
    1242             : 
    1243           0 :       Int_t patch=fCurrentPatch;
    1244           0 :       if(patch==-1) patch=0; //never store negative patch number
    1245           0 :       fSpacePointData[counter].SetID( fCurrentSlice, patch, counter );
    1246             : 
    1247           0 :       if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
    1248           0 :         fRawClusters[counter].SetSigmaPad2(fSpacePointData[counter].fSigmaY2);
    1249           0 :         fRawClusters[counter].SetSigmaTime2(fSpacePointData[counter].fSigmaZ2);
    1250           0 :         fRawClusters[counter].SetCharge(fSpacePointData[counter].fCharge);
    1251           0 :         fRawClusters[counter].SetQMax(fSpacePointData[counter].fQMax);
    1252           0 :       }
    1253             : 
    1254             : #ifdef do_mc
    1255             :       Int_t trackID[3];
    1256             :       GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
    1257             : 
    1258             :       fSpacePointData[counter].fTrackID[0] = trackID[0];
    1259             :       fSpacePointData[counter].fTrackID[1] = trackID[1];
    1260             :       fSpacePointData[counter].fTrackID[2] = trackID[2];
    1261             : 
    1262             : #endif
    1263             :       
    1264           0 :       fNClusters++;
    1265           0 :       counter++;
    1266           0 :     }
    1267           0 : }
    1268             : 
    1269             : // STILL TO FIX  ----------------------------------------------------------------------------
    1270             : 
    1271             : #ifdef do_mc
    1272             : void AliHLTTPCClusterFinder::GetTrackID(Int_t pad,Int_t time,Int_t *trackID) const {
    1273             :   // see header file for class documentation
    1274             : 
    1275             :   //get mc id
    1276             :   AliHLTTPCDigitRowData *rowPt = (AliHLTTPCDigitRowData*)fDigitRowData;
    1277             :   
    1278             :   trackID[0]=trackID[1]=trackID[2]=-2;
    1279             :   for(Int_t i=fFirstRow; i<=fLastRow; i++){
    1280             :     if(rowPt->fRow < (UInt_t)fCurrentRow){
    1281             :       AliHLTTPCMemHandler::UpdateRowPointer(rowPt);
    1282             :       continue;
    1283             :     }
    1284             :     AliHLTTPCDigitData *digPt = (AliHLTTPCDigitData*)rowPt->fDigitData;
    1285             :     for(UInt_t j=0; j<rowPt->fNDigit; j++){
    1286             :       Int_t cpad = digPt[j].fPad;
    1287             :       Int_t ctime = digPt[j].fTime;
    1288             :       if(cpad != pad) continue;
    1289             :       if(ctime != time) continue;
    1290             : 
    1291             :       trackID[0] = digPt[j].fTrackID[0];
    1292             :       trackID[1] = digPt[j].fTrackID[1];
    1293             :       trackID[2] = digPt[j].fTrackID[2];
    1294             :       
    1295             :       break;
    1296             :     }
    1297             :     break;
    1298             :   }
    1299             : }
    1300             : #endif
    1301             : 
    1302             : 
    1303             : 
    1304             : void AliHLTTPCClusterFinder::WriteClusters(Int_t nclusters,AliHLTTPCClusters *list){//This is used when using the AliHLTTPCClusters class for cluster data
    1305             :   // see header file for class documentation
    1306             : 
    1307             :   //write cluster to output pointer
    1308           0 :   Int_t thisrow,thissector;
    1309           0 :   UInt_t counter = fNClusters;
    1310             : 
    1311           0 :   if (fFillRawClusters) {
    1312           0 :     fRawClusters.resize(nclusters);
    1313           0 :   }
    1314             :   
    1315           0 :   for(int j=0; j<nclusters; j++)
    1316             :     {
    1317           0 :       if(!list[j].fFlags) continue; //discard single pad clusters
    1318           0 :       if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
    1319             : 
    1320           0 :       Float_t xyz[3];      
    1321           0 :       Float_t fpad =(Float_t)list[j].fPad / list[j].fTotalCharge;
    1322           0 :       Float_t fpad2=fXYErr*fXYErr; //fixed given error
    1323           0 :       Float_t ftime =(Float_t)list[j].fTime / list[j].fTotalCharge;
    1324           0 :       Float_t ftime2=fZErr*fZErr;  //fixed given error
    1325             : 
    1326             : 
    1327           0 :       if(fCalcerr) { //calc the errors, otherwice take the fixed error 
    1328           0 :         Int_t patch = AliHLTTPCGeometry::GetPatch(fCurrentRow);
    1329           0 :         UInt_t q2=list[j].fTotalCharge*list[j].fTotalCharge;
    1330           0 :         Float_t sy2=list[j].fPad2 * list[j].fTotalCharge - list[j].fPad * list[j].fPad;
    1331           0 :         sy2/=q2;
    1332           0 :         if(sy2 < 0) {
    1333           0 :             LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
    1334           0 :               <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
    1335           0 :             continue;
    1336             :         } else {
    1337             :           {
    1338           0 :             fpad2 = (sy2 + 1./12)*AliHLTTPCGeometry::GetPadPitchWidth(patch)*AliHLTTPCGeometry::GetPadPitchWidth(patch);
    1339           0 :             if(sy2 != 0){
    1340           0 :               fpad2*=0.108; //constants are from offline studies
    1341           0 :               if(patch<2)
    1342           0 :                 fpad2*=2.07;
    1343             :             }
    1344             :           }
    1345             :         }
    1346           0 :         Float_t sz2=list[j].fTime2*list[j].fTotalCharge - list[j].fTime*list[j].fTime;
    1347           0 :         sz2/=q2;
    1348           0 :         if(sz2 < 0){
    1349           0 :           LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
    1350           0 :             <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
    1351           0 :           continue;
    1352             :         } else {
    1353             :           {
    1354           0 :             ftime2 = (sz2 + 1./12)*AliHLTTPCGeometry::GetZWidth()*AliHLTTPCGeometry::GetZWidth();
    1355           0 :             if(sz2 != 0) {
    1356           0 :               ftime2 *= 0.169; //constants are from offline studies
    1357           0 :               if(patch<2)
    1358           0 :                 ftime2 *= 1.77;
    1359             :             }
    1360             :           }
    1361             :         }
    1362           0 :       }
    1363           0 :       if(fStdout==kTRUE)
    1364           0 :         HLTInfo("WriteCluster: padrow %d pad %d +- %d time +- %d charge %d",fCurrentRow, fpad, fpad2, ftime, ftime2, list[j].fTotalCharge);
    1365             : 
    1366           0 :       if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
    1367           0 :         fRawClusters[counter].SetPadRow(fCurrentRow);
    1368           0 :         fRawClusters[counter].SetPad(fpad);  
    1369           0 :         fRawClusters[counter].SetTime(ftime);
    1370           0 :       }
    1371             :       {
    1372           0 :         AliHLTTPCGeometry::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
    1373           0 :         AliHLTTPCGeometry::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
    1374             :         
    1375           0 :         if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
    1376           0 :           <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
    1377           0 :         if(fNClusters >= fMaxNClusters)
    1378             :           {
    1379           0 :             LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
    1380           0 :               <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
    1381           0 :             return;
    1382             :           }  
    1383             :         
    1384           0 :         fSpacePointData[counter].fX = xyz[0];
    1385             :         //      fSpacePointData[counter].fY = xyz[1];
    1386           0 :         if(fCurrentSlice<18){
    1387           0 :           fSpacePointData[counter].fY = xyz[1];
    1388           0 :         }
    1389             :         else{
    1390           0 :           fSpacePointData[counter].fY = -1*xyz[1];
    1391             :         }
    1392           0 :         fSpacePointData[counter].fZ = xyz[2];
    1393             :         
    1394             :       }
    1395             :       
    1396           0 :       fSpacePointData[counter].fCharge = list[j].fTotalCharge;
    1397           0 :       fSpacePointData[counter].fPadRow = fCurrentRow;
    1398           0 :       fSpacePointData[counter].fSigmaY2 = fpad2;
    1399           0 :       fSpacePointData[counter].fSigmaZ2  = ftime2;
    1400             : 
    1401           0 :       fSpacePointData[counter].fQMax = list[j].fQMax;
    1402             : 
    1403           0 :       fSpacePointData[counter].SetUsed(kFALSE);         // only used / set in AliHLTTPCDisplay
    1404           0 :       fSpacePointData[counter].SetTrackNumber(-1);      // only used / set in AliHLTTPCDisplay
    1405             : 
    1406           0 :       Int_t patch=fCurrentPatch;
    1407           0 :       if(patch==-1) patch=0; //never store negative patch number
    1408           0 :       fSpacePointData[counter].SetID( fCurrentSlice, patch, counter );
    1409             : 
    1410           0 :       if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
    1411           0 :         fRawClusters[counter].SetSigmaPad2(fSpacePointData[counter].fSigmaY2);
    1412           0 :         fRawClusters[counter].SetSigmaTime2(fSpacePointData[counter].fSigmaZ2);
    1413           0 :         fRawClusters[counter].SetCharge(fSpacePointData[counter].fCharge);
    1414           0 :         fRawClusters[counter].SetQMax(fSpacePointData[counter].fQMax);
    1415           0 :       }
    1416             : 
    1417             : #ifdef do_mc
    1418             :       Int_t trackID[3];
    1419             :       GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
    1420             : 
    1421             :       fSpacePointData[counter].fTrackID[0] = trackID[0];
    1422             :       fSpacePointData[counter].fTrackID[1] = trackID[1];
    1423             :       fSpacePointData[counter].fTrackID[2] = trackID[2];
    1424             : 
    1425             : #endif
    1426             :       
    1427           0 :       fNClusters++;
    1428           0 :       counter++;
    1429           0 :     }
    1430           0 : }

Generated by: LCOV version 1.11