Cut class for the filtering of ESD V0s (Boris Hippolyte <hippolyt@in2p3.fr>)
[u/mrichter/AliRoot.git] / MUON / AliMUONRawStreamTriggerHP.cxx
CommitLineData
1788245f 1/**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
4 * *
5 * Primary Authors: *
6 * Artur Szostak <artursz@iafrica.com> *
7 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17/* $Id$ */
18
19/// \class AliMUONRawStreamTriggerHP
20///
21/// Implementation of a streamer interface to the high performance trigger decoder.
22/// This is the raw stream class which interfaces between the high performance
23/// core decoder for MUON trigger chambers and the AliRawReader class.
24/// To gain the most out of the decoder, the Next() method should be used,
25/// for example:
26/// \code
27/// AliMUONRawStreamTriggerHP* rawStream; // assume initialised
28/// const AliMUONRawStreamTriggerHP::AliLocalStruct* localStruct;
29/// while ((localStruct = rawStream->Next()) != NULL)
30/// {
31/// // Do something with localStruct here.
32/// }
33/// \endcode
34///
35/// This decoder tries to implement as similar an interface as possible to
36/// AliMUONRawStreamTrigger where possible. However certain constructs which
37/// would slow us down too much are avoided.
38///
39/// \author Artur Szostak <artursz@iafrica.com>
40
41#include "AliMUONRawStreamTriggerHP.h"
42#include "AliRawReader.h"
43#include "AliLog.h"
44#include <cassert>
45#include <iostream>
46#include <iomanip>
47using std::cout;
48using std::endl;
49using std::hex;
50using std::dec;
51
52/// \cond CLASSIMP
53ClassImp(AliMUONRawStreamTriggerHP)
54/// \endcond
55
56const Int_t AliMUONRawStreamTriggerHP::fgkMaxDDL = 2;
57
58
59AliMUONRawStreamTriggerHP::AliMUONRawStreamTriggerHP() :
60 AliMUONVRawStreamTrigger(),
61 fDecoder(),
62 fDDL(0),
63 fBufferSize(8192),
64 fBuffer(new UChar_t[8192]),
65 fCurrentLocalStruct(NULL),
66 fHadError(kFALSE),
67 fDone(kFALSE)
68{
69 ///
70 /// Default constructor.
71 ///
72
73 fDecoder.ExitOnError(false);
74
75 fDecoder.GetHandler().SetMaxStructs(
76 fDecoder.MaxRegionals(),
77 fDecoder.MaxLocals()
78 );
79
80 fDecoder.GetHandler().SetRawStream(this);
81}
82
83
84AliMUONRawStreamTriggerHP::AliMUONRawStreamTriggerHP(AliRawReader* rawReader) :
85 AliMUONVRawStreamTrigger(rawReader),
86 fDecoder(),
87 fDDL(0),
88 fBufferSize(8192),
89 fBuffer(new UChar_t[8192]),
90 fCurrentLocalStruct(NULL),
91 fHadError(kFALSE),
92 fDone(kFALSE)
93{
94 ///
95 /// Constructor with AliRawReader as argument.
96 ///
97
98 fDecoder.ExitOnError(false);
99
100 fDecoder.GetHandler().SetMaxStructs(
101 fDecoder.MaxRegionals(),
102 fDecoder.MaxLocals()
103 );
104
105 fDecoder.GetHandler().SetRawStream(this);
106}
107
108
109AliMUONRawStreamTriggerHP::~AliMUONRawStreamTriggerHP()
110{
111 ///
112 /// Default destructor which cleans up the memory allocated.
113 ///
114
115 if (fBuffer != NULL)
116 {
117 delete [] fBuffer;
118 }
119}
120
121
122void AliMUONRawStreamTriggerHP::First()
123{
124 /// Initialise or reset the iterator.
125 /// The first DDL will be found and decoded.
126
127 assert( GetReader() != NULL );
128
129 fDDL = 0;
130 fDone = kFALSE;
131 NextDDL();
132}
133
134
135Bool_t AliMUONRawStreamTriggerHP::NextDDL()
136{
137 /// Read in the next trigger DDL and decode the payload with the
138 /// high performance decoder.
139 /// \return kTRUE if the next DDL was successfully read and kFALSE
140 /// otherwise.
141
142 assert( GetReader() != NULL );
143
144 fCurrentLocalStruct = NULL;
145
146 while (fDDL < GetMaxDDL())
147 {
148 GetReader()->Reset();
149 GetReader()->Select("MUONTRG", fDDL, fDDL); // Select the DDL file to be read.
150 if (GetReader()->ReadHeader()) break;
151 AliDebug(3, Form("Skipping DDL %d which does not seem to be there", fDDL+1));
152 fDDL++;
153 }
154
155 // If we reach the end of the DDL list for this event then reset the
156 // DDL counter, mark the iteration as done and exit.
157 if (fDDL >= GetMaxDDL())
158 {
159 fDDL = 0;
160 fDone = kTRUE;
161 return kFALSE;
162 }
163 else
164 {
165 fDone = kFALSE;
166 }
167
168 AliDebug(3, Form("DDL Number %d\n", fDDL));
169
170 Int_t dataSize = GetReader()->GetDataSize(); // in bytes
171 // Check if we have enough buffer space already in fBuffer. If we do then
172 // just continue reading otherwise we need to resize the buffer.
173 if (fBufferSize < dataSize)
174 {
175 if (fBuffer != NULL)
176 {
177 delete [] fBuffer;
178 fBuffer = NULL;
179 fBufferSize = 0;
180 }
181 try
182 {
183 fBuffer = new UChar_t[dataSize];
184 fBufferSize = dataSize;
185 }
186 catch (const std::bad_alloc&)
187 {
188 AliError("Could not allocate more buffer space. Cannot decode DDL.");
189 return kFALSE;
190 }
191 }
192
193 if (not GetReader()->ReadNext(fBuffer, dataSize))
194 {
195 return kFALSE;
196 }
197
198#ifndef R__BYTESWAP
199 Swap(reinterpret_cast<UInt_t*>(fBuffer), dataSize / sizeof(UInt_t)); // Swap needed for mac power pc.
200#endif
201
202 bool result = false;
203 try
204 {
205 // Since we might allocate memory inside OnNewBuffer in the event
206 // handler we need to trap any memory allocation exception to be robust.
207 result = fDecoder.Decode(fBuffer, dataSize);
208 fHadError = (result == true ? kFALSE : kTRUE);
209 }
210 catch (const std::bad_alloc&)
211 {
212 AliError("Could not allocate more buffer space. Cannot decode DDL.");
213 return kFALSE;
214 }
215
216 // Update the current local structure pointer.
217 fCurrentLocalStruct = fDecoder.GetHandler().FirstLocalStruct();
218
219 fDDL++; // Remember to increment index to next DDL.
220 return kTRUE;
221}
222
223
224Bool_t AliMUONRawStreamTriggerHP::IsDone() const
225{
226 /// Indicates whether the iteration is finished or not.
227 /// \return kTRUE if we already read all the digits and kFALSE if not.
228
229 return fDone;
230}
231
232
233Bool_t AliMUONRawStreamTriggerHP::Next(
234 UChar_t& id, UChar_t& dec, Bool_t& trigY,
235 UChar_t& yPos, UChar_t& sXDev, UChar_t& xDev,
236 UChar_t& xPos, Bool_t& triggerY, Bool_t& triggerX,
237 TArrayS& xPattern, TArrayS& yPattern
238 )
239{
240 const AliLocalStruct* localStruct = Next();
241 if (localStruct == NULL) return kFALSE;
242
243 id = localStruct->GetId();
244 dec = localStruct->GetDec();
245 trigY = localStruct->GetTrigY();
246 yPos = localStruct->GetYPos();
247 sXDev = localStruct->GetSXDev();
248 xDev = localStruct->GetXDev();
249 xPos = localStruct->GetXPos();
250
251 triggerX = localStruct->GetTriggerX();
252 triggerY = localStruct->GetTriggerY();
253
254 localStruct->GetXPattern(xPattern);
255 localStruct->GetYPattern(yPattern);
256
257 return kTRUE;
258}
259
260
261void AliMUONRawStreamTriggerHP::SetMaxRegAllowed(Int_t reg)
262{
263 /// Set the maximum allowed number of regional cards in the DDL.
264
265 fDecoder.MaxRegionals( (UInt_t) reg );
266
267 fDecoder.GetHandler().SetMaxStructs(
268 fDecoder.MaxRegionals(),
269 fDecoder.MaxLocals()
270 );
271}
272
273
274void AliMUONRawStreamTriggerHP::SetMaxLoc(Int_t loc)
275{
276 /// Sets the maximum number of local cards in the DDL.
277
278 fDecoder.MaxLocals( (UInt_t) loc );
279
280 fDecoder.GetHandler().SetMaxStructs(
281 fDecoder.MaxRegionals(),
282 fDecoder.MaxLocals()
283 );
284}
285
286///////////////////////////////////////////////////////////////////////////////
287
288void AliMUONRawStreamTriggerHP::AliHeader::Print() const
289{
290 /// Print DARC header, global header and global scalars to screen.
291
292 cout << "===== DARC info =====" << endl;
293 cout << "Header bits : 0x" << hex << fDarcHeader << dec << endl;
294 if (fDarcScalars != NULL)
295 {
296 cout << "L0R : " << fDarcScalars->fL0R << " (0x"
297 << hex << fDarcScalars->fL0R << dec << ")" << endl;
298 cout << "L1P : " << fDarcScalars->fL1P << " (0x"
299 << hex << fDarcScalars->fL1P << dec << ")" << endl;
300 cout << "L1S : " << fDarcScalars->fL1S << " (0x"
301 << hex << fDarcScalars->fL1S << dec << ")" << endl;
302 cout << "L2A : " << fDarcScalars->fL2A << " (0x"
303 << hex << fDarcScalars->fL2A << dec << ")" << endl;
304 cout << "L2R : " << fDarcScalars->fL2R << " (0x"
305 << hex << fDarcScalars->fL2R << dec << ")" << endl;
306 cout << "Clock : " << fDarcScalars->fClk << " (0x"
307 << hex << fDarcScalars->fClk << dec << ")" << endl;
308 cout << "Hold : " << fDarcScalars->fHold << " (0x"
309 << hex << fDarcScalars->fHold << dec << ")" << endl;
310 cout << "Spare : " << fDarcScalars->fSpare << " (0x"
311 << hex << fDarcScalars->fSpare << dec << ")" << endl;
312 }
313 else
314 {
315 cout << "Scalars == NULL" << endl;
316 }
317
318 cout << "===== Global info =====" << endl;
319 for (int i = 0; i < 4; i++)
320 {
321 cout << "Input[" << i << "] : " << fGlobalHeader->fInput[i] << " (0x"
322 << hex << fGlobalHeader->fInput[i] << dec << ")" << endl;
323 }
324 cout << "Output : " << fGlobalHeader->fOutput << " (0x"
325 << hex << fGlobalHeader->fOutput << dec << ")" << endl;
326 if (fGlobalScalars != NULL)
327 {
328 cout << "L0 : " << fGlobalScalars->fL0 << " (0x"
329 << hex << fGlobalScalars->fL0 << dec << ")" << endl;
330 cout << "Clock : " << fGlobalScalars->fClk << " (0x"
331 << hex << fGlobalScalars->fClk << dec << ")" << endl;
332 for (int j = 0; j < 4; j++)
333 {
334 cout << "Scaler[" << j << "] : " << fGlobalScalars->fScaler[j] << " (0x"
335 << hex << fGlobalScalars->fScaler[j] << dec << ")" << endl;
336 }
337 cout << "Hold : " << fGlobalScalars->fHold << " (0x"
338 << hex << fGlobalScalars->fHold << dec << ")" << endl;
339 cout << "Spare : " << fGlobalScalars->fSpare << " (0x"
340 << hex << fGlobalScalars->fSpare << dec << ")" << endl;
341 }
342 else
343 {
344 cout << "Scalars == NULL" << endl;
345 }
346}
347
348void AliMUONRawStreamTriggerHP::AliRegionalHeader::Print() const
349{
350 /// Print the regional header and scalars to screen.
351
352 cout << "===== Regional card info =====" << endl;
353 cout << "DarcWord : " << fHeader->fDarcWord << " (0x"
354 << hex << fHeader->fDarcWord << dec << ")" << endl;
355 cout << "Word : " << fHeader->fWord << " (0x"
356 << hex << fHeader->fWord << dec << ")" << endl;
357 cout << "Input[0] : " << fHeader->fInput[0] << " (0x"
358 << hex << fHeader->fInput[0] << dec << ")" << endl;
359 cout << "Input[1] : " << fHeader->fInput[1] << " (0x"
360 << hex << fHeader->fInput[1] << dec << ")" << endl;
361 cout << "L0/Mask : " << fHeader->fL0CountAndMask << " (0x"
362 << hex << fHeader->fL0CountAndMask << dec << ")" << endl;
363 if (fScalars != NULL)
364 {
365 cout << "Clock : " << fScalars->fClk << " (0x"
366 << hex << fScalars->fClk << dec << ")" << endl;
367 for (int i = 0; i < 8; i++)
368 {
369 cout << "Scaler[" << i << "] : " << fScalars->fScaler[i] << " (0x"
370 << hex << fScalars->fScaler[i] << dec << ")" << endl;
371 }
372 cout << "Hold : " << fScalars->fHold << " (0x"
373 << hex << fScalars->fHold << dec << ")" << endl;
374 }
375 else
376 {
377 cout << "Scalars == NULL" << endl;
378 }
379}
380
381void AliMUONRawStreamTriggerHP::AliLocalStruct::Print() const
382{
383 /// Print local trigger structure and scalars to screen.
384
385 cout << "===== Local card info =====" << endl;
386 cout << "X2X1 : " << fLocalStruct->fX2X1 << " (0x"
387 << hex << fLocalStruct->fX2X1 << dec << ")" << endl;
388 cout << "X4X3 : " << fLocalStruct->fX4X3 << " (0x"
389 << hex << fLocalStruct->fX4X3 << dec << ")" << endl;
390 cout << "Y2Y1 : " << fLocalStruct->fY2Y1 << " (0x"
391 << hex << fLocalStruct->fY2Y1 << dec << ")" << endl;
392 cout << "Y4Y3 : " << fLocalStruct->fY4Y3 << " (0x"
393 << hex << fLocalStruct->fY4Y3 << dec << ")" << endl;
394 cout << "Trigger bits : " << fLocalStruct->fTriggerBits << " (0x"
395 << hex << fLocalStruct->fTriggerBits << dec << ")" << endl;
396 if (fScalars != NULL)
397 {
398 cout << "L0 : " << fScalars->fL0 << " (0x"
399 << hex << fScalars->fL0 << dec << ")" << endl;
400 cout << "Hold : " << fScalars->fHold << " (0x"
401 << hex << fScalars->fHold << dec << ")" << endl;
402 cout << "Clock : " << fScalars->fClk << " (0x"
403 << hex << fScalars->fClk << dec << ")" << endl;
404 cout << "LPtNTrig : " << fScalars->fLPtNTrig << " (0x"
405 << hex << fScalars->fLPtNTrig << dec << ")" << endl;
406 cout << "HPtNTrig : " << fScalars->fHPtNTrig << " (0x"
407 << hex << fScalars->fHPtNTrig << dec << ")" << endl;
408 cout << "LPtRTrig : " << fScalars->fLPtRTrig << " (0x"
409 << hex << fScalars->fLPtRTrig << dec << ")" << endl;
410 cout << "HPtRTrig : " << fScalars->fHPtRTrig << " (0x"
411 << hex << fScalars->fHPtRTrig << dec << ")" << endl;
412 cout << "LPtLTrig : " << fScalars->fLPtLTrig << " (0x"
413 << hex << fScalars->fLPtLTrig << dec << ")" << endl;
414 cout << "HPtLTrig : " << fScalars->fHPtLTrig << " (0x"
415 << hex << fScalars->fHPtLTrig << dec << ")" << endl;
416 cout << "LPtSTrig : " << fScalars->fLPtSTrig << " (0x"
417 << hex << fScalars->fLPtSTrig << dec << ")" << endl;
418 cout << "HPtSTrig : " << fScalars->fHPtSTrig << " (0x"
419 << hex << fScalars->fHPtSTrig << dec << ")" << endl;
420 for (int i = 0; i < 8*4; i++)
421 {
422 cout << "Scaler[" << i << "] : " << fScalars->fScaler[i] << " (0x"
423 << hex << fScalars->fScaler[i] << dec << ")" << endl;
424 }
425 cout << "EOS : " << fScalars->fEOS << " (0x"
426 << hex << fScalars->fEOS << dec << ")" << endl;
427 cout << "Reset : " << fScalars->fReset << " (0x"
428 << hex << fScalars->fReset << dec << ")" << endl;
429 }
430 else
431 {
432 cout << "Scalars == NULL" << endl;
433 }
434}
435
436///////////////////////////////////////////////////////////////////////////////
437
438AliMUONRawStreamTriggerHP::AliDecoderEventHandler::AliDecoderEventHandler() :
439 fRawStream(NULL),
440 fBufferStart(NULL),
441 fDarcHeader(0),
442 fDarcScalars(NULL),
443 fHeaders(),
444 fRegionalsCount(0),
445 fRegionals(NULL),
446 fLocals(NULL),
447 fEndOfLocals(NULL),
448 fCurrentRegional(NULL),
449 fCurrentLocal(NULL),
450 fDarcEoWErrors(0),
451 fGlobalEoWErrors(0),
452 fRegEoWErrors(0),
453 fLocalEoWErrors(0),
454 fWarnings(kTRUE)
455{
456 /// Default constructor
457}
458
459
460AliMUONRawStreamTriggerHP::AliDecoderEventHandler::~AliDecoderEventHandler()
461{
462 /// Default destructor cleans up the allocated memory.
463
464 if (fRegionals != NULL) delete [] fRegionals;
465 if (fLocals != NULL) delete [] fLocals;
466}
467
468
469void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::SetMaxStructs(
470 UInt_t maxRegionals, UInt_t maxLocals
471 )
472{
473 /// Sets the maximum number of structures allowed.
474
475 // Start by clearing the current arrays.
476 if (fRegionals != NULL)
477 {
478 delete [] fRegionals;
479 fRegionals = NULL;
480 }
481 if (fLocals != NULL)
482 {
483 delete [] fLocals;
484 fLocals = NULL;
485 fEndOfLocals = NULL;
486 }
487 fCurrentRegional = NULL;
488 fCurrentLocal = NULL;
489
490 // Allocate new memory.
491 fRegionals = new AliRegionalHeader[maxRegionals];
492 fLocals = new AliLocalStruct[maxRegionals*maxLocals];
493 fEndOfLocals = fLocals;
494}
495
496
497void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::OnNewBuffer(
498 const void* buffer, UInt_t /*bufferSize*/
499 )
500{
501 /// This is called by the high performance decoder when a new DDL payload
502 /// is about to be decoded.
503
504 assert( fRawStream != NULL );
505
506 // remember the start of the buffer to be used in OnError.
507 fBufferStart = buffer;
508
509 // Reset error counters.
510 fDarcEoWErrors = 0;
511 fGlobalEoWErrors = 0;
512 fRegEoWErrors = 0;
513 fLocalEoWErrors = 0;
514
515 // Reset the current pointers which will be used to track where we need to
516 // fill fRegionals and fLocals. We have to subtract one space because we
517 // will increment the pointer the first time in the OnNewRegionalStruct
518 // and OnLocalStruct methods.
519 fCurrentRegional = fRegionals-1;
520 fCurrentLocal = fLocals-1;
521 fRegionalsCount = 0;
522}
523
524
525void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::OnError(
526 ErrorCode error, const void* location
527 )
528{
529 /// This is called by the high performance decoder when a error occurs
530 /// when trying to decode the DDL payload. This indicates corruption in
531 /// the data. This method converts the error code to a descriptive message
532 /// and logs this with the raw reader.
533 /// \param error The error code indicating the problem.
534 /// \param location A pointer to the location within the DDL payload buffer
535 /// being decoded where the problem with the data was found.
536
537 assert( fRawStream != NULL );
538 assert( fRawStream->GetReader() != NULL );
539
540 Char_t* message = NULL;
541 //UInt_t word = 0;
542
543 switch (error)
544 {
545 case kWrongEventType:
546 message = Form("Wrong event type obtained from the Darc header, take the one of CDH");
547 break;
548
549 case kBadEndOfDarc:
550 fDarcEoWErrors++;
551 message = Form(
552 "Wrong end of Darc word %x instead of %x\n",
553 *reinterpret_cast<const UInt_t*>(location),
554 AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfDarcWord()
555 );
556 fRawStream->GetReader()->AddMajorErrorLog(kDarcEoWErr, message);
557 break;
558
559 case kBadEndOfGlobal:
560 fGlobalEoWErrors++;
561 message = Form(
562 "Wrong end of Global word %x instead of %x\n",
563 *reinterpret_cast<const UInt_t*>(location),
564 AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfGlobalWord()
565 );
566 fRawStream->GetReader()->AddMajorErrorLog(kGlobalEoWErr, message);
567 break;
568
569 case kBadEndOfRegional:
570 fRegEoWErrors++;
571 message = Form(
572 "Wrong end of Regional word %x instead of %x\n",
573 *reinterpret_cast<const UInt_t*>(location),
574 AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfRegionalWord()
575 );
576 fRawStream->GetReader()->AddMajorErrorLog(kRegEoWErr, message);
577 break;
578
579 case kBadEndOfLocal:
580 fLocalEoWErrors++;
581 message = Form(
582 "Wrong end of Local word %x instead of %x\n",
583 *reinterpret_cast<const UInt_t*>(location),
584 AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfLocalWord()
585 );
586 fRawStream->GetReader()->AddMajorErrorLog(kLocalEoWErr, message);
587 break;
588
589 default:
590 message = Form(
591 "%s (At byte %d in DDL.)",
592 ErrorCodeToMessage(error),
593 (unsigned long)location - (unsigned long)fBufferStart + sizeof(AliRawDataHeader)
594 );
595 fRawStream->GetReader()->AddMajorErrorLog(error, message);
596 break;
597 }
598
599 if (fWarnings)
600 {
601 AliWarningGeneral(
602 "AliMUONRawStreamTriggerHP::AliDecoderEventHandler",
603 message
604 );
605 }
606}
607