]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/TPCLib/AliHLTTPCHWCFSpacePointContainer.cxx
ALIROOT-5433 Transition to CDHv3 in HLT
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCHWCFSpacePointContainer.cxx
index 9da0a7c878ec5d682a1385e3fd3b98c210e041e5..5e90b14dea2b10e7424cd6bea9e4ed996a57e4fa 100644 (file)
@@ -33,7 +33,7 @@
 #include "AliHLTComponent.h"
 #include "AliHLTTemplates.h"
 #include "AliHLTDataDeflater.h"
-#include "AliRawDataHeader.h"
+#include "AliHLTCDHWrapper.h"
 #include "AliLog.h"
 #include "TMath.h"
 #include <memory>
@@ -54,13 +54,14 @@ AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointContainer(int mode)
   , fBlocks()
   , fSingleBlock()
   , fMode(mode)
+  , fWrittenClusterIds(NULL)
 {
   // 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) {
+  if (fMode&kModeSingle) {
     fSingleBlock.SetDecoder(new AliHLTTPCHWCFData);
     fSingleBlock.SetGrid(AllocateIndexGrid());
   }
@@ -73,6 +74,7 @@ AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointContainer(const AliHLTT
   , fBlocks()
   , fSingleBlock()
   , fMode(c.fMode)
+  , fWrittenClusterIds(NULL)
 {
   /// copy constructor
 }
@@ -84,6 +86,7 @@ AliHLTTPCHWCFSpacePointContainer& AliHLTTPCHWCFSpacePointContainer::operator=(co
   AliHLTSpacePointContainer::operator=(c);
   fClusters=c.fClusters;
   fMode=c.fMode;
+  fWrittenClusterIds=NULL;
 
   return *this;
 }
@@ -94,6 +97,7 @@ AliHLTTPCHWCFSpacePointContainer::~AliHLTTPCHWCFSpacePointContainer()
   Clear();
   if (fSingleBlock.GetDecoder()) delete fSingleBlock.GetDecoder();
   if (fSingleBlock.GetGrid()) delete fSingleBlock.GetGrid();
+  if (fWrittenClusterIds) delete fWrittenClusterIds;
 }
 
 int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockData* pDesc)
@@ -107,7 +111,8 @@ int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockDa
     return 0;
   }
   if (!pDesc->fPtr) return -ENODATA;
-  if (pDesc->fSize<=sizeof(AliRawDataHeader)) return 0;
+  AliHLTCDHWrapper header(pDesc->fPtr);
+  if (pDesc->fSize<=header.GetHeaderSize()) return 0;
 
   AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
   AliHLTUInt8_t part  = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
@@ -115,13 +120,13 @@ int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockDa
   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);
+  // skip the first 8 or 10 CDH words
+  buffer += header.GetHeaderSize()/sizeof(AliHLTUInt32_t);
+  UInt_t bufferSize32 = ((Int_t)pDesc->fSize - header.GetHeaderSize() )/sizeof(AliHLTUInt32_t);
 
   AliHLTTPCHWCFData* pDecoder=NULL;
   AliHLTSpacePointPropertyGrid* pGrid=NULL;
