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