implementing the encoding and decoding of compressed cluster format; added indexing...
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 18 Aug 2011 23:09:52 +0000 (23:09 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 18 Aug 2011 23:09:52 +0000 (23:09 +0000)
HLT/TPCLib/AliHLTTPCClusterAccessHLTOUT.cxx
HLT/TPCLib/AliHLTTPCClusterAccessHLTOUT.h
HLT/TPCLib/AliHLTTPCDefinitions.cxx
HLT/TPCLib/AliHLTTPCHWCFSpacePointContainer.cxx
HLT/TPCLib/AliHLTTPCHWCFSpacePointContainer.h
HLT/TPCLib/comp/AliHLTTPCDataCompressionComponent.cxx

index c501227..2fe2c1e 100644 (file)
 #include "AliHLTTPCDefinitions.h"
 #include "AliHLTTPCClusterDataFormat.h"
 #include "AliHLTTPCRawCluster.h"
+#include "AliHLTTPCTransform.h"
 #include "AliHLTOUT.h"
 #include "AliHLTComponent.h"
 #include "AliHLTErrorGuard.h"
+#include "AliHLTDataInflater.h"
+#include "AliHLTTPCDefinitions.h"
 #include "AliLog.h"
 #include "AliHLTSystem.h"
 #include "AliHLTPluginBase.h"
@@ -335,6 +338,20 @@ int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterData(AliHLTOUT* pHLTOUT
     }
     const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer);
     Int_t nCount = (Int_t) clusterData->fCount;
+    if (clusterData->fVersion!=0) {
+      // this is encoded data of different formats
+      switch (clusterData->fVersion) {
+      case 1: 
+       iResult=ReadAliHLTTPCRawClusterDataDeflateSimple(reinterpret_cast<const AliHLTUInt8_t*>(clusterData->fClusters),
+                                                        size-sizeof(AliHLTTPCRawClusterData), nCount, specification,
+                                                        pClusters, tpcClusterLabels);
+       break;
+      default:
+       iResult=-EPROTO;
+      }
+      return iResult;
+    }
+
     if (nCount*sizeof(AliHLTTPCRawCluster) + sizeof(AliHLTTPCRawClusterData) != size) {
       AliError("inconsistent cluster data block size, skipping block");
       continue;
@@ -384,3 +401,110 @@ int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterData(AliHLTOUT* pHLTOUT
   } while (pHLTOUT->SelectNextDataBlock()>=0);
   return iResult;
 }
+
+int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterDataDeflateSimple(const AliHLTUInt8_t* pData, int dataSize,
+                                                                          int nofClusters, AliHLTUInt32_t specification,
+                                                                          TClonesArray* pClusters,
+                                                                          const AliHLTTPCClusterMCDataList *tpcClusterLabels)
+{
+  // read cluster data from AliHLTTPCClusterData
+
+  // FIXME: quick implementation to read the compressed cluster data from HLTOUT
+  // the data definition below is the same as in AliHLTTPCDataCompressionComponent
+  // but needs to be moved to a common class (AliHLTTPCDefinitions?)
+  // Think about a decoder class supporting iterator objects for various types
+  // of cluster data
+  int iResult=0;
+  if (!pData || !pClusters) return -EINVAL;
+  AliHLTDataInflater inflater;
+  if ((iResult=inflater.InitBitDataInput(pData, dataSize))<0) {
+    return iResult;
+  }
+
+  int offset=pClusters->GetEntries();
+  pClusters->ExpandCreate(offset+nofClusters);
+  AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
+  AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
+  // the compressed format stores the difference of the local row number in
+  // the partition to the row of the last cluster
+  // add the first row in the partition to get global row number
+  // offline uses row number in physical sector, inner sector consists of
+  // partitions 0 and 1, outer sector of partition 2-5
+  int rowOffset=AliHLTTPCTransform::GetFirstRow(partition)-(partition<2?0:AliHLTTPCTransform::GetFirstRow(2));
+
+  int parameterId=0;
+  int outClusterCnt=0;
+  AliHLTUInt8_t switchBit=0;
+  AliHLTUInt64_t value=0;
+  AliTPCclusterMI* pCluster=NULL;
+  AliHLTUInt32_t lastPadRow=0;
+  while (outClusterCnt<nofClusters && inflater.InputBit(switchBit)) {
+    const AliHLTTPCDefinitions::AliClusterParameter& parameter
+      =AliHLTTPCDefinitions::fgkClusterParameterDefinitions[parameterId];
+    // in mode DeflaterSimple, the optional parameter of the cluster parameter definition
+    // corresponds to the number bits of the reduced format
+    if (!inflater.InputBits(value, switchBit?parameter.fBitLength:parameter.fOptional)) {
+      break;
+    }
+
+    if (!pCluster) {
+      if (!pClusters->At(offset+outClusterCnt)) {
+       // here we should not get anymore because of the condition outClusterCnt<nofClusters
+       return -ENOSPC;
+      }
+      pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+outClusterCnt));
+      if (!pCluster) {
+       AliError("invalid object type, expecting AliTPCclusterMI");
+       iResult=-EBADF; // this is a problem of all objects
+       break;
+      }
+    }
+    switch (parameterId) {
+    case AliHLTTPCDefinitions::kPadRow:
+      {pCluster->SetRow(value+lastPadRow+rowOffset); lastPadRow+=value;break;}
+    case AliHLTTPCDefinitions::kPad:
+      {float pad=value; pad/=parameter.fScale; pCluster->SetPad(pad); break;}
+    case AliHLTTPCDefinitions::kTime:
+      {float time=value; time/=parameter.fScale; pCluster->SetTimeBin(time); break;}
+    case AliHLTTPCDefinitions::kSigmaY2:
+      {float sigmaY2=value; sigmaY2/=parameter.fScale; pCluster->SetSigmaY2(sigmaY2); break;}
+    case AliHLTTPCDefinitions::kSigmaZ2:
+      {float sigmaZ2=value; sigmaZ2/=parameter.fScale; pCluster->SetSigmaZ2(sigmaZ2); break;}
+    case AliHLTTPCDefinitions::kCharge:
+      {pCluster->SetQ(value); break;}
+    case AliHLTTPCDefinitions::kQMax:
+      {pCluster->SetMax(value); break;}
+    }
+    if (parameterId>=AliHLTTPCDefinitions::kLast) {
+      // switch to next cluster
+      if (tpcClusterLabels) {
+       UInt_t clusterID=AliHLTTPCSpacePointData::GetID(slice, partition, outClusterCnt);
+       if (tpcClusterLabels->find(clusterID)!=tpcClusterLabels->end()) {
+         const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusterID)->second.fClusterID;
+         for (int k=0; k<3; k++) {
+           // TODO: sort the labels according to the weight in order to assign the most likely mc label
+           // to the first component 
+           pCluster->SetLabel(mcWeights[k].fMCID, k);
+         }
+       } else {
+         AliError(Form("can not find mc label of cluster with id %0x08x", clusterID));
+       }
+      }
+      outClusterCnt++;
+      pCluster=NULL;
+      parameterId=-1;
+    }
+    parameterId++;
+  }
+  inflater.Pad8Bits();
+  if (inflater.InputBit(switchBit)) {
+    AliWarning("format error of compressed clusters, there is more data than expected");
+  }
+  inflater.CloseBitDataInput();
+  if (iResult>=0 && nofClusters!=outClusterCnt) {
+    // is this a Fatal?
+    AliError(Form("error reading compressed cluster format: expected %d, read only %d cluster(s)", nofClusters, outClusterCnt));
+    return -EPROTO;
+  }
+  return iResult;
+}
index aef7e7a..c111176 100644 (file)
@@ -101,6 +101,10 @@ class AliHLTTPCClusterAccessHLTOUT : public TObject
   /// process the cluster data block {CLUSTRAW:TPC } from HLTOUT
   int ReadAliHLTTPCRawClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels);
 
