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