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