+  int ReadAliHLTTPCRawClusterDataDeflateSimple(const AliHLTUInt8_t* pData, int dataSize,
+                                              int nofClusters, AliHLTUInt32_t specification,
+                                              TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels);
+
  private:
   /// copy constructor prohibited
   AliHLTTPCClusterAccessHLTOUT(const AliHLTTPCClusterAccessHLTOUT&);
index babdb50..f50c716 100644 (file)
@@ -139,7 +139,7 @@ const AliHLTComponentDataType AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCIn
 
 
 const AliHLTTPCDefinitions::AliClusterParameter AliHLTTPCDefinitions::fgkClusterParameterDefinitions[]= {
-  {AliHLTTPCDefinitions::kPadRow,  "padrow",   6,  4,   1},
+  {AliHLTTPCDefinitions::kPadRow,  "padrow",   6,  1,   1}, // difference of rows, mostly 0 or 1
   {AliHLTTPCDefinitions::kPad,     "pad",     14, 12,  60}, // 100um for 6mm pads
   {AliHLTTPCDefinitions::kTime,    "time",    15, 13,  25}, // 100um for 2.5 mm timebin pitch
   {AliHLTTPCDefinitions::kSigmaY2, "sigmaY2",  8,  5,  25},
index 5e57be5..f7d8d43 100644 (file)
 #include <memory>
 #include <algorithm>
 #include <cmath>
+#include <iostream>
+#include <iomanip>
+
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTTPCHWCFSpacePointContainer)
 
-AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointContainer()
+AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointContainer(int mode)
   : AliHLTSpacePointContainer()
   , fClusters()
   , fSelections()
-  , fDecoders()
+  , fBlocks()
+  , fSingleBlock()
+  , fMode(mode)
 {
   // see header file for class documentation
   // or
   // refer to README to build package
   // or
   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+  if (fMode==1) {
+    fSingleBlock.SetDecoder(new AliHLTTPCHWCFData);
+    fSingleBlock.SetGrid(new AliHLTSpacePointGrid(33, 1.0, 140, 8, 1024, 10));
+  }
 }
 
 AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointContainer(const AliHLTTPCHWCFSpacePointContainer& c)
   : AliHLTSpacePointContainer(c)
   , fClusters(c.fClusters.begin(), c.fClusters.end())
   , fSelections()
-  , fDecoders()
+  , fBlocks()
+  , fSingleBlock()
+  , fMode(c.fMode)
 {
   /// copy constructor
 }
@@ -71,6 +82,7 @@ AliHLTTPCHWCFSpacePointContainer& AliHLTTPCHWCFSpacePointContainer::operator=(co
   if (&c==this) return *this;
   AliHLTSpacePointContainer::operator=(c);
   fClusters=c.fClusters;
+  fMode=c.fMode;
 
   return *this;
 }
