adding AliHLTAltroGenerator including unit test for simulation of Altro data and...
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 17 Mar 2008 12:06:30 +0000 (12:06 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 17 Mar 2008 12:06:30 +0000 (12:06 +0000)
13 files changed:
HLT/Makefile.am
HLT/RCU/AliHLTAltroGenerator.cxx [new file with mode: 0644]
HLT/RCU/AliHLTAltroGenerator.h [new file with mode: 0644]
HLT/RCU/test/Makefile.am
HLT/RCU/test/testAliHLTAltroEncoder.C
HLT/RCU/test/testAliHLTAltroGenerator.C [new file with mode: 0644]
HLT/TPCLib/AliHLTTPCDigitReader.cxx
HLT/TPCLib/Makefile.am
HLT/TPCLib/test/Makefile.am [new file with mode: 0644]
HLT/TPCLib/test/testAliHLTTPCDigitReaderDecoder.C [new file with mode: 0644]
HLT/TPCLib/test/testAliHLTTPCDigitReaderPacked.C [new file with mode: 0644]
HLT/configure.ac
HLT/libAliHLTRCU.pkg

index 0863954..ee0e5a9 100644 (file)
@@ -42,9 +42,9 @@ SUBDIRS               = BASE \
                          sim \
                          rec \
                          shuttle \
+                         $(RCU_DIR) \
                          $(SAMPLE_DIR) \
                          $(TPC_DIR) \
-                         $(RCU_DIR) \
                          $(PHOS_DIR) \
                          $(TRD_DIR) \
                          $(MUON_DIR) \
diff --git a/HLT/RCU/AliHLTAltroGenerator.cxx b/HLT/RCU/AliHLTAltroGenerator.cxx
new file mode 100644 (file)
index 0000000..ea7c562
--- /dev/null
@@ -0,0 +1,647 @@
+// $Id$
+
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+//*                  for The ALICE HLT Project.                            *
+//*                                                                        *
+//* Permission to use, copy, modify and distribute this software and its   *
+//* documentation strictly for non-commercial purposes is hereby granted   *
+//* without fee, provided that the above copyright notice appears in all   *
+//* copies and that both the copyright notice and this permission notice   *
+//* appear in the supporting documentation. The authors make no claims     *
+//* about the suitability of this software for any purpose. It is          *
+//* provided "as is" without express or implied warranty.                  *
+//**************************************************************************
+
+/** @file   AliHLTAltroGenerator.cxx
+    @author Matthias Richter
+    @date   
+    @brief  Simulation class of 10/40bit Altro Data.
+*/
+
+#include <cassert>
+#include <cerrno>
+#include "AliHLTAltroGenerator.h"
+#include "TArrayS.h"
+#include "TArrayC.h"
+#include "TRandom.h"
+#include "TDatime.h"
+#include "AliRawDataHeader.h"
+#include "AliHLTAltroEncoder.h"
+
+/** ROOT macro for the implementation of ROOT specific class methods */
+ClassImp(AliHLTAltroGenerator)
+
+AliHLTAltroGenerator::AliHLTAltroGenerator(int maxChannels,
+                                          int maxBunches,
+                                          int maxBunchLength,
+                                          int maxTimebin,
+                                          int maxSignal)
+  :
+  fpData(NULL),
+  fpSimData(NULL),
+  fChannelPositions(),
+  fNof10BitWords(0),
+  fpCDH(NULL),
+  fCDHSize(0),
+  fpTrailer(NULL),
+  fTrailerSize(0),
+  fMaxChannels(maxChannels),
+  fMaxBunches(maxBunches),
+  fMaxBunchLength(maxBunchLength),
+  fMaxTimebin(maxTimebin),
+  fMaxSignal(maxSignal),
+  fpRand(NULL),
+  fDirection(kBackwards),
+  fCurrentPosition(-1),
+  fCurrentBunch(-1),
+  fCurrentTimeOffset(-1)
+{
+  // see header file for class documentation
+  // or
+  // refer to README to build package
+  // or
+  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+}
+
+AliHLTAltroGenerator::~AliHLTAltroGenerator()
+{
+  // see header file for class documentation
+  if (fpTrailer) delete[] fpTrailer;
+  if (fpCDH) delete[] fpCDH;
+  if (fpSimData) delete fpSimData;
+  if (fpData) delete fpData;
+}
+
+int AliHLTAltroGenerator::Generate()
+{
+  // see header file for class documentation
+  int iResult=0;
+
+  if (!fpSimData) fpSimData=new TArrayS;
+  if (!fpSimData) {
+    return -ENOMEM;
+  }
+
+  Reset();
+
+  int nofChannels=GetRandom(1, fMaxChannels);
+  if (nofChannels==0) nofChannels=1;
+
+  HLTDebug("number of channels: %d", nofChannels);
+  int channelAddress=-1;
+  int lastChannel=-1;
+  int dataPos=0;
+  int repetitions=0;
+  for (int channel=0; channel<nofChannels; channel++) {
+    channelAddress=GetRandom(0, fMaxChannels);
+    //HLTDebug("channel %d: address %d, %d bunch(es)", channel, channelAddress, nofBunches);
+    if (channelAddress==lastChannel) {
+      channel--;
+      if (repetitions++>5) break;
+      continue;
+    }
+    int nofBunches=GetRandom(1, fMaxBunches);
+    if (nofBunches==0) {
+      channel--;
+      if (repetitions++>5) break;
+      continue;
+    }
+    repetitions=0;
+    int totalBunches=0;
+    int bunchEndTime=fMaxTimebin;
+
+    HLTDebug("simulate channel %d: address %d", channel, channelAddress);
+
+    // save beginning of this channel for better navigation
+    AliChannelPosition position={channelAddress, dataPos, 0};
+
+    // add channel address and bunch count at the beginning
+    if (fpSimData->GetSize()<dataPos+2) fpSimData->Set(dataPos+2);
+    (*fpSimData)[dataPos++]=channelAddress;
+    dataPos++; // placeholder for number of bunches
+
+    int bunch=0;
+    for (bunch=0; bunch<nofBunches && bunchEndTime>0; bunch++) {
+      bunchEndTime=GetRandom(0, bunchEndTime-1);
+      int bunchLength=GetRandom(0, bunchEndTime<fMaxBunchLength?bunchEndTime:fMaxBunchLength);
+      if (bunchLength==0) continue;
+      totalBunches++;
+
+      HLTDebug("       bunch %d, length %d, end time %d ", bunch, bunchLength, bunchEndTime);
+
+      if (fpSimData->GetSize()<dataPos+bunchLength+4) fpSimData->Set(dataPos+bunchLength+4);
+      // write bunch length and time at both ends
+      (*fpSimData)[dataPos++]=bunchLength;
+      int time=bunchEndTime-bunchLength+1;
+      (*fpSimData)[dataPos++]=time;
+      for (; time<=bunchEndTime; time++) {     
+       int signal=GetRandom(0, fMaxSignal);
+       (*fpSimData)[dataPos++]=signal;
+      }
+      (*fpSimData)[dataPos++]=bunchEndTime;
+      (*fpSimData)[dataPos++]=bunchLength;
+      fNof10BitWords+=bunchLength+2;
+    }
+    if (totalBunches>0) {
+      (*fpSimData)[position.fPosition+1]=totalBunches;
+      if (fpSimData->GetSize()<dataPos+2) fpSimData->Set(dataPos+2);
+      (*fpSimData)[dataPos++]=totalBunches;
+      position.fEnd=dataPos;
+      (*fpSimData)[dataPos++]=channelAddress;
+      lastChannel=channelAddress;
+      fNof10BitWords=(fNof10BitWords+7)/4; fNof10BitWords*=4; // align to 4 and add 4
+      fChannelPositions.push_back(position);
+      assert((*fpSimData)[position.fPosition]==(*fpSimData)[position.fEnd]);
+      HLTDebug("       channel %d added: address %d, %d bunch(es)", channel, channelAddress, totalBunches);
+    } else {
+      dataPos-=2;
+      HLTDebug("       channel %d skipped: address %d, %d bunch(es)", channel, channelAddress, totalBunches);
+    }
+  }
+
+  assert(fNof10BitWords%4==0);
+  if (iResult<0) {
+    fpSimData->Set(0);
+    return iResult;
+  }
+  fpSimData->Set(dataPos);
+  return GetDataSize();
+}
+
+int AliHLTAltroGenerator::GetNof40BitAltroWords() const
+{
+  // see header file for class documentation
+  assert(fNof10BitWords%4==0);
+  return fNof10BitWords/4;
+}
+
+int AliHLTAltroGenerator::GetDataSize()
+{
+  // see header file for class documentation
+  int iResult=0;
+  iResult=(fNof10BitWords*5)/4;
+  if (fpTrailer) {
+    *(reinterpret_cast<AliHLTUInt32_t*>(fpTrailer))=GetNof40BitAltroWords();
+    iResult+=fTrailerSize;
+  }
+  if (fpCDH) iResult+=fCDHSize;
+  return iResult;
+}
+
+int AliHLTAltroGenerator::GetData(AliHLTUInt8_t* &pBuffer)
+{
+  // see header file for class documentation
+  int iResult=GetDataSize();
+  if (iResult>0) {
+    if (!fpData) fpData=new TArrayC(iResult);
+    if (fpData) {
+      if (fpData->GetSize()<iResult) fpData->Set(iResult);
+      if ((iResult=GetData(reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray()), fpData->GetSize()))>=0) {
+       pBuffer=reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray());
+      }
+    } else {
+      iResult=-ENOMEM;
+    }
+  }
+  return iResult;
+}
+
+int AliHLTAltroGenerator::GetData(AliHLTUInt8_t* pBuffer, int size)
+{
+  // see header file for class documentation
+  int iResult=0;
+  int dataPos=0;
+
+  if (size<GetDataSize()) return -ENOSPC;
+
+  // copy Common Data Header
+  if (fpCDH) {
+    fpCDH->fSize=GetDataSize();
+    memcpy(pBuffer+dataPos, fpCDH, fCDHSize);
+    dataPos+=fCDHSize;
+  }
+
+  // encode simulated data
+  if ((iResult=EncodeData(pBuffer+dataPos, size-dataPos))>=0) {
+    dataPos+=iResult;
+  }
+
+  // copy trailer
+  if (fpTrailer) {
+    memcpy(pBuffer+dataPos, fpTrailer, fTrailerSize);
+    AliHLTUInt32_t* pLast=reinterpret_cast<AliHLTUInt32_t*>(fpTrailer+fTrailerSize-sizeof(AliHLTUInt32_t));
+    *pLast=GetNof40BitAltroWords();
+    dataPos+=fTrailerSize;
+  }
+
+  if (iResult<0) return iResult;
+  assert(fpCDH==NULL || (int)fpCDH->fSize==dataPos);
+  return dataPos;
+}
+
+int AliHLTAltroGenerator::SetCDH(AliRawDataHeader* pCDH, int size)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (pCDH && size>0) {
+    if (fpCDH) delete[] fpCDH;
+    fpCDH=new AliRawDataHeader;
+    if (fpCDH) {
+      memcpy(fpCDH, pCDH, size);
+      fCDHSize=size;
+    } else {
+      iResult=-ENOMEM;
+    }
+  } else {
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTAltroGenerator::SetRCUTrailer(AliHLTUInt8_t* pTrailer, int size)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (pTrailer && size>=(int)sizeof(AliHLTUInt32_t)) {
+    AliHLTUInt32_t* pLast=reinterpret_cast<AliHLTUInt32_t*>(pTrailer+size-sizeof(AliHLTUInt32_t));
+    if (size!=sizeof(AliHLTUInt32_t)) {
+      // if more than one trailer words, the last one is the trailer length (# 32bit words)
+      if (*pLast!=size/sizeof(AliHLTUInt32_t)) {
+       HLTError("invalid trailer: trailer length (last 32bit word) does not match trailer size (bytes)");
+       return -EBADF;
+      }
+    }
+    if (fpTrailer) delete[] fpTrailer;
+    fpTrailer=new AliHLTUInt8_t[size];
+    if (fpTrailer) {
+      memcpy(fpTrailer, pTrailer, size);
+      fTrailerSize=size;
+    } else {
+      iResult=-ENOMEM;
+    }
+  } else {
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTAltroGenerator::GetChannels(vector<AliHLTUInt16_t> list)
+{
+  // see header file for class documentation
+  int iResult=0;
+  list.clear();
+  for (vector<AliChannelPosition>::iterator element=fChannelPositions.begin();
+       element!=fChannelPositions.end();
+       element++) {
+    list.push_back(element->fChannel);
+  }
+  iResult=list.size();
+  return iResult;
+}
+
+int AliHLTAltroGenerator::SetSorting(AliHLTUInt16_t */*array*/, int /*arraySize*/)
+{
+  // see header file for class documentation
+  int iResult=0;
+  HLTError("function not yet implemented");
+  return iResult;
+}
+
+int AliHLTAltroGenerator::EncodeData(AliHLTUInt8_t* pBuffer, int size)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (!pBuffer) return -EINVAL;
+
+  AliHLTAltroEncoder encoder;
+  encoder.SetBuffer(pBuffer, size);
+
+  Short_t channelAddress=-1;
+  for (vector<AliChannelPosition>::iterator element=fChannelPositions.begin();
+       element!=fChannelPositions.end() && iResult>=0;
+       element++) {
+    if (!fpSimData ||
+       fpSimData->GetSize()<=element->fPosition ||
+       fNof10BitWords==0) {
+      iResult=-ENODATA;
+      break;
+    }
+    channelAddress=element->fChannel;
+    assert(fpSimData->At(element->fPosition)==channelAddress);
+    if (fpSimData->At(element->fPosition)!=channelAddress) {
+      iResult=-ENODATA;
+      break;
+    }
+    int dataPos=element->fPosition+1;
+    int nofBunches=fpSimData->At(dataPos++);
+    int bunch=0;
+    for (; bunch<nofBunches; bunch++) {
+      int bunchLength=fpSimData->At(dataPos++);
+      int startTime=fpSimData->At(dataPos++);
+      int time=startTime;
+      for (; time<startTime+bunchLength; time++) {
+       //iResult=encoder.AddSignal(fpSimData->At(dataPos++), time);
+       iResult=encoder.AddChannelSignal(fpSimData->At(dataPos++), time, channelAddress);
+      }
+      assert(time-1==fpSimData->At(dataPos));
+      dataPos++; // DO NOT PUT INTO ASSERT
+      assert(bunchLength==fpSimData->At(dataPos));
+      dataPos++; // DO NOT PUT INTO ASSERT
+    }
+
+    if (iResult>=0 && channelAddress>=0) {
+      assert(nofBunches==fpSimData->At(dataPos));
+      dataPos++; // DO NOT PUT INTO ASSERT
+      assert(channelAddress==fpSimData->At(dataPos));
+      dataPos++; // DO NOT PUT INTO ASSERT
+    }
+    //encoder.SetChannel(channelAddress);
+  }
+  if (iResult>=0 && channelAddress>=0) {
+    encoder.SetChannel(channelAddress);
+  }
+
+  if (iResult>=0) {
+    iResult=(encoder.GetTotal40bitWords()*5)/4;
+  }
+
+  return iResult;
+}
+
+int AliHLTAltroGenerator::GetRandom(int min, int max)
+{
+  // see header file for class documentation
+  if (max-min<2) return min;
+  bool setTheSeed=fpRand!=NULL;
+  if (fpRand==NULL) {
+    fpRand=new TRandom;
+  }
+  if (fpRand==NULL) return min;
+  if (!setTheSeed) {
+    TDatime dt;
+    fpRand->SetSeed(dt.Get());
+  }
+  return fpRand->Integer(max-min);
+}
+
+int AliHLTAltroGenerator::Reset()
+{
+  // see header file for class documentation
+  fChannelPositions.clear();
+  fNof10BitWords=0;
+  Rewind();
+  return 0;
+}
+
+int AliHLTAltroGenerator::Rewind()
+{
+  // see header file for class documentation
+  fCurrentPosition=-1;
+  fCurrentBunch=-1;
+  fCurrentTimeOffset=-1;
+  return 0;
+}
+
+bool AliHLTAltroGenerator::Next()
+{
+  // see header file for class documentation
+  bool haveData=false;
+  if (!fpSimData) return false;
+  do {
+    if (haveData=(fCurrentTimeOffset>=0 &&
+                 fCurrentBunch>0 &&
+                 ++fCurrentTimeOffset<GetBunchSize())) {
+      break;
+    }
+
+    if (haveData=(NextBunch() && GetBunchSize()>0)) {
+      fCurrentTimeOffset=0;
+      break;
+    }
+  } while (NextChannel());
+  return haveData;
+}
+
+AliHLTUInt16_t AliHLTAltroGenerator::GetSignal()
+{
+  // see header file for class documentation
+  if (!fpSimData || fCurrentTimeOffset<0) return 0;
+  assert(fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size());
+  assert(fCurrentBunch>=0);
+  if (fDirection==kForwards) {
+    return fpSimData->At(fCurrentBunch+2+fCurrentTimeOffset);
+  } else if (fDirection==kBackwards){
+    return fpSimData->At(fCurrentBunch-(2+fCurrentTimeOffset));
+  }
+  return 0;
+}
+
+bool AliHLTAltroGenerator::NextChannel()
+{
+  // see header file for class documentation
+  bool haveData=false;
+  if (fpSimData && fChannelPositions.size()==0) return false;
+  fpSimData->GetArray();
+  if (fCurrentPosition==-1) {
+    if (fDirection==kForwards) fCurrentPosition=0;
+    else fCurrentPosition=fChannelPositions.size()-1;
+    haveData=true;
+  } else {
+    if (fDirection==kForwards && (haveData=(fCurrentPosition+1<(int)fChannelPositions.size()))) {
+      fCurrentPosition++;
+    } else if (fDirection==kBackwards && (haveData=(fCurrentPosition>0))) {
+      fCurrentPosition--;
+    }
+  }
+  
+  fCurrentBunch=-1;
+  fCurrentTimeOffset=-1;
+  return haveData;
+}
+
+AliHLTUInt16_t AliHLTAltroGenerator::GetHwAddress()
+{
+  // see header file for class documentation
+  if (fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size())
+    return fChannelPositions[fCurrentPosition].fChannel;
+  return ~((AliHLTUInt16_t)0);
+}
+
+int AliHLTAltroGenerator::GetBunchCount()
+{
+  // see header file for class documentation
+  if (fpSimData && fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size()) {
+    if (fDirection==kForwards)
+      return fpSimData->At(fChannelPositions[fCurrentPosition].fPosition+1);
+    else if (fDirection==kBackwards)
+      return fpSimData->At(fChannelPositions[fCurrentPosition].fEnd-1);
+  }
+  return ~((AliHLTUInt16_t)0);
+}
+
+bool AliHLTAltroGenerator::NextBunch()
+{
+  // see header file for class documentation
+  bool haveData=false;
+  if (fpSimData && fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size()) {
+    if (fDirection==kBackwards) {
+      if (fCurrentBunch<0) {
+       // bunch count in channel end - 1
+       if (haveData=(fpSimData->At(fChannelPositions[fCurrentPosition].fEnd-1))>0) {
+         // first bunch length at channel end - 2
+         fCurrentBunch=fChannelPositions[fCurrentPosition].fEnd-2;
+       }
+      } else if (fCurrentBunch>fChannelPositions[fCurrentPosition].fPosition+1) {
+       fCurrentBunch-=fpSimData->At(fCurrentBunch)+4;
+       haveData=fCurrentBunch>fChannelPositions[fCurrentPosition].fPosition+1;
+      }
+      // cross check
+      if (haveData) {
+       assert(fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch-fpSimData->At(fCurrentBunch)-3));
+       haveData=fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch-fpSimData->At(fCurrentBunch)-3);
+      }
+    } else if (fDirection==kForwards) {
+      if (fCurrentBunch<0) {
+       // bunch count in channel start + 1
+       if (haveData=(fpSimData->At(fChannelPositions[fCurrentPosition].fPosition+1))>0) {
+         // first bunch length at channel start + 2
+         fCurrentBunch=fChannelPositions[fCurrentPosition].fPosition+2;
+       }
+      } else if (fCurrentBunch<fChannelPositions[fCurrentPosition].fEnd-1) {
+       fCurrentBunch+=fpSimData->At(fCurrentBunch)+4;
+       haveData=fCurrentBunch<fChannelPositions[fCurrentPosition].fEnd-1;
+      }
+      // cross check
+      if (haveData) {
+       assert(fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch+fpSimData->At(fCurrentBunch)+3));
+       haveData=fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch+fpSimData->At(fCurrentBunch)+3);
+      }
+    }
+  }
+  fCurrentTimeOffset=-1;
+  return haveData;
+}
+
+AliHLTUInt16_t AliHLTAltroGenerator::GetBunchSize()
+{
+  // see header file for class documentation
+  if (fCurrentBunch<0) return 0;
+  if (fCurrentBunch<fChannelPositions[fCurrentPosition].fPosition+2) return 0;
+  if (fCurrentBunch>fChannelPositions[fCurrentPosition].fEnd-2) return 0;
+  return fpSimData->At(fCurrentBunch);
+}
+
+AliHLTUInt16_t AliHLTAltroGenerator::GetStartTime()
+{
+  // see header file for class documentation
+  if (!fpSimData || GetBunchSize()==0) return 0;
+  AliHLTUInt16_t startTime=0;
+  if (fDirection==kForwards) {
+    startTime=fpSimData->At(fCurrentBunch+1);
+  } else if (fDirection==kBackwards) {
+    startTime=fpSimData->At(fCurrentBunch-fpSimData->At(fCurrentBunch)-2);
+  }
+  if (fCurrentTimeOffset>=0) {
+    if (fDirection==kForwards) {
+      startTime+=fCurrentTimeOffset;
+    } else if (fDirection==kBackwards) {
+      startTime=GetEndTime();
+    }
+  }
+  return startTime;
+}
+
+AliHLTUInt16_t AliHLTAltroGenerator::GetEndTime()
+{
+  // see header file for class documentation
+  if (!fpSimData || GetBunchSize()==0) return 0;
+  AliHLTUInt16_t endTime=0;
+  if (fDirection==kForwards) {
+    endTime=fpSimData->At(fCurrentBunch+fpSimData->At(fCurrentBunch)+2);
+  } else if (fDirection==kBackwards) {
+    endTime=fpSimData->At(fCurrentBunch-1);
+  }
+  if (fCurrentTimeOffset>=0) {
+    assert(fCurrentTimeOffset<fpSimData->At(fCurrentBunch));
+    if (fDirection==kForwards) {
+      endTime=GetStartTime();
+    } else if (fDirection==kBackwards) {
+      endTime-=fCurrentTimeOffset;
+    }
+  }
+  return endTime;
+}
+
+const Short_t* AliHLTAltroGenerator::GetSignals()
+{
+  // see header file for class documentation
+  if (!fpSimData || GetBunchSize()==0) return NULL;
+  if (fDirection==kForwards) {
+    return fpSimData->GetArray()+fCurrentBunch+2;
+  } else if (fDirection==kBackwards) {
+    return fpSimData->GetArray()+(fCurrentBunch-fpSimData->At(fCurrentBunch)-1);
+  }
+  return NULL;
+}
+
+void AliHLTAltroGenerator::Print()
+{
+  // see header file for class documentation
+  cout << *this << endl;
+}
+
+ostream &operator<<(ostream &stream, AliHLTAltroGenerator &generator)
+{
+  // see header file for class documentation
+  int iResult=0;
+  Short_t channelAddress=-1;
+  for (vector<AliHLTAltroGenerator::AliChannelPosition>::iterator element=generator.fChannelPositions.begin();
+       element!=generator.fChannelPositions.end() && iResult>=0;
+       element++) {
+    if (!generator.fpSimData ||
+       generator.fpSimData->GetSize()<=element->fPosition ||
+       generator.fNof10BitWords==0) {
+      stream << "AliHLTAltroGenerator: no data available" << endl;;
+      break;
+    }
+    channelAddress=element->fChannel;
+    assert(generator.fpSimData->At(element->fPosition)==channelAddress);
+    if (generator.fpSimData->At(element->fPosition)!=channelAddress) {
+      stream << "AliHLTAltroGenerator: internal data mismatch" << endl;;
+      iResult=-ENODATA;
+      break;
+    }
+    int dataPos=element->fPosition+1;
+    int nofBunches=generator.fpSimData->At(dataPos++);
+    stream << "***************************************************************" << endl;
+    stream << "channel address: " << channelAddress << "    " << nofBunches << " bunch(es)" << endl;
+    int bunch=0;
+    for (; bunch<nofBunches; bunch++) {
+      int bunchLength=generator.fpSimData->At(dataPos++);
+      int startTime=generator.fpSimData->At(dataPos++);
+      int time=startTime;
+      stream << "   length " << bunchLength << " start time " << startTime << ":     ";
+      for (; time<startTime+bunchLength; time++) {
+       stream << " " << generator.fpSimData->At(dataPos++);
+      }
+      assert(time-1==generator.fpSimData->At(dataPos));
+      dataPos++; // DO NOT PUT INTO ASSERT
+      assert(bunchLength==generator.fpSimData->At(dataPos));
+      dataPos++; // DO NOT PUT INTO ASSERT
+      stream << "      -> end time " << time-1 << endl;
+    }
+
+    if (iResult>=0 && channelAddress>=0) {
+      assert(nofBunches==generator.fpSimData->At(dataPos));
+      dataPos++; // DO NOT PUT INTO ASSERT
+      assert(channelAddress==generator.fpSimData->At(dataPos));
+      dataPos++; // DO NOT PUT INTO ASSERT
+    }
+  }
+
+  return stream;
+}
diff --git a/HLT/RCU/AliHLTAltroGenerator.h b/HLT/RCU/AliHLTAltroGenerator.h
new file mode 100644 (file)
index 0000000..261090f
--- /dev/null
@@ -0,0 +1,292 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+#ifndef ALIHLTALTROGENERATOR_H
+#define ALIHLTALTROGENERATOR_H
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+/** @file   AliHLTAltroGenerator.h
+    @author Matthias Richter
+    @date   
+    @brief  Simulation class of 10/40bit Altro Data.
+*/
+
+// see below for class documentation
+// or
+// refer to README to build package
+// or
+// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt   
+
+#include "AliHLTDataTypes.h"
+#include "AliHLTLogging.h"
+#include <vector>
+#include <ostream>
+
+class AliRawDataHeader;
+class TArrayS;
+class TArrayC;
+class TRandom;
+
+/**
+ * @class AliHLTAltroGenerator
+ */
+class AliHLTAltroGenerator : AliHLTLogging {
+ public:
+  /** constructor */
+  AliHLTAltroGenerator(int maxChannels=1000,
+                      int maxBunches=50,
+                      int maxBunchLength=10,
+                      int maxTimebin=1024,
+                      int maxSignal=500);
+  /** destructor */
+  virtual ~AliHLTAltroGenerator();
+
+  /**
+   * Generate a new event.
+   * Simulate new data and store internally in plain format.
+   *
+   * @return size of the encoded data in byte. If the CDH and/or RCU
+   * trailer was set, the size includes those.
+   */
+  int Generate();
+
+  /**
+   * Get the number of 40bit Altro words of the current data set.
+   * @return number of 40bit Altro words.
+   */
+  int GetNof40BitAltroWords() const;
+
+  /**
+   * Get the data size of the current data set.
+   * @return size of the encoded data in byte. If the CDH and/or RCU
+   * trailer was set, the size includes those.
+   */
+  int GetDataSize();
+
+  /**
+   * Get the simulated data.
+   * Get a pointer to the internal buffer. The buffer is filled with
+   * the encoded data from the previous simulation.
+   * @param pBuffer     target variable to receive the pointer
+   * @return size in byte, neg. error if failed
+   */
+  int GetData(AliHLTUInt8_t* &pBuffer);
+
+  /**
+   * Get the simulated data.
+   * The provided buffer is filled with the encoded data from the
+   * previous simulation.
+   * @param pBuffer     target variable to receive the pointer
+   * @return size in byte, neg. error if failed
+   */
+  int GetData(AliHLTUInt8_t* pBuffer, int size);
+
+  /**
+   * Set the Common Data Header.
+   * @param pCDH        the CDH
+   * @param size        size of the header in byte
+   * @return neg. error code if failed
+   */
+  int SetCDH(AliRawDataHeader* pCDH, int size);
+
+  /**
+   * Set the RCU trailer.
+   * @param pTrailer    the trailer
+   * @param size        size of the header in byte
+   * @return neg. error code if failed
+   */
+  int SetRCUTrailer(AliHLTUInt8_t* pTrailer, int size);
+
+  /**
+   * Get list of channels in the current data set.
+   */
+  int GetChannels(vector<AliHLTUInt16_t> list);
+
+  /**
+   * Set array of channels for sorting of channels.
+   * The encoded data will be sorted according to the specified
+   * list.
+   * @param array       array of channels
+   * @param arraySize   size of the array
+   */
+  int SetSorting(AliHLTUInt16_t *array, int arraySize);
+
+  /**
+   * Get a random number in the given range.
+   */
+  int GetRandom(int min, int max);
+
+  /**
+   * Set parsing direction for the Next functions.
+   * @param direction   @ref AliHLTAltroGenerator::kBackwards (default),
+   *                    @ref AliHLTAltroGenerator::kForwards
+   */
+  void SetDirection(int direction) {fDirection=direction;}
+
+  /**
+   * Position at the next signal.
+   * The function follows the pure stream model.
+   * @return true if there is a new signal available
+   */
+  bool Next();
+
+  /**
+   * Get the current signal.
+   * The current time value can be retrieved by ::GetStartTime or
+   * ::GetEndTime which return both the current time in the stream
+   * model.
+   * @return signal value
+   */
+  AliHLTUInt16_t GetSignal();
+
+  /**
+   * Position at the beginning of the next channel.
+   * Depending on the mode, the function works either back or
+   * forwards.
+   * @return true if there is a new channel available
+   */
+  bool NextChannel();
+
+  /**
+   * Get the hardware address of the current channel.
+   */
+  AliHLTUInt16_t GetHwAddress();
+
+  /**
+   * Get bunch count of the current channel
+   */
+  int GetBunchCount();
+
+  /**
+   * Position at the beginning of the next bunch.
+   * Depending on the mode, the function works either back or
+   * forwards.
+   * @return true if there is a new bunch available
+   */
+  bool NextBunch();
+
+  /**
+   * Get size of the current bunch.
+   */
+  AliHLTUInt16_t GetBunchSize();
+
+  /**
+   * Get start time of the current bunch or signal.
+   */
+  AliHLTUInt16_t  GetStartTime();
+
+  /**
+   * Get end time of the current bunch or signal.
+   */
+  AliHLTUInt16_t  GetEndTime();
+
+  /**
+   * Get pointer to signals of current bunch.
+   * The signals are always in ascending order.
+   */
+  const Short_t* GetSignals();
+
+  /**
+   * Reset the internal position variables.
+   */
+  int Reset();
+
+  /**
+   * Rewind stream position for Next funxtions
+   */
+  int Rewind();
+
+  /**
+   * Print content of simulated data to cout.
+   */
+  void Print();
+
+  /**
+   * Printout of simulated data.
+   */
+  friend ostream &operator<<(ostream &str, AliHLTAltroGenerator &generator);
+
+  enum {
+    kBackwards = 0,
+    kForwards = 1
+  };
+
+ protected:
+ private:
+  /** copy constructor prohibited */
+  AliHLTAltroGenerator(const AliHLTAltroGenerator&);
+  /** assignment operator prohibited */
+  AliHLTAltroGenerator& operator=(const AliHLTAltroGenerator&);
+
+  /**
+   * Encode the simulated data into Altro format
+   */
+  int EncodeData(AliHLTUInt8_t* pBuffer, int size);
+
+  /// internal data buffer
+  TArrayC* fpData; //!transient
+
+  /// array of simulated data
+  TArrayS* fpSimData; //! transient
+
+  struct AliChannelPosition {
+    AliHLTUInt16_t fChannel; //! transient
+    int fPosition; //! transient
+    int fEnd; //! transient
+  };
+
+  /// channels and their positions in the simulated data
+  vector<AliChannelPosition> fChannelPositions; //! transient
+
+  /// the Altro payload in the simulated data
+  int fNof10BitWords; //! transient
+
+  /// the Common Data Header
+  AliRawDataHeader* fpCDH; //!transient
+
+  /// size of the Common Data Header in byte
+  int fCDHSize; //! transient
+
+  /// the RCU trailer
+  AliHLTUInt8_t* fpTrailer; //!transient
+
+  /// size of the trailer
+  int fTrailerSize; //!transient
+
+  /// maximum number of channels
+  int fMaxChannels; //! transient
+
+  /// maximum number of bunches
+  int fMaxBunches; //! transient
+
+  /// maximum bunche length
+  int fMaxBunchLength; //! transient
+
+  /// max timebin
+  int fMaxTimebin; //!transient
+
+  /// maximum signal
+  int fMaxSignal; // transient
+
+  /// the random number generator
+  TRandom* fpRand; //! transient
+
+  /// direction of parsing
+  int fDirection; //! transient
+
+  /// current channel position for the Next functions
+  int fCurrentPosition; //! transient
+
+  /// current bunch position in the simulated data
+  int fCurrentBunch; //! transient
+
+  /// current offset in the current bunch
+  int fCurrentTimeOffset; //! transient
+
+  ClassDef(AliHLTAltroGenerator, 0);
+};
+
+#endif
index 7241a6f..909584f 100644 (file)
@@ -8,16 +8,25 @@ AM_CPPFLAGS                   = -I$(top_srcdir)/BASE \
 
 EXTRA_DIST                     = 
 
