Additiona TOF data members (S.Arcelli)
[u/mrichter/AliRoot.git] / FMD / AliFMDRawStream.cxx
CommitLineData
4347b38f 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
e802be3e 18//____________________________________________________________________
4347b38f 19//
20// Buffer to read RAW ALTRO FMD format from a AliRawReader
21//
7684b53c 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.
4347b38f 27//
e802be3e 28#include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H
56b1929b 29#include <AliRawReader.h> // ALIRAWREADER_H
1e8f773e 30#include <AliLog.h>
31#include <iomanip>
32#include <iostream>
4347b38f 33
34//____________________________________________________________________
925e6570 35ClassImp(AliFMDRawStream)
1a1fdef7 36#if 0
37 ; // This is here to keep Emacs for indenting the next line
38#endif
4347b38f 39
40//____________________________________________________________________
e802be3e 41AliFMDRawStream::AliFMDRawStream(AliRawReader* reader, UShort_t sampleRate)
4347b38f 42 : AliAltroRawStream(reader),
e802be3e 43 fSampleRate(sampleRate),
44 fPrevTime(-1),
1e8f773e 45 fExplicitSampleRate(kFALSE),
46 fPos(0),
47 fCur(0),
48 fRead(0)
e802be3e 49{
50 if (fSampleRate > 0) fExplicitSampleRate = kTRUE;
51}
4347b38f 52
53//_____________________________________________________________________________
1e8f773e 54Int_t
55AliFMDRawStream::ReadTrailer(UInt_t& addr, UInt_t& len)
56{
57 if (fPos <= 0) return 0;
58 if (fPos < 4) {
59 AliError("could not read trailer");
60 return -1;
61 }
62 AliDebug(1, Form("Reading a trailer at %d", fPos));
63 Int_t temp = Get10BitWord();
64 if (temp != 0x2AA) {
65 AliError(Form("Incorrect trailer! Expected 0x2AA but got %x!",temp));
66 return -1;
67 }
68 temp = Get10BitWord();
69 if ((temp >> 6) != 0xA) {
70 AliError(Form("Incorrect trailer! Expected 0xA but got %x!",temp >> 6));
71 return -1;
72 }
73
74 len = (temp << 4) & 0x3FF;
75 temp = Get10BitWord();
76 len |= (temp >> 6);
77 if (((temp >> 2) & 0xF) != 0xA) {
78 AliError(Form("Incorrect trailer! Expected 0xA but got %x!",temp >> 6));
79 return -1;
80 }
81 addr = (temp & 0x3) << 10;
82 temp = Get10BitWord();
83 addr |= temp;
84
85 return 4;
86}
87
88//_____________________________________________________________________________
89Int_t
90AliFMDRawStream::ReadFillWords(UInt_t len)
91{
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();
97 if (fill != 0x2AA) {
98 AliError(Form("Invalid fill! Expected 0x2AA, but got %X!", fill));
99 return -1;
100 }
101 }
102 return nFill;
103}
104
105//_____________________________________________________________________________
106Int_t
107AliFMDRawStream::ReadBunch(UShort_t* data)
108{
109 AliDebug(1, "Reading a bunch");
110 if (fPos <= 0) {
111 AliError("could not read bunch length");
112 return -1;
113 }
114 UShort_t len = Get10BitWord();
115 if (fPos <= 0) {
116 AliError("could not read bunch length");
117 return -1;
118 }
119 UShort_t time = Get10BitWord();
120
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();
124 if (amp < 0) {
125 AliError(Form("Bad adc value (%X) !", amp));
126 return -1;
127 }
128 data[time - (i-2)] = amp;
129 }
130 return len;
131}
132
133//_____________________________________________________________________________
134Int_t
135AliFMDRawStream::ReadIntoBuffer()
136{
137 if (fPos > 0) return kTRUE;
138 do {
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
144 // trailer?
145#if 0
146 UShort_t skip;
147 while ((skip = Get10BitWord()) != 0x2AA)
148 AliDebug(1,Form("Skipping one %x", skip));
149#endif
150 fPos++;
151 return fPos;
152}
153
154//_____________________________________________________________________________
155Bool_t
156AliFMDRawStream::ReadChannel(UInt_t& addr, UInt_t& len, UShort_t* data)
157{
158 Int_t ret = 0;
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;
163 Int_t toRead = len;
164 while (toRead > 0) {
165 if ((ret = ReadBunch(data)) < 0) return kFALSE;
166 toRead -= ret;
167 }
168 len -= 2;
169 return kTRUE;
170}
171
172//_____________________________________________________________________________
173Bool_t
174AliFMDRawStream::DumpData()
175{
176 Int_t ret;
177 if ((ret = ReadIntoBuffer()) < 0) return kFALSE;
178 UShort_t data;
179 Int_t i = 0;
180 while ((data = Get10BitWord()) != 0xffff) {
181 if (i % 4 == 0) {
182 if (i != 0) std::cout << "\n";
183 std::cout << std::setw(6) << i << ":";
184 }
185 std::cout << " 0x" << std::setfill('0') << std::setw(3)
186 << std::hex << data << std::dec << std::setfill(' ')
187 << std::flush;
188 i++;
189 }
190 return kTRUE;
191}
192
193//_____________________________________________________________________________
194UShort_t
195AliFMDRawStream::Get10BitWord()
196{
197 // return a word in a 10 bit array as an UShort_t
198 --fPos;
199 if (fPos < 0) {
200 AliWarning("At high water mark");
201 return 0xFFFF;
202 }
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;
207
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);
212 iByte++;
213 Int_t iByteLow = 4 * (iByte / 4) + 3 - (iByte % 4);
214 shift = 6 - shift;
215 return ((fRead[iByteHigh] * 256 + fRead[iByteLow]) >> shift) & 0x03FF;
216}
217
218//_____________________________________________________________________________
4347b38f 219Bool_t
220AliFMDRawStream::Next()
221{
222 // read the next raw digit
223 // returns kFALSE if there is no digit left
224 fPrevTime = fTime;
225 if (AliAltroRawStream::Next()) {
e802be3e 226 if (!fExplicitSampleRate && fPrevPad != fPad)
4347b38f 227 fSampleRate = fTimeBunch / 128;
4347b38f 228 return kTRUE;
229 }
230 return kFALSE;
231}
232
4347b38f 233//_____________________________________________________________________________
234//
235// EOF
236//