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)
53 //___________________________________________
54 AliMUONRawStreamTracker::AliMUONRawStreamTracker()
55 : AliMUONVRawStreamTracker(),
56 fPayload(new AliMUONPayloadTracker()),
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 for monitoring purposes
76 //_________________________________________________________________
77 AliMUONRawStreamTracker::AliMUONRawStreamTracker(AliRawReader* rawReader)
78 : AliMUONVRawStreamTracker(rawReader),
79 fPayload(new AliMUONPayloadTracker()),
81 fCurrentDDLIndex(fgkMaxDDL),
82 fCurrentBlockHeader(0),
83 fCurrentBlockHeaderIndex(0),
85 fCurrentDspHeaderIndex(0),
87 fCurrentBusStructIndex(0),
92 /// ctor with AliRawReader as argument
93 /// for reconstruction purpose
99 //___________________________________
100 AliMUONRawStreamTracker::~AliMUONRawStreamTracker()
108 //_____________________________________________________________
110 AliMUONRawStreamTracker::Next(Int_t& busPatchId,
111 UShort_t& manuId, UChar_t& manuChannel,
115 /// read the next raw digit (buspatch structure)
116 /// returns kFALSE if there is no digit left
117 /// Should call First() before this method to start the iteration.
120 if ( IsDone() ) return kFALSE;
122 if ( fCurrentDataIndex >= fCurrentBusStruct->GetLength()-1 )
124 Bool_t ok = GetNextBusStruct();
134 busPatchId = fCurrentBusStruct->GetBusPatchId();
135 manuId = fCurrentBusStruct->GetManuId(fCurrentDataIndex);
136 manuChannel = fCurrentBusStruct->GetChannelId(fCurrentDataIndex);
137 adc = fCurrentBusStruct->GetCharge(fCurrentDataIndex);
142 //______________________________________________________
144 AliMUONRawStreamTracker::IsDone() const
146 /// Whether the iteration is finished or not
147 return (fCurrentBusStruct==0);
150 //______________________________________________________
152 AliMUONRawStreamTracker::First()
154 /// Initialize the iteration process.
156 fCurrentDDLIndex = -1;
157 // fCurrentDspHeaderIndex = -1; // Not necessary since this gets reset in the GetNextXXX methods.
158 // fCurrentBusStructIndex = -1;
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.
165 fCurrentBlockHeader = 0;
166 fCurrentDspHeader = 0;
167 fCurrentBusStruct = 0;
169 // Find the first non-empty structure
170 if (not GetNextDDL()) return;
171 if (not GetNextBlockHeader()) return;
172 if (not GetNextDspHeader()) return;
176 //______________________________________________________
178 AliMUONRawStreamTracker::GetNextDDL()
180 /// Returns the next DDL present
182 assert( GetReader() != 0 );
184 Bool_t kFound(kFALSE);
186 while ( fCurrentDDLIndex < fgkMaxDDL-1 && !kFound )
189 GetReader()->Reset();
190 GetReader()->Select("MUONTRK",fCurrentDDLIndex,fCurrentDDLIndex);
191 if ( GetReader()->ReadHeader() )
199 // fCurrentDDLIndex is set to fgkMaxDDL so that we exit the above loop immediately
200 // for a subsequent call to this method, unless NextEvent is called in between.
201 fCurrentDDLIndex = fgkMaxDDL;
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.
205 if (IsErrorLogger()) AddErrorMessage();
209 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
211 AliDebug(3, Form("DDL Number %d totalDataWord %d\n", fCurrentDDLIndex,
214 UInt_t *buffer = new UInt_t[totalDataWord/4];
216 if ( !GetReader()->ReadNext((UChar_t*)buffer, totalDataWord) )
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.
224 fPayload->ResetDDL();
227 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
230 Bool_t ok = fPayload->Decode(buffer, totalDataWord/4);
234 fCurrentDDL = fPayload->GetDDLTracker();
236 fCurrentBlockHeaderIndex = -1;
241 //______________________________________________________
243 AliMUONRawStreamTracker::GetNextBlockHeader()
245 /// Returns the next block Header present
247 assert( fCurrentDDL != 0 );
249 fCurrentBlockHeader = 0;
251 Int_t i(fCurrentBlockHeaderIndex);
253 while ( fCurrentBlockHeader == 0 && i < fCurrentDDL->GetBlkHeaderEntries()-1 )
256 fCurrentBlockHeader = fCurrentDDL->GetBlkHeaderEntry(i);
259 if ( !fCurrentBlockHeader )
261 Bool_t ok = GetNextDDL();
268 return GetNextBlockHeader();
272 fCurrentBlockHeaderIndex = i;
274 fCurrentDspHeaderIndex = -1;
279 //______________________________________________________
281 AliMUONRawStreamTracker::GetNextDspHeader()
283 /// Returns the next Dsp Header present
285 assert( fCurrentBlockHeader != 0 );
287 fCurrentDspHeader = 0;
289 Int_t i(fCurrentDspHeaderIndex);
291 while ( fCurrentDspHeader == 0 && i < fCurrentBlockHeader->GetDspHeaderEntries()-1 )
294 fCurrentDspHeader = fCurrentBlockHeader->GetDspHeaderEntry(i);
297 if ( !fCurrentDspHeader )
299 Bool_t ok = GetNextBlockHeader();
306 return GetNextDspHeader();
310 fCurrentDspHeaderIndex = i;
312 fCurrentBusStructIndex = -1;
317 //______________________________________________________
319 AliMUONRawStreamTracker::GetNextBusStruct()
321 /// Find the next non-empty busPatch structure
323 assert( fCurrentDspHeader != 0 );
325 fCurrentBusStruct = 0;
327 Int_t i(fCurrentBusStructIndex);
329 while ( fCurrentBusStruct == 0 && i < fCurrentDspHeader->GetBusPatchEntries()-1 )
332 fCurrentBusStruct = fCurrentDspHeader->GetBusPatchEntry(i);
335 if ( !fCurrentBusStruct )
337 Bool_t ok = GetNextDspHeader();
344 return GetNextBusStruct();
348 fCurrentBusStructIndex = i;
350 fCurrentDataIndex = -1;
355 //______________________________________________________
356 Bool_t AliMUONRawStreamTracker::NextDDL()
358 /// reading tracker DDL
360 assert( GetReader() != 0 );
362 fPayload->ResetDDL();
364 while ( fDDL < fgkMaxDDL )
366 GetReader()->Reset();
367 GetReader()->Select("MUONTRK", fDDL, fDDL); //Select the DDL file to be read
368 if (GetReader()->ReadHeader()) break;
369 AliDebug(3,Form("Skipping DDL %d which does not seem to be there",fDDL));
373 if ( fDDL == fgkMaxDDL )
376 if ( IsErrorLogger()) AddErrorMessage();
380 AliDebug(3, Form("DDL Number %d\n", fDDL ));
382 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
384 UInt_t *buffer = new UInt_t[totalDataWord/4];
386 if(!GetReader()->ReadNext((UChar_t*)buffer, totalDataWord))
393 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
396 Bool_t ok = fPayload->Decode(buffer, totalDataWord/4);
405 //______________________________________________________
406 void AliMUONRawStreamTracker::SetMaxBlock(Int_t blk)
408 /// set regional card number
409 fPayload->SetMaxBlock(blk);
412 //______________________________________________________
413 void AliMUONRawStreamTracker::AddErrorMessage()
415 /// add message into logger of AliRawReader per event
417 assert( GetReader() != 0 );
420 AliMUONLogger* log = fPayload->GetErrorLogger();
423 while(log->Next(msg, occurance))
425 if (msg.Contains("Parity"))
426 GetReader()->AddMinorErrorLog(kParityErr, msg.Data());
428 if (msg.Contains("Glitch"))
429 GetReader()->AddMajorErrorLog(kGlitchErr, msg.Data());
431 if (msg.Contains("Padding"))
432 GetReader()->AddMinorErrorLog(kPaddingWordErr, msg.Data());
435 log->Clear(); // clear logger after each event
438 //______________________________________________________
439 Bool_t AliMUONRawStreamTracker::IsErrorMessage() const
441 /// true if there is any error/warning
442 if (GetPayLoad()->GetParityErrors() ||
443 GetPayLoad()->GetGlitchErrors() ||
444 GetPayLoad()->GetPaddingErrors())