-  if (fMode==1) {
+  if (fMode&kModeSingle) {
     pDecoder=fSingleBlock.GetDecoder();
     pGrid=fSingleBlock.GetGrid();
   } else {
@@ -137,13 +142,13 @@ int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockDa
   }
 
   if (pDecoder->Init(reinterpret_cast<AliHLTUInt8_t*>(buffer), bufferSize32*sizeof(AliHLTUInt32_t))<0 ||
-      (pDecoder->CheckVersion()<0 && (int)bufferSize32>pDecoder->GetRCUTrailerSize())) {
+      (pDecoder->CheckVersion()<0 && (int)(bufferSize32*sizeof(AliHLTUInt32_t))>pDecoder->GetRCUTrailerSize())) {
     HLTError("data block of type %s corrupted: can not decode format",
             AliHLTComponent::DataType2Text(pDesc->fDataType).c_str());
     return -EBADMSG;
   }
 
-  if (fMode==1 && !pGrid) {
+  if (fMode&kModeSingle && !pGrid) {
     pGrid=AllocateIndexGrid();
     if (!pGrid) {
       delete pDecoder;
@@ -151,7 +156,7 @@ int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockDa
     }
   }
 
-  if (fMode==0) { // register immediately
+  if (fMode&kModeCreateMap) { // register immediately
   UInt_t nofClusters=pDecoder->GetNumberOfClusters();
 
   for (UInt_t i=0; i<nofClusters; i++) {
@@ -176,7 +181,7 @@ int AliHLTTPCHWCFSpacePointContainer::AddInputBlock(const AliHLTComponentBlockDa
     return iResult;
   }
 
-  if (fMode==1) {
+  if (fMode&kModeSingle) {
     fSingleBlock.SetDecoder(pDecoder);
     fSingleBlock.SetGrid(pGrid);
     fSingleBlock.SetId(decoderIndex);
@@ -191,9 +196,12 @@ AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* AliHLTTPCHWCFSpacePoint
   // allocate index grid, one single point to define the dimensions
   
   // max 33 padrows, step 1 padrow
-  // max 139 pads, step 8 pads
-  // max 1024 time bins, step 10 timebins
-  return new AliHLTSpacePointPropertyGrid(33, 1.0, 140, 8, 1024, 10);
+  // max 140 pads, step 2x max delta pad
+  // max 1024 time bins, step 2x max delta time
+  return new AliHLTSpacePointPropertyGrid(33, 1.0,
+                                         140, 2*AliHLTTPCDefinitions::GetMaxClusterDeltaPad(),
+                                         1024, 2*AliHLTTPCDefinitions::GetMaxClusterDeltaTime()
+                                         );
 }
 
 int AliHLTTPCHWCFSpacePointContainer::PopulateAccessGrid(AliHLTSpacePointPropertyGrid* pGrid, AliHLTUInt32_t mask) const
@@ -402,6 +410,16 @@ float AliHLTTPCHWCFSpacePointContainer::GetCharge(AliHLTUInt32_t clusterID) cons
   return cl->second.Decoder()->GetCharge(index);
 }
 
+float AliHLTTPCHWCFSpacePointContainer::GetQMax(AliHLTUInt32_t clusterID) const
+{
+  // get charge
+  std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(clusterID);
+  if (cl==fClusters.end() ||
+      cl->second.Decoder()==NULL) return 0.0;
+  int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
+  return cl->second.Decoder()->GetQMax(index);
+}
+
 float AliHLTTPCHWCFSpacePointContainer::GetPhi(AliHLTUInt32_t clusterID) const
 {
   // get charge
@@ -446,7 +464,7 @@ void AliHLTTPCHWCFSpacePointContainer::Print(ostream& out, Option_t */*option*/)
        cl!=fClusters.end(); cl++) {
     str << " 0x" << hex << setw(8) << setfill('0') << cl->first << dec << cl->second << endl;
   }
-  out << str;
+  out << str.str();
 }
 
 AliHLTSpacePointContainer* AliHLTTPCHWCFSpacePointContainer::SelectByMask(AliHLTUInt32_t mask, bool /*bAlloc*/) const
@@ -580,134 +598,9 @@ int AliHLTTPCHWCFSpacePointContainer::Write(AliHLTUInt8_t* outputPtr,
                                            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;
-  int iResult=0;
-  AliHLTUInt32_t capacity=size;
-  size=0;
-
-  for (int slice=0; slice<AliHLTTPCTransform::GetNSlice() && iResult>=0; slice++) {
-    for (int part=0; part<AliHLTTPCTransform::GetNPatches() && iResult>=0; part++) {
-      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 || 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;
-       break;
-      }
-      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;
-      vector<AliHLTUInt32_t>::const_iterator clusterID=collection->begin();
-      if (clusterID!=collection->end()) {
-       std::map<AliHLTUInt32_t, AliHLTTPCHWCFSpacePointProperties>::const_iterator cl=fClusters.find(*clusterID);
-       for (; clusterID!=collection->end(); clusterID++, (cl!=fClusters.end())?cl++:cl) {
-         if (cl!=fClusters.end() && cl->first!=*clusterID) cl=fClusters.find(*clusterID);
-         if (cl==fClusters.end() || cl->second.Decoder()==NULL) continue;
-         int index=AliHLTTPCSpacePointData::GetNumber(cl->first);
-         int padrow=cl->second.Decoder()->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 =cl->second.Decoder()->GetPad(index);
-         float time =cl->second.Decoder()->GetTime(index);
-         float sigmaY2=cl->second.Decoder()->GetSigmaY2(index);
-         float sigmaZ2=cl->second.Decoder()->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(cl->second.Decoder()->GetCharge(index));
-           c.SetPad(pad);  
-           c.SetTime(time);
-           c.SetSigmaY2(sigmaY2);
-           c.SetSigmaZ2(sigmaZ2);
-           c.SetQMax(cl->second.Decoder()->GetQMax(index));
-         } else {
-           AliHLTUInt64_t padrow64=cl->second.Decoder()->GetPadRow(index);
-           // enable if padrows are ordered
-           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 , cl->second.Decoder()->GetCharge(index));
-           pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kQMax   , cl->second.Decoder()->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;
-}
-
 int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
                                                  AliHLTUInt32_t size,
                                                  AliHLTUInt32_t offset,
@@ -719,7 +612,7 @@ int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
   /// write blocks to HLT component output
   int iResult=0;
 
-  if (fMode==1) {
+  if (fMode&kModeSingle) {
     iResult=WriteSorted(outputPtr, size, offset, fSingleBlock.GetDecoder(), fSingleBlock.GetGrid(), fSingleBlock.GetId(), outputBlocks, pDeflater, option);
   } else {
     iResult=-ENOENT;
@@ -750,11 +643,18 @@ int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
                                                  AliHLTComponentBlockDataList&
                                                  outputBlocks,
                                                  AliHLTDataDeflater* pDeflater,
-                                                 const char* /*option*/) const
+                                                 const char* option) const
 {
   /// write blocks to HLT component output
   if (!outputPtr || !pDecoder || !pGrid) return -EINVAL;
   if (pDecoder->GetNumberOfClusters()==0) return 0;
+  if (option) {
+    // this is only for sending mc labels in simulation and testing
+    // no impact to real running
+    if (!fWrittenClusterIds && strcmp(option, "write-cluster-ids")==0) {
+      const_cast<AliHLTTPCHWCFSpacePointContainer*>(this)->fWrittenClusterIds=new vector<AliHLTUInt32_t>;
+    }
+  }
   int iResult=0;
   AliHLTUInt32_t capacity=size;
   size=0;
@@ -762,6 +662,8 @@ int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
   int slice=AliHLTTPCSpacePointData::GetSlice(mask);
   int part=AliHLTTPCSpacePointData::GetPatch(mask);
 
+  // Note: the offset parameter is only for the block descriptors, output pointer and size
+  // consider already the offset
   AliHLTTPCRawClusterData* blockout=reinterpret_cast<AliHLTTPCRawClusterData*>(outputPtr+size);
   blockout->fVersion=0;
   blockout->fCount=0;
@@ -770,12 +672,23 @@ int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
     pDeflater->Clear();
     pDeflater->InitBitDataOutput(reinterpret_cast<AliHLTUInt8_t*>(blockout->fClusters), capacity-size-sizeof(AliHLTTPCRawClusterData));
     blockout->fVersion=pDeflater->GetDeflaterVersion();
+    if (fMode&kModeDifferentialPadTime) blockout->fVersion+=2;
   }
 
   unsigned lastPadRow=0;
+  AliHLTUInt64_t lastPad64=0;
+  AliHLTUInt64_t lastTime64=0;
   AliHLTSpacePointPropertyGrid::iterator clusterID=pGrid->begin();
   if (clusterID!=pGrid->end()) {
     for (; clusterID!=pGrid->end(); clusterID++) {
+      if (clusterID.Data().fTrackId>-1) {
+       // this is an assigned cluster, skip
+       // TODO: introduce selectors into AliHLTIndexGrid::begin to loop
+       // consistently over entries, e.g. this check has to be done also
+       // in the forwarding of MC labels in
+       // AliHLTTPCDataCompressionComponent::ForwardMCLabels
+       continue;
+      }
       if ((unsigned)slice!=AliHLTTPCSpacePointData::GetSlice(clusterID.Data().fId) ||
          (unsigned)part!=AliHLTTPCSpacePointData::GetPatch(clusterID.Data().fId)) {
        HLTError("cluster index 0x%08x out of slice %d partition %d", clusterID.Data().fId, slice, part);
@@ -783,6 +696,7 @@ int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
       int index=AliHLTTPCSpacePointData::GetNumber(clusterID.Data().fId);
       const AliHLTTPCHWCFData::iterator& input=pDecoder->find(index);
       if (!(input!=pDecoder->end())) continue;
+      if (fWrittenClusterIds) fWrittenClusterIds->push_back(clusterID.Data().fId);
       int padrow=input.GetPadRow();
       if (padrow<0) {
        // something wrong here, padrow is stored in the cluster header
@@ -793,17 +707,10 @@ int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
        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 =input.GetPad();
       float time =input.GetTime();
       float sigmaY2=input.GetSigmaY2();
       float sigmaZ2=input.GetSigmaZ2();
-      sigmaY2-=pad*pad;
-      sigmaZ2-=time*time;
-
       if (!pDeflater) {
        AliHLTTPCRawCluster& c=blockout->fClusters[blockout->fCount];
        padrow+=AliHLTTPCTransform::GetFirstRow(part);
@@ -825,18 +732,58 @@ int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
          AliFatal("padrows not ordered");
        }
 
+       AliHLTUInt32_t padType=0;
+       AliHLTUInt32_t signdPad=0;
        AliHLTUInt64_t pad64=0;
+       if ((fMode&kModeDifferentialPadTime)!=0 && sigmaY2<.00001) {
+         // single pad cluster
+         // use twice the pad position to take account for the 0.5 offset
+         // added in the AliHLTTPCHWCFData decoder in accordance with the
+         // offline definition. Using the factor 2, this offset is not
+         // cut off by rounding
+         pad64=(AliHLTUInt64_t)round(2*pad);
+         padType=1;
+       } else {
        if (!isnan(pad)) pad64=(AliHLTUInt64_t)round(pad*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kPad].fScale);
+       }
+       if (fMode&kModeDifferentialPadTime && padType==0) {
+         AliHLTUInt64_t dpad64=0;
+         if (pad64<lastPad64) {
+           dpad64=lastPad64-pad64;
+           signdPad=1;
+         } else {
+           dpad64=pad64-lastPad64;
+           signdPad=0;
+         }
+         lastPad64=pad64;
+         pad64=dpad64;
+       }
+       AliHLTUInt32_t signdTime=0;
        AliHLTUInt64_t time64=0;
        if (!isnan(time)) time64=(AliHLTUInt64_t)round(time*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kTime].fScale);
+       if (fMode&kModeDifferentialPadTime) {
+         AliHLTUInt64_t dtime64=0;
+         if (time64<lastTime64) {
+           dtime64=lastTime64-time64;
+           signdTime=1;
+         } else {
+           dtime64=time64-lastTime64;
+           signdTime=0;
+         }
+         lastTime64=time64;
+         time64=dtime64;
+       }
        AliHLTUInt64_t sigmaY264=0;
        if (!isnan(sigmaY2)) sigmaY264=(AliHLTUInt64_t)round(sigmaY2*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaY2].fScale);
        AliHLTUInt64_t sigmaZ264=0;
        if (!isnan(sigmaZ2)) sigmaZ264=(AliHLTUInt64_t)round(sigmaZ2*AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kSigmaZ2].fScale);
        pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPadRow , padrow64);
-       pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPad    , pad64);  
+       pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kPad    , pad64);
+       if (fMode&kModeDifferentialPadTime) pDeflater->OutputBit(padType);
+       if (fMode&kModeDifferentialPadTime && padType==0) pDeflater->OutputBit(signdPad);
        pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kTime   , time64);
-       pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaY2, sigmaY264);
+       if (fMode&kModeDifferentialPadTime) pDeflater->OutputBit(signdTime);
+       if (padType==0) pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaY2, sigmaY264);
        pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kSigmaZ2, sigmaZ264);
        pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kCharge , input.GetCharge());
        pDeflater->OutputParameterBits(AliHLTTPCDefinitions::kQMax   , input.GetQMax());
