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