@@ -79,12 +91,15 @@ AliHLTTPCHWCFSpacePointContainer::~AliHLTTPCHWCFSpacePointContainer()
 {
   // destructor
   Clear();
+  if (fSingleBlock.GetDecoder()) delete fSingleBlock.GetDecoder();
+  if (fSingleBlock.GetGrid()) delete fSingleBlock.GetGrid();
 }
 
 int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockData* pDesc)
 {
   // add input block to the collection
   if (!pDesc) return -EINVAL;
+  int iResult=0;
   int count=0;
   if (pDesc->fDataType!=AliHLTTPCDefinitions::fgkHWClustersDataType) {
     HLTWarning("ignoring data block of type %s", AliHLTComponent::DataType2Text(pDesc->fDataType).c_str());
@@ -93,13 +108,39 @@ int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockDa
   if (!pDesc->fPtr) return -ENODATA;
   if (pDesc->fSize<=sizeof(AliRawDataHeader)) return 0;
 
-  AliHLTUInt32_t *buffer=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);  
+  AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
+  AliHLTUInt8_t part  = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
+
+  AliHLTUInt32_t decoderIndex=AliHLTTPCSpacePointData::GetID(slice, part, 0);
+
+  AliHLTUInt32_t *buffer=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
   // skip the first 8 32-bit CDH words
   buffer += 8;
   UInt_t bufferSize32 = ((Int_t)pDesc->fSize - sizeof(AliRawDataHeader) )/sizeof(AliHLTUInt32_t);
 
-  std::auto_ptr<AliHLTTPCHWCFData> pDecoder(new AliHLTTPCHWCFData);
-  if (!pDecoder.get()) return -ENOMEM;
+  AliHLTTPCHWCFData* pDecoder=NULL;
+  AliHLTSpacePointGrid* pGrid=NULL;
+  if (fMode==1) {
+    pDecoder=fSingleBlock.GetDecoder();
+    pGrid=fSingleBlock.GetGrid();
+  } else {
+    if (fBlocks.find(decoderIndex)!=fBlocks.end()) {
+      HLTError("data block of slice %d partition %d already added, skipping data block", slice, part);
+      return -EEXIST;
+    }
+  }
+
+  if (!pDecoder) {
+    pDecoder=new AliHLTTPCHWCFData;
+    if (!pDecoder) return -ENOMEM;
+  }
+  if (!pGrid) {
+    pGrid=new AliHLTSpacePointGrid(33, 1.0, 140, 8, 1024, 10);
+    if (!pGrid) {
+      delete pDecoder;
+      return -ENOMEM;
+    }
+  }
 
   if (pDecoder->Init(reinterpret_cast<AliHLTUInt8_t*>(buffer), bufferSize32*sizeof(AliHLTUInt32_t))<0 ||
       (pDecoder->CheckVersion()<0 && (int)bufferSize32>pDecoder->GetRCUTrailerSize())) {
@@ -108,31 +149,100 @@ int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockDa
     return -EBADMSG;
   }
 
+  if (fMode!=1) {
   UInt_t nofClusters=pDecoder->GetNumberOfClusters();
 
-  AliHLTUInt8_t minslice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
-  AliHLTUInt8_t minpart  = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
-
   for (UInt_t i=0; i<nofClusters; i++) {
     AliHLTUInt32_t clusterID=~(AliHLTUInt32_t)0;
     // cluster ID from slice, partition and index
-    clusterID=AliHLTTPCSpacePointData::GetID(minslice, minpart, i);
+    clusterID=AliHLTTPCSpacePointData::GetID(slice, part, i);
 
     if (fClusters.find(clusterID)==fClusters.end()) {
       // new cluster
-      fClusters[clusterID]=AliHLTTPCHWCFSpacePointProperties(pDecoder.get(), i);
+      fClusters[clusterID]=AliHLTTPCHWCFSpacePointProperties(pDecoder, i);
       count++;
     } else {
       HLTError("cluster with ID 0x%08x already existing, skipping cluster %d of data block 0x%08x",
               clusterID, i, pDesc->fSpecification);
     }
   }
+  }
 
-  fDecoders.push_back(pDecoder.release());
+  if ((iResult=PopulateAccessGrid(pGrid, pDecoder, slice, part))<0) {
+    HLTError("failed to populate access grid for block %s 0x%09x: %d",
+            AliHLTComponent::DataType2Text(pDesc->fDataType).c_str(), pDesc->fSpecification, iResult);
+    return iResult;
+  }
 
+  if (fMode==1) {
+    fSingleBlock.SetDecoder(pDecoder);
+    fSingleBlock.SetGrid(pGrid);
+    fSingleBlock.SetId(decoderIndex);
+  } else {
+    fBlocks[decoderIndex]=AliHLTTPCHWCFSpacePointBlock(decoderIndex, pDecoder, pGrid);
+  }
   return count;
 }
 
