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