]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/utils/AliHLTMUONDataCheckerComponent.cxx
Making important updates to the internal data structures:
[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 (Int_t(chNum) < minChamber or maxChamber < Int_t(chNum))
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                                 chamber+1
971                         );
972                         result = false;
973                 }
974         }
975         else
976         {
977                 HLTWarning("Cannot check a hit's detector element ID information"
978                         " without being able to load the mapping from CDB."
979                 );
980                 result = false;
981         }
982         
983         return result;
984 }
985
986
987 bool AliHLTMUONDataCheckerComponent::IsMansoTrackOk(
988                 const AliHLTComponentBlockData& block,
989                 AliHLTUInt32_t blockNumber,
990                 const char* name,
991                 AliHLTUInt32_t entryNumber,
992                 const AliHLTMUONMansoTrackStruct& track,
993                 bool ddl[22]
994         ) const
995 {
996         /// Checks if the Manso track structure is Ok.
997         /// \param  block The block from which the track data comes from.
998         /// \param  blockNumber The block index number.
999         /// \param  name The name of the type of block.
1000         /// \param  entryNumber The entry index number of the structure in the
1001         ///      block being checked.
1002         /// \param  track The Manso track data being checked.
1003         /// \param  ddl  The array decoded by AliHLTMUONUtils::UnpackSpecBits.
1004         /// \returns true if the hit is valid and false otherwise.
1005         
1006         bool result = true;
1007         
1008         // Chi^2 should not be greater than the worst fit possible, estimated
1009         // as the diameter of largest chamber times the number of points
1010         // findable in a track. Max points is 10 tracker chambers times
1011         // 2 cathodes + 4 trigger chambers.
1012         if (track.fChi2 > AliMUONConstants::Dmax(6)*AliMUONConstants::Dmax(6)*(10*2+4))
1013         {
1014                 // Just a warning since this is not technically an
1015                 // integrity problem.
1016                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
1017                         " fPtr = %p and fSize = %u bytes."
1018                         " Assuming this is a %s data block."
1019                         " Problem with entry %d in block: The Manso track has"
1020                         " the chi squared value of %f that unreasonably big.",
1021                         blockNumber,
1022                         DataType2Text(block.fDataType).c_str(),
1023                         block.fPtr,
1024                         block.fSize,
1025                         name,
1026                         entryNumber,
1027                         track.fChi2
1028                 );
1029                 result = false;
1030         }
1031         
1032         // Check if the momentum vector is reasonable.
1033         bool momOk = IsMomentumVectorOk(
1034                         block, blockNumber, name, entryNumber,
1035                         track.fPx, track.fPy, track.fPz
1036                 );
1037         if (not momOk) result = false;
1038         
1039         AliHLTMUONParticleSign sign;
1040         bool hitset[4];
1041         AliHLTMUONUtils::UnpackMansoTrackFlags(track.fFlags, sign, hitset);
1042         
1043         // Min and max allowed chamber numbers for hits:
1044         Int_t minCh = 0;
1045         Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
1046         
1047         // Check that this hit coordinates are OK.
1048         for (AliHLTUInt32_t i = 0; i < 4; i++)
1049         {
1050                 if (not hitset[i]) continue; // ignore hits that are not initialised.
1051                 bool hitOk = IsHitCoordinateOk(
1052                                 block, blockNumber, name, entryNumber, track.fHit[i],
1053                                 minCh, maxCh, i+6, ddl
1054                         );
1055                 if (not hitOk) result = false;
1056         }
1057         
1058         return result;
1059 }
1060
1061
1062 bool AliHLTMUONDataCheckerComponent::CheckDetElemIds(
1063                 const AliHLTComponentBlockData& infoBlock,
1064                 AliHLTUInt32_t infoBlockNumber,
1065                 AliHLTUInt32_t infoEntryNumber,
1066                 const AliHLTMUONTrigRecInfoStruct& info,
1067                 const AliHLTComponentBlockData& trBlock,
1068                 AliHLTUInt32_t trBlockNumber,
1069                 AliHLTUInt32_t trEntryNumber,
1070                 const AliHLTMUONTriggerRecordStruct& tr
1071         ) const
1072 {
1073         /// Checks if the detector element IDs are the same in the debug
1074         /// information structure and the trigger record structure.
1075         /// \param  infoBlock The debug information block from which the 'info'
1076         ///      data comes from.
1077         /// \param  infoBlockNumber The debug information block index number.
1078         /// \param  infoEntryNumber The entry index number of the 'info'
1079         ///      structure in the debug information data block.
1080         /// \param  info  The debug information structure being checked.
1081         /// \param  trBlock The trigger record block from which the 'tr' data
1082         ///      comes from.
1083         /// \param  trBlockNumber The trigger record block index number.
1084         /// \param  trEntryNumber The entry index number of the 'tr' structure
1085         ///      in the trigger record data block.
1086         /// \param  tr  The trigger record structure being checked.
1087         /// \returns true if the detector element IDs are the same and false
1088         ///      otherwise.
1089         
1090         bool result = true;
1091         
1092         for (int i = 0; i < 4; i++)
1093         {
1094                 AliHLTUInt8_t chamber = 0xFF;
1095                 AliHLTUInt16_t detElemId = 0xFFFF;
1096                 AliHLTMUONUtils::UnpackRecHitFlags(tr.fHit[i].fFlags, chamber, detElemId);
1097                 if (info.fDetElemId[i] == detElemId) continue;
1098                 
1099                 HLTError("Problem found with trigger record debug information %d"
1100                         " in data block %d (fDataType = '%s', fPtr = %p, fSize"
1101                         " = %u bytes) and trigger record %d in data block %d"
1102                         " (fDataType = '%s', fPtr = %p, fSize = %u bytes):"
1103                         " The detection element ID %d for chamber %d in the debug"
1104                         " information, is not the same as %d"
1105                         " found in the trigger record.",
1106                         infoEntryNumber,
1107                         infoBlockNumber,
1108                         DataType2Text(infoBlock.fDataType).c_str(),
1109                         infoBlock.fPtr,
1110                         infoBlock.fSize,
1111                         trEntryNumber,
1112                         trBlockNumber,
1113                         DataType2Text(trBlock.fDataType).c_str(),
1114                         trBlock.fPtr,
1115                         trBlock.fSize,
1116                         info.fDetElemId[i],
1117                         i+11,
1118                         detElemId
1119                 );
1120                 result = false;
1121         }
1122         
1123         return result;
1124 }
1125
1126
1127 bool AliHLTMUONDataCheckerComponent::CheckDetElemIds(
1128                 const AliHLTComponentBlockData& clusterBlock,
1129                 AliHLTUInt32_t clusterBlockNumber,
1130                 AliHLTUInt32_t clusterEntryNumber,
1131                 const AliHLTMUONClusterStruct& cluster,
1132                 const AliHLTComponentBlockData& hitBlock,
1133                 AliHLTUInt32_t hitBlockNumber,
1134                 AliHLTUInt32_t hitEntryNumber,
1135                 const AliHLTMUONRecHitStruct& hit
1136         ) const
1137 {
1138         /// Checks if the detector element IDs are the same in the cluster
1139         /// structure and the reconstructed hit structure.
1140         /// \param  clusterBlock The cluster block from which the 'cluster' data
1141         ///      comes from.
1142         /// \param  clusterBlockNumber The cluster block index number.
1143         /// \param  clusterEntryNumber The entry index number of the 'cluster'
1144         ///      structure in the cluster data block.
1145         /// \param  cluster  The cluster structure being checked.
1146         /// \param  hitBlock The reconstructed hit block from which the 'hit'
1147         ///      data comes from.
1148         /// \param  hitBlockNumber The reconstructed hit block index number.
1149         /// \param  hitEntryNumber The entry index number of the 'hit' structure
1150         ///      in the reconstructed hit data block.
1151         /// \param  hit  The trigger record structure being checked.
1152         /// \returns true if the detector element IDs are the same and false
1153         ///      otherwise.
1154         
1155         bool result = true;
1156         
1157         AliHLTUInt8_t chamber = 0xFF;
1158         AliHLTUInt16_t detElemId = 0xFFFF;
1159         AliHLTMUONUtils::UnpackRecHitFlags(hit.fFlags, chamber, detElemId);
1160         if (cluster.fDetElemId != detElemId)
1161         {
1162                 HLTError("Problem found with cluster %d in data block %d"
1163                         " (fDataType = '%s', fPtr = %p, fSize = %u bytes)"
1164                         " and reconstructed hit %d in data block %d"
1165                         " (fDataType = '%s', fPtr = %p, fSize = %u bytes):"
1166                         " The detection element ID %d in the cluster, is not"
1167                         " the same as %d found in the reconstructed hit.",
1168                         clusterEntryNumber,
1169                         clusterBlockNumber,
1170                         DataType2Text(clusterBlock.fDataType).c_str(),
1171                         clusterBlock.fPtr,
1172                         clusterBlock.fSize,
1173                         hitEntryNumber,
1174                         hitBlockNumber,
1175                         DataType2Text(hitBlock.fDataType).c_str(),
1176                         hitBlock.fPtr,
1177                         hitBlock.fSize,
1178                         cluster.fDetElemId,
1179                         detElemId
1180                 );
1181                 result = false;
1182         }
1183         
1184         return result;
1185 }
1186
1187
1188 namespace
1189 {
1190         /**
1191          * Class for logging errors found in raw DDL data.
1192          */
1193         class AliHLTMUONDecoderHandler : public AliHLTLogging
1194         {
1195         public:
1196         
1197                 /// Default constructor
1198                 AliHLTMUONDecoderHandler() :
1199                         AliHLTLogging(),
1200                         fBufferStart(NULL),
1201                         fDescriptor(NULL),
1202                         fBlockNumber(0)
1203                 {
1204                 }
1205                 
1206                 /// Default destructor.
1207                 virtual ~AliHLTMUONDecoderHandler() {}
1208                 
1209                 /// Sets the DDL raw data block descriptor.
1210                 void SetDescriptor(const AliHLTComponentBlockData* b) { fDescriptor = b; }
1211                 
1212                 /// Sets the block number of the raw data block descriptor.
1213                 void SetBlockNumber(AliHLTUInt32_t n) { fBlockNumber = n; }
1214                 
1215                 /// Logs an error message describing the problem with the DDL raw data.
1216                 template <typename ErrorCode, class DecoderHandler>
1217                 void LogError(ErrorCode code, const void* location, DecoderHandler& handler);
1218         
1219         protected:
1220                 // Do not allow copying of this class.
1221                 /// Not implemented
1222                 AliHLTMUONDecoderHandler(const AliHLTMUONDecoderHandler& rhs); // copy constructor
1223                 /// Not implemented
1224                 AliHLTMUONDecoderHandler& operator = (const AliHLTMUONDecoderHandler& rhs); // assignment operator
1225                 
1226                 const void* fBufferStart; ///< Pointer to the start of the current DDL payload buffer.
1227                 const AliHLTComponentBlockData* fDescriptor; ///< Descriptor for the DDL raw data block corresponding to the buffer.
1228                 AliHLTUInt32_t fBlockNumber;  ///< The number / index of the block descriptor.
1229         };
1230         
1231         
1232         template <typename ErrorCode, class DecoderHandler>
1233         void AliHLTMUONDecoderHandler::LogError(ErrorCode code, const void* location, DecoderHandler& handler)
1234         {
1235                 /// Logs a HLT error message describing the problem with the raw DDL data.
1236                 /// \param code  The error code describing the problem.
1237                 /// \param location  A pointer to the location in the raw data buffer
1238                 ///      where the problem was found.
1239                 /// \param handler  The decoder handler object.
1240                 
1241                 long bytepos = long(location) - long(fBufferStart) + sizeof(AliRawDataHeader);
1242                 
1243                 // create data type string.
1244                 char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1245                 memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1246                 strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1247                 strcat( dataType, ":" );
1248                 strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1249                 
1250                 HLTError("Problem found with data block %d, fDataType = '%s',"
1251                          " fPtr = %p and fSize = %u bytes."
1252                          " Assuming this is a DDL raw data block."
1253                          " Problem: %s (Error code: %d, at byte %d)",
1254                         fBlockNumber,
1255                         &dataType[0],
1256                         fDescriptor->fPtr,
1257                         fDescriptor->fSize,
1258                         handler.ErrorCodeToMessage(code),
1259                         code,
1260                         bytepos
1261                 );
1262         };
1263         
1264         
1265         /**
1266          * Class for logging decoding errors when checking tracker raw DDL data.
1267          * Used in the AliHLTMUONDataCheckerComponent::CheckRawDataBlock method.
1268          */
1269         class AliHLTMUONTrackerDecoderHandler :
1270                 public AliMUONTrackerDDLDecoderEventHandler, public AliHLTMUONDecoderHandler
1271         {
1272         public:
1273                 AliHLTMUONTrackerDecoderHandler() :
1274                         AliMUONTrackerDDLDecoderEventHandler(),
1275                         AliHLTMUONDecoderHandler(),
1276                         fMaxDigits(0),
1277                         fDigitCount(0),
1278                         fDigits(NULL),
1279                         fCurrentBusPatch(0),
1280                         fDataProblems(false)
1281                 {}
1282                 
1283                 virtual ~AliHLTMUONTrackerDecoderHandler()
1284                 {
1285                         if (fDigits != NULL) delete [] fDigits;
1286                 }
1287                 
1288                 /// Structure to store raw data words found in the raw data.
1289                 struct AliDigit
1290                 {
1291                         UInt_t fBusPatchId;  ///< Bus patch ID for the data word.
1292                         UInt_t fDataWord;   ///< Raw data word found in the DDL payload.
1293                 };
1294                 
1295                 /// Returns the number of digits found.
1296                 UInt_t DigitCount() const { return fDigitCount; }
1297                 
1298                 /// Returns the array of digits found.
1299                 const AliDigit* Digits() const { return fDigits; }
1300                 
1301                 /// Returns true if there were problems with the data.
1302                 bool DataProblems() const { return fDataProblems; }
1303                 
1304                 // Methods inherited from AliMUONTrackerDDLDecoderEventHandler:
1305                 
1306                 /// Called for each new buffer.
1307                 void OnNewBuffer(const void* buffer, UInt_t bufferSize);
1308                 
1309                 /// Called for each new DSP header.
1310                 void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/);
1311                 
1312                 /// Called for each new bus patch. Just marks the current bus patch ID.
1313                 void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* /*data*/)
1314                 {
1315                         fCurrentBusPatch = header->fBusPatchId;
1316                 }
1317                 
1318                 /// Called for each new data word found.
1319                 void OnData(UInt_t data, bool /*parityError*/);
1320                 
1321                 /// Logs an error message if there was a decoding problem with the DDL payload.
1322                 void OnError(ErrorCode code, const void* location)
1323                 {
1324                         fDataProblems = true;
1325                         LogError(code, location, *this);
1326                 }
1327         
1328         private:
1329         
1330                 // Do not allow copying of this object.
1331                 /// Not implemented.
1332                 AliHLTMUONTrackerDecoderHandler(const AliHLTMUONTrackerDecoderHandler& obj);
1333                 /// Not implemented.
1334                 AliHLTMUONTrackerDecoderHandler& operator = (const AliHLTMUONTrackerDecoderHandler& obj);
1335                 
1336                 UInt_t fMaxDigits;  ///< Maximum number of digits that can be stored in fDigits.
1337                 UInt_t fDigitCount;  ///< The number of digits currently stored in fDigits.
1338                 AliDigit* fDigits;  ///< The array of digits found in the DDL data.
1339                 UInt_t fCurrentBusPatch;  ///< The current bus patch ID being processed.
1340                 bool fDataProblems;  ///< flag indicating there were problems with the data.
1341         };
1342         
1343         
1344         void AliHLTMUONTrackerDecoderHandler::OnNewBuffer(const void* buffer, UInt_t bufferSize)
1345         {
1346                 /// Called for a new buffer. It will reset internal counters and
1347                 /// resize the digits array if necessary.
1348                 
1349                 fDataProblems = false;
1350                 fDigitCount = 0;
1351                 fBufferStart = buffer;
1352                 
1353                 // Resize the fDigits array to be able to store
1354                 // all the digits in the data buffer.
1355                 UInt_t maxSize = bufferSize / sizeof(UInt_t) + 1;
1356                 if (maxSize > fMaxDigits)
1357                 {
1358                         if (fDigits != NULL)
1359                         {
1360                                 delete [] fDigits;
1361                                 fDigits = NULL;
1362                                 fMaxDigits = 0;
1363                         }
1364                         try
1365                         {
1366                                 fDigits = new AliDigit[maxSize];
1367                                 fMaxDigits = maxSize;
1368                         }
1369                         catch (const std::bad_alloc&)
1370                         {
1371                                 HLTError("Could not allocate enough buffer space for internal arrays.");
1372                                 return;
1373                         }
1374                 }
1375         }
1376         
1377         
1378         void AliHLTMUONTrackerDecoderHandler::OnNewDSP(
1379                         const AliMUONDSPHeaderStruct* header, const void* /*data*/
1380                 )
1381         {
1382                 if (header->fPaddingWord != 0 and header->fPaddingWord != 1)
1383                 {
1384                         // create data type string.
1385                         char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1386                         memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1387                         strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1388                         strcat( dataType, ":" );
1389                         strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1390                                 
1391                         HLTError("Problem found with data block %d, fDataType = '%s',"
1392                                 " fPtr = %p and fSize = %u bytes."
1393                                 " Assuming this is a tracker DDL raw data block."
1394                                 " Problem: Found padding word marker 0x%8.8X in DSP"
1395                                 " header with DSP ID %d which has an invalid value.",
1396                                 fBlockNumber,
1397                                 &dataType[0],
1398                                 fDescriptor->fPtr,
1399                                 fDescriptor->fSize,
1400                                 header->fPaddingWord,
1401                                 header->fDSPId
1402                         );
1403                         fDataProblems = true;
1404                         return;
1405                 }
1406         }
1407         
1408         
1409         void AliHLTMUONTrackerDecoderHandler::OnData(UInt_t data, bool /*parityError*/)
1410         {
1411                 /// Called for each new data word found. This method will add
1412                 /// these to the list of digits and check if they are not duplicated.
1413                 
1414                 assert( fDigits != NULL );
1415                 
1416                 if ((data & 0x60000000) != 0)
1417                 {
1418                         // create data type string.
1419                         char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1420                         memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1421                         strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1422                         strcat( dataType, ":" );
1423                         strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1424                                 
1425                         HLTError("Problem found with data block %d, fDataType = '%s',"
1426                                 " fPtr = %p and fSize = %u bytes."
1427                                 " Assuming this is a tracker DDL raw data block."
1428                                 " Problem: Found a data word 0x%8.8X for bus patch %d"
1429                                 " whose bits 29 or 30 are not zero.",
1430                                 fBlockNumber,
1431                                 &dataType[0],
1432                                 fDescriptor->fPtr,
1433                                 fDescriptor->fSize,
1434                                 data,
1435                                 fCurrentBusPatch
1436                         );
1437                         fDataProblems = true;
1438                         return;
1439                 }
1440                 
1441                 // Check if the data word + bus patch have been duplicated.
1442                 for (UInt_t i = 0; i < fDigitCount; i++)
1443                 {
1444                         if (fDigits[i].fDataWord == data and fDigits[i].fBusPatchId == fCurrentBusPatch)
1445                         {
1446                                 // create data type string.
1447                                 char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1448                                 memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1449                                 strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1450                                 strcat( dataType, ":" );
1451                                 strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1452                                 
1453                                 HLTError("Problem found with data block %d, fDataType = '%s',"
1454                                         " fPtr = %p and fSize = %u bytes."
1455                                         " Assuming this is a tracker DDL raw data block."
1456                                         " Problem: Found a duplicate data word 0x%8.8X for bus patch %d.",
1457                                         fBlockNumber,
1458                                         &dataType[0],
1459                                         fDescriptor->fPtr,
1460                                         fDescriptor->fSize,
1461                                         data,
1462                                         fCurrentBusPatch
1463                                 );
1464                                 fDataProblems = true;
1465                                 return;
1466                         }
1467                 }
1468                 
1469                 // Add the data word + bus patch to the list of decoded digits.
1470                 if (fDigitCount < fMaxDigits)
1471                 {
1472                         fDigits[fDigitCount].fBusPatchId = fCurrentBusPatch;
1473                         fDigits[fDigitCount].fDataWord = data;
1474                         fDigitCount++;
1475                 }
1476         }
1477         
1478         /**
1479          * Class for logging decoding errors when checking trigger raw DDL data.
1480          * Used in the AliHLTMUONDataCheckerComponent::CheckRawDataBlock method.
1481          */
1482         class AliHLTMUONTriggerDecoderHandler :
1483                 public AliMUONTriggerDDLDecoderEventHandler, public AliHLTMUONDecoderHandler
1484         {
1485         public:
1486                 // Methods inherited from AliMUONTriggerDDLDecoderEventHandler:
1487                 
1488                 /// Called for each new buffer.
1489                 void OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
1490                 {
1491                         fBufferStart = buffer;
1492                 }
1493                 
1494                 /// Logs an error message if there was a decoding problem with the DDL payload.
1495                 void OnError(ErrorCode code, const void* location)
1496                 {
1497                         LogError(code, location, *this);
1498                 }
1499         };
1500         
1501 } // end of namespace
1502
1503
1504 bool AliHLTMUONDataCheckerComponent::CheckRawDataBlock(
1505                 const AliHLTComponentBlockData& block,
1506                 AliHLTUInt32_t blockNumber
1507         ) const
1508 {
1509         /// Checks the validity of a raw data block.
1510         
1511         bool result = true;
1512
1513         if (fIgnoreSpec)
1514         {
1515                 HLTWarning("Not able to check DDL raw data if -ignorespec is specified.");
1516                 return false;
1517         }
1518         
1519         bool ddl[22];
1520         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1521         
1522         // Check that only one DDL was marked in the specification.
1523         int ddlIndex = -1;
1524         for (int i = 0; i < 22; i++)
1525         {
1526                 if (not ddl[i]) continue;
1527                 
1528                 if (ddlIndex == -1)
1529                 {
1530                         ddlIndex = i;
1531                         continue;
1532                 }
1533                 
1534                 HLTError("Problem found with data block %d, fDataType = '%s',"
1535                          " fPtr = %p and fSize = %u bytes."
1536                          " Assuming this is a DDL raw data block."
1537                          " Problem: The specification indicates multiple"
1538                          " DDL sources, DDL %d and %d.",
1539                         blockNumber,
1540                         DataType2Text(block.fDataType).c_str(),
1541                         block.fPtr,
1542                         block.fSize,
1543                         ddlIndex,
1544                         i
1545                 );
1546                 result = false;
1547         }
1548         
1549         // Check the DDL common data header.
1550         AliHLTUInt32_t totalDDLSize = block.fSize;
1551         if (totalDDLSize < sizeof(AliRawDataHeader))
1552         {
1553                 HLTError("Problem found with data block %d, fDataType = '%s',"
1554                          " fPtr = %p and fSize = %u bytes."
1555                          " Assuming this is a DDL raw data block."
1556                          " Problem: The size of the data block is too short to contain"
1557                          " a valid common DDL data header. Size of buffer is only %d"
1558                          " bytes, but expected at least %d bytes.",
1559                         blockNumber,
1560                         DataType2Text(block.fDataType).c_str(),
1561                         block.fPtr,
1562                         block.fSize,
1563                         totalDDLSize,
1564                         sizeof(AliRawDataHeader)
1565                 );
1566                 return false;
1567         }
1568         
1569         const AliRawDataHeader* header =
1570                 reinterpret_cast<const AliRawDataHeader*>(block.fPtr);
1571         
1572         if (header->GetVersion() != 2)
1573         {
1574                 HLTError("Problem found with data block %d, fDataType = '%s',"
1575                          " fPtr = %p and fSize = %u bytes."
1576                          " Assuming this is a DDL raw data block."
1577                          " Problem: The common DDL data header indicates an"
1578                          " incorrect version number. Expected 2 but got %d.",
1579                         blockNumber,
1580                         DataType2Text(block.fDataType).c_str(),
1581                         block.fPtr,
1582                         block.fSize,
1583                         int( header->GetVersion() )
1584                 );
1585                 result = false;
1586         }
1587         
1588         if (header->fSize != 0xFFFFFFFF and header->fSize != block.fSize)
1589         {
1590                 HLTError("Problem found with data block %d, fDataType = '%s',"
1591                          " fPtr = %p and fSize = %u bytes."
1592                          " Assuming this is a DDL raw data block."
1593                          " Problem: The common DDL data header indicates an"
1594                          " incorrect DDL buffer size. Expected %d bytes but"
1595                          " size reported in header is %d bytes.",
1596                         blockNumber,
1597                         DataType2Text(block.fDataType).c_str(),
1598                         block.fPtr,
1599                         block.fSize,
1600                         block.fSize,
1601                         header->fSize
1602                 );
1603                 result = false;
1604         }
1605         
1606         if (header->fSize != 0xFFFFFFFF and header->fSize != block.fSize)
1607         {
1608                 HLTError("Problem found with data block %d, fDataType = '%s',"
1609                          " fPtr = %p and fSize = %u bytes."
1610                          " Assuming this is a DDL raw data block."
1611                          " Problem: The common DDL data header indicates an"
1612                          " incorrect DDL buffer size. Expected %d bytes but"
1613                          " size reported in header is %d bytes.",
1614                         blockNumber,
1615                         DataType2Text(block.fDataType).c_str(),
1616                         block.fPtr,
1617                         block.fSize,
1618                         block.fSize,
1619                         header->fSize
1620                 );
1621                 result = false;
1622         }
1623         
1624         // Check that the bits that should be zero in the CDH are infact zero.
1625         if ((header->fWord2 & 0x00C03000) != 0 or
1626             (header->fEventID2 & 0xFF000000) != 0 or
1627             (header->fStatusMiniEventID & 0xF0000000) != 0 or
1628             (header->fROILowTriggerClassHigh & 0x0FFC0000) != 0
1629            )
1630         {
1631                 HLTError("Problem found with data block %d, fDataType = '%s',"
1632                          " fPtr = %p and fSize = %u bytes."
1633                          " Assuming this is a DDL raw data block."
1634                          " Problem: The common DDL data header has non-zero"
1635                          " bits that are reserved and must be set to zero.",
1636                         blockNumber,
1637                         DataType2Text(block.fDataType).c_str(),
1638                         block.fPtr,
1639                         block.fSize
1640                 );
1641                 result = false;
1642         }
1643         
1644         AliHLTUInt32_t payloadSize = block.fSize - sizeof(AliRawDataHeader);
1645         const AliHLTUInt8_t* payload =
1646                 reinterpret_cast<const AliHLTUInt8_t*>(header + 1);
1647         
1648         if (AliHLTMUONUtils::IsTriggerDDL(block.fSpecification))
1649         {
1650                 bool scalarEvent = ((header->GetL1TriggerMessage() & 0x1) == 0x1);
1651                 AliMUONTriggerDDLDecoder<AliHLTMUONTriggerDecoderHandler> decoder;
1652                 decoder.ExitOnError(false);
1653                 decoder.TryRecover(false);
1654                 decoder.AutoDetectScalars(false);
1655                 decoder.GetHandler().SetDescriptor(&block);
1656                 decoder.GetHandler().SetBlockNumber(blockNumber);
1657                 result = decoder.Decode(payload, payloadSize, scalarEvent);
1658         }
1659         else if (AliHLTMUONUtils::IsTrackerDDL(block.fSpecification))
1660         {
1661                 AliMUONTrackerDDLDecoder<AliHLTMUONTrackerDecoderHandler> decoder;
1662                 decoder.ExitOnError(false);
1663                 decoder.TryRecover(false);
1664                 decoder.SendDataOnParityError(true);
1665                 decoder.AutoDetectTrailer(true);
1666                 decoder.CheckForTrailer(true);
1667                 decoder.GetHandler().SetDescriptor(&block);
1668                 decoder.GetHandler().SetBlockNumber(blockNumber);
1669                 result = decoder.Decode(payload, payloadSize);
1670                 if (decoder.GetHandler().DataProblems()) result = false;
1671                 
1672                 if (FetchMappingStores() == 0)  // are stores loaded?
1673                 {
1674                         Bool_t warn = kFALSE;
1675                         AliMpDDLStore* ddlStore = AliMpDDLStore::Instance(warn);
1676                         
1677                         // Check that the bus patch, manu ID and channel addresses are valid
1678                         // for each raw data word.
1679                         for (UInt_t i = 0; i < decoder.GetHandler().DigitCount(); i++)
1680                         {
1681                                 UInt_t busPatchId = decoder.GetHandler().Digits()[i].fBusPatchId;
1682                                 UInt_t dataWord = decoder.GetHandler().Digits()[i].fDataWord;
1683                                 
1684                                 UShort_t manuId; UChar_t channelId; UShort_t adc;
1685                                 AliMUONTrackerDDLDecoderEventHandler::UnpackADC(
1686                                                 dataWord, manuId, channelId, adc
1687                                         );
1688                                 
1689                                 // Check if the bus patch is valid.
1690                                 AliMpBusPatch* busPatch = ddlStore->GetBusPatch(busPatchId, warn);
1691                                 if (busPatch == NULL)
1692                                 {
1693                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1694                                                  " fPtr = %p and fSize = %u bytes."
1695                                                  " Assuming this is a tracker DDL raw data block."
1696                                                  " Problem: Found a bus patch identifier %d that"
1697                                                  " is not valid.",
1698                                                 blockNumber,
1699                                                 DataType2Text(block.fDataType).c_str(),
1700                                                 block.fPtr,
1701                                                 block.fSize,
1702                                                 busPatchId
1703                                         );
1704                                         result = false;
1705                                         continue;
1706                                 }
1707                                 
1708                                 // We can check that the bus patch is for the DDL
1709                                 // which is also indicated by the specification bits.
1710                                 if (not fIgnoreSpec and busPatch->GetDdlId() != ddlIndex)
1711                                 {
1712                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1713                                                  " fPtr = %p and fSize = %u bytes."
1714                                                  " Assuming this is a tracker DDL raw data block."
1715                                                  " Problem: Found a bus patch identifier %d for"
1716                                                  " DDL %d, but the data block specification 0x%8.8X"
1717                                                  " indicates a different DDL of %d.",
1718                                                 blockNumber,
1719                                                 DataType2Text(block.fDataType).c_str(),
1720                                                 block.fPtr,
1721                                                 block.fSize,
1722                                                 busPatchId,
1723                                                 busPatch->GetDdlId(),
1724                                                 block.fSpecification,
1725                                                 ddlIndex
1726                                         );
1727                                         result = false;
1728                                         continue;
1729                                 }
1730                                 
1731                                 // Check if the MANU ID is valid.
1732                                 if (not busPatch->HasManu(manuId))
1733                                 {
1734                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1735                                                  " fPtr = %p and fSize = %u bytes."
1736                                                  " Assuming this is a tracker DDL raw data block."
1737                                                  " Problem: Found a MANU identifier %d on bus patch %d"
1738                                                  " that is not valid.",
1739                                                 blockNumber,
1740                                                 DataType2Text(block.fDataType).c_str(),
1741                                                 block.fPtr,
1742                                                 block.fSize,
1743                                                 manuId,
1744                                                 busPatchId
1745                                         );
1746                                         result = false;
1747                                         continue;
1748                                 }
1749                                 
1750                                 // Now try to fetch the detector element to check the MANU channel.
1751                                 AliMpDetElement* de = ddlStore->GetDetElement(busPatch->GetDEId(), warn);
1752                                 if (de == NULL)
1753                                 {
1754                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1755                                                  " fPtr = %p and fSize = %u bytes."
1756                                                  " Assuming this is a tracker DDL raw data block."
1757                                                  " Problem: Found a bus patch identifier %d that"
1758                                                  " does not correspond to a detector element.",
1759                                                 blockNumber,
1760                                                 DataType2Text(block.fDataType).c_str(),
1761                                                 block.fPtr,
1762                                                 block.fSize,
1763                                                 busPatchId
1764                                         );
1765                                         result = false;
1766                                         continue;
1767                                 }
1768                                 
1769                                 if (not de->IsConnectedChannel(manuId, channelId))
1770                                 {
1771                                         // Just a warning because this is marked not
1772                                         // to be an error in the AliMUONDigitMaker.
1773                                         HLTWarning("Problem found with data block %d, fDataType = '%s',"
1774                                                  " fPtr = %p and fSize = %u bytes."
1775                                                  " Assuming this is a tracker DDL raw data block."
1776                                                  " Problem: Found a channel with address %d on"
1777                                                  " MANU ID %d and bus patch %d that is not connected.",
1778                                                 blockNumber,
1779                                                 DataType2Text(block.fDataType).c_str(),
1780                                                 block.fPtr,
1781                                                 block.fSize,
1782                                                 channelId,
1783                                                 manuId,
1784                                                 busPatchId
1785                                         );
1786                                         result = false;
1787                                         continue;
1788                                 }
1789                                 
1790                                 // Need to also load the correct segmentation to check the channel.
1791                                 const AliMpVSegmentation* seg =
1792                                         AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(
1793                                                 busPatch->GetDEId(), manuId
1794                                         );
1795                                 if (seg == NULL)
1796                                 {
1797                                         HLTError("Could not load segmentation for detector element %d"
1798                                                  " and MANU ID %d.",
1799                                                 busPatch->GetDEId(), manuId
1800                                         );
1801                                         result = false;
1802                                         continue;
1803                                 }
1804                                 
1805                                 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId, channelId), warn);
1806                                 if (not pad.IsValid())
1807                                 {
1808                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1809                                                  " fPtr = %p and fSize = %u bytes."
1810                                                  " Assuming this is a tracker DDL raw data block."
1811                                                  " Problem: Found a channel with address %d on"
1812                                                  " MANU ID %d and bus patch %d that is not valid.",
1813                                                 blockNumber,
1814                                                 DataType2Text(block.fDataType).c_str(),
1815                                                 block.fPtr,
1816                                                 block.fSize,
1817                                                 channelId,
1818                                                 manuId,
1819                                                 busPatchId
1820                                         );
1821                                         result = false;
1822                                         continue;
1823                                 }
1824                         }
1825                 }
1826                 else
1827                 {
1828                         HLTWarning("Cannot check if the bus patch IDs, MANU ID and"
1829                                 " channel addresses for DDL raw data are valid without"
1830                                 " being able to load the mapping from CDB."
1831                         );
1832                         result = false;
1833                 }
1834         }
1835         else
1836         {
1837                 HLTError("Problem found with data block %d, fDataType = '%s',"
1838                          " fPtr = %p and fSize = %u bytes."
1839                          " Assuming this is a DDL raw data block."
1840                          " Problem: The specification does not contain a valid pattern,"
1841                          " received 0x%8.8X for the specification.",
1842                         blockNumber,
1843                         DataType2Text(block.fDataType).c_str(),
1844                         block.fPtr,
1845                         block.fSize,
1846                         block.fSpecification
1847                 );
1848                 result = false;
1849         }
1850         
1851         return result;
1852 }
1853
1854
1855 bool AliHLTMUONDataCheckerComponent::CheckTriggerRecordsBlock(
1856                 const AliHLTComponentBlockData& block,
1857                 AliHLTUInt32_t blockNumber
1858         ) const
1859 {
1860         /// Checks the validity of a trigger records block.
1861
1862         bool result = true;
1863         const char* name = "trigger records";
1864         
1865         if (not fIgnoreSpec)
1866         {
1867                 if (not IsFromTriggerOnly(block, blockNumber, name))
1868                         result = false;
1869         }
1870         
1871         AliHLTMUONTriggerRecordsBlockReader inblock(block.fPtr, block.fSize);
1872         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
1873                 return false;
1874         
1875         bool ddl[22];
1876         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1877         
1878         // Min and max allowed chamber numbers for hits:
1879         Int_t minCh = AliMUONConstants::NCh() - AliMUONConstants::NTriggerCh();
1880         Int_t maxCh = AliMUONConstants::NCh() - 1;
1881         
1882         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1883         {
1884                 // Check that each hit in each trigger record has a reasonable coordinate.
1885                 AliHLTMUONParticleSign sign;
1886                 bool hitset[4];
1887                 AliHLTMUONUtils::UnpackTriggerRecordFlags(inblock[i].fFlags, sign, hitset);
1888         
1889                 for (Int_t j = 0; j < 4; j++)  // loop over 4 trigger chamber hits.
1890                 {
1891                         if (not hitset[i]) continue; // ignore hits that are not initialised.
1892                         bool hitOk = IsHitCoordinateOk(
1893                                         block, blockNumber, name, i, inblock[i].fHit[j],
1894                                         minCh, maxCh, j+10, ddl
1895                                 );
1896                         if (not hitOk) result = false;
1897                 }
1898                 
1899                 // We can also check the momentum vector.
1900                 bool momOk = IsMomentumVectorOk(
1901                                 block, blockNumber, name, i,
1902                                 inblock[i].fPx, inblock[i].fPy, inblock[i].fPz
1903                         );
1904                 if (not momOk) result = false;
1905         }
1906         
1907         // Need to check that no entries have duplicated data but with a different
1908         // ID number.
1909         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1910         {
1911                 AliHLTMUONTriggerRecordStruct ti = inblock[i];
1912                 ti.fId = -1;
1913                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
1914                 {
1915                         AliHLTMUONTriggerRecordStruct tj = inblock[j];
1916                         tj.fId = ti.fId;
1917                         
1918                         if (ti == tj)
1919                         {
1920                                 HLTError("Problem found with data block %d, fDataType = '%s',"
1921                                         " fPtr = %p and fSize = %u bytes."
1922                                         " Assuming this is a %s data block."
1923                                         " Problem: The trigger records %d and %d contain the"
1924                                         " same data. The data might have been duplicated.",
1925                                         blockNumber,
1926                                         DataType2Text(block.fDataType).c_str(),
1927                                         block.fPtr,
1928                                         block.fSize,
1929                                         name,
1930                                         i, j
1931                                 );
1932                                 result = false;
1933                         }
1934                 }
1935         }
1936         
1937         return result;
1938 }
1939
1940
1941 bool AliHLTMUONDataCheckerComponent::CheckTrigRecsDebugBlock(
1942                 const AliHLTComponentBlockData& block,
1943                 AliHLTUInt32_t blockNumber
1944         ) const
1945 {
1946         /// Checks the validity of a trigger records debug block.
1947         
1948         bool result = true;
1949         const char* name = "trigger records debug information";
1950         
1951         if (not fIgnoreSpec)
1952         {
1953                 if (not IsFromTriggerOnly(block, blockNumber, name))
1954                         result = false;
1955         }
1956         
1957         AliHLTMUONTrigRecsDebugBlockReader inblock(block.fPtr, block.fSize);
1958         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
1959                 return false;
1960         
1961         bool ddl[22];
1962         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1963         
1964         // Check that each detector element ID is valid and the corresponding DDL
1965         // bit is set in the data block specification.
1966         if (FetchMappingStores() == 0)  // are stores loaded?
1967         {
1968                 Bool_t warn = kFALSE;
1969                 AliMpDEStore* store = AliMpDEStore::Instance(warn);
1970                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1971                 for (AliHLTUInt32_t j = 0; j < 4; j++)
1972                 {
1973                         const AliHLTMUONTrigRecInfoStruct& trig = inblock[i];
1974                         AliMpDetElement* de = store->GetDetElement(trig.fDetElemId[j], warn);
1975                         if (de == NULL)
1976                         {
1977                                 HLTError("Problem found with data block %d, fDataType = '%s',"
1978                                          " fPtr = %p and fSize = %u bytes."
1979                                          " Assuming this is a %s data block."
1980                                          " Problem: The detector element number %d on chamber"
1981                                          " %d for trigger record debug structure %d is not valid.",
1982                                         blockNumber,
1983                                         DataType2Text(block.fDataType).c_str(),
1984                                         block.fPtr,
1985                                         block.fSize,
1986                                         name,
1987                                         trig.fDetElemId[j],
1988                                         j+11,
1989                                         i
1990                                 );
1991                                 result = false;
1992                                 continue;
1993                         }
1994                         
1995                         // Check that the chamber number from the detector element number
1996                         // has the expected value.
1997                         Int_t chamber = AliMpDEManager::GetChamberId(trig.fDetElemId[j], warn);
1998                         if (chamber != Int_t(j+10))
1999                         {
2000                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2001                                          " fPtr = %p and fSize = %u bytes."
2002                                          " Assuming this is a %s data block."
2003                                          " Problem: The detector element number %d for trigger"
2004                                          " record debug structure %d, corresponds to chamber"
2005                                          " %d, but we expected a hit for chamber %d.",
2006                                         blockNumber,
2007                                         DataType2Text(block.fDataType).c_str(),
2008                                         block.fPtr,
2009                                         block.fSize,
2010                                         name,
2011                                         trig.fDetElemId[j],
2012                                         i,
2013                                         chamber+1,
2014                                         j+11
2015                                 );
2016                                 result = false;
2017                         }
2018                         
2019                         if (fIgnoreSpec) continue;
2020                         if (0 <= de->GetDdlId() and de->GetDdlId() < 22 and ddl[de->GetDdlId()])
2021                         {
2022                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2023                                          " fPtr = %p and fSize = %u bytes."
2024                                          " Assuming this is a %s data block."
2025                                          " Problem: The detector element number %d for trigger"
2026                                          " record %d corresponds to DDL number %d, but the"
2027                                          " data block specification 0x%8.8X does not have the"
2028                                          " corresponding bit set.",
2029                                         blockNumber,
2030                                         DataType2Text(block.fDataType).c_str(),
2031                                         block.fPtr,
2032                                         block.fSize,
2033                                         name,
2034                                         trig.fDetElemId[j],
2035                                         i,
2036                                         de->GetDdlId(),
2037                                         block.fSpecification
2038                                 );
2039                                 result = false;
2040                         }
2041                 }
2042         }
2043         else
2044         {
2045                 HLTWarning("Cannot check trigger record debug information without"
2046                         " being able to load the mapping from CDB."
2047                 );
2048                 result = false;
2049         }
2050         
2051         // Need to check that no entries have duplicated data but with a different
2052         // ID number.
2053         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2054         {
2055                 AliHLTMUONTrigRecInfoStruct ti = inblock[i];
2056                 ti.fTrigRecId = -1;
2057                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2058                 {
2059                         AliHLTMUONTrigRecInfoStruct tj = inblock[j];
2060                         tj.fTrigRecId = ti.fTrigRecId;
2061                         
2062                         if (ti == tj)
2063                         {
2064                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2065                                         " fPtr = %p and fSize = %u bytes."
2066                                         " Assuming this is a %s data block."
2067                                         " Problem: The trigger record debug information"
2068                                         " structures %d and %d contain the same data."
2069                                         " The data might have been duplicated.",
2070                                         blockNumber,
2071                                         DataType2Text(block.fDataType).c_str(),
2072                                         block.fPtr,
2073                                         block.fSize,
2074                                         name,
2075                                         i, j
2076                                 );
2077                                 result = false;
2078                         }
2079                 }
2080                 
2081                 // Can also check that the value of the fZmiddle and fBl.
2082                 bool paramsOk = AreMomentumCalcParamsOk(
2083                                 block, blockNumber, name, i, ti.fZmiddle, ti.fBl
2084                         );
2085                 if (not paramsOk) result = false;
2086         }
2087         
2088         return result;
2089 }
2090
2091
2092 bool AliHLTMUONDataCheckerComponent::CheckRecHitsBlock(
2093                 const AliHLTComponentBlockData& block,
2094                 AliHLTUInt32_t blockNumber
2095         ) const
2096 {
2097         /// Checks the validity of a reconstructed hits block.
2098
2099         bool result = true;
2100         const char* name = "reconstructed hits";
2101         
2102         if (not fIgnoreSpec)
2103         {
2104                 if (not IsFromTrackerOnly(block, blockNumber, name))
2105                         result = false;
2106         }
2107         
2108         AliHLTMUONRecHitsBlockReader inblock(block.fPtr, block.fSize);
2109         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2110                 return false;
2111         
2112         bool ddl[22];
2113         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2114         
2115         // Check that each hit has a reasonable coordinate.
2116         Int_t minCh = 0;
2117         Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
2118         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2119         {
2120                 bool hitOk = IsHitCoordinateOk(
2121                                 block, blockNumber, name, i, inblock[i],
2122                                 minCh, maxCh, -1, ddl
2123                         );
2124                 if (not hitOk) result = false;
2125         }
2126         
2127         return result;
2128 }
2129
2130
2131 bool AliHLTMUONDataCheckerComponent::CheckClustersBlock(
2132                 const AliHLTComponentBlockData& block,
2133                 AliHLTUInt32_t blockNumber
2134         ) const
2135 {
2136         /// Checks the validity of a clusters block.
2137
2138         bool result = true;
2139         const char* name = "clusters";
2140         
2141         if (not fIgnoreSpec)
2142         {
2143                 if (not IsFromTrackerOnly(block, blockNumber, name))
2144                         result = false;
2145         }
2146         
2147         AliHLTMUONClustersBlockReader inblock(block.fPtr, block.fSize);
2148         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2149                 return false;
2150         
2151         bool ddl[22];
2152         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2153         
2154         if (FetchMappingStores() == 0)  // are stores loaded?
2155         {
2156                 Bool_t warn = kFALSE;
2157                 AliMpDEStore* store = AliMpDEStore::Instance(warn);
2158                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2159                 {
2160                         const AliHLTMUONClusterStruct& cluster = inblock[i];
2161                         
2162                         // Check that the detector element ID is valid.
2163                         AliMpDetElement* de = store->GetDetElement(cluster.fDetElemId, warn);
2164                         if (de == NULL)
2165                         {
2166                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2167                                          " fPtr = %p and fSize = %u bytes."
2168                                          " Assuming this is a %s data block."
2169                                          " Problem: The detector element number %d for cluster"
2170                                          " %d is not valid.",
2171                                         blockNumber,
2172                                         DataType2Text(block.fDataType).c_str(),
2173                                         block.fPtr,
2174                                         block.fSize,
2175                                         name,
2176                                         cluster.fDetElemId,
2177                                         i
2178                                 );
2179                                 result = false;
2180                                 continue;
2181                         }
2182                         
2183                         // Check that the chamber number found from the hit coordinate and
2184                         // that from the detector element number are the same.
2185                         Int_t chamberFromHit = AliMUONConstants::ChamberNumber(cluster.fHit.fZ, warn);
2186                         Int_t chamberFromDE = AliMpDEManager::GetChamberId(cluster.fDetElemId, warn);
2187                         if (chamberFromHit != chamberFromDE)
2188                         {
2189                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2190                                          " fPtr = %p and fSize = %u bytes."
2191                                          " Assuming this is a %s data block."
2192                                          " Problem: The detector element number %d for"
2193                                          " cluster %d, corresponds to chamber %d, but"
2194                                          " found a different chamber number %d for the"
2195                                          " corresponding hit coordinate {x = %f, y = %f,"
2196                                          " z = %f}.",
2197                                         blockNumber,
2198                                         DataType2Text(block.fDataType).c_str(),
2199                                         block.fPtr,
2200                                         block.fSize,
2201                                         name,
2202                                         cluster.fDetElemId,
2203                                         i,
2204                                         chamberFromDE+1,
2205                                         chamberFromHit+1,
2206                                         cluster.fHit.fX,
2207                                         cluster.fHit.fY,
2208                                         cluster.fHit.fZ
2209                                 );
2210                                 result = false;
2211                         }
2212                         
2213                         // Make sure the corresponding DDL bit is set in the data
2214                         // block specification.
2215                         if (fIgnoreSpec) continue;
2216                         if (0 <= de->GetDdlId() and de->GetDdlId() < 22 and ddl[de->GetDdlId()])
2217                         {
2218                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2219                                          " fPtr = %p and fSize = %u bytes."
2220                                          " Assuming this is a %s data block."
2221                                          " Problem: The detector element number %d for cluster"
2222                                          " %d corresponds to DDL number %d, but the data"
2223                                          " block specification 0x%8.8X does not have the"
2224                                          " corresponding bit set.",
2225                                         blockNumber,
2226                                         DataType2Text(block.fDataType).c_str(),
2227                                         block.fPtr,
2228                                         block.fSize,
2229                                         name,
2230                                         cluster.fDetElemId,
2231                                         i,
2232                                         de->GetDdlId(),
2233                                         block.fSpecification
2234                                 );
2235                                 result = false;
2236                         }
2237                 }
2238         }
2239         else
2240         {
2241                 HLTWarning("Cannot check cluster information without being able"
2242                         " to load the mapping from CDB."
2243                 );
2244                 result = false;
2245         }
2246         
2247         // Min and max chamber numbers allowed for the cluster hits.
2248         Int_t minCh = 0;
2249         Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
2250         
2251         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2252         {
2253                 // Need to check that no cluster data has duplicated data but with
2254                 // a different ID number.
2255                 AliHLTMUONClusterStruct ci = inblock[i];
2256                 ci.fId = -1;
2257                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2258                 {
2259                         AliHLTMUONClusterStruct cj = inblock[j];
2260                         cj.fId = ci.fId;
2261                         
2262                         if (ci == cj)
2263                         {
2264                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2265                                         " fPtr = %p and fSize = %u bytes."
2266                                         " Assuming this is a %s data block."
2267                                         " Problem: The cluster structures %d and %d contain"
2268                                         " the same data. The data might have been duplicated.",
2269                                         blockNumber,
2270                                         DataType2Text(block.fDataType).c_str(),
2271                                         block.fPtr,
2272                                         block.fSize,
2273                                         name,
2274                                         i, j
2275                                 );
2276                                 result = false;
2277                         }
2278                 }
2279                 
2280                 // Check that the hit structure in the cluster corresponds
2281                 // to a tracker chamber.
2282                 bool hitOk = IsHitCoordinateOk(
2283                                 block, blockNumber, name, i, ci.fHit,
2284                                 minCh, maxCh, -1, ddl
2285                         );
2286                 if (not hitOk) result = false;
2287         }
2288         
2289         return result;
2290 }
2291
2292
2293 bool AliHLTMUONDataCheckerComponent::CheckChannelsBlock(
2294                 const AliHLTComponentBlockData& block,
2295                 AliHLTUInt32_t blockNumber
2296         ) const
2297 {
2298         /// Checks the validity of a channels block.
2299
2300         bool result = true;
2301         const char* name = "channels";
2302         
2303         if (not fIgnoreSpec)
2304         {
2305                 if (not IsFromTrackerOnly(block, blockNumber, name))
2306                         result = false;
2307         }
2308         
2309         AliHLTMUONChannelsBlockReader inblock(block.fPtr, block.fSize);
2310         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2311                 return false;
2312         
2313         bool ddl[22];
2314         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2315         
2316         if (FetchMappingStores() == 0)  // are stores loaded?
2317         {
2318                 Bool_t warn = kFALSE;
2319                 AliMpDDLStore* store = AliMpDDLStore::Instance(warn);
2320                 
2321                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2322                 {
2323                         const AliHLTMUONChannelStruct& channel = inblock[i];
2324                         
2325                         // Check if the bus patch is valid.
2326                         AliMpBusPatch* busPatch = store->GetBusPatch(channel.fBusPatch, warn);
2327                         if (busPatch == NULL)
2328                         {
2329                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2330                                         " fPtr = %p and fSize = %u bytes."
2331                                         " Assuming this is a %s data block."
2332                                         " Problem: Found a bus patch identifier %d that"
2333                                         " is not valid.",
2334                                         blockNumber,
2335                                         DataType2Text(block.fDataType).c_str(),
2336                                         block.fPtr,
2337                                         block.fSize,
2338                                         name,
2339                                         channel.fBusPatch
2340                                 );
2341                                 result = false;
2342                                 continue;
2343                         }
2344                         
2345                         // We can check that the bus patch is for a DDL
2346                         // which is also indicated by the specification bits.
2347                         if (not fIgnoreSpec and (
2348                              not (0 <= busPatch->GetDdlId() and busPatch->GetDdlId() < 20)
2349                              or  (0 <= busPatch->GetDdlId() and busPatch->GetDdlId() < 20
2350                                   and not ddl[busPatch->GetDdlId()])
2351                            ))
2352                         {
2353                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2354                                          " fPtr = %p and fSize = %u bytes."
2355                                          " Assuming this is a %s data block."
2356                                          " Problem: Found a bus patch identifier %d for"
2357                                          " DDL %d, but the data block specification 0x%8.8X"
2358                                          " does not have the corresponding bit set.",
2359                                         blockNumber,
2360                                         DataType2Text(block.fDataType).c_str(),
2361                                         block.fPtr,
2362                                         block.fSize,
2363                                         name,
2364                                         channel.fBusPatch,
2365                                         busPatch->GetDdlId(),
2366                                         block.fSpecification
2367                                 );
2368                                 result = false;
2369                                 continue;
2370                         }
2371                         
2372                         // Check if the MANU ID is valid.
2373                         if (not busPatch->HasManu(channel.fManu))
2374                         {
2375                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2376                                          " fPtr = %p and fSize = %u bytes."
2377                                          " Assuming this is a %s data block."
2378                                          " Problem: Found a MANU identifier %d on bus patch %d"
2379                                          " that is not valid.",
2380                                         blockNumber,
2381                                         DataType2Text(block.fDataType).c_str(),
2382                                         block.fPtr,
2383                                         block.fSize,
2384                                         name,
2385                                         channel.fManu,
2386                                         channel.fBusPatch
2387                                 );
2388                                 result = false;
2389                                 continue;
2390                         }
2391                         
2392                         // Now try to fetch the detector element to check the MANU channel.
2393                         AliMpDetElement* de = store->GetDetElement(busPatch->GetDEId(), warn);
2394                         if (de == NULL)
2395                         {
2396                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2397                                          " fPtr = %p and fSize = %u bytes."
2398                                          " Assuming this is a %s data block."
2399                                          " Problem: Found a bus patch identifier %d that"
2400                                          " does not correspond to a detector element.",
2401                                         blockNumber,
2402                                         DataType2Text(block.fDataType).c_str(),
2403                                         block.fPtr,
2404                                         block.fSize,
2405                                         name,
2406                                         channel.fBusPatch
2407                                 );
2408                                 result = false;
2409                                 continue;
2410                         }
2411                         
2412                         if (not de->IsConnectedChannel(channel.fManu, channel.fChannelAddress))
2413                         {
2414                                 // Just a warning because this is marked not
2415                                 // to be an error in the AliMUONDigitMaker.
2416                                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2417                                         " fPtr = %p and fSize = %u bytes."
2418                                         " Assuming this is a %s data block."
2419                                         " Problem: Found a channel with address %d on"
2420                                         " MANU ID %d and bus patch %d that is not connected.",
2421                                         blockNumber,
2422                                         DataType2Text(block.fDataType).c_str(),
2423                                         block.fPtr,
2424                                         block.fSize,
2425                                         name,
2426                                         channel.fChannelAddress,
2427                                         channel.fManu,
2428                                         channel.fBusPatch
2429                                 );
2430                                 result = false;
2431                                 continue;
2432                         }
2433                         
2434                         // Need to also load the correct segmentation to check the channel.
2435                         const AliMpVSegmentation* seg =
2436                                 AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(
2437                                         busPatch->GetDEId(), channel.fManu
2438                                 );
2439                         if (seg == NULL)
2440                         {
2441                                 HLTError("Could not load segmentation for detector element %d"
2442                                          " and MANU ID %d.",
2443                                         busPatch->GetDEId(), channel.fManu
2444                                 );
2445                                 result = false;
2446                                 continue;
2447                         }
2448                         
2449                         AliMpPad pad = seg->PadByLocation(
2450                                         AliMpIntPair(channel.fManu, channel.fChannelAddress),
2451                                         warn
2452                                 );
2453                         if (not pad.IsValid())
2454                         {
2455                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2456                                         " fPtr = %p and fSize = %u bytes."
2457                                         " Assuming this is a %s data block."
2458                                         " Problem: Found a channel with address %d on"
2459                                         " MANU ID %d and bus patch %d that is not valid.",
2460                                         blockNumber,
2461                                         DataType2Text(block.fDataType).c_str(),
2462                                         block.fPtr,
2463                                         block.fSize,
2464                                         name,
2465                                         channel.fChannelAddress,
2466                                         channel.fManu,
2467                                         channel.fBusPatch
2468                                 );
2469                                 result = false;
2470                                 continue;
2471                         }
2472                 }
2473         }
2474         else
2475         {
2476                 HLTWarning("Cannot check channel information without being able"
2477                         " to load the mapping from CDB."
2478                 );
2479                 result = false;
2480         }
2481         
2482         // Need to check that no channel data has duplicated data but with
2483         // a different cluster ID number.
2484         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2485         {
2486                 AliHLTMUONChannelStruct ci = inblock[i];
2487                 ci.fClusterId = -1;
2488                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2489                 {
2490                         AliHLTMUONChannelStruct cj = inblock[j];
2491                         cj.fClusterId = ci.fClusterId;
2492                         
2493                         if (ci == cj)
2494                         {
2495                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2496                                         " fPtr = %p and fSize = %u bytes."
2497                                         " Assuming this is a %s data block."
2498                                         " Problem: The channel structures %d and %d contain"
2499                                         " the same data. The data might have been duplicated.",
2500                                         blockNumber,
2501                                         DataType2Text(block.fDataType).c_str(),
2502                                         block.fPtr,
2503                                         block.fSize,
2504                                         name,
2505                                         i, j
2506                                 );
2507                                 result = false;
2508                         }
2509                 }
2510         }
2511         
2512         return result;
2513 }
2514
2515
2516 bool AliHLTMUONDataCheckerComponent::CheckMansoTracksBlock(
2517                 const AliHLTComponentBlockData& block,
2518                 AliHLTUInt32_t blockNumber
2519         ) const
2520 {
2521         /// Checks the validity of a Manso tracks block.
2522
2523         bool result = true;
2524         const char* name = "Manso tracks";
2525         
2526         if (not fIgnoreSpec)
2527         {
2528                 if (not IsSpecificationValid(block, blockNumber, name))
2529                         result = false;
2530         }
2531         
2532         AliHLTMUONMansoTracksBlockReader inblock(block.fPtr, block.fSize);
2533         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2534                 return false;
2535         
2536         bool ddl[22];
2537         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2538         
2539         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2540         {
2541                 // Need to check that no entries have duplicated data but with
2542                 // a different track ID number.
2543                 AliHLTMUONMansoTrackStruct ti = inblock[i];
2544                 ti.fId = -1;
2545                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2546                 {
2547                         AliHLTMUONMansoTrackStruct tj = inblock[j];
2548                         tj.fId = ti.fId;
2549                         
2550                         if (ti == tj)
2551                         {
2552                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2553                                         " fPtr = %p and fSize = %u bytes."
2554                                         " Assuming this is a %s data block."
2555                                         " Problem: The Manso tracks %d and %d contain the"
2556                                         " same data. The data might have been duplicated.",
2557                                         blockNumber,
2558                                         DataType2Text(block.fDataType).c_str(),
2559                                         block.fPtr,
2560                                         block.fSize,
2561                                         name,
2562                                         i, j
2563                                 );
2564                                 result = false;
2565                         }
2566                 }
2567                 
2568                 bool trackOk = IsMansoTrackOk(block, blockNumber, name, i, ti, ddl);
2569                 if (not trackOk) result = false;
2570         }
2571         
2572         return result;
2573 }
2574
2575
2576 bool AliHLTMUONDataCheckerComponent::CheckMansoCandidatesBlock(
2577                 const AliHLTComponentBlockData& block,
2578                 AliHLTUInt32_t blockNumber
2579         ) const
2580 {
2581         /// Checks the validity of a Manso candidates block.
2582
2583         bool result = true;
2584         const char* name = "Manso track candidates";
2585         
2586         if (not fIgnoreSpec)
2587         {
2588                 if (not IsSpecificationValid(block, blockNumber, name))
2589                         result = false;
2590         }
2591         
2592         AliHLTMUONMansoCandidatesBlockReader inblock(block.fPtr, block.fSize);
2593         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2594                 return false;
2595         
2596         bool ddl[22];
2597         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2598         
2599         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2600         {
2601                 // Need to check that no entries have duplicated data but with a
2602                 // different track ID number.
2603                 AliHLTMUONMansoCandidateStruct ti = inblock[i];
2604                 ti.fTrack.fId = -1;
2605                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2606                 {
2607                         AliHLTMUONMansoCandidateStruct tj = inblock[j];
2608                         tj.fTrack.fId = ti.fTrack.fId;
2609                         
2610                         if (ti == tj)
2611                         {
2612                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2613                                         " fPtr = %p and fSize = %u bytes."
2614                                         " Assuming this is a %s data block."
2615                                         " Problem: The Manso track candidates %d and %d"
2616                                         " contain the same data."
2617                                         " The data might have been duplicated.",
2618                                         blockNumber,
2619                                         DataType2Text(block.fDataType).c_str(),
2620                                         block.fPtr,
2621                                         block.fSize,
2622                                         name,
2623                                         i, j
2624                                 );
2625                                 result = false;
2626                         }
2627                 }
2628                 
2629                 bool trackOk = IsMansoTrackOk(block, blockNumber, name, i, ti.fTrack, ddl);
2630                 if (not trackOk) result = false;
2631                 
2632                 // Check that each ROI has a centre point somewhere on the correct
2633                 // corresponding chamber and that the Radius is not bigger thant
2634                 // the diameter of the chamber which would be pointless.
2635                 for (AliHLTInt32_t j = 0; j < 4; j++)
2636                 {
2637                         if (ti.fRoI[j].fRadius == -1) continue; // Ignore invalid ROIs
2638                         
2639                         Int_t chamber = AliMUONConstants::ChamberNumber(
2640                                         ti.fRoI[j].fZ, false  // false = do not warn.
2641                                 );
2642                         if (chamber != j+6)
2643                         {
2644                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2645                                         " fPtr = %p and fSize = %u bytes."
2646                                         " Assuming this is a %s data block."
2647                                         " Problem: The region of interest on chamber %d for"
2648                                         " Manso track candidate %d has a z-coordinate of %f"
2649                                         " cm that does not correspond to that chamber.",
2650                                         blockNumber,
2651                                         DataType2Text(block.fDataType).c_str(),
2652                                         block.fPtr,
2653                                         block.fSize,
2654                                         name,
2655                                         j+6+1,
2656                                         i,
2657                                         ti.fRoI[j].fZ
2658                                 );
2659                                 result = false;
2660                         }
2661                         
2662                         double x = ti.fRoI[j].fX;
2663                         double y = ti.fRoI[j].fY;
2664                         double r = sqrt(x*x + y*y);
2665                         if (r > AliMUONConstants::Dmax((j+6)/2))
2666                         {
2667                                 // Just a warning since this is not a data integrity problem
2668                                 // but rather just a data sanity problem.
2669                                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2670                                         " fPtr = %p and fSize = %u bytes."
2671                                         " Assuming this is a %s data block."
2672                                         " Problem: The region of interest coordinate {x = %f,"
2673                                         " y = %f} cm on chamber %d for Manso track candidate %d"
2674                                         " does not correspond to that chamber.",
2675                                         blockNumber,
2676                                         DataType2Text(block.fDataType).c_str(),
2677                                         block.fPtr,
2678                                         block.fSize,
2679                                         name,
2680                                         ti.fRoI[j].fX,
2681                                         ti.fRoI[j].fY,
2682                                         j+6+1,
2683                                         i
2684                                 );
2685                                 result = false;
2686                         }
2687                         
2688                         if (ti.fRoI[j].fRadius > AliMUONConstants::Dmax((j+6)/2))
2689                         {
2690                                 // Just a warning since this is not a data integrity problem
2691                                 // but rather just a data sanity problem.
2692                                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2693                                         " fPtr = %p and fSize = %u bytes."
2694                                         " Assuming this is a %s data block."
2695                                         " Problem: The region of interest radius of %f cm"
2696                                         " on chamber %d for Manso track candidate %d"
2697                                         " is bigger than the chamber diameter %f cm.",
2698                                         blockNumber,
2699                                         DataType2Text(block.fDataType).c_str(),
2700                                         block.fPtr,
2701                                         block.fSize,
2702                                         name,
2703                                         ti.fRoI[j].fRadius,
2704                                         j+6+1,
2705                                         i,
2706                                         AliMUONConstants::Dmax((j+6)/2)
2707                                 );
2708                                 result = false;
2709                         }
2710                 }
2711         }
2712         
2713         return result;
2714 }
2715
2716
2717 bool AliHLTMUONDataCheckerComponent::CheckSinglesDecisionBlock(
2718                 const AliHLTComponentBlockData& block,
2719                 AliHLTUInt32_t blockNumber
2720         ) const
2721 {
2722         /// Checks the validity of a single tracks trigger decision block.
2723
2724         bool result = true;
2725         const char* name = "singles decision";
2726         
2727         if (not fIgnoreSpec)
2728         {
2729                 if (not IsSpecificationValid(block, blockNumber, name))
2730                         result = false;
2731         }
2732         
2733         AliHLTMUONSinglesDecisionBlockReader inblock(block.fPtr, block.fSize);
2734         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2735                 return false;
2736         
2737         return result;
2738 }
2739
2740
2741 bool AliHLTMUONDataCheckerComponent::CheckPairsDecisionBlock(
2742                 const AliHLTComponentBlockData& block,
2743                 AliHLTUInt32_t blockNumber
2744         ) const
2745 {
2746         /// Checks the validity of a track pairs trigger decision block.
2747
2748         bool result = true;
2749         const char* name = "pairs decision";
2750         
2751         if (not fIgnoreSpec)
2752         {
2753                 if (not IsSpecificationValid(block, blockNumber, name))
2754                         result = false;
2755         }
2756         
2757         AliHLTMUONPairsDecisionBlockReader inblock(block.fPtr, block.fSize);
2758         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2759                 return false;
2760         
2761         return result;
2762 }
2763
2764
2765 bool AliHLTMUONDataCheckerComponent::AreMomentaCompatible(
2766                 AliHLTFloat32_t px1,
2767                 AliHLTFloat32_t py1,
2768                 AliHLTFloat32_t pz1,
2769                 AliHLTFloat32_t px2,
2770                 AliHLTFloat32_t py2,
2771                 AliHLTFloat32_t pz2
2772         ) const
2773 {
2774         /// Checks to see if the two momenta vectors are compatible or not.
2775         /// The vectors should not have an angle more than 10 degrees between
2776         /// them and their magnitudes should not be more different than 50%.
2777         
2778         double p1 = sqrt(px1*px1 + py1*py1 + pz1*pz1);
2779         double p2 = sqrt(px2*px2 + py2*py2 + pz2*pz2);
2780         if (p1 == 0 and p2 == 0) return true;
2781         if (fabs(p1 - p2) / ((p1 + p2)*0.5) > 0.5) return false;
2782         double denom = p1 * p2;
2783         if (denom == 0) return false;
2784         double angle = acos( (px1*px2 + py1*py2 + pz1*pz2) / denom );
2785         if (angle > 3.14159265358979323846 * 10. / 180.) return false;
2786         return true;
2787 }
2788
2789
2790 bool AliHLTMUONDataCheckerComponent::IsScalarTooLarge(
2791                 const AliHLTComponentBlockData* block,
2792                 AliHLTUInt32_t blockNumber,
2793                 const char* blockTypeName,
2794                 const char* scalarName,
2795                 AliHLTUInt32_t scalarValue,
2796                 AliHLTUInt32_t totalTrackCount
2797         ) const
2798 {
2799         /// Checks if the scalar value is larger than the number of Manso
2800         /// tracks in the event.
2801
2802         if (scalarValue > totalTrackCount)
2803         {
2804                 HLTError("Problem found with %s trigger decision"
2805                         " data block %d, fDataType = '%s', fPtr = %p and"
2806                         " fSize = %u bytes."
2807                         " Problem: The %s scalar with value %d is larger"
2808                         " than the total number of Manso tracks found for the"
2809                         " event (%d tracks).",
2810                         blockTypeName,
2811                         blockNumber,
2812                         DataType2Text(block->fDataType).c_str(),
2813                         block->fPtr,
2814                         block->fSize,
2815                         scalarName,
2816                         scalarValue,
2817                         totalTrackCount
2818                 );
2819                 return true;
2820         }
2821         else
2822         {
2823                 return false;
2824         }
2825 }
2826
2827
2828 bool AliHLTMUONDataCheckerComponent::IsScalarALargerThanB(
2829                 const AliHLTComponentBlockData* block,
2830                 AliHLTUInt32_t blockNumber,
2831                 const char* blockTypeName,
2832                 const char* scalarAName,
2833                 AliHLTUInt32_t scalarAValue,
2834                 const char* scalarBName,
2835                 AliHLTUInt32_t scalarBValue
2836         ) const
2837 {
2838         /// Checks if the scalar value is larger than the number of Manso
2839         /// tracks in the event.
2840
2841         if (scalarAValue > scalarBValue)
2842         {
2843                 HLTError("Problem found with %s trigger decision"
2844                         " data block %d, fDataType = '%s', fPtr = %p and"
2845                         " fSize = %u bytes."
2846                         " Problem: The %s scalar with value %d is larger"
2847                         " than scalar %s with value %d, but is should not be.",
2848                         blockTypeName,
2849                         blockNumber,
2850                         DataType2Text(block->fDataType).c_str(),
2851                         block->fPtr,
2852                         block->fSize,
2853                         scalarAName,
2854                         scalarAValue,
2855                         scalarBName,
2856                         scalarBValue
2857                 );
2858                 return true;
2859         }
2860         else
2861         {
2862                 return false;
2863         }
2864 }
2865
2866
2867 void AliHLTMUONDataCheckerComponent::MarkBlock(
2868                 const AliHLTComponentBlockData* blocks,
2869                 bool* blockOk,
2870                 AliHLTUInt32_t blockCount,
2871                 const AliHLTComponentBlockData* blockToMark
2872         ) const
2873 {
2874         /// Tries to find the 'blockToMark' in the list of blocks and sets the
2875         /// corresponding 'blockOk' flag to false.
2876         
2877         for (AliHLTUInt32_t i = 0; i < blockCount; i++)
2878         {
2879                 if (&blocks[i] == blockToMark)
2880                 {
2881                         blockOk[i] = false;
2882                         return;
2883                 }
2884         }
2885 }
2886
2887
2888 void AliHLTMUONDataCheckerComponent::MakeGlobalChecks(
2889                 const AliHLTComponentBlockData* blocks,
2890                 bool* blockOk,
2891                 AliHLTUInt32_t blockCount,
2892                 const AliHLTComponentBlockData** trigRecBlocks,
2893                 AliHLTUInt32_t trigRecBlocksCount,
2894                 const AliHLTComponentBlockData** trigRecDebugBlocks,
2895                 AliHLTUInt32_t trigRecDebugBlocksCount,
2896                 const AliHLTComponentBlockData** hitBlocks,
2897                 AliHLTUInt32_t hitBlocksCount,
2898                 const AliHLTComponentBlockData** clusterBlocks,
2899                 AliHLTUInt32_t clusterBlocksCount,
2900                 const AliHLTComponentBlockData** channelBlocks,
2901                 AliHLTUInt32_t channelBlocksCount,
2902                 const AliHLTComponentBlockData** mansoTrackBlocks,
2903                 AliHLTUInt32_t mansoTrackBlocksCount,
2904                 const AliHLTComponentBlockData** mansoCandidateBlocks,
2905                 AliHLTUInt32_t mansoCandidateBlocksCount,
2906                 const AliHLTComponentBlockData** singleDecisionBlocks,
2907                 AliHLTUInt32_t singleDecisionBlocksCount,
2908                 const AliHLTComponentBlockData** pairDecisionBlocks,
2909                 AliHLTUInt32_t pairDecisionBlocksCount
2910         ) const
2911 {
2912         /// The following set of global checks are performed:
2913         /// 1) Checks if all the ID numbers in all the blocks are unique.
2914         /// 2) Check if all the structures are unique up to their ID numbers,
2915         /// that it, make sure there are no structures with the same data but
2916         /// for a different ID number.
2917         /// 3) Check if the reference ID numbers are correct, i.e. are the
2918         /// trigger record ID numbers in the track structures found in any of
2919         /// the trigger record data blocks.
2920         /// 4) Do the number of channels claimed in the cluster correspond to
2921         /// the number of channel structures.
2922         /// 5) Check that the momentum vectors between the Manso tracks and
2923         /// the corresponding trigger record are compatible.
2924         /// 6) Check that the trigger decision scalars are reasonable.
2925         /// 7) Check that the detector element IDs are the same between rec
2926         /// hits and clusters / trigger record debug blocks.
2927         
2928         // Check if all the trigger record identifiers and data are unique.
2929         for (AliHLTUInt32_t bi = 0; bi < trigRecBlocksCount; bi++)
2930         {
2931                 AliHLTMUONTriggerRecordsBlockReader inblocki(trigRecBlocks[bi]->fPtr, trigRecBlocks[bi]->fSize);
2932                 if (not inblocki.BufferSizeOk()) continue;
2933                 for (AliHLTUInt32_t bj = bi+1; bj < trigRecBlocksCount; bj++)
2934                 {
2935                         AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
2936                         if (not inblockj.BufferSizeOk()) continue;
2937                         
2938                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2939                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2940                         {
2941                                 if (inblocki[i].fId == inblockj[j].fId)
2942                                 {
2943                                         HLTError("Problem found with trigger record data block %d,"
2944                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
2945                                                 " and trigger record data block %d,"
2946                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2947                                                 " Problem: Trigger record %d in block %d and entry"
2948                                                 " %d in block %d have the same identfier, but they"
2949                                                 " should be unique.",
2950                                                 bi,
2951                                                 DataType2Text(trigRecBlocks[bi]->fDataType).c_str(),
2952                                                 trigRecBlocks[bi]->fPtr,
2953                                                 trigRecBlocks[bi]->fSize,
2954                                                 bj,
2955                                                 DataType2Text(trigRecBlocks[bj]->fDataType).c_str(),
2956                                                 trigRecBlocks[bj]->fPtr,
2957                                                 trigRecBlocks[bj]->fSize,
2958                                                 bi, i,
2959                                                 bj, j
2960                                         );
2961                                         MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bi]);
2962                                         MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
2963                                 }
2964                                 
2965                                 AliHLTMUONTriggerRecordStruct a = inblocki[i];
2966                                 AliHLTMUONTriggerRecordStruct b = inblockj[j];
2967                                 a.fId = b.fId = -1;
2968                                 if (a == b)
2969                                 {
2970                                         HLTError("Problem found with trigger record data block %d,"
2971                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
2972                                                 " and trigger record data block %d,"
2973                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2974                                                 " Problem: Trigger record %d in block %d and entry"
2975                                                 " %d in block %d have the same data."
2976                                                 " The data may have been duplicated.",
2977                                                 bi,
2978                                                 DataType2Text(trigRecBlocks[bi]->fDataType).c_str(),
2979                                                 trigRecBlocks[bi]->fPtr,
2980                                                 trigRecBlocks[bi]->fSize,
2981                                                 bj,
2982                                                 DataType2Text(trigRecBlocks[bj]->fDataType).c_str(),
2983                                                 trigRecBlocks[bj]->fPtr,
2984                                                 trigRecBlocks[bj]->fSize,
2985                                                 bi, i,
2986                                                 bj, j
2987                                         );
2988                                         MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bi]);
2989                                         MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
2990                                 }
2991                         }
2992                 }
2993         }
2994         
2995         for (AliHLTUInt32_t bi = 0; bi < trigRecDebugBlocksCount; bi++)
2996         {
2997                 AliHLTMUONTrigRecsDebugBlockReader inblocki(trigRecDebugBlocks[bi]->fPtr, trigRecDebugBlocks[bi]->fSize);
2998                 if (not inblocki.BufferSizeOk()) continue;
2999                 
3000                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3001                 {
3002                         // Check if all the trigger record IDs in the debug information structures exist.
3003                         bool found = false;
3004                         
3005                         for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
3006                         {
3007                                 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
3008                                 if (not inblockj.BufferSizeOk()) continue;
3009                                 
3010                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3011                                 {
3012                                         if (inblocki[i].fTrigRecId == inblockj[j].fId)
3013                                         {
3014                                                 found = true;
3015                                                 
3016                                                 // Since we found the corresponding trigger record,
3017                                                 // check if the detector element IDs are the same.
3018                                                 bool deOk = CheckDetElemIds(
3019                                                                 *trigRecDebugBlocks[bi], bi, i, inblocki[i],
3020                                                                 *trigRecBlocks[bj], bj, j, inblockj[j]
3021                                                         );
3022                                                 if (not deOk)
3023                                                 {
3024                                                         MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
3025                                                         MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
3026                                                 }
3027                                                 
3028                                                 break;
3029                                         }
3030                                 }
3031                         }
3032                         
3033                         if (not found)
3034                         {
3035                                 HLTError("Problem found with trigger record debug information"
3036                                         " data block %d, fDataType = '%s', fPtr = %p and"
3037                                         " fSize = %u bytes."
3038                                         " Problem with entry %d in block: The trigger record"
3039                                         " identifier %d does not exist in any trigger record"
3040                                         " data block.",
3041                                         bi,
3042                                         DataType2Text(trigRecDebugBlocks[bi]->fDataType).c_str(),
3043                                         trigRecDebugBlocks[bi]->fPtr,
3044                                         trigRecDebugBlocks[bi]->fSize,
3045                                         i, inblocki[i].fTrigRecId
3046                                 );
3047                                 MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
3048                         }
3049                 }
3050                 
3051                 // Check if all the trigger record debug information structures are unique.
3052                 for (AliHLTUInt32_t bj = bi+1; bj < trigRecDebugBlocksCount; bj++)
3053                 {
3054                         AliHLTMUONTrigRecsDebugBlockReader inblockj(trigRecDebugBlocks[bj]->fPtr, trigRecDebugBlocks[bj]->fSize);
3055                         if (not inblockj.BufferSizeOk()) continue;
3056                         
3057                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3058                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3059                         {
3060                                 AliHLTMUONTrigRecInfoStruct a = inblocki[i];
3061                                 AliHLTMUONTrigRecInfoStruct b = inblockj[j];
3062                                 a.fTrigRecId = b.fTrigRecId = -1;
3063                                 if (a == b)
3064                                 {
3065                                         HLTError("Problem found with trigger record debug information"
3066                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3067                                                 " fSize = %u bytes, and trigger record debug"
3068                                                 " information data block %d,"
3069                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3070                                                 " Problem: The trigger record debug inforamtion"
3071                                                 " structure %d in block %d and entry"
3072                                                 " %d in block %d have the same data."
3073                                                 " The data may have been duplicated.",
3074                                                 bi,
3075                                                 DataType2Text(trigRecDebugBlocks[bi]->fDataType).c_str(),
3076                                                 trigRecDebugBlocks[bi]->fPtr,
3077                                                 trigRecDebugBlocks[bi]->fSize,
3078                                                 bj,
3079                                                 DataType2Text(trigRecDebugBlocks[bj]->fDataType).c_str(),
3080                                                 trigRecDebugBlocks[bj]->fPtr,
3081                                                 trigRecDebugBlocks[bj]->fSize,
3082                                                 bi, i,
3083                                                 bj, j
3084                                         );
3085                                         MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
3086                                         MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bj]);
3087                                 }
3088                         }
3089                 }
3090         }
3091         
3092         // Check that all the reconstructed hits are unique.
3093         for (AliHLTUInt32_t bi = 0; bi < hitBlocksCount; bi++)
3094         {
3095                 AliHLTMUONRecHitsBlockReader inblocki(hitBlocks[bi]->fPtr, hitBlocks[bi]->fSize);
3096                 if (not inblocki.BufferSizeOk()) continue;
3097                 for (AliHLTUInt32_t bj = bi+1; bj < hitBlocksCount; bj++)
3098                 {
3099                         AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3100                         if (not inblockj.BufferSizeOk()) continue;
3101                         
3102                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3103                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3104                         {
3105                                 if (inblocki[i] == inblockj[j])
3106                                 {
3107                                         HLTError("Problem found with reconstructed hit data block %d,"
3108                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
3109                                                 " and reconstructed hit data block %d,"
3110                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3111                                                 " Problem: Reconstructed hit %d in block %d and entry"
3112                                                 " %d in block %d are the same, but all hits"
3113                                                 " should be unique.",
3114                                                 bi,
3115                                                 DataType2Text(hitBlocks[bi]->fDataType).c_str(),
3116                                                 hitBlocks[bi]->fPtr,
3117                                                 hitBlocks[bi]->fSize,
3118                                                 bj,
3119                                                 DataType2Text(hitBlocks[bj]->fDataType).c_str(),
3120                                                 hitBlocks[bj]->fPtr,
3121                                                 hitBlocks[bj]->fSize,
3122                                                 bi, i,
3123                                                 bj, j
3124                                         );
3125                                         MarkBlock(blocks, blockOk, blockCount, hitBlocks[bi]);
3126                                         MarkBlock(blocks, blockOk, blockCount, hitBlocks[bj]);
3127                                 }
3128                         }
3129                 }
3130         }
3131         
3132         for (AliHLTUInt32_t bi = 0; bi < clusterBlocksCount; bi++)
3133         {
3134                 AliHLTMUONClustersBlockReader inblocki(clusterBlocks[bi]->fPtr, clusterBlocks[bi]->fSize);
3135                 if (not inblocki.BufferSizeOk()) continue;
3136                 
3137                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3138                 {
3139                         // Check if all the reconstructed hit coordinates in the cluster structures exist.
3140                         bool found = false;
3141                         
3142                         for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
3143                         {
3144                                 AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3145                                 if (not inblockj.BufferSizeOk()) continue;
3146                                 
3147                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3148                                 {
3149                                         if (inblocki[i].fHit == inblockj[j])
3150                                         {
3151                                                 found = true;
3152                                                 
3153                                                 // Since we found the corresponding cluster,
3154                                                 // check if the detector element IDs are the same.
3155                                                 bool deOk = CheckDetElemIds(
3156                                                                 *clusterBlocks[bi], bi, i, inblocki[i],
3157                                                                 *hitBlocks[bj], bj, j, inblockj[j]
3158                                                         );
3159                                                 if (not deOk)
3160                                                 {
3161                                                         MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3162                                                         MarkBlock(blocks, blockOk, blockCount, hitBlocks[bj]);
3163                                                 }
3164                                                 
3165                                                 break;
3166                                         }
3167                                 }
3168                         }
3169                         
3170                         // If the hit was not found then it should be nil.
3171                         if (not found and (inblocki[i].fHit != AliHLTMUONConstants::NilRecHitStruct()))
3172                         {
3173                                 HLTError("Problem found with cluster data block %d,"
3174                                         " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3175                                         " Problem with entry %d in block: The cluster hit"
3176                                         " coordinate {x = %f, y = %f, z = %f} does not exist"
3177                                         " in any reconstructed hit data block.",
3178                                         bi,
3179                                         DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3180                                         clusterBlocks[bi]->fPtr,
3181                                         clusterBlocks[bi]->fSize,
3182                                         i,
3183                                         inblocki[i].fHit.fX,
3184                                         inblocki[i].fHit.fY,
3185                                         inblocki[i].fHit.fZ
3186                                 );
3187                                 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3188                         }
3189                         
3190                         // Check that the fNchannels value is correct.
3191                         AliHLTUInt32_t count = 0;
3192                         for (AliHLTUInt32_t bj = 0; bj < channelBlocksCount and not found; bj++)
3193                         {
3194                                 AliHLTMUONChannelsBlockReader inblockj(channelBlocks[bj]->fPtr, channelBlocks[bj]->fSize);
3195                                 if (not inblockj.BufferSizeOk()) continue;
3196                                 
3197                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3198                                 {
3199                                         if (inblocki[i].fId == inblockj[j].fClusterId)
3200                                         {
3201                                                 count++;
3202                                         }
3203                                 }
3204                         }
3205                         
3206                         if (inblocki[i].fNchannels != count)
3207                         {
3208                                 HLTError("Problem found with cluster data block %d,"
3209                                         " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3210                                         " Problem with entry %d in block: The number of"
3211                                         " channels in the cluster is reported as %d, but"
3212                                         " only %d channel structures were found.",
3213                                         bi,
3214                                         DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3215                                         clusterBlocks[bi]->fPtr,
3216                                         clusterBlocks[bi]->fSize,
3217                                         i,
3218                                         inblocki[i].fNchannels,
3219                                         count
3220                                 );
3221                                 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3222                         }
3223                 }
3224                 
3225                 // Check if all the cluster structures are unique up to the identifier
3226                 // and have unique identifiers.
3227                 for (AliHLTUInt32_t bj = bi+1; bj < clusterBlocksCount; bj++)
3228                 {
3229                         AliHLTMUONClustersBlockReader inblockj(clusterBlocks[bj]->fPtr, clusterBlocks[bj]->fSize);
3230                         if (not inblockj.BufferSizeOk()) continue;
3231                         
3232                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3233                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3234                         {
3235                                 if (inblocki[i].fId == inblockj[j].fId)
3236                                 {
3237                                         HLTError("Problem found with cluster"
3238                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3239                                                 " fSize = %u bytes, and cluster data block %d,"
3240                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3241                                                 " Problem: The cluster %d in block %d and entry"
3242                                                 " %d in block %d have the same identifier, but they"
3243                                                 " should be unique.",
3244                                                 bi,
3245                                                 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3246                                                 clusterBlocks[bi]->fPtr,
3247                                                 clusterBlocks[bi]->fSize,
3248                                                 bj,
3249                                                 DataType2Text(clusterBlocks[bj]->fDataType).c_str(),
3250                                                 clusterBlocks[bj]->fPtr,
3251                                                 clusterBlocks[bj]->fSize,
3252                                                 bi, i,
3253                                                 bj, j
3254                                         );
3255                                         MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3256                                         MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bj]);
3257                                 }
3258                                 
3259                                 AliHLTMUONClusterStruct a = inblocki[i];
3260                                 AliHLTMUONClusterStruct b = inblockj[j];
3261                                 a.fId = b.fId = -1;
3262                                 if (a == b)
3263                                 {
3264                                         HLTError("Problem found with cluster"
3265                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3266                                                 " fSize = %u bytes, and cluster data block %d,"
3267                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3268                                                 " Problem: The cluster %d in block %d and entry"
3269                                                 " %d in block %d have the same data."
3270                                                 " The data may have been duplicated.",
3271                                                 bi,
3272                                                 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3273                                                 clusterBlocks[bi]->fPtr,
3274                                                 clusterBlocks[bi]->fSize,
3275                                                 bj,
3276                                                 DataType2Text(clusterBlocks[bj]->fDataType).c_str(),
3277                                                 clusterBlocks[bj]->fPtr,
3278                                                 clusterBlocks[bj]->fSize,
3279                                                 bi, i,
3280                                                 bj, j
3281                                         );
3282                                         MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3283                                         MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bj]);
3284                                 }
3285                         }
3286                 }
3287         }
3288         
3289         for (AliHLTUInt32_t bi = 0; bi < channelBlocksCount; bi++)
3290         {
3291                 AliHLTMUONChannelsBlockReader inblocki(channelBlocks[bi]->fPtr, channelBlocks[bi]->fSize);
3292                 if (not inblocki.BufferSizeOk()) continue;
3293                 
3294                 // Check if all the cluster IDs in the channel structures exist.
3295                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3296                 {
3297                         bool found = false;
3298                         
3299                         for (AliHLTUInt32_t bj = 0; bj < clusterBlocksCount and not found; bj++)
3300                         {
3301                                 AliHLTMUONClustersBlockReader inblockj(clusterBlocks[bj]->fPtr, clusterBlocks[bj]->fSize);
3302                                 if (not inblockj.BufferSizeOk()) continue;
3303                                 
3304                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3305                                 {
3306                                         if (inblocki[i].fClusterId == inblockj[j].fId)
3307                                         {
3308                                                 found = true;
3309                                                 break;
3310                                         }
3311                                 }
3312                         }
3313                         
3314                         if (not found)
3315                         {
3316                                 HLTError("Problem found with channel"
3317                                         " data block %d, fDataType = '%s', fPtr = %p and"
3318                                         " fSize = %u bytes."
3319                                         " Problem with entry %d in block: The cluster"
3320                                         " identifier %d does not exist in any cluster"
3321                                         " data block.",
3322                                         bi,
3323                                         DataType2Text(channelBlocks[bi]->fDataType).c_str(),
3324                                         channelBlocks[bi]->fPtr,
3325                                         channelBlocks[bi]->fSize,
3326                                         i, inblocki[i].fClusterId
3327                                 );
3328                                 MarkBlock(blocks, blockOk, blockCount, channelBlocks[bi]);
3329                         }
3330                 }
3331                 
3332                 // Check if all the channel structures are unique up to the cluster ID.
3333                 for (AliHLTUInt32_t bj = bi+1; bj < channelBlocksCount; bj++)
3334                 {
3335                         AliHLTMUONChannelsBlockReader inblockj(channelBlocks[bj]->fPtr, channelBlocks[bj]->fSize);
3336                         if (not inblockj.BufferSizeOk()) continue;
3337                         
3338                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3339                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3340                         {
3341                                 AliHLTMUONChannelStruct a = inblocki[i];
3342                                 AliHLTMUONChannelStruct b = inblockj[j];
3343                                 a.fClusterId = b.fClusterId = -1;
3344                                 if (a == b)
3345                                 {
3346                                         HLTError("Problem found with channel"
3347                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3348                                                 " fSize = %u bytes, and channel data block %d,"
3349                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3350                                                 " Problem: The channel %d in block %d and entry"
3351                                                 " %d in block %d have the same data."
3352                                                 " The data may have been duplicated.",
3353                                                 bi,
3354                                                 DataType2Text(channelBlocks[bi]->fDataType).c_str(),
3355                                                 channelBlocks[bi]->fPtr,
3356                                                 channelBlocks[bi]->fSize,
3357                                                 bj,
3358                                                 DataType2Text(channelBlocks[bj]->fDataType).c_str(),
3359                                                 channelBlocks[bj]->fPtr,
3360                                                 channelBlocks[bj]->fSize,
3361                                                 bi, i,
3362                                                 bj, j
3363                                         );
3364                                         MarkBlock(blocks, blockOk, blockCount, channelBlocks[bi]);
3365                                         MarkBlock(blocks, blockOk, blockCount, channelBlocks[bj]);
3366                                 }
3367                         }
3368                 }
3369         }
3370         
3371         // Will need the total number of tracks later for comparison to trigger scalars.
3372         AliHLTUInt32_t totalTrackCount = 0;
3373         
3374         for (AliHLTUInt32_t bi = 0; bi < mansoTrackBlocksCount; bi++)
3375         {
3376                 AliHLTMUONMansoTracksBlockReader inblocki(mansoTrackBlocks[bi]->fPtr, mansoTrackBlocks[bi]->fSize);
3377                 if (not inblocki.BufferSizeOk()) continue;
3378                 
3379                 totalTrackCount += inblocki.Nentries();
3380                 
3381                 // Check if all the trigger record IDs in the Manso track structures exist.
3382                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3383                 {
3384                         bool found = false;
3385                         
3386                         for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
3387                         {
3388                                 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
3389                                 if (not inblockj.BufferSizeOk()) continue;
3390                                 
3391                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3392                                 {
3393                                         if (inblocki[i].fTrigRec == inblockj[j].fId)
3394                                         {
3395                                                 // At this point we can check if the momentum
3396                                                 // is compatible with the trigger record.
3397                                                 if (not AreMomentaCompatible(
3398                                                                 inblocki[i].fPx, inblocki[i].fPy, inblocki[i].fPz,
3399                                                                 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3400                                                         )
3401                                                    )
3402                                                 {
3403                                                         HLTWarning("Problem found with Manso track"
3404                                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3405                                                                 " fSize = %u bytes."
3406                                                                 " Problem with Manso track %d in block: The momentum"
3407                                                                 " vector of the track p = {%f, %f, %f} GeV/c is not"
3408                                                                 " compatible with the momentum vector of the trigger"
3409                                                                 " record with p = {%f, %f, %f} GeV/c.",
3410                                                                 bi,
3411                                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3412                                                                 mansoTrackBlocks[bi]->fPtr,
3413                                                                 mansoTrackBlocks[bi]->fSize,
3414                                                                 i, inblocki[i].fPx, inblocki[i].fPy, inblocki[i].fPz,
3415                                                                 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3416                                                         );
3417                                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3418                                                 }
3419                                                 
3420                                                 found = true;
3421                                                 break;
3422                                         }
3423                                 }
3424                         }
3425                         
3426                         if (not found)
3427                         {
3428                                 HLTError("Problem found with Manso track"
3429                                         " data block %d, fDataType = '%s', fPtr = %p and"
3430                                         " fSize = %u bytes."
3431                                         " Problem with Manso track %d in block: The trigger"
3432                                         " record identifier %d does not exist in any trigger"
3433                                         " record data block.",
3434                                         bi,
3435                                         DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3436                                         mansoTrackBlocks[bi]->fPtr,
3437                                         mansoTrackBlocks[bi]->fSize,
3438                                         i, inblocki[i].fTrigRec
3439                                 );
3440                                 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3441                         }
3442                 }
3443                 
3444                 // Check if all the hits in the Manso track structures exist.
3445                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3446                 {
3447                         AliHLTMUONParticleSign sign;
3448                         bool hitset[4];
3449                         AliHLTMUONUtils::UnpackMansoTrackFlags(inblocki[i].fFlags, sign, hitset);
3450                         
3451                         for (AliHLTUInt32_t n = 0; n < 4; n++)
3452                         {
3453                                 if (not hitset[n]) continue;
3454                                 bool found = false;
3455                                 
3456                                 for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
3457                                 {
3458                                         AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3459                                         if (not inblockj.BufferSizeOk()) continue;
3460                                         
3461                                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3462                                         {
3463                                                 if (inblocki[i].fHit[n] == inblockj[j])
3464                                                 {
3465                                                         found = true;
3466                                                         break;
3467                                                 }
3468                                         }
3469                                 }
3470                                 
3471                                 if (not found)
3472                                 {
3473                                         HLTError("Problem found with Manso track"
3474                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3475                                                 " fSize = %u bytes."
3476                                                 " Problem with Manso track %d in block: The hit"
3477                                                 " for chamber %d does not exist in any"
3478                                                 " reconstructed hits data block.",
3479                                                 bi,
3480                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3481                                                 mansoTrackBlocks[bi]->fPtr,
3482                                                 mansoTrackBlocks[bi]->fSize,
3483                                                 i, n+6+1
3484                                         );
3485                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3486                                 }
3487                         }
3488                 }
3489                 
3490                 // Check if all the Manso track structures are unique up to the ID and
3491                 // have unique identifiers.
3492                 for (AliHLTUInt32_t bj = bi+1; bj < mansoTrackBlocksCount; bj++)
3493                 {
3494                         AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3495                         if (not inblockj.BufferSizeOk()) continue;
3496                         
3497                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3498                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3499                         {
3500                                 if (inblocki[i].fId == inblockj[j].fId)
3501                                 {
3502                                         HLTError("Problem found with Manso track"
3503                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3504                                                 " fSize = %u bytes, and Manso track data block %d,"
3505                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3506                                                 " Problem: The Manso track %d in block %d and entry"
3507                                                 " %d in block %d have the same identifier, but they"
3508                                                 " should be unique.",
3509                                                 bi,
3510                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3511                                                 mansoTrackBlocks[bi]->fPtr,
3512                                                 mansoTrackBlocks[bi]->fSize,
3513                                                 bj,
3514                                                 DataType2Text(mansoTrackBlocks[bj]->fDataType).c_str(),
3515                                                 mansoTrackBlocks[bj]->fPtr,
3516                                                 mansoTrackBlocks[bj]->fSize,
3517                                                 bi, i,
3518                                                 bj, j
3519                                         );
3520                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3521                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bj]);
3522                                 }
3523                                 
3524                                 AliHLTMUONMansoTrackStruct a = inblocki[i];
3525                                 AliHLTMUONMansoTrackStruct b = inblockj[j];
3526                                 a.fId = b.fId = -1;
3527                                 if (a == b)
3528                                 {
3529                                         HLTError("Problem found with Manso track"
3530                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3531                                                 " fSize = %u bytes, and Manso track data block %d,"
3532                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3533                                                 " Problem: The Manso track %d in block %d and entry"
3534                                                 " %d in block %d have the same data."
3535                                                 " The data may have been duplicated.",
3536                                                 bi,
3537                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3538                                                 mansoTrackBlocks[bi]->fPtr,
3539                                                 mansoTrackBlocks[bi]->fSize,
3540                                                 bj,
3541                                                 DataType2Text(mansoTrackBlocks[bj]->fDataType).c_str(),
3542                                                 mansoTrackBlocks[bj]->fPtr,
3543                                                 mansoTrackBlocks[bj]->fSize,
3544                                                 bi, i,
3545                                                 bj, j
3546                                         );
3547                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3548                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bj]);
3549                                 }
3550                         }
3551                 }
3552         }
3553         
3554         for (AliHLTUInt32_t bi = 0; bi < mansoCandidateBlocksCount; bi++)
3555         {
3556                 AliHLTMUONMansoCandidatesBlockReader inblocki(mansoCandidateBlocks[bi]->fPtr, mansoCandidateBlocks[bi]->fSize);
3557                 if (not inblocki.BufferSizeOk()) continue;
3558                 
3559                 // Check if all the trigger record IDs in the Manso track candidate structures exist.
3560                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3561                 {
3562                         bool found = false;
3563                         
3564                         for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
3565                         {
3566                                 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
3567                                 if (not inblockj.BufferSizeOk()) continue;
3568                                 
3569                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3570                                 {
3571                                         if (inblocki[i].fTrack.fTrigRec == inblockj[j].fId)
3572                                         {
3573                                                 // At this point we can check if the momentum
3574                                                 // is compatible with the trigger record.
3575                                                 if (not AreMomentaCompatible(
3576                                                                 inblocki[i].fTrack.fPx, inblocki[i].fTrack.fPy, inblocki[i].fTrack.fPz,
3577                                                                 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3578                                                         )
3579                                                    )
3580                                                 {
3581                                                         HLTWarning("Problem found with Manso track candidate"
3582                                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3583                                                                 " fSize = %u bytes."
3584                                                                 " Problem with track candidate %d in block: The momentum"
3585                                                                 " vector of the candidate p = {%f, %f, %f} GeV/c is not"
3586                                                                 " compatible with the momentum vector of the trigger"
3587                                                                 " record with p = {%f, %f, %f} GeV/c.",
3588                                                                 bi,
3589                                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3590                                                                 mansoTrackBlocks[bi]->fPtr,
3591                                                                 mansoTrackBlocks[bi]->fSize,
3592                                                                 i,
3593                                                                 inblocki[i].fTrack.fPx, inblocki[i].fTrack.fPy, inblocki[i].fTrack.fPz,
3594                                                                 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3595                                                         );
3596                                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3597                                                 }
3598                                                 
3599                                                 found = true;
3600                                                 break;
3601                                         }
3602                                 }
3603                         }
3604                         
3605                         if (not found)
3606                         {
3607                                 HLTError("Problem found with Manso track candidate"
3608                                         " data block %d, fDataType = '%s', fPtr = %p and"
3609                                         " fSize = %u bytes."
3610                                         " Problem with track candidate %d in block: The trigger"
3611                                         " record identifier %d does not exist in any trigger"
3612                                         " record data block.",
3613                                         bi,
3614                                         DataType2Text(mansoCandidateBlocks[bi]->fDataType).c_str(),
3615                                         mansoCandidateBlocks[bi]->fPtr,
3616                                         mansoCandidateBlocks[bi]->fSize,
3617                                         i, inblocki[i].fTrack.fTrigRec
3618                                 );
3619                                 MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bi]);
3620                         }
3621                 }
3622                 
3623                 // Check if all the hits in the Manso track candidate structures exist.
3624                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3625                 {
3626                         AliHLTMUONParticleSign sign;
3627                         bool hitset[4];
3628                         AliHLTMUONUtils::UnpackMansoTrackFlags(inblocki[i].fTrack.fFlags, sign, hitset);
3629                         
3630                         for (AliHLTUInt32_t n = 0; n < 4; n++)
3631                         {
3632                                 if (not hitset[n]) continue;
3633                                 bool found = false;
3634                                 
3635                                 for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
3636                                 {
3637                                         AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3638                                         if (not inblockj.BufferSizeOk()) continue;
3639                                         
3640                                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3641                                         {
3642                                                 if (inblocki[i].fTrack.fHit[n] == inblockj[j])
3643                                                 {
3644                                                         found = true;
3645                                                         break;
3646                                                 }
3647                                         }
3648                                 }
3649                                 
3650                                 if (not found)
3651                                 {
3652                                         HLTError("Problem found with Manso track candidate"
3653                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3654                                                 " fSize = %u bytes."
3655                                                 " Problem with track candidate %d in block: The hit"
3656                                                 " for chamber %d does not exist in any"
3657                                                 " reconstructed hits data block.",
3658                                                 bi,
3659                                                 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3660                                                 mansoTrackBlocks[bi]->fPtr,
3661                                                 mansoTrackBlocks[bi]->fSize,
3662                                                 i, n+6+1
3663                                         );
3664                                         MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3665                                 }
3666                         }
3667                 }
3668                 
3669                 // Check if all the Manso track candidate structures are unique up to the
3670                 // track ID and have unique identifiers.
3671                 for (AliHLTUInt32_t bj = bi+1; bj < mansoCandidateBlocksCount; bj++)
3672                 {
3673                         AliHLTMUONMansoCandidatesBlockReader inblockj(mansoCandidateBlocks[bj]->fPtr, mansoCandidateBlocks[bj]->fSize);
3674                         if (not inblockj.BufferSizeOk()) continue;
3675                         
3676                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3677                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3678                         {
3679                                 if (inblocki[i].fTrack.fId == inblockj[j].fTrack.fId)
3680                                 {
3681                                         HLTError("Problem found with Manso track candidate"
3682                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3683                                                 " fSize = %u bytes, and Manso track candidate data block %d,"
3684                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3685                                                 " Problem: The track candidate %d in block %d and entry"
3686                                                 " %d in block %d have the same identifier, but they"
3687                                                 " should be unique.",
3688                                                 bi,
3689                                                 DataType2Text(mansoCandidateBlocks[bi]->fDataType).c_str(),
3690                                                 mansoCandidateBlocks[bi]->fPtr,
3691                                                 mansoCandidateBlocks[bi]->fSize,
3692                                                 bj,
3693                                                 DataType2Text(mansoCandidateBlocks[bj]->fDataType).c_str(),
3694                                                 mansoCandidateBlocks[bj]->fPtr,
3695                                                 mansoCandidateBlocks[bj]->fSize,
3696                                                 bi, i,
3697                                                 bj, j
3698                                         );
3699                                         MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bi]);
3700                                         MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bj]);
3701                                 }
3702                                 
3703                                 AliHLTMUONMansoCandidateStruct a = inblocki[i];
3704                                 AliHLTMUONMansoCandidateStruct b = inblockj[j];
3705                                 a.fTrack.fId = b.fTrack.fId = -1;
3706                                 if (a == b)
3707                                 {
3708                                         HLTError("Problem found with Manso track candidate"
3709                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3710                                                 " fSize = %u bytes, and Manso track candidate data block %d,"
3711                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3712                                                 " Problem: The track candidate %d in block %d and entry"
3713                                                 " %d in block %d have the same data."
3714                                                 " The data may have been duplicated.",
3715                                                 bi,
3716                                                 DataType2Text(mansoCandidateBlocks[bi]->fDataType).c_str(),
3717                                                 mansoCandidateBlocks[bi]->fPtr,
3718                                                 mansoCandidateBlocks[bi]->fSize,
3719                                                 bj,
3720                                                 DataType2Text(mansoCandidateBlocks[bj]->fDataType).c_str(),
3721                                                 mansoCandidateBlocks[bj]->fPtr,
3722                                                 mansoCandidateBlocks[bj]->fSize,
3723                                                 bi, i,
3724                                                 bj, j
3725                                         );
3726                                         MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bi]);
3727                                         MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bj]);
3728                                 }
3729                         }
3730                 }
3731         }
3732         
3733         for (AliHLTUInt32_t bi = 0; bi < singleDecisionBlocksCount; bi++)
3734         {
3735                 AliHLTMUONSinglesDecisionBlockReader inblocki(singleDecisionBlocks[bi]->fPtr, singleDecisionBlocks[bi]->fSize);
3736                 if (not inblocki.BufferSizeOk()) continue;
3737                 
3738                 // Check that the scalars are within reasonable limits.
3739                 const AliHLTMUONSinglesDecisionBlockStruct& hdr = inblocki.BlockHeader();
3740                 const AliHLTComponentBlockData* block = singleDecisionBlocks[bi];
3741                 if (IsScalarTooLarge(block, bi, "single track", "fNlowPt", hdr.fNlowPt, totalTrackCount) or
3742                     IsScalarTooLarge(block, bi, "single track", "fNhighPt", hdr.fNhighPt, totalTrackCount) or
3743                     IsScalarALargerThanB(block, bi, "single track", "fNlowPt", hdr.fNlowPt, "fNhighPt", hdr.fNhighPt)
3744                    )
3745                 {
3746                         MarkBlock(blocks, blockOk, blockCount, block);
3747                 }
3748                 
3749                 // Check if all the Manso track IDs in the trigger decision structures exist.
3750                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3751                 {
3752                         bool found = false;
3753                         
3754                         for (AliHLTUInt32_t bj = 0; bj < mansoTrackBlocksCount and not found; bj++)
3755                         {
3756                                 AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3757                                 if (not inblockj.BufferSizeOk()) continue;
3758                                 
3759                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3760                                 {
3761                                         if (inblocki[i].fTrackId == inblockj[j].fId)
3762                                         {
3763                                                 found = true;
3764                                                 break;
3765                                         }
3766                                 }
3767                         }
3768                         
3769                         if (not found)
3770                         {
3771                                 HLTError("Problem found with single track trigger decision"
3772                                         " data block %d, fDataType = '%s', fPtr = %p and"
3773                                         " fSize = %u bytes."
3774                                         " Problem with decision %d in block: The track"
3775                                         " identifier %d does not exist in any Manso tracks"
3776                                         " data block.",
3777                                         bi,
3778                                         DataType2Text(singleDecisionBlocks[bi]->fDataType).c_str(),
3779                                         singleDecisionBlocks[bi]->fPtr,
3780                                         singleDecisionBlocks[bi]->fSize,
3781                                         i, inblocki[i].fTrackId
3782                                 );
3783                                 MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bi]);
3784                         }
3785                 }
3786                 
3787                 // Check if all the trigger decision structures are unique up to the ID and
3788                 // have unique Manso track identifiers.
3789                 for (AliHLTUInt32_t bj = bi+1; bj < singleDecisionBlocksCount; bj++)
3790                 {
3791                         AliHLTMUONSinglesDecisionBlockReader inblockj(singleDecisionBlocks[bj]->fPtr, singleDecisionBlocks[bj]->fSize);
3792                         if (not inblockj.BufferSizeOk()) continue;
3793                         
3794                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3795                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3796                         {
3797                                 if (inblocki[i].fTrackId == inblockj[j].fTrackId)
3798                                 {
3799                                         HLTError("Problem found with single track trigger decision"
3800                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3801                                                 " fSize = %u bytes, and single track trigger decision"
3802                                                 " data block %d,"
3803                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3804                                                 " Problem: The trigger decision %d in block %d and entry"
3805                                                 " %d in block %d have the same Manso track identifier,"
3806                                                 " but they should be unique.",
3807                                                 bi,
3808                                                 DataType2Text(singleDecisionBlocks[bi]->fDataType).c_str(),
3809                                                 singleDecisionBlocks[bi]->fPtr,
3810                                                 singleDecisionBlocks[bi]->fSize,
3811                                                 bj,
3812                                                 DataType2Text(singleDecisionBlocks[bj]->fDataType).c_str(),
3813                                                 singleDecisionBlocks[bj]->fPtr,
3814                                                 singleDecisionBlocks[bj]->fSize,
3815                                                 bi, i,
3816                                                 bj, j
3817                                         );
3818                                         MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bi]);
3819                                         MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bj]);
3820                                 }
3821                                 
3822                                 AliHLTMUONTrackDecisionStruct a = inblocki[i];
3823                                 AliHLTMUONTrackDecisionStruct b = inblockj[j];
3824                                 a.fTrackId = b.fTrackId = -1;
3825                                 if (a == b)
3826                                 {
3827                                         HLTError("Problem found with single track trigger decision"
3828                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3829                                                 " fSize = %u bytes, and single track trigger decision"
3830                                                 " data block %d,"
3831                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3832                                                 " Problem: The trigger decision %d in block %d and entry"
3833                                                 " %d in block %d have the same data."
3834                                                 " The data may have been duplicated.",
3835                                                 bi,
3836                                                 DataType2Text(singleDecisionBlocks[bi]->fDataType).c_str(),
3837                                                 singleDecisionBlocks[bi]->fPtr,
3838                                                 singleDecisionBlocks[bi]->fSize,
3839                                                 bj,
3840                                                 DataType2Text(singleDecisionBlocks[bj]->fDataType).c_str(),
3841                                                 singleDecisionBlocks[bj]->fPtr,
3842                                                 singleDecisionBlocks[bj]->fSize,
3843                                                 bi, i,
3844                                                 bj, j
3845                                         );
3846                                         MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bi]);
3847                                         MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bj]);
3848                                 }
3849                         }
3850                 }
3851         }
3852         
3853         for (AliHLTUInt32_t bi = 0; bi < pairDecisionBlocksCount; bi++)
3854         {
3855                 AliHLTMUONPairsDecisionBlockReader inblocki(pairDecisionBlocks[bi]->fPtr, pairDecisionBlocks[bi]->fSize);
3856                 if (not inblocki.BufferSizeOk()) continue;
3857                 
3858                 AliHLTUInt32_t maxPairs = totalTrackCount * (totalTrackCount-1) / 2;
3859                 const AliHLTMUONPairsDecisionBlockStruct& hdr = inblocki.BlockHeader();
3860                 const AliHLTComponentBlockData* block = pairDecisionBlocks[bi];
3861                 if (IsScalarTooLarge(block, bi, "track pair", "fNunlikeAnyPt", hdr.fNunlikeAnyPt, maxPairs) or
3862                     IsScalarTooLarge(block, bi, "track pair", "fNunlikeLowPt", hdr.fNunlikeLowPt, maxPairs) or
3863                     IsScalarTooLarge(block, bi, "track pair", "fNunlikeHighPt", hdr.fNunlikeHighPt, maxPairs) or
3864                     IsScalarTooLarge(block, bi, "track pair", "fNlikeAnyPt", hdr.fNlikeAnyPt, maxPairs) or
3865                     IsScalarTooLarge(block, bi, "track pair", "fNlikeLowPt", hdr.fNlikeLowPt, maxPairs) or
3866                     IsScalarTooLarge(block, bi, "track pair", "fNlikeHighPt", hdr.fNlikeHighPt, maxPairs) or
3867                     IsScalarTooLarge(block, bi, "track pair", "fNmassAny", hdr.fNmassAny, maxPairs) or
3868                     IsScalarTooLarge(block, bi, "track pair", "fNmassLow", hdr.fNmassLow, maxPairs) or
3869                     IsScalarTooLarge(block, bi, "track pair", "fNmassHigh", hdr.fNmassHigh, maxPairs) or
3870                     IsScalarALargerThanB(block, bi, "track pair", "fNunlikeLowPt", hdr.fNunlikeLowPt, "fNunlikeHighPt", hdr.fNunlikeHighPt) or
3871                     IsScalarALargerThanB(block, bi, "track pair", "fNunlikeAnyPt", hdr.fNunlikeAnyPt, "fNunlikeLowPt", hdr.fNunlikeLowPt) or
3872                     IsScalarALargerThanB(block, bi, "track pair", "fNlikeLowPt", hdr.fNlikeLowPt, "fNlikeHighPt", hdr.fNlikeHighPt) or
3873                     IsScalarALargerThanB(block, bi, "track pair", "fNlikeAnyPt", hdr.fNlikeAnyPt, "fNlikeLowPt", hdr.fNlikeLowPt) or
3874                     IsScalarALargerThanB(block, bi, "track pair", "fNmassLow", hdr.fNmassLow, "fNmassHigh", hdr.fNmassHigh) or
3875                     IsScalarALargerThanB(block, bi, "track pair", "fNmassAny", hdr.fNmassAny, "fNmassLow", hdr.fNmassLow)
3876                    )
3877                 {
3878                         MarkBlock(blocks, blockOk, blockCount, block);
3879                 }
3880                 
3881                 // Check if all the Manso track IDs in the trigger decision structures exist.
3882                 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3883                 {
3884                         bool found = false;
3885                         
3886                         for (AliHLTUInt32_t bj = 0; bj < mansoTrackBlocksCount and not found; bj++)
3887                         {
3888                                 AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3889                                 if (not inblockj.BufferSizeOk()) continue;
3890                                 
3891                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3892                                 {
3893                                         if (inblocki[i].fTrackAId == inblockj[j].fId)
3894                                         {
3895                                                 found = true;
3896                                                 break;
3897                                         }
3898                                 }
3899                         }
3900                         
3901                         if (not found)
3902                         {
3903                                 HLTError("Problem found with track pair trigger decision"
3904                                         " data block %d, fDataType = '%s', fPtr = %p and"
3905                                         " fSize = %u bytes."
3906                                         " Problem with decision %d in block: The track"
3907                                         " identifier %d does not exist in any Manso tracks"
3908                                         " data block.",
3909                                         bi,
3910                                         DataType2Text(pairDecisionBlocks[bi]->fDataType).c_str(),
3911                                         pairDecisionBlocks[bi]->fPtr,
3912                                         pairDecisionBlocks[bi]->fSize,
3913                                         i, inblocki[i].fTrackAId
3914                                 );
3915                                 MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bi]);
3916                         }
3917                         
3918                         found = false;
3919                         
3920                         for (AliHLTUInt32_t bj = 0; bj < mansoTrackBlocksCount and not found; bj++)
3921                         {
3922                                 AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3923                                 if (not inblockj.BufferSizeOk()) continue;
3924                                 
3925                                 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3926                                 {
3927                                         if (inblocki[i].fTrackBId == inblockj[j].fId)
3928                                         {
3929                                                 found = true;
3930                                                 break;
3931                                         }
3932                                 }
3933                         }
3934                         
3935                         if (not found)
3936                         {
3937                                 HLTError("Problem found with track pair trigger decision"
3938                                         " data block %d, fDataType = '%s', fPtr = %p and"
3939                                         " fSize = %u bytes."
3940                                         " Problem with decision %d in block: The track"
3941                                         " identifier %d does not exist in any Manso tracks"
3942                                         " data block.",
3943                                         bi,
3944                                         DataType2Text(pairDecisionBlocks[bi]->fDataType).c_str(),
3945                                         pairDecisionBlocks[bi]->fPtr,
3946                                         pairDecisionBlocks[bi]->fSize,
3947                                         i, inblocki[i].fTrackBId
3948                                 );
3949                                 MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bi]);
3950                         }
3951                 }
3952                 
3953                 // Check if all the trigger decision structures are unique up to the ID and
3954                 // have unique Manso track identifier pairs.
3955                 for (AliHLTUInt32_t bj = bi+1; bj < pairDecisionBlocksCount; bj++)
3956                 {
3957                         AliHLTMUONPairsDecisionBlockReader inblockj(pairDecisionBlocks[bj]->fPtr, pairDecisionBlocks[bj]->fSize);
3958                         if (not inblockj.BufferSizeOk()) continue;
3959                         
3960                         for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3961                         for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3962                         {
3963                                 if (inblocki[i].fTrackAId == inblockj[j].fTrackAId and
3964                                     inblocki[i].fTrackBId == inblockj[j].fTrackBId
3965                                    )
3966                                 {
3967                                         HLTError("Problem found with track pair trigger decision"
3968                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3969                                                 " fSize = %u bytes, and track pair trigger decision"
3970                                                 " data block %d,"
3971                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3972                                                 " Problem: The trigger decision %d in block %d and entry"
3973                                                 " %d in block %d have the same Manso track identifier pair,"
3974                                                 " but the pair should be unique.",
3975                                                 bi,
3976                                                 DataType2Text(pairDecisionBlocks[bi]->fDataType).c_str(),
3977                                                 pairDecisionBlocks[bi]->fPtr,
3978                                                 pairDecisionBlocks[bi]->fSize,
3979                                                 bj,
3980                                                 DataType2Text(pairDecisionBlocks[bj]->fDataType).c_str(),
3981                                                 pairDecisionBlocks[bj]->fPtr,
3982                                                 pairDecisionBlocks[bj]->fSize,
3983                                                 bi, i,
3984                                                 bj, j
3985                                         );
3986                                         MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bi]);
3987                                         MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bj]);
3988                                 }
3989                                 
3990                                 AliHLTMUONPairDecisionStruct a = inblocki[i];
3991                                 AliHLTMUONPairDecisionStruct b = inblockj[j];
3992                                 a.fTrackAId = a.fTrackBId = b.fTrackAId = b.fTrackBId = -1;
3993                                 if (a == b)
3994                                 {
3995                                         HLTError("Problem found with track pair trigger decision"
3996                                                 " data block %d, fDataType = '%s', fPtr = %p and"
3997                                                 " fSize = %u bytes, and track pair trigger decision"
3998                                                 " data block %d,"
3999                                                 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
4000                                                 " Problem: The trigger decision %d in block %d and entry"
4001                                                 " %d in block %d have the same data."
4002                                                 " The data may have been duplicated.",
4003                                                 bi,
4004                                                 DataType2Text(pairDecisionBlocks[bi]->fDataType).c_str(),
4005                                                 pairDecisionBlocks[bi]->fPtr,
4006                                                 pairDecisionBlocks[bi]->fSize,
4007                                                 bj,
4008                                                 DataType2Text(pairDecisionBlocks[bj]->fDataType).c_str(),
4009                                                 pairDecisionBlocks[bj]->fPtr,
4010                                                 pairDecisionBlocks[bj]->fSize,
4011                                                 bi, i,
4012                                                 bj, j
4013                                         );
4014                                         MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bi]);
4015                                         MarkBlock(blocks, blockOk, blockCount, pairDecisionBlocks[bj]);
4016                                 }
4017                         }
4018                 }
4019         }
4020 }
4021