// $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> *
- * Timm Steinbeck <timm@kip.uni-heidelberg.de> *
- * Jochen Thaeder <thaeder@kip.uni-heidelberg.de> *
- * 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. *
- **************************************************************************/
+//*************************************************************************
+// 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> *
+// Timm Steinbeck <timm@kip.uni-heidelberg.de> *
+// Jochen Thaeder <thaeder@kip.uni-heidelberg.de> *
+// 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 AliHLTTPCDigitReaderPacked.cxx
@author Timm Steinbeck, Jochen Thaeder, Matthias Richter, Kenneth Aamodt
@date
- @brief A digit reader implementation for simulated, packed TPC 'raw' data.
+ @brief A digit reader implementation for raw data, using the offline
+ AliAltroRawStream/AliTPCRawStream.
*/
#if __GNUC__>= 3
#include "AliRawReaderMemory.h"
#include "AliRawDataHeader.h"
-//#if ENABLE_PAD_SORTING
#include "AliHLTTPCTransform.h"
-//#endif // ENABLE_PAD_SORTING
#include "AliHLTStdIncludes.h"
ClassImp(AliHLTTPCDigitReaderPacked)
-#if defined(HAVE_ALIRAWDATA) && defined(HAVE_ALITPCRAWSTREAM_H)
AliHLTTPCDigitReaderPacked::AliHLTTPCDigitReaderPacked()
:
- //#if ENABLE_PAD_SORTING
+ fTPCRawStream(NULL),
fCurrentRow(0),
fCurrentPad(0),
fCurrentBin(-1),
- fNRows(0),
fRowOffset(0),
- fNMaxRows(0),
- fNMaxPads(0),
- fNTimeBins(0),
+ fNRows(0),
+ fNPads(0),
fData(NULL),
- //#endif // ENABLE_PAD_SORTING
- fRawMemoryReader(NULL),
- fTPCRawStream(NULL),
- fOldRCUFormat(kFALSE),
- fUnsorted(kFALSE)
+ fUnsorted(kFALSE),
+ fDataBunch(),
+ fCurrentChannel(-1),
+ fbHaveData(false),
+ fCurrentPatch(0)
{
- fRawMemoryReader = new AliRawReaderMemory;
-
- fTPCRawStream = new AliTPCRawStream( fRawMemoryReader );
+ // see header file for class documentation
+ // or
+ // refer to README to build package
+ // or
+ // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+
+
+ // Matthias Sep 2008: the pad sorting functionality needs a deep
+ // revision of the code
+ // I just stumbled over a few awkward implementation
+ // - each instance allocates the buffer for sorted data, this is
+ // approx. 8 MByte each
+ // - each instance loops to extract the buffer size
+ // - the AliTPCRawStream reads the Altro mapping for each instance
+ //
+ // There is now an instance handling of the buffer and the buffer size
+ // is only calculated once The sorting of pads is going to be a common
+ // functionality of the DigitReader base class in the future.
+ //
+ // Same applies to the instance of the AliRawReaderMemory and
+ // AliTPCRawStream. Since processing of multiple instances is always
+ // sequential, one instance can be used for all readers.
- //#if ENABLE_PAD_SORTING
// get max number of rows
+ if (fNMaxRows<0) {
for (Int_t ii=0; ii < 6; ii++)
if (AliHLTTPCTransform::GetNRows(ii) > fNMaxRows)
fNMaxRows = AliHLTTPCTransform::GetNRows(ii);
+ }
// get max number of pads
+ if (fNMaxPads<0) {
for (Int_t ii=0; ii < AliHLTTPCTransform::GetNRows();ii++ )
if (AliHLTTPCTransform::GetNPads(ii) > fNMaxPads)
fNMaxPads = AliHLTTPCTransform::GetNPads(ii);
+ }
// get max number of bins
+ if (fNTimeBins<0) {
fNTimeBins = AliHLTTPCTransform::GetNTimeBins();
+ }
- HLTDebug("Array Borders ||| MAXPAD=%d ||| MAXROW=%d ||| MAXBIN=%d ||| MAXMUL=%d",
- fNMaxPads, fNMaxRows, fNTimeBins, fNTimeBins*fNMaxRows*fNMaxPads);
-
- // init Data array
- fData = new Int_t[ fNMaxRows*fNMaxPads*fNTimeBins ];
- //#endif // ENABLE_PAD_SORTING
+ fgObjectCount++;
}
-AliHLTTPCDigitReaderPacked::~AliHLTTPCDigitReaderPacked(){
- if ( fRawMemoryReader )
- delete fRawMemoryReader;
- fRawMemoryReader = NULL;
- if ( fTPCRawStream )
- delete fTPCRawStream;
- fTPCRawStream = NULL;
- //#if ENABLE_PAD_SORTING
- if ( fData )
- delete [] fData;
- fData = NULL;
- //#endif // ENABLE_PAD_SORTING
-}
+Int_t AliHLTTPCDigitReaderPacked::fNMaxRows=-1;
+Int_t AliHLTTPCDigitReaderPacked::fNMaxPads=-1;
+Int_t AliHLTTPCDigitReaderPacked::fNTimeBins=-1;
+Int_t* AliHLTTPCDigitReaderPacked::fgpFreeBufferInstance=NULL;
+Int_t* AliHLTTPCDigitReaderPacked::fgpIssuedBufferInstance=NULL;
+AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream* AliHLTTPCDigitReaderPacked::fgpFreeStreamInstance=NULL;
+AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream* AliHLTTPCDigitReaderPacked::fgpIssuedStreamInstance=NULL;
+Int_t AliHLTTPCDigitReaderPacked::fgObjectCount=0;
-Int_t AliHLTTPCDigitReaderPacked::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice){
+AliHLTTPCDigitReaderPacked::~AliHLTTPCDigitReaderPacked()
+{
+ // see header file for class documentation
+ if (fData) ReleaseBufferInstance(fData);
+ fData=NULL;
+
+ if (fTPCRawStream) ReleaseRawStreamInstance(fTPCRawStream);
+ fTPCRawStream=NULL;
+
+ if (--fgObjectCount==0) {
+ if (fgpFreeBufferInstance) delete fgpFreeBufferInstance;
+ fgpFreeBufferInstance=NULL;
+ if (fgpIssuedBufferInstance) delete fgpIssuedBufferInstance;
+ fgpIssuedBufferInstance=NULL;
+ if (fgpFreeStreamInstance) delete fgpFreeStreamInstance;
+ fgpFreeStreamInstance=NULL;
+ if (fgpIssuedStreamInstance) delete fgpIssuedStreamInstance;
+ fgpIssuedStreamInstance=NULL;
+ }
+}
- fRawMemoryReader->SetMemory( reinterpret_cast<UChar_t*>( ptr ), size );
+Int_t AliHLTTPCDigitReaderPacked::InitBlock(void* ptr,ULong_t size, Int_t patch, Int_t slice)
+{
+ // see header file for class documentation
+ fTPCRawStream=GetRawStreamInstance();
+ if (!fTPCRawStream) return -ENODEV;
+ fCurrentPatch=patch;
+
//get DDL ID in order to tell the memory reader which slice/patch to use
Int_t DDLid= 0;
if (patch < 2)
else
DDLid = 840 + 4*slice + patch-2;
- fRawMemoryReader->SetEquipmentID(DDLid);
- //fRawMemoryReader->SetEquipmentID(1);
- if(fOldRCUFormat)
- fTPCRawStream->SetOldRCUFormat(kTRUE);
-
- if(!fUnsorted){
- //#if ENABLE_PAD_SORTING
+ fTPCRawStream->SetMemory(DDLid, reinterpret_cast<UChar_t*>( ptr ), size );
+ // fCurrentRow always is the row number within a partition, whereas the TPCRawStream
+ // counts rows within the inner and outer sector, i.e. 0 to 62 for the inner and
+ // 63 to 158 for the outer sector
+ // fRowOffset is the offset of the first row of the current partition with respect
+ // to inner or outer sector.
fCurrentRow = 0;
fCurrentPad = 0;
fCurrentBin = -1;
Int_t firstrow=AliHLTTPCTransform::GetFirstRow(patch);
Int_t lastrow=AliHLTTPCTransform::GetLastRow(patch);
fNRows = lastrow - firstrow + 1;
+ for (Int_t ii=firstrow; ii <= lastrow;ii++ ) {
+ if (AliHLTTPCTransform::GetNPads(ii) > fNPads)
+ fNPads = AliHLTTPCTransform::GetNPads(ii);
+ }
Int_t offset=0;
if (patch > 1) offset = AliHLTTPCTransform::GetFirstRow( 2 );
firstrow -= offset;
lastrow -= offset;
+ fbHaveData=false;
+
+ if(!fUnsorted){
+
+ // get the global instance of the array
+ fData=GetBufferInstance();
+ if (!fData) return -ENOMEM;
+
// Init array with -1
memset( fData, 0xFF, sizeof(Int_t)*(fNMaxRows*fNMaxPads*fNTimeBins) );
}
}
}
- //#endif // ENABLE_PAD_SORTING
}
return 0;
}
-Bool_t AliHLTTPCDigitReaderPacked::NextSignal(){
+int AliHLTTPCDigitReaderPacked::Reset()
+{
+ // see header file for class documentation
+ if (fData) ReleaseBufferInstance(fData);
+ fData=NULL;
+ if (fTPCRawStream) ReleaseRawStreamInstance(fTPCRawStream);
+ fTPCRawStream=NULL;
+ return 0;
+}
+
+Bool_t AliHLTTPCDigitReaderPacked::NextSignal()
+{
+ // see header file for class documentation
Bool_t readvalue = kTRUE;
- if(!fUnsorted){//added for test
- //#if ENABLE_PAD_SORTING
+ if(!fUnsorted) {
+ if (!fData) return false;
while (1) {
fCurrentBin++;
if (fCurrentBin >= fNTimeBins){
fCurrentBin = 0;
fCurrentPad++;
- if (fCurrentPad >=fNMaxPads){
+ if (fCurrentPad >=fNPads){
fCurrentPad = 0;
fCurrentRow++;
- if (fCurrentRow >= fNMaxRows){
+ if (fCurrentRow >= fNRows){
readvalue = kFALSE;
break;
}
if (fData[ fCurrentRow*fNMaxPads*fNTimeBins + fCurrentPad*fNTimeBins + fCurrentBin ] != -1) break;
}
- }// added for test
- else{//added for test
- //#else // !ENABLE_PAD_SORTING
- readvalue = fTPCRawStream->Next();
- }//added for test
- //#endif // ENABLE_PAD_SORTING
+ } else{
+ if ((readvalue = fTPCRawStream->Next())) {
+ fCurrentBin=fTPCRawStream->GetTime();
+ }
+ }
+ fbHaveData=readvalue;
return readvalue;
}
-Int_t AliHLTTPCDigitReaderPacked::GetRow(){
- /*#if ENABLE_PAD_SORTING
- return (fCurrentRow + fRowOffset);
-#else // !ENABLE_PAD_SORTING
- return (Int_t) fTPCRawStream->GetRow();
-#endif // ENABLE_PAD_SORTING
- */
+Int_t AliHLTTPCDigitReaderPacked::GetRow()
+{
+ // see header file for class documentation
if(!fUnsorted){
return (fCurrentRow + fRowOffset);
}
else{
- return (Int_t) fTPCRawStream->GetRow();
+ return (Int_t) fTPCRawStream->GetRow()-fRowOffset;
}
}
-int AliHLTTPCDigitReaderPacked::GetPad(){
- /*#if ENABLE_PAD_SORTING
- return fCurrentPad;
- #else // !ENABLE_PAD_SORTING
- return fTPCRawStream->GetPad();
- #endif // ENABLE_PAD_SORTING
- */
+int AliHLTTPCDigitReaderPacked::GetPad()
+{
+ // see header file for class documentation
if(!fUnsorted){
return fCurrentPad;
}
}
}
-Int_t AliHLTTPCDigitReaderPacked::GetSignal(){
- /*
- #if ENABLE_PAD_SORTING
- return fData[ fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin ];
- #else // !ENABLE_PAD_SORTING
- return fTPCRawStream->GetSignal();
- #endif // ENABLE_PAD_SORTING
- */
+AliHLTUInt32_t AliHLTTPCDigitReaderPacked::GetAltroBlockHWaddr() const
+{
+ // see header file for class documentation
+ return fTPCRawStream->GetHWAddress();
+}
+
+int AliHLTTPCDigitReaderPacked::GetRCUTrailerSize()
+{
+ // see header file for class documentation
+ if(fTPCRawStream){
+ return fTPCRawStream->GetRCUTrailerSize();
+ }
+ return 0;
+}
+
+bool AliHLTTPCDigitReaderPacked::GetRCUTrailerData(UChar_t*& trData)
+{
+ // see header file for class documentation
+ if(fTPCRawStream){
+ return fTPCRawStream->GetRCUTrailerData(trData);
+ }
+ return false;
+}
+
+Int_t AliHLTTPCDigitReaderPacked::GetSignal()
+{
+ // see header file for class documentation
if(!fUnsorted){
+ // check for validity of fData is in NextSignal, no check at here
return fData[ fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin ];
}
else{
}
}
-Int_t AliHLTTPCDigitReaderPacked::GetTime(){
- /*
- #if ENABLE_PAD_SORTING
- return fCurrentBin;
- #else // !ENABLE_PAD_SORTING
- return fTPCRawStream->GetTime();
- #endif // ENABLE_PAD_SORTING
- */
- if(!fUnsorted){
- return fCurrentBin;
+Int_t AliHLTTPCDigitReaderPacked::GetTime()
+{
+ // see header file for class documentation
+ return fCurrentBin;
+}
+
+Int_t AliHLTTPCDigitReaderPacked::GetTimeOfUnsortedSignal(){
+ return fTPCRawStream->GetTime();
+}
+
+bool AliHLTTPCDigitReaderPacked::NextChannel()
+{
+ // see header file for class documentation
+
+ // return true if a channel is available. This is true if
+ // 1. the current row position >=0 : a signal has already been read in the stream
+ // but it was not part of the previous bunch
+ // 2. the current row position <0 : this is the first invocation at all, read
+ // signal and send result according to the availability
+ if(fbHaveData || // data available from the last NextSignal call?
+ NextSignal()) { // there is data
+ fCurrentChannel=GetAltroBlockHWaddr();
+ return true;
}
- else{
- return fTPCRawStream->GetTime();
+ return false;
+}
+
+int AliHLTTPCDigitReaderPacked::NextBunch()
+{
+ // see header file for class documentation
+ if (fCurrentChannel<0) return 0;
+
+ fDataBunch.clear();
+ //adding the first signal (will always be the leftover from either NextChannel call or Previous bunch)
+ fDataBunch.push_back(GetSignal());
+
+ Int_t prevTime=GetTimeOfUnsortedSignal();
+ do{
+ if(NextSignal()){
+ if((int)GetAltroBlockHWaddr()==fCurrentChannel){//check if there is a change in channel(new row and pad)
+ if(prevTime==GetTimeOfUnsortedSignal()+1){//if true means that we have consecutive signals
+ prevTime=GetTimeOfUnsortedSignal();
+ fDataBunch.insert(fDataBunch.begin(), GetSignal());
+ }
+ else{//end of bunch but not of channel
+ break;
+ }
+ }
+ else{
+ fCurrentChannel=-1;
+ break;
+ }
+ }
+ else{
+ // end of data, but there is one bunch to be completed
+ fCurrentChannel=-1;
+ break;
+ }
+ }while(1);
+
+ fCurrentBin=prevTime;
+ return fDataBunch.size();
+
+}
+
+int AliHLTTPCDigitReaderPacked::GetBunchSize(){
+ // see header file for class documentation
+ return fDataBunch.size();
+}
+
+const UInt_t* AliHLTTPCDigitReaderPacked::GetSignals()
+{
+ // see header file for class documentation
+ return &fDataBunch[0];
+}
+
+Int_t* AliHLTTPCDigitReaderPacked::GetBufferInstance()
+{
+ // see header file for class documentation
+
+ // for the moment only a singleton of the buffer is foreseen
+ // could be extended but very unlikly to be worth the effort
+ // because pad sorting is just a debug feature.
+
+ // This is just a poor man's solution, no synchronization for the
+ // moment
+ AliHLTLogging log;
+ if (fgpIssuedBufferInstance) {
+ log.LoggingVarargs(kHLTLogError, "AliHLTTPCDigitReaderPacked", "GetBufferInstance" , __FILE__ , __LINE__ ,
+ "instance of sorted buffer has not been released or multiple instances requested. Only available as global singleton for DigitReaderPacked");
+ return NULL;
+ }
+
+ if (!fgpFreeBufferInstance) {
+ if (fNMaxRows<0 || fNMaxPads<0 || fNTimeBins<0) {
+ log.LoggingVarargs(kHLTLogError, "AliHLTTPCDigitReaderPacked", "GetBufferInstance" , __FILE__ , __LINE__ ,
+ "can not determine size of buffer for sorted data");
+ return NULL;
+ }
+ fgpFreeBufferInstance=new Int_t[ fNMaxRows*fNMaxPads*fNTimeBins ];
+ log.LoggingVarargs(kHLTLogDebug, "AliHLTTPCDigitReaderPacked", "GetBufferInstance" , __FILE__ , __LINE__ ,
+ "Array Borders ||| MAXPAD=%d ||| MAXROW=%d ||| MAXBIN=%d ||| MAXMUL=%d",
+ fNMaxPads, fNMaxRows, fNTimeBins, fNTimeBins*fNMaxRows*fNMaxPads);
+ }
+
+ fgpIssuedBufferInstance=fgpFreeBufferInstance;
+ fgpFreeBufferInstance=NULL;
+ return fgpIssuedBufferInstance;
+}
+
+void AliHLTTPCDigitReaderPacked::ReleaseBufferInstance(Int_t* pInstance)
+{
+ // see header file for class documentation
+ if (!pInstance) return;
+ if (pInstance!=fgpIssuedBufferInstance) {
+ AliHLTLogging log;
+ log.LoggingVarargs(kHLTLogError, "AliHLTTPCDigitReaderPacked", "ReleaseBufferInstance" , __FILE__ , __LINE__ ,
+ "wrong instance %p, expecting %p", pInstance, fgpIssuedBufferInstance);
+ return;
+ }
+ fgpFreeBufferInstance=fgpIssuedBufferInstance;
+ fgpIssuedBufferInstance=NULL;
+}
+
+AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream* AliHLTTPCDigitReaderPacked::GetRawStreamInstance()
+{
+ // see header file for class documentation
+ if (fgpIssuedStreamInstance) {
+ HLTError("instance of TPCRawStream has not been released or multiple instances requested. Only available as global singleton for DigitReaderPacked");
+ return NULL;
+ }
+
+ if (!fgpFreeStreamInstance) {
+ fgpFreeStreamInstance=new AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream;
}
+
+ fgpIssuedStreamInstance=fgpFreeStreamInstance;
+ fgpFreeStreamInstance=NULL;
+ return fgpIssuedStreamInstance;
+}
+
+void AliHLTTPCDigitReaderPacked::ReleaseRawStreamInstance(AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream* pInstance)
+{
+ // see header file for class documentation
+ if (!pInstance) return;
+ if (pInstance!=fgpIssuedStreamInstance) {
+ HLTError("wrong instance %p, expecting %p", pInstance, fgpIssuedStreamInstance);
+ return;
+ }
+ fgpFreeStreamInstance=fgpIssuedStreamInstance;
+ fgpIssuedStreamInstance=NULL;
+}
+
+AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::AliHLTTPCRawStream()
+ :
+ fRawMemoryReader(new AliRawReaderMemory),
+ fTPCRawStream(new AliTPCRawStream(fRawMemoryReader))
+{
+ // see header file for class documentation
+}
+
+AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::~AliHLTTPCRawStream()
+{
+ // see header file for class documentation
+ if (fRawMemoryReader) delete fRawMemoryReader;
+ fRawMemoryReader=NULL;
+ if (fTPCRawStream) delete fTPCRawStream;
+ fTPCRawStream=NULL;
+}
+
+Bool_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::SetMemory(Int_t ddlId, UChar_t* memory, ULong_t size )
+{
+ // see header file for class documentation
+ if (!fRawMemoryReader) return false;
+ Bool_t result=fRawMemoryReader->SetMemory(memory, size );
+ fRawMemoryReader->SetEquipmentID(ddlId);
+ fRawMemoryReader->RewindEvents();
+ fRawMemoryReader->NextEvent();
+ return result;
+}
+
+bool AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::Next()
+{
+ // see header file for class documentation
+ if (!fTPCRawStream) return -1;
+ return fTPCRawStream->Next();
+}
+
+Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetRow() const
+{
+ // see header file for class documentation
+ if (!fTPCRawStream) return -1;
+ return fTPCRawStream->GetRow();
+}
+
+Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetPad() const
+{
+ // see header file for class documentation
+ if (!fTPCRawStream) return -1;
+ return fTPCRawStream->GetPad();
+}
+
+Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetTime() const
+{
+ // see header file for class documentation
+ if (!fTPCRawStream) return -1;
+ return fTPCRawStream->GetTime();
+}
+
+Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetSignal() const
+{
+ // see header file for class documentation
+ if (!fTPCRawStream) return -1;
+ return fTPCRawStream->GetSignal();
+}
+
+Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetHWAddress() const
+{
+ // see header file for class documentation
+ if (!fTPCRawStream) return -1;
+ return fTPCRawStream->GetHWAddress();
+}
+
+Bool_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetRCUTrailerData(UChar_t*& data) const
+{
+ // see header file for class documentation
+ if (!fTPCRawStream) return -1;
+ return fTPCRawStream->GetRCUTrailerData(data);
+}
+
+Int_t AliHLTTPCDigitReaderPacked::AliHLTTPCRawStream::GetRCUTrailerSize() const
+{
+ // see header file for class documentation
+ if (!fTPCRawStream) return -1;
+ return fTPCRawStream->GetRCUTrailerSize();
}
-#endif //defined(HAVE_ALIRAWDATA) && defined(HAVE_ALITPCRAWSTREAM_H)