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