Adding MUONChamberMaterialBudget.C:
[u/mrichter/AliRoot.git] / MUON / AliMUONRawStreamTrigger.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 /// \class AliMUONRawStreamTrigger
20 /// This class provides access to MUON digits in raw data.
21 ///
22 /// It loops over all MUON digits in the raw data given by the AliRawReader.
23 /// The Next method goes to the next local response. If there are no local response left
24 /// it returns kFALSE.
25 /// It can loop also over DDL and store the decoded rawdata in TClonesArrays
26 /// in payload class.
27 /// 
28 /// Version implement for Trigger
29 /// \author Christian Finck
30 //-----------------------------------------------------------------------------
31
32 #include <TArrayS.h>
33
34 #include "AliMUONRawStreamTrigger.h"
35 #include "AliMUONDarcHeader.h"
36 #include "AliMUONRegHeader.h"
37 #include "AliMUONLocalStruct.h"
38 #include "AliMUONDDLTrigger.h"
39 #include "AliMUONLogger.h"
40
41 #include "AliRawReader.h"
42 #include "AliRawDataHeader.h"
43 #include "AliDAQ.h"
44 #include "AliLog.h"
45
46 #include <cassert>
47
48 /// \cond CLASSIMP
49 ClassImp(AliMUONRawStreamTrigger)
50 /// \endcond
51
52 const Int_t AliMUONRawStreamTrigger::fgkMaxDDL = 2;
53
54 //___________________________________________
55 AliMUONRawStreamTrigger::AliMUONRawStreamTrigger()
56 :   AliMUONVRawStreamTrigger(),
57     fPayload(new AliMUONPayloadTrigger()),
58     fCurrentDDL(0x0),
59     fCurrentDDLIndex(fgkMaxDDL),
60     fCurrentDarcHeader(0x0),
61     fCurrentRegHeader(0x0),
62     fCurrentRegHeaderIndex(0),
63     fCurrentLocalStruct(0x0),
64     fCurrentLocalStructIndex(0),
65     fLocalStructRead(kFALSE),
66     fDDL(0),
67     fNextDDL(kFALSE),
68     fEnableErrorLogger(kFALSE)
69 {
70   ///
71   /// create an object to read MUON raw digits
72   /// Default ctor for monitoring purposes
73   ///
74
75
76 }
77
78 //_________________________________________________________________
79 AliMUONRawStreamTrigger::AliMUONRawStreamTrigger(AliRawReader* rawReader)
80   : AliMUONVRawStreamTrigger(rawReader),
81     fPayload(new AliMUONPayloadTrigger()),
82     fCurrentDDL(0x0),
83     fCurrentDDLIndex(fgkMaxDDL),
84     fCurrentDarcHeader(0x0),
85     fCurrentRegHeader(0x0),
86     fCurrentRegHeaderIndex(0),
87     fCurrentLocalStruct(0x0),
88     fCurrentLocalStructIndex(0),
89     fLocalStructRead(kFALSE),
90     fDDL(0),
91     fNextDDL(kFALSE),
92     fEnableErrorLogger(kFALSE)
93 {
94   ///
95   /// ctor with AliRawReader as argument
96   /// for reconstruction purpose
97   ///
98
99 }
100
101 //___________________________________
102 AliMUONRawStreamTrigger::~AliMUONRawStreamTrigger()
103 {
104   ///
105   /// clean up
106   ///
107   delete fPayload;
108 }
109
110 //_____________________________________________________________
111 Bool_t AliMUONRawStreamTrigger::Next(UChar_t& id,   UChar_t& dec,      Bool_t& trigY, 
112                                      UChar_t& yPos, UChar_t& sXDev,    UChar_t& xDev,
113                                      UChar_t& xPos, Bool_t& triggerY,  Bool_t& triggerX,
114                                      TArrayS& xPattern, TArrayS& yPattern)
115 {
116   ///
117   /// read the next raw digit (local structure)
118   /// returns kFALSE if there is no digit left
119   /// Should call First() before this method to start the iteration.
120   ///
121   
122   if ( IsDone() ) return kFALSE;
123   
124   if ( fLocalStructRead ) {
125
126     Bool_t ok = GetNextLocalStruct();
127     if (!ok)
128     {
129       // this is the end
130       return kFALSE;
131     } 
132   }
133
134   fLocalStructRead = kTRUE;
135
136   id    = fCurrentLocalStruct->GetId();
137   dec   = fCurrentLocalStruct->GetDec(); 
138   trigY = fCurrentLocalStruct->GetTrigY();
139   yPos  = fCurrentLocalStruct->GetYPos();
140   sXDev = fCurrentLocalStruct->GetSXDev();
141   xDev  = fCurrentLocalStruct->GetXDev();
142   xPos  = fCurrentLocalStruct->GetXPos();
143
144   triggerX = fCurrentLocalStruct->GetTriggerX();
145   triggerY = fCurrentLocalStruct->GetTriggerY();
146
147   fCurrentLocalStruct->GetXPattern(xPattern);
148   fCurrentLocalStruct->GetYPattern(yPattern);
149
150   return kTRUE;
151 }
152
153 //______________________________________________________
154 Bool_t AliMUONRawStreamTrigger::IsDone() const
155 {
156   /// Whether the iteration is finished or not
157   return (fCurrentLocalStruct==0);
158 }
159
160 //______________________________________________________
161 void AliMUONRawStreamTrigger::First()
162 {
163   /// Initialize the iteration process.
164   
165   fCurrentDDLIndex = -1;
166   // Must reset all the pointers because if we return before calling
167   // GetNextLocalStruct() the user might call CurrentDDL(), CurrentBlockHeader(),
168   // CurrentRegHeader() or CurrentLocalStruct() which should return reasonable
169   // results in that case.
170   fCurrentDDL         = 0;
171   fCurrentDarcHeader  = 0;
172   fCurrentRegHeader   = 0;
173   fCurrentLocalStruct = 0;
174   
175   // Find the first non-empty structure
176   if (not GetNextDDL()) return;
177   if (not GetNextRegHeader()) return;
178   GetNextLocalStruct();
179 }
180
181 //______________________________________________________
182 Bool_t AliMUONRawStreamTrigger::GetNextDDL()
183 {
184   /// Returns the next DDL present
185   
186   assert( GetReader() != 0 );
187
188   
189   Bool_t kFound(kFALSE);
190   
191   while ( fCurrentDDLIndex < fgkMaxDDL-1 && !kFound ) 
192   {
193     ++fCurrentDDLIndex;
194     GetReader()->Reset();
195     GetReader()->Select("MUONTRG",fCurrentDDLIndex,fCurrentDDLIndex);
196     if ( GetReader()->ReadHeader() ) 
197     {
198       kFound = kTRUE;
199     }
200   }
201   
202   if ( !kFound ) 
203   {
204     // fCurrentDDLIndex is set to fgkMaxDDL so that we exit the above loop immediately
205     // for a subsequent call to this method, unless NextEvent is called in between.
206     fCurrentDDLIndex = fgkMaxDDL;
207     // We have not actually been able to complete the loading of the new DDL so
208     // we are still on the old one. In this case we do not need to reset fCurrentDDL.
209     //fCurrentDDL = 0;
210     if (IsErrorLogger()) AddErrorMessage();
211     return kFALSE;
212   }
213   
214   Int_t totalDataWord  = GetReader()->GetDataSize(); // in bytes
215   
216   Bool_t scalerEvent =  GetReader()->GetDataHeader()->GetL1TriggerMessage() & 0x1;
217
218   AliDebug(3, Form("DDL Number %d totalDataWord %d\n", fCurrentDDLIndex,
219                    totalDataWord));
220
221   UInt_t *buffer = new UInt_t[totalDataWord/4];
222
223   if ( !GetReader()->ReadNext((UChar_t*)buffer, totalDataWord) )
224   {
225     // We have not actually been able to complete the loading of the new DDL so
226     // we are still on the old one. In this case we do not need to reset fCurrentDDL.
227     //fCurrentDDL = 0;
228     delete [] buffer;
229     return kFALSE;
230   }
231
232 #ifndef R__BYTESWAP  
233   Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
234 #endif
235
236   fPayload->ResetDDL();
237   
238
239
240   Bool_t ok = fPayload->Decode(buffer, scalerEvent);
241
242   delete[] buffer;
243   
244   fCurrentDDL = fPayload->GetDDLTrigger();
245   
246   fCurrentDarcHeader = fCurrentDDL->GetDarcHeader();
247   
248   fCurrentRegHeaderIndex = -1;
249
250
251   return ok;
252 }
253
254
255 //______________________________________________________
256 Bool_t AliMUONRawStreamTrigger::GetNextRegHeader()
257 {
258   /// Returns the next Reg Header present
259
260   assert( fCurrentDarcHeader != 0 );
261   assert( fCurrentDDL != 0 );
262
263   fCurrentRegHeader = 0;
264   
265   Int_t i = fCurrentRegHeaderIndex;
266   
267   while ( fCurrentRegHeader == 0 && i < fCurrentDarcHeader->GetRegHeaderEntries()-1 )
268   {
269     ++i;
270     fCurrentRegHeader = fCurrentDarcHeader->GetRegHeaderEntry(i);
271   }
272      
273   if ( !fCurrentRegHeader ) 
274   {
275     Bool_t ok = GetNextDDL();
276     if (!ok) 
277     {
278       return kFALSE;
279     }
280     else
281     {
282       return GetNextRegHeader();
283     }
284   }
285   
286   fCurrentRegHeaderIndex = i;
287   
288   fCurrentLocalStructIndex = -1;
289   
290   return kTRUE;
291 }
292
293 //______________________________________________________
294 Bool_t AliMUONRawStreamTrigger::GetNextLocalStruct()
295 {
296   /// Find the next non-empty local structure
297   
298   assert( fCurrentRegHeader != 0 );
299   
300   fCurrentLocalStruct = 0;
301
302   Int_t i = fCurrentLocalStructIndex;
303   
304   while ( fCurrentLocalStruct == 0 && i < fCurrentRegHeader->GetLocalEntries()-1 ) 
305   {
306     ++i;
307     fCurrentLocalStruct = fCurrentRegHeader->GetLocalEntry(i);
308   }
309     
310   if ( !fCurrentLocalStruct ) 
311   {
312     Bool_t ok = GetNextRegHeader();
313     if (!ok)
314     {
315       return kFALSE;
316     }
317     else
318     {
319       return GetNextLocalStruct();
320     }
321   }
322   
323   fCurrentLocalStructIndex = i;
324   
325   fLocalStructRead = kFALSE;
326   
327   return kTRUE;
328 }
329
330 //______________________________________________________
331 Bool_t AliMUONRawStreamTrigger::NextDDL()
332 {
333   /// reading tracker DDL
334   /// store local info into Array
335   /// store only non-empty structures
336
337   // reset TClones
338   fPayload->ResetDDL();
339
340
341   // loop over the two ddl's
342
343   while ( fDDL < fgkMaxDDL ) {
344     GetReader()->Reset();
345     GetReader()->Select("MUONTRG", fDDL, fDDL);  //Select the DDL file to be read  
346     if (GetReader()->ReadHeader()) break;
347     AliDebug(3,Form("Skipping DDL %d which does not seem to be there",fDDL));
348     ++fDDL;
349   }
350
351   if (fDDL >= fgkMaxDDL) {
352     fDDL = 0;
353     if (IsErrorLogger()) AddErrorMessage();
354     return kFALSE;
355   }
356
357   AliDebug(3, Form("DDL Number %d\n", fDDL ));
358
359   Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
360
361   Bool_t scalerEvent =  GetReader()->GetDataHeader() && GetReader()->GetDataHeader()->GetL1TriggerMessage() & 0x1;
362
363
364   UInt_t *buffer = new UInt_t[totalDataWord/4];
365
366   // check not necessary yet, but for future developments
367   if (!GetReader()->ReadNext((UChar_t*)buffer, totalDataWord)) return kFALSE; 
368   
369 #ifndef R__BYTESWAP
370   Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
371 #endif
372
373   fPayload->Decode(buffer, scalerEvent);
374
375
376   fDDL++;
377
378   delete [] buffer;
379
380
381   return kTRUE;
382 }
383
384 // //______________________________________________________
385 // void AliMUONRawStreamTrigger::SetMaxReg(Int_t reg) 
386 // {
387 //   /// set regional card number
388 //   fPayload->SetMaxReg(reg);
389 // }
390
391 //______________________________________________________
392 void AliMUONRawStreamTrigger::SetMaxLoc(Int_t loc) 
393 {
394   /// set local card number
395   fPayload->SetMaxLoc(loc);
396 }
397
398 //______________________________________________________
399 void AliMUONRawStreamTrigger::AddErrorMessage()
400 {
401 /// add message into logger of AliRawReader per event
402
403   TString msg;
404   Int_t occurance = 0;
405   AliMUONLogger* log = fPayload->GetErrorLogger();
406   
407   log->ResetItr();
408   while(log->Next(msg, occurance))
409   { 
410     if (msg.Contains("Darc"))
411       GetReader()->AddMajorErrorLog(kDarcEoWErr, msg.Data());
412
413     if (msg.Contains("Global"))
414       GetReader()->AddMajorErrorLog(kGlobalEoWErr, msg.Data());
415
416     if (msg.Contains("Regional"))
417       GetReader()->AddMajorErrorLog(kRegEoWErr, msg.Data());
418
419     if (msg.Contains("Local"))
420       GetReader()->AddMajorErrorLog(kLocalEoWErr, msg.Data());
421   }
422   
423   log->Clear(); // clear after each event
424 }