-check_PROGRAMS                 = testAliHLTAltroEncoder
+check_PROGRAMS                 = testAliHLTAltroEncoder \
+                                 testAliHLTAltroGenerator
 
 testAliHLTAltroEncoder_SOURCES         = testAliHLTAltroEncoder.C
-testAliHLTAltroEncoder_LDADD   = $(top_builddir)/BASE/libHLTbase.la \
-                                 $(top_builddir)/RCU/libAliHLTRCU.la
+testAliHLTAltroGenerator_SOURCES= testAliHLTAltroGenerator.C
+
 
 # linker flags
-testAliHLTAltroEncoder_LDFLAGS = -L@ROOTLIBDIR@ \
+LDADD_COMMON                   = $(top_builddir)/BASE/libHLTbase.la \
+                                 $(top_builddir)/RCU/libAliHLTRCU.la
+LDFLAGS_COMMON                 = -L@ROOTLIBDIR@ \
                                  @ROOTLIBS@ \
                                  @ALIROOT_LDFLAGS@ \
                                  @ALIROOT_LIBS@
 
-TESTS                          = $(check_PROGRAMS)
\ No newline at end of file
+testAliHLTAltroEncoder_LDADD   = $(LDADD_COMMON)
+testAliHLTAltroGenerator_LDADD         = $(LDADD_COMMON)
+
+testAliHLTAltroEncoder_LDFLAGS = $(LDFLAGS_COMMON)
+testAliHLTAltroGenerator_LDFLAGS= $(LDFLAGS_COMMON)
+
+TESTS                          = $(check_PROGRAMS)
index fd6df3d..21306da 100644 (file)
@@ -16,7 +16,7 @@
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
-/** @file   altro-encoder.C
+/** @file   testAliHLTAltroEncoder.C
     @author Matthias Richter
     @date   
     @brief  Test macro/program for the AliHLTAltroEncoder
@@ -273,7 +273,7 @@ void CompareDumpFiles()
   Compare(simData, encData);
 }
 
-int altro_encoder()
+int testAliHLTAltroEncoder()
 {
   int nofChannels=GetRandom(1, maxChannels);
   if (nofChannels==0) nofChannels=1;
@@ -393,11 +393,11 @@ int main(int argc, const char** argv)
   int iResult=0;
   int iCount=10000;
   for (int i=0; i<iCount; i++) {
-    if ((iResult=altro_encoder())<0) {
+    if ((iResult=testAliHLTAltroEncoder())<0) {
       cout << "missmatch in block no " << i << endl;
       return iResult;
     }
   }
-  cout << iCount << " encoding cycle(s) successfully tested" << endl;
+  cout << "checking: " << iCount << " encoding cycle(s) successfully tested" << endl;
   return 0;
 }
diff --git a/HLT/RCU/test/testAliHLTAltroGenerator.C b/HLT/RCU/test/testAliHLTAltroGenerator.C
new file mode 100644 (file)
index 0000000..8a9799c
--- /dev/null
@@ -0,0 +1,241 @@
+// $Id$
+
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ *                                                                        *
+ * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+ *                  for The ALICE HLT Project.                            *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/** @file   testAliHLTAltroGenerator.C
+    @author Matthias Richter
+    @date   
+    @brief  Test macro/program for the AliHLTAltroGenerator
+ */
+
+#ifndef __CINT__
+#include "TSystem.h"
+#include "AliHLTSystem.h"
+#include "AliRawDataHeader.h"
+#include "AliAltroDecoder.h"
+#include "AliAltroData.h"
+#include "AliAltroBunch.h"
+#include "AliHLTAltroGenerator.h"
+#include <ostream>
+#endif //__CINT__
+
+#ifndef __CINT__
+const int sizeofAliRawDataHeader=sizeof(AliRawDataHeader);
+#else
+// cint does not handle sizeof correctly
+const int sizeofAliRawDataHeader=32;
+#endif
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+//
+// configuration of the test program
+//
+
+// printouts or not
+const bool bVerbose=false;
+
+// some defaults
+const int maxChannels=1000;
+const int maxBunches=50;
+const int maxBunchLength=10;
+const int maxTimebin=1024;
+const int maxSignal=1024;
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+int testAliHLTAltroGenerator()
+{
+  int iResult=0;
+#ifdef __CINT__
+  gSystem->Load("libAliHLTRCU.so");
+#endif
+  AliHLTSystem gHLT;
+
+  AliHLTAltroGenerator g(maxChannels, maxBunches, maxBunchLength, maxTimebin, maxSignal);
+  //g.SetDirection(AliHLTAltroGenerator::kForwards);
+  if ((iResult=g.Generate())<0) return iResult;
+
+  if (bVerbose) {
+    cout << "***************************************************************" << endl;
+    cout << "************** Dumping simulated Altro data *******************" << endl;
+    g.Print();
+    cout << endl;
+  }
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  if (bVerbose) {
+    g.Rewind();
+    cout << "***************************************************************" << endl;
+    cout << "********************** reading bunch model  *******************" << endl;
+    while (iResult>=0 && g.NextChannel()) {
+    cout << "***************************************************************" << endl;
+      cout << "channel address: " << g.GetHwAddress() << "    " << g.GetBunchCount() << " bunch(es)" << endl;
+
+      while (iResult>=0 && g.NextBunch()) {
+       int bunchLength=g.GetBunchSize();
+       cout << "   length " << bunchLength << " start time " << g.GetStartTime() << ":     ";
+       const Short_t* pData=g.GetSignals();
+       while (bunchLength-->0 && pData) {
+         cout << " " << *pData++;
+       }
+       cout << "      -> end time " << g.GetEndTime() << endl;
+      }
+    }
+    cout << endl;
+  }
+
+  if (bVerbose) {
+    g.Rewind();
+    int lastChannel=-1;
+    int lastTime=-1;
+    cout << "***************************************************************" << endl;
+    cout << "********************** reading stream model *******************" << endl;
+    while (iResult>=0 && g.Next()) {
+      if (lastTime>=0 && lastTime!=g.GetStartTime()+1 && lastTime!=g.GetStartTime()-1)
+       cout << endl;
+
+      if (lastChannel<0 || lastChannel!=g.GetHwAddress()) {
+       cout << "***************************************************************" << endl;
+       cout << "channel address: " << g.GetHwAddress() << endl;
+      }
+
+      if (lastTime<0 || (lastTime!=g.GetStartTime()+1 && lastTime!=g.GetStartTime()-1))
+       cout << " time " << g.GetStartTime() << ":     ";
+
+      cout << " " << g.GetSignal();
+
+      lastChannel=g.GetHwAddress();
+      lastTime=g.GetStartTime();
+    }
+    cout << endl;
+    cout << endl;
+  }
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  AliRawDataHeader cdh;
+  g.SetCDH(&cdh, 32);
+
+  UInt_t trailer=0;
+  g.SetRCUTrailer((UChar_t*)&trailer, 4);
+
+  UChar_t* pBuffer=NULL;
+  Int_t size=g.GetData(pBuffer);
+
+  /*
+  ios::openmode filemode=(ios::openmode)0;
+  ofstream rawfile("/tmp/altro-enc.dat", filemode);
+  if (rawfile.good()) {
+    rawfile.write(reinterpret_cast<const char*>(pBuffer), size);
+  }
+  rawfile.close();
+  */
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  // can not have a static AltroDecoder, crash when function
+  // is called. I had a similar problem in the AliHLTAltroChannelSelectorComponent
+
+  if (bVerbose) {
+    cout << "***************************************************************" << endl;
+    cout << "********************* comparing encoded data ******************" << endl;
+    cout << "***************************************************************" << endl;
+  }
+
+  g.Rewind();
+  AliAltroDecoder* decoder=new AliAltroDecoder;
+  if (iResult>=0 && decoder->SetMemory(pBuffer, size)<0) {
+    cout << "error setting up decoder " << endl;
+    iResult=-1;
+  }
+
+  if (iResult>=0 && !decoder->Decode()) {
+    cout << "error decoding data" << endl;
+    iResult=-1;    
+  }
+
+  AliAltroData altrochannel;
+  while (iResult>=0 && decoder->NextChannel(&altrochannel)) {
+    if (!g.NextChannel()) {
+      cout << "error getting next simulated channel" << endl;
+      iResult=-1;
+      break;
+    }
+    int hwadd=altrochannel.GetHadd();
+    if (hwadd!=g.GetHwAddress()) {
+      cout << "channel address missmatch: simulated " << g.GetHwAddress() << " encoded " << hwadd << endl;
+      iResult=-1;
+      break;
+    }
+
+    if (bVerbose) cout << "comparing channel " << hwadd << endl;
+
+    AliAltroBunch altrobunch;
+    while (iResult>=0 && altrochannel.NextBunch(&altrobunch)) {
+      if (!g.NextBunch()) {
+       cout << "error getting bunch in simulated data" <<endl;
+       iResult=-1;
+       break;
+      }
+      int bunchLength=altrobunch.GetBunchSize();
+      if (bunchLength!=(int)g.GetBunchSize()) {
+       cout << "bunch length missmatch: simulated " << g.GetBunchSize() << " encoded " << bunchLength << hex << " (" << bunchLength << ")" << dec << endl;
+       iResult=-1;
+       break;
+      }
+      int bunchEndTime=altrobunch.GetEndTimeBin();
+       if (bunchEndTime!=(int)g.GetEndTime()) {
+       cout << "bunch end time missmatch: simulated " << g.GetEndTime() << " encoded " << bunchEndTime << endl;
+       iResult=-1;
+       break;
+      }
+      if (bVerbose) cout << " bunch length " << bunchLength << ", end time " << bunchEndTime << endl;
+      const  UInt_t* bunchData=altrobunch.GetData();
+      const  Short_t* simData=g.GetSignals();
+      for (int bin=0; bin<bunchLength; bin++) {
+       if ((Short_t)bunchData[bin]!=simData[bin]) {
+         cout << "data missmatch at bunch position " << bin << " : simulated " << simData[bin] << " encoded " << bunchData[bin] << endl;
+         iResult=-1;
+         break;
+       }
+      }
+    }
+
+  }
+  
+  delete decoder;
+
+  return 0;
+}
+
+int main(int /*argc*/, const char** /*argv*/)
+{
+  int iResult=0;
+  // this test takes ~20 times longer than the testAliHLTAltroEncoder
+  // no clue why, has to be traced with vtune
+  int iCount=500;
+  for (int i=0; i<iCount; i++) {
+    if ((iResult=testAliHLTAltroGenerator())<0) {
+      cout << "missmatch in cycle no " << i << endl;
+      return iResult;
+    }
+  }
+  cout << "checking: "<< iCount << " encoding cycle(s) successfully tested" << endl;
+  return 0;
+}
index 4783388..63d0c83 100644 (file)
@@ -190,5 +190,7 @@ void AliHLTTPCDigitReader::PrintMissingFastAccessWarning()
   // see header file for class documentation
   if (CheckFlag(kWarnMissFastAccess)) return;
   SetFlag(kWarnMissFastAccess);
