Adding the AliAnalysisGUI class which is the main class that controls the GUI.
[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     PrintDebug();
212     AliFatal("Incorrect trailer found ! Expected 0x2AA not found !");
213   }
214
215   //Then read the trailer
216   if (fPosition <= 4) {
217     PrintDebug();
218     AliFatal(Form("Incorrect raw data size ! Expected at lest 4 words but found %d !",fPosition));
219   }
220
221   fCount = (temp << 4) & 0x3FF;
222   if ((temp >> 6) != 0xA) {
223     PrintDebug();
224     AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6));
225   }
226
227   temp = GetNextWord();
228   fHWAddress = (temp & 0x3) << 10;
229   if (((temp >> 2) & 0xF) != 0xA) {
230     PrintDebug();
231     AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",(temp >> 2) & 0xF));
232   }
233   fCount |= ((temp & 0x3FF) >> 6);
234   if (fCount == 0) return kFALSE;
235
236   temp = GetNextWord();
237   fHWAddress |= temp;
238
239   fPosition -= (4 - (fCount % 4)) % 4;  // skip fill words
240
241   return kTRUE;
242 }
243
244 //_____________________________________________________________________________
245 Bool_t AliAltroRawStream::ReadDummyTrailer()
246 {
247   //Read a trailer of 40 bits in the backward reading mode
248   //In case of no mapping is provided, read a dummy trailer
249   UShort_t temp;
250   while ((temp = GetNextWord()) == 0x2AA);
251
252   fSegmentation[0] = temp;
253   fSegmentation[1] = GetNextWord();
254   fSegmentation[2] = GetNextWord();
255   fCount = GetNextWord();
256   if (fCount == 0) return kFALSE;
257   fHWAddress = -1;
258
259   fPosition -= (4 - (fCount % 4)) % 4;  // skip fill words
260
261   return kTRUE;
262 }
263
264 //_____________________________________________________________________________
265 void AliAltroRawStream::ReadBunch()
266 {
267   // Read altro payload in 
268   // backward direction
269   if (fPosition <= 0) {
270     PrintDebug();
271     AliFatal("Could not read bunch length !");
272   }
273
274   fBunchLength = GetNextWord() - 2;
275   fTimeBunch = fBunchLength;
276   fCount--;
277
278   if (fPosition <= 0) {
279     PrintDebug();
280     AliFatal("Could not read time bin !");
281   }
282
283   fTime = GetNextWord();
284   fCount--;
285
286   return;
287 }
288
289 //_____________________________________________________________________________
290 void AliAltroRawStream::ReadAmplitude()
291 {
292   // Read next time bin amplitude
293   if (fPosition <= 0) {
294     PrintDebug();
295     AliFatal("Could not read sample amplitude !");
296   }
297
298   fSignal = GetNextWord();
299   fCount--;
300   fBunchLength--;
301
302   return;
303 }
304
305 //_____________________________________________________________________________
306 Int_t AliAltroRawStream::GetPosition()
307 {
308   // Sets the position in the
309   // input stream
310   // Read the RCU trailer
311   // This includes the trailer size,
312   // RCU identifier and raw data payload.
313   // The RCU trailer format is described
314   // in details in the RCU manual.
315
316   if (!fIsOldRCUFormat) {
317     // First read 32-bit word with the
318     // trailer size (22 bits) and RCU ID (the rest)
319     Int_t index = fRawReader->GetDataSize();
320     UInt_t word = Get32bitWord(index);
321     fRCUId = (Int_t)(word >> 22);
322     Int_t trailerSize = (word & 0x3FFFFF);
323
324     // Now read the beginning of the trailer
325     // where the payload size is written
326     if (trailerSize < 2) {
327       PrintDebug();
328       AliFatal(Form("Invalid trailer size found (%d bytes) !",trailerSize*4));
329     }
330     fRCUTrailerSize = (trailerSize-2)*4;
331     index -= fRCUTrailerSize;
332     if (index < 4) {
333       PrintDebug();
334       AliFatal(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
335                     trailerSize*4,
336                     fRawReader->GetDataSize()));
337     }
338     fRCUTrailerData = fData + index;
339     Int_t position = Get32bitWord(index);
340     // The size is specified in a number of 40bits
341     // Therefore we need to transform it to number of bytes
342     position *= 5;
343
344     // Check the consistency of the header and trailer
345     if ((fRawReader->GetDataSize() - trailerSize*4) != position) {
346       PrintDebug();
347       AliFatal(Form("Inconsistent raw data size ! Raw data size - %d bytes (from the header), RCU trailer - %d bytes, raw data paylod - %d bytes !",
348                     fRawReader->GetDataSize(),
349                     trailerSize*4,
350                     position));
351     }
352
353     return position * 8 / 10;
354   }
355   else {
356     // In case of the Old RCU trailer format
357     // we have to read just the size of altro payload
358     // in units of 40-bit words
359     Int_t index = fRawReader->GetDataSize();
360     Int_t position = Get32bitWord(index);
361
362     fRCUId = -1;
363     fRCUTrailerSize = 0;
364     fRCUTrailerData = NULL;
365
366     // The size is specified in a number of 40bits
367     // Therefore we need to transform it to number of bytes
368     position *= 5;
369
370     if (!fIsShortDataHeader) {
371
372       // Check the consistency of the header and trailer
373       if ((fRawReader->GetDataSize() - 4) != position) {
374         PrintDebug();
375         AliFatal(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
376                       fRawReader->GetDataSize()-4,
377                       position));
378       }
379     }
380     else {
381       // Check the consistency of the header and trailer
382       // In this case the header is shorter by 4 bytes
383       if (fRawReader->GetDataSize() != position) {
384         PrintDebug();
385         AliFatal(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
386                       fRawReader->GetDataSize(),
387                       position));
388       }
389
390       // 7 32-bit words Common Data Header
391       // therefore we have to shift back by 4 bytes
392       // the pointer to the raw data payload
393       fData -= 4;
394     }
395      
396     // Return the position in units of 10-bit words
397     return position*8/10;
398   }
399 }
400
401 //_____________________________________________________________________________
402 UInt_t AliAltroRawStream::Get32bitWord(Int_t &index)
403 {
404   // This method returns the 32 bit word at a given
405   // position inside the raw data payload.
406   // The 'index' points to the beginning of the next word.
407   // The method is supposed to be endian (platform)
408   // independent.
409   if (!fData) {
410     PrintDebug();
411     AliFatal("Raw data paylod buffer is not yet initialized !");
412   }
413
414   if (index < 4) {
415     PrintDebug();
416     AliFatal(Form("Invalid raw data payload index (%d) !",index));
417   }
418
419   UInt_t word = 0;
420   word  = fData[--index] << 24;
421   word |= fData[--index] << 16;
422   word |= fData[--index] << 8;
423   word |= fData[--index];
424
425   return word;
426 }
427
428 //_____________________________________________________________________________
429 Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const
430 {
431   // Return a pointer to the RCU trailer
432   // data. Should be called always after
433   // the RCU trailer was already processed
434   // in the GetPosition() method
435   if (!fRCUTrailerSize || !fRCUTrailerData) {
436     AliError("No valid RCU trailer data is found !");
437     data = NULL;
438     return kFALSE;
439   }
440
441   data = fRCUTrailerData;
442
443   return kTRUE;
444 }
445
446 //_____________________________________________________________________________
447 void AliAltroRawStream::PrintDebug() const
448 {
449   // The method prints all the available
450   // debug information.
451   // Its is used in case of decoding errors.
452
453   AliError("Start of debug printout\n--------------------");
454
455   Dump();
456   if (fRawReader) fRawReader->Dump();
457
458   AliError("End of debug printout\n--------------------");
459 }