]>
Commit | Line | Data |
---|---|---|
3ea47630 | 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 | ||
18 | /////////////////////////////////////////////////////////////////////////////// | |
19 | /// | |
20 | /// This class provides access to Altro digits in raw data. | |
21 | /// | |
22 | /// It loops over all Altro digits in the raw data given by the AliRawReader. | |
23 | /// The Next method goes to the next digit. If there are no digits left | |
24 | /// it returns kFALSE. | |
25 | /// Several getters provide information about the current digit. | |
26 | /// | |
27 | /////////////////////////////////////////////////////////////////////////////// | |
28 | ||
29 | #include "AliAltroRawStream.h" | |
30 | #include "AliRawReader.h" | |
3a291af4 | 31 | #include "AliLog.h" |
3ea47630 | 32 | |
33 | ClassImp(AliAltroRawStream) | |
34 | ||
35 | ||
36 | //_____________________________________________________________________________ | |
37 | AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) : | |
e7fd2555 | 38 | fNoAltroMapping(kTRUE), |
39 | fDDLNumber(-1), | |
40 | fPrevDDLNumber(-1), | |
5e6235b5 | 41 | fRCUId(-1), |
42 | fPrevRCUId(-1), | |
3a291af4 | 43 | fHWAddress(-1), |
44 | fPrevHWAddress(-1), | |
3ea47630 | 45 | fTime(-1), |
e7fd2555 | 46 | fPrevTime(-1), |
3ea47630 | 47 | fSignal(-1), |
e7fd2555 | 48 | fTimeBunch(-1), |
3ea47630 | 49 | fRawReader(rawReader), |
50 | fData(NULL), | |
51 | fPosition(0), | |
52 | fCount(0), | |
5e6235b5 | 53 | fBunchLength(0), |
54 | fRCUTrailerData(NULL), | |
55 | fRCUTrailerSize(0) | |
3ea47630 | 56 | { |
57 | // create an object to read Altro raw digits | |
e7fd2555 | 58 | fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1; |
3ea47630 | 59 | } |
60 | ||
61 | //_____________________________________________________________________________ | |
62 | AliAltroRawStream::AliAltroRawStream(const AliAltroRawStream& stream) : | |
63 | TObject(stream), | |
e7fd2555 | 64 | fNoAltroMapping(kTRUE), |
65 | fDDLNumber(-1), | |
66 | fPrevDDLNumber(-1), | |
5e6235b5 | 67 | fRCUId(-1), |
68 | fPrevRCUId(-1), | |
3a291af4 | 69 | fHWAddress(-1), |
70 | fPrevHWAddress(-1), | |
3ea47630 | 71 | fTime(-1), |
e7fd2555 | 72 | fPrevTime(-1), |
3ea47630 | 73 | fSignal(-1), |
e7fd2555 | 74 | fTimeBunch(-1), |
3ea47630 | 75 | fRawReader(NULL), |
76 | fData(NULL), | |
77 | fPosition(0), | |
78 | fCount(0), | |
5e6235b5 | 79 | fBunchLength(0), |
80 | fRCUTrailerData(NULL), | |
81 | fRCUTrailerSize(0) | |
3ea47630 | 82 | { |
83 | Fatal("AliAltroRawStream", "copy constructor not implemented"); | |
84 | } | |
85 | ||
86 | //_____________________________________________________________________________ | |
87 | AliAltroRawStream& AliAltroRawStream::operator = (const AliAltroRawStream& | |
88 | /* stream */) | |
89 | { | |
90 | Fatal("operator =", "assignment operator not implemented"); | |
91 | return *this; | |
92 | } | |
93 | ||
94 | //_____________________________________________________________________________ | |
95 | AliAltroRawStream::~AliAltroRawStream() | |
96 | { | |
97 | // clean up | |
98 | ||
99 | } | |
100 | ||
3a291af4 | 101 | //_____________________________________________________________________________ |
102 | void AliAltroRawStream::Reset() | |
103 | { | |
104 | // reset altro raw stream params | |
105 | ||
106 | fPosition = fCount = fBunchLength = 0; | |
107 | ||
5e6235b5 | 108 | fRCUTrailerData = NULL; |
109 | fRCUTrailerSize = 0; | |
110 | ||
111 | fDDLNumber = fPrevDDLNumber = fRCUId = fPrevRCUId = fHWAddress = fPrevHWAddress = fTime = fPrevTime = fSignal = fTimeBunch = -1; | |
3a291af4 | 112 | |
113 | if (fRawReader) fRawReader->Reset(); | |
e7fd2555 | 114 | |
115 | fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1; | |
3a291af4 | 116 | } |
3ea47630 | 117 | |
118 | //_____________________________________________________________________________ | |
119 | Bool_t AliAltroRawStream::Next() | |
120 | { | |
121 | // read the next raw digit | |
122 | // returns kFALSE if there is no digit left | |
123 | ||
e7fd2555 | 124 | fPrevDDLNumber = fDDLNumber; |
5e6235b5 | 125 | fPrevRCUId = fRCUId; |
3a291af4 | 126 | fPrevHWAddress = fHWAddress; |
e7fd2555 | 127 | fPrevTime = fTime; |
3ea47630 | 128 | |
129 | while (fCount == 0) { // next trailer | |
130 | if (fPosition <= 0) { // next payload | |
131 | do { | |
132 | if (!fRawReader->ReadNextData(fData)) return kFALSE; | |
133 | } while (fRawReader->GetDataSize() == 0); | |
134 | ||
e7fd2555 | 135 | fDDLNumber = fRawReader->GetDDLID(); |
136 | ||
3a291af4 | 137 | fPosition = GetPosition(); |
3ea47630 | 138 | } |
3ea47630 | 139 | |
3a291af4 | 140 | if (!ReadTrailer()) |
141 | AliFatal("Incorrect trailer information !"); | |
3ea47630 | 142 | |
3a291af4 | 143 | fBunchLength = 0; |
3ea47630 | 144 | } |
145 | ||
3a291af4 | 146 | if (fBunchLength == 0) ReadBunch(); |
147 | else fTime--; | |
148 | ||
149 | ReadAmplitude(); | |
3ea47630 | 150 | |
151 | return kTRUE; | |
152 | } | |
153 | ||
e7fd2555 | 154 | //_____________________________________________________________________________ |
155 | void AliAltroRawStream::SelectRawData(Int_t detId) | |
156 | { | |
157 | // Select the raw data for specific | |
158 | // detector id | |
159 | AliDebug(1,Form("Selecting raw data for detector %d",detId)); | |
160 | fRawReader->Select(detId); | |
161 | } | |
162 | ||
3ea47630 | 163 | //_____________________________________________________________________________ |
3a291af4 | 164 | UShort_t AliAltroRawStream::GetNextWord() |
3ea47630 | 165 | { |
3a291af4 | 166 | // Read the next 10 bit word in backward direction |
167 | // The input stream access is given by fData and fPosition | |
3ea47630 | 168 | |
3a291af4 | 169 | fPosition--; |
170 | ||
171 | Int_t iBit = fPosition * 10; | |
3ea47630 | 172 | Int_t iByte = iBit / 8; |
173 | Int_t shift = iBit % 8; | |
3ea47630 | 174 | |
5e6235b5 | 175 | // the raw data is written as integers where the low bits are filled first |
3ea47630 | 176 | // -> little endian is assumed here ! |
5e6235b5 | 177 | Int_t iByteLow = iByte; |
3ea47630 | 178 | iByte++; |
5e6235b5 | 179 | Int_t iByteHigh = iByte; |
3a291af4 | 180 | return ((fData[iByteHigh] * 256 + fData[iByteLow]) >> shift) & 0x03FF; |
181 | } | |
182 | ||
183 | //_____________________________________________________________________________ | |
184 | Bool_t AliAltroRawStream::ReadTrailer() | |
185 | { | |
186 | //Read a trailer of 40 bits in the backward reading mode | |
187 | //In case of no mapping is provided, read a dummy trailer | |
188 | if (fNoAltroMapping) { | |
189 | AliError("No ALTRO mapping information is loaded! Reading a dummy trailer!"); | |
190 | return ReadDummyTrailer(); | |
191 | } | |
192 | ||
193 | //First reading filling words | |
194 | UShort_t temp; | |
195 | Int_t nFillWords = 0; | |
196 | while ((temp = GetNextWord()) == 0x2AA) nFillWords++; | |
197 | if (nFillWords == 0) | |
198 | AliFatal("Incorrect trailer found ! Expected 0x2AA not found !"); | |
199 | ||
200 | //Then read the trailer | |
201 | if (fPosition <= 4) | |
202 | AliFatal(Form("Incorrect raw data size ! Expected at lest 4 words but found %d !",fPosition)); | |
203 | ||
204 | fCount = (temp << 4) & 0x3FF; | |
205 | if ((temp >> 6) != 0xA) | |
206 | AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6)); | |
207 | ||
208 | temp = GetNextWord(); | |
209 | fHWAddress = (temp & 0x3) << 10; | |
210 | if (((temp >> 2) & 0xF) != 0xA) | |
211 | AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",(temp >> 2) & 0xF)); | |
212 | fCount |= ((temp & 0x3FF) >> 6); | |
213 | if (fCount == 0) return kFALSE; | |
214 | ||
215 | temp = GetNextWord(); | |
216 | fHWAddress |= temp; | |
217 | ||
218 | fPosition -= (4 - (fCount % 4)) % 4; // skip fill words | |
219 | ||
3a291af4 | 220 | return kTRUE; |
221 | } | |
222 | ||
223 | //_____________________________________________________________________________ | |
224 | Bool_t AliAltroRawStream::ReadDummyTrailer() | |
225 | { | |
226 | //Read a trailer of 40 bits in the backward reading mode | |
227 | //In case of no mapping is provided, read a dummy trailer | |
228 | UShort_t temp; | |
229 | while ((temp = GetNextWord()) == 0x2AA); | |
230 | ||
e7fd2555 | 231 | fSegmentation[0] = temp; |
232 | fSegmentation[1] = GetNextWord(); | |
233 | fSegmentation[2] = GetNextWord(); | |
3a291af4 | 234 | fCount = GetNextWord(); |
235 | if (fCount == 0) return kFALSE; | |
236 | fHWAddress = -1; | |
237 | ||
e7fd2555 | 238 | fPosition -= (4 - (fCount % 4)) % 4; // skip fill words |
239 | ||
3a291af4 | 240 | return kTRUE; |
241 | } | |
242 | ||
243 | //_____________________________________________________________________________ | |
244 | void AliAltroRawStream::ReadBunch() | |
245 | { | |
246 | // Read altro payload in | |
247 | // backward direction | |
248 | if (fPosition <= 0) | |
249 | AliFatal("Could not read bunch length !"); | |
250 | ||
251 | fBunchLength = GetNextWord() - 2; | |
252 | fTimeBunch = fBunchLength; | |
253 | fCount--; | |
254 | ||
255 | if (fPosition <= 0) | |
256 | AliFatal("Could not read time bin !"); | |
257 | ||
258 | fTime = GetNextWord(); | |
259 | fCount--; | |
260 | ||
261 | return; | |
262 | } | |
263 | ||
264 | //_____________________________________________________________________________ | |
265 | void AliAltroRawStream::ReadAmplitude() | |
266 | { | |
267 | // Read next time bin amplitude | |
268 | if (fPosition <= 0) | |
269 | AliFatal("Could not read sample amplitude !"); | |
270 | ||
271 | fSignal = GetNextWord(); | |
272 | fCount--; | |
273 | fBunchLength--; | |
274 | ||
275 | return; | |
276 | } | |
277 | ||
278 | //_____________________________________________________________________________ | |
279 | Int_t AliAltroRawStream::GetPosition() | |
280 | { | |
281 | // Sets the position in the | |
282 | // input stream | |
5e6235b5 | 283 | // Read the RCU trailer |
284 | // This includes the trailer size, | |
285 | // RCU identifier and raw data payload. | |
286 | // The RCU trailer format is described | |
287 | // in details in the RCU manual. | |
288 | ||
289 | // First read 32-bit word with the | |
290 | // trailer size (22 bits) and RCU ID (the rest) | |
291 | Int_t index = fRawReader->GetDataSize(); | |
292 | UInt_t word = Get32bitWord(index); | |
293 | fRCUId = (Int_t)(word >> 22); | |
294 | Int_t trailerSize = (word & 0x3FFFFF); | |
295 | ||
296 | // Now read the beginning of the trailer | |
297 | // where the payload size is written | |
298 | if (trailerSize < 2) | |
299 | AliFatal(Form("Invalid trailer size found (%d bytes) !",trailerSize*4)); | |
300 | fRCUTrailerSize = (trailerSize-2)*4; | |
301 | index -= fRCUTrailerSize; | |
302 | if (index < 4) | |
303 | AliFatal(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!", | |
304 | trailerSize*4, | |
305 | fRawReader->GetDataSize())); | |
306 | fRCUTrailerData = fData + index; | |
307 | Int_t position = Get32bitWord(index); | |
308 | // The size is specified in a number of 40bits | |
309 | // Therefore we need to transform it to number of bytes | |
310 | position *= 5; | |
311 | ||
312 | // Check the consistency of the header and trailer | |
313 | if ((fRawReader->GetDataSize() - trailerSize*4) != position) | |
314 | AliFatal(Form("Inconsistent raw data size ! Raw data size - %d bytes (from the header), RCU trailer - %d bytes, raw data paylod - %d bytes !", | |
315 | fRawReader->GetDataSize(), | |
316 | trailerSize*4, | |
317 | position)); | |
318 | ||
319 | return position * 8 / 10; | |
320 | } | |
321 | ||
322 | //_____________________________________________________________________________ | |
323 | UInt_t AliAltroRawStream::Get32bitWord(Int_t &index) | |
324 | { | |
325 | // This method returns the 32 bit word at a given | |
326 | // position inside the raw data payload. | |
327 | // The 'index' points to the beginning of the next word. | |
328 | // The method is supposed to be endian (platform) | |
329 | // independent. | |
330 | if (!fData) | |
331 | AliFatal("Raw data paylod buffer is not yet initialized !"); | |
332 | if (index < 4) | |
333 | AliFatal(Form("Invalid raw data payload index (%d) !",index)); | |
334 | ||
335 | UInt_t word = 0; | |
336 | word = fData[--index] << 24; | |
337 | word |= fData[--index] << 16; | |
338 | word |= fData[--index] << 8; | |
339 | word |= fData[--index]; | |
340 | ||
341 | return word; | |
342 | } | |
343 | ||
344 | //_____________________________________________________________________________ | |
345 | Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const | |
346 | { | |
347 | // Return a pointer to the RCU trailer | |
348 | // data. Should be called always after | |
349 | // the RCU trailer was already processed | |
350 | // in the GetPosition() method | |
351 | if (!fRCUTrailerSize || !fRCUTrailerData) { | |
352 | AliError("No valid RCU trailer data is found !"); | |
353 | data = NULL; | |
354 | return kFALSE; | |
355 | } | |
356 | ||
357 | data = fRCUTrailerData; | |
358 | ||
359 | return kTRUE; | |
3ea47630 | 360 | } |