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 **************************************************************************/
19 //-----------------------------------------------------------------------------
20 /// \class AliMUONRawStreamTracker
21 /// This class provides access to MUON digits in raw data.
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
26 /// It can loop also over DDL and store the decoded rawdata in TClonesArray
29 /// Implement for Tracker
31 /// \author Christian Finck & Laurent Aphecetche
32 //-----------------------------------------------------------------------------
34 #include "AliMUONRawStreamTracker.h"
36 #include "AliMUONLogger.h"
37 #include "AliRawReader.h"
38 #include "AliRawDataHeader.h"
41 #include "AliMUONPayloadTracker.h"
42 #include "AliMUONBlockHeader.h"
43 #include "AliMUONDspHeader.h"
44 #include "AliMUONBusStruct.h"
45 #include "AliMUONDDLTracker.h"
46 #include "Riostream.h"
50 ClassImp(AliMUONRawStreamTracker)
54 //___________________________________________
55 AliMUONRawStreamTracker::AliMUONRawStreamTracker(TRootIOCtor* /*dummy*/)
56 : AliMUONVRawStreamTracker(),
59 fCurrentDDLIndex(fgkMaxDDL),
60 fCurrentBlockHeader(0),
61 fCurrentBlockHeaderIndex(0),
63 fCurrentDspHeaderIndex(0),
65 fCurrentBusStructIndex(0),
70 /// create an object to read MUON raw digits
71 /// Default ctor with no memory allocation for I/O
75 //___________________________________________
76 AliMUONRawStreamTracker::AliMUONRawStreamTracker()
77 : AliMUONVRawStreamTracker(),
78 fPayload(new AliMUONPayloadTracker()),
80 fCurrentDDLIndex(fgkMaxDDL),
81 fCurrentBlockHeader(0),
82 fCurrentBlockHeaderIndex(0),
84 fCurrentDspHeaderIndex(0),
86 fCurrentBusStructIndex(0),
91 /// create an object to read MUON raw digits
92 /// Default ctor for monitoring purposes
98 //_________________________________________________________________
99 AliMUONRawStreamTracker::AliMUONRawStreamTracker(AliRawReader* rawReader)
100 : AliMUONVRawStreamTracker(rawReader),
101 fPayload(new AliMUONPayloadTracker()),
103 fCurrentDDLIndex(fgkMaxDDL),
104 fCurrentBlockHeader(0),
105 fCurrentBlockHeaderIndex(0),
106 fCurrentDspHeader(0),
107 fCurrentDspHeaderIndex(0),
108 fCurrentBusStruct(0),
109 fCurrentBusStructIndex(0),
110 fCurrentDataIndex(0),
114 /// ctor with AliRawReader as argument
115 /// for reconstruction purpose
121 //___________________________________
122 AliMUONRawStreamTracker::~AliMUONRawStreamTracker()
130 //_____________________________________________________________
132 AliMUONRawStreamTracker::Next(Int_t& busPatchId,
133 UShort_t& manuId, UChar_t& manuChannel,
137 /// read the next raw digit (buspatch structure)
138 /// returns kFALSE if there is no digit left
139 /// Should call First() before this method to start the iteration.
142 if ( IsDone() ) return kFALSE;
144 if ( fCurrentDataIndex >= fCurrentBusStruct->GetLength()-1 )
146 Bool_t ok = GetNextBusStruct();
156 busPatchId = fCurrentBusStruct->GetBusPatchId();
157 manuId = fCurrentBusStruct->GetManuId(fCurrentDataIndex);
158 manuChannel = fCurrentBusStruct->GetChannelId(fCurrentDataIndex);
159 adc = fCurrentBusStruct->GetCharge(fCurrentDataIndex);
164 //______________________________________________________
166 AliMUONRawStreamTracker::IsDone() const
168 /// Whether the iteration is finished or not
169 return (fCurrentBusStruct==0);
172 //______________________________________________________
174 AliMUONRawStreamTracker::First()
176 /// Initialize the iteration process.
178 fCurrentDDLIndex = -1;
179 // fCurrentDspHeaderIndex = -1; // Not necessary since this gets reset in the GetNextXXX methods.
180 // fCurrentBusStructIndex = -1;
182 // Must reset all the pointers because if we return before calling
183 // GetNextBusStruct() the user might call CurrentDDL(), CurrentBlockHeader(),
184 // CurrentDspHeader() or CurrentBusStruct() which should return reasonable
185 // results in that case.
187 fCurrentBlockHeader = 0;
188 fCurrentDspHeader = 0;
189 fCurrentBusStruct = 0;
191 // Find the first non-empty structure
192 if (not GetNextDDL()) return;
193 if (not GetNextBlockHeader()) return;
194 if (not GetNextDspHeader()) return;
198 //______________________________________________________
200 AliMUONRawStreamTracker::GetNextDDL()
202 /// Returns the next DDL present
204 assert( GetReader() != 0 );
206 Bool_t kFound(kFALSE);
208 while ( fCurrentDDLIndex < fgkMaxDDL-1 && !kFound )
211 GetReader()->Reset();
212 GetReader()->Select("MUONTRK",fCurrentDDLIndex,fCurrentDDLIndex);
213 if ( GetReader()->ReadHeader() )
221 // fCurrentDDLIndex is set to fgkMaxDDL so that we exit the above loop immediately
222 // for a subsequent call to this method, unless NextEvent is called in between.
223 fCurrentDDLIndex = fgkMaxDDL;
224 // We have not actually been able to complete the loading of the new DDL so
225 // we are still on the old one. In this case we do not need to reset fCurrentDDL.
227 if (IsErrorLogger()) AddErrorMessage();
231 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
233 AliDebug(3, Form("DDL Number %d totalDataWord %d\n", fCurrentDDLIndex,
236 UInt_t *buffer = new UInt_t[totalDataWord/4];
238 if ( !GetReader()->ReadNext((UChar_t*)buffer, totalDataWord) )
240 // We have not actually been able to complete the loading of the new DDL so
241 // we are still on the old one. In this case we do not need to reset fCurrentDDL.
246 fPayload->ResetDDL();
249 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
252 Bool_t ok = fPayload->Decode(buffer, totalDataWord/4);
256 fCurrentDDL = fPayload->GetDDLTracker();
258 fCurrentBlockHeaderIndex = -1;
263 //______________________________________________________
265 AliMUONRawStreamTracker::GetNextBlockHeader()
267 /// Returns the next block Header present
269 assert( fCurrentDDL != 0 );
271 fCurrentBlockHeader = 0;
273 Int_t i(fCurrentBlockHeaderIndex);
275 while ( fCurrentBlockHeader == 0 && i < fCurrentDDL->GetBlkHeaderEntries()-1 )
278 fCurrentBlockHeader = fCurrentDDL->GetBlkHeaderEntry(i);
281 if ( !fCurrentBlockHeader )
283 Bool_t ok = GetNextDDL();
290 return GetNextBlockHeader();
294 fCurrentBlockHeaderIndex = i;
296 fCurrentDspHeaderIndex = -1;
301 //______________________________________________________
303 AliMUONRawStreamTracker::GetNextDspHeader()
305 /// Returns the next Dsp Header present
307 assert( fCurrentBlockHeader != 0 );
309 fCurrentDspHeader = 0;
311 Int_t i(fCurrentDspHeaderIndex);
313 while ( fCurrentDspHeader == 0 && i < fCurrentBlockHeader->GetDspHeaderEntries()-1 )
316 fCurrentDspHeader = fCurrentBlockHeader->GetDspHeaderEntry(i);
319 if ( !fCurrentDspHeader )
321 Bool_t ok = GetNextBlockHeader();
328 return GetNextDspHeader();
332 fCurrentDspHeaderIndex = i;
334 fCurrentBusStructIndex = -1;
339 //______________________________________________________
341 AliMUONRawStreamTracker::GetNextBusStruct()
343 /// Find the next non-empty busPatch structure
345 assert( fCurrentDspHeader != 0 );
347 fCurrentBusStruct = 0;
349 Int_t i(fCurrentBusStructIndex);
351 while ( fCurrentBusStruct == 0 && i < fCurrentDspHeader->GetBusPatchEntries()-1 )
354 fCurrentBusStruct = fCurrentDspHeader->GetBusPatchEntry(i);
357 if ( !fCurrentBusStruct )
359 Bool_t ok = GetNextDspHeader();
366 return GetNextBusStruct();
370 fCurrentBusStructIndex = i;
372 fCurrentDataIndex = -1;
377 //______________________________________________________
378 Bool_t AliMUONRawStreamTracker::NextDDL()
380 /// reading tracker DDL
382 assert( GetReader() != 0 );
384 fPayload->ResetDDL();
386 while ( fDDL < fgkMaxDDL )
388 GetReader()->Reset();
389 GetReader()->Select("MUONTRK", fDDL, fDDL); //Select the DDL file to be read
390 if (GetReader()->ReadHeader()) break;
391 AliDebug(3,Form("Skipping DDL %d which does not seem to be there",fDDL));
395 if ( fDDL == fgkMaxDDL )
398 if ( IsErrorLogger()) AddErrorMessage();
402 AliDebug(3, Form("DDL Number %d\n", fDDL ));
404 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
406 UInt_t *buffer = new UInt_t[totalDataWord/4];
408 if(!GetReader()->ReadNext((UChar_t*)buffer, totalDataWord))
415 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
418 Bool_t ok = fPayload->Decode(buffer, totalDataWord/4);
427 //______________________________________________________
428 void AliMUONRawStreamTracker::SetMaxBlock(Int_t blk)
430 /// set regional card number
431 fPayload->SetMaxBlock(blk);
434 //______________________________________________________
435 void AliMUONRawStreamTracker::AddErrorMessage()
437 /// add message into logger of AliRawReader per event
439 assert( GetReader() != 0 );
442 AliMUONLogger* log = fPayload->GetErrorLogger();
445 while(log->Next(msg, occurance))
447 if (msg.Contains("Parity"))
448 GetReader()->AddMinorErrorLog(kParityErr, msg.Data());
450 if (msg.Contains("Glitch"))
451 GetReader()->AddMajorErrorLog(kGlitchErr, msg.Data());
453 if (msg.Contains("Padding"))
454 GetReader()->AddMinorErrorLog(kPaddingWordErr, msg.Data());
457 log->Clear(); // clear logger after each event
460 //______________________________________________________
461 Bool_t AliMUONRawStreamTracker::IsErrorMessage() const
463 /// true if there is any error/warning
464 if (GetPayLoad()->GetParityErrors() ||
465 GetPayLoad()->GetGlitchErrors() ||
466 GetPayLoad()->GetPaddingErrors())