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