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