]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/utils/AliHLTMUONDataCheckerComponent.cxx
ae9d87c92b27199229ee77b3779bcad354c59717
[u/mrichter/AliRoot.git] / HLT / MUON / utils / AliHLTMUONDataCheckerComponent.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: AliHLTMUONDataCheckerComponent.cxx 26179 2008-05-29 22:27:27Z aszostak $ */
18
19 ///
20 /// @file   AliHLTMUONDataCheckerComponent.cxx
21 /// @author Artur Szostak <artursz@iafrica.com>
22 /// @date   27 May 2008
23 /// @brief  Implementation of the dHLT data integrity checker component.
24 ///
25 /// This component is used to check the data integrity of dHLT raw internal data
26 /// blocks. If there are any problems found then an appropriate error message is
27 /// logged.
28 ///
29
30 #include "AliHLTMUONDataCheckerComponent.h"
31 #include "AliHLTMUONConstants.h"
32 #include "AliHLTLogging.h"
33 #include "AliHLTSystem.h"
34 #include "AliHLTDefinitions.h"
35 #include "AliRawDataHeader.h"
36 #include "AliMUONConstants.h"
37 #include "AliMUONTrackerDDLDecoder.h"
38 #include "AliMUONTrackerDDLDecoderEventHandler.h"
39 #include "AliMUONTriggerDDLDecoder.h"
40 #include "AliMUONTriggerDDLDecoderEventHandler.h"
41 #include "AliMpDDLStore.h"
42 #include "AliMpDEStore.h"
43 #include "AliMpDEManager.h"
44 #include "AliMpBusPatch.h"
45 #include "AliMpDetElement.h"
46 #include "AliMpSegmentation.h"
47 #include "AliMpVSegmentation.h"
48 #include "AliMpPad.h"
49 #include <cstring>
50 #include <cstdlib>
51 #include <cmath>
52 #include <cerrno>
53 #include <cassert>
54
55
56 namespace
57 {
58         /**
59          * Routine to check if at least one corresponding DDL has been marked
60          * for a particular chamber.
61          */
62         bool ChamberMarkedInDDLList(AliHLTInt32_t chamber, bool ddl[22])
63         {
64                 if (chamber < 0 or chamber > 21) return false;
65                 switch (chamber)
66                 {
67                 case 0:  return ddl[0] or ddl[1];
68                 case 1:  return ddl[2] or ddl[3];
69                 case 2:  return ddl[4] or ddl[5];
70                 case 3:  return ddl[6] or ddl[7];
71                 case 4:  return ddl[8] or ddl[9] or ddl[10] or ddl[11];
72                 case 5:  return ddl[8] or ddl[9] or ddl[10] or ddl[11];
73                 case 6:  return ddl[12] or ddl[13];
74                 case 7:  return ddl[14] or ddl[15];
75                 case 8:  return ddl[16] or ddl[17];
76                 case 9:  return ddl[18] or ddl[19];
77                 case 10: return ddl[20] or ddl[21];
78                 case 11: return ddl[20] or ddl[21];
79                 case 12: return ddl[20] or ddl[21];
80                 case 13: return ddl[20] or ddl[21];
81                 default: return false;
82                 }
83         }
84
85 } // end of namespace
86
87
88 ClassImp(AliHLTMUONDataCheckerComponent)
89
90
91 AliHLTMUONDataCheckerComponent::AliHLTMUONDataCheckerComponent() :
92         AliHLTMUONProcessor(),
93         fIgnoreType(false),
94         fIgnoreSpec(false),
95         fDontForward(false),
96         fFilterBadBlocks(false),
97         fNoGlobalChecks(false),
98         fWarnForUnexpecedBlock(false),
99         fReturnError(false)
100 {
101         /// Default constructor.
102 }
103
104
105 AliHLTMUONDataCheckerComponent::~AliHLTMUONDataCheckerComponent()
106 {
107         /// Default destructor.
108 }
109
110 const char* AliHLTMUONDataCheckerComponent::GetComponentID()
111 {
112         /// Inherited from AliHLTComponent. Returns the component ID.
113         
114         return AliHLTMUONConstants::DataCheckerComponentId();
115 }
116
117
118 void AliHLTMUONDataCheckerComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
119 {
120         /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
121         /// At the moment this list is "any data type" since it is not known before
122         /// hand what kind of input blocks we will get.
123         
124         assert( list.empty() );
125         list.push_back( kAliHLTAnyDataType );
126 }
127
128
129 AliHLTComponentDataType AliHLTMUONDataCheckerComponent::GetOutputDataType()
130 {
131         /// Inherited from AliHLTComponent. Returns the output data type of
132         /// "any data type" with MUON origin.
133         
134         return kAliHLTAnyDataType | kAliHLTDataOriginMUON;
135 }
136
137
138 void AliHLTMUONDataCheckerComponent::GetOutputDataSize(
139                 unsigned long& constBase, double& inputMultiplier
140         )
141 {
142         /// Inherited from AliHLTComponent.
143         /// Returns an estimate of the expected output data size.
144         
145         // Both of these are zero because we will only ever pass on input data blocks
146         // and never generate data in this component.
147         constBase = 0;
148         inputMultiplier = 0;
149 }
150
151
152 AliHLTComponent* AliHLTMUONDataCheckerComponent::Spawn()
153 {
154         /// Inherited from AliHLTComponent. Creates a new object instance.
155         
156         return new AliHLTMUONDataCheckerComponent;
157 }
158
159
160 int AliHLTMUONDataCheckerComponent::DoInit(int argc, const char** argv)
161 {
162         /// Inherited from AliHLTComponent.
163         /// Parses the command line parameters and initialises the component.
164         
165         HLTInfo("Initialising dHLT data checker component.");
166         
167         // Inherit the parents functionality.
168         int result = AliHLTMUONProcessor::DoInit(argc, argv);
169         if (result != 0) return result;
170
171         // Initialise flags with default values.
172         fIgnoreType = false;
173         fIgnoreSpec = false;
174         fDontForward = false;
175         fFilterBadBlocks = false;
176         fNoGlobalChecks = false;
177         fWarnForUnexpecedBlock = false;
178         fReturnError = false;
179
180         for (int i = 0; i < argc; i++)
181         {
182                 if (ArgumentAlreadyHandled(i, argv[i])) continue;
183
184                 if (strcmp(argv[i], "-ignoretype") == 0)
185                 {
186                         fIgnoreType = true;
187                         HLTInfo("Ignoring data type of data blocks as given by framework.");
188                         continue;
189                 }
190                 if (strcmp(argv[i], "-ignorespec") == 0)
191                 {
192                         fIgnoreSpec = true;
193                         HLTInfo("Ignoring data specification of data blocks as given by framework.");
194                         continue;
195                 }
196                 if (strcmp(argv[i], "-dontforward") == 0)
197                 {
198                         fDontForward = true;
199                         HLTInfo("Not forwarding input data blocks.");
200                         continue;
201                 }
202                 if (strcmp(argv[i], "-filter") == 0)
203                 {
204                         fFilterBadBlocks = true;
205                         HLTInfo("Passing only bad blocks to output.");
206                         continue;
207                 }
208                 if (strcmp(argv[i], "-no_global_check") == 0)
209                 {
210                         fNoGlobalChecks = true;
211                         HLTInfo("Only per block data consistancy checks will be applied,"
212                                 " but no global checks will be made."
213                         );
214                         continue;
215                 }
216                 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
217                 {
218                         fWarnForUnexpecedBlock = true;
219                         continue;
220                 }
221                 if (strcmp(argv[i], "-return_error") == 0)
222                 {
223                         fReturnError = true;
224                         continue;
225                 }
226                 
227                 HLTError("Unknown option '%s'.", argv[i]);
228                 return -EINVAL;
229         }
230
231         return 0;
232 }
233
234
235 int AliHLTMUONDataCheckerComponent::DoDeinit()
236 {
237         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
238         
239         HLTInfo("Deinitialising dHLT data checker component.");
240         return 0;
241 }
242
243
244 int AliHLTMUONDataCheckerComponent::DoEvent(
245                 const AliHLTComponentEventData& evtData,
246                 const AliHLTComponentBlockData* blocks,
247                 AliHLTComponentTriggerData& trigData,
248                 AliHLTUInt8_t* /*outputPtr*/,
249                 AliHLTUInt32_t& size,
250                 AliHLTComponentBlockDataList& outputBlocks
251         )
252 {
253         /// Inherited from AliHLTProcessor. Processes the new event data.
254         /// Here we go through the list of input data blocks and apply extensive
255         /// data integrity checking on the data found.
256         
257         if (not IsDataEvent()) return 0;
258         
259         HLTDebug("Processing event %llu with %u input data blocks.",
260                 evtData.fEventID, evtData.fBlockCnt
261         );
262         
263         // Allocate an array of flags indicating if the data block is OK or not,
264         // also arrays to store specific.
265         bool dataProblems = false;
266         bool* blockOk = NULL;
267         typedef const AliHLTComponentBlockData* PAliHLTComponentBlockData;
268         PAliHLTComponentBlockData* trigRecBlocks = NULL;
269         PAliHLTComponentBlockData* trigRecDebugBlocks = NULL;
270         PAliHLTComponentBlockData* hitBlocks = NULL;
271         PAliHLTComponentBlockData* clusterBlocks = NULL;
272         PAliHLTComponentBlockData* channelBlocks = NULL;
273         PAliHLTComponentBlockData* mansoTrackBlocks = NULL;
274         PAliHLTComponentBlockData* mansoCandidateBlocks = NULL;
275         PAliHLTComponentBlockData* singleDecisionBlocks = NULL;
276         PAliHLTComponentBlockData* pairDecisionBlocks = NULL;
277         AliHLTUInt32_t trigRecBlocksCount = 0;
278         AliHLTUInt32_t trigRecDebugBlocksCount = 0;
279         AliHLTUInt32_t hitBlocksCount = 0;
280         AliHLTUInt32_t clusterBlocksCount = 0;
281         AliHLTUInt32_t channelBlocksCount = 0;
282         AliHLTUInt32_t mansoTrackBlocksCount = 0;
283         AliHLTUInt32_t mansoCandidateBlocksCount = 0;
284         AliHLTUInt32_t singleDecisionBlocksCount = 0;
285         AliHLTUInt32_t pairDecisionBlocksCount = 0;
286         try
287         {
288                 blockOk = new bool[evtData.fBlockCnt];
289                 trigRecBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
290                 trigRecDebugBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
291                 hitBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
292                 clusterBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
293                 channelBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
294                 mansoTrackBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
295                 mansoCandidateBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
296                 singleDecisionBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
297                 pairDecisionBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
298         }
299         catch (const std::bad_alloc&)
300         {
301                 HLTError("Could not allocate more memory for internal arrays.");
302                 // Make sure to clean up if partially allocated memory.
303                 if (blockOk != NULL) delete [] blockOk;
304                 if (trigRecBlocks != NULL) delete [] trigRecBlocks;
305                 if (trigRecDebugBlocks != NULL) delete [] trigRecDebugBlocks;
306                 if (hitBlocks != NULL) delete [] hitBlocks;
307                 if (clusterBlocks != NULL) delete [] clusterBlocks;
308                 if (channelBlocks != NULL) delete [] channelBlocks;
309                 if (mansoTrackBlocks != NULL) delete [] mansoTrackBlocks;
310                 if (mansoCandidateBlocks != NULL) delete [] mansoCandidateBlocks;
311                 if (singleDecisionBlocks != NULL) delete [] singleDecisionBlocks;
312                 if (pairDecisionBlocks != NULL) delete [] pairDecisionBlocks;
313                 return -ENOMEM;
314         }
315         
316         AliHLTComponentDataType anyPrivateType = AliHLTComponentDataTypeInitializer(
317                         kAliHLTAnyDataType, kAliHLTDataOriginPrivate
318                 );
319         
320         try
321         {
322                 // Clear all the flags indicating if the blocks are ok.
323                 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
324                 {
325                         blockOk[n] = false;
326                 }
327         
328                 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
329                 {
330                         HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
331                                 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
332                         );
333                         
334                         AliHLTMUONDataBlockType blockType = kUnknownDataBlock;
335                         
336                         if (fIgnoreType)
337                         {
338                                 // Decode the block type if we must ignore the block type
339                                 // as given by the HLT framework.
340                                 if (blocks[n].fSize >= sizeof(AliHLTMUONDataBlockHeader))
341                                 {
342                                         const AliHLTMUONDataBlockHeader* header =
343                                                 reinterpret_cast<const AliHLTMUONDataBlockHeader*>(blocks[n].fPtr);
344                                         blockType = AliHLTMUONDataBlockType(header->fType);
345                                 }
346                         }
347                         else
348                         {
349                                 if (blocks[n].fDataType == anyPrivateType)
350                                 {
351                                         // Completely ignore any private HLT internal block types.
352                                         blockOk[n] = true;
353                                         continue;
354                                 }
355                                 else if (blocks[n].fDataType == AliHLTMUONConstants::DDLRawDataType())
356                                 {
357                                         blockOk[n] = CheckRawDataBlock(blocks[n], n);
358                                         continue;
359                                 }
360                                 else if (blocks[n].fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
361                                 {
362                                         blockType = kTriggerRecordsDataBlock;
363                                 }
364                                 else if (blocks[n].fDataType == AliHLTMUONConstants::TrigRecsDebugBlockDataType())
365                                 {
366                                         blockType = kTrigRecsDebugDataBlock;
367                                 }
368                                 else if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
369                                 {
370                                         blockType = kRecHitsDataBlock;
371                                 }
372                                 else if (blocks[n].fDataType == AliHLTMUONConstants::ClusterBlockDataType())
373                                 {
374                                         blockType = kClustersDataBlock;
375                                 }
376                                 else if (blocks[n].fDataType == AliHLTMUONConstants::ChannelBlockDataType())
377                                 {
378                                         blockType = kChannelsDataBlock;
379                                 }
380                                 else if (blocks[n].fDataType == AliHLTMUONConstants::MansoTracksBlockDataType())
381                                 {
382                                         blockType = kMansoTracksDataBlock;
383                                 }
384                                 else if (blocks[n].fDataType == AliHLTMUONConstants::MansoCandidatesBlockDataType())
385                                 {
386                                         blockType = kMansoCandidatesDataBlock;
387                                 }
388                                 else if (blocks[n].fDataType == AliHLTMUONConstants::SinglesDecisionBlockDataType())
389                                 {
390                                         blockType = kSinglesDecisionDataBlock;
391                                 }
392                                 else if (blocks[n].fDataType == AliHLTMUONConstants::PairsDecisionBlockDataType())
393                                 {
394                                         blockType = kPairsDecisionDataBlock;
395                                 }
396                                 else
397                                 {
398                                         // Log a message indicating that we got a data block that we
399                                         // do not know how to handle.
400                                         if (fWarnForUnexpecedBlock)
401                                                 HLTWarning("Received a data block of a type we cannot"
402                                                         " handle: '%s', spec: 0x%8.8X",
403                                                         DataType2Text(blocks[n].fDataType).c_str(),
404                                                         blocks[n].fSpecification
405                                                 );
406 #ifdef __DEBUG
407                                         else
408                                                 HLTDebug("Received a data block of a type we cannot"
409                                                         " handle: '%s', spec: 0x%8.8X",
410                                                         DataType2Text(blocks[n].fDataType).c_str(),
411                                                         blocks[n].fSpecification
412                                                 );
413 #endif
414                                 }
415                         }
416                         
417                         switch (blockType)
418                         {
419                         case kTriggerRecordsDataBlock:
420                                 blockOk[n] = CheckTriggerRecordsBlock(blocks[n], n);
421                                 trigRecBlocks[trigRecBlocksCount++] = &blocks[n];
422                                 break;
423                         case kTrigRecsDebugDataBlock:
424                                 blockOk[n] = CheckTrigRecsDebugBlock(blocks[n], n);
425                                 trigRecDebugBlocks[trigRecDebugBlocksCount++] = &blocks[n];
426                                 break;
427                         case kRecHitsDataBlock:
428                                 blockOk[n] = CheckRecHitsBlock(blocks[n], n);
429                                 hitBlocks[hitBlocksCount++] = &blocks[n];
430                                 break;
431                         case kClustersDataBlock:
432                                 blockOk[n] = CheckClustersBlock(blocks[n], n);
433                                 clusterBlocks[clusterBlocksCount++] = &blocks[n];
434                                 break;
435                         case kChannelsDataBlock:
436                                 blockOk[n] = CheckChannelsBlock(blocks[n], n);
437                                 channelBlocks[channelBlocksCount++] = &blocks[n];
438                                 break;
439                         case kMansoTracksDataBlock:
440                                 blockOk[n] = CheckMansoTracksBlock(blocks[n], n);
441                                 mansoTrackBlocks[mansoTrackBlocksCount++] = &blocks[n];
442                                 break;
443                         case kMansoCandidatesDataBlock:
444                                 blockOk[n] = CheckMansoCandidatesBlock(blocks[n], n);
445                                 mansoCandidateBlocks[mansoCandidateBlocksCount++] = &blocks[n];
446                                 break;
447                         case kSinglesDecisionDataBlock:
448                                 blockOk[n] = CheckSinglesDecisionBlock(blocks[n], n);
449                                 singleDecisionBlocks[singleDecisionBlocksCount++] = &blocks[n];
450                                 break;
451                         case kPairsDecisionDataBlock:
452                                 blockOk[n] = CheckPairsDecisionBlock(blocks[n], n);
453                                 pairDecisionBlocks[pairDecisionBlocksCount++] = &blocks[n];
454                                 break;
455                         default:
456                                 HLTDebug("Received a data block for which we could not decode the data type."
457                                         " fDataType = '%s', fSpecification = 0x%8.8X, fSize = %u bytes.",
458                                         DataType2Text(blocks[n].fDataType).c_str(),
459                                         blocks[n].fSpecification,
460                                         blocks[n].fSize
461                                 );
462                                 break;
463                         }
464                 }
465                 
466                 // Apply the global data consistancy checks if not suppressed by the user.
467                 if (not fNoGlobalChecks)
468                 {
469                         MakeGlobalChecks(
470                                 blocks, blockOk, evtData.fBlockCnt,
471                                 trigRecBlocks, trigRecBlocksCount,
472                                 trigRecDebugBlocks, trigRecDebugBlocksCount,
473                                 hitBlocks, hitBlocksCount,
474                                 clusterBlocks, clusterBlocksCount,
475                                 channelBlocks, channelBlocksCount,
476                                 mansoTrackBlocks, mansoTrackBlocksCount,
477                                 mansoCandidateBlocks, mansoCandidateBlocksCount,
478                                 singleDecisionBlocks, singleDecisionBlocksCount,
479                                 pairDecisionBlocks, pairDecisionBlocksCount
480                         );
481                 }
482                 
483                 // Forward the input data blocks if we have not been asked to drop them.
484                 // Also remember to filter for bad blocks if so specified.
485                 if (not fDontForward)
486                 {
487                         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
488                         {
489                                 if (fFilterBadBlocks and blockOk[n]) continue;
490                                 outputBlocks.push_back(blocks[n]);
491                         }
492                 }
493                 
494                 // Set dataProblems flag is there was at least one block with problems.
495                 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
496                 {
497                         if (not blockOk[n]) dataProblems = true;
498                 }
499         }
500         finally
501         (
502                 // make sure to cleanup memory
503                 delete [] blockOk;
504                 delete [] trigRecBlocks;
505                 delete [] trigRecDebugBlocks;
506                 delete [] hitBlocks;
507                 delete [] clusterBlocks;
508                 delete [] channelBlocks;
509                 delete [] mansoTrackBlocks;
510                 delete [] mansoCandidateBlocks;
511                 delete [] singleDecisionBlocks;
512                 delete [] pairDecisionBlocks;
513         )
514         
515         // Finally we set the total size of output memory we consumed, which is
516         // zero since we just copied the input descriptors to output if anything.
517         size = 0;
518
519         if (dataProblems and DumpDataOnError()) DumpEvent(evtData, trigData);
520         
521         if (fReturnError)
522         {
523                 // If we were requested to return errors if there were integrity
524                 // problems then check if any data blocks had problems and return
525                 // an error code.
526                 if (dataProblems) return -EFAULT;
527         }
528         return 0;
529 }
530
531
532 bool AliHLTMUONDataCheckerComponent::IsSpecificationValid(
533                 const AliHLTComponentBlockData& block,
534                 AliHLTUInt32_t blockNumber,
535                 const char* name
536         ) const
537 {
538         /// Checks if the specification bits are valid.
539         /// \param  block The block whose specification should be checked.
540         /// \param  blockNumber The block index number being checked.
541         /// \param  name The name of the type of block being checked.
542         /// \returns true if the specification is valid and false otherwise.
543
544         if (AliHLTMUONUtils::IsSpecValid(block.fSpecification))
545                 return true;
546         
547         HLTError("Problem found with data block %d, fDataType = '%s',"
548                  " fPtr = %p and fSize = %u bytes."
549                  " Assuming this is a %s data block."
550                  " Problem: The specification does not contain a valid pattern,"
551                  " received 0x%8.8X for the specification.",
552                 blockNumber,
553                 DataType2Text(block.fDataType).c_str(),
554                 block.fPtr,
555                 block.fSize,
556                 name,
557                 block.fSpecification
558         );
559         return false;
560 }
561
562
563 bool AliHLTMUONDataCheckerComponent::IsFromTrackerOnly(
564                 const AliHLTComponentBlockData& block,
565                 AliHLTUInt32_t blockNumber,
566                 const char* name
567         ) const
568 {
569         /// Checks if the specification bits are valid and indicate the block
570         /// contains data or information only from the tracker DDLs.
571         /// \param  block The block whose specification should be checked.
572         /// \param  blockNumber The block index number being checked.
573         /// \param  name The name of the type of block being checked.
574         /// \returns true if the specification indicates data is only from tracker.
575         
576         bool result = IsSpecificationValid(block, blockNumber, name);
577         
578         if (AliHLTMUONUtils::ContainsDataFromTracker(block.fSpecification) and
579             not AliHLTMUONUtils::ContainsDataFromTrigger(block.fSpecification)
580            )
581         {
582                 return result;
583         }
584         
585         HLTError("Problem found with data block %d, fDataType = '%s',"
586                  " fPtr = %p and fSize = %u bytes."
587                  " Assuming this is a %s data block."
588                  " Problem: The data block does not contain data only from the"
589                  " tracker DDLs as expected."
590                  " Received 0x%8.8X for the specification.",
591                 blockNumber,
592                 DataType2Text(block.fDataType).c_str(),
593                 block.fPtr,
594                 block.fSize,
595                 name,
596                 block.fSpecification
597         );
598         return false;
599 }
600
601
602 bool AliHLTMUONDataCheckerComponent::IsFromTriggerOnly(
603                 const AliHLTComponentBlockData& block,
604                 AliHLTUInt32_t blockNumber,
605                 const char* name
606         ) const
607 {
608         /// Checks if the specification bits are valid and indicate the block
609         /// contains data or information only from the trigger DDLs.
610         /// \param  block The block whose specification should be checked.
611         /// \param  blockNumber The block index number being checked.
612         /// \param  name The name of the type of block being checked.
613         /// \returns true if the specification indicates data is only from trigger.
614         
615         bool result = IsSpecificationValid(block, blockNumber, name);
616         
617         if (AliHLTMUONUtils::ContainsDataFromTrigger(block.fSpecification) and
618             not AliHLTMUONUtils::ContainsDataFromTracker(block.fSpecification)
619            )
620         {
621                 return result;
622         }
623         
624         HLTError("Problem found with data block %d, fDataType = '%s',"
625                  " fPtr = %p and fSize = %u bytes."
626                  " Assuming this is a %s data block."
627                  " Problem: The data block does not contain data only from the"
628                  " trigger DDLs as expected."
629                  " Received 0x%8.8X for the specification.",
630                 blockNumber,
631                 DataType2Text(block.fDataType).c_str(),
632                 block.fPtr,
633                 block.fSize,
634                 name,
635                 block.fSpecification
636         );
637         return false;
638 }
639
640
641 bool AliHLTMUONDataCheckerComponent::IsMomentumVectorOk(
642                 const AliHLTComponentBlockData& block,
643                 AliHLTUInt32_t blockNumber,
644                 const char* name,
645                 AliHLTUInt32_t entryNumber,
646                 AliHLTFloat32_t px,
647                 AliHLTFloat32_t py,
648                 AliHLTFloat32_t pz
649         ) const
650 {
651         /// Checks if the momentum vector is reasonable.
652         /// \param  block The block from which the momentum vector data comes from.
653         /// \param  blockNumber The block index number.
654         /// \param  name The name of the type of block.
655         /// \param  entryNumber The entry index number of the structure holding
656         ///      the momentum vector data.
657         /// \param  px The X coordinate of the momentum vector (GeV/c).
658         /// \param  py The Y coordinate of the momentum vector (GeV/c).
659         /// \param  pz The Z coordinate of the momentum vector (GeV/c).
660         /// \returns true if the momentum vector is valid and false otherwise.
661         
662         // If the momentum vector is nil then ignore it.
663         if (px == 0 and py == 0 and pz == 0) return true;
664         
665         bool result = true;
666         
667         // If the momentum vector is sane then we should not have a particle with
668         // more energy than 14 TeV and momentum should be in the negative direction.
669         double momentum = sqrt(px*px + py*py + pz*pz);
670         if (momentum > 14e3)
671         {
672                 // Just warn since this is a data sanity problem rather
673                 // than a data integrity problem.
674                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
675                         " fPtr = %p and fSize = %u bytes."
676                         " Assuming this is a %s data block."
677                         " Problem with entry %d in block: The momentum vector"
678                         " p = {%f, %f, %f}, |p| = %f looks too big.",
679                         blockNumber,
680                         DataType2Text(block.fDataType).c_str(),
681                         block.fPtr,
682                         block.fSize,
683                         name,
684                         entryNumber,
685                         px, py, pz,
686                         momentum
687                 );
688                 result = false;
689         }
690         
691         if (pz > 0.)
692         {
693                 // Just warn since this is a data sanity problem rather
694                 // than a data integrity problem.
695                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
696                         " fPtr = %p and fSize = %u bytes."
697                         " Assuming this is a %s data block."
698                         " Problem with entry %d in block: The momentum vector"
699                         " p = {%f, %f, %f} points away from the dimuon"
700                         " spectrometer (p_z > 0).",
701                         blockNumber,
702                         DataType2Text(block.fDataType).c_str(),
703                         block.fPtr,
704                         block.fSize,
705                         name,
706                         entryNumber,
707                         px, py, pz
708                 );
709                 result = false;
710         }
711         
712         return result;
713 }
714
715
716 bool AliHLTMUONDataCheckerComponent::AreMomentumCalcParamsOk(
717                 const AliHLTComponentBlockData& block,
718                 AliHLTUInt32_t blockNumber,
719                 const char* name,
720                 AliHLTUInt32_t entryNumber,
721                 AliHLTFloat32_t zmiddle,
722                 AliHLTFloat32_t bl
723         ) const
724 {
725         /// Checks if the parameters for the momentum calculation are reasonable.
726         /// \param  block The block from which the parameter data comes from.
727         /// \param  blockNumber The block index number.
728         /// \param  name The name of the type of block.
729         /// \param  entryNumber The entry index number of the structure holding
730         ///      the parameter data data.
731         /// \param  zmiddle The z-coordinate of the middle of the magnetic field (cm).
732         /// \param  bl The integrated magnetic field (T.m).
733         /// \returns true if the parameters are valid and false otherwise.
734         
735         bool result = true;
736         
737         // Check that the value of the fZmiddle value is somewhere
738         // within the tracking / dipole magnetic field area.
739         if (zmiddle < AliMUONConstants::AbsZEnd() or
740                 zmiddle < AliMUONConstants::MuonFilterZBeg()
741                 )
742         {
743                 // Just warn since this is a data sanity problem rather
744                 // than a data integrity problem.
745                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
746                         " fPtr = %p and fSize = %u bytes."
747                         " Assuming this is a %s data block."
748                         " Problem with entry %d in block: The Z coordinate %f cm"
749                         " used as the middle of the magnetic field in the momentum"
750                         " calculation is outside the dimuon spectrometers dipole"
751                         " magnetic field volume.",
752                         blockNumber,
753                         DataType2Text(block.fDataType).c_str(),
754                         block.fPtr,
755                         block.fSize,
756                         name,
757                         entryNumber,
758                         zmiddle
759                 );
760                 result = false;
761         }
762         
763         // Also check that the value of the 'bl' value is within a
764         // reasonable range: |bl| < Lmax * Bmax, where
765         // Lmax = max length from vertex to end of spectrometer, and
766         // Bmax = max magnetic field of dipole, taken as 1 tesla.
767         // Approximating Lmax * Bmax as 20 T.m
768         if (fabs(bl) > 20.)
769         {
770                 // Just warn since this is a data sanity problem rather
771                 // than a data integrity problem.
772                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
773                         " fPtr = %p and fSize = %u bytes."
774                         " Assuming this is a %s data block."
775                         " Problem with entry %d in block: The integrated magnetic"
776                         " field value %f T.m used in the momentum calculation"
777                         " has an unreasonably large absolute value.",
778                         blockNumber,
779                         DataType2Text(block.fDataType).c_str(),
780                         block.fPtr,
781                         block.fSize,
782                         name,
783                         entryNumber,
784                         bl
785                 );
786                 result = false;
787         }
788         
789         return result;
790 }
791
792
793 bool AliHLTMUONDataCheckerComponent::IsHitCoordinateOk(
794                 const AliHLTComponentBlockData& block,
795                 AliHLTUInt32_t blockNumber,
796                 const char* name,
797                 AliHLTUInt32_t entryNumber,
798                 const AliHLTMUONRecHitStruct& hit,
799                 AliHLTInt32_t minChamber,
800                 AliHLTInt32_t maxChamber,
801                 AliHLTInt32_t expectedChamber,
802                 bool ddl[22]
803         ) const
804 {
805         /// Checks if the hit coordinate is compatible with a the location of a
806         /// dimuon spectrometer chamber. Also, if expectedChamber is not -1, then
807         /// the hit coordinate is checked if to comes from that chamber.
808         /// We also check if the fFlags containing the chamber number and detector
809         /// element ID are correct.
810         /// \param  block The block from which the hit data comes from.
811         /// \param  blockNumber The block index number.
812         /// \param  name The name of the type of block.
813         /// \param  entryNumber The entry index number of the hit.
814         /// \param  hit The hit data being checked.
815         /// \param  minChamber The minimum valid chamber number to check for.
816         /// \param  maxChamber The maximum valid chamber number to check for.
817         /// \param  expectedChamber If not -1 then this is the chamber number to
818         ///      check against.
819         /// \param  ddl  The array decoded by AliHLTMUONUtils::UnpackSpecBits.
820         /// \returns true if the hit is valid and false otherwise.
821         
822         assert( 0 <= minChamber and minChamber < 14 );
823         assert( 0 <= maxChamber and maxChamber < 14 );
824         
825         bool result = true;
826         
827         AliHLTUInt8_t chNum = 0xFF;
828         AliHLTUInt16_t detElemId = 0xFFFF;
829         AliHLTMUONUtils::UnpackRecHitFlags(hit.fFlags, chNum, detElemId);
830         
831         Int_t chamber = AliMUONConstants::ChamberNumber(hit.fZ, false); // false = do not warn.
832         if (chamber < minChamber or maxChamber < chamber)
833         {
834                 HLTError("Problem found with data block %d, fDataType = '%s',"
835                         " fPtr = %p and fSize = %u bytes."
836                         " Assuming this is a %s data block."
837                         " Problem with entry %d in block: The hit {x = %f, y = %f,"
838                         " z = %f} cm has a z-coordinate that does not correspond"
839                         " to the nominal position of any chambers in the range"
840                         " [%d..%d].",
841                         blockNumber,
842                         DataType2Text(block.fDataType).c_str(),
843                         block.fPtr,
844                         block.fSize,
845                         name,
846                         entryNumber,
847                         hit.fX, hit.fY, hit.fZ,
848                         minChamber+1,
849                         maxChamber+1
850                 );
851                 return false;
852         }
853         
854         if (chNum != chamber)
855         {
856                 HLTError("Problem found with data block %d, fDataType = '%s',"
857                         " fPtr = %p and fSize = %u bytes."
858                         " Assuming this is a %s data block."
859                         " Problem with entry %d in block: The hit {x = %f, y = %f,"
860                         " z = %f} cm has a chamber number %d that does not correspond"
861                         " to the expected chamber %d given by the z-coordinate.",
862                         blockNumber,
863                         DataType2Text(block.fDataType).c_str(),
864                         block.fPtr,
865                         block.fSize,
866                         name,
867                         entryNumber,
868                         hit.fX, hit.fY, hit.fZ,
869                         chNum+1,
870                         chamber+1
871                 );
872                 result = false;
873                 if (minChamber <= Int_t(chNum) and Int_t(chNum) <= maxChamber)
874                 {
875                         // Rather use the explicit value in the data if it
876                         // is in range.
877                         chamber = chNum;
878                 }
879         }
880         
881         if (expectedChamber != -1 and chamber != expectedChamber)
882         {
883                 HLTError("Problem found with data block %d, fDataType = '%s',"
884                         " fPtr = %p and fSize = %u bytes."
885                         " Assuming this is a %s data block."
886                         " Problem with entry %d in block: The hit {x = %f, y = %f,"
887                         " z = %f} cm has a position that corresponds to chamber %d,"
888                         " but expected it to be on chamber %d.",
889                         blockNumber,
890                         DataType2Text(block.fDataType).c_str(),
891                         block.fPtr,
892                         block.fSize,
893                         name,
894                         entryNumber,
895                         hit.fX, hit.fY, hit.fZ,
896                         chamber+1,
897                         expectedChamber+1
898                 );
899                 result = false;
900         }
901         
902         AliHLTFloat32_t rmin = AliMUONConstants::Rmin(chamber / 2);
903         AliHLTFloat32_t rmax = AliMUONConstants::Rmax(chamber / 2);
904         AliHLTFloat32_t radius = sqrt(hit.fX*hit.fX + hit.fY*hit.fY);
905         if (radius < rmin or rmax < radius)
906         {
907                 HLTError("Problem found with data block %d, fDataType = '%s',"
908                         " fPtr = %p and fSize = %u bytes."
909                         " Assuming this is a %s data block."
910                         " Problem with entry %d in block: The hit {x = %f, y = %f,"
911                         " z = %f} cm has a position in the X-Y plane that does not"
912                         " correspond to the nominal position of chamber %d.",
913                         blockNumber,
914                         DataType2Text(block.fDataType).c_str(),
915                         block.fPtr,
916                         block.fSize,
917                         name,
918                         entryNumber,
919                         hit.fX, hit.fY, hit.fZ,
920                         chamber+1
921                 );
922                 result = false;
923         }
924         
925         if (not fIgnoreSpec and not ChamberMarkedInDDLList(chamber, ddl))
926         {
927                 HLTError("Problem found with data block %d, fDataType = '%s',"
928                         " fPtr = %p and fSize = %u bytes."
929                         " Assuming this is a %s data block."
930                         " Problem with entry %d in block: The hit {x = %f, y = %f,"
931                         " z = %f} cm has a position that corresponds to chamber %d"
932                         " but the data block specification 0x%8.8X does have a"
933                         " corresponding DDL bit set.",
934                         blockNumber,
935                         DataType2Text(block.fDataType).c_str(),
936                         block.fPtr,
937                         block.fSize,
938                         name,
939                         entryNumber,
940                         hit.fX, hit.fY, hit.fZ,
941                         chamber+1,
942                         block.fSpecification
943                 );
944                 result = false;
945         }
946         
947         // Check that the detector element ID is valid and it corresponds to
948         // the chamber number.
949         if (FetchMappingStores() == 0)  // are stores loaded?
950         {
951                 Bool_t warn = kFALSE;
952                 AliMpDEStore* store = AliMpDEStore::Instance(warn);
953                 AliMpDetElement* de = store->GetDetElement(Int_t(detElemId), warn);
954                 if (de == NULL)
955                 {
956                         HLTError("Problem found with data block %d, fDataType = '%s',"
957                                 " fPtr = %p and fSize = %u bytes."
958                                 " Assuming this is a %s data block."
959                                 " Problem with entry %d in block: The hit {x = %f, y = %f,"
960                                 " z = %f} cm has a detector element ID %d,"
961                                 " which is not valid.",
962                                 blockNumber,
963                                 DataType2Text(block.fDataType).c_str(),
964                                 block.fPtr,
965                                 block.fSize,
966                                 name,
967                                 entryNumber,
968                                 hit.fX, hit.fY, hit.fZ,
969                                 detElemId
970                         );
971                         result = false;
972                 }
973                         
974                 // Check that the chamber number from the detector element number
975                 // has the expected value.
976                 Int_t ch = AliMpDEManager::GetChamberId(Int_t(detElemId), warn);
977                 if (ch != chamber)
978                 {
979                         HLTError("Problem found with data block %d, fDataType = '%s',"
980                                 " fPtr = %p and fSize = %u bytes."
981                                 " Assuming this is a %s data block."
982                                 " Problem with entry %d in block: The hit {x = %f, y = %f,"
983                                 " z = %f} cm has a detector element ID %d,"
984                                 " which does not correspond to the chamber %d.",
985                                 blockNumber,
986                                 DataType2Text(block.fDataType).c_str(),
987                                 block.fPtr,
988                                 block.fSize,
989                                 name,
990                                 entryNumber,
991                                 hit.fX, hit.fY, hit.fZ,
992                                 detElemId,
993                                 chamber+1
994                         );
995                         result = false;
996                 }
997         }
998         else
999         {
1000                 HLTWarning("Cannot check a hit's detector element ID information"
1001                         " without being able to load the mapping from CDB."
1002                 );
1003                 result = false;
1004         }
1005         
1006         return result;
1007 }
1008
1009
1010 bool AliHLTMUONDataCheckerComponent::IsMansoTrackOk(
1011                 const AliHLTComponentBlockData& block,
1012                 AliHLTUInt32_t blockNumber,
1013                 const char* name,
1014                 AliHLTUInt32_t entryNumber,
1015                 const AliHLTMUONMansoTrackStruct& track,
1016                 bool ddl[22]
1017         ) const
1018 {
1019         /// Checks if the Manso track structure is Ok.
1020         /// \param  block The block from which the track data comes from.
1021         /// \param  blockNumber The block index number.
1022         /// \param  name The name of the type of block.
1023         /// \param  entryNumber The entry index number of the structure in the
1024         ///      block being checked.
1025         /// \param  track The Manso track data being checked.
1026         /// \param  ddl  The array decoded by AliHLTMUONUtils::UnpackSpecBits.
1027         /// \returns true if the hit is valid and false otherwise.
1028         
1029         bool result = true;
1030         
1031         // Chi^2 should not be greater than the worst fit possible, estimated
1032         // as the diameter of largest chamber times the number of points
1033         // findable in a track. Max points is 10 tracker chambers times
1034         // 2 cathodes + 4 trigger chambers.
1035         if (track.fChi2 > AliMUONConstants::Dmax(6)*AliMUONConstants::Dmax(6)*(10*2+4))
1036         {
1037                 // Just a warning since this is not technically an
1038                 // integrity problem.
1039                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
1040                         " fPtr = %p and fSize = %u bytes."
1041                         " Assuming this is a %s data block."
1042                         " Problem with entry %d in block: The Manso track has"
1043                         " the chi squared value of %f that unreasonably big.",
1044                         blockNumber,
1045                         DataType2Text(block.fDataType).c_str(),
1046                         block.fPtr,
1047                         block.fSize,
1048                         name,
1049                         entryNumber,
1050                         track.fChi2
1051                 );
1052                 result = false;
1053         }
1054         
1055         // Check if the momentum vector is reasonable.
1056         bool momOk = IsMomentumVectorOk(
1057                         block, blockNumber, name, entryNumber,
1058                         track.fPx, track.fPy, track.fPz
1059                 );
1060         if (not momOk) result = false;
1061         
1062         AliHLTMUONParticleSign sign;
1063         bool hitset[4];
1064         AliHLTMUONUtils::UnpackMansoTrackFlags(track.fFlags, sign, hitset);
1065         
1066         // Min and max allowed chamber numbers for hits:
1067         Int_t minCh = 0;
1068         Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
1069         
1070         // Check that this hit coordinates are OK.
1071         for (AliHLTUInt32_t i = 0; i < 4; i++)
1072         {
1073                 if (not hitset[i]) continue; // ignore hits that are not initialised.
1074                 bool hitOk = IsHitCoordinateOk(
1075                                 block, blockNumber, name, entryNumber, track.fHit[i],
1076                                 minCh, maxCh, i+6, ddl
1077                         );
1078                 if (not hitOk) result = false;
1079         }
1080         
1081         return result;
1082 }
1083
1084
1085 bool AliHLTMUONDataCheckerComponent::CheckDetElemIds(
1086                 const AliHLTComponentBlockData& infoBlock,
1087                 AliHLTUInt32_t infoBlockNumber,
1088                 AliHLTUInt32_t infoEntryNumber,
1089                 const AliHLTMUONTrigRecInfoStruct& info,
1090                 const AliHLTComponentBlockData& trBlock,
1091                 AliHLTUInt32_t trBlockNumber,
1092                 AliHLTUInt32_t trEntryNumber,
1093                 const AliHLTMUONTriggerRecordStruct& tr
1094         ) const
1095 {
1096         /// Checks if the detector element IDs are the same in the debug
1097         /// information structure and the trigger record structure.
1098         /// \param  infoBlock The debug information block from which the 'info'
1099         ///      data comes from.
1100         /// \param  infoBlockNumber The debug information block index number.
1101         /// \param  infoEntryNumber The entry index number of the 'info'
1102         ///      structure in the debug information data block.
1103         /// \param  info  The debug information structure being checked.
1104         /// \param  trBlock The trigger record block from which the 'tr' data
1105         ///      comes from.
1106         /// \param  trBlockNumber The trigger record block index number.
1107         /// \param  trEntryNumber The entry index number of the 'tr' structure
1108         ///      in the trigger record data block.
1109         /// \param  tr  The trigger record structure being checked.
1110         /// \returns true if the detector element IDs are the same and false
1111         ///      otherwise.
1112         
1113         bool result = true;
1114         
1115         for (int i = 0; i < 4; i++)
1116         {
1117                 AliHLTUInt8_t chamber = 0xFF;
1118                 AliHLTUInt16_t detElemId = 0xFFFF;
1119                 AliHLTMUONUtils::UnpackRecHitFlags(tr.fHit[i].fFlags, chamber, detElemId);
1120                 if (info.fDetElemId[i] == detElemId) continue;
1121                 
1122                 HLTError("Problem found with trigger record debug information %d"
1123                         " in data block %d (fDataType = '%s', fPtr = %p, fSize"
1124                         " = %u bytes) and trigger record %d in data block %d"
1125                         " (fDataType = '%s', fPtr = %p, fSize = %u bytes):"
1126                         " The detection element ID %d for chamber %d in the debug"
1127                         " information, is not the same as %d"
1128                         " found in the trigger record.",
1129                         infoEntryNumber,
1130                         infoBlockNumber,
1131                         DataType2Text(infoBlock.fDataType).c_str(),
1132                         infoBlock.fPtr,
1133                         infoBlock.fSize,
1134                         trEntryNumber,
1135                         trBlockNumber,
1136                         DataType2Text(trBlock.fDataType).c_str(),
1137                         trBlock.fPtr,
1138                         trBlock.fSize,
1139                         info.fDetElemId[i],
1140                         i+11,
1141                         detElemId
1142                 );
1143                 result = false;
1144         }
1145         
1146         return result;
1147 }
1148
1149
1150 bool AliHLTMUONDataCheckerComponent::CheckDetElemIds(
1151                 const AliHLTComponentBlockData& clusterBlock,
1152                 AliHLTUInt32_t clusterBlockNumber,
1153                 AliHLTUInt32_t clusterEntryNumber,
1154                 const AliHLTMUONClusterStruct& cluster,
1155                 const AliHLTComponentBlockData& hitBlock,
1156                 AliHLTUInt32_t hitBlockNumber,
1157                 AliHLTUInt32_t hitEntryNumber,
1158                 const AliHLTMUONRecHitStruct& hit
1159         ) const
1160 {
1161         /// Checks if the detector element IDs are the same in the cluster
1162         /// structure and the reconstructed hit structure.
1163         /// \param  clusterBlock The cluster block from which the 'cluster' data
1164         ///      comes from.
1165         /// \param  clusterBlockNumber The cluster block index number.
1166         /// \param  clusterEntryNumber The entry index number of the 'cluster'
1167         ///      structure in the cluster data block.
1168         /// \param  cluster  The cluster structure being checked.
1169         /// \param  hitBlock The reconstructed hit block from which the 'hit'
1170         ///      data comes from.
1171         /// \param  hitBlockNumber The reconstructed hit block index number.
1172         /// \param  hitEntryNumber The entry index number of the 'hit' structure
1173         ///      in the reconstructed hit data block.
1174         /// \param  hit  The trigger record structure being checked.
1175         /// \returns true if the detector element IDs are the same and false
1176         ///      otherwise.
1177         
1178         bool result = true;
1179         
1180         AliHLTUInt8_t chamber = 0xFF;
1181         AliHLTUInt16_t detElemId = 0xFFFF;
1182         AliHLTMUONUtils::UnpackRecHitFlags(hit.fFlags, chamber, detElemId);
1183         if (cluster.fDetElemId != detElemId)
1184         {
1185                 HLTError("Problem found with cluster %d in data block %d"
1186                         " (fDataType = '%s', fPtr = %p, fSize = %u bytes)"
1187                         " and reconstructed hit %d in data block %d"
1188                         " (fDataType = '%s', fPtr = %p, fSize = %u bytes):"
1189                         " The detection element ID %d in the cluster, is not"
1190                         " the same as %d found in the reconstructed hit.",
1191                         clusterEntryNumber,
1192                         clusterBlockNumber,
1193                         DataType2Text(clusterBlock.fDataType).c_str(),
1194                         clusterBlock.fPtr,
1195                         clusterBlock.fSize,
1196                         hitEntryNumber,
1197                         hitBlockNumber,
1198                         DataType2Text(hitBlock.fDataType).c_str(),
1199                         hitBlock.fPtr,
1200                         hitBlock.fSize,
1201                         cluster.fDetElemId,
1202                         detElemId
1203                 );
1204                 result = false;
1205         }
1206         
1207         return result;
1208 }
1209
1210
1211 namespace
1212 {
1213         /**
1214          * Class for logging errors found in raw DDL data.
1215          */
1216         class AliHLTMUONDecoderHandler : public AliHLTLogging
1217         {
1218         public:
1219         
1220                 /// Default constructor
1221                 AliHLTMUONDecoderHandler() :
1222                         AliHLTLogging(),
1223                         fBufferStart(NULL),
1224                         fDescriptor(NULL),
1225                         fBlockNumber(0)
1226                 {
1227                 }
1228                 
1229                 /// Default destructor.
1230                 virtual ~AliHLTMUONDecoderHandler() {}
1231                 
1232                 /// Sets the DDL raw data block descriptor.
1233                 void SetDescriptor(const AliHLTComponentBlockData* b) { fDescriptor = b; }
1234                 
1235                 /// Sets the block number of the raw data block descriptor.
1236                 void SetBlockNumber(AliHLTUInt32_t n) { fBlockNumber = n; }
1237                 
1238                 /// Logs an error message describing the problem with the DDL raw data.
1239                 template <typename ErrorCode, class DecoderHandler>
1240                 void LogError(ErrorCode code, const void* location, DecoderHandler& handler);
1241         
1242         protected:
1243                 // Do not allow copying of this class.
1244                 /// Not implemented
1245                 AliHLTMUONDecoderHandler(const AliHLTMUONDecoderHandler& rhs); // copy constructor
1246                 /// Not implemented
1247                 AliHLTMUONDecoderHandler& operator = (const AliHLTMUONDecoderHandler& rhs); // assignment operator
1248                 
1249                 const void* fBufferStart; ///< Pointer to the start of the current DDL payload buffer.
1250                 const AliHLTComponentBlockData* fDescriptor; ///< Descriptor for the DDL raw data block corresponding to the buffer.
1251                 AliHLTUInt32_t fBlockNumber;  ///< The number / index of the block descriptor.
1252         };
1253         
1254         
1255         template <typename ErrorCode, class DecoderHandler>
1256         void AliHLTMUONDecoderHandler::LogError(ErrorCode code, const void* location, DecoderHandler& handler)
1257         {
1258                 /// Logs a HLT error message describing the problem with the raw DDL data.
1259                 /// \param code  The error code describing the problem.
1260                 /// \param location  A pointer to the location in the raw data buffer
1261                 ///      where the problem was found.
1262                 /// \param handler  The decoder handler object.
1263                 
1264                 long bytepos = long(location) - long(fBufferStart) + sizeof(AliRawDataHeader);
1265                 
1266                 // create data type string.
1267                 char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1268                 memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1269                 strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1270                 strcat( dataType, ":" );
1271                 strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1272                 
1273                 HLTError("Problem found with data block %d, fDataType = '%s',"
1274                          " fPtr = %p and fSize = %u bytes."
1275                          " Assuming this is a DDL raw data block."
1276                          " Problem: %s (Error code: %d, at byte %d)",
1277                         fBlockNumber,
1278                         &dataType[0],
1279                         fDescriptor->fPtr,
1280                         fDescriptor->fSize,
1281                         handler.ErrorCodeToMessage(code),
1282                         code,
1283                         bytepos
1284                 );
1285         };
1286         
1287         
1288         /**
1289          * Class for logging decoding errors when checking tracker raw DDL data.
1290          * Used in the AliHLTMUONDataCheckerComponent::CheckRawDataBlock method.
1291          */
1292         class AliHLTMUONTrackerDecoderHandler :
1293                 public AliMUONTrackerDDLDecoderEventHandler, public AliHLTMUONDecoderHandler
1294         {
1295         public:
1296                 AliHLTMUONTrackerDecoderHandler() :
1297                         AliMUONTrackerDDLDecoderEventHandler(),
1298                         AliHLTMUONDecoderHandler(),
1299                         fMaxDigits(0),
1300                         fDigitCount(0),
1301                         fDigits(NULL),
1302                         fCurrentBusPatch(0),
1303                         fDataProblems(false)
1304                 {}
1305                 
1306                 virtual ~AliHLTMUONTrackerDecoderHandler()
1307                 {
1308                         if (fDigits != NULL) delete [] fDigits;
1309                 }
1310                 
1311                 /// Structure to store raw data words found in the raw data.
1312                 struct AliDigit
1313                 {
1314                         UInt_t fBusPatchId;  ///< Bus patch ID for the data word.
1315                         UInt_t fDataWord;   ///< Raw data word found in the DDL payload.
1316                 };
1317                 
1318                 /// Returns the number of digits found.
1319                 UInt_t DigitCount() const { return fDigitCount; }
1320                 
1321                 /// Returns the array of digits found.
1322                 const AliDigit* Digits() const { return fDigits; }
1323                 
1324                 /// Returns true if there were problems with the data.
1325                 bool DataProblems() const { return fDataProblems; }
1326                 
1327                 // Methods inherited from AliMUONTrackerDDLDecoderEventHandler:
1328                 
1329                 /// Called for each new buffer.
1330                 void OnNewBuffer(const void* buffer, UInt_t bufferSize);
1331                 
1332                 /// Called for each new DSP header.
1333                 void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/);
1334                 
1335                 /// Called for each new bus patch. Just marks the current bus patch ID.
1336                 void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* /*data*/)
1337                 {
1338                         fCurrentBusPatch = header->fBusPatchId;
1339                 }
1340                 
1341                 /// Called for each new data word found.
1342                 void OnData(UInt_t data, bool /*parityError*/);
1343                 
1344                 /// Logs an error message if there was a decoding problem with the DDL payload.
1345                 void OnError(ErrorCode code, const void* location)
1346                 {
1347                         fDataProblems = true;
1348                         LogError(code, location, *this);
1349                 }
1350         
1351         private:
1352         
1353                 // Do not allow copying of this object.
1354                 /// Not implemented.
1355                 AliHLTMUONTrackerDecoderHandler(const AliHLTMUONTrackerDecoderHandler& obj);
1356                 /// Not implemented.
1357                 AliHLTMUONTrackerDecoderHandler& operator = (const AliHLTMUONTrackerDecoderHandler& obj);
1358                 
1359                 UInt_t fMaxDigits;  ///< Maximum number of digits that can be stored in fDigits.
1360                 UInt_t fDigitCount;  ///< The number of digits currently stored in fDigits.
1361                 AliDigit* fDigits;  ///< The array of digits found in the DDL data.
1362                 UInt_t fCurrentBusPatch;  ///< The current bus patch ID being processed.
1363                 bool fDataProblems;  ///< flag indicating there were problems with the data.
1364         };
1365         
1366         
1367         void AliHLTMUONTrackerDecoderHandler::OnNewBuffer(const void* buffer, UInt_t bufferSize)
1368         {
1369                 /// Called for a new buffer. It will reset internal counters and
1370                 /// resize the digits array if necessary.
1371                 
1372                 fDataProblems = false;
1373                 fDigitCount = 0;
1374                 fBufferStart = buffer;
1375                 
1376                 // Resize the fDigits array to be able to store
1377                 // all the digits in the data buffer.
1378                 UInt_t maxSize = bufferSize / sizeof(UInt_t) + 1;
1379                 if (maxSize > fMaxDigits)
1380                 {
1381                         if (fDigits != NULL)
1382                         {
1383                                 delete [] fDigits;
1384                                 fDigits = NULL;
1385                                 fMaxDigits = 0;
1386                         }
1387                         try
1388                         {
1389                                 fDigits = new AliDigit[maxSize];
1390                                 fMaxDigits = maxSize;
1391                         }
1392                         catch (const std::bad_alloc&)
1393                         {
1394                                 HLTError("Could not allocate enough buffer space for internal arrays.");
1395                                 return;
1396                         }
1397                 }
1398         }
1399         
1400         
1401         void AliHLTMUONTrackerDecoderHandler::OnNewDSP(
1402                         const AliMUONDSPHeaderStruct* header, const void* /*data*/
1403                 )
1404         {
1405                 if (header->fPaddingWord != 0 and header->fPaddingWord != 1)
1406                 {
1407                         // create data type string.
1408                         char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1409                         memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1410                         strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1411                         strcat( dataType, ":" );
1412                         strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1413                                 
1414                         HLTError("Problem found with data block %d, fDataType = '%s',"
1415                                 " fPtr = %p and fSize = %u bytes."
1416                                 " Assuming this is a tracker DDL raw data block."
1417                                 " Problem: Found padding word marker 0x%8.8X in DSP"
1418                                 " header with DSP ID %d which has an invalid value.",
1419                                 fBlockNumber,
1420                                 &dataType[0],
1421                                 fDescriptor->fPtr,
1422                                 fDescriptor->fSize,
1423                                 header->fPaddingWord,
1424                                 header->fDSPId
1425                         );
1426                         fDataProblems = true;
1427                         return;
1428                 }
1429         }
1430         
1431         
1432         void AliHLTMUONTrackerDecoderHandler::OnData(UInt_t data, bool /*parityError*/)
1433         {
1434                 /// Called for each new data word found. This method will add
1435                 /// these to the list of digits and check if they are not duplicated.
1436                 
1437                 assert( fDigits != NULL );
1438                 
1439                 if ((data & 0x60000000) != 0)
1440                 {
1441                         // create data type string.
1442                         char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1443                         memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1444                         strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1445                         strcat( dataType, ":" );
1446                         strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1447                                 
1448                         HLTError("Problem found with data block %d, fDataType = '%s',"
1449                                 " fPtr = %p and fSize = %u bytes."
1450                                 " Assuming this is a tracker DDL raw data block."
1451                                 " Problem: Found a data word 0x%8.8X for bus patch %d"
1452                                 " whose bits 29 or 30 are not zero.",
1453                                 fBlockNumber,
1454                                 &dataType[0],
1455                                 fDescriptor->fPtr,
1456                                 fDescriptor->fSize,
1457                                 data,
1458                                 fCurrentBusPatch
1459                         );
1460                         fDataProblems = true;
1461                         return;
1462                 }
1463                 
1464                 // Check if the data word + bus patch have been duplicated.
1465                 for (UInt_t i = 0; i < fDigitCount; i++)
1466                 {
1467                         if (fDigits[i].fDataWord == data and fDigits[i].fBusPatchId == fCurrentBusPatch)
1468                         {
1469                                 // create data type string.
1470                                 char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1471                                 memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1472                                 strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1473                                 strcat( dataType, ":" );
1474                                 strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1475                                 
1476                                 HLTError("Problem found with data block %d, fDataType = '%s',"
1477                                         " fPtr = %p and fSize = %u bytes."
1478                                         " Assuming this is a tracker DDL raw data block."
1479                                         " Problem: Found a duplicate data word 0x%8.8X for bus patch %d.",
1480                                         fBlockNumber,
1481                                         &dataType[0],
1482                                         fDescriptor->fPtr,
1483                                         fDescriptor->fSize,
1484                                         data,
1485                                         fCurrentBusPatch
1486                                 );
1487                                 fDataProblems = true;
1488                                 return;
1489                         }
1490                 }
1491                 
1492                 // Add the data word + bus patch to the list of decoded digits.
1493                 if (fDigitCount < fMaxDigits)
1494                 {
1495                         fDigits[fDigitCount].fBusPatchId = fCurrentBusPatch;
1496                         fDigits[fDigitCount].fDataWord = data;
1497                         fDigitCount++;
1498                 }
1499         }
1500         
1501         /**
1502          * Class for logging decoding errors when checking trigger raw DDL data.
1503          * Used in the AliHLTMUONDataCheckerComponent::CheckRawDataBlock method.
1504          */
1505         class AliHLTMUONTriggerDecoderHandler :
1506                 public AliMUONTriggerDDLDecoderEventHandler, public AliHLTMUONDecoderHandler
1507         {
1508         public:
1509                 // Methods inherited from AliMUONTriggerDDLDecoderEventHandler:
1510                 
1511                 /// Called for each new buffer.
1512                 void OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
1513                 {
1514                         fBufferStart = buffer;
1515                 }
1516                 
1517                 /// Logs an error message if there was a decoding problem with the DDL payload.
1518                 void OnError(ErrorCode code, const void* location)
1519                 {
1520                         LogError(code, location, *this);
1521                 }
1522         };
1523         
1524 } // end of namespace
1525
1526
1527 bool AliHLTMUONDataCheckerComponent::CheckRawDataBlock(
1528                 const AliHLTComponentBlockData& block,
1529                 AliHLTUInt32_t blockNumber
1530         ) const
1531 {
1532         /// Checks the validity of a raw data block.
1533         
1534         bool result = true;
1535
1536         if (fIgnoreSpec)
1537         {
1538                 HLTWarning("Not able to check DDL raw data if -ignorespec is specified.");
1539                 return false;
1540         }
1541         
1542         bool ddl[22];
1543         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1544         
1545         // Check that only one DDL was marked in the specification.
1546         int ddlIndex = -1;
1547         for (int i = 0; i < 22; i++)
1548         {
1549                 if (not ddl[i]) continue;
1550                 
1551                 if (ddlIndex == -1)
1552                 {
1553                         ddlIndex = i;
1554                         continue;
1555                 }
1556                 
1557                 HLTError("Problem found with data block %d, fDataType = '%s',"
1558                          " fPtr = %p and fSize = %u bytes."
1559                          " Assuming this is a DDL raw data block."
1560                          " Problem: The specification indicates multiple"
1561                          " DDL sources, DDL %d and %d.",
1562                         blockNumber,
1563                         DataType2Text(block.fDataType).c_str(),
1564                         block.fPtr,
1565                         block.fSize,
1566                         ddlIndex,
1567                         i
1568                 );
1569                 result = false;
1570         }
1571         
1572         // Check the DDL common data header.
1573         AliHLTUInt32_t totalDDLSize = block.fSize;
1574         if (totalDDLSize < sizeof(AliRawDataHeader))
1575         {
1576                 HLTError("Problem found with data block %d, fDataType = '%s',"
1577                          " fPtr = %p and fSize = %u bytes."
1578                          " Assuming this is a DDL raw data block."
1579                          " Problem: The size of the data block is too short to contain"
1580                          " a valid common DDL data header. Size of buffer is only %d"
1581                          " bytes, but expected at least %d bytes.",
1582                         blockNumber,
1583                         DataType2Text(block.fDataType).c_str(),
1584                         block.fPtr,
1585                         block.fSize,
1586                         totalDDLSize,
1587                         sizeof(AliRawDataHeader)
1588                 );
1589                 return false;
1590         }
1591         
1592         const AliRawDataHeader* header =
1593                 reinterpret_cast<const AliRawDataHeader*>(block.fPtr);
1594         
1595         if (header->GetVersion() != 2)
1596         {
1597                 HLTError("Problem found with data block %d, fDataType = '%s',"
1598                          " fPtr = %p and fSize = %u bytes."
1599                          " Assuming this is a DDL raw data block."
1600                          " Problem: The common DDL data header indicates an"
1601                          " incorrect version number. Expected 2 but got %d.",
1602                         blockNumber,
1603                         DataType2Text(block.fDataType).c_str(),
1604                         block.fPtr,
1605                         block.fSize,
1606                         int( header->GetVersion() )
1607                 );
1608                 result = false;
1609         }
1610         
1611         if (header->fSize != 0xFFFFFFFF and header->fSize != block.fSize)
1612         {
1613                 HLTError("Problem found with data block %d, fDataType = '%s',"
1614                          " fPtr = %p and fSize = %u bytes."
1615                          " Assuming this is a DDL raw data block."
1616                          " Problem: The common DDL data header indicates an"
1617                          " incorrect DDL buffer size. Expected %d bytes but"
1618                          " size reported in header is %d bytes.",
1619                         blockNumber,
1620                         DataType2Text(block.fDataType).c_str(),
1621                         block.fPtr,
1622                         block.fSize,
1623                         block.fSize,
1624                         header->fSize
1625                 );
1626                 result = false;
1627         }
1628         
1629         if (header->fSize != 0xFFFFFFFF and header->fSize != block.fSize)
1630         {
1631                 HLTError("Problem found with data block %d, fDataType = '%s',"
1632                          " fPtr = %p and fSize = %u bytes."
1633                          " Assuming this is a DDL raw data block."
1634                          " Problem: The common DDL data header indicates an"
1635                          " incorrect DDL buffer size. Expected %d bytes but"
1636                          " size reported in header is %d bytes.",
1637                         blockNumber,
1638                         DataType2Text(block.fDataType).c_str(),
1639                         block.fPtr,
1640                         block.fSize,
1641                         block.fSize,
1642                         header->fSize
1643                 );
1644                 result = false;
1645         }
1646         
1647         // Check that the bits that should be zero in the CDH are infact zero.
1648         if ((header->fWord2 & 0x00C03000) != 0 or
1649             (header->fEventID2 & 0xFF000000) != 0 or
1650             (header->fStatusMiniEventID & 0xF0000000) != 0 or
1651             (header->fROILowTriggerClassHigh & 0x0FFC0000) != 0
1652            )
1653         {
1654                 HLTError("Problem found with data block %d, fDataType = '%s',"
1655                          " fPtr = %p and fSize = %u bytes."
1656                          " Assuming this is a DDL raw data block."
1657                          " Problem: The common DDL data header has non-zero"
1658                          " bits that are reserved and must be set to zero.",
1659                         blockNumber,
1660                         DataType2Text(block.fDataType).c_str(),
1661                         block.fPtr,
1662                         block.fSize
1663                 );
1664                 result = false;
1665         }
1666         
1667         AliHLTUInt32_t payloadSize = block.fSize - sizeof(AliRawDataHeader);
1668         const AliHLTUInt8_t* payload =
1669                 reinterpret_cast<const AliHLTUInt8_t*>(header + 1);
1670         
1671         if (AliHLTMUONUtils::IsTriggerDDL(block.fSpecification))
1672         {
1673                 bool scalarEvent = ((header->GetL1TriggerMessage() & 0x1) == 0x1);
1674                 AliMUONTriggerDDLDecoder<AliHLTMUONTriggerDecoderHandler> decoder;
1675                 decoder.ExitOnError(false);
1676                 decoder.TryRecover(false);
1677                 decoder.AutoDetectScalars(false);
1678                 decoder.GetHandler().SetDescriptor(&block);
1679                 decoder.GetHandler().SetBlockNumber(blockNumber);
1680                 result = decoder.Decode(payload, payloadSize, scalarEvent);
1681         }
1682         else if (AliHLTMUONUtils::IsTrackerDDL(block.fSpecification))
1683         {
1684                 AliMUONTrackerDDLDecoder<AliHLTMUONTrackerDecoderHandler> decoder;
1685                 decoder.ExitOnError(false);
1686                 decoder.TryRecover(false);
1687                 decoder.SendDataOnParityError(true);
1688                 decoder.AutoDetectTrailer(true);
1689                 decoder.CheckForTrailer(true);
1690                 decoder.GetHandler().SetDescriptor(&block);
1691                 decoder.GetHandler().SetBlockNumber(blockNumber);
1692                 result = decoder.Decode(payload, payloadSize);
1693                 if (decoder.GetHandler().DataProblems()) result = false;
1694                 
1695                 if (FetchMappingStores() == 0)  // are stores loaded?
1696                 {
1697                         Bool_t warn = kFALSE;
1698                         AliMpDDLStore* ddlStore = AliMpDDLStore::Instance(warn);
1699                         
1700                         // Check that the bus patch, manu ID and channel addresses are valid
1701                         // for each raw data word.
1702                         for (UInt_t i = 0; i < decoder.GetHandler().DigitCount(); i++)
1703                         {
1704                                 UInt_t busPatchId = decoder.GetHandler().Digits()[i].fBusPatchId;
1705                                 UInt_t dataWord = decoder.GetHandler().Digits()[i].fDataWord;
1706                                 
1707                                 UShort_t manuId; UChar_t channelId; UShort_t adc;
1708                                 AliMUONTrackerDDLDecoderEventHandler::UnpackADC(
1709                                                 dataWord, manuId, channelId, adc
1710                                         );
1711                                 
1712                                 // Check if the bus patch is valid.
1713                                 AliMpBusPatch* busPatch = ddlStore->GetBusPatch(busPatchId, warn);
1714                                 if (busPatch == NULL)
1715                                 {
1716                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1717                                                  " fPtr = %p and fSize = %u bytes."
1718                                                  " Assuming this is a tracker DDL raw data block."
1719                                                  " Problem: Found a bus patch identifier %d that"
1720                                                  " is not valid.",
1721                                                 blockNumber,
1722                                                 DataType2Text(block.fDataType).c_str(),
1723                                                 block.fPtr,
1724                                                 block.fSize,
1725                                                 busPatchId
1726                                         );
1727                                         result = false;
1728                                         continue;
1729                                 }
1730                                 
1731                                 // We can check that the bus patch is for the DDL
1732                                 // which is also indicated by the specification bits.
1733                                 if (not fIgnoreSpec and busPatch->GetDdlId() != ddlIndex)
1734                                 {
1735                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1736                                                  " fPtr = %p and fSize = %u bytes."
1737                                                  " Assuming this is a tracker DDL raw data block."
1738                                                  " Problem: Found a bus patch identifier %d for"
1739                                                  " DDL %d, but the data block specification 0x%8.8X"
1740                                                  " indicates a different DDL of %d.",
1741                                                 blockNumber,
1742                                                 DataType2Text(block.fDataType).c_str(),
1743                                                 block.fPtr,
1744                                                 block.fSize,
1745                                                 busPatchId,
1746                                                 busPatch->GetDdlId(),
1747                                                 block.fSpecification,
1748                                                 ddlIndex
1749                                         );
1750                                         result = false;
1751                                         continue;
1752                                 }
1753                                 
1754                                 // Check if the MANU ID is valid.
1755                                 if (not busPatch->HasManu(manuId))
1756                                 {
1757                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1758                                                  " fPtr = %p and fSize = %u bytes."
1759                                                  " Assuming this is a tracker DDL raw data block."
1760                                                  " Problem: Found a MANU identifier %d on bus patch %d"
1761                                                  " that is not valid.",
1762                                                 blockNumber,
1763                                                 DataType2Text(block.fDataType).c_str(),
1764                                                 block.fPtr,
1765                                                 block.fSize,
1766                                                 manuId,
1767                                                 busPatchId
1768                                         );
1769                                         result = false;
1770                                         continue;
1771                                 }
1772                                 
1773                                 // Now try to fetch the detector element to check the MANU channel.
1774                                 AliMpDetElement* de = ddlStore->GetDetElement(busPatch->GetDEId(), warn);
1775                                 if (de == NULL)
1776                                 {
1777                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1778                                                  " fPtr = %p and fSize = %u bytes."
1779                                                  " Assuming this is a tracker DDL raw data block."
1780                                                  " Problem: Found a bus patch identifier %d that"
1781                                                  " does not correspond to a detector element.",
1782                                                 blockNumber,
1783                                                 DataType2Text(block.fDataType).c_str(),
1784                                                 block.fPtr,
1785                                                 block.fSize,
1786                                                 busPatchId
1787                                         );
1788                                         result = false;
1789                                         continue;
1790                                 }
1791                                 
1792                                 if (not de->IsConnectedChannel(manuId, channelId))
1793                                 {
1794                                         // Just a warning because this is marked not
1795                                         // to be an error in the AliMUONDigitMaker.
1796                                         HLTWarning("Problem found with data block %d, fDataType = '%s',"
1797                                                  " fPtr = %p and fSize = %u bytes."
1798                                                  " Assuming this is a tracker DDL raw data block."
1799                                                  " Problem: Found a channel with address %d on"
1800                                                  " MANU ID %d and bus patch %d that is not connected.",
1801                                                 blockNumber,
1802                                                 DataType2Text(block.fDataType).c_str(),
1803                                                 block.fPtr,
1804                                                 block.fSize,
1805                                                 channelId,
1806                                                 manuId,
1807                                                 busPatchId
1808                                         );
1809                                         result = false;
1810                                         continue;
1811                                 }
1812                                 
1813                                 // Need to also load the correct segmentation to check the channel.
1814                                 const AliMpVSegmentation* seg =
1815                                         AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(
1816                                                 busPatch->GetDEId(), manuId
1817                                         );
1818                                 if (seg == NULL)
1819                                 {
1820                                         HLTError("Could not load segmentation for detector element %d"
1821                                                  " and MANU ID %d.",
1822                                                 busPatch->GetDEId(), manuId
1823                                         );
1824                                         result = false;
1825                                         continue;
1826                                 }
1827                                 
1828 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1829                                 AliMpPad pad = seg->PadByLocation(manuId, channelId, warn);
1830 #else // old AliMpPad functionality < r 31742
1831                                 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId, channelId), warn);
1832 #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1833                                 if (not pad.IsValid())
1834                                 {
1835                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1836                                                  " fPtr = %p and fSize = %u bytes."
1837                                                  " Assuming this is a tracker DDL raw data block."
1838                                                  " Problem: Found a channel with address %d on"
1839                                                  " MANU ID %d and bus patch %d that is not valid.",
1840                                                 blockNumber,
1841                                                 DataType2Text(block.fDataType).c_str(),
1842                                                 block.fPtr,
1843                                                 block.fSize,
1844                                                 channelId,
1845                                                 manuId,
1846                                                 busPatchId
1847                                         );
1848                                         result = false;
1849                                         continue;
1850                                 }
1851                         }
1852                 }
1853                 else
1854                 {
1855                         HLTWarning("Cannot check if the bus patch IDs, MANU ID and"
1856                                 " channel addresses for DDL raw data are valid without"
1857                                 " being able to load the mapping from CDB."
1858                         );
1859                         result = false;
1860                 }
1861         }
1862         else
1863         {
1864                 HLTError("Problem found with data block %d, fDataType = '%s',"
1865                          " fPtr = %p and fSize = %u bytes."
1866                          " Assuming this is a DDL raw data block."
1867                          " Problem: The specification does not contain a valid pattern,"
1868                          " received 0x%8.8X for the specification.",
1869                         blockNumber,
1870                         DataType2Text(block.fDataType).c_str(),
1871                         block.fPtr,
1872                         block.fSize,
1873                         block.fSpecification
1874                 );
1875                 result = false;
1876         }
1877         
1878         return result;
1879 }
1880
1881
1882 bool AliHLTMUONDataCheckerComponent::CheckTriggerRecordsBlock(
1883                 const AliHLTComponentBlockData& block,
1884                 AliHLTUInt32_t blockNumber
1885         ) const
1886 {
1887         /// Checks the validity of a trigger records block.
1888
1889         bool result = true;
1890         const char* name = "trigger records";
1891         
1892         if (not fIgnoreSpec)
1893         {
1894                 if (not IsFromTriggerOnly(block, blockNumber, name))
1895                         result = false;
1896         }
1897         
1898         AliHLTMUONTriggerRecordsBlockReader inblock(block.fPtr, block.fSize);
1899         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
1900                 return false;
1901         
1902         bool ddl[22];
1903         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1904         
1905         // Min and max allowed chamber numbers for hits:
1906         Int_t minCh = AliMUONConstants::NCh() - AliMUONConstants::NTriggerCh();
1907         Int_t maxCh = AliMUONConstants::NCh() - 1;
1908         
1909         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1910         {
1911                 // Check that each hit in each trigger record has a reasonable coordinate.
1912                 AliHLTMUONParticleSign sign;
1913                 bool hitset[4];
1914                 AliHLTMUONUtils::UnpackTriggerRecordFlags(inblock[i].fFlags, sign, hitset);
1915         
1916                 for (Int_t j = 0; j < 4; j++)  // loop over 4 trigger chamber hits.
1917                 {
1918                         if (not hitset[i]) continue; // ignore hits that are not initialised.
1919                         bool hitOk = IsHitCoordinateOk(
1920                                         block, blockNumber, name, i, inblock[i].fHit[j],
1921                                         minCh, maxCh, j+10, ddl
1922                                 );
1923                         if (not hitOk) result = false;
1924                 }
1925                 
1926                 // We can also check the momentum vector.
1927                 bool momOk = IsMomentumVectorOk(
1928                                 block, blockNumber, name, i,
1929                                 inblock[i].fPx, inblock[i].fPy, inblock[i].fPz
1930                         );
1931                 if (not momOk) result = false;
1932         }
1933         
1934         // Need to check that no entries have duplicated data but with a different
1935         // ID number.
1936         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1937         {
1938                 AliHLTMUONTriggerRecordStruct ti = inblock[i];
1939                 ti.fId = -1;
1940                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
1941                 {
1942                         AliHLTMUONTriggerRecordStruct tj = inblock[j];
1943                         tj.fId = ti.fId;
1944                         
1945                         if (ti == tj)
1946                         {
1947                                 HLTError("Problem found with data block %d, fDataType = '%s',"
1948                                         " fPtr = %p and fSize = %u bytes."
1949                                         " Assuming this is a %s data block."
1950                                         " Problem: The trigger records %d and %d contain the"
1951                                         " same data. The data might have been duplicated.",
1952                                         blockNumber,
1953                                         DataType2Text(block.fDataType).c_str(),
1954                                         block.fPtr,
1955                                         block.fSize,
1956                                         name,
1957                                         i, j
1958                                 );
1959                                 result = false;
1960                         }
1961                 }
1962         }
1963         
1964         return result;
1965 }
1966
1967
1968 bool AliHLTMUONDataCheckerComponent::CheckTrigRecsDebugBlock(
1969                 const AliHLTComponentBlockData& block,
1970                 AliHLTUInt32_t blockNumber
1971         ) const
1972 {
1973         /// Checks the validity of a trigger records debug block.
1974         
1975         bool result = true;
1976         const char* name = "trigger records debug information";
1977         
1978         if (not fIgnoreSpec)
1979         {
1980                 if (not IsFromTriggerOnly(block, blockNumber, name))
1981                         result = false;
1982         }
1983         
1984         AliHLTMUONTrigRecsDebugBlockReader inblock(block.fPtr, block.fSize);
1985         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
1986                 return false;
1987         
1988         bool ddl[22];
1989         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1990         
1991         // Check that each detector element ID is valid and the corresponding DDL
1992         // bit is set in the data block specification.
1993         if (FetchMappingStores() == 0)  // are stores loaded?
1994         {
1995                 Bool_t warn = kFALSE;
1996                 AliMpDEStore* store = AliMpDEStore::Instance(warn);
1997                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1998                 for (AliHLTUInt32_t j = 0; j < 4; j++)
1999                 {
2000                         const AliHLTMUONTrigRecInfoStruct& trig = inblock[i];
2001                         AliMpDetElement* de = store->GetDetElement(trig.fDetElemId[j], warn);
2002                         if (de == NULL)
2003                         {
2004                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2005                                          " fPtr = %p and fSize = %u bytes."
2006                                          " Assuming this is a %s data block."
2007                                          " Problem: The detector element number %d on chamber"
2008                                          " %d for trigger record debug structure %d is not valid.",
2009                                         blockNumber,
2010                                         DataType2Text(block.fDataType).c_str(),
2011                                         block.fPtr,
2012                                         block.fSize,
2013                                         name,
2014                                         trig.fDetElemId[j],
2015                                         j+11,
2016                                         i
2017                                 );
2018                                 result = false;
2019                                 continue;
2020                         }
2021                         
2022                         // Check that the chamber number from the detector element number
2023                         // has the expected value.
2024                         Int_t chamber = AliMpDEManager::GetChamberId(trig.fDetElemId[j], warn);
2025                         if (chamber != Int_t(j+10))
2026                         {
2027                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2028                                          " fPtr = %p and fSize = %u bytes."
2029                                          " Assuming this is a %s data block."
2030                                          " Problem: The detector element number %d for trigger"
2031                                          " record debug structure %d, corresponds to chamber"
2032                                          " %d, but we expected a hit for chamber %d.",
2033                                         blockNumber,
2034                                         DataType2Text(block.fDataType).c_str(),
2035                                         block.fPtr,
2036                                         block.fSize,
2037                                         name,
2038                                         trig.fDetElemId[j],
2039                                         i,
2040                                         chamber+1,
2041                                         j+11
2042                                 );
2043                                 result = false;
2044                         }
2045                         
2046                         if (fIgnoreSpec) continue;
2047                         if (0 <= de->GetDdlId() and de->GetDdlId() < 22 and not ddl[de->GetDdlId()])
2048                         {
2049                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2050                                          " fPtr = %p and fSize = %u bytes."
2051                                          " Assuming this is a %s data block."
2052                                          " Problem: The detector element number %d for trigger"
2053                                          " record %d corresponds to DDL number %d, but the"
2054                                          " data block specification 0x%8.8X does not have the"
2055                                          " corresponding bit set.",
2056                                         blockNumber,
2057                                         DataType2Text(block.fDataType).c_str(),
2058                                         block.fPtr,
2059                                         block.fSize,
2060                                         name,
2061                                         trig.fDetElemId[j],
2062                                         i,
2063                                         de->GetDdlId(),
2064                                         block.fSpecification
2065                                 );
2066                                 result = false;
2067                         }
2068                 }
2069         }
2070         else
2071         {
2072                 HLTWarning("Cannot check trigger record debug information without"
2073                         " being able to load the mapping from CDB."
2074                 );
2075                 result = false;
2076         }
2077         
2078         // Need to check that no entries have duplicated data but with a different
2079         // ID number.
2080         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2081         {
2082                 AliHLTMUONTrigRecInfoStruct ti = inblock[i];
2083                 ti.fTrigRecId = -1;
2084                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2085                 {
2086                         AliHLTMUONTrigRecInfoStruct tj = inblock[j];
2087                         tj.fTrigRecId = ti.fTrigRecId;
2088                         
2089                         if (ti == tj)
2090                         {
2091                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2092                                         " fPtr = %p and fSize = %u bytes."
2093                                         " Assuming this is a %s data block."
2094                                         " Problem: The trigger record debug information"
2095                                         " structures %d and %d contain the same data."
2096                                         " The data might have been duplicated.",
2097                                         blockNumber,
2098                                         DataType2Text(block.fDataType).c_str(),
2099                                         block.fPtr,
2100                                         block.fSize,
2101                                         name,
2102                                         i, j
2103                                 );
2104                                 result = false;
2105                         }
2106                 }
2107                 
2108                 // Can also check that the value of the fZmiddle and fBl.
2109                 bool paramsOk = AreMomentumCalcParamsOk(
2110                                 block, blockNumber, name, i, ti.fZmiddle, ti.fBl
2111                         );
2112                 if (not paramsOk) result = false;
2113         }
2114         
2115         return result;
2116 }
2117
2118
2119 bool AliHLTMUONDataCheckerComponent::CheckRecHitsBlock(
2120                 const AliHLTComponentBlockData& block,
2121                 AliHLTUInt32_t blockNumber
2122         ) const
2123 {
2124         /// Checks the validity of a reconstructed hits block.
2125
2126         bool result = true;
2127         const char* name = "reconstructed hits";
2128         
2129         if (not fIgnoreSpec)
2130         {
2131                 if (not IsFromTrackerOnly(block, blockNumber, name))
2132                         result = false;
2133         }
2134         
2135         AliHLTMUONRecHitsBlockReader inblock(block.fPtr, block.fSize);
2136         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2137                 return false;
2138         
2139         bool ddl[22];
2140         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2141         
2142         // Check that each hit has a reasonable coordinate.
2143         Int_t minCh = 0;
2144         Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
2145         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2146         {
2147                 bool hitOk = IsHitCoordinateOk(
2148                                 block, blockNumber, name, i, inblock[i],
2149                                 minCh, maxCh, -1, ddl
2150                         );
2151                 if (not hitOk) result = false;
2152         }
2153         
2154         return result;
2155 }
2156
2157
2158 bool AliHLTMUONDataCheckerComponent::CheckClustersBlock(
2159                 const AliHLTComponentBlockData& block,
2160                 AliHLTUInt32_t blockNumber
2161         ) const
2162 {
2163         /// Checks the validity of a clusters block.
2164
2165         bool result = true;
2166         const char* name = "clusters";
2167         
2168         if (not fIgnoreSpec)
2169         {
2170                 if (not IsFromTrackerOnly(block, blockNumber, name))
2171                         result = false;
2172         }
2173         
2174         AliHLTMUONClustersBlockReader inblock(block.fPtr, block.fSize);
2175         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2176                 return false;
2177         
2178         bool ddl[22];
2179         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2180         
2181         if (FetchMappingStores() == 0)  // are stores loaded?
2182         {
2183                 Bool_t warn = kFALSE;
2184                 AliMpDEStore* store = AliMpDEStore::Instance(warn);
2185                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2186                 {
2187                         const AliHLTMUONClusterStruct& cluster = inblock[i];
2188                         
2189                         // Check that the detector element ID is valid.
2190                         AliMpDetElement* de = store->GetDetElement(cluster.fDetElemId, warn);
2191                         if (de == NULL)
2192                         {
2193                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2194                                          " fPtr = %p and fSize = %u bytes."
2195                                          " Assuming this is a %s data block."
2196                                          " Problem: The detector element number %d for cluster"
2197                                          " %d is not valid.",
2198                                         blockNumber,
2199                                         DataType2Text(block.fDataType).c_str(),
2200                                         block.fPtr,
2201                                         block.fSize,
2202                                         name,
2203                                         cluster.fDetElemId,
2204                                         i
2205                                 );
2206                                 result = false;
2207                                 continue;
2208                         }
2209                         
2210                         // Check that the chamber number found from the hit coordinate and
2211                         // that from the detector element number are the same.
2212                         Int_t chamberFromHit = AliMUONConstants::ChamberNumber(cluster.fHit.fZ, warn);
2213                         Int_t chamberFromDE = AliMpDEManager::GetChamberId(cluster.fDetElemId, warn);
2214                         if (chamberFromHit != chamberFromDE)
2215                         {
2216                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2217                                          " fPtr = %p and fSize = %u bytes."
2218                                          " Assuming this is a %s data block."
2219                                          " Problem: The detector element number %d for"
2220                                          " cluster %d, corresponds to chamber %d, but"
2221                                          " found a different chamber number %d for the"
2222                                          " corresponding hit coordinate {x = %f, y = %f,"
2223                                          " z = %f}.",
2224                                         blockNumber,
2225                                         DataType2Text(block.fDataType).c_str(),
2226                                         block.fPtr,
2227                                         block.fSize,
2228                                         name,
2229                                         cluster.fDetElemId,
2230                                         i,
2231                                         chamberFromDE+1,
2232                                         chamberFromHit+1,
2233                                         cluster.fHit.fX,
2234                                         cluster.fHit.fY,
2235                                         cluster.fHit.fZ
2236                                 );
2237                                 result = false;
2238                         }
2239                         
2240                         // Make sure the corresponding DDL bit is set in the data
2241                         // block specification.
2242                         if (fIgnoreSpec) continue;
2243                         if (0 <= de->GetDdlId() and de->GetDdlId() < 22 and not ddl[de->GetDdlId()])
2244                         {
2245                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2246                                          " fPtr = %p and fSize = %u bytes."
2247                                          " Assuming this is a %s data block."
2248                                          " Problem: The detector element number %d for cluster"
2249                                          " %d corresponds to DDL number %d, but the data"
2250                                          " block specification 0x%8.8X does not have the"
2251                                          " corresponding bit set.",
2252                                         blockNumber,
2253                                         DataType2Text(block.fDataType).c_str(),
2254                                         block.fPtr,
2255                                         block.fSize,
2256                                         name,
2257                                         cluster.fDetElemId,
2258                                         i,
2259                                         de->GetDdlId(),
2260                                         block.fSpecification
2261                                 );
2262                                 result = false;
2263                         }
2264                         
2265                         // Check that the total cluster charge is a reasonable value.
2266                         if ((cluster.fChargeB + cluster.fChargeNB)< 0 and 1e4 < (cluster.fChargeB + cluster.fChargeNB))
2267                         {
2268                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2269                                          " fPtr = %p and fSize = %u bytes."
2270                                          " Assuming this is a %s data block."
2271                                          " Problem: The total charge %f for the cluster"
2272                                          " %d is not in a reasonable range [0..1e4].",
2273                                         blockNumber,
2274                                         DataType2Text(block.fDataType).c_str(),
2275                                         block.fPtr,
2276                                         block.fSize,
2277                                         name,
2278                                         (cluster.fChargeB + cluster.fChargeNB),
2279                                         i
2280                                 );
2281                                 result = false;
2282                                 continue;
2283                         }
2284                 }
2285         }
2286         else
2287         {
2288                 HLTWarning("Cannot check cluster information without being able"
2289                         " to load the mapping from CDB."
2290                 );
2291                 result = false;
2292         }
2293         
2294         // Min and max chamber numbers allowed for the cluster hits.
2295         Int_t minCh = 0;
2296         Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
2297         
2298         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2299         {
2300                 // Need to check that no cluster data has duplicated data but with
2301                 // a different ID number.
2302                 AliHLTMUONClusterStruct ci = inblock[i];
2303                 ci.fId = -1;
2304                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2305                 {
2306                         AliHLTMUONClusterStruct cj = inblock[j];
2307                         cj.fId = ci.fId;
2308                         
2309                         if (ci == cj)
2310                         {
2311                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2312                                         " fPtr = %p and fSize = %u bytes."
2313                                         " Assuming this is a %s data block."
2314                                         " Problem: The cluster structures %d and %d contain"
2315                                         " the same data. The data might have been duplicated.",
2316                                         blockNumber,
2317                                         DataType2Text(block.fDataType).c_str(),
2318                                         block.fPtr,
2319                                         block.fSize,
2320                                         name,
2321                                         i, j
2322                                 );
2323                                 result = false;
2324                         }
2325                 }
2326                 
2327                 // Check that the hit structure in the cluster corresponds
2328                 // to a tracker chamber.
2329                 bool hitOk = IsHitCoordinateOk(
2330                                 block, blockNumber, name, i, ci.fHit,
2331                                 minCh, maxCh, -1, ddl
2332                         );
2333                 if (not hitOk) result = false;
2334         }
2335         
2336         return result;
2337 }
2338
2339
2340 bool AliHLTMUONDataCheckerComponent::CheckChannelsBlock(
2341                 const AliHLTComponentBlockData& block,
2342                 AliHLTUInt32_t blockNumber
2343         ) const
2344 {
2345         /// Checks the validity of a channels block.
2346
2347         bool result = true;
2348         const char* name = "channels";
2349         
2350         if (not fIgnoreSpec)
2351         {
2352                 if (not IsFromTrackerOnly(block, blockNumber, name))
2353                         result = false;
2354         }
2355         
2356         AliHLTMUONChannelsBlockReader inblock(block.fPtr, block.fSize);
2357         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2358                 return false;
2359         
2360         bool ddl[22];
2361         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2362         
2363         if (FetchMappingStores() == 0)  // are stores loaded?
2364         {
2365                 Bool_t warn = kFALSE;
2366                 AliMpDDLStore* store = AliMpDDLStore::Instance(warn);
2367                 
2368                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2369                 {
2370                         const AliHLTMUONChannelStruct& channel = inblock[i];
2371                         
2372                         // Check if the bus patch is valid.
2373                         AliMpBusPatch* busPatch = store->GetBusPatch(channel.fBusPatch, warn);
2374                         if (busPatch == NULL)
2375                         {
2376                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2377                                         " fPtr = %p and fSize = %u bytes."
2378                                         " Assuming this is a %s data block."
2379                                         " Problem: Found a bus patch identifier %d that"
2380                                         " is not valid.",
2381                                         blockNumber,
2382                                         DataType2Text(block.fDataType).c_str(),
2383                                         block.fPtr,
2384                                         block.fSize,
2385                                         name,
2386                                         channel.fBusPatch
2387                                 );
2388                                 result = false;
2389                                 continue;
2390                         }
2391                         
2392                         // We can check that the bus patch is for a DDL
2393                         // which is also indicated by the specification bits.
2394                         if (not fIgnoreSpec and (
2395                              not (0 <= busPatch->GetDdlId() and busPatch->GetDdlId() < 20)
2396                              or  (0 <= busPatch->GetDdlId() and busPatch->GetDdlId() < 20
2397                                   and not ddl[busPatch->GetDdlId()])
2398                            ))
2399                         {
2400                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2401                                          " fPtr = %p and fSize = %u bytes."
2402                                          " Assuming this is a %s data block."
2403                                          " Problem: Found a bus patch identifier %d for"
2404                                          " DDL %d, but the data block specification 0x%8.8X"
2405                                          " does not have the corresponding bit set.",
2406                                         blockNumber,
2407                                         DataType2Text(block.fDataType).c_str(),
2408                                         block.fPtr,
2409                                         block.fSize,
2410                                         name,
2411                                         channel.fBusPatch,
2412                                         busPatch->GetDdlId(),
2413                                         block.fSpecification
2414                                 );
2415                                 result = false;
2416                                 continue;
2417                         }
2418                         
2419                         // Check if the MANU ID is valid.
2420                         if (not busPatch->HasManu(channel.fManu))
2421                         {
2422                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2423                                          " fPtr = %p and fSize = %u bytes."
2424                                          " Assuming this is a %s data block."
2425                                          " Problem: Found a MANU identifier %d on bus patch %d"
2426                                          " that is not valid.",
2427                                         blockNumber,
2428                                         DataType2Text(block.fDataType).c_str(),
2429                                         block.fPtr,
2430                                         block.fSize,
2431                                         name,
2432                                         channel.fManu,
2433                                         channel.fBusPatch
2434                                 );
2435                                 result = false;
2436                                 continue;
2437                         }
2438                         
2439                         // Now try to fetch the detector element to check the MANU channel.
2440                         AliMpDetElement* de = store->GetDetElement(busPatch->GetDEId(), warn);
2441                         if (de == NULL)
2442                         {
2443                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2444                                          " fPtr = %p and fSize = %u bytes."
2445                                          " Assuming this is a %s data block."
2446                                          " Problem: Found a bus patch identifier %d that"
2447                                          " does not correspond to a detector element.",
2448                                         blockNumber,
2449                                         DataType2Text(block.fDataType).c_str(),
2450                                         block.fPtr,
2451                                         block.fSize,
2452                                         name,
2453                                         channel.fBusPatch
2454                                 );
2455                                 result = false;
2456                                 continue;
2457                         }
2458                         
2459                         if (not de->IsConnectedChannel(channel.fManu, channel.fChannelAddress))
2460                         {
2461                                 // Just a warning because this is marked not
2462                                 // to be an error in the AliMUONDigitMaker.
2463                                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2464                                         " fPtr = %p and fSize = %u bytes."
2465                                         " Assuming this is a %s data block."
2466                                         " Problem: Found a channel with address %d on"
2467                                         " MANU ID %d and bus patch %d that is not connected.",
2468                                         blockNumber,
2469                                         DataType2Text(block.fDataType).c_str(),
2470                                         block.fPtr,
2471                                         block.fSize,
2472                                         name,
2473                                         channel.fChannelAddress,
2474                                         channel.fManu,
2475                                         channel.fBusPatch
2476                                 );
2477                                 result = false;
2478                                 continue;
2479                         }
2480                         
2481                         // Need to also load the correct segmentation to check the channel.
2482                         const AliMpVSegmentation* seg =
2483                                 AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(
2484                                         busPatch->GetDEId(), channel.fManu
2485                                 );
2486                         if (seg == NULL)
2487                         {
2488                                 HLTError("Could not load segmentation for detector element %d"
2489                                          " and MANU ID %d.",
2490                                         busPatch->GetDEId(), channel.fManu
2491                                 );
2492                                 result = false;
2493                                 continue;
2494                         }
2495                         
2496                         AliMpPad pad = seg->PadByLocation(
2497 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
2498                                         channel.fManu, channel.fChannelAddress,
2499 #else // old AliMpPad functionality < r 31742
2500                                         AliMpIntPair(channel.fManu, channel.fChannelAddress),
2501 #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
2502                                         warn
2503                                 );
2504                         if (not pad.IsValid())
2505                         {
2506                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2507                                         " fPtr = %p and fSize = %u bytes."
2508                                         " Assuming this is a %s data block."
2509                                         " Problem: Found a channel with address %d on"
2510                                         " MANU ID %d and bus patch %d that is not valid.",
2511                                         blockNumber,
2512                                         DataType2Text(block.fDataType).c_str(),
2513                                         block.fPtr,
2514                                         block.fSize,
2515                                         name,
2516                                         channel.fChannelAddress,
2517                                         channel.fManu,
2518                                         channel.fBusPatch
2519                                 );
2520                                 result = false;
2521                                 continue;
2522                         }
2523                 }
2524         }
2525         else
2526         {
2527                 HLTWarning("Cannot check channel information without being able"
2528                         " to load the mapping from CDB."
2529                 );
2530                 result = false;
2531         }
2532         
2533         // Need to check that no channel data has duplicated data but with
2534         // a different cluster ID number.
2535         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2536         {
2537                 AliHLTMUONChannelStruct ci = inblock[i];
2538                 ci.fClusterId = -1;
2539                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2540                 {
2541                         AliHLTMUONChannelStruct cj = inblock[j];
2542                         cj.fClusterId = ci.fClusterId;
2543                         
2544                         if (ci == cj)
2545                         {
2546                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2547                                         " fPtr = %p and fSize = %u bytes."
2548                                         " Assuming this is a %s data block."
2549                                         " Problem: The channel structures %d and %d contain"
2550                                         " the same data. The data might have been duplicated.",
2551                                         blockNumber,
2552                                         DataType2Text(block.fDataType).c_str(),
2553                                         block.fPtr,
2554                                         block.fSize,
2555                                         name,
2556                                         i, j
2557                                 );
2558                                 result = false;
2559                         }
2560                 }
2561         }
2562         
2563         return result;
2564 }
2565
2566
2567 bool AliHLTMUONDataCheckerComponent::CheckMansoTracksBlock(
2568                 const AliHLTComponentBlockData& block,
2569                 AliHLTUInt32_t blockNumber
2570         ) const
2571 {
2572         /// Checks the validity of a Manso tracks block.
2573
2574         bool result = true;
2575         const char* name = "Manso tracks";
2576         
2577         if (not fIgnoreSpec)
2578         {
2579                 if (not IsSpecificationValid(block, blockNumber, name))
2580                         result = false;
2581         }
2582         
2583         AliHLTMUONMansoTracksBlockReader inblock(block.fPtr, block.fSize);
2584         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2585                 return false;
2586         
2587         bool ddl[22];
2588         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2589         
2590         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2591         {
2592                 // Need to check that no entries have duplicated data but with
2593                 // a different track ID number.
2594                 AliHLTMUONMansoTrackStruct ti = inblock[i];
2595                 ti.fId = -1;
2596                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2597                 {
2598                         AliHLTMUONMansoTrackStruct tj = inblock[j];
2599                         tj.fId = ti.fId;
2600                         
2601                         if (ti == tj)
2602                         {
2603                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2604                                         " fPtr = %p and fSize = %u bytes."
2605                                         " Assuming this is a %s data block."
2606                                         " Problem: The Manso tracks %d and %d contain the"
2607                                         " same data. The data might have been duplicated.",
2608                                         blockNumber,
2609                                         DataType2Text(block.fDataType).c_str(),
2610                                         block.fPtr,
2611                                         block.fSize,
2612                                         name,
2613                                         i, j
2614                                 );
2615                                 result = false;
2616                         }
2617                 }
2618                 
2619                 bool trackOk = IsMansoTrackOk(block, blockNumber, name, i, ti, ddl);
2620                 if (not trackOk) result = false;
2621         }
2622         
2623         return result;
2624 }
2625
2626
2627 bool AliHLTMUONDataCheckerComponent::CheckMansoCandidatesBlock(
2628                 const AliHLTComponentBlockData& block,
2629                 AliHLTUInt32_t blockNumber
2630         ) const
2631 {
2632         /// Checks the validity of a Manso candidates block.
2633
2634         bool result = true;
2635         const char* name = "Manso track candidates";
2636         
2637         if (not fIgnoreSpec)
2638         {
2639                 if (not IsSpecificationValid(block, blockNumber, name))
2640                         result = false;
2641         }
2642         
2643         AliHLTMUONMansoCandidatesBlockReader inblock(block.fPtr, block.fSize);
2644         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2645                 return false;
2646         
2647         bool ddl[22];
2648         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2649         
2650         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2651         {
2652                 // Need to check that no entries have duplicated data but with a
2653                 // different track ID number.
2654                 AliHLTMUONMansoCandidateStruct ti = inblock[i];
2655                 ti.fTrack.fId = -1;
2656                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2657                 {
2658                         AliHLTMUONMansoCandidateStruct tj = inblock[j];
2659                         tj.fTrack.fId = ti.fTrack.fId;
2660                         
2661                         if (ti == tj)
2662                         {
2663                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2664                                         " fPtr = %p and fSize = %u bytes."
2665                                         " Assuming this is a %s data block."
2666                                         " Problem: The Manso track candidates %d and %d"
2667                                         " contain the same data."
2668                                         " The data might have been duplicated.",
2669                                         blockNumber,
2670                                         DataType2Text(block.fDataType).c_str(),
2671                                         block.fPtr,
2672                                         block.fSize,
2673                                         name,
2674                                         i, j
2675                                 );
2676                                 result = false;
2677                         }
2678                 }
2679                 
2680                 bool trackOk = IsMansoTrackOk(block, blockNumber, name, i, ti.fTrack, ddl);
2681                 if (not trackOk) result = false;
2682                 
2683                 // Check that each ROI has a centre point somewhere on the correct
2684                 // corresponding chamber and that the Radius is not bigger thant
2685                 // the diameter of the chamber which would be pointless.
2686                 for (AliHLTInt32_t j = 0; j < 4; j++)
2687                 {
2688                         if (ti.fRoI[j].fRadius == -1) continue; // Ignore invalid ROIs
2689                         
2690                         Int_t chamber = AliMUONConstants::ChamberNumber(
2691                                         ti.fRoI[j].fZ, false  // false = do not warn.
2692                                 );
2693                         if (chamber != j+6)
2694                         {
2695                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2696                                         " fPtr = %p and fSize = %u bytes."
2697                                         " Assuming this is a %s data block."
2698                                         " Problem: The region of interest on chamber %d for"
2699                                         " Manso track candidate %d has a z-coordinate of %f"
2700                                         " cm that does not correspond to that chamber.",
2701                                         blockNumber,
2702                                         DataType2Text(block.fDataType).c_str(),
2703                                         block.fPtr,
2704                                         block.fSize,
2705                                         name,
2706                                         j+6+1,
2707                                         i,
2708                                         ti.fRoI[j].fZ
2709                                 );
2710                                 result = false;
2711                         }
2712                         
2713                         double x = ti.fRoI[j].fX;
2714                         double y = ti.fRoI[j].fY;
2715                         double r = sqrt(x*x + y*y);
2716                         if (r > AliMUONConstants::Dmax((j+6)/2))
2717                         {
2718                                 // Just a warning since this is not a data integrity problem
2719                                 // but rather just a data sanity problem.
2720                                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2721                                         " fPtr = %p and fSize = %u bytes."
2722                                         " Assuming this is a %s data block."
2723                                         " Problem: The region of interest coordinate {x = %f,"
2724                                         " y = %f} cm on chamber %d for Manso track candidate %d"
2725                                         " does not correspond to that chamber.",
2726                                         blockNumber,
2727                                         DataType2Text(block.fDataType).c_str(),
2728                                         block.fPtr,
2729                                         block.fSize,
2730                                         name,
2731                                         ti.fRoI[j].fX,
2732                                         ti.fRoI[j].fY,
2733                                         j+6+1,
2734                                         i
2735                                 );
2736                                 result = false;
2737                         }
2738                         
2739                         if (ti.fRoI[j].fRadius > AliMUONConstants::Dmax((j+6)/2))
2740                         {
2741                                 // Just a warning since this is not a data integrity problem
2742                                 // but rather just a data sanity problem.
2743                                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2744                                         " fPtr = %p and fSize = %u bytes."
2745                                         " Assuming this is a %s data block."
2746                                         " Problem: The region of interest radius of %f cm"
2747                                         " on chamber %d for Manso track candidate %d"
2748                                         " is bigger than the chamber diameter %f cm.",
2749                                         blockNumber,
2750                                         DataType2Text(block.fDataType).c_str(),
2751                                         block.fPtr,
2752                                         block.fSize,
2753                                         name,
2754                                         ti.fRoI[j].fRadius,
2755                                         j+6+1,
2756                                         i,
2757                                         AliMUONConstants::Dmax((j+6)/2)
2758                                 );
2759                                 result = false;
2760                         }
2761                 }
2762         }
2763         
2764         return result;
2765 }
2766
2767
2768 bool AliHLTMUONDataCheckerComponent::CheckSinglesDecisionBlock(
2769                 const AliHLTComponentBlockData& block,
2770                 AliHLTUInt32_t blockNumber
2771         ) const
2772 {
2773         /// Checks the validity of a single tracks trigger decision block.
2774
2775         bool result = true;
2776         const char* name = "singles decision";
2777         
2778         if (not fIgnoreSpec)
2779         {
2780                 if (not IsSpecificationValid(block, blockNumber, name))
2781                         result = false;
2782         }
2783         
2784         AliHLTMUONSinglesDecisionBlockReader inblock(block.fPtr, block.fSize);
2785         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2786                 return false;
2787         
2788         return result;
2789 }
2790
2791
2792 bool AliHLTMUONDataCheckerComponent::CheckPairsDecisionBlock(
2793                 const AliHLTComponentBlockData& block,
2794                 AliHLTUInt32_t blockNumber
2795         ) const
2796 {
2797         /// Checks the validity of a track pairs trigger decision block.
2798
2799         bool result = true;
2800         const char* name = "pairs decision";
2801         
2802         if (not fIgnoreSpec)
2803         {
2804                 if (not IsSpecificationValid(block, blockNumber, name))
2805                         result = false;
2806         }
2807         
2808         AliHLTMUONPairsDecisionBlockReader inblock(block.fPtr, block.fSize);
2809         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2810                 return false;
2811         
2812         return result;
2813 }
2814
2815
2816 bool AliHLTMUONDataCheckerComponent::AreMomentaCompatible(
2817                 AliHLTFloat32_t px1,
2818                 AliHLTFloat32_t py1,
2819                 AliHLTFloat32_t pz1,
2820                 AliHLTFloat32_t px2,
2821                 AliHLTFloat32_t py2,
2822                 AliHLTFloat32_t pz2
2823         ) const
2824 {
2825         /// Checks to see if the two momenta vectors are compatible or not.
2826         /// The vectors should not have an angle more than 10 degrees between
2827         /// them and their magnitudes should not be more different than 50%.
2828         
2829         double p1 = sqrt(double(px1)*double(px1) + double(py1)*double(py1) + double(pz1)*double(pz1));
2830         double p2 = sqrt(double(px2)*double(px2) + double(py2)*double(py2) + double(pz2)*double(pz2));
2831         if (p1 == 0 and p2 == 0) return true;
2832         if (fabs(p1 - p2) / ((p1 + p2)*0.5) > 0.5) return false;
2833         double denom = p1 * p2;
2834         if (denom == 0) return false;
2835         double ratio = (double(px1)*double(px2) + double(py1)*double(py2) + double(pz1)*double(pz2)) / denom;
2836         if (ratio < -1) return true;
2837         if (ratio > 1) return true;
2838         double angle = acos(ratio);
2839         if (angle > 3.14159265358979323846 * 10. / 180.) return false;
2840         return true;
2841 }
2842
2843
2844 bool AliHLTMUONDataCheckerComponent::IsScalarTooLarge(
2845                 const AliHLTComponentBlockData* block,
2846                 AliHLTUInt32_t blockNumber,
2847                 const char* blockTypeName,
2848                 const char* scalarName,
2849                 AliHLTUInt32_t scalarValue,
2850                 AliHLTUInt32_t totalTrackCount
2851         ) const
2852 {
2853         /// Checks if the scalar value is larger than the number of Manso
2854         /// tracks in the event.
2855
2856         if (scalarValue > totalTrackCount)
2857         {
2858                 HLTError("Problem found with %s trigger decision"
2859                         " data block %d, fDataType = '%s', fPtr = %p and"
2860                         " fSize = %u bytes."
2861                         " Problem: The %s scalar with value %d is larger"
2862                         " than the total number of Manso tracks found for the"
2863                         " event (%d tracks).",
2864                         blockTypeName,
2865                         blockNumber,
2866                         DataType2Text(block->fDataType).c_str(),
2867                         block->fPtr,
2868                         block->fSize,
2869                         scalarName,
2870                         scalarValue,
2871                         totalTrackCount
2872                 );
2873                 return true;
2874         }
2875         else
2876         {
2877                 return false;
2878         }
2879 }
2880
2881
2882 bool AliHLTMUONDataCheckerComponent::IsScalarALargerThanB(
2883                 const AliHLTComponentBlockData* block,
2884                 AliHLTUInt32_t blockNumber,
2885                 const char* blockTypeName,
2886                 const char* scalarAName,
2887                 AliHLTUInt32_t scalarAValue,
2888                 const char* scalarBName,
2889                 AliHLTUInt32_t scalarBValue
2890         ) const
2891 {
2892         /// Checks if the scalar value is larger than the number of Manso
2893         /// tracks in the event.
2894
2895         if (scalarAValue > scalarBValue)
2896         {
2897                 HLTError("Problem found with %s trigger decision"
2898                         " data block %d, fDataType = '%s', fPtr = %p and"
2899                         " fSize = %u bytes."
2900                         " Problem: The %s scalar with value %d is larger"
2901                         " than scalar %s with value %d, but is should not be.",
2902                         blockTypeName,
2903                         blockNumber,
2904                         DataType2Text(block->fDataType).c_str(),
2905                         block->fPtr,
2906                         block->fSize,
2907                         scalarAName,
2908                         scalarAValue,
2909                         scalarBName,
2910                         scalarBValue
2911                 );
2912                 return true;
2913         }
2914         else
2915         {
2916                 return false;
2917         }
2918 }
2919
2920
2921 void AliHLTMUONDataCheckerComponent::MarkBlock(
2922                 const AliHLTComponentBlockData* blocks,
2923                 bool* blockOk,
2924                 AliHLTUInt32_t blockCount,
2925                 const AliHLTComponentBlockData* blockToMark
2926         ) const
2927 {
2928         /// Tries to find the 'blockToMark' in the list of blocks and sets the
2929         /// corresponding 'blockOk' flag to false.
2930         
2931         for (AliHLTUInt32_t i = 0; i < blockCount; i++)
2932         {
2933                 if (&blocks[i] == blockToMark)
2934                 {
2935                         blockOk[i] = false;
2936                         return;
2937                 }
2938         }
2939 }
2940
2941
2942 void AliHLTMUONDataCheckerComponent::MakeGlobalChecks(
2943                 const AliHLTComponentBlockData* blocks,
2944                 bool* blockOk,
2945                 AliHLTUInt32_t blockCount,
2946                 const AliHLTComponentBlockData** trigRecBlocks,
2947                 AliHLTUInt32_t trigRecBlocksCount,
2948                 const AliHLTComponentBlockData** trigRecDebugBlocks,
2949                 AliHLTUInt32_t trigRecDebugBlocksCount,
2950                 const AliHLTComponentBlockData** hitBlocks,
2951                 AliHLTUInt32_t hitBlocksCount,
2952                 const AliHLTComponentBlockData** clusterBlocks,
2953                 AliHLTUInt32_t clusterBlocksCount,
2954                 const AliHLTComponentBlockData** channelBlocks,
2955                 AliHLTUInt32_t channelBlocksCount,
2956                 const AliHLTComponentBlockData** mansoTrackBlocks,
2957                 AliHLTUInt32_t mansoTrackBlocksCount,
2958                 const AliHLTComponentBlockData** mansoCandidateBlocks,
2959                 AliHLTUInt32_t mansoCandidateBlocksCount,
2960                 const AliHLTComponentBlockData** singleDecisionBlocks,
2961                 AliHLTUInt32_t singleDecisionBlocksCount,
2962                 const AliHLTComponentBlockData** pairDecisionBlocks,
2963                 AliHLTUInt32_t pairDecisionBlocksCount
2964         ) const
2965 {
2966         /// The following set of global checks are performed:
2967         /// 1) Checks if all the ID numbers in all the blocks are unique.
2968         /// 2) Check if all the structures are unique up to their ID numbers,
2969         /// that it, make sure there are no structures with the same data but
2970         /// for a different ID number.
2971         /// 3) Check if the reference ID numbers are correct, i.e. are the
2972         /// trigger record ID numbers in the track structures found in any of
2973         /// the trigger record data blocks.
2974         /// 4) Do the number of channels claimed in the cluster correspond to
2975         /// the number of channel structures.
2976         /// 5) Check that the momentum vectors between the Manso tracks and
2977         /// the corresponding trigger record are compatible.
2978         /// 6) Check that the trigger decision scalars are reasonable.
2979         /// 7) Check that the detector element IDs are the same between rec
2980         /// hits and clusters / trigger record debug blocks.
2981         
2982         // Check if all the trigger record identifiers and data are unique.
2983         for (AliHLTUInt32_t bi = 0; bi < trigRecBlocksCount; bi++)
2984         {
2985                 AliHLTMUONTriggerRecordsBlockReader inblocki(trigRecBlocks[bi]->fPtr, trigRecBlocks[bi]->fSize);
2986                 if (not inblocki.BufferSizeOk()) continue;
2987                 for (AliHLTUInt32_t bj = bi+1; bj < trigRecBlocksCount; bj++)
2988                 {
2989                         AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
2990                         if (not inblockj.BufferSizeOk()) continue;
2991                         
2992                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2993                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2994                         {
2995                                 if (inblocki[i].fId == inblockj[j].fId)
2996                                 {
2997                                         HLTError("Problem found with trigger record data block %d,"
2998                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
2999                                                 " and trigger record data block %d,"
3000                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3001                                                 " Problem: Trigger record %d in block %d and entry"
3002                                                 " %d in block %d have the same identfier, but they"
3003                                                 " should be unique.",
3004                                                 bi,
3005                                                 DataType2Text(trigRecBlocks[bi]->fDataType).c_str(),
3006                                                 trigRecBlocks[bi]->fPtr,
3007                                                 trigRecBlocks[bi]->fSize,
3008                                                 bj,
3009                                                 DataType2Text(trigRecBlocks[bj]->fDataType).c_str(),
3010                                                 trigRecBlocks[bj]->fPtr,
3011                                                 trigRecBlocks[bj]->fSize,
3012                                                 bi, i,
3013                                                 bj, j
3014                                         );
3015                                         MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bi]);
3016                                         MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
3017                                 }
3018                                 
3019                                 AliHLTMUONTriggerRecordStruct a = inblocki[i];
3020                                 AliHLTMUONTriggerRecordStruct b = inblockj[j];
3021                                 a.fId = b.fId = -1;
3022                                 if (a == b)
3023                                 {
3024                                         HLTError("Problem found with trigger record data block %d,"
3025                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
3026                                                 " and trigger record data block %d,"
3027                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3028                                                 " Problem: Trigger record %d in block %d and entry"
3029                                                 " %d in block %d have the same data."
3030                                                 " The data may have been duplicated.",
3031                                                 bi,
3032                                                 DataType2Text(trigRecBlocks[bi]->fDataType).c_str(),
3033                                                 trigRecBlocks[bi]->fPtr,
3034                                                 trigRecBlocks[bi]->fSize,
3035                                                 bj,
3036                                                 DataType2Text(trigRecBlocks[bj]->fDataType).c_str(),
3037                                                 trigRecBlocks[bj]->fPtr,
3038                                                 trigRecBlocks[bj]->fSize,
3039                                                 bi, i,
3040                                                 bj, j
3041                                         );
3042                                         MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bi]);
3043                                         MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
3044                                 }
3045                         }
3046                 }
3047         }
3048         
3049         for (AliHLTUInt32_t bi = 0; bi < trigRecDebugBlocksCount; bi++)
3050         {
3051                 AliHLTMUONTrigRecsDebugBlockReader inblocki(trigRecDebugBlocks[bi]->fPtr, trigRecDebugBlocks[bi]->fSize);
3052                 if (not inblocki.BufferSizeOk()) continue;
3053                 
3054                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3055                 {
3056                         // Check if all the trigger record IDs in the debug information structures exist.
3057                         bool found = false;
3058                         
3059                         for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
3060                         {
3061                                 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
3062                                 if (not inblockj.BufferSizeOk()) continue;
3063                                 
3064                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3065                                 {
3066                                         if (inblocki[i].fTrigRecId == inblockj[j].fId)
3067                                         {
3068                                                 found = true;
3069                                                 
3070                                                 // Since we found the corresponding trigger record,
3071                                                 // check if the detector element IDs are the same.
3072                                                 bool deOk = CheckDetElemIds(
3073                                                                 *trigRecDebugBlocks[bi], bi, i, inblocki[i],
3074                                                                 *trigRecBlocks[bj], bj, j, inblockj[j]
3075                                                         );
3076                                                 if (not deOk)
3077                                                 {
3078                                                         MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
3079                                                         MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
3080                                                 }
3081                                                 
3082                                                 break;
3083                                         }
3084                                 }
3085                         }
3086                         
3087                         if (not found)
3088                         {
3089                                 HLTError("Problem found with trigger record debug information"
3090                                         " data block %d, fDataType = '%s', fPtr = %p and"
3091                                         " fSize = %u bytes."
3092                                         " Problem with entry %d in block: The trigger record"
3093                                         " identifier %d does not exist in any trigger record"
3094                                         " data block.",
3095                                         bi,
3096                                         DataType2Text(trigRecDebugBlocks[bi]->fDataType).c_str(),
3097                                         trigRecDebugBlocks[bi]->fPtr,
3098                                         trigRecDebugBlocks[bi]->fSize,
3099                                         i, inblocki[i].fTrigRecId
3100                                 );
3101                                 MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
3102                         }
3103                 }
3104                 
3105                 // Check if all the trigger record debug information structures are unique.
3106                 for (AliHLTUInt32_t bj = bi+1; bj < trigRecDebugBlocksCount; bj++)
3107                 {
3108                         AliHLTMUONTrigRecsDebugBlockReader inblockj(trigRecDebugBlocks[bj]->fPtr, trigRecDebugBlocks[bj]->fSize);
3109                         if (not inblockj.BufferSizeOk()) continue;
3110                         
3111                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3112                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3113                         {
3114                                 AliHLTMUONTrigRecInfoStruct a = inblocki[i];
3115                                 AliHLTMUONTrigRecInfoStruct b = inblockj[j];
3116                                 a.fTrigRecId = b.fTrigRecId = -1;
3117                                 if (a == b)
3118                                 {
3119                                         HLTError("Problem found with trigger record debug information"
3120                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3121                                                 " fSize = %u bytes, and trigger record debug"
3122                                                 " information data block %d,"
3123                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3124                                                 " Problem: The trigger record debug inforamtion"
3125                                                 " structure %d in block %d and entry"
3126                                                 " %d in block %d have the same data."
3127                                                 " The data may have been duplicated.",
3128                                                 bi,
3129                                                 DataType2Text(trigRecDebugBlocks[bi]->fDataType).c_str(),
3130                                                 trigRecDebugBlocks[bi]->fPtr,
3131                                                 trigRecDebugBlocks[bi]->fSize,
3132                                                 bj,
3133                                                 DataType2Text(trigRecDebugBlocks[bj]->fDataType).c_str(),
3134                                                 trigRecDebugBlocks[bj]->fPtr,
3135                                                 trigRecDebugBlocks[bj]->fSize,
3136                                                 bi, i,
3137                                                 bj, j
3138                                         );
3139                                         MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
3140                                         MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bj]);
3141                                 }
3142                         }
3143                 }
3144         }
3145         
3146         // Check that all the reconstructed hits are unique.
3147         for (AliHLTUInt32_t bi = 0; bi < hitBlocksCount; bi++)
3148         {
3149                 AliHLTMUONRecHitsBlockReader inblocki(hitBlocks[bi]->fPtr, hitBlocks[bi]->fSize);
3150                 if (not inblocki.BufferSizeOk()) continue;
3151                 for (AliHLTUInt32_t bj = bi+1; bj < hitBlocksCount; bj++)
3152                 {
3153                         AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3154                         if (not inblockj.BufferSizeOk()) continue;
3155                         
3156                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3157                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3158                         {
3159                                 if (inblocki[i] == inblockj[j])
3160                                 {
3161                                         HLTError("Problem found with reconstructed hit data block %d,"
3162                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
3163                                                 " and reconstructed hit data block %d,"
3164                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3165                                                 " Problem: Reconstructed hit %d in block %d and entry"
3166                                                 " %d in block %d are the same, but all hits"
3167                                                 " should be unique.",
3168                                                 bi,
3169                                                 DataType2Text(hitBlocks[bi]->fDataType).c_str(),
3170                                                 hitBlocks[bi]->fPtr,
3171                                                 hitBlocks[bi]->fSize,
3172                                                 bj,
3173                                                 DataType2Text(hitBlocks[bj]->fDataType).c_str(),
3174                                                 hitBlocks[bj]->fPtr,
3175                                                 hitBlocks[bj]->fSize,
3176                                                 bi, i,
3177                                                 bj, j
3178                                         );
3179                                         MarkBlock(blocks, blockOk, blockCount, hitBlocks[bi]);
3180                                         MarkBlock(blocks, blockOk, blockCount, hitBlocks[bj]);
3181                                 }
3182                         }
3183                 }
3184         }
3185         
3186         for (AliHLTUInt32_t bi = 0; bi < clusterBlocksCount; bi++)
3187         {
3188                 AliHLTMUONClustersBlockReader inblocki(clusterBlocks[bi]->fPtr, clusterBlocks[bi]->fSize);
3189                 if (not inblocki.BufferSizeOk()) continue;
3190                 
3191                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3192                 {
3193                         // Check if all the reconstructed hit coordinates in the cluster structures exist.
3194                         bool found = false;
3195                         
3196                         for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
3197                         {
3198                                 AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3199                                 if (not inblockj.BufferSizeOk()) continue;
3200                                 
3201                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3202                                 {
3203                                         if (inblocki[i].fHit == inblockj[j])
3204                                         {
3205                                                 found = true;
3206                                                 
3207                                                 // Since we found the corresponding cluster,
3208                                                 // check if the detector element IDs are the same.
3209                                                 bool deOk = CheckDetElemIds(
3210                                                                 *clusterBlocks[bi], bi, i, inblocki[i],
3211                                                                 *hitBlocks[bj], bj, j, inblockj[j]
3212                                                         );
3213                                                 if (not deOk)
3214                                                 {
3215                                                         MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3216                                                         MarkBlock(blocks, blockOk, blockCount, hitBlocks[bj]);
3217                                                 }
3218                                                 
3219                                                 break;
3220                                         }
3221                                 }
3222                         }
3223                         
3224                         // If the hit was not found then it should be nil.
3225                         if (not found and (inblocki[i].fHit != AliHLTMUONConstants::NilRecHitStruct()))
3226                         {
3227                                 HLTError("Problem found with cluster data block %d,"
3228                                         " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3229                                         " Problem with entry %d in block: The cluster hit"
3230                                         " coordinate {x = %f, y = %f, z = %f} does not exist"
3231                                         " in any reconstructed hit data block.",
3232                                         bi,
3233                                         DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3234                                         clusterBlocks[bi]->fPtr,
3235                                         clusterBlocks[bi]->fSize,
3236                                         i,
3237                                         inblocki[i].fHit.fX,
3238                                         inblocki[i].fHit.fY,
3239                                         inblocki[i].fHit.fZ
3240                                 );
3241                                 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3242                         }
3243                         
3244                         // Check that the fNchannelsB value is correct.
3245                         // First count the number of channels found in the channels block that
3246                         // correspond to the cluster. Do this for the bending and non-bending planes.
3247                         AliHLTUInt32_t countB = 0;
3248                         AliHLTUInt32_t countNB = 0;
3249                         for (AliHLTUInt32_t bj = 0; bj < channelBlocksCount and not found; bj++)
3250                         {
3251                                 AliHLTMUONChannelsBlockReader inblockj(channelBlocks[bj]->fPtr, channelBlocks[bj]->fSize);
3252                                 if (not inblockj.BufferSizeOk()) continue;
3253                                 
3254                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3255                                 {
3256                                         if (inblocki[i].fId != inblockj[j].fClusterId) continue;
3257                                         if ((inblockj[j].fRawDataWord & (1 << 28)) == 0)
3258                                                 countB++;
3259                                         else
3260                                                 countNB++;
3261                                 }
3262                         }
3263                         
3264                         if (inblocki[i].fNchannelsB != countB)
3265                         {
3266                                 HLTWarning("Problem found with cluster data block %d,"
3267                                         " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3268                                         " Problem with entry %d in block: The number of bending plane"
3269                                         " channels in the cluster is reported as %d,"
3270                                         " but %d channel structures were found.",
3271                                         bi,
3272                                         DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3273                                         clusterBlocks[bi]->fPtr,
3274                                         clusterBlocks[bi]->fSize,
3275                                         i,
3276                                         inblocki[i].fNchannelsB,
3277                                         countB
3278                                 );
3279                                 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3280                         }
3281                         
3282                         if (inblocki[i].fNchannelsNB != countNB)
3283                         {
3284                                 HLTWarning("Problem found with cluster data block %d,"
3285                                         " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3286                                         " Problem with entry %d in block: The number of"
3287                                         " channels in the cluster of non-bending plane is reported as %d,"
3288                                         " but %d channel structures were found.",
3289                                         bi,
3290                                         DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3291                                         clusterBlocks[bi]->fPtr,
3292                                         clusterBlocks[bi]->fSize,
3293                                         i,
3294                                         inblocki[i].fNchannelsNB,
3295                                         countNB
3296                                 );
3297                                 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3298                         }
3299                 }
3300                 
3301                 // Check if all the cluster structures are unique up to the identifier
3302                 // and have unique identifiers.
3303                 for (AliHLTUInt32_t bj = bi+1; bj < clusterBlocksCount; bj++)
3304                 {
3305                         AliHLTMUONClustersBlockReader inblockj(clusterBlocks[bj]->fPtr, clusterBlocks[bj]->fSize);
3306                         if (not inblockj.BufferSizeOk()) continue;
3307                         
3308                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3309                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3310                         {
3311                                 if (inblocki[i].fId == inblockj[j].fId)
3312                                 {
3313                                         HLTError("Problem found with cluster"
3314                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3315                                                 " fSize = %u bytes, and cluster data block %d,"
3316                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3317                                                 " Problem: The cluster %d in block %d and entry"
3318                                                 " %d in block %d have the same identifier, but they"
3319                                                 " should be unique.",
3320                                                 bi,
3321                                                 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3322                                                 clusterBlocks[bi]->fPtr,
3323                                                 clusterBlocks[bi]->fSize,
3324                                                 bj,
3325                                                 DataType2Text(clusterBlocks[bj]->fDataType).c_str(),
3326                                                 clusterBlocks[bj]->fPtr,
3327                                                 clusterBlocks[bj]->fSize,
3328                                                 bi, i,
3329                                                 bj, j
3330                                         );
3331                                         MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3332                                         MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bj]);
3333                                 }
3334                                 
3335                                 AliHLTMUONClusterStruct a = inblocki[i];
3336                                 AliHLTMUONClusterStruct b = inblockj[j];
3337                                 a.fId = b.fId = -1;
3338                                 if (a == b)
3339                                 {
3340                                         HLTError("Problem found with cluster"
3341                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3342                                                 " fSize = %u bytes, and cluster data block %d,"
3343                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3344                                                 " Problem: The cluster %d in block %d and entry"
3345                                                 " %d in block %d have the same data."
3346                                                 " The data may have been duplicated.",
3347                                                 bi,
3348                                                 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3349                                                 clusterBlocks[bi]->fPtr,
3350                                                 clusterBlocks[bi]->fSize,
3351                                                 bj,
3352                                                 DataType2Text(clusterBlocks[bj]->fDataType).c_str(),
3353                                                 clusterBlocks[bj]->fPtr,
3354                                                 clusterBlocks[bj]->fSize,
3355                                                 bi, i,
3356                                                 bj, j
3357                                         );
3358                                         MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3359                                         MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bj]);
3360                                 }
3361                         }
3362                 }
3363         }
3364         
3365         for (AliHLTUInt32_t bi = 0; bi < channelBlocksCount; bi++)
3366         {
3367                 AliHLTMUONChannelsBlockReader inblocki(channelBlocks[bi]->fPtr, channelBlocks[bi]->fSize);
3368                 if (not inblocki.BufferSizeOk()) continue;
3369                 
3370                 // Check if all the cluster IDs in the channel structures exist.
3371                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3372                 {
3373                         bool found = false;
3374                         
3375                         for (AliHLTUInt32_t bj = 0; bj < clusterBlocksCount and not found; bj++)
3376                         {
3377                                 AliHLTMUONClustersBlockReader inblockj(clusterBlocks[bj]->fPtr, clusterBlocks[bj]->fSize);
3378                                 if (not inblockj.BufferSizeOk()) continue;
3379                                 
3380                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3381                                 {
3382                                         if (inblocki[i].fClusterId == inblockj[j].fId)
3383                                         {
3384                                                 found = true;
3385                                                 break;
3386                                         }
3387                                 }
3388                         }
3389                         
3390                         if (not found)
3391                         {
3392                                 HLTError("Problem found with channel"
3393                                         " data block %d, fDataType = '%s', fPtr = %p and"
3394                                         " fSize = %u bytes."
3395                                         " Problem with entry %d in block: The cluster"
3396                                         " identifier %d does not exist in any cluster"
3397                                         " data block.",
3398                                         bi,
3399                                         DataType2Text(channelBlocks[bi]->fDataType).c_str(),
3400                                         channelBlocks[bi]->fPtr,
3401                                         channelBlocks[bi]->fSize,
3402                                         i, inblocki[i].fClusterId
3403                                 );
3404                                 MarkBlock(blocks, blockOk, blockCount, channelBlocks[bi]);
3405                         }
3406                 }
3407                 
3408                 // Check if all the channel structures are unique up to the cluster ID.
3409                 for (AliHLTUInt32_t bj = bi+1; bj < channelBlocksCount; bj++)
3410                 {
3411                         AliHLTMUONChannelsBlockReader inblockj(channelBlocks[bj]->fPtr, channelBlocks[bj]->fSize);
3412                         if (not inblockj.BufferSizeOk()) continue;
3413                         
3414                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3415                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3416                         {
3417                                 AliHLTMUONChannelStruct a = inblocki[i];
3418                                 AliHLTMUONChannelStruct b = inblockj[j];
3419                                 a.fClusterId = b.fClusterId = -1;
3420                                 if (a == b)
3421                                 {
3422                                         HLTError("Problem found with channel"
3423                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3424                                                 " fSize = %u bytes, and channel data block %d,"
3425                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3426                                                 " Problem: The channel %d in block %d and entry"
3427                                                 " %d in block %d have the same data."
3428                                                 " The data may have been duplicated.",
3429                                                 bi,
3430                                                 DataType2Text(channelBlocks[bi]->fDataType).c_str(),
3431                                                 channelBlocks[bi]->fPtr,
3432                                                 channelBlocks[bi]->fSize,
3433                                                 bj,
3434                                                 DataType2Text(channelBlocks[bj]->fDataType).c_str(),
3435                                                 channelBlocks[bj]->fPtr,
3436                                                 channelBlocks[bj]->fSize,
3437                                                 bi, i,
3438                                                 bj, j
3439                                         );
3440                                         MarkBlock(blocks, blockOk, blockCount, channelBlocks[bi]);
3441                                         MarkBlock(blocks, blockOk, blockCount, channelBlocks[bj]);
3442                                 }
3443                         }
3444                 }
3445         }
3446         
3447         // Will need the total number of tracks later for comparison to trigger scalars.
3448         AliHLTUInt32_t totalTrackCount = 0;
3449         
3450         for (AliHLTUInt32_t bi = 0; bi < mansoTrackBlocksCount; bi++)
3451         {
3452                 AliHLTMUONMansoTracksBlockReader inblocki(mansoTrackBlocks[bi]->fPtr, mansoTrackBlocks[bi]->fSize);
3453                 if (not inblocki.BufferSizeOk()) continue;
3454                 
3455                 totalTrackCount += inblocki.Nentries();
3456                 
3457                 // Check if all the trigger record IDs in the Manso track structures exist.
3458                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3459                 {
3460                         bool found = false;
3461                         
3462                         for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
3463                         {
3464                                 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
3465                                 if (not inblockj.BufferSizeOk()) continue;
3466                                 
3467                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3468                                 {
3469                                         if (inblocki[i].fTrigRec == inblockj[j].fId)
3470                                         {
3471                                                 // At this point we can check if the momentum
3472                                                 // is compatible with the trigger record.
3473                                                 if (not AreMomentaCompatible(
3474                                                                 inblocki[i].fPx, inblocki[i].fPy, inblocki[i].fPz,
3475                                                                 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3476                                                         )
3477                                                    )
3478                                                 {
3479                                                         HLTWarning("Problem found with Manso track"
3480                                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3481                                                                 " fSize = %u bytes."
3482                                                                 " Problem with Manso track %d in block: The momentum"
3483                                                                 " vector of the track p = {%f, %f, %f} GeV/c is not"
3484                                                                 " compatible with the momentum vector of the trigger"
3485                                                                 " record with p = {%f, %f, %f} GeV/c.",
3486                                                                 bi,
3487                                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3488                                                                 mansoTrackBlocks[bi]->fPtr,
3489                                                                 mansoTrackBlocks[bi]->fSize,
3490                                                                 i, inblocki[i].fPx, inblocki[i].fPy, inblocki[i].fPz,
3491                                                                 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3492                                                         );
3493                                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3494                                                 }
3495                                                 
3496                                                 found = true;
3497                                                 break;
3498                                         }
3499                                 }
3500                         }
3501                         
3502                         if (not found)
3503                         {
3504                                 HLTError("Problem found with Manso track"
3505                                         " data block %d, fDataType = '%s', fPtr = %p and"
3506                                         " fSize = %u bytes."
3507                                         " Problem with Manso track %d in block: The trigger"
3508                                         " record identifier %d does not exist in any trigger"
3509                                         " record data block.",
3510                                         bi,
3511                                         DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3512                                         mansoTrackBlocks[bi]->fPtr,
3513                                         mansoTrackBlocks[bi]->fSize,
3514                                         i, inblocki[i].fTrigRec
3515                                 );
3516                                 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3517                         }
3518                 }
3519                 
3520                 // Check if all the hits in the Manso track structures exist.
3521                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3522                 {
3523                         AliHLTMUONParticleSign sign;
3524                         bool hitset[4];
3525                         AliHLTMUONUtils::UnpackMansoTrackFlags(inblocki[i].fFlags, sign, hitset);
3526                         
3527                         for (AliHLTUInt32_t n = 0; n < 4; n++)
3528                         {
3529                                 if (not hitset[n]) continue;
3530                                 bool found = false;
3531                                 
3532                                 for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
3533                                 {
3534                                         AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3535                                         if (not inblockj.BufferSizeOk()) continue;
3536                                         
3537                                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3538                                         {
3539                                                 if (inblocki[i].fHit[n] == inblockj[j])
3540                                                 {
3541                                                         found = true;
3542                                                         break;
3543                                                 }
3544                                         }
3545                                 }
3546                                 
3547                                 if (not found)
3548                                 {
3549                                         HLTError("Problem found with Manso track"
3550                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3551                                                 " fSize = %u bytes."
3552                                                 " Problem with Manso track %d in block: The hit"
3553                                                 " for chamber %d does not exist in any"
3554                                                 " reconstructed hits data block.",
3555                                                 bi,
3556                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3557                                                 mansoTrackBlocks[bi]->fPtr,
3558                                                 mansoTrackBlocks[bi]->fSize,
3559                                                 i, n+6+1
3560                                         );
3561                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3562                                 }
3563                         }
3564                 }
3565                 
3566                 // Check if all the Manso track structures are unique up to the ID and
3567                 // have unique identifiers.
3568                 for (AliHLTUInt32_t bj = bi+1; bj < mansoTrackBlocksCount; bj++)
3569                 {
3570                         AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3571                         if (not inblockj.BufferSizeOk()) continue;
3572                         
3573                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3574                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3575                         {
3576                                 if (inblocki[i].fId == inblockj[j].fId)
3577                                 {
3578                                         HLTError("Problem found with Manso track"
3579                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3580                                                 " fSize = %u bytes, and Manso track data block %d,"
3581                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3582                                                 " Problem: The Manso track %d in block %d and entry"
3583                                                 " %d in block %d have the same identifier, but they"
3584                                                 " should be unique.",
3585                                                 bi,
3586                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3587                                                 mansoTrackBlocks[bi]->fPtr,
3588                                                 mansoTrackBlocks[bi]->fSize,
3589                                                 bj,
3590                                                 DataType2Text(mansoTrackBlocks[bj]->fDataType).c_str(),
3591                                                 mansoTrackBlocks[bj]->fPtr,
3592                                                 mansoTrackBlocks[bj]->fSize,
3593                                                 bi, i,
3594                                                 bj, j
3595                                         );
3596                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3597                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bj]);
3598                                 }
3599                                 
3600                                 AliHLTMUONMansoTrackStruct a = inblocki[i];
3601                                 AliHLTMUONMansoTrackStruct b = inblockj[j];
3602                                 a.fId = b.fId = -1;
3603                                 if (a == b)
3604                                 {
3605                                         HLTError("Problem found with Manso track"
3606                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3607                                                 " fSize = %u bytes, and Manso track data block %d,"
3608                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3609                                                 " Problem: The Manso track %d in block %d and entry"
3610                                                 " %d in block %d have the same data."
3611                                                 " The data may have been duplicated.",
3612                                                 bi,
3613                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3614                                                 mansoTrackBlocks[bi]->fPtr,
3615                                                 mansoTrackBlocks[bi]->fSize,
3616                                                 bj,
3617                                                 DataType2Text(mansoTrackBlocks[bj]->fDataType).c_str(),
3618                                                 mansoTrackBlocks[bj]->fPtr,
3619                                                 mansoTrackBlocks[bj]->fSize,
3620                                                 bi, i,
3621                                                 bj, j
3622                                         );
3623                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3624                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bj]);
3625                                 }
3626                         }
3627                 }
3628         }
3629         
3630         for (AliHLTUInt32_t bi = 0; bi < mansoCandidateBlocksCount; bi++)
3631         {
3632                 AliHLTMUONMansoCandidatesBlockReader inblocki(mansoCandidateBlocks[bi]->fPtr, mansoCandidateBlocks[bi]->fSize);
3633                 if (not inblocki.BufferSizeOk()) continue;
3634                 
3635                 // Check if all the trigger record IDs in the Manso track candidate structures exist.
3636                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3637                 {
3638                         bool found = false;
3639                         
3640                         for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
3641                         {
3642                                 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
3643                                 if (not inblockj.BufferSizeOk()) continue;
3644                                 
3645                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3646                                 {
3647                                         if (inblocki[i].fTrack.fTrigRec == inblockj[j].fId)
3648                                         {
3649                                                 // At this point we can check if the momentum
3650                                                 // is compatible with the trigger record.
3651                                                 if (not AreMomentaCompatible(
3652                                                                 inblocki[i].fTrack.fPx, inblocki[i].fTrack.fPy, inblocki[i].fTrack.fPz,
3653                                                                 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3654                                                         )
3655                                                    )
3656                                                 {
3657                                                         HLTWarning("Problem found with Manso track candidate"
3658                                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3659                                                                 " fSize = %u bytes."
3660                                                                 " Problem with track candidate %d in block: The momentum"
3661                                                                 " vector of the candidate p = {%f, %f, %f} GeV/c is not"
3662                                                                 " compatible with the momentum vector of the trigger"
3663                                                                 " record with p = {%f, %f, %f} GeV/c.",
3664                                                                 bi,
3665                                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3666                                                                 mansoTrackBlocks[bi]->fPtr,
3667                                                                 mansoTrackBlocks[bi]->fSize,
3668                                                                 i,
3669                                                                 inblocki[i].fTrack.fPx, inblocki[i].fTrack.fPy, inblocki[i].fTrack.fPz,
3670                                                                 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3671                                                         );
3672                                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3673                                                 }
3674                                                 
3675                                                 found = true;
3676                                                 break;
3677                                         }
3678                                 }
3679                         }
3680                         
3681                         if (not found)
3682                         {
3683                                 HLTError("Problem found with Manso track candidate"
3684                                         " data block %d, fDataType = '%s', fPtr = %p and"
3685                                         " fSize = %u bytes."
3686                                         " Problem with track candidate %d in block: The trigger"
3687                                         " record identifier %d does not exist in any trigger"
3688                                         " record data block.",
3689                                         bi,
3690                                         DataType2Text(mansoCandidateBlocks[bi]->fDataType).c_str(),
3691                                         mansoCandidateBlocks[bi]->fPtr,
3692                                         mansoCandidateBlocks[bi]->fSize,
3693                                         i, inblocki[i].fTrack.fTrigRec
3694                                 );
3695                                 MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bi]);
3696                         }
3697                 }
3698                 
3699                 // Check if all the hits in the Manso track candidate structures exist.
3700                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3701                 {
3702                         AliHLTMUONParticleSign sign;
3703                         bool hitset[4];
3704                         AliHLTMUONUtils::UnpackMansoTrackFlags(inblocki[i].fTrack.fFlags, sign, hitset);
3705                         
3706                         for (AliHLTUInt32_t n = 0; n < 4; n++)
3707                         {
3708                                 if (not hitset[n]) continue;
3709                                 bool found = false;
3710                                 
3711                                 for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
3712                                 {
3713                                         AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3714                                         if (not inblockj.BufferSizeOk()) continue;
3715                                         
3716                                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3717                                         {
3718                                                 if (inblocki[i].fTrack.fHit[n] == inblockj[j])
3719                                                 {
3720                                                         found = true;
3721                                                         break;
3722                                                 }
3723                                         }
3724                                 }
3725                                 
3726                                 if (not found)
3727                                 {
3728                                         HLTError("Problem found with Manso track candidate"
3729                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3730                                                 " fSize = %u bytes."
3731                                                 " Problem with track candidate %d in block: The hit"
3732                                                 " for chamber %d does not exist in any"
3733                                                 " reconstructed hits data block.",
3734                                                 bi,
3735                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3736                                                 mansoTrackBlocks[bi]->fPtr,
3737                                                 mansoTrackBlocks[bi]->fSize,
3738                                                 i, n+6+1
3739                                         );
3740                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3741                                 }
3742                         }
3743                 }
3744                 
3745                 // Check if all the Manso track candidate structures are unique up to the
3746                 // track ID and have unique identifiers.
3747                 for (AliHLTUInt32_t bj = bi+1; bj < mansoCandidateBlocksCount; bj++)
3748                 {
3749                         AliHLTMUONMansoCandidatesBlockReader inblockj(mansoCandidateBlocks[bj]->fPtr, mansoCandidateBlocks[bj]->fSize);
3750                         if (not inblockj.BufferSizeOk()) continue;
3751                         
3752                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3753                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3754                         {
3755                                 if (inblocki[i].fTrack.fId == inblockj[j].fTrack.fId)
3756                                 {
3757                                         HLTError("Problem found with Manso track candidate"
3758                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3759                                                 " fSize = %u bytes, and Manso track candidate data block %d,"
3760                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3761                                                 " Problem: The track candidate %d in block %d and entry"
3762                                                 " %d in block %d have the same identifier, but they"
3763                                                 " should be unique.",
3764                                                 bi,
3765                                                 DataType2Text(mansoCandidateBlocks[bi]->fDataType).c_str(),
3766                                                 mansoCandidateBlocks[bi]->fPtr,
3767                                                 mansoCandidateBlocks[bi]->fSize,
3768                                                 bj,
3769                                                 DataType2Text(mansoCandidateBlocks[bj]->fDataType).c_str(),
3770                                                 mansoCandidateBlocks[bj]->fPtr,
3771                                                 mansoCandidateBlocks[bj]->fSize,
3772                                                 bi, i,
3773                                                 bj, j
3774                                         );
3775                                         MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bi]);
3776                                         MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bj]);
3777                                 }
3778                                 
3779                                 AliHLTMUONMansoCandidateStruct a = inblocki[i];
3780                                 AliHLTMUONMansoCandidateStruct b = inblockj[j];
3781                                 a.fTrack.fId = b.fTrack.fId = -1;
3782                                 if (a == b)
3783                                 {
3784                                         HLTError("Problem found with Manso track candidate"
3785                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3786                                                 " fSize = %u bytes, and Manso track candidate data block %d,"
3787                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3788                                                 " Problem: The track candidate %d in block %d and entry"
3789                                                 " %d in block %d have the same data."
3790                                                 " The data may have been duplicated.",
3791                                                 bi,
3792                                                 DataType2Text(mansoCandidateBlocks[bi]->fDataType).c_str(),
3793                                                 mansoCandidateBlocks[bi]->fPtr,
3794                                                 mansoCandidateBlocks[bi]->fSize,
3795                                                 bj,
3796                                                 DataType2Text(mansoCandidateBlocks[bj]->fDataType).c_str(),
3797                                                 mansoCandidateBlocks[bj]->fPtr,
3798                                                 mansoCandidateBlocks[bj]->fSize,
3799                                                 bi, i,
3800                                                 bj, j
3801                                         );
3802                                         MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bi]);
3803                                         MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bj]);
3804                                 }
3805                         }
3806                 }
3807         }
3808         
3809         for (AliHLTUInt32_t bi = 0; bi < singleDecisionBlocksCount; bi++)
3810         {
3811                 AliHLTMUONSinglesDecisionBlockReader inblocki(singleDecisionBlocks[bi]->fPtr, singleDecisionBlocks[bi]->fSize);
3812                 if (not inblocki.BufferSizeOk()) continue;
3813                 
3814                 // Check that the scalars are within reasonable limits.
3815                 const AliHLTMUONSinglesDecisionBlockStruct& hdr = inblocki.BlockHeader();
3816                 const AliHLTComponentBlockData* block = singleDecisionBlocks[bi];
3817                 if (IsScalarTooLarge(block, bi, "single track", "fNlowPt", hdr.fNlowPt, totalTrackCount) or
3818                     IsScalarTooLarge(block, bi, "single track", "fNhighPt", hdr.fNhighPt, totalTrackCount) or
3819                     IsScalarALargerThanB(block, bi, "single track", "fNhighPt", hdr.fNhighPt, "fNlowPt", hdr.fNlowPt)
3820                    )
3821                 {
3822                         MarkBlock(blocks, blockOk, blockCount, block);
3823                 }
3824                 
3825                 // Check if all the Manso track IDs in the trigger decision structures exist.
3826                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3827                 {
3828                         bool found = false;
3829                         
3830                         for (AliHLTUInt32_t bj = 0; bj < mansoTrackBlocksCount and not found; bj++)
3831                         {
3832                                 AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3833                                 if (not inblockj.BufferSizeOk()) continue;
3834                                 
3835                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3836                                 {
3837                                         if (inblocki[i].fTrackId == inblockj[j].fId)
3838                                         {
3839                                                 found = true;
3840                                                 break;
3841                                         }
3842                                 }
3843                         }
3844                         
3845                         if (not found)
3846                         {
3847                                 HLTError("Problem found with single track trigger decision"
3848                                         " data block %d, fDataType = '%s', fPtr = %p and"
3849                                         " fSize = %u bytes."
3850                                         " Problem with decision %d in block: The track"
3851                                         " identifier %d does not exist in any Manso tracks"
3852                                         " data block.",
3853                                         bi,
3854                                         DataType2Text(singleDecisionBlocks[bi]->fDataType).c_str(),
3855                                         singleDecisionBlocks[bi]->fPtr,
3856                                         singleDecisionBlocks[bi]->fSize,
3857                                         i, inblocki[i].fTrackId
3858                                 );
3859                                 MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bi]);
3860                         }
3861                 }
3862                 
3863                 // Check if all the trigger decision structures are unique up to the ID and
3864                 // have unique Manso track identifiers.
3865                 for (AliHLTUInt32_t bj = bi+1; bj < singleDecisionBlocksCount; bj++)
3866                 {
3867                         AliHLTMUONSinglesDecisionBlockReader inblockj(singleDecisionBlocks[bj]->fPtr, singleDecisionBlocks[bj]->fSize);
3868                         if (not inblockj.BufferSizeOk()) continue;
3869                         
3870                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3871                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3872                         {
3873                                 if (inblocki[i].fTrackId == inblockj[j].fTrackId)
3874                                 {
3875                                         HLTError("Problem found with single track trigger decision"
3876                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3877                                                 " fSize = %u bytes, and single track trigger decision"
3878                                                 " data block %d,"
3879                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3880                                                 " Problem: The trigger decision %d in block %d and entry"
3881                                                 " %d in block %d have the same Manso track identifier,"
3882                                                 " but they should be unique.",
3883                                                 bi,
3884                                                 DataType2Text(singleDecisionBlocks[bi]->fDataType).c_str(),
3885                                                 singleDecisionBlocks[bi]->fPtr,
3886                                                 singleDecisionBlocks[bi]->fSize,
3887                                                 bj,
3888                                                 DataType2Text(singleDecisionBlocks[bj]->fDataType).c_str(),
3889                                                 singleDecisionBlocks[bj]->fPtr,
3890                                                 singleDecisionBlocks[bj]->fSize,
3891                                                 bi, i,
3892                                                 bj, j
3893                                         );
3894                                         MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bi]);
3895                                         MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bj]);
3896                                 }
3897                                 
3898                                 AliHLTMUONTrackDecisionStruct a = inblocki[i];
3899                                 AliHLTMUONTrackDecisionStruct b = inblockj[j];
3900                                 a.fTrackId = b.fTrackId = -1;
3901                                 if (a == b)
3902                                 {
3903                                         HLTError("Problem found with single track trigger decision"
3904                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3905                                                 " fSize = %u bytes, and single track trigger decision"
3906                                                 " data block %d,"
3907                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3908                                                 " Problem: The trigger decision %d in block %d and entry"
3909                                                 " %d in block %d have the same data."
3910                                                 " The data may have been duplicated.",
3911                                                 bi,
3912                                                 DataType2Text(singleDecisionBlocks[bi]->fDataType).c_str(),
3913                                                 singleDecisionBlocks[bi]->fPtr,
3914                                                 singleDecisionBlocks[bi]->fSize,
3915                                                 bj,
3916                                                 DataType2Text(singleDecisionBlocks[bj]->fDataType).c_str(),
3917                                                 singleDecisionBlocks[bj]->fPtr,
3918                                                 singleDecisionBlocks[bj]->fSize,
3919                                                 bi, i,
3920                                                 bj, j
3921                                         );
3922                                         MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bi]);
3923                                         MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bj]);
3924                                 }
3925                         }
3926                 }
3927         }
3928         
3929         for (AliHLTUInt32_t bi = 0; bi < pairDecisionBlocksCount; bi++)
3930         {
3931                 AliHLTMUONPairsDecisionBlockReader inblocki(pairDecisionBlocks[bi]->fPtr, pairDecisionBlocks[bi]->fSize);
3932                 if (not inblocki.BufferSizeOk()) continue;
3933                 
3934                 AliHLTUInt32_t maxPairs = totalTrackCount * (totalTrackCount-1) / 2;
3935                 const AliHLTMUONPairsDecisionBlockStruct& hdr = inblocki.BlockHeader();
3936                 const AliHLTComponentBlockData* block = pairDecisionBlocks[bi];
3937                 if (IsScalarTooLarge(block, bi, "track pair", "fNunlikeAnyPt", hdr.fNunlikeAnyPt, maxPairs) or
3938                     IsScalarTooLarge(block, bi, "track pair", "fNunlikeLowPt", hdr.fNunlikeLowPt, maxPairs) or
3939                     IsScalarTooLarge(block, bi, "track pair", "fNunlikeHighPt", hdr.fNunlikeHighPt, maxPairs) or
3940                     IsScalarTooLarge(block, bi, "track pair", "fNlikeAnyPt", hdr.fNlikeAnyPt, maxPairs) or
3941                     IsScalarTooLarge(block, bi, "track pair", "fNlikeLowPt", hdr.fNlikeLowPt, maxPairs) or
3942                     IsScalarTooLarge(block, bi, "track pair", "fNlikeHighPt", hdr.fNlikeHighPt, maxPairs) or
3943                     IsScalarTooLarge(block, bi, "track pair", "fNmassAny", hdr.fNmassAny, maxPairs) or
3944                     IsScalarTooLarge(block, bi, "track pair", "fNmassLow", hdr.fNmassLow, maxPairs) or
3945                     IsScalarTooLarge(block, bi, "track pair", "fNmassHigh", hdr.fNmassHigh, maxPairs) or
3946                     IsScalarALargerThanB(block, bi, "track pair", "fNunlikeHighPt", hdr.fNunlikeHighPt, "fNunlikeLowPt", hdr.fNunlikeLowPt) or
3947                     IsScalarALargerThanB(block, bi, "track pair", "fNunlikeLowPt", hdr.fNunlikeLowPt, "fNunlikeAnyPt", hdr.fNunlikeAnyPt) or
3948                     IsScalarALargerThanB(block, bi, "track pair", "fNlikeHighPt", hdr.fNlikeHighPt, "fNlikeLowPt", hdr.fNlikeLowPt) or
3949                     IsScalarALargerThanB(block, bi, "track pair", "fNlikeLowPt", hdr.fNlikeLowPt, "fNlikeAnyPt", hdr.fNlikeAnyPt) or
3950                     IsScalarALargerThanB(block, bi, "track pair", "fNmassHigh", hdr.fNmassHigh, "fNmassLow", hdr.fNmassLow) or
3951                     IsScalarALargerThanB(block, bi, "track pair", "fNmassLow", hdr.fNmassLow, "fNmassAny", hdr.fNmassAny)
3952                    )
3953                 {
3954                         MarkBlock(blocks, blockOk, blockCount, block);
3955                 }
3956                 
3957                 // Check if all the Manso track IDs in the trigger decision structures exist.
3958                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3959                 {
3960                         bool found = false;
3961                         
3962                         for (AliHLTUInt32_t bj = 0; bj < mansoTrackBlocksCount and not found; bj++)
3963                         {
3964                                 AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3965                                 if (not inblockj.BufferSizeOk()) continue;
3966                                 
3967                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3968                                 {
3969                                         if (inblocki[i].fTrackAId == inblockj[j].fId)
3970                                         {
3971                                                 found = true;
3972                                                 break;
3973                                         }
3974                                 }
3975                         }
3976                         
3977                         if (not found)
3978                         {
3979                                 HLTError("Problem found with track pair trigger decision"
3980                                         " data block %d, fDataType = '%s', fPtr = %p and"
3981                                         " fSize = %u bytes."
3982                                         " Problem with decision %d in block: The track"
3983                                         " identifier %d does not exist in any Manso tracks"
3984                                         " data block.",
3985                                         bi,
3986                                         DataType2Text(pairDecisionBlocks[bi]->fDataType).c_str(),
3987                                         pairDecisionBlocks[bi]->fPtr,
3988                                         pairDecisionBlocks[bi]->fSize,
3989                                         i, inblocki[i].fTrackAId
3990                                 );
3991                                 MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bi]);
3992                         }
3993                         
3994                         found = false;
3995                         
3996                         for (AliHLTUInt32_t bj = 0; bj < mansoTrackBlocksCount and not found; bj++)
3997                         {
3998                                 AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3999                                 if (not inblockj.BufferSizeOk()) continue;
4000                                 
4001                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
4002                                 {
4003                                         if (inblocki[i].fTrackBId == inblockj[j].fId)
4004                                         {
4005                                                 found = true;
4006                                                 break;
4007                                         }
4008                                 }
4009                         }
4010                         
4011                         if (not found)
4012                         {
4013                                 HLTError("Problem found with track pair trigger decision"
4014                                         " data block %d, fDataType = '%s', fPtr = %p and"
4015                                         " fSize = %u bytes."
4016                                         " Problem with decision %d in block: The track"
4017                                         " identifier %d does not exist in any Manso tracks"
4018                                         " data block.",
4019                                         bi,
4020                                         DataType2Text(pairDecisionBlocks[bi]->fDataType).c_str(),
4021                                         pairDecisionBlocks[bi]->fPtr,
4022                                         pairDecisionBlocks[bi]->fSize,
4023                                         i, inblocki[i].fTrackBId
4024                                 );
4025                                 MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bi]);
4026                         }
4027                 }
4028                 
4029                 // Check if all the trigger decision structures are unique up to the ID and
4030                 // have unique Manso track identifier pairs.
4031                 for (AliHLTUInt32_t bj = bi+1; bj < pairDecisionBlocksCount; bj++)
4032                 {
4033                         AliHLTMUONPairsDecisionBlockReader inblockj(pairDecisionBlocks[bj]->fPtr, pairDecisionBlocks[bj]->fSize);
4034                         if (not inblockj.BufferSizeOk()) continue;
4035                         
4036                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
4037                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
4038                         {
4039                                 if (inblocki[i].fTrackAId == inblockj[j].fTrackAId and
4040                                     inblocki[i].fTrackBId == inblockj[j].fTrackBId
4041                                    )
4042                                 {
4043                                         HLTError("Problem found with track pair trigger decision"
4044                                                 " data block %d, fDataType = '%s', fPtr = %p and"
4045                                                 " fSize = %u bytes, and track pair trigger decision"
4046                                                 " data block %d,"
4047                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
4048                                                 " Problem: The trigger decision %d in block %d and entry"
4049                                                 " %d in block %d have the same Manso track identifier pair,"
4050                                                 " but the pair should be unique.",
4051                                                 bi,
4052                                                 DataType2Text(pairDecisionBlocks[bi]->fDataType).c_str(),
4053                                                 pairDecisionBlocks[bi]->fPtr,
4054                                                 pairDecisionBlocks[bi]->fSize,
4055                                                 bj,
4056                                                 DataType2Text(pairDecisionBlocks[bj]->fDataType).c_str(),
4057                                                 pairDecisionBlocks[bj]->fPtr,
4058                                                 pairDecisionBlocks[bj]->fSize,
4059                                                 bi, i,
4060                                                 bj, j
4061                                         );
4062                                         MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bi]);
4063                                         MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bj]);
4064                                 }
4065                                 
4066                                 AliHLTMUONPairDecisionStruct a = inblocki[i];
4067                                 AliHLTMUONPairDecisionStruct b = inblockj[j];
4068                                 a.fTrackAId = a.fTrackBId = b.fTrackAId = b.fTrackBId = -1;
4069                                 if (a == b)
4070                                 {
4071                                         HLTError("Problem found with track pair trigger decision"
4072                                                 " data block %d, fDataType = '%s', fPtr = %p and"
4073                                                 " fSize = %u bytes, and track pair trigger decision"
4074                                                 " data block %d,"
4075                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
4076                                                 " Problem: The trigger decision %d in block %d and entry"
4077                                                 " %d in block %d have the same data."
4078                                                 " The data may have been duplicated.",
4079                                                 bi,
4080                                                 DataType2Text(pairDecisionBlocks[bi]->fDataType).c_str(),
4081                                                 pairDecisionBlocks[bi]->fPtr,
4082                                                 pairDecisionBlocks[bi]->fSize,
4083                                                 bj,
4084                                                 DataType2Text(pairDecisionBlocks[bj]->fDataType).c_str(),
4085                                                 pairDecisionBlocks[bj]->fPtr,
4086                                                 pairDecisionBlocks[bj]->fSize,
4087                                                 bi, i,
4088                                                 bj, j
4089                                         );
4090                                         MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bi]);
4091                                         MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bj]);
4092                                 }
4093                         }
4094                 }
4095         }
4096 }
4097