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