1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Artur Szostak <artursz@iafrica.com> *
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 **************************************************************************/
19 /// \class AliMUONRawStreamTriggerHP
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,
27 /// AliMUONRawStreamTriggerHP* rawStream; // assume initialised
28 /// const AliMUONRawStreamTriggerHP::AliLocalStruct* localStruct;
29 /// while ((localStruct = rawStream->Next()) != NULL)
31 /// // Do something with localStruct here.
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.
39 /// \author Artur Szostak <artursz@iafrica.com>
41 #include "AliMUONRawStreamTriggerHP.h"
42 #include "AliRawReader.h"
53 ClassImp(AliMUONRawStreamTriggerHP)
56 const Int_t AliMUONRawStreamTriggerHP::fgkMaxDDL = 2;
59 AliMUONRawStreamTriggerHP::AliMUONRawStreamTriggerHP() :
60 AliMUONVRawStreamTrigger(),
64 fBuffer(new UChar_t[8192]),
65 fCurrentLocalStruct(NULL),
70 /// Default constructor.
73 fDecoder.ExitOnError(false);
75 fDecoder.GetHandler().SetMaxStructs(
76 fDecoder.MaxRegionals(),
80 fDecoder.GetHandler().SetRawStream(this);
84 AliMUONRawStreamTriggerHP::AliMUONRawStreamTriggerHP(AliRawReader* rawReader) :
85 AliMUONVRawStreamTrigger(rawReader),
89 fBuffer(new UChar_t[8192]),
90 fCurrentLocalStruct(NULL),
95 /// Constructor with AliRawReader as argument.
98 fDecoder.ExitOnError(false);
100 fDecoder.GetHandler().SetMaxStructs(
101 fDecoder.MaxRegionals(),
105 fDecoder.GetHandler().SetRawStream(this);
109 AliMUONRawStreamTriggerHP::~AliMUONRawStreamTriggerHP()
112 /// Default destructor which cleans up the memory allocated.
122 void AliMUONRawStreamTriggerHP::First()
124 /// Initialise or reset the iterator.
125 /// The first DDL will be found and decoded.
127 assert( GetReader() != NULL );
135 Bool_t AliMUONRawStreamTriggerHP::NextDDL()
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
142 assert( GetReader() != NULL );
144 fCurrentLocalStruct = NULL;
146 while (fDDL < GetMaxDDL())
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));
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())
168 AliDebug(3, Form("DDL Number %d\n", fDDL));
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)
183 fBuffer = new UChar_t[dataSize];
184 fBufferSize = dataSize;
186 catch (const std::bad_alloc&)
188 AliError("Could not allocate more buffer space. Cannot decode DDL.");
193 if (not GetReader()->ReadNext(fBuffer, dataSize))
199 Swap(reinterpret_cast<UInt_t*>(fBuffer), dataSize / sizeof(UInt_t)); // Swap needed for mac power pc.
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);
210 catch (const std::bad_alloc&)
212 AliError("Could not allocate more buffer space. Cannot decode DDL.");
216 // Update the current local structure pointer.
217 fCurrentLocalStruct = fDecoder.GetHandler().FirstLocalStruct();
219 fDDL++; // Remember to increment index to next DDL.
224 Bool_t AliMUONRawStreamTriggerHP::IsDone() const
226 /// Indicates whether the iteration is finished or not.
227 /// \return kTRUE if we already read all the digits and kFALSE if not.
233 Bool_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
240 const AliLocalStruct* localStruct = Next();
241 if (localStruct == NULL) return kFALSE;
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();
251 triggerX = localStruct->GetTriggerX();
252 triggerY = localStruct->GetTriggerY();
254 localStruct->GetXPattern(xPattern);
255 localStruct->GetYPattern(yPattern);
261 void AliMUONRawStreamTriggerHP::SetMaxRegAllowed(Int_t reg)
263 /// Set the maximum allowed number of regional cards in the DDL.
265 fDecoder.MaxRegionals( (UInt_t) reg );
267 fDecoder.GetHandler().SetMaxStructs(
268 fDecoder.MaxRegionals(),
274 void AliMUONRawStreamTriggerHP::SetMaxLoc(Int_t loc)
276 /// Sets the maximum number of local cards in the DDL.
278 fDecoder.MaxLocals( (UInt_t) loc );
280 fDecoder.GetHandler().SetMaxStructs(
281 fDecoder.MaxRegionals(),
286 ///////////////////////////////////////////////////////////////////////////////
288 void AliMUONRawStreamTriggerHP::AliHeader::Print() const
290 /// Print DARC header, global header and global scalars to screen.
292 cout << "===== DARC info =====" << endl;
293 cout << "Header bits : 0x" << hex << fDarcHeader << dec << endl;
294 if (fDarcScalars != NULL)
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;
315 cout << "Scalars == NULL" << endl;
318 cout << "===== Global info =====" << endl;
319 for (int i = 0; i < 4; i++)
321 cout << "Input[" << i << "] : " << fGlobalHeader->fInput[i] << " (0x"
322 << hex << fGlobalHeader->fInput[i] << dec << ")" << endl;
324 cout << "Output : " << fGlobalHeader->fOutput << " (0x"
325 << hex << fGlobalHeader->fOutput << dec << ")" << endl;
326 if (fGlobalScalars != NULL)
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++)
334 cout << "Scaler[" << j << "] : " << fGlobalScalars->fScaler[j] << " (0x"
335 << hex << fGlobalScalars->fScaler[j] << dec << ")" << endl;
337 cout << "Hold : " << fGlobalScalars->fHold << " (0x"
338 << hex << fGlobalScalars->fHold << dec << ")" << endl;
339 cout << "Spare : " << fGlobalScalars->fSpare << " (0x"
340 << hex << fGlobalScalars->fSpare << dec << ")" << endl;
344 cout << "Scalars == NULL" << endl;
348 void AliMUONRawStreamTriggerHP::AliRegionalHeader::Print() const
350 /// Print the regional header and scalars to screen.
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)
365 cout << "Clock : " << fScalars->fClk << " (0x"
366 << hex << fScalars->fClk << dec << ")" << endl;
367 for (int i = 0; i < 8; i++)
369 cout << "Scaler[" << i << "] : " << fScalars->fScaler[i] << " (0x"
370 << hex << fScalars->fScaler[i] << dec << ")" << endl;
372 cout << "Hold : " << fScalars->fHold << " (0x"
373 << hex << fScalars->fHold << dec << ")" << endl;
377 cout << "Scalars == NULL" << endl;
381 void AliMUONRawStreamTriggerHP::AliLocalStruct::Print() const
383 /// Print local trigger structure and scalars to screen.
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)
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++)
422 cout << "Scaler[" << i << "] : " << fScalars->fScaler[i] << " (0x"
423 << hex << fScalars->fScaler[i] << dec << ")" << endl;
425 cout << "EOS : " << fScalars->fEOS << " (0x"
426 << hex << fScalars->fEOS << dec << ")" << endl;
427 cout << "Reset : " << fScalars->fReset << " (0x"
428 << hex << fScalars->fReset << dec << ")" << endl;
432 cout << "Scalars == NULL" << endl;
436 ///////////////////////////////////////////////////////////////////////////////
438 AliMUONRawStreamTriggerHP::AliDecoderEventHandler::AliDecoderEventHandler() :
448 fCurrentRegional(NULL),
456 /// Default constructor
460 AliMUONRawStreamTriggerHP::AliDecoderEventHandler::~AliDecoderEventHandler()
462 /// Default destructor cleans up the allocated memory.
464 if (fRegionals != NULL) delete [] fRegionals;
465 if (fLocals != NULL) delete [] fLocals;
469 void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::SetMaxStructs(
470 UInt_t maxRegionals, UInt_t maxLocals
473 /// Sets the maximum number of structures allowed.
475 // Start by clearing the current arrays.
476 if (fRegionals != NULL)
478 delete [] fRegionals;
487 fCurrentRegional = NULL;
488 fCurrentLocal = NULL;
490 // Allocate new memory.
491 fRegionals = new AliRegionalHeader[maxRegionals];
492 fLocals = new AliLocalStruct[maxRegionals*maxLocals];
493 fEndOfLocals = fLocals;
497 void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::OnNewBuffer(
498 const void* buffer, UInt_t /*bufferSize*/
501 /// This is called by the high performance decoder when a new DDL payload
502 /// is about to be decoded.
504 assert( fRawStream != NULL );
506 // remember the start of the buffer to be used in OnError.
507 fBufferStart = buffer;
509 // Reset error counters.
511 fGlobalEoWErrors = 0;
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;
525 void AliMUONRawStreamTriggerHP::AliDecoderEventHandler::OnError(
526 ErrorCode error, const void* location
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.
537 assert( fRawStream != NULL );
538 assert( fRawStream->GetReader() != NULL );
540 Char_t* message = NULL;
545 case kWrongEventType:
546 message = Form("Wrong event type obtained from the Darc header, take the one of CDH");
552 "Wrong end of Darc word %x instead of %x\n",
553 *reinterpret_cast<const UInt_t*>(location),
554 AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfDarcWord()
556 fRawStream->GetReader()->AddMajorErrorLog(kDarcEoWErr, message);
559 case kBadEndOfGlobal:
562 "Wrong end of Global word %x instead of %x\n",
563 *reinterpret_cast<const UInt_t*>(location),
564 AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfGlobalWord()
566 fRawStream->GetReader()->AddMajorErrorLog(kGlobalEoWErr, message);
569 case kBadEndOfRegional:
572 "Wrong end of Regional word %x instead of %x\n",
573 *reinterpret_cast<const UInt_t*>(location),
574 AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfRegionalWord()
576 fRawStream->GetReader()->AddMajorErrorLog(kRegEoWErr, message);
582 "Wrong end of Local word %x instead of %x\n",
583 *reinterpret_cast<const UInt_t*>(location),
584 AliMUONTriggerDDLDecoder<AliMUONTriggerDDLDecoderEventHandler>::EndOfLocalWord()
586 fRawStream->GetReader()->AddMajorErrorLog(kLocalEoWErr, message);
591 "%s (At byte %d in DDL.)",
592 ErrorCodeToMessage(error),
593 (unsigned long)location - (unsigned long)fBufferStart + sizeof(AliRawDataHeader)
595 fRawStream->GetReader()->AddMajorErrorLog(error, message);
602 "AliMUONRawStreamTriggerHP::AliDecoderEventHandler",