+int AliHLTTPCHWCFSpacePointContainer::PopulateAccessGrid(AliHLTSpacePointGrid* pGrid, AliHLTUInt32_t mask) const
+{
+  // populate an access grid
+  if (!pGrid) return -EINVAL;
+
+  pGrid->Clear();
+  
+  AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(mask);
+  AliHLTUInt8_t partition  = AliHLTTPCDefinitions::GetMinPatchNr(mask);
+  AliHLTUInt32_t decoderIndex=AliHLTTPCSpacePointData::GetID(slice, partition, 0);
+  std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointBlock>::const_iterator block=fBlocks.find(decoderIndex);
+  if (block==fBlocks.end()) {
+    HLTError("can not find data block of id 0x%08x", mask);
+    return -ENOENT;
+  }
+  return PopulateAccessGrid(pGrid, block->second.GetDecoder(), slice, partition);
+}
+
+int AliHLTTPCHWCFSpacePointContainer::PopulateAccessGrid(AliHLTSpacePointGrid* pGrid, AliHLTTPCHWCFData* pDecoder,
+                                                        int slice, int partition) const
+{
+  // populate an access grid
+  if (!pDecoder) return -EINVAL;
+  int iResult=0;
+
+  if (pDecoder->GetNumberOfClusters()==0) return 0;
+  AliHLTTPCHWCFData::iterator cl=pDecoder->begin();
+  for (; cl!=pDecoder->end(); ++cl) {
+    iResult=pGrid->CountSpacePoint(cl.GetPadRow(), cl.GetPad(), cl.GetTime());
+    if (iResult<0)
+      HLTError("CountSpacePoint %f %f %f failed: %d", cl.GetPadRow(), cl.GetPad(), cl.GetTime(), iResult);
+  }
+  
+  int count=0;
+  cl=pDecoder->begin();
+  for (; cl!=pDecoder->end(); ++cl, count++) {
+    AliHLTUInt32_t id=AliHLTTPCSpacePointData::GetID(slice, partition, count);
+    iResult=pGrid->AddSpacePoint(id, cl.GetPadRow(), cl.GetPad(), cl.GetTime());
+    if (iResult<0)
+      HLTError("AddSpacePoint 0x%08x %f %f %f failed: %d", id, cl.GetPadRow(), cl.GetPad(), cl.GetTime(), iResult);
+  }
+
+  return 0;
+}
+
+const AliHLTSpacePointContainer::AliHLTSpacePointGrid* AliHLTTPCHWCFSpacePointContainer::GetAccessGrid(AliHLTUInt32_t mask) const
+{
+  // get the access grid for a data block
+  AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(mask);
+  AliHLTUInt8_t part  = AliHLTTPCDefinitions::GetMinPatchNr(mask);
+  AliHLTUInt32_t decoderIndex=AliHLTTPCSpacePointData::GetID(slice, part, 0);
+  std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointBlock>::const_iterator block=fBlocks.find(decoderIndex);
+  if (block==fBlocks.end()) {
+    HLTError("can not find data block of id 0x%08x", mask);
+    return NULL;
+  }
+  return block->second.GetGrid();
+}
+
 int AliHLTTPCHWCFSpacePointContainer::GetClusterIDs(vector<AliHLTUInt32_t>& tgt) const
 {
   // get array of cluster IDs
@@ -281,11 +391,15 @@ void AliHLTTPCHWCFSpacePointContainer::Clear(Option_t * option)
   }
   fSelections.clear();
 
-  for (std::vector<AliHLTTPCHWCFData*>::iterator decoder=fDecoders.begin();
-       decoder!=fDecoders.end(); decoder++) {
-    if (*decoder) delete *decoder;
+  for (std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointBlock>::iterator block=fBlocks.begin();
+       block!=fBlocks.end(); block++) {
+    if (block->second.GetDecoder()) delete block->second.GetDecoder();
+    if (block->second.GetGrid()) delete block->second.GetGrid();
   }
-  fDecoders.clear();
+  fBlocks.clear();
+
+  if (fSingleBlock.GetDecoder()) fSingleBlock.GetDecoder()->Reset();
+  if (fSingleBlock.GetGrid()) fSingleBlock.GetGrid()->Clear();
 
   AliHLTSpacePointContainer::Clear(option);
 }
@@ -297,7 +411,7 @@ void AliHLTTPCHWCFSpacePointContainer::Print(ostream& out, Option_t */*option*/)
   out << "n clusters: " << fClusters.size() << endl;
   for (std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.begin();
        cl!=fClusters.end(); cl++) {
-    out << " " << cl->first << cl->second << endl;
+    out << " 0x" << hex << setw(8) << setfill('0') << cl->first << dec << cl->second << endl;
   }
 }
 
