]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - MUON/AliMUONRawStreamTracker.cxx
bug fixed
[u/mrichter/AliRoot.git] / MUON / AliMUONRawStreamTracker.cxx
... / ...
CommitLineData
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//-----------------------------------------------------------------------------
20/// \class AliMUONRawStreamTracker
21/// This class provides access to MUON digits in raw data.
22///
23/// It loops over all MUON digits in the raw data given by the AliRawReader.
24/// The Next method goes to the next digit. If there are no digits left
25/// it returns kFALSE
26/// It can loop also over DDL and store the decoded rawdata in TClonesArray
27/// in Payload class.
28///
29/// Implement for Tracker
30///
31/// \author Christian Finck & Laurent Aphecetche
32//-----------------------------------------------------------------------------
33
34#include "AliMUONRawStreamTracker.h"
35
36#include "AliMUONLogger.h"
37#include "AliRawReader.h"
38#include "AliRawDataHeader.h"
39#include "AliDAQ.h"
40#include "AliLog.h"
41#include "AliMUONPayloadTracker.h"
42#include "AliMUONBlockHeader.h"
43#include "AliMUONDspHeader.h"
44#include "AliMUONBusStruct.h"
45#include "AliMUONDDLTracker.h"
46#include "Riostream.h"
47#include <cassert>
48
49/// \cond CLASSIMP
50ClassImp(AliMUONRawStreamTracker)
51/// \endcond
52
53//___________________________________________
54AliMUONRawStreamTracker::AliMUONRawStreamTracker()
55 : AliMUONVRawStreamTracker(),
56 fPayload(new AliMUONPayloadTracker()),
57 fCurrentDDL(0),
58 fCurrentDDLIndex(fgkMaxDDL),
59 fCurrentBlockHeader(0),
60 fCurrentBlockHeaderIndex(0),
61 fCurrentDspHeader(0),
62 fCurrentDspHeaderIndex(0),
63 fCurrentBusStruct(0),
64 fCurrentBusStructIndex(0),
65 fCurrentDataIndex(0),
66 fDDL(0)
67{
68 ///
69 /// create an object to read MUON raw digits
70 /// Default ctor for monitoring purposes
71 ///
72
73
74}
75
76//_________________________________________________________________
77AliMUONRawStreamTracker::AliMUONRawStreamTracker(AliRawReader* rawReader)
78: AliMUONVRawStreamTracker(rawReader),
79 fPayload(new AliMUONPayloadTracker()),
80 fCurrentDDL(0),
81 fCurrentDDLIndex(fgkMaxDDL),
82 fCurrentBlockHeader(0),
83 fCurrentBlockHeaderIndex(0),
84 fCurrentDspHeader(0),
85 fCurrentDspHeaderIndex(0),
86 fCurrentBusStruct(0),
87 fCurrentBusStructIndex(0),
88 fCurrentDataIndex(0),
89 fDDL(0)
90{
91 ///
92 /// ctor with AliRawReader as argument
93 /// for reconstruction purpose
94 ///
95
96
97}
98
99//___________________________________
100AliMUONRawStreamTracker::~AliMUONRawStreamTracker()
101{
102 ///
103 /// clean up
104 ///
105 delete fPayload;
106}
107
108//_____________________________________________________________
109Bool_t
110AliMUONRawStreamTracker::Next(Int_t& busPatchId,
111 UShort_t& manuId, UChar_t& manuChannel,
112 UShort_t& adc)
113{
114 ///
115 /// read the next raw digit (buspatch 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 ( fCurrentDataIndex >= fCurrentBusStruct->GetLength()-1 )
123 {
124 Bool_t ok = GetNextBusStruct();
125 if (!ok)
126 {
127 // this is the end
128 return kFALSE;
129 }
130 }
131
132 ++fCurrentDataIndex;
133
134 busPatchId = fCurrentBusStruct->GetBusPatchId();
135 manuId = fCurrentBusStruct->GetManuId(fCurrentDataIndex);
136 manuChannel = fCurrentBusStruct->GetChannelId(fCurrentDataIndex);
137 adc = fCurrentBusStruct->GetCharge(fCurrentDataIndex);
138
139 return kTRUE;
140}
141
142//______________________________________________________
143Bool_t
144AliMUONRawStreamTracker::IsDone() const
145{
146 /// Whether the iteration is finished or not
147 return (fCurrentBusStruct==0);
148}
149
150//______________________________________________________
151void
152AliMUONRawStreamTracker::First()
153{
154 /// Initialize the iteration process.
155
156 fCurrentDDLIndex = -1;
157// fCurrentDspHeaderIndex = -1; // Not necessary since this gets reset in the GetNextXXX methods.
158// fCurrentBusStructIndex = -1;
159
160 // Must reset all the pointers because if we return before calling
161 // GetNextBusStruct() the user might call CurrentDDL(), CurrentBlockHeader(),
162 // CurrentDspHeader() or CurrentBusStruct() which should return reasonable
163 // results in that case.
164 fCurrentDDL = 0;
165 fCurrentBlockHeader = 0;
166 fCurrentDspHeader = 0;
167 fCurrentBusStruct = 0;
168
169 // Find the first non-empty structure
170 if (not GetNextDDL()) return;
171 if (not GetNextBlockHeader()) return;
172 if (not GetNextDspHeader()) return;
173 GetNextBusStruct();
174}
175
176//______________________________________________________
177Bool_t
178AliMUONRawStreamTracker::GetNextDDL()
179{
180 /// Returns the next DDL present
181
182 assert( GetReader() != 0 );
183
184 Bool_t kFound(kFALSE);
185
186 while ( fCurrentDDLIndex < fgkMaxDDL-1 && !kFound )
187 {
188 ++fCurrentDDLIndex;
189 GetReader()->Reset();
190 GetReader()->Select("MUONTRK",fCurrentDDLIndex,fCurrentDDLIndex);
191 if ( GetReader()->ReadHeader() )
192 {
193 kFound = kTRUE;
194 }
195 }
196
197 if ( !kFound )
198 {
199 // fCurrentDDLIndex is set to fgkMaxDDL so that we exit the above loop immediately
200 // for a subsequent call to this method, unless NextEvent is called in between.
201 fCurrentDDLIndex = fgkMaxDDL;
202 // We have not actually been able to complete the loading of the new DDL so
203 // we are still on the old one. In this case we do not need to reset fCurrentDDL.
204 //fCurrentDDL = 0;
205 if (IsErrorLogger()) AddErrorMessage();
206 return kFALSE;
207 }
208
209 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
210
211 AliDebug(3, Form("DDL Number %d totalDataWord %d\n", fCurrentDDLIndex,
212 totalDataWord));
213
214 UInt_t *buffer = new UInt_t[totalDataWord/4];
215
216 if ( !GetReader()->ReadNext((UChar_t*)buffer, totalDataWord) )
217 {
218 // We have not actually been able to complete the loading of the new DDL so
219 // we are still on the old one. In this case we do not need to reset fCurrentDDL.
220 //fCurrentDDL = 0;
221 delete [] buffer;
222 return kFALSE;
223 }
224 fPayload->ResetDDL();
225
226#ifndef R__BYTESWAP
227 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
228#endif
229
230 Bool_t ok = fPayload->Decode(buffer, totalDataWord/4);
231
232 delete[] buffer;
233
234 fCurrentDDL = fPayload->GetDDLTracker();
235
236 fCurrentBlockHeaderIndex = -1;
237
238 return ok;
239}
240
241//______________________________________________________
242Bool_t
243AliMUONRawStreamTracker::GetNextBlockHeader()
244{
245 /// Returns the next block Header present
246
247 assert( fCurrentDDL != 0 );
248
249 fCurrentBlockHeader = 0;
250
251 Int_t i(fCurrentBlockHeaderIndex);
252
253 while ( fCurrentBlockHeader == 0 && i < fCurrentDDL->GetBlkHeaderEntries()-1 )
254 {
255 ++i;
256 fCurrentBlockHeader = fCurrentDDL->GetBlkHeaderEntry(i);
257 }
258
259 if ( !fCurrentBlockHeader )
260 {
261 Bool_t ok = GetNextDDL();
262 if (!ok)
263 {
264 return kFALSE;
265 }
266 else
267 {
268 return GetNextBlockHeader();
269 }
270 }
271
272 fCurrentBlockHeaderIndex = i;
273
274 fCurrentDspHeaderIndex = -1;
275
276 return kTRUE;
277}
278
279//______________________________________________________
280Bool_t
281AliMUONRawStreamTracker::GetNextDspHeader()
282{
283 /// Returns the next Dsp Header present
284
285 assert( fCurrentBlockHeader != 0 );
286
287 fCurrentDspHeader = 0;
288
289 Int_t i(fCurrentDspHeaderIndex);
290
291 while ( fCurrentDspHeader == 0 && i < fCurrentBlockHeader->GetDspHeaderEntries()-1 )
292 {
293 ++i;
294 fCurrentDspHeader = fCurrentBlockHeader->GetDspHeaderEntry(i);
295 }
296
297 if ( !fCurrentDspHeader )
298 {
299 Bool_t ok = GetNextBlockHeader();
300 if (!ok)
301 {
302 return kFALSE;
303 }
304 else
305 {
306 return GetNextDspHeader();
307 }
308 }
309
310 fCurrentDspHeaderIndex = i;
311
312 fCurrentBusStructIndex = -1;
313
314 return kTRUE;
315}
316
317//______________________________________________________
318Bool_t
319AliMUONRawStreamTracker::GetNextBusStruct()
320{
321 /// Find the next non-empty busPatch structure
322
323 assert( fCurrentDspHeader != 0 );
324
325 fCurrentBusStruct = 0;
326
327 Int_t i(fCurrentBusStructIndex);
328
329 while ( fCurrentBusStruct == 0 && i < fCurrentDspHeader->GetBusPatchEntries()-1 )
330 {
331 ++i;
332 fCurrentBusStruct = fCurrentDspHeader->GetBusPatchEntry(i);
333 }
334
335 if ( !fCurrentBusStruct )
336 {
337 Bool_t ok = GetNextDspHeader();
338 if (!ok)
339 {
340 return kFALSE;
341 }
342 else
343 {
344 return GetNextBusStruct();
345 }
346 }
347
348 fCurrentBusStructIndex = i;
349
350 fCurrentDataIndex = -1;
351
352 return kTRUE;
353}
354
355//______________________________________________________
356Bool_t AliMUONRawStreamTracker::NextDDL()
357{
358 /// reading tracker DDL
359
360 assert( GetReader() != 0 );
361
362 fPayload->ResetDDL();
363
364 while ( fDDL < fgkMaxDDL )
365 {
366 GetReader()->Reset();
367 GetReader()->Select("MUONTRK", fDDL, fDDL); //Select the DDL file to be read
368 if (GetReader()->ReadHeader()) break;
369 AliDebug(3,Form("Skipping DDL %d which does not seem to be there",fDDL));
370 ++fDDL;
371 }
372
373 if ( fDDL == fgkMaxDDL )
374 {
375 fDDL = 0;
376 if ( IsErrorLogger()) AddErrorMessage();
377 return kFALSE;
378 }
379
380 AliDebug(3, Form("DDL Number %d\n", fDDL ));
381
382 Int_t totalDataWord = GetReader()->GetDataSize(); // in bytes
383
384 UInt_t *buffer = new UInt_t[totalDataWord/4];
385
386 if(!GetReader()->ReadNext((UChar_t*)buffer, totalDataWord))
387 {
388 delete[] buffer;
389 return kFALSE;
390 }
391
392#ifndef R__BYTESWAP
393 Swap(buffer, totalDataWord / sizeof(UInt_t)); // swap needed for mac power pc
394#endif
395
396 Bool_t ok = fPayload->Decode(buffer, totalDataWord/4);
397
398 delete[] buffer;
399
400 fDDL++;
401
402 return ok;
403}
404
405//______________________________________________________
406void AliMUONRawStreamTracker::SetMaxBlock(Int_t blk)
407{
408 /// set regional card number
409 fPayload->SetMaxBlock(blk);
410}
411
412//______________________________________________________
413void AliMUONRawStreamTracker::AddErrorMessage()
414{
415 /// add message into logger of AliRawReader per event
416
417 assert( GetReader() != 0 );
418 TString msg;
419 Int_t occurance = 0;
420 AliMUONLogger* log = fPayload->GetErrorLogger();
421
422 log->ResetItr();
423 while(log->Next(msg, occurance))
424 {
425 if (msg.Contains("Parity"))
426 GetReader()->AddMinorErrorLog(kParityErr, msg.Data());
427
428 if (msg.Contains("Glitch"))
429 GetReader()->AddMajorErrorLog(kGlitchErr, msg.Data());
430
431 if (msg.Contains("Padding"))
432 GetReader()->AddMinorErrorLog(kPaddingWordErr, msg.Data());
433 }
434
435 log->Clear(); // clear logger after each event
436}
437
438//______________________________________________________
439Bool_t AliMUONRawStreamTracker::IsErrorMessage() const
440{
441 /// true if there is any error/warning
442 if (GetPayLoad()->GetParityErrors() ||
443 GetPayLoad()->GetGlitchErrors() ||
444 GetPayLoad()->GetPaddingErrors())
445 return kTRUE;
446
447 return kFALSE;
448}
449
450
451
452
453