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