@@ -858,9 +805,25 @@ int AliHLTTPCHWCFSpacePointContainer::WriteSorted(AliHLTUInt8_t* outputPtr,
   }
   bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, part, part);
   outputBlocks.push_back(bd);
-      
+
   size += bd.fSize;
 
+  if (fWrittenClusterIds && fWrittenClusterIds->size()>0) {
+    AliHLTComponent::FillBlockData(bd);
+    bd.fOffset        = size+offset;
+    bd.fSize        = fWrittenClusterIds->size()*sizeof(vector<AliHLTUInt32_t>::value_type);
+    if (bd.fSize+size<=capacity) {
+      memcpy(outputPtr+size, &(*fWrittenClusterIds)[0], bd.fSize);
+      bd.fDataType    = AliHLTTPCDefinitions::RemainingClusterIdsDataType();
+      bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(slice, slice, part, part);
+      outputBlocks.push_back(bd);    
+      size += bd.fSize;
+    } else {
+      iResult=-ENOSPC;
+    }
+    fWrittenClusterIds->clear();
+  }
+
   if (iResult<0) return iResult;
   return size;
 }
@@ -926,7 +889,7 @@ void AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties::Print(
       << " " << setw(5) << decoder->GetCharge(fIndex) 
       << " " << setw(5) << decoder->GetQMax(fIndex)
       << " " << fTrackId << " " << fMCId << " " << fUsed;
-  out << str;
+  out << str.str();
 }
 
 ostream& operator<<(ostream &out, const AliHLTTPCHWCFSpacePointContainer::AliHLTTPCHWCFSpacePointProperties& p)