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