1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 //____________________________________________________________________
20 // Buffer to read RAW ALTRO FMD format from a AliRawReader
22 // This class derives from AliAltroBuffer, but overloads the memer
23 // function Next to do some extra processing. In particular, it tries
24 // to autodetect the sample rate. If zero-suppression was used when
25 // writing the raw data, then the automatic discovery will not work,
26 // and the sample rate should be set explicitly.
28 #include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H
29 #include <AliRawReader.h> // ALIRAWREADER_H
34 //____________________________________________________________________
35 ClassImp(AliFMDRawStream)
37 ; // This is here to keep Emacs for indenting the next line
40 //____________________________________________________________________
41 AliFMDRawStream::AliFMDRawStream(AliRawReader* reader, UShort_t sampleRate)
42 : AliAltroRawStream(reader),
43 fSampleRate(sampleRate),
45 fExplicitSampleRate(kFALSE),
50 if (fSampleRate > 0) fExplicitSampleRate = kTRUE;
53 //_____________________________________________________________________________
55 AliFMDRawStream::ReadTrailer(UInt_t& addr, UInt_t& len)
57 if (fPos <= 0) return 0;
59 AliError("could not read trailer");
62 AliDebug(1, Form("Reading a trailer at %d", fPos));
63 Int_t temp = Get10BitWord();
65 AliError(Form("Incorrect trailer! Expected 0x2AA but got %x!",temp));
68 temp = Get10BitWord();
69 if ((temp >> 6) != 0xA) {
70 AliError(Form("Incorrect trailer! Expected 0xA but got %x!",temp >> 6));
74 len = (temp << 4) & 0x3FF;
75 temp = Get10BitWord();
77 if (((temp >> 2) & 0xF) != 0xA) {
78 AliError(Form("Incorrect trailer! Expected 0xA but got %x!",temp >> 6));
81 addr = (temp & 0x3) << 10;
82 temp = Get10BitWord();
88 //_____________________________________________________________________________
90 AliFMDRawStream::ReadFillWords(UInt_t len)
92 if (len % 4 == 0) return 0;
93 Int_t nFill = (4 - (len % 4)) % 4;
94 AliDebug(1, Form("Reading %d fill words", nFill));
95 for (Int_t i = 0; i < nFill; i++) {
96 UInt_t fill = Get10BitWord();
98 AliError(Form("Invalid fill! Expected 0x2AA, but got %X!", fill));
105 //_____________________________________________________________________________
107 AliFMDRawStream::ReadBunch(UShort_t* data)
109 AliDebug(1, "Reading a bunch");
111 AliError("could not read bunch length");
114 UShort_t len = Get10BitWord();
116 AliError("could not read bunch length");
119 UShort_t time = Get10BitWord();
121 AliDebug(1, Form("Bunch is %d long and ends at t=%d", len, time));
122 for (UInt_t i = 2; i < len; i++) {
123 Int_t amp = Get10BitWord();
125 AliError(Form("Bad adc value (%X) !", amp));
128 data[time - (i-2)] = amp;
133 //_____________________________________________________________________________
135 AliFMDRawStream::ReadIntoBuffer()
137 if (fPos > 0) return kTRUE;
139 AliDebug(1, Form("Reading into the buffer"));
140 if (!fRawReader->ReadNextData(fRead)) return -1;
141 } while (fRawReader->GetDataSize() == 0);
142 fPos = (fRawReader->GetDataSize() * 8) / 10;
143 // Skip trailing `0x2AA's - is this needed? Won't it break the
147 while ((skip = Get10BitWord()) != 0x2AA)
148 AliDebug(1,Form("Skipping one %x", skip));
154 //_____________________________________________________________________________
156 AliFMDRawStream::ReadChannel(UInt_t& addr, UInt_t& len, UShort_t* data)
159 AliDebug(1, "Reading a channel");
160 if ((ret = ReadIntoBuffer()) < 0) return kFALSE;
161 if ((ret = ReadTrailer(addr, len)) < 0) return kFALSE;
162 if ((ret = ReadFillWords(len)) < 0) return kFALSE;
165 if ((ret = ReadBunch(data)) < 0) return kFALSE;
172 //_____________________________________________________________________________
174 AliFMDRawStream::DumpData()
177 if ((ret = ReadIntoBuffer()) < 0) return kFALSE;
180 while ((data = Get10BitWord()) != 0xffff) {
182 if (i != 0) std::cout << "\n";
183 std::cout << std::setw(6) << i << ":";
185 std::cout << " 0x" << std::setfill('0') << std::setw(3)
186 << std::hex << data << std::dec << std::setfill(' ')
193 //_____________________________________________________________________________
195 AliFMDRawStream::Get10BitWord()
197 // return a word in a 10 bit array as an UShort_t
200 AliWarning("At high water mark");
203 Int_t iBit = fPos * 10;
204 Int_t iByte = iBit / 8;
205 Int_t shift = iBit % 8;
206 // return ((buffer[iByte+1] * 256 + buffer[iByte]) >> shift) & 0x03FF;
208 // recalculate the byte numbers and the shift because
209 // the raw data is written as integers where the high bits are filled first
210 // -> little endian is assumed here !
211 Int_t iByteHigh = 4 * (iByte / 4) + 3 - (iByte % 4);
213 Int_t iByteLow = 4 * (iByte / 4) + 3 - (iByte % 4);
215 return ((fRead[iByteHigh] * 256 + fRead[iByteLow]) >> shift) & 0x03FF;
218 //_____________________________________________________________________________
220 AliFMDRawStream::Next()
222 // read the next raw digit
223 // returns kFALSE if there is no digit left
225 if (AliAltroRawStream::Next()) {
226 if (!fExplicitSampleRate && fPrevPad != fPad)
227 fSampleRate = fTimeBunch / 128;
233 //_____________________________________________________________________________