6a6b9040fffe08372951ed1329552025b840740d
[u/mrichter/AliRoot.git] / RAW / AliAltroRawStreamOld.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 ///////////////////////////////////////////////////////////////////////////////
17 ///
18 /// This class provides access to Altro digits in raw data.
19 ///
20 /// It loops over all Altro digits in the raw data given by the AliRawReader.
21 /// The Next method goes to the next digit. If there are no digits left
22 /// it returns kFALSE.
23 /// Several getters provide information about the current digit.
24 ///
25 ///////////////////////////////////////////////////////////////////////////////
26
27 #include "AliAltroRawStreamOld.h"
28 #include "AliRawReader.h"
29 #include "AliLog.h"
30
31 ClassImp(AliAltroRawStreamOld)
32
33
34 //_____________________________________________________________________________
35 AliAltroRawStreamOld::AliAltroRawStreamOld(AliRawReader* rawReader) :
36   fNoAltroMapping(kTRUE),
37   fDDLNumber(-1),
38   fPrevDDLNumber(-1),
39   fHWAddress(-1),
40   fPrevHWAddress(-1),
41   fTime(-1),
42   fPrevTime(-1),
43   fSignal(-1),
44   fTimeBunch(-1),
45   fRawReader(rawReader),
46   fData(NULL),
47   fPosition(0),
48   fCount(0),
49   fBunchLength(0)
50 {
51 // create an object to read Altro raw digits
52   fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1;
53
54   // Invalid Common Data Header is used
55   // --> therefore skip the header and read
56   // only the payload
57   rawReader->RequireHeader(kFALSE);
58 }
59
60 //_____________________________________________________________________________
61 AliAltroRawStreamOld::AliAltroRawStreamOld(const AliAltroRawStreamOld& stream) :
62   TObject(stream),
63   fNoAltroMapping(kTRUE),
64   fDDLNumber(-1),
65   fPrevDDLNumber(-1),
66   fHWAddress(-1),
67   fPrevHWAddress(-1),
68   fTime(-1),
69   fPrevTime(-1),
70   fSignal(-1),
71   fTimeBunch(-1),
72   fRawReader(NULL),
73   fData(NULL),
74   fPosition(0),
75   fCount(0),
76   fBunchLength(0)
77 {
78   Fatal("AliAltroRawStreamOld", "copy constructor not implemented");
79 }
80
81 //_____________________________________________________________________________
82 AliAltroRawStreamOld& AliAltroRawStreamOld::operator = (const AliAltroRawStreamOld& 
83                                               /* stream */)
84 {
85   Fatal("operator =", "assignment operator not implemented");
86   return *this;
87 }
88
89 //_____________________________________________________________________________
90 AliAltroRawStreamOld::~AliAltroRawStreamOld()
91 {
92 // clean up
93
94 }
95
96 //_____________________________________________________________________________
97 void AliAltroRawStreamOld::Reset()
98 {
99 // reset altro raw stream params
100
101   fPosition = fCount = fBunchLength = 0;
102
103   fDDLNumber = fPrevDDLNumber = fHWAddress = fPrevHWAddress = fTime = fPrevTime = fSignal = fTimeBunch = -1;
104
105   if (fRawReader) fRawReader->Reset();
106
107   fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1;
108 }
109
110 //_____________________________________________________________________________
111 Bool_t AliAltroRawStreamOld::Next()
112 {
113 // read the next raw digit
114 // returns kFALSE if there is no digit left
115
116   fPrevDDLNumber = fDDLNumber;
117   fPrevHWAddress = fHWAddress;
118   fPrevTime = fTime;
119
120   while (fCount == 0) {  // next trailer
121     if (fPosition <= 0) {  // next payload
122       do {
123         if (!fRawReader->ReadNextData(fData)) return kFALSE;
124       } while (fRawReader->GetDataSize() == 0);
125
126       fDDLNumber = fRawReader->GetDDLID();
127
128       fPosition = GetPosition();
129     }
130
131     if (!ReadTrailer())
132       AliFatal("Incorrect trailer information !");
133
134     fBunchLength = 0;
135   }
136
137   if (fBunchLength == 0) ReadBunch();
138   else fTime--;
139
140   ReadAmplitude();
141
142   return kTRUE;
143 }
144
145 //_____________________________________________________________________________
146 void AliAltroRawStreamOld::SelectRawData(Int_t detId)
147 {
148   // Select the raw data for specific
149   // detector id
150   AliDebug(1,Form("Selecting raw data for detector %d",detId));
151   fRawReader->Select(detId);
152 }
153
154 //_____________________________________________________________________________
155 UShort_t AliAltroRawStreamOld::GetNextWord()
156 {
157   // Read the next 10 bit word in backward direction
158   // The input stream access is given by fData and fPosition
159
160   fPosition--;
161
162   Int_t iBit = fPosition * 10;
163   Int_t iByte = iBit / 8;
164   Int_t shift = iBit % 8;
165
166   // the raw data is written as integers where the low bits are filled first
167   // -> little endian is assumed here !
168   Int_t iByteLow = iByte;
169   iByte++;
170   Int_t iByteHigh  = iByte;
171   return ((fData[iByteHigh] * 256 + fData[iByteLow]) >> shift) & 0x03FF;
172 }
173
174 //_____________________________________________________________________________
175 Bool_t AliAltroRawStreamOld::ReadTrailer()
176 {
177   //Read a trailer of 40 bits in the backward reading mode
178   //In case of no mapping is provided, read a dummy trailer
179   if (fNoAltroMapping) {
180     AliError("No ALTRO mapping information is loaded! Reading a dummy trailer!");
181     return ReadDummyTrailer();
182   }
183
184   //First reading filling words
185   UShort_t temp;
186   Int_t nFillWords = 0;
187   while ((temp = GetNextWord()) == 0x2AA) nFillWords++;
188   if (nFillWords == 0)
189     AliFatal("Incorrect trailer found ! Expected 0x2AA not found !");
190
191   //Then read the trailer
192   if (fPosition <= 4)
193     AliFatal(Form("Incorrect raw data size ! Expected at lest 4 words but found %d !",fPosition));
194
195   fCount = (temp << 4) & 0x3FF;
196   if ((temp >> 6) != 0xA)
197     AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6));
198
199   temp = GetNextWord();
200   fHWAddress = (temp & 0x3) << 10;
201   if (((temp >> 2) & 0xF) != 0xA)
202     AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",(temp >> 2) & 0xF));
203   fCount |= ((temp & 0x3FF) >> 6);
204   if (fCount == 0) return kFALSE;
205
206   temp = GetNextWord();
207   fHWAddress |= temp;
208
209   fPosition -= (4 - (fCount % 4)) % 4;  // skip fill words
210
211   return kTRUE;
212 }
213
214 //_____________________________________________________________________________
215 Bool_t AliAltroRawStreamOld::ReadDummyTrailer()
216 {
217   //Read a trailer of 40 bits in the backward reading mode
218   //In case of no mapping is provided, read a dummy trailer
219   UShort_t temp;
220   while ((temp = GetNextWord()) == 0x2AA);
221
222   fSegmentation[0] = temp;
223   fSegmentation[1] = GetNextWord();
224   fSegmentation[2] = GetNextWord();
225   fCount = GetNextWord();
226   if (fCount == 0) return kFALSE;
227   fHWAddress = -1;
228
229   fPosition -= (4 - (fCount % 4)) % 4;  // skip fill words
230
231   return kTRUE;
232 }
233
234 //_____________________________________________________________________________
235 void AliAltroRawStreamOld::ReadBunch()
236 {
237   // Read altro payload in 
238   // backward direction
239   if (fPosition <= 0)
240     AliFatal("Could not read bunch length !");
241
242   fBunchLength = GetNextWord() - 2;
243   fTimeBunch = fBunchLength;
244   fCount--;
245
246   if (fPosition <= 0)
247     AliFatal("Could not read time bin !");
248
249   fTime = GetNextWord();
250   fCount--;
251
252   return;
253 }
254
255 //_____________________________________________________________________________
256 void AliAltroRawStreamOld::ReadAmplitude()
257 {
258   // Read next time bin amplitude
259   if (fPosition <= 0)
260     AliFatal("Could not read sample amplitude !");
261
262   fSignal = GetNextWord();
263   fCount--;
264   fBunchLength--;
265
266   return;
267 }
268
269 //_____________________________________________________________________________
270 Int_t AliAltroRawStreamOld::GetPosition()
271 {
272   // Sets the position in the
273   // input stream
274
275   // Get the payload size from the RCU trailer
276   // The trailer is actually one 32-bit word
277   Int_t position = (fData[fRawReader->GetDataSize()-29]) << 24;
278   position |= (fData[fRawReader->GetDataSize()-30]) << 16;
279   position |= (fData[fRawReader->GetDataSize()-31]) << 8;
280   position |= (fData[fRawReader->GetDataSize()-32]);
281   // The size is specified in a number of 40bits
282   // Therefore we need to transform it to number of bytes
283   position *= 5;
284
285   // Check the consistency of the header and trailer
286   if ((fRawReader->GetDataSize() - 64) != position)
287     AliFatal(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d words (in the RCU trailer)!",
288                   fRawReader->GetDataSize()-64,
289                   position));
290
291   // Skip the Common Data Header which contains
292   // only 7 (!) words
293   fData += 32;
294
295   // Return the position in units of 10-bit words
296   return position*8/10;
297 }