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"
40 #include "AliMUONPayloadTracker.h"
41 #include "AliMUONBlockHeader.h"
42 #include "AliMUONDspHeader.h"
43 #include "AliMUONBusStruct.h"
44 #include "AliMUONDDLTracker.h"
45 #include "Riostream.h"
49 ClassImp(AliMUONRawStreamTracker)
53 //___________________________________________
54 AliMUONRawStreamTracker::AliMUONRawStreamTracker(TRootIOCtor* /*dummy*/)
55 : AliMUONVRawStreamTracker(),
58 fCurrentDDLIndex(fgkMaxDDL),
59 fCurrentBlockHeader(0),
60 fCurrentBlockHeaderIndex(0),
62 fCurrentDspHeaderIndex(0),
64 fCurrentBusStructIndex(0),
69 /// create an object to read MUON raw digits
70 /// Default ctor with no memory allocation for I/O
74 //___________________________________________
75 AliMUONRawStreamTracker::AliMUONRawStreamTracker()
76 : AliMUONVRawStreamTracker(),
77 fPayload(new AliMUONPayloadTracker()),
79 fCurrentDDLIndex(fgkMaxDDL),
80 fCurrentBlockHeader(0),
81 fCurrentBlockHeaderIndex(0),
83 fCurrentDspHeaderIndex(0),
85 fCurrentBusStructIndex(0),
90 /// create an object to read MUON raw digits
91 /// Default ctor for monitoring purposes
97 //_________________________________________________________________
98 AliMUONRawStreamTracker::AliMUONRawStreamTracker(AliRawReader* rawReader)
99 : AliMUONVRawStreamTracker(rawReader),
100 fPayload(new AliMUONPayloadTracker()),
102 fCurrentDDLIndex(fgkMaxDDL),
103 fCurrentBlockHeader(0),
104 fCurrentBlockHeaderIndex(0),
105 fCurrentDspHeader(0),
106 fCurrentDspHeaderIndex(0),
107 fCurrentBusStruct(0),
108 fCurrentBusStructIndex(0),
109 fCurrentDataIndex(0),
113 /// ctor with AliRawReader as argument
114 /// for reconstruction purpose
120 //___________________________________
121 AliMUONRawStreamTracker::~AliMUONRawStreamTracker()
129 //_____________________________________________________________
131 AliMUONRawStreamTracker::Next(Int_t& busPatchId,
132 UShort_t& manuId, UChar_t& manuChannel,
136 /// read the next raw digit (buspatch structure)
137 /// returns kFALSE if there is no digit left
138 /// Should call First() before this method to start the iteration.
141 if ( IsDone() ) return kFALSE;
143 if ( fCurrentDataIndex >= fCurrentBusStruct->GetLength()-1 )
145 Bool_t ok = GetNextBusStruct();
155 busPatchId = fCurrentBusStruct->GetBusPatchId();
156 manuId = fCurrentBusStruct->GetManuId(fCurrentDataIndex);
157 manuChannel = fCurrentBusStruct->GetChannelId(fCurrentDataIndex);
158 adc = fCurrentBusStruct->GetCharge(fCurrentDataIndex);
163 //______________________________________________________
165 AliMUONRawStreamTracker::IsDone() const
167 /// Whether the iteration is finished or not
168 return (fCurrentBusStruct==0);
171 //______________________________________________________
173 AliMUONRawStreamTracker::First()
175 /// Initialize the iteration process.
177 fCurrentDDLIndex = -1;
178 // fCurrentDspHeaderIndex = -1; // Not necessary since this gets reset in the GetNextXXX methods.
179 // fCurrentBusStructIndex = -1;
181 // Must reset all the pointers because if we return before calling
182 // GetNextBusStruct() the user might call CurrentDDL(), CurrentBlockHeader(),
183 // CurrentDspHeader() or CurrentBusStruct() which should return reasonable
184 // results in that case.
186 fCurrentBlockHeader = 0;
187 fCurrentDspHeader = 0;
188 fCurrentBusStruct = 0;
190 // Find the first non-empty structure
191 if (not GetNextDDL()) return;
192 if (not GetNextBlockHeader()) return;
193 if (not GetNextDspHeader()) return;
197 //______________________________________________________
199 AliMUONRawStreamTracker::GetNextDDL()
201 /// Returns the next DDL present
203 assert( GetReader() != 0 );
205 Bool_t kFound(kFALSE);
207 while ( fCurrentDDLIndex < fgkMaxDDL-1 && !kFound )
210 GetReader()->Reset();
211 GetReader()->Select("MUONTRK",fCurrentDDLIndex,fCurrentDDLIndex);
212 if ( GetReader()->ReadHeader() )
220 // fCurrentDDLIndex is set to fgkMaxDDL so that we exit the above loop immediately
221 // for a subsequent call to this method, unless NextEvent is called in between.
222 fCurrentDDLIndex = fgkMaxDDL;
223 // We have not actually been able to complete the loading of the new DDL so
224 // we are still on the old one. In this case we do not need to reset fCurrentDDL.
226 if (IsErrorLogger()) AddErrorMessage();
230 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
232 AliDebug(3, Form("DDL Number %d totalDataWord %d\n", fCurrentDDLIndex,
235 UInt_t *buffer = new UInt_t[totalDataWord/4];
237 if ( !GetReader()->ReadNext((UChar_t*)buffer, totalDataWord) )
239 // We have not actually been able to complete the loading of the new DDL so
240 // we are still on the old one. In this case we do not need to reset fCurrentDDL.
245 fPayload->ResetDDL();
248 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
251 Bool_t ok = fPayload->Decode(buffer, totalDataWord/4);
255 fCurrentDDL = fPayload->GetDDLTracker();
257 fCurrentBlockHeaderIndex = -1;
262 //______________________________________________________
264 AliMUONRawStreamTracker::GetNextBlockHeader()
266 /// Returns the next block Header present
268 assert( fCurrentDDL != 0 );
270 fCurrentBlockHeader = 0;
272 Int_t i(fCurrentBlockHeaderIndex);
274 while ( fCurrentBlockHeader == 0 && i < fCurrentDDL->GetBlkHeaderEntries()-1 )
277 fCurrentBlockHeader = fCurrentDDL->GetBlkHeaderEntry(i);
280 if ( !fCurrentBlockHeader )
282 Bool_t ok = GetNextDDL();
289 return GetNextBlockHeader();
293 fCurrentBlockHeaderIndex = i;
295 fCurrentDspHeaderIndex = -1;
300 //______________________________________________________
302 AliMUONRawStreamTracker::GetNextDspHeader()
304 /// Returns the next Dsp Header present
306 assert( fCurrentBlockHeader != 0 );
308 fCurrentDspHeader = 0;
310 Int_t i(fCurrentDspHeaderIndex);
312 while ( fCurrentDspHeader == 0 && i < fCurrentBlockHeader->GetDspHeaderEntries()-1 )
315 fCurrentDspHeader = fCurrentBlockHeader->GetDspHeaderEntry(i);
318 if ( !fCurrentDspHeader )
320 Bool_t ok = GetNextBlockHeader();
327 return GetNextDspHeader();
331 fCurrentDspHeaderIndex = i;
333 fCurrentBusStructIndex = -1;
338 //______________________________________________________
340 AliMUONRawStreamTracker::GetNextBusStruct()
342 /// Find the next non-empty busPatch structure
344 assert( fCurrentDspHeader != 0 );
346 fCurrentBusStruct = 0;
348 Int_t i(fCurrentBusStructIndex);
350 while ( fCurrentBusStruct == 0 && i < fCurrentDspHeader->GetBusPatchEntries()-1 )
353 fCurrentBusStruct = fCurrentDspHeader->GetBusPatchEntry(i);
356 if ( !fCurrentBusStruct )
358 Bool_t ok = GetNextDspHeader();
365 return GetNextBusStruct();
369 fCurrentBusStructIndex = i;
371 fCurrentDataIndex = -1;
376 //______________________________________________________
377 Bool_t AliMUONRawStreamTracker::NextDDL()
379 /// reading tracker DDL
381 assert( GetReader() != 0 );
383 fPayload->ResetDDL();
385 while ( fDDL < fgkMaxDDL )
387 GetReader()->Reset();
388 GetReader()->Select("MUONTRK", fDDL, fDDL); //Select the DDL file to be read
389 if (GetReader()->ReadHeader()) break;
390 AliDebug(3,Form("Skipping DDL %d which does not seem to be there",fDDL));
394 if ( fDDL == fgkMaxDDL )
397 if ( IsErrorLogger()) AddErrorMessage();
401 AliDebug(3, Form("DDL Number %d\n", fDDL ));
403 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
405 UInt_t *buffer = new UInt_t[totalDataWord/4];
407 if(!GetReader()->ReadNext((UChar_t*)buffer, totalDataWord))
414 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
417 Bool_t ok = fPayload->Decode(buffer, totalDataWord/4);
426 //______________________________________________________
427 void AliMUONRawStreamTracker::SetMaxBlock(Int_t blk)
429 /// set regional card number
430 fPayload->SetMaxBlock(blk);
433 //______________________________________________________
434 void AliMUONRawStreamTracker::AddErrorMessage()
436 /// add message into logger of AliRawReader per event
438 assert( GetReader() != 0 );
441 AliMUONLogger* log = fPayload->GetErrorLogger();
444 while(log->Next(msg, occurance))
446 if (msg.Contains("Parity"))
447 GetReader()->AddMinorErrorLog(kParityErr, msg.Data());
449 if (msg.Contains("Glitch"))
450 GetReader()->AddMajorErrorLog(kGlitchErr, msg.Data());
452 if (msg.Contains("Padding"))
453 GetReader()->AddMinorErrorLog(kPaddingWordErr, msg.Data());
456 log->Clear(); // clear logger after each event
459 //______________________________________________________
460 Bool_t AliMUONRawStreamTracker::IsErrorMessage() const
462 /// true if there is any error/warning
463 if (GetPayLoad()->GetParityErrors() ||
464 GetPayLoad()->GetGlitchErrors() ||
465 GetPayLoad()->GetPaddingErrors())