@@ -413,7 +527,36 @@ int AliHLTTPCHWCFSpacePointContainer::Write(AliHLTUInt8_t* outputPtr,
                                            AliHLTComponentBlockDataList&
                                            outputBlocks,
                                            AliHLTDataDeflater* pDeflater,
-                                           const char* /*option*/) const
+                                           const char* option) const
+{
+  /// write blocks to HLT component output
+  AliHLTUInt32_t offset=0;
+  if (outputBlocks.size()>0) {
+    offset=outputBlocks.back().fOffset+outputBlocks.back().fSize;
+  }
+  return Write(outputPtr, size, offset, outputBlocks, pDeflater, option);
+}
+
+int AliHLTTPCHWCFSpacePointContainer::Write(AliHLTUInt8_t* outputPtr,
+                                           AliHLTUInt32_t size,
+                                           AliHLTUInt32_t offset,
+                                           AliHLTComponentBlockDataList&
+                                           outputBlocks,
+                                           AliHLTDataDeflater* pDeflater,
+                                           const char* option) const
+{
+  /// write blocks to HLT component output
+  if (fMode==0) return WriteUnsorted(outputPtr, size, offset, outputBlocks, pDeflater, option);
+  return WriteSorted(outputPtr, size, offset, outputBlocks, pDeflater, option);
+}
+
+int AliHLTTPCHWCFSpacePointContainer::WriteUnsorted(AliHLTUInt8_t* outputPtr,
+                                                   AliHLTUInt32_t size,
+                                                   AliHLTUInt32_t offset,
+                                                   AliHLTComponentBlockDataList&
+                                                   outputBlocks,
+                                                   AliHLTDataDeflater* pDeflater,
+                                                   const char* /*option*/) const
 {
   /// write blocks to HLT component output
   if (!outputPtr) return -EINVAL;
@@ -426,7 +569,7 @@ int AliHLTTPCHWCFSpacePointContainer::Write(AliHLTUInt8_t* outputPtr,
       AliHLTUInt32_t mask=AliHLTTPCSpacePointData::GetID(slice,part,0);
       // FIXME: make GetClusterIDs a const function and handle the cast there
       const vector<AliHLTUInt32_t>* collection=const_cast<AliHLTTPCHWCFSpacePointContainer*>(this)->GetClusterIDs(mask);
-      if (!collection) continue;
+      if (!collection || collection->size()==0) continue;
       if (size+sizeof(AliHLTTPCRawClusterData)+collection->size()*sizeof(AliHLTTPCRawCluster)>capacity) {
        ALIHLTERRORGUARD(1,"too little space to write cluster output block");
        iResult=-ENOSPC;
@@ -511,7 +654,7 @@ int AliHLTTPCHWCFSpacePointContainer::Write(AliHLTUInt8_t* outputPtr,
       }
       AliHLTComponent_BlockData bd;
       AliHLTComponent::FillBlockData(bd);
-      bd.fOffset        = size;
+      bd.fOffset        = size+offset;
       if (!pDeflater) {
        bd.fSize        = sizeof(AliHLTTPCRawClusterData)+blockout->fCount*sizeof(AliHLTTPCRawCluster);
       } else {
@@ -531,6 +674,151 @@ int AliHLTTPCHWCFSpacePointContainer::Write(AliHLTUInt8_t* outputPtr,
   return size;
 }
 
+int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
+                                                 AliHLTUInt32_t size,
+                                                 AliHLTUInt32_t offset,
+                                                 AliHLTComponentBlockDataList&
+                                                 outputBlocks,
+                                                 AliHLTDataDeflater* pDeflater,
+                                                 const char* option) const
+{
+  /// write blocks to HLT component output
+  int iResult=0;
+
+  if (fMode==1) {
+    iResult=WriteSorted(outputPtr, size, offset, fSingleBlock.GetDecoder(), fSingleBlock.GetGrid(), fSingleBlock.GetId(), outputBlocks, pDeflater, option);
+  } else {
+    for (std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointBlock>::const_iterator block=fBlocks.begin();
+        block!=fBlocks.end() && iResult>=0; block++) {
+      AliHLTTPCHWCFData* pDecoder=block->second.GetDecoder();
+      AliHLTSpacePointGrid* pGrid=block->second.GetGrid();
+      AliHLTUInt32_t mask=block->first;
+      iResult=WriteSorted(outputPtr, size, offset, pDecoder, pGrid, mask, outputBlocks, pDeflater, option);
+    }
+  }
+  return iResult;
+}
+
+int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
+                                                 AliHLTUInt32_t size,
+                                                 AliHLTUInt32_t offset,
+                                                 AliHLTTPCHWCFData* pDecoder,
+                                                 AliHLTSpacePointGrid* pGrid,
+                                                 AliHLTUInt32_t mask,
+                                                 AliHLTComponentBlockDataList&
+                                                 outputBlocks,
+                                                 AliHLTDataDeflater* pDeflater,
+                                                 const char* /*option*/) const
+{
+  /// write blocks to HLT component output
+  if (!outputPtr || !pDecoder || !pGrid) return -EINVAL;
+  if (pDecoder->GetNumberOfClusters()==0) return 0;
+  int iResult=0;
+  AliHLTUInt32_t capacity=size;
+  size=0;
+
+  int slice=AliHLTTPCSpacePointData::GetSlice(mask);
+  int part=AliHLTTPCSpacePointData::GetPatch(mask);
+
+  AliHLTTPCRawClusterData* blockout=reinterpret_cast<AliHLTTPCRawClusterData*>(outputPtr+size);
+  blockout->fVersion=0;
+  blockout->fCount=0;
+
+  if (pDeflater) {
+    pDeflater->Clear();
+    pDeflater->InitBitDataOutput(reinterpret_cast<AliHLTUInt8_t*>(blockout->fClusters), capacity-size-sizeof(AliHLTTPCRawClusterData));
+    blockout->fVersion=pDeflater->GetDeflaterVersion();
+  }
+
+  unsigned lastPadRow=0;
+  AliHLTSpacePointGrid::iterator clusterID=pGrid->begin();
+  if (clusterID!=pGrid->end()) {
+    for (; clusterID!=pGrid->end(); clusterID++) {
+      if ((unsigned)slice!=AliHLTTPCSpacePointData::GetSlice(clusterID.Data()) ||
+         (unsigned)part!=AliHLTTPCSpacePointData::GetPatch(clusterID.Data())) {
+       HLTError("cluster index 0x%08x out of slice %d partition %d", clusterID.Data(), slice, part);
+      }
+      int index=AliHLTTPCSpacePointData::GetNumber(clusterID.Data());
+      int padrow=pDecoder->GetPadRow(index);
+      if (padrow<0) {
+       // something wrong here, padrow is stored in the cluster header
+       // word which has bit pattern 0x3 in bits bit 30 and 31 which was
+       // not recognized
+       ALIHLTERRORGUARD(1, "can not read cluster header word");
+       break;
+      }
+
+      // FIXME: the HW ClusterFinder returns only the sum
+      // sum(q_i*pad_i*pad_i)/sum(q_i)
+      // where the mean needs to be subtracted, not yet in the decoder
+      // but should be implemented there
+      float pad =pDecoder->GetPad(index);
+      float time =pDecoder->GetTime(index);
+      float sigmaY2=pDecoder->GetSigmaY2(index);
+      float sigmaZ2=pDecoder->GetSigmaZ2(index);
+      sigmaY2-=pad*pad;
+      sigmaZ2-=time*time;
+
+      if (!pDeflater) {
+       AliHLTTPCRawCluster& c=blockout->fClusters[blockout->fCount];
+       padrow+=AliHLTTPCTransform::GetFirstRow(part);
+       c.SetPadRow(padrow);
+       c.SetCharge(pDecoder->GetCharge(index));
+       c.SetPad(pad);  
+       c.SetTime(time);
+       c.SetSigmaY2(sigmaY2);
+       c.SetSigmaZ2(sigmaZ2);
+       c.SetQMax(pDecoder->GetQMax(index));
+      } else {
+       AliHLTUInt64_t padrow64=pDecoder->GetPadRow(index);
+       if (padrow64==lastPadRow) {
+         padrow64-=lastPadRow;
+       } else if (padrow64>lastPadRow) {
+         padrow64-=lastPadRow;
+         lastPadRow+=padrow64;
+       } else {
+         AliFatal("padrows not ordered");
+       }
+
+       AliHLTUInt64_t pad64
+         =(AliHLTUInt64_t)round(pad*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kPad].fScale);
+       AliHLTUInt64_t time64
+         =(AliHLTUInt64_t)round(time*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kTime].fScale);
+       AliHLTUInt64_t sigmaY264
+         =(AliHLTUInt64_t)round(sigmaY2*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaY2].fScale);
+       AliHLTUInt64_t sigmaZ264
+         =(AliHLTUInt64_t)round(sigmaZ2*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaZ2].fScale);
+       pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPadRow , padrow64);
+       pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPad    , pad64);  
+       pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kTime   , time64);
+       pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaY2, sigmaY264);
+       pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaZ2, sigmaZ264);
+       pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kCharge , pDecoder->GetCharge(index));
+       pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kQMax   , pDecoder->GetQMax(index));
+      }
+      blockout->fCount++;
+    }
+  }
+  AliHLTComponent_BlockData bd;
+  AliHLTComponent::FillBlockData(bd);
+  bd.fOffset        = size+offset;
+  if (!pDeflater) {
+    bd.fSize        = sizeof(AliHLTTPCRawClusterData)+blockout->fCount*sizeof(AliHLTTPCRawCluster);
+  } else {
+    pDeflater->Pad8Bits();
+    bd.fSize        = sizeof(AliHLTTPCRawClusterData)+pDeflater->GetBitDataOutputSizeBytes();
+    pDeflater->CloseBitDataOutput();
+  }
+  bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, part, part);
+  bd.fDataType      = AliHLTTPCDefinitions::fgkRawClustersDataType;
+  outputBlocks.push_back(bd);
+      
+  size += bd.fSize;
+
+  if (iResult<0) return iResult;
+  return size;
+}
+
 AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::AliHLTTPCHWCFSpacePointProperties()
   : fDecoder(NULL)
   , fIndex(-1)
