* provided "as is" without express or implied warranty. *
**************************************************************************/
+/* $Id$ */
+
///////////////////////////////////////////////////////////////////////////////
-//
-// This is a base class for reading TPC raw data and providing
-// information about digits
-//
+///
+/// This class provides access to TPC digits in raw data.
+///
+/// It loops over all TPC digits in the raw data given by the AliRawReader.
+/// The Next method goes to the next digit. If there are no digits left
+/// it returns kFALSE.
+/// Several getters provide information about the current digit.
+///
///////////////////////////////////////////////////////////////////////////////
+#include <TSystem.h>
+
#include "AliTPCRawStream.h"
-#include "AliTPCHuffman.h"
+#include "AliRawReader.h"
+#include "AliLog.h"
+#include "AliTPCAltroMapping.h"
ClassImp(AliTPCRawStream)
+//_____________________________________________________________________________
+AliTPCRawStream::AliTPCRawStream(AliRawReader* rawReader, AliAltroMapping **mapping) :
+ AliAltroRawStream(rawReader),
+ fSector(-1),
+ fPrevSector(-1),
+ fRow(-1),
+ fPrevRow(-1),
+ fPad(-1),
+ fPrevPad(-1),
+ fIsMapOwner(kFALSE)
+{
+ // create an object to read TPC raw digits
+
+ SelectRawData("TPC");
+
+ if (mapping == NULL) {
+ TString path = gSystem->Getenv("ALICE_ROOT");
+ path += "/TPC/mapping/Patch";
+ TString path2;
+ for(Int_t i = 0; i < 6; i++) {
+ path2 = path;
+ path2 += i;
+ path2 += ".data";
+ fMapping[i] = new AliTPCAltroMapping(path2.Data());
+ }
+ fIsMapOwner = kTRUE;
+ }
+ else {
+ for(Int_t i = 0; i < 6; i++)
+ fMapping[i] = mapping[i];
+ }
+
+}
-AliTPCHNode** AliTPCRawStream::fgRootNode = NULL;
-
+//_____________________________________________________________________________
+AliTPCRawStream::AliTPCRawStream(const AliTPCRawStream& stream) :
+ AliAltroRawStream(stream),
+ fSector(stream.fSector),
+ fPrevSector(stream.fPrevSector),
+ fRow(stream.fRow),
+ fPrevRow(stream.fPrevRow),
+ fPad(stream.fPad),
+ fPrevPad(stream.fPrevPad),
+ fIsMapOwner(kFALSE)
+{
+ for(Int_t i = 0; i < 6; i++) fMapping[i] = stream.fMapping[i];
+}
-AliTPCRawStream::AliTPCRawStream(AliRawReader* rawReader)
+//_____________________________________________________________________________
+AliTPCRawStream& AliTPCRawStream::operator = (const AliTPCRawStream& stream)
{
-// create an object to read TPC raw digits
+ if(&stream == this) return *this;
- fRawReader = rawReader;
- fRawReader->Select(0);
- fData = new UShort_t[kDataMax];
- fDataSize = fPosition = 0;
- fCount = fBunchLength = 0;
+ ((AliAltroRawStream *)this)->operator=(stream);
- if (!fgRootNode) {
- fgRootNode = new AliTPCHNode*[kNumTables];
- fCompression.CreateTreesFromFile(fgRootNode, kNumTables);
- }
+ fSector = stream.fSector;
+ fPrevSector = stream.fPrevSector;
+ fRow = stream.fRow;
+ fPrevRow = stream.fPrevRow;
+ fPad = stream.fPad;
+ fPrevPad = stream.fPrevPad;
+ fIsMapOwner = kFALSE;
+
+ for(Int_t i = 0; i < 6; i++) fMapping[i] = stream.fMapping[i];
- fSector = fPrevSector = fRow = fPrevRow = fPad = fPrevPad = fTime = fSignal = -1;
+ return *this;
}
+//_____________________________________________________________________________
AliTPCRawStream::~AliTPCRawStream()
{
-// clean up
+// destructor
- delete[] fData;
+ if (fIsMapOwner)
+ for(Int_t i = 0; i < 6; i++) delete fMapping[i];
}
+//_____________________________________________________________________________
+void AliTPCRawStream::Reset()
+{
+ // reset tpc raw stream params
+ AliAltroRawStream::Reset();
+ fSector = fPrevSector = fRow = fPrevRow = fPad = fPrevPad = -1;
+}
+//_____________________________________________________________________________
Bool_t AliTPCRawStream::Next()
{
-// read the next raw digit
-// returns kFALSE if there is no digit left
-
+ // Read next TPC signal
+ // Apply the TPC altro mapping to get
+ // the sector,pad-row and pad indeces
fPrevSector = fSector;
fPrevRow = fRow;
fPrevPad = fPad;
-
- while (fCount == 0) { // next trailer
- if (fPosition >= fDataSize) { // next payload
- UChar_t* data;
- do {
- if (!fRawReader->ReadNextData(data)) return kFALSE;
- } while (fRawReader->GetDataSize() == 0);
-
- if (fRawReader->IsCompressed()) { // compressed data
- ULong_t size = 0;
- fCompression.Decompress(fgRootNode, kNumTables,
- (char*) data, fRawReader->GetDataSize(),
- fData, size);
- fDataSize = size;
-
- } else { // uncompressed data
- fDataSize = 0;
- Int_t pos = (fRawReader->GetDataSize() * 8) / 10;
- while (Get10BitWord(data, pos-1) == 0x2AA) pos--;
- while (pos > 0) {
- for (Int_t i = 0; i < 4; i++) { // copy trailer
- fData[fDataSize++] = Get10BitWord(data, pos-4+i);
- }
- pos -= 4;
- Int_t count = fData[fDataSize-4];
- pos -= (4 - (count % 4)) % 4; // skip fill words
-
- while (count > 0) {
- UShort_t bunchLength = Get10BitWord(data, pos-1);
- fData[fDataSize++] = bunchLength;
- fData[fDataSize++] = Get10BitWord(data, pos-2); // time bin
-
- // copy signal amplitudes in increasing order on time
- for (Int_t i = 0; i < bunchLength-2; i++) {
- fData[fDataSize++] = Get10BitWord(data, pos - bunchLength + i);
- }
- pos -= bunchLength;
- count -= bunchLength;
- }
- }
- }
-
- fPosition = 0;
- }
- if (fPosition + 4 >= fDataSize) {
- Error("Next", "could not read trailer");
- return kFALSE;
- }
- fCount = fData[fPosition++];
- fPad = fData[fPosition++];
- fRow = fData[fPosition++];
- fSector = fData[fPosition++];
- fBunchLength = 0;
+ if (AliAltroRawStream::Next()) {
+ if (IsNewHWAddress())
+ ApplyAltroMapping();
+ return kTRUE;
}
+ else
+ return kFALSE;
+}
- if (fBunchLength == 0) {
- if (fPosition >= fDataSize) {
- Error("Next", "could not read bunch length");
- return kFALSE;
- }
- fBunchLength = fData[fPosition++] - 2;
- fCount--;
-
- if (fPosition >= fDataSize) {
- Error("Next", "could not read time bin");
- return kFALSE;
- }
- fTime = fData[fPosition++] - fBunchLength;
- fCount--;
+//_____________________________________________________________________________
+void AliTPCRawStream::ApplyAltroMapping()
+{
+ // Take the DDL index, load
+ // the corresponding altro mapping
+ // object and fill the sector,row and pad indeces
+ Int_t ddlNumber = GetDDLNumber();
+ Int_t patchIndex;
+ if (ddlNumber < 72) {
+ fSector = ddlNumber / 2;
+ patchIndex = ddlNumber % 2;
}
-
- fTime++;
- if (fPosition >= fDataSize) {
- Error("Next", "could not read sample amplitude");
- return kFALSE;
+ else {
+ fSector = (ddlNumber - 72) / 4 + 36;
+ patchIndex = (ddlNumber - 72) % 4 + 2;
}
- fSignal = fData[fPosition++] + kOffset;
- fCount--;
- fBunchLength--;
-
- return kTRUE;
-}
+ Short_t hwAddress = GetHWAddress();
+ fRow = fMapping[patchIndex]->GetPadRow(hwAddress);
+ fPad = fMapping[patchIndex]->GetPad(hwAddress);
-UShort_t AliTPCRawStream::Get10BitWord(UChar_t* buffer, Int_t position)
-// return a word in a 10 bit array as an UShort_t
-{
- Int_t iBit = position * 10;
- Int_t iByte = iBit / 8;
- Int_t shift = iBit % 8;
-// return ((buffer[iByte+1] * 256 + buffer[iByte]) >> shift) & 0x03FF;
-
- // recalculate the byte numbers and the shift because
- // the raw data is written as integers where the high bits are filled first
- // -> little endian is assumed here !
- Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4);
- iByte++;
- Int_t iByteLow = 4 * (iByte / 4) + 3 - (iByte % 4);
- shift = 6 - shift;
- return ((buffer[iByteHigh] * 256 + buffer[iByteLow]) >> shift) & 0x03FF;
+ if ((fRow < 0) || (fPad < 0))
+ AddMappingErrorLog(Form("hw=%d",hwAddress));
}