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