@@ -582,9 +870,14 @@ void AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::Print(
     return;
   }
   const AliHLTTPCHWCFData* decoder=Decoder();
-  out << " " << decoder->GetPadRow(fIndex) << " " << decoder->GetPad(fIndex) << " " << decoder->GetTime(fIndex)
-      << " " << decoder->GetSigmaY2(fIndex) << " "  << decoder->GetSigmaZ2(fIndex)
-      << " " << decoder->GetCharge(fIndex) << " "  << decoder->GetQMax(fIndex)
+  out.setf(ios::fixed,ios::floatfield);
+  out << " " << setfill(' ') << setw(3) << decoder->GetPadRow(fIndex) 
+      << " " << setw(8) << setprecision(3) << decoder->GetPad(fIndex)
+      << " " << setw(8) << setprecision(3) << decoder->GetTime(fIndex)
+      << " " << setw(8) << setprecision(1) << decoder->GetSigmaY2(fIndex) 
+      << " " << setw(9) << setprecision(1) << decoder->GetSigmaZ2(fIndex)
+      << " " << setw(5) << decoder->GetCharge(fIndex) 
+      << " " << setw(5) << decoder->GetQMax(fIndex)
       << " " << fTrackId << " " << fMCId << " " << fUsed;
 }
 
index fb7b500..a5c8887 100644 (file)
@@ -29,7 +29,7 @@ class AliHLTTPCHWCFSpacePointContainer : public AliHLTSpacePointContainer
 {
  public:
   /// standard constructor
-  AliHLTTPCHWCFSpacePointContainer();
+  AliHLTTPCHWCFSpacePointContainer(int mode=0);
   /// copy constructor
   AliHLTTPCHWCFSpacePointContainer(const AliHLTTPCHWCFSpacePointContainer& c);
   /// assignment operator
@@ -52,6 +52,10 @@ class AliHLTTPCHWCFSpacePointContainer : public AliHLTSpacePointContainer
   /// add input block to the collection
   virtual int AddInputBlock(const AliHLTComponentBlockData* pDesc);
 
+  virtual int PopulateAccessGrid(AliHLTSpacePointGrid* pGrid, AliHLTUInt32_t mask) const;
+  int PopulateAccessGrid(AliHLTSpacePointGrid* pGrid, AliHLTTPCHWCFData* pDecoder, int slice, int partition) const;
+  virtual const AliHLTSpacePointGrid* GetAccessGrid(AliHLTUInt32_t /*mask*/) const;
+
   /// clear the object and reset pointer references
   virtual void Clear(Option_t * option ="");
 
@@ -82,6 +86,27 @@ class AliHLTTPCHWCFSpacePointContainer : public AliHLTSpacePointContainer
                    vector<AliHLTComponentBlockData>& outputBlocks,
                    AliHLTDataDeflater* pDeflater,
                    const char* option="") const;
