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