bug fixed
[u/mrichter/AliRoot.git] / MUON / AliMUONRawStreamTracker.cxx
CommitLineData
c0751163 1/**************************************************************************
33434f31 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**************************************************************************/
c0751163 15
e3a2b9c9 16/* $Id$ */
c4ee792d 17
c0751163 18
3d1463c8 19//-----------------------------------------------------------------------------
c4ee792d 20/// \class AliMUONRawStreamTracker
c0751163 21/// This class provides access to MUON digits in raw data.
22///
23/// It loops over all MUON digits in the raw data given by the AliRawReader.
24/// The Next method goes to the next digit. If there are no digits left
dabf5427 25/// it returns kFALSE
313a427d 26/// It can loop also over DDL and store the decoded rawdata in TClonesArray
27/// in Payload class.
c0751163 28///
dabf5427 29/// Implement for Tracker
c0751163 30///
3c7f5307 31/// \author Christian Finck & Laurent Aphecetche
3d1463c8 32//-----------------------------------------------------------------------------
c0751163 33
34#include "AliMUONRawStreamTracker.h"
35
dabf5427 36#include "AliMUONLogger.h"
c0751163 37#include "AliRawReader.h"
38#include "AliRawDataHeader.h"
9e378ff4 39#include "AliDAQ.h"
c0751163 40#include "AliLog.h"
33434f31 41#include "AliMUONPayloadTracker.h"
42#include "AliMUONBlockHeader.h"
43#include "AliMUONDspHeader.h"
44#include "AliMUONBusStruct.h"
45#include "AliMUONDDLTracker.h"
46#include "Riostream.h"
236f997c 47#include <cassert>
c0751163 48
00e86732 49/// \cond CLASSIMP
c0751163 50ClassImp(AliMUONRawStreamTracker)
00e86732 51/// \endcond
c0751163 52
dabf5427 53//___________________________________________
c0751163 54AliMUONRawStreamTracker::AliMUONRawStreamTracker()
e3a2b9c9 55 : AliMUONVRawStreamTracker(),
dabf5427 56 fPayload(new AliMUONPayloadTracker()),
57 fCurrentDDL(0),
58 fCurrentDDLIndex(fgkMaxDDL),
59 fCurrentBlockHeader(0),
60 fCurrentBlockHeaderIndex(0),
61 fCurrentDspHeader(0),
62 fCurrentDspHeaderIndex(0),
63 fCurrentBusStruct(0),
64 fCurrentBusStructIndex(0),
65 fCurrentDataIndex(0),
8a0dae7c 66 fDDL(0)
c0751163 67{
00e86732 68 ///
69 /// create an object to read MUON raw digits
70 /// Default ctor for monitoring purposes
71 ///
33434f31 72
73
c0751163 74}
75
76//_________________________________________________________________
77AliMUONRawStreamTracker::AliMUONRawStreamTracker(AliRawReader* rawReader)
e3a2b9c9 78: AliMUONVRawStreamTracker(rawReader),
3c7f5307 79 fPayload(new AliMUONPayloadTracker()),
dabf5427 80 fCurrentDDL(0),
81 fCurrentDDLIndex(fgkMaxDDL),
3c7f5307 82 fCurrentBlockHeader(0),
83 fCurrentBlockHeaderIndex(0),
84 fCurrentDspHeader(0),
85 fCurrentDspHeaderIndex(0),
86 fCurrentBusStruct(0),
87 fCurrentBusStructIndex(0),
88 fCurrentDataIndex(0),
8a0dae7c 89 fDDL(0)
c0751163 90{
00e86732 91 ///
92 /// ctor with AliRawReader as argument
93 /// for reconstruction purpose
94 ///
33434f31 95
96
c0751163 97}
98
c0751163 99//___________________________________
100AliMUONRawStreamTracker::~AliMUONRawStreamTracker()
101{
00e86732 102 ///
103 /// clean up
104 ///
313a427d 105 delete fPayload;
c0751163 106}
107
108//_____________________________________________________________
33434f31 109Bool_t
110AliMUONRawStreamTracker::Next(Int_t& busPatchId,
111 UShort_t& manuId, UChar_t& manuChannel,
112 UShort_t& adc)
c0751163 113{
00e86732 114 ///
115 /// read the next raw digit (buspatch structure)
116 /// returns kFALSE if there is no digit left
236f997c 117 /// Should call First() before this method to start the iteration.
33434f31 118 ///
119
120 if ( IsDone() ) return kFALSE;
121
122 if ( fCurrentDataIndex >= fCurrentBusStruct->GetLength()-1 )
123 {
124 Bool_t ok = GetNextBusStruct();
125 if (!ok)
126 {
127 // this is the end
128 return kFALSE;
129 }
130 }
131
132 ++fCurrentDataIndex;
133
134 busPatchId = fCurrentBusStruct->GetBusPatchId();
135 manuId = fCurrentBusStruct->GetManuId(fCurrentDataIndex);
136 manuChannel = fCurrentBusStruct->GetChannelId(fCurrentDataIndex);
137 adc = fCurrentBusStruct->GetCharge(fCurrentDataIndex);
138
139 return kTRUE;
c0751163 140}
141
142//______________________________________________________
33434f31 143Bool_t
144AliMUONRawStreamTracker::IsDone() const
c0751163 145{
33434f31 146 /// Whether the iteration is finished or not
147 return (fCurrentBusStruct==0);
148}
c0751163 149
33434f31 150//______________________________________________________
151void
152AliMUONRawStreamTracker::First()
153{
236f997c 154 /// Initialize the iteration process.
33434f31 155
156 fCurrentDDLIndex = -1;
236f997c 157// fCurrentDspHeaderIndex = -1; // Not necessary since this gets reset in the GetNextXXX methods.
158// fCurrentBusStructIndex = -1;
159
160 // Must reset all the pointers because if we return before calling
161 // GetNextBusStruct() the user might call CurrentDDL(), CurrentBlockHeader(),
162 // CurrentDspHeader() or CurrentBusStruct() which should return reasonable
163 // results in that case.
164 fCurrentDDL = 0;
165 fCurrentBlockHeader = 0;
33434f31 166 fCurrentDspHeader = 0;
167 fCurrentBusStruct = 0;
168
169 // Find the first non-empty structure
236f997c 170 if (not GetNextDDL()) return;
171 if (not GetNextBlockHeader()) return;
172 if (not GetNextDspHeader()) return;
33434f31 173 GetNextBusStruct();
174}
c0751163 175
33434f31 176//______________________________________________________
177Bool_t
178AliMUONRawStreamTracker::GetNextDDL()
179{
180 /// Returns the next DDL present
181
dabf5427 182 assert( GetReader() != 0 );
236f997c 183
33434f31 184 Bool_t kFound(kFALSE);
185
dabf5427 186 while ( fCurrentDDLIndex < fgkMaxDDL-1 && !kFound )
33434f31 187 {
188 ++fCurrentDDLIndex;
dabf5427 189 GetReader()->Reset();
190 GetReader()->Select("MUONTRK",fCurrentDDLIndex,fCurrentDDLIndex);
191 if ( GetReader()->ReadHeader() )
33434f31 192 {
193 kFound = kTRUE;
194 }
195 }
196
197 if ( !kFound )
198 {
dabf5427 199 // fCurrentDDLIndex is set to fgkMaxDDL so that we exit the above loop immediately
236f997c 200 // for a subsequent call to this method, unless NextEvent is called in between.
dabf5427 201 fCurrentDDLIndex = fgkMaxDDL;
236f997c 202 // We have not actually been able to complete the loading of the new DDL so
203 // we are still on the old one. In this case we do not need to reset fCurrentDDL.
204 //fCurrentDDL = 0;
6817de1c 205 if (IsErrorLogger()) AddErrorMessage();
c0751163 206 return kFALSE;
207 }
33434f31 208
dabf5427 209 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
33434f31 210
211 AliDebug(3, Form("DDL Number %d totalDataWord %d\n", fCurrentDDLIndex,
212 totalDataWord));
dabf5427 213
313a427d 214 UInt_t *buffer = new UInt_t[totalDataWord/4];
33434f31 215
dabf5427 216 if ( !GetReader()->ReadNext((UChar_t*)buffer, totalDataWord) )
33434f31 217 {
236f997c 218 // We have not actually been able to complete the loading of the new DDL so
219 // we are still on the old one. In this case we do not need to reset fCurrentDDL.
220 //fCurrentDDL = 0;
221 delete [] buffer;
33434f31 222 return kFALSE;
223 }
224 fPayload->ResetDDL();
225
dabf5427 226#ifndef R__BYTESWAP
47c48013 227 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
dabf5427 228#endif
229
33434f31 230 Bool_t ok = fPayload->Decode(buffer, totalDataWord/4);
231
232 delete[] buffer;
233
234 fCurrentDDL = fPayload->GetDDLTracker();
235
236 fCurrentBlockHeaderIndex = -1;
237
238 return ok;
239}
c0751163 240
33434f31 241//______________________________________________________
242Bool_t
243AliMUONRawStreamTracker::GetNextBlockHeader()
244{
245 /// Returns the next block Header present
236f997c 246
247 assert( fCurrentDDL != 0 );
c0751163 248
33434f31 249 fCurrentBlockHeader = 0;
c0751163 250
33434f31 251 Int_t i(fCurrentBlockHeaderIndex);
252
253 while ( fCurrentBlockHeader == 0 && i < fCurrentDDL->GetBlkHeaderEntries()-1 )
254 {
255 ++i;
256 fCurrentBlockHeader = fCurrentDDL->GetBlkHeaderEntry(i);
257 }
258
259 if ( !fCurrentBlockHeader )
260 {
261 Bool_t ok = GetNextDDL();
262 if (!ok)
263 {
264 return kFALSE;
265 }
266 else
267 {
268 return GetNextBlockHeader();
269 }
270 }
271
272 fCurrentBlockHeaderIndex = i;
273
274 fCurrentDspHeaderIndex = -1;
275
276 return kTRUE;
277}
c0751163 278
33434f31 279//______________________________________________________
280Bool_t
281AliMUONRawStreamTracker::GetNextDspHeader()
282{
283 /// Returns the next Dsp Header present
284
236f997c 285 assert( fCurrentBlockHeader != 0 );
286
33434f31 287 fCurrentDspHeader = 0;
288
289 Int_t i(fCurrentDspHeaderIndex);
290
291 while ( fCurrentDspHeader == 0 && i < fCurrentBlockHeader->GetDspHeaderEntries()-1 )
292 {
293 ++i;
294 fCurrentDspHeader = fCurrentBlockHeader->GetDspHeaderEntry(i);
295 }
296
297 if ( !fCurrentDspHeader )
298 {
299 Bool_t ok = GetNextBlockHeader();
300 if (!ok)
301 {
302 return kFALSE;
303 }
304 else
305 {
306 return GetNextDspHeader();
307 }
308 }
309
310 fCurrentDspHeaderIndex = i;
311
312 fCurrentBusStructIndex = -1;
313
314 return kTRUE;
315}
c0751163 316
33434f31 317//______________________________________________________
318Bool_t
319AliMUONRawStreamTracker::GetNextBusStruct()
320{
321 /// Find the next non-empty busPatch structure
322
236f997c 323 assert( fCurrentDspHeader != 0 );
324
33434f31 325 fCurrentBusStruct = 0;
326
327 Int_t i(fCurrentBusStructIndex);
328
329 while ( fCurrentBusStruct == 0 && i < fCurrentDspHeader->GetBusPatchEntries()-1 )
330 {
331 ++i;
332 fCurrentBusStruct = fCurrentDspHeader->GetBusPatchEntry(i);
333 }
334
335 if ( !fCurrentBusStruct )
336 {
337 Bool_t ok = GetNextDspHeader();
338 if (!ok)
339 {
340 return kFALSE;
341 }
342 else
343 {
344 return GetNextBusStruct();
345 }
346 }
347
348 fCurrentBusStructIndex = i;
349
350 fCurrentDataIndex = -1;
351
c0751163 352 return kTRUE;
353}
c0751163 354
355//______________________________________________________
33434f31 356Bool_t AliMUONRawStreamTracker::NextDDL()
357{
358 /// reading tracker DDL
359
dabf5427 360 assert( GetReader() != 0 );
236f997c 361
33434f31 362 fPayload->ResetDDL();
363
dabf5427 364 while ( fDDL < fgkMaxDDL )
33434f31 365 {
dabf5427 366 GetReader()->Reset();
367 GetReader()->Select("MUONTRK", fDDL, fDDL); //Select the DDL file to be read
368 if (GetReader()->ReadHeader()) break;
33434f31 369 AliDebug(3,Form("Skipping DDL %d which does not seem to be there",fDDL));
370 ++fDDL;
371 }
372
dabf5427 373 if ( fDDL == fgkMaxDDL )
33434f31 374 {
375 fDDL = 0;
6817de1c 376 if ( IsErrorLogger()) AddErrorMessage();
33434f31 377 return kFALSE;
378 }
379
380 AliDebug(3, Form("DDL Number %d\n", fDDL ));
381
dabf5427 382 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
33434f31 383
384 UInt_t *buffer = new UInt_t[totalDataWord/4];
dabf5427 385
386 if(!GetReader()->ReadNext((UChar_t*)buffer, totalDataWord))
33434f31 387 {
ea59383d 388 delete[] buffer;
33434f31 389 return kFALSE;
390 }
dabf5427 391
392#ifndef R__BYTESWAP
47c48013 393 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
dabf5427 394#endif
33434f31 395
396 Bool_t ok = fPayload->Decode(buffer, totalDataWord/4);
ea59383d 397
33434f31 398 delete[] buffer;
399
400 fDDL++;
401
402 return ok;
403}
404
405//______________________________________________________
c0751163 406void AliMUONRawStreamTracker::SetMaxBlock(Int_t blk)
407{
00e86732 408 /// set regional card number
313a427d 409 fPayload->SetMaxBlock(blk);
c0751163 410}
ea59383d 411
412//______________________________________________________
413void AliMUONRawStreamTracker::AddErrorMessage()
414{
dabf5427 415 /// add message into logger of AliRawReader per event
ea59383d 416
dabf5427 417 assert( GetReader() != 0 );
9b4aee57 418 TString msg;
dabf5427 419 Int_t occurance = 0;
420 AliMUONLogger* log = fPayload->GetErrorLogger();
421
422 log->ResetItr();
423 while(log->Next(msg, occurance))
424 {
425 if (msg.Contains("Parity"))
426 GetReader()->AddMinorErrorLog(kParityErr, msg.Data());
236f997c 427
dabf5427 428 if (msg.Contains("Glitch"))
429 GetReader()->AddMajorErrorLog(kGlitchErr, msg.Data());
ea59383d 430
dabf5427 431 if (msg.Contains("Padding"))
432 GetReader()->AddMinorErrorLog(kPaddingWordErr, msg.Data());
433 }
6817de1c 434
435 log->Clear(); // clear logger after each event
dabf5427 436}
ea59383d 437
dabf5427 438//______________________________________________________
439Bool_t AliMUONRawStreamTracker::IsErrorMessage() const
440{
441 /// true if there is any error/warning
442 if (GetPayLoad()->GetParityErrors() ||
443 GetPayLoad()->GetGlitchErrors() ||
444 GetPayLoad()->GetPaddingErrors())
445 return kTRUE;
446
447 return kFALSE;
448}
449
450
451
452
ea59383d 453