+  virtual int Write(AliHLTUInt8_t* outputPtr, AliHLTUInt32_t size, AliHLTUInt32_t offset,
+                   vector<AliHLTComponentBlockData>& outputBlocks,
+                   AliHLTDataDeflater* pDeflater,
+                   const char* option="") const;
+
+  int WriteUnsorted(AliHLTUInt8_t* outputPtr, AliHLTUInt32_t size, AliHLTUInt32_t offset,
+                   vector<AliHLTComponentBlockData>& outputBlocks,
+                   AliHLTDataDeflater* pDeflater,
+                   const char* option="") const;
+
+  int WriteSorted(AliHLTUInt8_t* outputPtr, AliHLTUInt32_t size, AliHLTUInt32_t offset,
+                 vector<AliHLTComponentBlockData>& outputBlocks,
+                 AliHLTDataDeflater* pDeflater,
+                 const char* option="") const;
+
+  int WriteSorted(AliHLTUInt8_t* outputPtr, AliHLTUInt32_t size, AliHLTUInt32_t offset,
+                 AliHLTTPCHWCFData* pDecoder, AliHLTSpacePointGrid* pGrid,
+                 AliHLTUInt32_t mask,
+                 vector<AliHLTComponentBlockData>&  outputBlocks,
+                 AliHLTDataDeflater* pDeflater,
+                 const char* option) const;
 
   class AliHLTTPCHWCFSpacePointProperties {
   public:
@@ -111,6 +136,31 @@ class AliHLTTPCHWCFSpacePointContainer : public AliHLTSpacePointContainer
     int fMCId; //! MC id
   };
 
+  class AliHLTTPCHWCFSpacePointBlock {
+  public:
+    AliHLTTPCHWCFSpacePointBlock(AliHLTUInt32_t id=0, AliHLTTPCHWCFData* pDecoder=NULL, AliHLTSpacePointGrid* pGrid=NULL)
+      : fDecoder(pDecoder), fGrid(pGrid), fId(id) {}
+    AliHLTTPCHWCFSpacePointBlock(const AliHLTTPCHWCFSpacePointBlock& s) 
+      : fDecoder(s.fDecoder), fGrid(s.fGrid), fId(s.fId) {}
+    AliHLTTPCHWCFSpacePointBlock& operator=(const AliHLTTPCHWCFSpacePointBlock& s) 
+    { fDecoder=s.fDecoder; fGrid=s.fGrid; fId=s.fId; return *this;}
+    ~AliHLTTPCHWCFSpacePointBlock() {}
+
+    int GetNofSpacepoints() const {return fDecoder?fDecoder->GetNumberOfClusters():0;}
+    AliHLTUInt32_t GetId() const {return fId;}
+    void SetId(AliHLTUInt32_t id) {fId=id;}
+    AliHLTTPCHWCFData* GetDecoder() const {return fDecoder;} 
+    void SetDecoder(AliHLTTPCHWCFData* pDecoder) {fDecoder=pDecoder;}
+    AliHLTSpacePointGrid* GetGrid() const {return fGrid;}
+    void SetGrid(AliHLTSpacePointGrid* pGrid) {fGrid=pGrid;}
+
+  protected:
+  private:
+    AliHLTTPCHWCFData* fDecoder; //!
+    AliHLTSpacePointGrid* fGrid; //!
+    AliHLTUInt32_t fId; //!
+  };
+
  protected:
 
  private:
@@ -121,7 +171,13 @@ class AliHLTTPCHWCFSpacePointContainer : public AliHLTSpacePointContainer
   std::map<AliHLTUInt32_t, vector<AliHLTUInt32_t>*> fSelections; //!
 
   /// array of decoders
-  std::vector<AliHLTTPCHWCFData*> fDecoders; //!
+  std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointBlock> fBlocks; //!
+
+  /// the one instance for mode single (=1)
+  AliHLTTPCHWCFSpacePointBlock fSingleBlock;
+
+  /// mode
+  int fMode; //!
 
   ClassDef(AliHLTTPCHWCFSpacePointContainer, 0)
 };
