// $Id$ /************************************************************************** * This file is property of and copyright by the ALICE HLT Project * * ALICE Experiment at CERN, All rights reserved. * * * * Primary Authors: Matthias Richter * * 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 testAliHLTAltroEncoder.C @author Matthias Richter @date @brief Test macro/program for the AliHLTAltroEncoder */ #ifndef __CINT__ #include "TFile.h" #include "TDatime.h" #include "TRandom.h" #include "TArrayI.h" #include "TArrayC.h" #include "TSystem.h" #include "AliRawDataHeader.h" #include "AliAltroDecoder.h" #include "AliAltroData.h" #include "AliAltroBunch.h" #include "AliHLTAltroEncoder.h" #include "AliHLTSystem.h" #include #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; // the encoder can be used in two different modes: using // AddSignal and terminating each channel by explicitely calling // SetChannel, or the combined version AddChannelSignal const bool bUseAddChannelSignal=true; // some defaults const int maxChannels=100; const int maxBunches=50; const int maxTimebin=1024; const int maxSignal=1024; const int maxEncodedDataSize=4000000+sizeofAliRawDataHeader; // file dumps const char* encDataDumpFile=NULL;//"/tmp/altro-enc.dat"; const char* encodedDataFile="/tmp/altro-encoded.dat"; const char* simulatedDataFile="/tmp/altro-simulated.dat"; ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// Bool_t seedSet=kFALSE; /** * Get a random number in the given range. */ int GetRandom(int min, int max) { if (max-min<2) return min; static TRandom rand; if (!seedSet) { TDatime dt; rand.SetSeed(dt.Get()); seedSet=kTRUE; } return rand.Integer(max-min); } /** * Print the bunch information of a channel. * The function goes recursively to the first bunch of the * channel and prints this one first. * @return number of 10bit words */ int DumpBunchRecursive(int nofBunches, int* pData, int size) { if (!pData || size<2) return -1; int pos=size; int bunchLength=pData[--pos]; int bunchEndTime=pData[--pos]; int read=0; if (bunchLength1) { read=DumpBunchRecursive(nofBunches-1, pData, pos-bunchLength); } cout << " bunch length " << bunchLength << ", end time " << bunchEndTime << ":"; for (int time=bunchEndTime; time>bunchEndTime-bunchLength; time--) { if (pos<1) { pos=0; cerr << "no data for bunch " << endl; return -1; } //cout << " " << pData[--pos]; } cout << endl; if (read<0) return read; return read+2+bunchLength; } /** * Write the encoded data to a file. */ template void DumpDataArray(T *array, const char* filename, int memberSize) { if (array->GetSize()==0) return; ios::openmode filemode=(ios::openmode)0; ofstream rawfile(filename, filemode); if (rawfile.good()) { rawfile.write(reinterpret_cast(array->GetArray()), array->GetSize()*memberSize); } rawfile.close(); } /** * Print the simulated data. */ void PrintSimulatedData(TArrayI& data) { cout << endl << "****** readback *******" << endl << endl; int dataPos=data.GetSize(); while (dataPos>0) { int channelAddress=data[--dataPos]; int nofBunches=data[--dataPos]; cout << " ------------------ new channel -------------------------" << endl; if (nofBunches>0) { int read=DumpBunchRecursive(nofBunches, data.GetArray(), dataPos); if (read<0) return; dataPos-=read; } cout << " channel " << channelAddress << ": number of bunches " << nofBunches << endl; } } int Compare(TArrayI& simData, TArrayC& encData) { if (bVerbose) cout << endl << "****** compare *******" << endl << endl; // can not have a static AltroDecoder, crash when function // is called. I had a similar problem in the AliHLTAltroChannelSelectorComponent int iResult=0; AliAltroDecoder* decoder=new AliAltroDecoder; if (iResult>=0 && decoder->SetMemory((UChar_t*)encData.GetArray(), (UInt_t)encData.GetSize())<0) { cout << "error setting up decoder " << endl; iResult=-1; } if (iResult>=0 && !decoder->Decode()) { cout << "error decoding data" << endl; iResult=-1; } AliAltroData altrochannel; int dataPos=simData.GetSize(); while (iResult>=0 && decoder->NextChannel(&altrochannel)) { int hwadd=altrochannel.GetHadd(); if (dataPos<2) { cout << "missmatch in simulated data" << endl; iResult=-1; break; } int channelAddress=simData[--dataPos]; int nofBunches=simData[--dataPos]; int nofBunchesBackup=nofBunches; if (channelAddress!=hwadd) { cout << "channel address missmatch: simulated " << channelAddress << " encoded " << hwadd << endl; iResult=-1; break; } if (bVerbose) cout << "comparing channel " << channelAddress << ", " << nofBunches << " bunche(s)" << endl; AliAltroBunch altrobunch; while (iResult>=0 && altrochannel.NextBunch(&altrobunch) && nofBunches-->0) { if (dataPos<2) { cout << "error reading bunch size and time bin from simulated data" << endl; iResult=-1; break; } int bunchLength=simData[--dataPos]; int bunchEndTime=simData[--dataPos]; if (bunchLength!=(int)altrobunch.GetBunchSize()) { cout << "bunch length missmatch: simulated " << bunchLength << " encoded " << altrobunch.GetBunchSize() << hex << " (" << altrobunch.GetBunchSize() << ")" << dec << endl; iResult=-1; break; } if (bunchEndTime!=(int)altrobunch.GetEndTimeBin()) { cout << "bunch end time missmatch: simulated " << bunchEndTime << " encoded " << altrobunch.GetEndTimeBin() << endl; iResult=-1; break; } if (bVerbose) cout << " bunch length " << bunchLength << ", end time " << bunchEndTime << endl; const UInt_t* bunchData=altrobunch.GetData(); if (bunchLength>dataPos) { cout << "error reading simulated bunch data, required "<< bunchLength << " available " << dataPos << endl; iResult=-1; break; } Int_t* pSim=simData.GetArray(); for (int bin=0; bin0 && iResult==0) { cout << "error getting " << nofBunches << " of " << nofBunchesBackup << " bunches from channel " << channelAddress << endl; iResult=-1; } } delete decoder; return iResult; } void CompareDumpFiles() { TString param=encodedDataFile; param+="?filetype=raw"; TFile encFile(param); if (encFile.IsZombie()) { cout << "can not open file " << encodedDataFile << endl; return; } TArrayC encData(encFile.GetSize()); if (encFile.ReadBuffer(encData.GetArray(), encData.GetSize())) { cout << "error reading file " << encodedDataFile << endl; return; } param=simulatedDataFile; param+="?filetype=raw"; TFile simFile(param); if (simFile.IsZombie()) { cout << "can not open file " << simulatedDataFile << endl; return; } TArrayI simData(simFile.GetSize()/4); if (simFile.ReadBuffer((char*)simData.GetArray(), simData.GetSize()*4)) { cout << "error reading file " << simulatedDataFile << endl; return; } Compare(simData, encData); } int testAliHLTAltroEncoder() { #ifdef __CINT__ string ld_library_path="../.libs:"; ld_library_path+=gSystem->GetDynamicPath(); gSystem->SetDynamicPath(ld_library_path.c_str()); gSystem->Load("libAliHLTRCU.so"); #endif AliHLTSystem gHLT; int nofChannels=GetRandom(1, maxChannels); if (nofChannels==0) nofChannels=1; TArrayI simData; TArrayC encData(maxEncodedDataSize); const int maxAltroDataSize=encData.GetSize()-sizeofAliRawDataHeader; int dataPos=0; AliHLTAltroEncoder encoder; encoder.SetBuffer((AliHLTUInt8_t*)encData.GetArray(), encData.GetSize()); // set the common data header TArrayC dummyCdh(sizeofAliRawDataHeader); encoder.SetCDH((AliHLTUInt8_t*)dummyCdh.GetArray(), dummyCdh.GetSize()); // set a trailer like in the real data format of the v1 RCU format (1 trailer word) Int_t trailer=0; encoder.SetRCUTrailer((AliHLTUInt8_t*)&trailer, 4); if (bVerbose) cout << "number of channels: " << nofChannels << endl; int channelAddress=-1; int lastChannel=-1; int nof10BitWords=0; // The nof10BitWords value is aligned to 4. In addition, one // 40bit word is needed for the channel trailer for (int channel=0; channel=maxAltroDataSize) break; totalBunches++; if (bVerbose) cout << " bunch " << bunch << ", length " << bunchLength << ", end time " << bunchEndTime << ":"; if (simData.GetSize()0) nof10BitWords+=added; } if (bVerbose) cout << endl; simData[dataPos++]=bunchEndTime; simData[dataPos++]=bunchLength; lastBunchEndTime=bunchEndTime; bunchEndTime+=bunchLength; } if (simData.GetSize()0) { simData[dataPos++]=totalBunches; simData[dataPos++]=channelAddress; } if (!bUseAddChannelSignal && lastChannel>=0) { encoder.SetChannel(lastChannel); } if (bVerbose) cout << " channel " << channelAddress << ": number of bunches " << totalBunches << endl; } int dataSize=encoder.SetLength(); if (dataSize<0) { cerr << "error finalizing encoded buffer" << endl; return -1; } int nof40bitWords=encoder.GetTotal40bitWords(); encData.Set(dataSize); if (bVerbose) cout << "simulated data array:" << simData.GetSize() << " , ALTRO block length: " << nof40bitWords << " ALTRO words -> encoded data: " << encData.GetSize() << endl; ///////////////////////////////////////////////////////// // some debugging options if (encDataDumpFile) DumpDataArray(&encData, encDataDumpFile, 1); simData.Set(dataPos); if (bVerbose) PrintSimulatedData(simData); ///////////////////////////////////////////////////////// // read back end compare the encoded data if (simData.GetSize()>0 && Compare(simData, encData)<0) { // dump files for further debugging DumpDataArray(&encData, encodedDataFile, 1); DumpDataArray(&simData, simulatedDataFile, 4); return -1; } else { if (bVerbose) cout << "check successfully completed: " << nof40bitWords << " ALTRO words" << endl; } return 0; } int main(int /*argc*/, const char** /*argv*/) { // CompareDumpFiles(); // return 0; int iResult=0; int iCount=1000; for (int i=0; i