1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 /// This class provides access to Altro digits in raw data.
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.
27 ///////////////////////////////////////////////////////////////////////////////
29 #include "AliAltroRawStream.h"
30 #include "AliRawReader.h"
33 ClassImp(AliAltroRawStream)
36 //_____________________________________________________________________________
37 AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) :
38 fNoAltroMapping(kTRUE),
39 fIsOldRCUFormat(kFALSE),
50 fRawReader(rawReader),
55 fRCUTrailerData(NULL),
58 // create an object to read Altro raw digits
59 fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1;
62 //_____________________________________________________________________________
63 AliAltroRawStream::AliAltroRawStream(const AliAltroRawStream& stream) :
65 fNoAltroMapping(kTRUE),
66 fIsOldRCUFormat(kFALSE),
82 fRCUTrailerData(NULL),
85 Fatal("AliAltroRawStream", "copy constructor not implemented");
88 //_____________________________________________________________________________
89 AliAltroRawStream& AliAltroRawStream::operator = (const AliAltroRawStream&
92 Fatal("operator =", "assignment operator not implemented");
96 //_____________________________________________________________________________
97 AliAltroRawStream::~AliAltroRawStream()
103 //_____________________________________________________________________________
104 void AliAltroRawStream::Reset()
106 // reset altro raw stream params
108 fPosition = fCount = fBunchLength = 0;
110 fRCUTrailerData = NULL;
113 fDDLNumber = fPrevDDLNumber = fRCUId = fPrevRCUId = fHWAddress = fPrevHWAddress = fTime = fPrevTime = fSignal = fTimeBunch = -1;
115 if (fRawReader) fRawReader->Reset();
117 fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1;
120 //_____________________________________________________________________________
121 Bool_t AliAltroRawStream::Next()
123 // read the next raw digit
124 // returns kFALSE if there is no digit left
126 fPrevDDLNumber = fDDLNumber;
128 fPrevHWAddress = fHWAddress;
131 while (fCount == 0) { // next trailer
132 if (fPosition <= 0) { // next payload
134 if (!fRawReader->ReadNextData(fData)) return kFALSE;
135 } while (fRawReader->GetDataSize() == 0);
137 fDDLNumber = fRawReader->GetDDLID();
139 fPosition = GetPosition();
143 AliFatal("Incorrect trailer information !");
148 if (fBunchLength == 0) ReadBunch();
156 //_____________________________________________________________________________
157 void AliAltroRawStream::SelectRawData(Int_t detId)
159 // Select the raw data for specific
161 AliDebug(1,Form("Selecting raw data for detector %d",detId));
162 fRawReader->Select(detId);
165 //_____________________________________________________________________________
166 UShort_t AliAltroRawStream::GetNextWord()
168 // Read the next 10 bit word in backward direction
169 // The input stream access is given by fData and fPosition
173 Int_t iBit = fPosition * 10;
174 Int_t iByte = iBit / 8;
175 Int_t shift = iBit % 8;
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;
181 Int_t iByteHigh = iByte;
182 return ((fData[iByteHigh] * 256 + fData[iByteLow]) >> shift) & 0x03FF;
185 //_____________________________________________________________________________
186 Bool_t AliAltroRawStream::ReadTrailer()
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();
195 //First reading filling words
197 Int_t nFillWords = 0;
198 while ((temp = GetNextWord()) == 0x2AA) nFillWords++;
200 AliFatal("Incorrect trailer found ! Expected 0x2AA not found !");
202 //Then read the trailer
204 AliFatal(Form("Incorrect raw data size ! Expected at lest 4 words but found %d !",fPosition));
206 fCount = (temp << 4) & 0x3FF;
207 if ((temp >> 6) != 0xA)
208 AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6));
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;
217 temp = GetNextWord();
220 fPosition -= (4 - (fCount % 4)) % 4; // skip fill words
225 //_____________________________________________________________________________
226 Bool_t AliAltroRawStream::ReadDummyTrailer()
228 //Read a trailer of 40 bits in the backward reading mode
229 //In case of no mapping is provided, read a dummy trailer
231 while ((temp = GetNextWord()) == 0x2AA);
233 fSegmentation[0] = temp;
234 fSegmentation[1] = GetNextWord();
235 fSegmentation[2] = GetNextWord();
236 fCount = GetNextWord();
237 if (fCount == 0) return kFALSE;
240 fPosition -= (4 - (fCount % 4)) % 4; // skip fill words
245 //_____________________________________________________________________________
246 void AliAltroRawStream::ReadBunch()
248 // Read altro payload in
249 // backward direction
251 AliFatal("Could not read bunch length !");
253 fBunchLength = GetNextWord() - 2;
254 fTimeBunch = fBunchLength;
258 AliFatal("Could not read time bin !");
260 fTime = GetNextWord();
266 //_____________________________________________________________________________
267 void AliAltroRawStream::ReadAmplitude()
269 // Read next time bin amplitude
271 AliFatal("Could not read sample amplitude !");
273 fSignal = GetNextWord();
280 //_____________________________________________________________________________
281 Int_t AliAltroRawStream::GetPosition()
283 // Sets the position in the
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.
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);
299 // Now read the beginning of the trailer
300 // where the payload size is written
302 AliFatal(Form("Invalid trailer size found (%d bytes) !",trailerSize*4));
303 fRCUTrailerSize = (trailerSize-2)*4;
304 index -= fRCUTrailerSize;
306 AliFatal(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
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
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(),
322 return position * 8 / 10;
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);
333 fRCUTrailerData = NULL;
335 // The size is specified in a number of 40bits
336 // Therefore we need to transform it to number of bytes
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,
345 // Return the position in units of 10-bit words
346 return position*8/10;
350 //_____________________________________________________________________________
351 UInt_t AliAltroRawStream::Get32bitWord(Int_t &index)
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)
359 AliFatal("Raw data paylod buffer is not yet initialized !");
361 AliFatal(Form("Invalid raw data payload index (%d) !",index));
364 word = fData[--index] << 24;
365 word |= fData[--index] << 16;
366 word |= fData[--index] << 8;
367 word |= fData[--index];
372 //_____________________________________________________________________________
373 Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const
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 !");
385 data = fRCUTrailerData;