]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONRawStreamTriggerHP.cxx
Update in HP decoders:
[u/mrichter/AliRoot.git] / MUON / AliMUONRawStreamTriggerHP.cxx
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>
47 using std::cout;
48 using std::endl;
49 using std::hex;
50 using std::dec;
51
52 /// \cond CLASSIMP
53 ClassImp(AliMUONRawStreamTriggerHP)
54 /// \endcond
55
56 const Int_t AliMUONRawStreamTriggerHP::fgkMaxDDL = 2;
57
58
59 AliMUONRawStreamTriggerHP::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
84 AliMUONRawStreamTriggerHP::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
109 AliMUONRawStreamTriggerHP::~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
122 void 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
135 Bool_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
224 Bool_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
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
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
261 void 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
274 void 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
288 void 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
348 void 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
381 void 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
438 AliMUONRawStreamTriggerHP::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
460 AliMUONRawStreamTriggerHP::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
469 void 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
497 void 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
525 void 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