// and the sample rate should be set explicitly.
//
#include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H
-#include <AliRawReader.h> // ALIRAWREADER_H
-#include <AliLog.h>
-#include <iomanip>
-#include <iostream>
+// #include <AliRawReader.h> // ALIRAWREADER_H
+#include "AliFMDParameters.h"
+// #include <AliLog.h>
+#include "AliFMDDebug.h" // Better debug macros
+// #include <iomanip>
+// #include <iostream>
+#include "AliRawReader.h"
+#include <climits>
//____________________________________________________________________
ClassImp(AliFMDRawStream)
#endif
//____________________________________________________________________
-AliFMDRawStream::AliFMDRawStream(AliRawReader* reader, UShort_t sampleRate)
- : AliAltroRawStream(reader),
- fSampleRate(sampleRate),
- fPrevTime(-1),
- fExplicitSampleRate(kFALSE),
- fPos(0),
- fCur(0),
- fRead(0)
+AliFMDRawStream::AliFMDRawStream(AliRawReader* reader)
+ : AliAltroRawStream(reader)
{
- if (fSampleRate > 0) fExplicitSampleRate = kTRUE;
+ // CTOR
+ reader->Reset();
+ // Select FMD DDL's
+ SelectRawData("FMD");
}
//_____________________________________________________________________________
-Int_t
-AliFMDRawStream::ReadTrailer(UInt_t& addr, UInt_t& len)
-{
- if (fPos <= 0) return 0;
- if (fPos < 4) {
- AliError("could not read trailer");
- return -1;
- }
- AliDebug(1, Form("Reading a trailer at %d", fPos));
- Int_t temp = Get10BitWord();
- if (temp != 0x2AA) {
- AliError(Form("Incorrect trailer! Expected 0x2AA but got %x!",temp));
- return -1;
- }
- temp = Get10BitWord();
- if ((temp >> 6) != 0xA) {
- AliError(Form("Incorrect trailer! Expected 0xA but got %x!",temp >> 6));
- return -1;
- }
-
- len = (temp << 4) & 0x3FF;
- temp = Get10BitWord();
- len |= (temp >> 6);
- if (((temp >> 2) & 0xF) != 0xA) {
- AliError(Form("Incorrect trailer! Expected 0xA but got %x!",temp >> 6));
- return -1;
- }
- addr = (temp & 0x3) << 10;
- temp = Get10BitWord();
- addr |= temp;
-
- return 4;
-}
-
-//_____________________________________________________________________________
-Int_t
-AliFMDRawStream::ReadFillWords(UInt_t len)
+Bool_t
+AliFMDRawStream::ReadChannel(UInt_t& ddl, UInt_t& addr,
+ UInt_t& len, volatile UShort_t* data)
{
- if (len % 4 == 0) return 0;
- Int_t nFill = (4 - (len % 4)) % 4;
- AliDebug(1, Form("Reading %d fill words", nFill));
- for (Int_t i = 0; i < nFill; i++) {
- UInt_t fill = Get10BitWord();
- if (fill != 0x2AA) {
- AliError(Form("Invalid fill! Expected 0x2AA, but got %X!", fill));
- return -1;
+ // Read one channel and return. Returns 0 when there's no more
+ // data.
+ Int_t l = 0;
+ static Int_t last = 0xFFFF; // 0xFFFF means signal is used
+ Bool_t next = kTRUE;
+ do {
+ Int_t signal = last;
+ if (last > 0x3FF) {
+ AliFMDDebug(30, ("Last is 0x%x, so reading a new word", last));
+ next = Next();
+ if(!next){
+ AliFMDDebug(15, ("Read word # %d (!next)", l));
+ addr = GetPrevHWAddress();
+ ddl = (GetPrevDDLNumber() < 0 ? UINT_MAX: UInt_t(GetPrevDDLNumber()));
+ len = l+1; // Need to add one - l points to last valid index
+ last = signal;
+ break;
+ }
+ signal = GetSignal();
+ if (GetHWAddress() != GetPrevHWAddress() && GetPrevHWAddress() >= 0) {
+ AliFMDDebug(15, ("New hardware address, was 0x%x, now 0x%x",
+ GetPrevHWAddress(), GetHWAddress()));
+ addr = GetPrevHWAddress();
+ ddl = (GetPrevDDLNumber() < 0 ? UINT_MAX : UInt_t(GetPrevDDLNumber()));
+ len = l+1; // Need to add one - l points to last valid index
+ last = signal;
+ break;
+ }
}
- }
- return nFill;
-}
-
-//_____________________________________________________________________________
-Int_t
-AliFMDRawStream::ReadBunch(UShort_t* data)
-{
- AliDebug(1, "Reading a bunch");
- if (fPos <= 0) {
- AliError("could not read bunch length");
- return -1;
- }
- UShort_t len = Get10BitWord();
- if (fPos <= 0) {
- AliError("could not read bunch length");
- return -1;
- }
- UShort_t time = Get10BitWord();
-
- AliDebug(1, Form("Bunch is %d long and ends at t=%d", len, time));
- for (UInt_t i = 2; i < len; i++) {
- Int_t amp = Get10BitWord();
- if (amp < 0) {
- AliError(Form("Bad adc value (%X) !", amp));
- return -1;
+ // Sanity check - if the total bunch length is less than 1, then
+ // read until we get the next bunch.
+ Int_t b = GetTimeLength();
+ if (b < 1) {
+ AliWarning(Form("Bunch length %0d is less than 0 for "
+ "DDL %4d address 0x%03x",
+ b, ddl, addr));
+ last = 0xFFFF;
+ continue;
}
- data[time - (i-2)] = amp;
- }
- return len;
-}
-//_____________________________________________________________________________
-Int_t
-AliFMDRawStream::ReadIntoBuffer()
-{
- if (fPos > 0) return kTRUE;
- do {
- AliDebug(1, Form("Reading into the buffer"));
- if (!fRawReader->ReadNextData(fRead)) return -1;
- } while (fRawReader->GetDataSize() == 0);
- fPos = (fRawReader->GetDataSize() * 8) / 10;
- // Skip trailing `0x2AA's - is this needed? Won't it break the
- // trailer?
+ // Sanity check - if the current time is less than 0, then read
+ // until we get a new bunch.
+ Int_t t = GetTime();
+ if (t < 0) {
+ AliWarning(Form("Time %0d is less than 0 for DDL %4d address 0x%03x",
+ t, ddl, addr));
+ last = 0xFFFF;
+ continue;
+ }
+ l = TMath::Max(l, t);
+ data[t] = signal;
+ last = 0xFFFF;
#if 0
- UShort_t skip;
- while ((skip = Get10BitWord()) != 0x2AA)
- AliDebug(1,Form("Skipping one %x", skip));
+ AliFMDDebug(signal > 512 ? 1 : 0, ("Signal @ %d (%d) is %d",
+ time, t, data[t]));
#endif
- fPos++;
- return fPos;
+ } while (next);
+ return next;
}
-//_____________________________________________________________________________
-Bool_t
-AliFMDRawStream::ReadChannel(UInt_t& addr, UInt_t& len, UShort_t* data)
-{
- Int_t ret = 0;
- AliDebug(1, "Reading a channel");
- if ((ret = ReadIntoBuffer()) < 0) return kFALSE;
- if ((ret = ReadTrailer(addr, len)) < 0) return kFALSE;
- if ((ret = ReadFillWords(len)) < 0) return kFALSE;
- Int_t toRead = len;
- while (toRead > 0) {
- if ((ret = ReadBunch(data)) < 0) return kFALSE;
- toRead -= ret;
- }
- len -= 2;
- return kTRUE;
-}
-
-//_____________________________________________________________________________
-Bool_t
-AliFMDRawStream::DumpData()
-{
- Int_t ret;
- if ((ret = ReadIntoBuffer()) < 0) return kFALSE;
- UShort_t data;
- Int_t i = 0;
- while ((data = Get10BitWord()) != 0xffff) {
- if (i % 4 == 0) {
- if (i != 0) std::cout << "\n";
- std::cout << std::setw(6) << i << ":";
- }
- std::cout << " 0x" << std::setfill('0') << std::setw(3)
- << std::hex << data << std::dec << std::setfill(' ')
- << std::flush;
- i++;
- }
- return kTRUE;
-}
-
-//_____________________________________________________________________________
-UShort_t
-AliFMDRawStream::Get10BitWord()
-{
- // return a word in a 10 bit array as an UShort_t
- --fPos;
- if (fPos < 0) {
- AliWarning("At high water mark");
- return 0xFFFF;
- }
- Int_t iBit = fPos * 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 ((fRead[iByteHigh] * 256 + fRead[iByteLow]) >> shift) & 0x03FF;
-}
-
-//_____________________________________________________________________________
-Bool_t
-AliFMDRawStream::Next()
-{
- // read the next raw digit
- // returns kFALSE if there is no digit left
- fPrevTime = fTime;
- if (AliAltroRawStream::Next()) {
- if (!fExplicitSampleRate && fPrevPad != fPad)
- fSampleRate = fTimeBunch / 128;
- return kTRUE;
- }
- return kFALSE;
-}
//_____________________________________________________________________________
//