-  HLTWarning("This digit reader does not implement the metghods for fast data access on channel/bunch basis. Data is discarded");
+  HLTWarning("\n"
+            "      !!! This digit reader does not implement the methods for       !!!\n"
+            "      !!! fast data access on channel/bunch basis. Data is discarded !!!");
 }
index e808a13..e78cba6 100644 (file)
@@ -69,7 +69,7 @@ CLEANFILES                    = $(COMPILE_INFO) \
 
 include $(top_srcdir)/make.dict
 
-SUBDIRS                        = . OnlineDisplay
+SUBDIRS                        = . test OnlineDisplay
 
 $(TPC_MAPPING_INC): $(TPC_MAPPING_NOINST_PGM)
        ./$<
diff --git a/HLT/TPCLib/test/Makefile.am b/HLT/TPCLib/test/Makefile.am
new file mode 100644 (file)
index 0000000..b63ad79
--- /dev/null
@@ -0,0 +1,34 @@
+# $Id$
+# Makefile template Alice HLT TPC library test programs
+
+AM_CPPFLAGS                    = -I$(top_srcdir)/BASE \
+                                 -I$(top_srcdir)/RCU \
+                                 -I$(srcdir)/.. \
+                                 @ALIROOT_CPPFLAGS@ \
+                                 -I@ROOTINCDIR@
+
+EXTRA_DIST                     = 
+
+check_PROGRAMS                 = testAliHLTTPCDigitReaderDecoder \
+                                 testAliHLTTPCDigitReaderPacked
+
+testAliHLTTPCDigitReaderDecoder_SOURCES = testAliHLTTPCDigitReaderDecoder.C
+testAliHLTTPCDigitReaderPacked_SOURCES = testAliHLTTPCDigitReaderPacked.C
+
+
+# linker flags
+LDADD_COMMON                           = $(top_builddir)/BASE/libHLTbase.la \
+                                         $(top_builddir)/TPCLib/libAliHLTTPC.la
+LDFLAGS_COMMON                         = -L@ROOTLIBDIR@ \
+                                         @ROOTLIBS@ \
+                                         @ALIROOT_LDFLAGS@ \
+                                         @ALIROOT_LIBS@
+
+testAliHLTTPCDigitReaderDecoder_LDADD  = $(LDADD_COMMON)
+testAliHLTTPCDigitReaderPacked_LDADD   = $(LDADD_COMMON)
+testAliHLTTPCDigitReaderDecoder_LDFLAGS        = $(LDFLAGS_COMMON)
+testAliHLTTPCDigitReaderPacked_LDFLAGS = $(LDFLAGS_COMMON)
+
+# set back to all as sson as DigitReaderPacked is fixed
+#TESTS                         = $(check_PROGRAMS)
+TESTS                          = testAliHLTTPCDigitReaderDecoder
diff --git a/HLT/TPCLib/test/testAliHLTTPCDigitReaderDecoder.C b/HLT/TPCLib/test/testAliHLTTPCDigitReaderDecoder.C
new file mode 100644 (file)
index 0000000..3b4b6f5
--- /dev/null
@@ -0,0 +1,222 @@
+// $Id$
+
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ *                                                                        *
+ * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+ *                  for The ALICE HLT Project.                            *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/** @file   testAliHLTTPCDigitReaderDecoder.C
+    @author Matthias Richter
+    @date   
+    @brief  Test macro/program for the AliHLTTPCDigitReaderDecoder
+ */
+
+#ifndef __CINT__
+#include "TSystem.h"
+#include "AliHLTSystem.h"
+#include "AliRawDataHeader.h"
+#include "AliHLTAltroGenerator.h"
+#include "AliHLTTPCDigitReaderDecoder.h"
+#include <ostream>
+#endif //__CINT__
+
+#ifndef __CINT__
+const int sizeofAliRawDataHeader=sizeof(AliRawDataHeader);
+#else
+// cint does not handle sizeof correctly
+const int sizeofAliRawDataHeader=32;
+#endif
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+//
+// configuration of the test program
+//
+
+// printouts or not
+const bool bVerbose=true;
+
+// some defaults
+const int maxChannels=10;
+const int maxBunches=10;
+const int maxBunchLength=10;
+const int maxTimebin=1024;
+const int maxSignal=1024;
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+int testAliHLTTPCDigitReaderDecoder()
+{
+  int iResult=0;
+#ifdef __CINT__
+  gSystem->Load("libAliHLTUtil.so");
+  gSystem->Load("libAliHLTRCU.so");
+  gSystem->Load("libAliHLTTPC.so");
+#endif
+  AliHLTSystem gHLT;
+
+  AliHLTAltroGenerator generator(maxChannels, maxBunches, maxBunchLength, maxTimebin, maxSignal);
+  //generator.SetDirection(AliHLTAltroGenerator::kForwards);
+  if ((iResult=generator.Generate())<0) return iResult;
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  if (bVerbose) {
+    cout << "***************************************************************" << endl;
+    cout << "************** Dumping simulated Altro data *******************" << endl;
+    generator.Print();
+    cout << endl;
+  }
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  AliRawDataHeader cdh;
+  generator.SetCDH(&cdh, 32);
+
+  UInt_t trailer=0;
+  generator.SetRCUTrailer((UChar_t*)&trailer, 4);
+
+  UChar_t* pBuffer=NULL;
+  Int_t size=generator.GetData(pBuffer);
+
+  int partition=0;
+  if (bVerbose) {
+    AliHLTTPCDigitReaderDecoder decoder;
+    decoder.SetUnsorted(true);
+    if ((iResult=decoder.InitBlock(pBuffer, size, partition, 0))>=0) {
+      cout << "***************************************************************" << endl;
+      cout << "********************** reading bunch model  *******************" << endl;
+      while (iResult>=0 && decoder.NextChannel()) {
+       cout << "***************************************************************" << endl;
+       cout << "channel address: " << decoder.GetAltroBlockHWaddr() << endl;
+
+       while (iResult>=0 && decoder.NextBunch()) {
+         int bunchLength=decoder.GetBunchSize();
+         cout << "   length " << bunchLength << " time " << decoder.GetTime() << ":     ";
+         const UInt_t* pData=decoder.GetSignals();
+         while (bunchLength-->0 && pData) {
+           cout << " " << *pData++;
+         }
+         cout << endl;
+       }
+      }
+      cout << endl;
+    }
+  }   
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  if (bVerbose) {
+    AliHLTTPCDigitReaderDecoder decoder;
+    decoder.SetUnsorted(true);
+    if ((iResult=decoder.InitBlock(pBuffer, size, partition, 0))>=0) {
+      int lastChannel=-1;
+      int lastTime=-1;
+      cout << "***************************************************************" << endl;
+      cout << "********************** reading stream model *******************" << endl;
+      while (iResult>=0 && decoder.Next()) {
+       if (lastTime>=0 && lastTime!=decoder.GetTime()+1 && lastTime!=decoder.GetTime()-1)
+         cout << endl;
+       
+       if (lastChannel<0 || lastChannel!=(int)decoder.GetAltroBlockHWaddr()) {
+         cout << "***************************************************************" << endl;
+         cout << "channel address: " << decoder.GetAltroBlockHWaddr() << endl;
+       }
+
+       if (lastTime<0 || (lastTime!=decoder.GetTime()+1 && lastTime!=decoder.GetTime()-1))
+         cout << " time " << decoder.GetTime() << ":     ";
+
+       cout << " " << decoder.GetSignal();
+
+       lastChannel=decoder.GetAltroBlockHWaddr();
+       lastTime=decoder.GetTime();
+      }
+      cout << endl;
+      cout << endl;
+    }    
+  }
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  if (bVerbose) {
+    cout << "***************************************************************" << endl;
+    cout << "********************* comparing encoded data ******************" << endl;
+    cout << "***************************************************************" << endl;
+  }
+
+  generator.Rewind();
+  AliHLTTPCDigitReaderDecoder decoder;
+  decoder.SetUnsorted(true);
+  if (iResult>=0) iResult=decoder.InitBlock(pBuffer, size, partition, 0);
+  while (iResult>=0 && decoder.NextChannel()) {
+    if (!generator.NextChannel()) {
+      cout << "error getting next simulated channel" << endl;
+      iResult=-1;
+      break;
+    }
+    int hwadd=decoder.GetAltroBlockHWaddr();
+    if (hwadd!=generator.GetHwAddress()) {
+      cout << "channel address missmatch: simulated " << generator.GetHwAddress() << " encoded " << hwadd << endl;
+      iResult=-1;
+      break;
+    }
+
+    if (bVerbose) cout << "comparing channel " << hwadd << endl;
+
+    while (iResult>=0 && decoder.NextBunch()) {
+      if (!generator.NextBunch()) {
+       cout << "error getting bunch in simulated data" <<endl;
+       iResult=-1;
+       break;
+      }
+      int bunchLength=decoder.GetBunchSize();
+      if (bunchLength!=(int)generator.GetBunchSize()) {
+       cout << "bunch length missmatch: simulated " << generator.GetBunchSize() << " encoded " << bunchLength << hex << " (" << bunchLength << ")" << dec << endl;
+       iResult=-1;
+       break;
+      }
+      int bunchStartTime=decoder.GetTime();
+       if (bunchStartTime!=(int)generator.GetStartTime()) {
+       cout << "bunch end time missmatch: simulated " << generator.GetStartTime() << " encoded " << bunchStartTime << endl;
+       iResult=-1;
+       break;
+      }
+      if (bVerbose) cout << " bunch length " << bunchLength << ", end time " << bunchStartTime << endl;
+      const  UInt_t* bunchData=decoder.GetSignals();
+      const  Short_t* simData=generator.GetSignals();
+      for (int bin=0; bin<bunchLength; bin++) {
+       if ((Short_t)bunchData[bin]!=simData[bin]) {
+         cout << "data missmatch at bunch position " << bin << " : simulated " << simData[bin] << " encoded " << bunchData[bin] << endl;
+         iResult=-1;
+         break;
+       }
+      }
+    }
+  }
+
+  return 0;
+}
+
+int main(int /*argc*/, const char** /*argv*/)
+{
+  int iResult=0;
+  int iCount=1;
+  for (int i=0; i<iCount; i++) {
+    if ((iResult=testAliHLTTPCDigitReaderDecoder())<0) {
+      cout << "missmatch in cycle no " << i << endl;
+      return iResult;
+    }
+  }
+  cout << "checking: "<< iCount << " encoding cycle(s) successfully tested" << endl;
+  return 0;
+}
diff --git a/HLT/TPCLib/test/testAliHLTTPCDigitReaderPacked.C b/HLT/TPCLib/test/testAliHLTTPCDigitReaderPacked.C
new file mode 100644 (file)
index 0000000..719fb47
--- /dev/null
@@ -0,0 +1,224 @@
+// $Id$
+
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ *                                                                        *
+ * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+ *                  for The ALICE HLT Project.                            *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/** @file   testAliHLTTPCDigitReaderPacked.C
+    @author Matthias Richter
+    @date   
+    @brief  Test macro/program for the AliHLTTPCDigitReaderPacked
+ */
+
+#ifndef __CINT__
+#include "TSystem.h"
+#include "AliHLTSystem.h"
+#include "AliRawDataHeader.h"
+#include "AliHLTAltroGenerator.h"
+#include "AliHLTTPCDigitReaderPacked.h"
+#include <ostream>
+#endif //__CINT__
+
+#ifndef __CINT__
+const int sizeofAliRawDataHeader=sizeof(AliRawDataHeader);
+#else
+// cint does not handle sizeof correctly
+const int sizeofAliRawDataHeader=32;
+#endif
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+//
+// configuration of the test program
+//
+
+// printouts or not
+const bool bVerbose=true;
+
+// some defaults
+const int maxChannels=10;
+const int maxBunches=10;
+const int maxBunchLength=10;
+const int maxTimebin=1024;
+const int maxSignal=1024;
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+int testAliHLTTPCDigitReaderPacked()
+{
+  int iResult=0;
+#ifdef __CINT__
+  gSystem->Load("libAliHLTUtil.so");
+  gSystem->Load("libAliHLTRCU.so");
+  gSystem->Load("libAliHLTTPC.so");
+#endif
+  AliHLTSystem gHLT;
+
+  AliHLTAltroGenerator generator(maxChannels, maxBunches, maxBunchLength, maxTimebin, maxSignal);
+  //generator.SetDirection(AliHLTAltroGenerator::kForwards);
+  if ((iResult=generator.Generate())<0) return iResult;
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  if (bVerbose) {
+    cout << "***************************************************************" << endl;
+    cout << "************** Dumping simulated Altro data *******************" << endl;
+    generator.Print();
+    cout << endl;
+  }
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  AliRawDataHeader cdh;
+  generator.SetCDH(&cdh, 32);
+
+  UInt_t trailer=0;
+  generator.SetRCUTrailer((UChar_t*)&trailer, 4);
+
+  UChar_t* pBuffer=NULL;
+  Int_t size=generator.GetData(pBuffer);
+
+  int partition=0;
+  if (bVerbose) {
+    AliHLTTPCDigitReaderPacked decoder;
+    decoder.SetOldRCUFormat(true);
+    decoder.SetUnsorted(true);
+    if ((iResult=decoder.InitBlock(pBuffer, size, partition, 0))>=0) {
+      cout << "***************************************************************" << endl;
+      cout << "********************** reading bunch model  *******************" << endl;
+      while (iResult>=0 && decoder.NextChannel()) {
+       cout << "***************************************************************" << endl;
+       cout << "channel address: " << decoder.GetAltroBlockHWaddr() << endl;
+
+       while (iResult>=0 && decoder.NextBunch()) {
+         int bunchLength=decoder.GetBunchSize();
+         cout << "   length " << bunchLength << " time " << decoder.GetTime() << ":     ";
+         const UInt_t* pData=decoder.GetSignals();
+         while (bunchLength-->0 && pData) {
+           cout << " " << *pData++;
+         }
+         cout << endl;
+       }
+      }
+      cout << endl;
+    }
+  }   
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  if (bVerbose) {
+    AliHLTTPCDigitReaderPacked decoder;
+    decoder.SetOldRCUFormat(true);
+    decoder.SetUnsorted(true);
+    if ((iResult=decoder.InitBlock(pBuffer, size, partition, 0))>=0) {
+      int lastChannel=-1;
+      int lastTime=-1;
+      cout << "***************************************************************" << endl;
+      cout << "********************** reading stream model *******************" << endl;
+      while (iResult>=0 && decoder.Next()) {
+       if (lastTime>=0 && lastTime!=decoder.GetTime()+1 && lastTime!=decoder.GetTime()-1)
+         cout << endl;
+       
+       if (lastChannel<0 || lastChannel!=(int)decoder.GetAltroBlockHWaddr()) {
+         cout << "***************************************************************" << endl;
+         cout << "channel address: " << decoder.GetAltroBlockHWaddr() << endl;
+       }
+
+       if (lastTime<0 || (lastTime!=decoder.GetTime()+1 && lastTime!=decoder.GetTime()-1))
+         cout << " time " << decoder.GetTime() << ":     ";
+
+       cout << " " << decoder.GetSignal();
+
+       lastChannel=decoder.GetAltroBlockHWaddr();
+       lastTime=decoder.GetTime();
+      }
+      cout << endl;
+      cout << endl;
+    }    
+  }
+
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  if (bVerbose) {
+    cout << "***************************************************************" << endl;
+    cout << "********************* comparing encoded data ******************" << endl;
+    cout << "***************************************************************" << endl;
+  }
+
+  generator.Rewind();
+  AliHLTTPCDigitReaderPacked decoder;
+  decoder.SetUnsorted(true);
+  if (iResult>=0) iResult=decoder.InitBlock(pBuffer, size, partition, 0);
+  while (iResult>=0 && decoder.NextChannel()) {
+    if (!generator.NextChannel()) {
+      cout << "error getting next simulated channel" << endl;
+      iResult=-1;
+      break;
+    }
+    int hwadd=decoder.GetAltroBlockHWaddr();
+    if (hwadd!=generator.GetHwAddress()) {
+      cout << "channel address missmatch: simulated " << generator.GetHwAddress() << " encoded " << hwadd << endl;
+      iResult=-1;
+      break;
+    }
+
+    if (bVerbose) cout << "comparing channel " << hwadd << endl;
+
+    while (iResult>=0 && decoder.NextBunch()) {
+      if (!generator.NextBunch()) {
+       cout << "error getting bunch in simulated data" <<endl;
+       iResult=-1;
+       break;
+      }
+      int bunchLength=decoder.GetBunchSize();
+      if (bunchLength!=(int)generator.GetBunchSize()) {
+       cout << "bunch length missmatch: simulated " << generator.GetBunchSize() << " encoded " << bunchLength << hex << " (" << bunchLength << ")" << dec << endl;
+       iResult=-1;
+       break;
+      }
+      int bunchStartTime=decoder.GetTime();
+       if (bunchStartTime!=(int)generator.GetStartTime()) {
+       cout << "bunch end time missmatch: simulated " << generator.GetStartTime() << " encoded " << bunchStartTime << endl;
+       iResult=-1;
+       break;
+      }
+      if (bVerbose) cout << " bunch length " << bunchLength << ", end time " << bunchStartTime << endl;
+      const  UInt_t* bunchData=decoder.GetSignals();
+      const  Short_t* simData=generator.GetSignals();
+      for (int bin=0; bin<bunchLength; bin++) {
+       if ((Short_t)bunchData[bin]!=simData[bin]) {
+         cout << "data missmatch at bunch position " << bin << " : simulated " << simData[bin] << " encoded " << bunchData[bin] << endl;
+         iResult=-1;
+         break;
+       }
+      }
+    }
+  }
+
+  return 0;
+}
+
+int main(int /*argc*/, const char** /*argv*/)
+{
+  int iResult=0;
+  int iCount=1;
+  for (int i=0; i<iCount; i++) {
+    if ((iResult=testAliHLTTPCDigitReaderPacked())<0) {
+      cout << "missmatch in cycle no " << i << endl;
+      return iResult;
+    }
+  }
+  cout << "checking: "<< iCount << " encoding cycle(s) successfully tested" << endl;
+  return 0;
+}
index 3fbb639..532e458 100644 (file)
@@ -877,6 +877,7 @@ AC_CONFIG_FILES([Makefile
                 shuttle/Makefile
                 SampleLib/Makefile
                 TPCLib/Makefile
+                TPCLib/test/Makefile
                 TPCLib/mapping2array.cxx
                 TPCLib/OnlineDisplay/Makefile
                 RCU/Makefile
index 980e8d8..f077448 100644 (file)
@@ -5,6 +5,7 @@ include $(MODDIR)/hlt.conf
 
 CLASS_HDRS:=   AliHLTAltroChannelSelectorComponent.h \
                AliHLTAltroEncoder.h \
+               AliHLTAltroGenerator.h \
                AliHLTRCUAgent.h
 
 MODULE_SRCS=   $(CLASS_HDRS:.h=.cxx)