index b1f8de3..2399b43 100644 (file)
@@ -125,33 +125,11 @@ int AliHLTTPCDataCompressionComponent::DoEvent( const AliHLTComponentEventData&
   vector<AliHLTGlobalBarrelTrack> inputTrackArray;
 
   if (GetBenchmarkInstance()) {
-    GetBenchmarkInstance()->Start(1);
-  }
-  for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkHWClustersDataType);
-       pDesc!=NULL; pDesc=GetNextInputBlock()) {
-    if (GetBenchmarkInstance()) {
-      GetBenchmarkInstance()->AddInput(pDesc->fSize);
-    }
-    AliHLTUInt8_t slice = 0;
-    AliHLTUInt8_t patch = 0;
-    slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
-    patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
-    if ( minSlice==0xFF || slice<minSlice )    minSlice = slice;
-    if ( maxSlice==0xFF || slice>maxSlice )    maxSlice = slice;
-    if ( minPatch==0xFF || patch<minPatch )    minPatch = patch;
-    if ( maxPatch==0xFF || patch>maxPatch )    maxPatch = patch;
-    if (fRawInputClusters) {
-      fRawInputClusters->AddInputBlock(pDesc);
-    }
-    inputRawClusterSize+=pDesc->fSize;
-  }
-  if (GetBenchmarkInstance()) {
-    GetBenchmarkInstance()->Stop(1);
     GetBenchmarkInstance()->Start(2);
   }
 
   // transformed clusters
-  if (fMode==1) { // FIXME: condition to be adjusted
+  if (fMode==10) { // FIXME: condition to be adjusted
     for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkClustersDataType);
         pDesc!=NULL; pDesc=GetNextInputBlock()) {
       if (GetBenchmarkInstance()) {
@@ -176,7 +154,7 @@ int AliHLTTPCDataCompressionComponent::DoEvent( const AliHLTComponentEventData&
   }
 
   // track data input
-  if (fMode==1) { // FIXME: condition to be adjusted
+  if (fMode==2) { // FIXME: condition to be adjusted
     for (pDesc=GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC);
         pDesc!=NULL; pDesc=GetNextInputBlock()) {
       if (GetBenchmarkInstance()) {
@@ -228,13 +206,39 @@ int AliHLTTPCDataCompressionComponent::DoEvent( const AliHLTComponentEventData&
     GetBenchmarkInstance()->Start(5);
   }
 
-  // output
-  if (fMode==0) {
+  // loop over raw cluster blocks, assign to tracks and write
+  // unassigned clusters
+  for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkHWClustersDataType);
+       pDesc!=NULL; pDesc=GetNextInputBlock()) {
+    if (GetBenchmarkInstance()) {
+      GetBenchmarkInstance()->Start(1);
+      GetBenchmarkInstance()->AddInput(pDesc->fSize);
+    }
+    AliHLTUInt8_t slice = 0;
+    AliHLTUInt8_t patch = 0;
+    slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
+    patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
+    if ( minSlice==0xFF || slice<minSlice )    minSlice = slice;
+    if ( maxSlice==0xFF || slice>maxSlice )    maxSlice = slice;
+    if ( minPatch==0xFF || patch<minPatch )    minPatch = patch;
+    if ( maxPatch==0xFF || patch>maxPatch )    maxPatch = patch;
+    if (fRawInputClusters) {
+      fRawInputClusters->AddInputBlock(pDesc);
+    }
+    if (GetBenchmarkInstance()) {
+      GetBenchmarkInstance()->Stop(1);
+      GetBenchmarkInstance()->Start(5);
+    }
+    inputRawClusterSize+=pDesc->fSize;
     iResult=fRawInputClusters->Write(outputPtr+size, capacity-size, outputBlocks, fpDataDeflater);
     if (iResult>=0) {
       size+=iResult;
       if (GetBenchmarkInstance()) GetBenchmarkInstance()->AddOutput(iResult);
     }
+    if (GetBenchmarkInstance()) {
+      GetBenchmarkInstance()->Stop(5);
+    }
+    fRawInputClusters->Clear();
   }
 
   float compressionFactor=(float)inputRawClusterSize;
@@ -243,7 +247,6 @@ int AliHLTTPCDataCompressionComponent::DoEvent( const AliHLTComponentEventData&
   if (fHistoCompFactor) fHistoCompFactor->Fill(compressionFactor);
 
   if (GetBenchmarkInstance()) {
-    GetBenchmarkInstance()->Stop(5);
     GetBenchmarkInstance()->Stop(0);
     HLTBenchmark("%s - compression factor %.2f", GetBenchmarkInstance()->GetStatistics(), compressionFactor);
   }
@@ -297,7 +300,7 @@ int AliHLTTPCDataCompressionComponent::DoInit( int argc, const char** argv )
     return -ENOMEM;
   }
 
-  std::auto_ptr<AliHLTTPCHWCFSpacePointContainer> rawInputClusters(new AliHLTTPCHWCFSpacePointContainer);
+  std::auto_ptr<AliHLTTPCHWCFSpacePointContainer> rawInputClusters(new AliHLTTPCHWCFSpacePointContainer(1));
   std::auto_ptr<AliHLTTPCSpacePointContainer> inputClusters(new AliHLTTPCSpacePointContainer);
   std::auto_ptr<TH1F> histoCompFactor(new TH1F("factor", "HLT TPC data compression factor", 100, 0, 10));