LCOV - code coverage report
Current view: top level - HLT/TPCLib/comp - AliHLTTPCDataCompressionComponent.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 34 717 4.7 %
Date: 2016-06-14 17:26:59 Functions: 7 24 29.2 %

          Line data    Source code
       1             : // $Id$
       2             : //**************************************************************************
       3             : //* This file is property of and copyright by the                          * 
       4             : //* ALICE Experiment at CERN, All rights reserved.                         *
       5             : //*                                                                        *
       6             : //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
       7             : //*                  for The ALICE HLT Project.                            *
       8             : //*                                                                        *
       9             : //* Permission to use, copy, modify and distribute this software and its   *
      10             : //* documentation strictly for non-commercial purposes is hereby granted   *
      11             : //* without fee, provided that the above copyright notice appears in all   *
      12             : //* copies and that both the copyright notice and this permission notice   *
      13             : //* appear in the supporting documentation. The authors make no claims     *
      14             : //* about the suitability of this software for any purpose. It is          *
      15             : //* provided "as is" without express or implied warranty.                  *
      16             : //**************************************************************************
      17             : 
      18             : /// @file   AliHLTTPCDataCompressionComponent.cxx
      19             : /// @author Matthias Richter
      20             : /// @date   2011-08-08
      21             : /// @brief  TPC component for data compression
      22             : ///
      23             : 
      24             : #include "AliHLTTPCDataCompressionComponent.h"
      25             : #include "AliHLTTPCDefinitions.h"
      26             : #include "AliHLTTPCDataCompressionDescriptor.h"
      27             : #include "AliHLTTPCRawClustersDescriptor.h"
      28             : #include "AliHLTTPCTrackGeometry.h"
      29             : #include "AliHLTTPCSpacePointContainer.h"
      30             : #include "AliHLTTPCRawSpacePointContainer.h"
      31             : #include "AliHLTGlobalBarrelTrack.h"
      32             : #include "AliHLTComponentBenchmark.h"
      33             : #include "AliHLTDataDeflaterSimple.h"
      34             : #include "AliHLTDataDeflaterHuffman.h"
      35             : #include "AliHLTTPCGeometry.h"
      36             : #include "AliHLTTPCClusterMCData.h"
      37             : #include "AliHLTTPCClusterTransformation.h"
      38             : #include "AliHLTErrorGuard.h"
      39             : #include "AliCDBManager.h"
      40             : #include "AliCDBPath.h"
      41             : #include "AliCDBId.h"
      42             : #include "AliCDBMetaData.h"
      43             : #include "AliCDBEntry.h"
      44             : #include "TH1F.h"
      45             : #include "TFile.h"
      46             : #include <memory>
      47             : 
      48           6 : ClassImp(AliHLTTPCDataCompressionComponent)
      49             : 
      50             : AliHLTTPCDataCompressionComponent::AliHLTTPCDataCompressionComponent()
      51           3 :   : AliHLTProcessor()
      52           3 :   , fMode(kCompressionModeNone)
      53           3 :   , fDeflaterMode(kDeflaterModeNone)
      54           3 :   , fVerificationMode(0)
      55           3 :   , fCreateFlags(0)
      56           3 :   , fMaxDeltaPad(AliHLTTPCDefinitions::GetMaxClusterDeltaPad())
      57           3 :   , fMaxDeltaTime(AliHLTTPCDefinitions::GetMaxClusterDeltaTime())
      58           3 :   , fRawInputClusters(NULL)
      59           3 :   , fInputClusters(NULL)
      60           3 :   , fTrackGrid(NULL)
      61           3 :   , fSpacePointGrid(NULL)
      62           3 :   , fpDataDeflater(NULL)
      63           3 :   , fHistoCompFactor(NULL)
      64           3 :   , fHistoResidualPad(NULL)
      65           3 :   , fHistoResidualTime(NULL)
      66           3 :   , fHistoClustersOnTracks(NULL)
      67           3 :   , fHistoClusterRatio(NULL)
      68           3 :   , fHistoTrackClusterRatio(NULL)
      69           3 :   , fHistogramFile()
      70           3 :   , fTrainingTableOutput()
      71           3 :   , fpBenchmark(NULL)
      72           3 :   , fpWrittenAssociatedClusterIds(NULL)
      73           3 :   , fDriftTimeFactorA(1.)
      74           3 :   , fDriftTimeOffsetA(0.)
      75           3 :   , fDriftTimeFactorC(1.)
      76           3 :   , fDriftTimeOffsetC(0.)
      77           3 :   , fVerbosity(0)
      78          15 : {
      79           6 : }
      80             : 
      81             : AliHLTTPCDataCompressionComponent::~AliHLTTPCDataCompressionComponent()
      82          18 : {
      83             :   /// destructor
      84           3 :   if (fpWrittenAssociatedClusterIds) delete fpWrittenAssociatedClusterIds;
      85           9 : }
      86             : 
      87             : 
      88             : const char* AliHLTTPCDataCompressionComponent::GetComponentID()
      89             : {
      90             :   /// inherited from AliHLTComponent: id of the component
      91         426 :   return "TPCDataCompressor";
      92             : }
      93             : 
      94             : 
      95             : void AliHLTTPCDataCompressionComponent::GetInputDataTypes( AliHLTComponentDataTypeList& tgtList)
      96             : {
      97             :   /// inherited from AliHLTComponent: list of data types in the vector reference
      98           0 :   tgtList.clear();
      99           0 :   tgtList.push_back(AliHLTTPCDefinitions::RawClustersDataType());
     100           0 :   tgtList.push_back(AliHLTTPCDefinitions::RawClustersDescriptorDataType());
     101           0 :   tgtList.push_back(AliHLTTPCDefinitions::ClustersDataType());
     102           0 :   tgtList.push_back(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC);
     103           0 : }
     104             : 
     105             : AliHLTComponentDataType AliHLTTPCDataCompressionComponent::GetOutputDataType()
     106             : {
     107             :   /// inherited from AliHLTComponent: output data type of the component.
     108           0 :   return kAliHLTMultipleDataType;
     109             : }
     110             : 
     111             : int AliHLTTPCDataCompressionComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
     112             : {
     113             :   /// inherited from AliHLTComponent: multiple output data types of the component.
     114           0 :   tgtList.clear();
     115           0 :   tgtList.push_back(AliHLTTPCDefinitions::DataCompressionDescriptorDataType());
     116           0 :   tgtList.push_back(AliHLTTPCDefinitions::RawClustersDataTypeNotCompressed());
     117           0 :   tgtList.push_back(AliHLTTPCDefinitions::RemainingClustersCompressedDataType());
     118           0 :   tgtList.push_back(AliHLTTPCDefinitions::RemainingClusterIdsDataType());
     119           0 :   tgtList.push_back(AliHLTTPCDefinitions::ClusterTracksCompressedDataType());
     120           0 :   tgtList.push_back(AliHLTTPCDefinitions::ClusterIdTracksDataType());
     121           0 :   tgtList.push_back(AliHLTTPCDefinitions::ClustersFlagsDataType());
     122           0 :   return tgtList.size();
     123             : }
     124             : 
     125             : void AliHLTTPCDataCompressionComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
     126             : {
     127             :   /// inherited from AliHLTComponent: output data size estimator
     128           0 :   constBase=0;
     129             :   inputMultiplier=1.;  // there should not be more data than input
     130           0 :   inputMultiplier+=.3; // slightly more data when using the old HWCF data with 20 Byte and raw clusters 22 Byte
     131           0 :   if (fpWrittenAssociatedClusterIds) inputMultiplier+=.3; // space for optional cluster id array
     132           0 : }
     133             : 
     134             : AliHLTComponent* AliHLTTPCDataCompressionComponent::Spawn()
     135             : {
     136             :   /// inherited from AliHLTComponent: spawn function.
     137           0 :   return new AliHLTTPCDataCompressionComponent;
     138           0 : }
     139             : 
     140             : void AliHLTTPCDataCompressionComponent::GetOCDBObjectDescription(TMap* const targetMap)
     141             : {
     142             :   /// Get a list of OCDB object needed for the particular component
     143           0 :   if (!targetMap) return;
     144             : 
     145           0 :   targetMap->Add(new TObjString("HLT/ConfigTPC/TPCDataCompressor"),
     146           0 :                  new TObjString("component arguments"));
     147           0 :   if (fDeflaterMode==kDeflaterModeHuffman) {
     148           0 :     targetMap->Add(new TObjString("HLT/ConfigTPC/TPCDataCompressorHuffmanTables"),
     149           0 :                    new TObjString("huffman tables for deflater mode 'huffman'"));
     150           0 :   }
     151           0 : }
     152             : 
     153             : int AliHLTTPCDataCompressionComponent::DoEvent( const AliHLTComponentEventData& /*evtData*/, 
     154             :                                                 const AliHLTComponentBlockData* /*inputBlocks*/, 
     155             :                                                 AliHLTComponentTriggerData& /*trigData*/,
     156             :                                                 AliHLTUInt8_t* outputPtr,
     157             :                                                 AliHLTUInt32_t& size,
     158             :                                                 AliHLTComponentBlockDataList& outputBlocks )
     159             : {
     160             :   /// inherited from AliHLTProcessor: data processing
     161             :   int iResult=0;
     162           0 :   AliHLTUInt32_t capacity=size;
     163           0 :   size=0;
     164             : 
     165           0 :   if (!IsDataEvent()) return 0;
     166             : 
     167           0 :   if (!fRawInputClusters) {
     168           0 :     return -ENODEV;
     169             :   }
     170             : 
     171           0 :   if (GetBenchmarkInstance()) {
     172           0 :     GetBenchmarkInstance()->StartNewEvent();
     173           0 :     GetBenchmarkInstance()->Start(0);
     174           0 :   }
     175             : 
     176             :   // Process an event
     177             : 
     178             :   // Loop over all input blocks in the event
     179           0 :   bool bHaveMC=(GetFirstInputBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC))!=NULL;
     180           0 :   if ((bHaveMC || fVerificationMode>0) && fpWrittenAssociatedClusterIds==NULL) {
     181           0 :     fpWrittenAssociatedClusterIds=new vector<AliHLTUInt32_t>;
     182           0 :   }
     183             : 
     184             :   const AliHLTComponentBlockData* pDesc=NULL;
     185             : 
     186             :   AliHLTUInt8_t minSlice=0xFF, maxSlice=0xFF, minPatch=0xFF, maxPatch=0xFF;
     187             :   AliHLTUInt32_t inputRawClusterSize=0;
     188             :   AliHLTUInt32_t outputDataSize=0;
     189             :   int allClusters=0;
     190             :   int associatedClusters=0;
     191           0 :   float bz=GetBz();
     192             : 
     193             :   /// input track array
     194           0 :   vector<AliHLTGlobalBarrelTrack> inputTrackArray;
     195             : 
     196           0 :   if (GetBenchmarkInstance()) {
     197           0 :     GetBenchmarkInstance()->Start(2);
     198             :   }
     199             : 
     200             :   bool isInputPresent = kFALSE;
     201             : 
     202             :   // transformed clusters
     203             :   // the transformed clusters have not been used yet
     204             :   if (false) { // FIXME: condition to be adjusted
     205             :     for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkClustersDataType);
     206             :          pDesc!=NULL; pDesc=GetNextInputBlock()) {
     207             :       if (GetBenchmarkInstance()) {
     208             :         GetBenchmarkInstance()->AddInput(pDesc->fSize);
     209             :       }
     210             :       isInputPresent = kTRUE;
     211             :       AliHLTUInt8_t slice = 0;
     212             :       AliHLTUInt8_t patch = 0;
     213             :       slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
     214             :       patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
     215             :       if ( minSlice==0xFF || slice<minSlice )        minSlice = slice;
     216             :       if ( maxSlice==0xFF || slice>maxSlice )        maxSlice = slice;
     217             :       if ( minPatch==0xFF || patch<minPatch )        minPatch = patch;
     218             :       if ( maxPatch==0xFF || patch>maxPatch )        maxPatch = patch;
     219             :       if (fInputClusters) {
     220             :         fInputClusters->AddInputBlock(pDesc);
     221             :       }
     222             :     }
     223             :     if (GetBenchmarkInstance()) {
     224             :       GetBenchmarkInstance()->Stop(2);
     225             :       GetBenchmarkInstance()->Start(3);
     226             :     }
     227             :   }
     228             : 
     229           0 :   vector<int> trackindexmap; // stores index for every track id
     230             : 
     231             :   // track data input
     232           0 :   if (fMode==kCompressionModeV1TrackModel || fMode==kCompressionModeV2TrackModel) {
     233           0 :     for (pDesc=GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC);
     234           0 :          pDesc!=NULL; pDesc=GetNextInputBlock()) {
     235           0 :       if (GetBenchmarkInstance()) {
     236           0 :         GetBenchmarkInstance()->AddInput(pDesc->fSize);
     237             :       }
     238             :       AliHLTUInt8_t slice = 0;
     239             :       AliHLTUInt8_t patch = 0;
     240           0 :       slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
     241           0 :       patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
     242           0 :       if ( minSlice==0xFF || slice<minSlice )        minSlice = slice;
     243           0 :       if ( maxSlice==0xFF || slice>maxSlice )        maxSlice = slice;
     244           0 :       if ( minPatch==0xFF || patch<minPatch )        minPatch = patch;
     245           0 :       if ( maxPatch==0xFF || patch>maxPatch )        maxPatch = patch;
     246           0 :       const AliHLTTracksData* pTracks=reinterpret_cast<const AliHLTTracksData*>(pDesc->fPtr);
     247           0 :       if ((iResult=AliHLTGlobalBarrelTrack::ConvertTrackDataArray(pTracks, pDesc->fSize, inputTrackArray))<0) {
     248           0 :         return iResult;
     249             :       }
     250           0 :       trackindexmap.resize(inputTrackArray.size(), -1);
     251           0 :     }
     252             :   }
     253             : 
     254           0 :   if (GetBenchmarkInstance()) {
     255           0 :     GetBenchmarkInstance()->Stop(3);
     256           0 :     GetBenchmarkInstance()->Start(4);
     257             :   }
     258             : 
     259             :   // processing
     260             :   int trackindex=0;
     261           0 :   for (vector<AliHLTGlobalBarrelTrack>::iterator track=inputTrackArray.begin();
     262           0 :        track!=inputTrackArray.end();
     263           0 :        track++, trackindex++) {
     264           0 :     int trackID=track->GetID();
     265           0 :     if (trackID<0) {
     266             :       // FIXME: error guard
     267           0 :       HLTError("invalid track ID");
     268           0 :       continue;
     269             :     }
     270           0 :     if (trackID>=(int)trackindexmap.size())
     271           0 :       trackindexmap.resize(trackID+1, -1);
     272           0 :     trackindexmap[trackID]=trackindex;
     273             : 
     274           0 :     if (fVerbosity>0) {
     275           0 :       UInt_t nofPoints=track->GetNumberOfPoints();
     276           0 :       const UInt_t* points=track->GetPoints();
     277           0 :       for (unsigned i=0; i<nofPoints; i++) {
     278           0 :         int slice=AliHLTTPCSpacePointData::GetSlice(points[i]);
     279           0 :         int partition=AliHLTTPCSpacePointData::GetPatch(points[i]);
     280           0 :         int number=AliHLTTPCSpacePointData::GetNumber(points[i]);
     281           0 :         HLTInfo("track %d point %d id 0x%08x slice %d partition %d number %d", track->GetID(), i, points[i], slice, partition, number);
     282             :       }
     283           0 :     }
     284             : 
     285           0 :     AliHLTTPCTrackGeometry* trackpoints=new AliHLTTPCTrackGeometry;
     286           0 :     if (!trackpoints) continue;
     287             :     HLTDebug("track %d id %d:", trackindex, trackID);
     288             : 
     289             :     // in order to avoid rounding errors the track points are
     290             :     // calculated in exactly the same way as in the decoding
     291             :     // Thats why the track instance can not be used directly
     292             :     // but a new instance is created from the values in the
     293             :     // storage format.
     294             :     // think about moving that to some common code used by
     295             :     // both compression and decoding
     296           0 :     AliHLTExternalTrackParam param;
     297           0 :     memset(&param, 0, sizeof(param));    
     298           0 :     float alpha=track->GetAlpha();
     299           0 :     while (alpha<0.) alpha+=TMath::TwoPi();
     300           0 :     while (alpha>TMath::TwoPi()) alpha-=TMath::TwoPi();
     301           0 :     AliHLTUInt8_t tSlice=AliHLTUInt8_t(9*alpha/TMath::Pi());
     302           0 :     param.fAlpha   =( tSlice + 0.5 ) * TMath::Pi() / 9.0;
     303           0 :     if (param.fAlpha>TMath::TwoPi()) param.fAlpha-=TMath::TwoPi();
     304           0 :     param.fX       = track->GetX();
     305           0 :     param.fY       = track->GetY();
     306           0 :     param.fZ       = track->GetZ();
     307           0 :     param.fSinPsi  = track->GetSnp();
     308           0 :     param.fTgl     = track->GetTgl();
     309           0 :     param.fq1Pt    = track->GetSigned1Pt();
     310           0 :     AliHLTGlobalBarrelTrack ctrack(param);
     311           0 :     ctrack.CalculateHelixParams(bz);
     312           0 :     trackpoints->InitDriftTimeTransformation(fDriftTimeFactorA, fDriftTimeOffsetA, fDriftTimeFactorC, fDriftTimeOffsetC);
     313           0 :     trackpoints->SetTrackId(trackID);
     314           0 :     trackpoints->CalculateTrackPoints(ctrack);
     315           0 :     trackpoints->RegisterTrackPoints(fTrackGrid);
     316           0 :     track->SetTrackGeometry(trackpoints);
     317           0 :   }
     318             : 
     319           0 :   for (vector<AliHLTGlobalBarrelTrack>::const_iterator track=inputTrackArray.begin();
     320           0 :        track!=inputTrackArray.end();
     321           0 :        track++) {
     322           0 :     AliHLTTrackGeometry* trackpoints=track->GetTrackGeometry();
     323           0 :     if (!trackpoints) continue;
     324           0 :     trackpoints->FillTrackPoints(fTrackGrid);
     325           0 :   }
     326           0 :   if (fVerbosity>0) {
     327           0 :     fTrackGrid->Print();
     328             :   }
     329             : 
     330           0 :   if (GetBenchmarkInstance()) {
     331           0 :     GetBenchmarkInstance()->Stop(4);
     332           0 :     GetBenchmarkInstance()->Start(5);
     333             :   }
     334             : 
     335             :   // loop over raw cluster blocks, assign to tracks and write
     336             :   // unassigned clusters
     337           0 :   for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkRawClustersDataType);
     338           0 :        pDesc!=NULL; pDesc=GetNextInputBlock()) {    
     339           0 :     if (GetBenchmarkInstance()) {
     340           0 :       GetBenchmarkInstance()->Start(1);
     341           0 :       GetBenchmarkInstance()->AddInput(pDesc->fSize);
     342             :     }
     343             :     isInputPresent = kTRUE;
     344             :     AliHLTUInt8_t slice = 0;
     345             :     AliHLTUInt8_t patch = 0;
     346           0 :     slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
     347           0 :     patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
     348           0 :     if ( minSlice==0xFF || slice<minSlice )  minSlice = slice;
     349           0 :     if ( maxSlice==0xFF || slice>maxSlice )  maxSlice = slice;
     350           0 :     if ( minPatch==0xFF || patch<minPatch )  minPatch = patch;
     351           0 :     if ( maxPatch==0xFF || patch>maxPatch )  maxPatch = patch;
     352           0 :     inputRawClusterSize+=pDesc->fSize;
     353             : 
     354             :     // add the data and populate the index grid
     355           0 :     fRawInputClusters->AddInputBlock(pDesc);
     356           0 :     fRawInputClusters->PopulateAccessGrid(fSpacePointGrid, pDesc->fSpecification);
     357           0 :     if (fVerbosity>0 && fSpacePointGrid->GetNumberOfSpacePoints()>0) {
     358           0 :       HLTInfo("index grid slice %d partition %d", slice, patch);
     359           0 :       fSpacePointGrid->Print();
     360           0 :       for (AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid::iterator& cl=fSpacePointGrid->begin();
     361           0 :            cl!=fSpacePointGrid->end(); cl++) {
     362           0 :         AliHLTUInt32_t id=cl.Data().fId;
     363           0 :         float row=fRawInputClusters->GetX(id);
     364           0 :         float pad=fRawInputClusters->GetY(id);
     365           0 :         float time=fRawInputClusters->GetZ(id);
     366           0 :         HLTInfo("    cluster id 0x%08x: row %f  pad %f  time %f", id, row, pad, time);
     367             :       }
     368           0 :     }
     369           0 :     if (GetBenchmarkInstance()) {
     370           0 :       GetBenchmarkInstance()->Stop(1);
     371           0 :       GetBenchmarkInstance()->Start(4);
     372             :     }
     373             : 
     374             :     // process the clusters per padrow and check the track grid
     375             :     // for tracks crossing that particular padrow
     376           0 :     if (GetBenchmarkInstance()) {
     377           0 :       GetBenchmarkInstance()->Stop(4);
     378           0 :       GetBenchmarkInstance()->Start(5);
     379             :     }
     380           0 :     allClusters+=fSpacePointGrid->GetNumberOfSpacePoints();
     381           0 :     iResult=ProcessTrackClusters(&inputTrackArray[0], inputTrackArray.size(), fTrackGrid, trackindexmap, fSpacePointGrid, fRawInputClusters, slice, patch);
     382           0 :     if( iResult< 0 ) break;
     383             :     int assignedInThisPartition = iResult;
     384           0 :     associatedClusters+=iResult;
     385             :     
     386           0 :     iResult=ProcessRemainingClusters(&inputTrackArray[0], inputTrackArray.size(), fTrackGrid, trackindexmap, fSpacePointGrid, fRawInputClusters, slice, patch);
     387           0 :     if( iResult< 0 ) break;
     388           0 :     associatedClusters+=iResult;
     389             : 
     390           0 :     if (fSpacePointGrid->GetNumberOfSpacePoints()>0) {
     391           0 :       if (fVerbosity>0) HLTInfo("associated %d (%d) of %d clusters in slice %d partition %d", iResult+assignedInThisPartition, assignedInThisPartition, fSpacePointGrid->GetNumberOfSpacePoints(), slice, patch);
     392             :     }
     393             : 
     394             :     // write all remaining clusters not yet assigned to tracks
     395             :     // the index grid is used to write sorted in padrow
     396             :     // FIXME: decoder index instead of data specification to be used
     397             :     // use an external access grid to reduce allocated memory
     398             :     // set to NULL after writing the clusters
     399             :     const char* writeoptions="";
     400           0 :     if (fpWrittenAssociatedClusterIds) {
     401             :       writeoptions="write-cluster-ids";
     402             :     }
     403           0 :     fRawInputClusters->SetSpacePointPropertyGrid(pDesc->fSpecification, fSpacePointGrid);
     404           0 :     iResult=fRawInputClusters->Write(outputPtr+size, capacity-size, outputBlocks, fpDataDeflater, writeoptions);
     405           0 :     fRawInputClusters->SetSpacePointPropertyGrid(pDesc->fSpecification, NULL);
     406           0 :     if( iResult<0 ) break;
     407             :     
     408           0 :     size+=iResult;
     409           0 :     outputDataSize+=iResult;
     410             :     // the size of the optional cluster id array must be subtracted
     411           0 :     if (fpWrittenAssociatedClusterIds && outputBlocks.size()>0 &&
     412           0 :         outputBlocks.back().fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType()) {
     413           0 :       outputDataSize-=outputBlocks.back().fSize;
     414           0 :     }
     415           0 :     if (GetBenchmarkInstance()) GetBenchmarkInstance()->AddOutput(iResult);
     416             :     
     417           0 :     if (GetBenchmarkInstance()) {
     418           0 :       GetBenchmarkInstance()->Stop(5);
     419             :     }
     420             : 
     421           0 :     fSpacePointGrid->Clear();
     422           0 :   }
     423           0 :   if (fHistoClusterRatio && allClusters>0) {
     424           0 :     if (fVerbosity>0) HLTInfo("associated %d of %d clusters to tracks", associatedClusters, allClusters);
     425           0 :     float ratio=associatedClusters; ratio/=allClusters;
     426           0 :     fHistoClusterRatio->Fill(ratio);
     427           0 :   }
     428             : 
     429             :   // output of track model clusters
     430           0 :   if (iResult>=0) do {
     431             :     AliHLTUInt32_t tracksBufferOffset=sizeof(AliHLTTPCTrackModelBlock);
     432           0 :     if (capacity-size<tracksBufferOffset) {
     433             :       iResult=-ENOSPC;
     434           0 :       break;
     435             :     }
     436           0 :     if (fpWrittenAssociatedClusterIds) fpWrittenAssociatedClusterIds->clear();
     437           0 :     AliHLTTPCTrackModelBlock* trackModelBlock=reinterpret_cast<AliHLTTPCTrackModelBlock*>(outputPtr+size);
     438           0 :     trackModelBlock->fVersion=1;
     439           0 :     trackModelBlock->fDeflaterMode=fpDataDeflater?fpDataDeflater->GetDeflaterVersion():0;
     440           0 :     trackModelBlock->fTrackCount=inputTrackArray.size();
     441           0 :     trackModelBlock->fClusterCount=0;
     442           0 :     trackModelBlock->fGlobalParameterCnt=5;
     443             :     tracksBufferOffset+=trackModelBlock->fGlobalParameterCnt*sizeof(trackModelBlock->fGlobalParameters);
     444           0 :     if (capacity-size<tracksBufferOffset) {
     445             :       iResult=-ENOSPC;
     446           0 :       break;
     447             :     }
     448             : 
     449             :     AliHLTUInt32_t parameterIndex=0;
     450           0 :     trackModelBlock->fGlobalParameters[parameterIndex++]=bz;
     451           0 :     trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeFactorA;
     452           0 :     trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeOffsetA;
     453           0 :     trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeFactorC;
     454           0 :     trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeOffsetC;
     455           0 :     if (parameterIndex!=trackModelBlock->fGlobalParameterCnt) {
     456           0 :       HLTError("internal error, size of parameter array has changed without providing all values");
     457             :       iResult=-EFAULT;
     458           0 :       break;
     459             :     }
     460             : 
     461           0 :     if (trackindexmap.size()>0) {// condition for track model compression
     462           0 :       iResult=WriteTrackClusters(inputTrackArray, fRawInputClusters, fpDataDeflater, outputPtr+size+tracksBufferOffset, capacity-size-tracksBufferOffset);
     463           0 :       if (iResult<0) break;
     464           0 :       AliHLTComponent_BlockData bd;
     465           0 :       FillBlockData(bd);
     466           0 :       bd.fOffset        = size;
     467           0 :       bd.fSize          = tracksBufferOffset+iResult;
     468           0 :       bd.fDataType      = AliHLTTPCDefinitions::ClusterTracksCompressedDataType();
     469           0 :       bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(minSlice, maxSlice, minPatch, maxPatch);
     470           0 :       outputBlocks.push_back(bd);
     471           0 :       size += bd.fSize;
     472           0 :       outputDataSize+=bd.fSize;
     473           0 :       HLTBenchmark("track data block of %d tracks: size %d", inputTrackArray.size(), bd.fSize);
     474             : 
     475           0 :       if (fpWrittenAssociatedClusterIds && fpWrittenAssociatedClusterIds->size()>0) {
     476           0 :         AliHLTComponent::FillBlockData(bd);
     477           0 :         bd.fOffset        = size;
     478           0 :         bd.fSize        = fpWrittenAssociatedClusterIds->size()*sizeof(vector<AliHLTUInt32_t>::value_type);
     479           0 :         if (capacity-size>bd.fSize) {
     480           0 :           memcpy(outputPtr+bd.fOffset, &(*fpWrittenAssociatedClusterIds)[0], bd.fSize);
     481           0 :           bd.fDataType    = AliHLTTPCDefinitions::ClusterIdTracksDataType();
     482           0 :           bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(minSlice, maxSlice, minPatch, maxPatch);
     483           0 :           outputBlocks.push_back(bd);    
     484           0 :           size += bd.fSize;
     485           0 :         } else {
     486             :           iResult=-ENOSPC;
     487             :         }
     488             :         
     489           0 :         fpWrittenAssociatedClusterIds->clear();
     490           0 :       }    
     491           0 :     }
     492             : 
     493           0 :   } while (0);
     494             : 
     495           0 :   fRawInputClusters->Clear();
     496             : 
     497             :   // Write header block 
     498             :   
     499           0 :   if( iResult>=0 && isInputPresent ){
     500           0 :     pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::RawClustersDescriptorDataType() );
     501           0 :     if( pDesc ){
     502           0 :       const AliHLTTPCRawClustersDescriptor &clDesc = *reinterpret_cast<const AliHLTTPCRawClustersDescriptor*>(pDesc->fPtr);
     503           0 :       if( !clDesc.CheckSize( pDesc->fSize ) ){
     504           0 :         HLTError("Corrupted cluster descriptor");
     505             :       }
     506             :      
     507           0 :       AliHLTComponent_BlockData bd;
     508           0 :       FillBlockData(bd);
     509           0 :       bd.fOffset        = size;
     510           0 :       bd.fSize          = sizeof(AliHLTTPCDataCompressionDescriptor);
     511           0 :       bd.fDataType      = AliHLTTPCDefinitions::DataCompressionDescriptorDataType();
     512           0 :       if( capacity < size + bd.fSize ){
     513             :         iResult = -ENOSPC;
     514           0 :       } else {
     515           0 :         AliHLTTPCDataCompressionDescriptor compDesc;
     516           0 :         compDesc.SetMergedClustersFlag( clDesc.GetMergedClustersFlag() );
     517           0 :         *(AliHLTTPCDataCompressionDescriptor*)(outputPtr + bd.fOffset ) = compDesc; 
     518           0 :         outputBlocks.push_back(bd);
     519           0 :         size += bd.fSize;
     520           0 :         outputDataSize+=bd.fSize;
     521             :         //HLTBenchmark("header data block of size %d", bd.fSize);
     522           0 :       }
     523           0 :     }
     524             :   }
     525             : 
     526           0 :   float compressionFactor=(float)inputRawClusterSize;
     527           0 :   if ((outputDataSize)>0) compressionFactor/=outputDataSize;
     528             :   else compressionFactor=0.;
     529           0 :   if (fHistoCompFactor) fHistoCompFactor->Fill(compressionFactor);
     530             : 
     531           0 :   if (GetBenchmarkInstance() && allClusters>0) {
     532           0 :     GetBenchmarkInstance()->Stop(0);
     533           0 :     if (fDeflaterMode!=kDeflaterModeHuffmanTrainer) {
     534           0 :       HLTBenchmark("%s - compression factor %.2f", GetBenchmarkInstance()->GetStatistics(), compressionFactor);
     535             :     } else {
     536           0 :       HLTBenchmark("%s", GetBenchmarkInstance()->GetStatistics());
     537             :     }
     538             :   }
     539             : 
     540           0 :   if (fInputClusters) {
     541           0 :     fInputClusters->Clear();
     542             :   }
     543           0 :   if (fRawInputClusters) {
     544           0 :     fRawInputClusters->Clear();
     545             :   }
     546           0 :   if (fTrackGrid) {
     547           0 :     fTrackGrid->Clear();
     548           0 :   }
     549             : 
     550           0 :   if( iResult>=0 ){ // forward MC labels
     551           0 :     for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC);
     552           0 :          pDesc!=NULL; pDesc=GetNextInputBlock()) {
     553           0 :       outputBlocks.push_back(*pDesc);
     554             :     }
     555             :   }
     556             : 
     557             :   return iResult;
     558           0 : }
     559             : 
     560             : int AliHLTTPCDataCompressionComponent::ProcessTrackClusters(AliHLTGlobalBarrelTrack* pTracks, unsigned nofTracks,
     561             :                                                             AliHLTTrackGeometry::AliHLTTrackGrid* pTrackIndex,
     562             :                                                             const vector<int>& trackIndexMap,
     563             :                                                             AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex,
     564             :                                                             AliHLTSpacePointContainer* pClusters,
     565             :                                                             int slice, int partition) const
     566             : {
     567             :   // process to assigned track clusters
     568             :   int iResult=0;
     569             :   int assignedClusters=0;
     570           0 :   if (!pTracks || nofTracks==0) return 0;
     571             : 
     572           0 :   vector<int> processedTracks(nofTracks, -1);
     573           0 :   for (AliHLTTrackGeometry::AliHLTTrackGrid::iterator& trackId=pTrackIndex->begin(slice, partition, -1);
     574           0 :        trackId!=pTrackIndex->end(); trackId++) {
     575           0 :     if (trackId.Data()>=trackIndexMap.size()) {
     576           0 :       HLTError("can not find track id %d in index map of size %d", trackId.Data(), trackIndexMap.size());
     577             :       continue;
     578             :     }
     579           0 :     int trackindex=trackIndexMap[trackId.Data()];
     580           0 :     if (trackindex<0 || trackindex>=(int)nofTracks) {
     581           0 :       HLTError("invalid index %d found for track id %d", trackindex, trackId.Data());
     582           0 :       continue;
     583             :     }
     584           0 :     if (processedTracks[trackindex]>0) continue;
     585           0 :     processedTracks[trackindex]=1;
     586           0 :     AliHLTGlobalBarrelTrack& track=pTracks[trackindex];
     587           0 :     if (!track.GetTrackGeometry()) {
     588           0 :       HLTError("can not find track geometry for track %d", trackId.Data());
     589           0 :       continue;
     590             :     }
     591           0 :     AliHLTTPCTrackGeometry* pTrackPoints=dynamic_cast<AliHLTTPCTrackGeometry*>(track.GetTrackGeometry());
     592           0 :     if (!pTrackPoints) {
     593           0 :       HLTError("invalid track geometry type for track %d, expecting AliHLTTPCTrackGeometry", trackId.Data());
     594           0 :       continue; 
     595             :     }
     596             : 
     597           0 :     UInt_t nofTrackPoints=track.GetNumberOfPoints();
     598           0 :     const UInt_t* trackPoints=track.GetPoints();
     599           0 :     for (unsigned i=0; i<nofTrackPoints; i++) {
     600           0 :       const AliHLTUInt32_t& clusterId=trackPoints[i];
     601           0 :       if (AliHLTTPCSpacePointData::GetSlice(clusterId)!=(unsigned)slice ||
     602           0 :           AliHLTTPCSpacePointData::GetPatch(clusterId)!=(unsigned)partition) {
     603             :         // not in the current partition;
     604           0 :         continue;
     605             :       }
     606             : 
     607           0 :       int clusterrow=(int)pClusters->GetX(clusterId);
     608           0 :       AliHLTUInt32_t pointId=AliHLTTPCSpacePointData::GetID(slice, partition, clusterrow);
     609           0 :       AliHLTTrackGeometry::AliHLTTrackPoint* point=pTrackPoints->GetRawTrackPoint(pointId);
     610           0 :       if (!point) {
     611             :         //HLTError("can not find track point slice %d partition %d padrow %d (0x%08x) of track %d", slice, partition, clusterrow, pointId, trackId.Data());
     612           0 :         continue;
     613             :       }
     614           0 :       float pad=point->GetU();
     615           0 :       float time=point->GetV();
     616             : 
     617           0 :       iResult=FindCellClusters(trackId.Data(), clusterrow, pad, time, pClusterIndex, pClusters, point, clusterId);
     618           0 :       if (iResult>0) assignedClusters+=iResult;
     619           0 :     }
     620           0 :   }
     621             :   return assignedClusters;
     622           0 : }
     623             : 
     624             : int AliHLTTPCDataCompressionComponent::ProcessRemainingClusters(AliHLTGlobalBarrelTrack* pTracks, unsigned nofTracks,
     625             :                                                                 AliHLTTrackGeometry::AliHLTTrackGrid* pTrackIndex,
     626             :                                                                 const vector<int>& trackIndexMap,
     627             :                                                                 AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex,
     628             :                                                                 AliHLTSpacePointContainer* pClusters,
     629             :                                                                 int slice, int partition) const
     630             : {
     631             :   // assign remaining clusters to tracks
     632             :   int iResult=0;
     633             :   int associatedClusters=0;
     634           0 :   if (!pTracks || nofTracks==0) return 0;
     635             : 
     636           0 :   for (int padrow=0; padrow<AliHLTTPCGeometry::GetNRows(partition); padrow++) {
     637           0 :     for (AliHLTTrackGeometry::AliHLTTrackGrid::iterator& trackId=pTrackIndex->begin(slice, partition, padrow);
     638           0 :          trackId!=pTrackIndex->end(); trackId++) {
     639           0 :       if (trackId.Data()>=trackIndexMap.size()) {
     640           0 :         HLTError("can not find track id %d in index map of size %d", trackId.Data(), trackIndexMap.size());
     641             :         continue;
     642             :       }
     643           0 :       int trackindex=trackIndexMap[trackId.Data()];
     644           0 :       if (trackindex<0 || trackindex>=(int)nofTracks) {
     645           0 :         HLTError("invalid index %d found for track id %d", trackindex, trackId.Data());
     646           0 :         continue;
     647             :       }
     648           0 :       AliHLTGlobalBarrelTrack& track=pTracks[trackindex];
     649           0 :       if (!track.GetTrackGeometry()) {
     650           0 :         HLTError("can not find track geometry for track %d", trackId.Data());
     651           0 :         continue;
     652             :       }
     653           0 :       AliHLTTPCTrackGeometry* pTrackPoints=dynamic_cast<AliHLTTPCTrackGeometry*>(track.GetTrackGeometry());
     654           0 :       if (!pTrackPoints) {
     655           0 :         HLTError("invalid track geometry type for track %d, expecting AliHLTTPCTrackGeometry", trackId.Data());
     656           0 :         continue;       
     657             :       }
     658           0 :       AliHLTUInt32_t pointId=AliHLTTPCSpacePointData::GetID(slice, partition, padrow);
     659           0 :       AliHLTTrackGeometry::AliHLTTrackPoint* point=pTrackPoints->GetRawTrackPoint(pointId);
     660           0 :       if (!point) {
     661             :         //HLTError("can not find track point slice %d partition %d padrow %d (0x%08x) of track %d", slice, partition, padrow, pointId, trackId.Data());
     662           0 :         continue;
     663             :       }
     664           0 :       float pad=point->GetU();
     665           0 :       float time=point->GetV();
     666             : 
     667           0 :       iResult=FindCellClusters(trackId.Data(), padrow, pad, time, pClusterIndex, pClusters, point);
     668           0 :       if (iResult>0) associatedClusters+=iResult;
     669           0 :       if (fVerbosity>0) {
     670           0 :         HLTInfo("trackpoint track %d slice %d partition %d padrow %d: %.3f \t%.3f - associated %d", track.GetID(), slice, partition, padrow, pad, time, iResult);
     671             :       }
     672           0 :     }
     673             :   }
     674           0 :   if (iResult<0) return iResult;
     675           0 :   return associatedClusters;
     676           0 : }
     677             : 
     678             : int AliHLTTPCDataCompressionComponent::FindCellClusters(int trackId, int padrow, float pad, float time,
     679             :                                                         AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex,
     680             :                                                         AliHLTSpacePointContainer* pClusters,
     681             :                                                         AliHLTTrackGeometry::AliHLTTrackPoint* pTrackPoint,
     682             :                                                         AliHLTUInt32_t clusterId) const
     683             : {
     684             :   // check index cell for entries and assign to track
     685             :   int count=0;
     686             :   // search a 4x4 matrix out of the 9x9 matrix around the cell addressed by
     687             :   // pad and time
     688           0 :   int rowindex=pClusterIndex->GetXIndex((float)padrow);
     689           0 :   int padstartindex=pClusterIndex->GetYIndex(pad);
     690           0 :   int timestartindex=pClusterIndex->GetZIndex(time);
     691           0 :   int cellindex=pClusterIndex->Index(rowindex, padstartindex, timestartindex);
     692           0 :   float centerpad=pClusterIndex->GetCenterY(cellindex);
     693           0 :   float centertime=pClusterIndex->GetCenterZ(cellindex);
     694           0 :   if ((TMath::Abs(centerpad-pad)>fMaxDeltaPad && pad>0.) ||
     695           0 :       (TMath::Abs(centertime-time)>fMaxDeltaTime && time>0.)) {
     696           0 :     ALIHLTERRORGUARD(20, "invalid pad center calculation, please check dimensions if dimensions of index grid match the maximum possible deviation");
     697           0 :   }
     698             : 
     699             :   int paddirection=1;
     700             :   int timedirection=1;
     701           0 :   if (centerpad>pad) paddirection=-1;
     702           0 :   if (centertime>time) timedirection=-1;
     703           0 :   for (int padcount=0, padindex=padstartindex; padcount<2; padcount++, padindex+=paddirection) {
     704           0 :     if (padindex<0) continue;
     705           0 :     if (padindex>=pClusterIndex->GetDimensionY()) break;
     706           0 :     for (int timecount=0, timeindex=timestartindex; timecount<2; timecount++, timeindex+=timedirection) {
     707           0 :       if (timeindex<0) continue;
     708           0 :       if (timeindex>=pClusterIndex->GetDimensionZ()) break;
     709           0 :       cellindex=pClusterIndex->Index(rowindex, padindex, timeindex);
     710           0 :       float cellpad=pClusterIndex->GetCenterY(cellindex);
     711           0 :       float celltime=pClusterIndex->GetCenterZ(cellindex);
     712           0 :       for (AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid::iterator& cl=pClusterIndex->begin((float)padrow, cellpad, celltime);
     713           0 :            cl!=pClusterIndex->end(); cl++) {
     714           0 :         if (cl.Data().fTrackId>=0) continue;
     715           0 :         if (clusterId!=(~(AliHLTUInt32_t)0) && clusterId!=cl.Data().fId) continue;
     716           0 :         if (TMath::Abs(padrow-pClusters->GetX(cl.Data().fId))>=1.) {
     717           0 :           HLTError("cluster 0x%08x: mismatch on padrow: trackpoint %d  cluster %f", cl.Data().fId, padrow, pClusters->GetX(cl.Data().fId));
     718             :           continue;
     719             :         }
     720           0 :         float clusterpad=pClusters->GetY(cl.Data().fId);
     721           0 :         float clustertime=pClusters->GetZ(cl.Data().fId);
     722           0 :         if (TMath::Abs(clusterpad-pad)<fMaxDeltaPad &&
     723           0 :             TMath::Abs(clustertime-time)<fMaxDeltaTime) {
     724             :           // add this cluster to the track point and mark in the index grid
     725           0 :           cl.Data().fTrackId=trackId;
     726           0 :           pTrackPoint->AddAssociatedSpacePoint(cl.Data().fId, clusterpad-pad, clustertime-time);
     727           0 :           count++;
     728           0 :         }
     729           0 :         if (clusterId!=(~(AliHLTUInt32_t)0)) break;
     730           0 :       }
     731           0 :     }
     732           0 :   }
     733           0 :   return count;
     734           0 : }
     735             : 
     736             : int AliHLTTPCDataCompressionComponent::WriteTrackClusters(const vector<AliHLTGlobalBarrelTrack>& tracks,
     737             :                                                           AliHLTSpacePointContainer* pSpacePoints,
     738             :                                                           AliHLTDataDeflater* pDeflater,
     739             :                                                           AliHLTUInt8_t* outputPtr,
     740             :                                                           AliHLTUInt32_t capacity) const
     741             : {
     742             :   // write the track data block including all associated clusters
     743             :   AliHLTUInt32_t size=0;
     744           0 :   for (vector<AliHLTGlobalBarrelTrack>::const_iterator track=tracks.begin();
     745           0 :        track!=tracks.end();
     746           0 :        track++) {
     747           0 :     if (!track->GetTrackGeometry()) {
     748           0 :       HLTError("can not find track geometry for track %d", track->GetID());
     749           0 :       return -EBADF;
     750             :     }
     751           0 :     AliHLTTPCTrackGeometry* pTrackPoints=dynamic_cast<AliHLTTPCTrackGeometry*>(track->GetTrackGeometry());
     752           0 :     if (!pTrackPoints) {
     753           0 :       HLTError("invalid track geometry type for track %d, expecting AliHLTTPCTrackGeometry", track->GetID());
     754           0 :       return -EBADF;
     755             :     }
     756             : 
     757           0 :     int result=pTrackPoints->Write(*track, pSpacePoints, pDeflater, outputPtr+size, capacity-size, fpWrittenAssociatedClusterIds);
     758           0 :     if (result<0) {
     759           0 :       HLTError("failed to write track points for track %d with error code %d, aborting", track->GetID(), result);
     760           0 :       return result;
     761             :     }
     762           0 :     size+=result;
     763             : 
     764           0 :     UInt_t nofTrackPoints=track->GetNumberOfPoints();
     765           0 :     const UInt_t* trackPoints=track->GetPoints();
     766             : 
     767             :     int assignedPoints=0;
     768             :     int assignedTrackPoints=0;
     769           0 :     const vector<AliHLTTrackGeometry::AliHLTTrackPoint>& rawPoints=pTrackPoints->GetRawPoints();
     770           0 :     for (vector<AliHLTTrackGeometry::AliHLTTrackPoint>::const_iterator point=rawPoints.begin();
     771           0 :          point!=rawPoints.end(); point++) {
     772           0 :       const vector<AliHLTTrackGeometry::AliHLTTrackSpacepoint>& spacePoints=point->GetSpacepoints();
     773           0 :       for (vector<AliHLTTrackGeometry::AliHLTTrackSpacepoint>::const_iterator spacePoint=spacePoints.begin();
     774           0 :            spacePoint!=spacePoints.end(); spacePoint++) {
     775           0 :         float dpad=spacePoint->GetResidual(0);
     776           0 :         float dtime=spacePoint->GetResidual(1);
     777           0 :         if (dpad>-1000 && dtime>-1000 && fHistoResidualPad && fHistoResidualTime) {
     778           0 :           fHistoResidualPad->Fill(dpad);
     779           0 :           fHistoResidualTime->Fill(dtime);
     780           0 :         }
     781           0 :         assignedPoints++;
     782           0 :         for (unsigned i=0; i<nofTrackPoints; i++) {
     783           0 :           if (trackPoints[i]==spacePoint->fId) {
     784           0 :             assignedTrackPoints++;
     785           0 :             break;
     786             :           }
     787             :         }
     788             :       }
     789             :     }
     790           0 :     if (fHistoClustersOnTracks) {
     791           0 :       fHistoClustersOnTracks->Fill(assignedPoints);
     792           0 :     }
     793           0 :     if (fHistoTrackClusterRatio && nofTrackPoints>0) {
     794           0 :       float ratio=assignedTrackPoints; ratio/=nofTrackPoints;
     795           0 :       fHistoTrackClusterRatio->Fill(ratio);
     796           0 :     }
     797           0 :   }
     798           0 :   return size;
     799           0 : }
     800             : 
     801             : int AliHLTTPCDataCompressionComponent::DoInit( int argc, const char** argv )
     802             : {
     803             :   /// inherited from AliHLTComponent: component initialisation and argument scan.
     804             :   int iResult=0;
     805             : 
     806             :   // component configuration
     807             :   //Stage 1: default initialization.
     808             :   //Default values.
     809             : 
     810             :   //Stage 2: OCDB.
     811           0 :   TString cdbPath("HLT/ConfigTPC/");
     812           0 :   cdbPath += GetComponentID();
     813             :   //
     814           0 :   iResult = ConfigureFromCDBTObjString(cdbPath);
     815           0 :   if (iResult < 0) 
     816           0 :     return iResult;
     817             : 
     818             :   //Stage 3: command line arguments.
     819           0 :   int mode=fMode; // just a backup for the info message below
     820           0 :   int deflaterMode=fDeflaterMode;
     821           0 :   if (argc && (iResult = ConfigureFromArgumentString(argc, argv)) < 0)
     822           0 :     return iResult;
     823             : 
     824           0 :   if (mode!=fMode || deflaterMode!=fDeflaterMode) {
     825           0 :     HLTInfo("configured from command line: mode %d, deflater mode %d", fMode, fDeflaterMode);
     826             :   }
     827             : 
     828           0 :   std::auto_ptr<AliHLTComponentBenchmark> benchmark(new AliHLTComponentBenchmark);
     829           0 :   if (benchmark.get()) {
     830           0 :     benchmark->SetTimer(0,"total");
     831           0 :     benchmark->SetTimer(1,"rawclusterinput");
     832           0 :     benchmark->SetTimer(2,"clusterinput");
     833           0 :     benchmark->SetTimer(3,"trackinput");
     834           0 :     benchmark->SetTimer(4,"processing");
     835           0 :     benchmark->SetTimer(5,"output");
     836             :   } else {
     837           0 :     return -ENOMEM;
     838             :   }
     839             : 
     840             :   unsigned spacePointContainerMode=0;
     841           0 :   if (fMode==kCompressionModeV1TrackModel || fMode==kCompressionModeV2TrackModel) {
     842             :     // initialize map data for cluster access in the track association loop
     843             :     spacePointContainerMode|=AliHLTTPCRawSpacePointContainer::kModeCreateMap;
     844           0 :   }
     845           0 :   if (fMode==kCompressionModeV2 || fMode==kCompressionModeV2TrackModel) {
     846             :     // optimized storage format: differential pad and time storage
     847           0 :     spacePointContainerMode|=AliHLTTPCRawSpacePointContainer::kModeDifferentialPadTime;
     848           0 :   }
     849           0 :   std::auto_ptr<AliHLTTPCRawSpacePointContainer> rawInputClusters(new AliHLTTPCRawSpacePointContainer(spacePointContainerMode, fCreateFlags));
     850           0 :   std::auto_ptr<AliHLTTPCSpacePointContainer> inputClusters(new AliHLTTPCSpacePointContainer);
     851             : 
     852           0 :   std::auto_ptr<TH1F> histoCompFactor(new TH1F("CompressionFactor",
     853             :                                                "HLT TPC data compression factor",
     854             :                                                100, 0., 10.));
     855           0 :   std::auto_ptr<TH1F> histoResidualPad(new TH1F("PadResidual",
     856             :                                                 "HLT TPC pad residual",
     857           0 :                                                 100, -fMaxDeltaPad, fMaxDeltaPad));
     858           0 :   std::auto_ptr<TH1F> histoResidualTime(new TH1F("TimeResidual",
     859             :                                                  "HLT TPC time residual",
     860           0 :                                                  100, -fMaxDeltaTime, fMaxDeltaTime));
     861           0 :   std::auto_ptr<TH1F> histoClustersOnTracks(new TH1F("ClustersOnTracks",
     862             :                                                  "Clusters in track model compression",
     863             :                                                  200, 0., 600));
     864           0 :   std::auto_ptr<TH1F> histoClusterRatio(new TH1F("ClusterRatio",
     865             :                                                  "Fraction of clusters in track model compression",
     866             :                                                  100, 0., 1.));
     867           0 :   std::auto_ptr<TH1F> histoTrackClusterRatio(new TH1F("UsedTrackClusters",
     868             :                                                  "Fraction of track clusters in track model compression",
     869             :                                                  100, 0., 1.));
     870             : 
     871             :   // track grid: 36 slices, each 6 partitions with max 33 rows
     872           0 :   fTrackGrid=new AliHLTTrackGeometry::AliHLTTrackGrid(36, 1, 6, 1, 33, 1, 20000);
     873           0 :   fSpacePointGrid=AliHLTTPCRawSpacePointContainer::AllocateIndexGrid();
     874             : 
     875           0 :   if (!rawInputClusters.get() ||
     876           0 :       !inputClusters.get() ||
     877           0 :       !fTrackGrid ||
     878           0 :       !fSpacePointGrid) {
     879           0 :     if (fTrackGrid) delete fTrackGrid; fTrackGrid=NULL;
     880           0 :     if (fSpacePointGrid) delete fSpacePointGrid; fSpacePointGrid=NULL;
     881           0 :     return -ENOMEM;
     882             :   }
     883             : 
     884           0 :   if (fDeflaterMode>0 && (iResult=InitDeflater(fDeflaterMode))<0)
     885           0 :     return iResult;
     886             : 
     887           0 :   fpBenchmark=benchmark.release();
     888           0 :   fRawInputClusters=rawInputClusters.release();
     889           0 :   fInputClusters=inputClusters.release();
     890             : 
     891             :   // initialize the histograms if stored at the end
     892             :   // condition might be extended
     893           0 :   if (!fHistogramFile.IsNull()) {
     894           0 :     fHistoCompFactor=histoCompFactor.release();
     895           0 :     fHistoResidualPad=histoResidualPad.release();
     896           0 :     fHistoResidualTime=histoResidualTime.release();
     897           0 :     fHistoClustersOnTracks=histoClustersOnTracks.release();
     898           0 :     fHistoClusterRatio=histoClusterRatio.release();
     899           0 :     fHistoTrackClusterRatio=histoTrackClusterRatio.release();
     900           0 :   }
     901             : 
     902             :   // only init drift time if actually needed
     903             :   // i.e. when using track model compression
     904             :   // transform init takes ages.....
     905           0 :   if (fMode==kCompressionModeV1TrackModel || fMode==kCompressionModeV2TrackModel) {
     906           0 :     if (iResult>=0 && (iResult=InitDriftTimeTransformation())<0) return iResult;
     907             :   }
     908             : 
     909           0 :   HLTInfo("TPC Cluster compression running in mode %d / deflaterMode %d", fMode, fDeflaterMode);
     910             : 
     911           0 :   return iResult;
     912           0 : }
     913             : 
     914             : int AliHLTTPCDataCompressionComponent::InitDeflater(int mode)
     915             : {
     916             :   /// init the data deflater
     917             :   int iResult=0;
     918           0 :   if (mode==kDeflaterModeHuffman || mode==kDeflaterModeHuffmanTrainer) {
     919             :     // huffman deflater
     920           0 :     std::auto_ptr<AliHLTDataDeflaterHuffman> deflater(new AliHLTDataDeflaterHuffman(mode==kDeflaterModeHuffmanTrainer));
     921           0 :     if (!deflater.get()) return -ENOMEM;
     922             : 
     923           0 :     if (!deflater->IsTrainingMode()) {
     924           0 :       TString cdbPath("HLT/ConfigTPC/");
     925           0 :       cdbPath += GetComponentID();
     926           0 :       cdbPath += "HuffmanTables";
     927           0 :       TObject* pConf=LoadAndExtractOCDBObject(cdbPath);
     928           0 :       if (!pConf) return -ENOENT;
     929           0 :       if (dynamic_cast<TList*>(pConf)==NULL) {
     930           0 :         HLTError("huffman table configuration object of inconsistent type");
     931           0 :         return -EINVAL;
     932             :       }
     933           0 :       iResult=deflater->InitDecoders(dynamic_cast<TList*>(pConf));
     934           0 :       if (iResult<0) return iResult;
     935           0 :     }
     936             :     
     937           0 :     if (!fHistogramFile.IsNull())
     938           0 :       deflater->EnableStatistics();
     939             : 
     940           0 :     unsigned nofParameters=AliHLTTPCDefinitions::GetNumberOfClusterParameterDefinitions();
     941             :     unsigned p=0;
     942           0 :     for (; p<nofParameters; p++) {
     943           0 :       const AliHLTTPCDefinitions::AliClusterParameter& parameter=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[p];
     944             :       // use the pad/time length as reference for the calculation of ratio for residuals
     945             :       unsigned refLength=0;
     946             :       unsigned refLengthPad=0;
     947             :       unsigned refLengthTime=0;
     948           0 :       if (parameter.fId==AliHLTTPCDefinitions::kPad)               refLengthPad=parameter.fBitLength;
     949           0 :       else if (parameter.fId==AliHLTTPCDefinitions::kTime)         refLengthTime=parameter.fBitLength;
     950           0 :       else if (parameter.fId==AliHLTTPCDefinitions::kResidualPad)  refLength=refLengthPad;
     951           0 :       else if (parameter.fId==AliHLTTPCDefinitions::kResidualTime) refLength=refLengthTime;
     952             : 
     953           0 :       if (deflater->AddParameterDefinition(parameter.fName,
     954           0 :                                            parameter.fBitLength,
     955           0 :                                            refLength)!=(int)parameter.fId) {
     956             :         // for performance reason the parameter id is simply used as index in the array of
     957             :         // definitions, the position must match the id
     958           0 :         HLTFatal("mismatch between parameter id and position in array for parameter %s, rearrange definitions!", parameter.fName);
     959           0 :         return -EFAULT;
     960             :       }
     961           0 :     }
     962           0 :     fpDataDeflater=deflater.release();
     963           0 :     return 0;
     964           0 :   }
     965           0 :   if (mode==kDeflaterModeSimple) {
     966           0 :     std::auto_ptr<AliHLTDataDeflaterSimple> deflater(new AliHLTDataDeflaterSimple);
     967           0 :     if (!deflater.get()) return -ENOMEM;
     968             : 
     969           0 :     if (!fHistogramFile.IsNull())
     970           0 :       deflater->EnableStatistics();
     971             : 
     972           0 :     unsigned nofParameters=AliHLTTPCDefinitions::GetNumberOfClusterParameterDefinitions();
     973             :     unsigned p=0;
     974           0 :     for (; p<nofParameters; p++) {
     975           0 :       const AliHLTTPCDefinitions::AliClusterParameter& parameter=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[p];
     976           0 :       if (deflater->AddParameterDefinition(parameter.fName,
     977           0 :                                            parameter.fBitLength,
     978           0 :                                            parameter.fOptional)!=(int)parameter.fId) {
     979             :         // for performance reason the parameter id is simply used as index in the array of
     980             :         // definitions, the position must match the id
     981           0 :         HLTFatal("mismatch between parameter id and position in array for parameter %s, rearrange definitions!", parameter.fName);
     982           0 :         return -EFAULT;
     983             :       }
     984           0 :     }
     985           0 :     fpDataDeflater=deflater.release();
     986           0 :     return 0;
     987           0 :   }
     988           0 :   HLTError("invalid deflater mode %d, allowed 1=simple 2=huffman", mode);
     989           0 :   return -EINVAL;
     990           0 : }
     991             : 
     992             : int AliHLTTPCDataCompressionComponent::DoDeinit()
     993             : {
     994             :   /// inherited from AliHLTComponent: component cleanup
     995             :   int iResult=0;
     996           0 :   if (fpBenchmark) delete fpBenchmark; fpBenchmark=NULL;
     997           0 :   if (fRawInputClusters) delete fRawInputClusters; fRawInputClusters=NULL;
     998           0 :   if (fInputClusters) delete fInputClusters; fInputClusters=NULL;
     999           0 :   if (!fHistogramFile.IsNull()) {
    1000           0 :     TFile out(fHistogramFile, "RECREATE");
    1001           0 :     if (!out.IsZombie()) {
    1002           0 :       out.cd();
    1003           0 :       if (fHistoCompFactor) fHistoCompFactor->Write();
    1004           0 :       if (fHistoResidualPad) fHistoResidualPad->Write();
    1005           0 :       if (fHistoResidualTime) fHistoResidualTime->Write();
    1006           0 :       if (fHistoClusterRatio) fHistoClusterRatio->Write();
    1007           0 :       if (fHistoClustersOnTracks) fHistoClustersOnTracks->Write();
    1008           0 :       if (fHistoTrackClusterRatio) fHistoTrackClusterRatio->Write();
    1009           0 :       out.Close();
    1010             :     }
    1011           0 :   }
    1012           0 :   if (fHistoCompFactor) delete fHistoCompFactor;
    1013           0 :   fHistoCompFactor=NULL;
    1014           0 :   if (fHistoResidualPad) delete fHistoResidualPad;
    1015           0 :   fHistoResidualPad=NULL;
    1016           0 :   if (fHistoResidualTime) delete fHistoResidualTime;
    1017           0 :   fHistoResidualTime=NULL;
    1018           0 :   if (fHistoClustersOnTracks) delete fHistoClustersOnTracks;
    1019           0 :   fHistoClustersOnTracks=NULL;
    1020           0 :   if (fHistoClusterRatio) delete fHistoClusterRatio;
    1021           0 :   fHistoClusterRatio=NULL;
    1022           0 :   if (fHistoTrackClusterRatio) delete fHistoTrackClusterRatio;
    1023           0 :   fHistoTrackClusterRatio=NULL;
    1024             : 
    1025           0 :   if (fpDataDeflater) {
    1026           0 :     if (!fHistogramFile.IsNull()) {
    1027           0 :       TString filename=fHistogramFile;
    1028           0 :       filename.ReplaceAll(".root", "-deflater.root");
    1029           0 :       fpDataDeflater->SaveAs(filename);
    1030           0 :     }
    1031           0 :     if (fDeflaterMode==kDeflaterModeHuffmanTrainer) {
    1032           0 :       if (fTrainingTableOutput.IsNull()) {
    1033           0 :         fTrainingTableOutput=GetComponentID();
    1034           0 :         fTrainingTableOutput+="-huffman.root";
    1035           0 :       }
    1036             :       // TODO: currently, the code tables are also calculated in FindObject
    1037             :       // check if a different function is more appropriate
    1038           0 :       TObject* pConf=fpDataDeflater->FindObject("DeflaterConfiguration");
    1039           0 :       if (pConf) {
    1040           0 :         TString cdbEntryPath("HLT/ConfigTPC/");
    1041           0 :         cdbEntryPath += GetComponentID();
    1042           0 :         cdbEntryPath += "HuffmanTables";
    1043           0 :         AliCDBPath cdbPath(cdbEntryPath);
    1044           0 :         AliCDBId cdbId(cdbPath, AliCDBManager::Instance()->GetRun(), AliCDBRunRange::Infinity(), 0, 0);
    1045           0 :         AliCDBMetaData* cdbMetaData=new AliCDBMetaData;
    1046           0 :         cdbMetaData->SetResponsible("ALICE HLT Matthias.Richter@cern.ch");
    1047           0 :         cdbMetaData->SetComment("Huffman encoder configuration");
    1048           0 :         AliCDBEntry* entry=new AliCDBEntry(pConf, cdbId, cdbMetaData, kTRUE);
    1049             : 
    1050           0 :         entry->SaveAs(fTrainingTableOutput);
    1051             :         // this is a small memory leak
    1052             :         // seg fault in ROOT object handling if the two objects are deleted
    1053             :         // investigate later
    1054             :         //delete entry;
    1055             :         //delete cdbMetaData;
    1056           0 :       }
    1057           0 :     }
    1058           0 :     delete fpDataDeflater;
    1059             :   }
    1060           0 :   fpDataDeflater=NULL;
    1061             : 
    1062             : 
    1063           0 :   if (fTrackGrid) delete fTrackGrid; fTrackGrid=NULL;
    1064           0 :   if (fSpacePointGrid) delete fSpacePointGrid; fSpacePointGrid=NULL;
    1065             : 
    1066           0 :   return iResult;
    1067           0 : }
    1068             : 
    1069             : int AliHLTTPCDataCompressionComponent::ScanConfigurationArgument(int argc, const char** argv)
    1070             : {
    1071             :   /// inherited from AliHLTComponent: argument scan
    1072             :   int iResult=0;
    1073           0 :   if (argc<1) return 0;
    1074             :   int bMissingParam=0;
    1075             :   int i=0;
    1076           0 :   TString argument=argv[i];
    1077             : 
    1078             :   do {
    1079             :     // -mode
    1080           0 :     if (argument.CompareTo("-mode")==0) {
    1081           0 :       if ((bMissingParam=(++i>=argc))) break;
    1082           0 :       TString parameter=argv[i];
    1083           0 :       if (parameter.IsDigit()) {
    1084           0 :         fMode=parameter.Atoi();
    1085           0 :         return 2;
    1086             :       } else {
    1087           0 :         HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data());
    1088           0 :         return -EPROTO;
    1089             :       }
    1090           0 :     }
    1091             : 
    1092             :     // -create-flags
    1093           0 :     if (argument.CompareTo("-create-flags")==0) {
    1094           0 :       if ((bMissingParam=(++i>=argc))) break;
    1095           0 :       TString parameter=argv[i];
    1096           0 :       if (parameter.IsDigit()) {
    1097           0 :         fCreateFlags=parameter.Atoi();
    1098           0 :         return 2;
    1099             :       } else {
    1100           0 :         HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data());
    1101           0 :         return -EPROTO;
    1102             :       }
    1103           0 :     }
    1104             : 
    1105             :     // -deflater-mode
    1106           0 :     if (argument.CompareTo("-deflater-mode")==0) {
    1107           0 :       if ((bMissingParam=(++i>=argc))) break;
    1108           0 :       TString parameter=argv[i];
    1109           0 :       if (parameter.IsDigit()) {
    1110           0 :         fDeflaterMode=parameter.Atoi();
    1111           0 :         return 2;
    1112             :       } else {
    1113           0 :         HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data());
    1114           0 :         return -EPROTO;
    1115             :       }
    1116           0 :     }
    1117             : 
    1118             :     // -histogram-file
    1119           0 :     if (argument.CompareTo("-histogram-file")==0) {
    1120           0 :       if ((bMissingParam=(++i>=argc))) break;
    1121           0 :       fHistogramFile=argv[i++];
    1122           0 :       return 2;
    1123             :     }
    1124             :     // -save-histogram-table
    1125           0 :     if (argument.CompareTo("-save-huffman-table")==0) {
    1126           0 :       if ((bMissingParam=(++i>=argc))) break;
    1127           0 :       fTrainingTableOutput=argv[i++];
    1128           0 :       return 2;
    1129             :     }
    1130             :     // -cluster-verification
    1131           0 :     if (argument.CompareTo("-cluster-verification")==0) {
    1132           0 :       if ((bMissingParam=(++i>=argc))) break;
    1133           0 :       TString parameter=argv[i];
    1134           0 :       if (parameter.IsDigit()) {
    1135           0 :         fVerificationMode=parameter.Atoi();
    1136           0 :         return 2;
    1137             :       } else {
    1138           0 :         HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data());
    1139           0 :         return -EPROTO;
    1140             :       }
    1141           0 :     }
    1142             :   } while (0); // using do-while only to have break available
    1143             : 
    1144           0 :   if (bMissingParam) {
    1145           0 :     HLTError("missing parameter for argument %s", argument.Data());
    1146             :     iResult=-EPROTO;
    1147           0 :   }
    1148             : 
    1149           0 :   return iResult;
    1150           0 : }
    1151             : 
    1152             : int AliHLTTPCDataCompressionComponent::InitDriftTimeTransformation()
    1153             : {
    1154             :   /// calculate correction factor and offset for a linear approximation of the
    1155             :   /// drift time transformation, separately for A and C side
    1156             :   int iResult=0;
    1157           0 :   AliHLTTPCClusterTransformation transform;
    1158           0 :   if ((iResult=transform.Init( GetBz(), GetTimeStamp()))<0) {
    1159           0 :     HLTError("failed to init AliHLTTPCClusterTransformation: %d", iResult);
    1160           0 :     return iResult;
    1161             :   }
    1162             : 
    1163           0 :   if ((iResult=CalculateDriftTimeTransformation(transform, 0, 0, fDriftTimeFactorA, fDriftTimeOffsetA))<0) return iResult;
    1164           0 :   if (fVerbosity>0) HLTInfo("drift time transformation A side: m=%f n=%f", fDriftTimeFactorA, fDriftTimeOffsetA);
    1165           0 :   if ((iResult=CalculateDriftTimeTransformation(transform, 18, 0, fDriftTimeFactorC, fDriftTimeOffsetC))<0) return iResult;
    1166           0 :   if (fVerbosity>0) HLTInfo("drift time transformation C side: m=%f n=%f", fDriftTimeFactorC, fDriftTimeOffsetC);
    1167             : 
    1168           0 :   return 0;
    1169           0 : }
    1170             : 
    1171             : int AliHLTTPCDataCompressionComponent::CalculateDriftTimeTransformation(AliHLTTPCClusterTransformation& transform,
    1172             :                                                                         int slice, int padrow,
    1173             :                                                                         float& m, float& n) const
    1174             : {
    1175             :   /// calculate correction factor and offset for a linear approximation of the
    1176             :   /// drift time transformation by just probing the range of timebins with
    1177             :   /// AliHLTTPCClusterTransformation
    1178             :   const int nofSteps=100;
    1179           0 :   vector<float> zvalues;
    1180             : 
    1181           0 :   int nofTimebins=AliHLTTPCGeometry::GetNTimeBins();
    1182           0 :   int stepWidth=nofTimebins/nofSteps;
    1183             :   int time=0;
    1184             :   int count=0;
    1185             :   float meanT=0.;
    1186             :   float meanZ=0.;
    1187           0 :   for (time=0; time<nofTimebins; time+=stepWidth, count++) {
    1188           0 :     Float_t xyz[3];
    1189           0 :     transform.Transform(slice, padrow, 0, time, xyz);
    1190           0 :     zvalues.push_back(xyz[2]);
    1191           0 :     meanT+=time;
    1192           0 :     meanZ+=xyz[2];
    1193           0 :   }
    1194           0 :   if (count==0) count=1;
    1195           0 :   meanT/=count;
    1196           0 :   meanZ/=count;
    1197             :   float sumTZ=.0;
    1198             :   float sumT2=.0;
    1199             :   time=0;
    1200           0 :   for (vector<float>::const_iterator z=zvalues.begin();
    1201           0 :        z!=zvalues.end(); z++, time+=stepWidth) {
    1202           0 :     sumTZ+=(time-meanT)*((*z)-meanZ);
    1203           0 :     sumT2+=(time-meanT)*(time-meanT);
    1204             :   }
    1205           0 :   m=sumTZ/sumT2;
    1206           0 :   n=meanZ-m*meanT;
    1207             : 
    1208             :   return 0;
    1209           0 : }

Generated by: LCOV version 1.11