]>
Commit | Line | Data |
---|---|---|
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 | 35 | ClassImp(AliFMDRawStream) |
1a1fdef7 | 36 | #if 0 |
37 | ; // This is here to keep Emacs for indenting the next line | |
38 | #endif | |
4347b38f | 39 | |
40 | //____________________________________________________________________ | |
e802be3e | 41 | AliFMDRawStream::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 | |
1e8f773e | 53 | //_____________________________________________________________________________ |
54 | Int_t | |
55 | AliFMDRawStream::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 | //_____________________________________________________________________________ | |
89 | Int_t | |
90 | AliFMDRawStream::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 | //_____________________________________________________________________________ | |
106 | Int_t | |
107 | AliFMDRawStream::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 | //_____________________________________________________________________________ | |
134 | Int_t | |
135 | AliFMDRawStream::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 | //_____________________________________________________________________________ | |
155 | Bool_t | |
156 | AliFMDRawStream::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 | //_____________________________________________________________________________ | |
173 | Bool_t | |
174 | AliFMDRawStream::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 | //_____________________________________________________________________________ | |
194 | UShort_t | |
195 | AliFMDRawStream::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 | ||
4347b38f | 218 | //_____________________________________________________________________________ |
219 | Bool_t | |
220 | AliFMDRawStream::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 | // |