1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONRawStreamTrigger
20 /// This class provides access to MUON digits in raw data.
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
28 /// Version implement for Trigger
29 /// \author Christian Finck
30 //-----------------------------------------------------------------------------
34 #include "AliMUONRawStreamTrigger.h"
35 #include "AliMUONDarcHeader.h"
36 #include "AliMUONRegHeader.h"
37 #include "AliMUONLocalStruct.h"
38 #include "AliMUONDDLTrigger.h"
39 #include "AliMUONLogger.h"
41 #include "AliRawReader.h"
42 #include "AliRawDataHeader.h"
43 #include "AliRawDataHeaderV3.h"
50 ClassImp(AliMUONRawStreamTrigger)
53 const Int_t AliMUONRawStreamTrigger::fgkMaxDDL = 2;
55 //___________________________________________
56 AliMUONRawStreamTrigger::AliMUONRawStreamTrigger(TRootIOCtor* /*dummy*/)
57 : AliMUONVRawStreamTrigger(),
60 fCurrentDDLIndex(fgkMaxDDL),
61 fCurrentDarcHeader(0x0),
62 fCurrentRegHeader(0x0),
63 fCurrentRegHeaderIndex(0),
64 fCurrentLocalStruct(0x0),
65 fCurrentLocalStructIndex(0),
66 fLocalStructRead(kFALSE),
71 /// create an object to read MUON raw digits
72 /// Default ctor with no mem allocation for I/O
76 //___________________________________________
77 AliMUONRawStreamTrigger::AliMUONRawStreamTrigger()
78 : AliMUONVRawStreamTrigger(),
79 fPayload(new AliMUONPayloadTrigger()),
81 fCurrentDDLIndex(fgkMaxDDL),
82 fCurrentDarcHeader(0x0),
83 fCurrentRegHeader(0x0),
84 fCurrentRegHeaderIndex(0),
85 fCurrentLocalStruct(0x0),
86 fCurrentLocalStructIndex(0),
87 fLocalStructRead(kFALSE),
92 /// create an object to read MUON raw digits
93 /// Default ctor for monitoring purposes
99 //_________________________________________________________________
100 AliMUONRawStreamTrigger::AliMUONRawStreamTrigger(AliRawReader* rawReader)
101 : AliMUONVRawStreamTrigger(rawReader),
102 fPayload(new AliMUONPayloadTrigger()),
104 fCurrentDDLIndex(fgkMaxDDL),
105 fCurrentDarcHeader(0x0),
106 fCurrentRegHeader(0x0),
107 fCurrentRegHeaderIndex(0),
108 fCurrentLocalStruct(0x0),
109 fCurrentLocalStructIndex(0),
110 fLocalStructRead(kFALSE),
115 /// ctor with AliRawReader as argument
116 /// for reconstruction purpose
121 //___________________________________
122 AliMUONRawStreamTrigger::~AliMUONRawStreamTrigger()
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)
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.
142 if ( IsDone() ) return kFALSE;
144 if ( fLocalStructRead ) {
146 Bool_t ok = GetNextLocalStruct();
154 fLocalStructRead = kTRUE;
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();
164 triggerX = fCurrentLocalStruct->GetTriggerX();
165 triggerY = fCurrentLocalStruct->GetTriggerY();
167 fCurrentLocalStruct->GetXPattern(xPattern);
168 fCurrentLocalStruct->GetYPattern(yPattern);
173 //______________________________________________________
174 Bool_t AliMUONRawStreamTrigger::IsDone() const
176 /// Whether the iteration is finished or not
177 return (fCurrentLocalStruct==0);
180 //______________________________________________________
181 void AliMUONRawStreamTrigger::First()
183 /// Initialize the iteration process.
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.
191 fCurrentDarcHeader = 0;
192 fCurrentRegHeader = 0;
193 fCurrentLocalStruct = 0;
195 // Find the first non-empty structure
196 if (not GetNextDDL()) return;
197 if (not GetNextRegHeader()) return;
198 GetNextLocalStruct();
201 //______________________________________________________
202 Bool_t AliMUONRawStreamTrigger::GetNextDDL()
204 /// Returns the next DDL present
206 assert( GetReader() != 0 );
209 Bool_t kFound(kFALSE);
211 while ( fCurrentDDLIndex < fgkMaxDDL-1 && !kFound )
214 GetReader()->Reset();
215 GetReader()->Select("MUONTRG",fCurrentDDLIndex,fCurrentDDLIndex);
216 if ( GetReader()->ReadHeader() )
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.
230 if (IsErrorLogger()) AddErrorMessage();
234 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
236 AliRawReader * reader = GetReader();
237 if (!reader) return kFALSE;
239 const AliRawDataHeader * cdh = reader->GetDataHeader();
240 const AliRawDataHeaderV3 * cdh3 = reader->GetDataHeaderV3();
242 if (!cdh && !cdh3) return kFALSE;
244 Bool_t scalerEvent = ((cdh ? cdh->GetL1TriggerMessage() : cdh3->GetL1TriggerMessage()) & 0x1) == 0x1;
246 AliDebug(3, Form("DDL Number %d totalDataWord %d\n", fCurrentDDLIndex,
249 UInt_t *buffer = new UInt_t[totalDataWord/4];
251 if ( !GetReader()->ReadNext((UChar_t*)buffer, totalDataWord) )
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.
261 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
264 fPayload->ResetDDL();
268 Bool_t ok = fPayload->Decode(buffer, scalerEvent);
272 fCurrentDDL = fPayload->GetDDLTrigger();
274 fCurrentDarcHeader = fCurrentDDL->GetDarcHeader();
276 fCurrentRegHeaderIndex = -1;
283 //______________________________________________________
284 Bool_t AliMUONRawStreamTrigger::GetNextRegHeader()
286 /// Returns the next Reg Header present
288 assert( fCurrentDarcHeader != 0 );
289 assert( fCurrentDDL != 0 );
291 fCurrentRegHeader = 0;
293 Int_t i = fCurrentRegHeaderIndex;
295 while ( fCurrentRegHeader == 0 && i < fCurrentDarcHeader->GetRegHeaderEntries()-1 )
298 fCurrentRegHeader = fCurrentDarcHeader->GetRegHeaderEntry(i);
301 if ( !fCurrentRegHeader )
303 Bool_t ok = GetNextDDL();
310 return GetNextRegHeader();
314 fCurrentRegHeaderIndex = i;
316 fCurrentLocalStructIndex = -1;
321 //______________________________________________________
322 Bool_t AliMUONRawStreamTrigger::GetNextLocalStruct()
324 /// Find the next non-empty local structure
326 assert( fCurrentRegHeader != 0 );
328 fCurrentLocalStruct = 0;
330 Int_t i = fCurrentLocalStructIndex;
332 while ( fCurrentLocalStruct == 0 && i < fCurrentRegHeader->GetLocalEntries()-1 )
335 fCurrentLocalStruct = fCurrentRegHeader->GetLocalEntry(i);
338 if ( !fCurrentLocalStruct )
340 Bool_t ok = GetNextRegHeader();
347 return GetNextLocalStruct();
351 fCurrentLocalStructIndex = i;
353 fLocalStructRead = kFALSE;
358 //______________________________________________________
359 Bool_t AliMUONRawStreamTrigger::NextDDL()
361 /// reading tracker DDL
362 /// store local info into Array
363 /// store only non-empty structures
366 fPayload->ResetDDL();
369 // loop over the two ddl's
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));
379 if (fDDL >= fgkMaxDDL) {
381 if (IsErrorLogger()) AddErrorMessage();
385 AliDebug(3, Form("DDL Number %d\n", fDDL ));
387 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
389 AliRawReader * reader = GetReader();
390 if (!reader) return kFALSE;
392 const AliRawDataHeader * cdh = reader->GetDataHeader();
393 const AliRawDataHeaderV3 * cdh3 = reader->GetDataHeaderV3();
395 if (!cdh && !cdh3) return kFALSE;
397 Bool_t scalerEvent = ((cdh ? cdh->GetL1TriggerMessage() : cdh3->GetL1TriggerMessage()) & 0x1) == 0x1;
400 UInt_t *buffer = new UInt_t[totalDataWord/4];
402 // check not necessary yet, but for future developments
403 if (!GetReader()->ReadNext((UChar_t*)buffer, totalDataWord)) return kFALSE;
406 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
409 fPayload->Decode(buffer, scalerEvent);
420 // //______________________________________________________
421 // void AliMUONRawStreamTrigger::SetMaxReg(Int_t reg)
423 // /// set regional card number
424 // fPayload->SetMaxReg(reg);
427 //______________________________________________________
428 void AliMUONRawStreamTrigger::SetMaxLoc(Int_t loc)
430 /// set local card number
431 fPayload->SetMaxLoc(loc);
434 //______________________________________________________
435 void AliMUONRawStreamTrigger::AddErrorMessage()
437 /// add message into logger of AliRawReader per event
441 AliMUONLogger* log = fPayload->GetErrorLogger();
444 while(log->Next(msg, occurance))
446 if (msg.Contains("Darc"))
447 GetReader()->AddMajorErrorLog(kDarcEoWErr, msg.Data());
449 if (msg.Contains("Global"))
450 GetReader()->AddMajorErrorLog(kGlobalEoWErr, msg.Data());
452 if (msg.Contains("Regional"))
453 GetReader()->AddMajorErrorLog(kRegEoWErr, msg.Data());
455 if (msg.Contains("Local"))
456 GetReader()->AddMajorErrorLog(kLocalEoWErr, msg.Data());
459 log->Clear(); // clear after each event