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