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