ALIROOT-5433 Transition to CDHv3 in HLT
[u/mrichter/AliRoot.git] / HLT / MUON / utils / AliHLTMUONDataCheckerComponent.cxx
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        *
3  * All rights reserved.                                                   *
4  *                                                                        *
5  * Primary Authors:                                                       *
6  *   Artur Szostak <artursz@iafrica.com>                                  *
7  *                                                                        *
8  * Permission to use, copy, modify and distribute this software and its   *
9  * documentation strictly for non-commercial purposes is hereby granted   *
10  * without fee, provided that the above copyright notice appears in all   *
11  * copies and that both the copyright notice and this permission notice   *
12  * appear in the supporting documentation. The authors make no claims     *
13  * about the suitability of this software for any purpose. It is          *
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16
17 // $Id: AliHLTMUONDataCheckerComponent.cxx 26179 2008-05-29 22:27:27Z aszostak $
18
19 ///
20 /// @file   AliHLTMUONDataCheckerComponent.cxx
21 /// @author Artur Szostak <artursz@iafrica.com>
22 /// @date   27 May 2008
23 /// @brief  Implementation of the dHLT data integrity checker component.
24 ///
25 /// This component is used to check the data integrity of dHLT raw internal data
26 /// blocks. If there are any problems found then an appropriate error message is
27 /// logged.
28 ///
29
30 #include "AliHLTMUONDataCheckerComponent.h"
31 #include "AliHLTMUONConstants.h"
32 #include "AliHLTLogging.h"
33 #include "AliHLTSystem.h"
34 #include "AliHLTDefinitions.h"
35 #include "AliRawDataHeader.h"
36 #include "AliHLTCDHWrapper.h"
37 #include "AliMUONConstants.h"
38 #include "AliMUONTrackerDDLDecoder.h"
39 #include "AliMUONTrackerDDLDecoderEventHandler.h"
40 #include "AliMUONTriggerDDLDecoder.h"
41 #include "AliMUONTriggerDDLDecoderEventHandler.h"
42 #include "AliMpDDLStore.h"
43 #include "AliMpDEStore.h"
44 #include "AliMpDEManager.h"
45 #include "AliMpBusPatch.h"
46 #include "AliMpDetElement.h"
47 #include "AliMpSegmentation.h"
48 #include "AliMpVSegmentation.h"
49 #include "AliMpPad.h"
50 #include <cstring>
51 #include <cstdlib>
52 #include <cmath>
53 #include <cerrno>
54 #include <cassert>
55
56
57 namespace
58 {
59         /**
60          * Routine to check if at least one corresponding DDL has been marked
61          * for a particular chamber.
62          */
63         bool ChamberMarkedInDDLList(AliHLTInt32_t chamber, bool ddl[22])
64         {
65                 if (chamber < 0 or chamber > 21) return false;
66                 switch (chamber)
67                 {
68                 case 0:  return ddl[0] or ddl[1];
69                 case 1:  return ddl[2] or ddl[3];
70                 case 2:  return ddl[4] or ddl[5];
71                 case 3:  return ddl[6] or ddl[7];
72                 case 4:  return ddl[8] or ddl[9] or ddl[10] or ddl[11];
73                 case 5:  return ddl[8] or ddl[9] or ddl[10] or ddl[11];
74                 case 6:  return ddl[12] or ddl[13];
75                 case 7:  return ddl[14] or ddl[15];
76                 case 8:  return ddl[16] or ddl[17];
77                 case 9:  return ddl[18] or ddl[19];
78                 case 10: return ddl[20] or ddl[21];
79                 case 11: return ddl[20] or ddl[21];
80                 case 12: return ddl[20] or ddl[21];
81                 case 13: return ddl[20] or ddl[21];
82                 default: return false;
83                 }
84         }
85
86 } // end of namespace
87
88
89 ClassImp(AliHLTMUONDataCheckerComponent)
90
91
92 AliHLTMUONDataCheckerComponent::AliHLTMUONDataCheckerComponent() :
93         AliHLTMUONProcessor(),
94         fIgnoreType(false),
95         fIgnoreSpec(false),
96         fDontForward(false),
97         fFilterBadBlocks(false),
98         fNoGlobalChecks(false),
99         fWarnForUnexpecedBlock(false),
100         fReturnError(false)
101 {
102         /// Default constructor.
103 }
104
105
106 AliHLTMUONDataCheckerComponent::~AliHLTMUONDataCheckerComponent()
107 {
108         /// Default destructor.
109 }
110
111 const char* AliHLTMUONDataCheckerComponent::GetComponentID()
112 {
113         /// Inherited from AliHLTComponent. Returns the component ID.
114         
115         return AliHLTMUONConstants::DataCheckerComponentId();
116 }
117
118
119 void AliHLTMUONDataCheckerComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
120 {
121         /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
122         /// At the moment this list is "any data type" origin MUON since it is not known
123         /// before hand what kind of input blocks we will get.
124         
125         assert( list.empty() );
126         list.push_back( kAliHLTAnyDataType | kAliHLTDataOriginMUON );
127 }
128
129
130 AliHLTComponentDataType AliHLTMUONDataCheckerComponent::GetOutputDataType()
131 {
132         /// Inherited from AliHLTComponent. Returns the output data type of
133         /// "any data type" with MUON origin.
134         
135         return kAliHLTAnyDataType | kAliHLTDataOriginMUON;
136 }
137
138
139 void AliHLTMUONDataCheckerComponent::GetOutputDataSize(
140                 unsigned long& constBase, double& inputMultiplier
141         )
142 {
143         /// Inherited from AliHLTComponent.
144         /// Returns an estimate of the expected output data size.
145         
146         // Both of these are zero because we will only ever pass on input data blocks
147         // and never generate data in this component.
148         constBase = 0;
149         inputMultiplier = 0;
150 }
151
152
153 AliHLTComponent* AliHLTMUONDataCheckerComponent::Spawn()
154 {
155         /// Inherited from AliHLTComponent. Creates a new object instance.
156         
157         return new AliHLTMUONDataCheckerComponent;
158 }
159
160
161 bool AliHLTMUONDataCheckerComponent::IgnoreArgument(const char* arg) const
162 {
163         /// Return true if the argument is -delaysetup
164         /// to prevent the parent class from parsing these arguments in DoInit.
165         
166         if (strcmp(arg, "-delaysetup") == 0)
167         {
168                 return true;
169         }
170         else
171         {
172                 return false;
173         }
174 }
175
176
177 int AliHLTMUONDataCheckerComponent::DoInit(int argc, const char** argv)
178 {
179         /// Inherited from AliHLTComponent.
180         /// Parses the command line parameters and initialises the component.
181         
182         HLTInfo("Initialising dHLT data checker component.");
183         
184         // Inherit the parents functionality.
185         int result = AliHLTMUONProcessor::DoInit(argc, argv);
186         if (result != 0) return result;
187
188         // Initialise flags with default values.
189         fIgnoreType = false;
190         fIgnoreSpec = false;
191         fDontForward = false;
192         fFilterBadBlocks = false;
193         fNoGlobalChecks = false;
194         fWarnForUnexpecedBlock = false;
195         fReturnError = false;
196
197         for (int i = 0; i < argc; i++)
198         {
199                 if (ArgumentAlreadyHandled(i, argv[i])) continue;
200
201                 if (strcmp(argv[i], "-ignoretype") == 0)
202                 {
203                         fIgnoreType = true;
204                         HLTInfo("Ignoring data type of data blocks as given by framework.");
205                         continue;
206                 }
207                 if (strcmp(argv[i], "-ignorespec") == 0)
208                 {
209                         fIgnoreSpec = true;
210                         HLTInfo("Ignoring data specification of data blocks as given by framework.");
211                         continue;
212                 }
213                 if (strcmp(argv[i], "-dontforward") == 0)
214                 {
215                         fDontForward = true;
216                         HLTInfo("Not forwarding input data blocks.");
217                         continue;
218                 }
219                 if (strcmp(argv[i], "-filter") == 0)
220                 {
221                         fFilterBadBlocks = true;
222                         HLTInfo("Passing only bad blocks to output.");
223                         continue;
224                 }
225                 if (strcmp(argv[i], "-no_global_check") == 0)
226                 {
227                         fNoGlobalChecks = true;
228                         HLTInfo("Only per block data consistancy checks will be applied,"
229                                 " but no global checks will be made."
230                         );
231                         continue;
232                 }
233                 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
234                 {
235                         fWarnForUnexpecedBlock = true;
236                         continue;
237                 }
238                 if (strcmp(argv[i], "-return_error") == 0)
239                 {
240                         fReturnError = true;
241                         continue;
242                 }
243                 
244                 HLTError("Unknown option '%s'.", argv[i]);
245                 return -EINVAL;
246         }
247
248         return 0;
249 }
250
251
252 int AliHLTMUONDataCheckerComponent::DoDeinit()
253 {
254         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
255         
256         HLTInfo("Deinitialising dHLT data checker component.");
257         return 0;
258 }
259
260
261 int AliHLTMUONDataCheckerComponent::DoEvent(
262                 const AliHLTComponentEventData& evtData,
263                 const AliHLTComponentBlockData* blocks,
264                 AliHLTComponentTriggerData& trigData,
265                 AliHLTUInt8_t* /*outputPtr*/,
266                 AliHLTUInt32_t& size,
267                 AliHLTComponentBlockDataList& outputBlocks
268         )
269 {
270         /// Inherited from AliHLTProcessor. Processes the new event data.
271         /// Here we go through the list of input data blocks and apply extensive
272         /// data integrity checking on the data found.
273         
274         if (not IsDataEvent()) return 0;
275         
276         HLTDebug("Processing event %llu with %u input data blocks.",
277                 evtData.fEventID, evtData.fBlockCnt
278         );
279         
280         // Allocate an array of flags indicating if the data block is OK or not,
281         // also arrays to store specific.
282         bool dataProblems = false;
283         bool* blockOk = NULL;
284         typedef const AliHLTComponentBlockData* PAliHLTComponentBlockData;
285         PAliHLTComponentBlockData* trigRecBlocks = NULL;
286         PAliHLTComponentBlockData* trigRecDebugBlocks = NULL;
287         PAliHLTComponentBlockData* hitBlocks = NULL;
288         PAliHLTComponentBlockData* clusterBlocks = NULL;
289         PAliHLTComponentBlockData* channelBlocks = NULL;
290         PAliHLTComponentBlockData* mansoTrackBlocks = NULL;
291         PAliHLTComponentBlockData* mansoCandidateBlocks = NULL;
292         PAliHLTComponentBlockData* trackBlocks = NULL;
293         PAliHLTComponentBlockData* singleDecisionBlocks = NULL;
294         PAliHLTComponentBlockData* pairDecisionBlocks = NULL;
295         AliHLTUInt32_t trigRecBlocksCount = 0;
296         AliHLTUInt32_t trigRecDebugBlocksCount = 0;
297         AliHLTUInt32_t hitBlocksCount = 0;
298         AliHLTUInt32_t clusterBlocksCount = 0;
299         AliHLTUInt32_t channelBlocksCount = 0;
300         AliHLTUInt32_t mansoTrackBlocksCount = 0;
301         AliHLTUInt32_t mansoCandidateBlocksCount = 0;
302         AliHLTUInt32_t trackBlocksCount = 0;
303         AliHLTUInt32_t singleDecisionBlocksCount = 0;
304         AliHLTUInt32_t pairDecisionBlocksCount = 0;
305         try
306         {
307                 blockOk = new bool[evtData.fBlockCnt];
308                 trigRecBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
309                 trigRecDebugBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
310                 hitBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
311                 clusterBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
312                 channelBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
313                 mansoTrackBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
314                 mansoCandidateBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
315                 trackBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
316                 singleDecisionBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
317                 pairDecisionBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
318         }
319         catch (const std::bad_alloc&)
320         {
321                 HLTError("Could not allocate more memory for internal arrays.");
322                 // Make sure to clean up if partially allocated memory.
323                 if (blockOk != NULL) delete [] blockOk;
324                 if (trigRecBlocks != NULL) delete [] trigRecBlocks;
325                 if (trigRecDebugBlocks != NULL) delete [] trigRecDebugBlocks;
326                 if (hitBlocks != NULL) delete [] hitBlocks;
327                 if (clusterBlocks != NULL) delete [] clusterBlocks;
328                 if (channelBlocks != NULL) delete [] channelBlocks;
329                 if (mansoTrackBlocks != NULL) delete [] mansoTrackBlocks;
330                 if (mansoCandidateBlocks != NULL) delete [] mansoCandidateBlocks;
331                 if (trackBlocks != NULL) delete [] trackBlocks;
332                 if (singleDecisionBlocks != NULL) delete [] singleDecisionBlocks;
333                 if (pairDecisionBlocks != NULL) delete [] pairDecisionBlocks;
334                 return -ENOMEM;
335         }
336         
337         AliHLTComponentDataType anyPrivateType = AliHLTComponentDataTypeInitializer(
338                         kAliHLTAnyDataType, kAliHLTDataOriginPrivate
339                 );
340         
341         try
342         {
343                 // Clear all the flags indicating if the blocks are ok.
344                 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
345                 {
346                         blockOk[n] = false;
347                 }
348         
349                 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
350                 {
351                         HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
352                                 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
353                         );
354                         
355                         AliHLTMUONDataBlockType blockType = kUnknownDataBlock;
356                         
357                         if (fIgnoreType)
358                         {
359                                 // Decode the block type if we must ignore the block type
360                                 // as given by the HLT framework.
361                                 if (blocks[n].fSize >= sizeof(AliHLTMUONDataBlockHeader))
362                                 {
363                                         const AliHLTMUONDataBlockHeader* header =
364                                                 reinterpret_cast<const AliHLTMUONDataBlockHeader*>(blocks[n].fPtr);
365                                         blockType = AliHLTMUONDataBlockType(header->fType);
366                                 }
367                         }
368                         else
369                         {
370                                 if (blocks[n].fDataType == anyPrivateType)
371                                 {
372                                         // Completely ignore any private HLT internal block types.
373                                         blockOk[n] = true;
374                                         continue;
375                                 }
376                                 else if (blocks[n].fDataType == AliHLTMUONConstants::DDLRawDataType())
377                                 {
378                                         blockOk[n] = CheckRawDataBlock(blocks[n], n);
379                                         continue;
380                                 }
381                                 else if (blocks[n].fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
382                                 {
383                                         blockType = kTriggerRecordsDataBlock;
384                                 }
385                                 else if (blocks[n].fDataType == AliHLTMUONConstants::TrigRecsDebugBlockDataType())
386                                 {
387                                         blockType = kTrigRecsDebugDataBlock;
388                                 }
389                                 else if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
390                                 {
391                                         blockType = kRecHitsDataBlock;
392                                 }
393                                 else if (blocks[n].fDataType == AliHLTMUONConstants::ClusterBlockDataType())
394                                 {
395                                         blockType = kClustersDataBlock;
396                                 }
397                                 else if (blocks[n].fDataType == AliHLTMUONConstants::ChannelBlockDataType())
398                                 {
399                                         blockType = kChannelsDataBlock;
400                                 }
401                                 else if (blocks[n].fDataType == AliHLTMUONConstants::MansoTracksBlockDataType())
402                                 {
403                                         blockType = kMansoTracksDataBlock;
404                                 }
405                                 else if (blocks[n].fDataType == AliHLTMUONConstants::MansoCandidatesBlockDataType())
406                                 {
407                                         blockType = kMansoCandidatesDataBlock;
408                                 }
409                                 else if (blocks[n].fDataType == AliHLTMUONConstants::TracksBlockDataType())
410                                 {
411                                         blockType = kTracksDataBlock;
412                                 }
413                                 else if (blocks[n].fDataType == AliHLTMUONConstants::SinglesDecisionBlockDataType())
414                                 {
415                                         blockType = kSinglesDecisionDataBlock;
416                                 }
417                                 else if (blocks[n].fDataType == AliHLTMUONConstants::PairsDecisionBlockDataType())
418                                 {
419                                         blockType = kPairsDecisionDataBlock;
420                                 }
421                                 else
422                                 {
423                                         // Log a message indicating that we got a data block that we
424                                         // do not know how to handle.
425                                         if (fWarnForUnexpecedBlock)
426                                                 HLTWarning("Received a data block of a type we cannot"
427                                                         " handle: '%s', spec: 0x%8.8X",
428                                                         DataType2Text(blocks[n].fDataType).c_str(),
429                                                         blocks[n].fSpecification
430                                                 );
431 #ifdef __DEBUG
432                                         else
433                                                 HLTDebug("Received a data block of a type we cannot"
434                                                         " handle: '%s', spec: 0x%8.8X",
435                                                         DataType2Text(blocks[n].fDataType).c_str(),
436                                                         blocks[n].fSpecification
437                                                 );
438 #endif
439                                 }
440                         }
441                         
442                         switch (blockType)
443                         {
444                         case kTriggerRecordsDataBlock:
445                                 blockOk[n] = CheckTriggerRecordsBlock(blocks[n], n);
446                                 trigRecBlocks[trigRecBlocksCount++] = &blocks[n];
447                                 break;
448                         case kTrigRecsDebugDataBlock:
449                                 blockOk[n] = CheckTrigRecsDebugBlock(blocks[n], n);
450                                 trigRecDebugBlocks[trigRecDebugBlocksCount++] = &blocks[n];
451                                 break;
452                         case kRecHitsDataBlock:
453                                 blockOk[n] = CheckRecHitsBlock(blocks[n], n);
454                                 hitBlocks[hitBlocksCount++] = &blocks[n];
455                                 break;
456                         case kClustersDataBlock:
457                                 blockOk[n] = CheckClustersBlock(blocks[n], n);
458                                 clusterBlocks[clusterBlocksCount++] = &blocks[n];
459                                 break;
460                         case kChannelsDataBlock:
461                                 blockOk[n] = CheckChannelsBlock(blocks[n], n);
462                                 channelBlocks[channelBlocksCount++] = &blocks[n];
463                                 break;
464                         case kMansoTracksDataBlock:
465                                 blockOk[n] = CheckMansoTracksBlock(blocks[n], n);
466                                 mansoTrackBlocks[mansoTrackBlocksCount++] = &blocks[n];
467                                 break;
468                         case kMansoCandidatesDataBlock:
469                                 blockOk[n] = CheckMansoCandidatesBlock(blocks[n], n);
470                                 mansoCandidateBlocks[mansoCandidateBlocksCount++] = &blocks[n];
471                                 break;
472                         case kTracksDataBlock:
473                                 blockOk[n] = CheckTracksBlock(blocks[n], n);
474                                 trackBlocks[trackBlocksCount++] = &blocks[n];
475                                 break;
476                         case kSinglesDecisionDataBlock:
477                                 blockOk[n] = CheckSinglesDecisionBlock(blocks[n], n);
478                                 singleDecisionBlocks[singleDecisionBlocksCount++] = &blocks[n];
479                                 break;
480                         case kPairsDecisionDataBlock:
481                                 blockOk[n] = CheckPairsDecisionBlock(blocks[n], n);
482                                 pairDecisionBlocks[pairDecisionBlocksCount++] = &blocks[n];
483                                 break;
484                         default:
485                                 HLTDebug("Received a data block for which we could not decode the data type."
486                                         " fDataType = '%s', fSpecification = 0x%8.8X, fSize = %u bytes.",
487                                         DataType2Text(blocks[n].fDataType).c_str(),
488                                         blocks[n].fSpecification,
489                                         blocks[n].fSize
490                                 );
491                                 break;
492                         }
493                 }
494                 
495                 // Apply the global data consistancy checks if not suppressed by the user.
496                 if (not fNoGlobalChecks)
497                 {
498                         MakeGlobalChecks(
499                                 blocks, blockOk, evtData.fBlockCnt,
500                                 trigRecBlocks, trigRecBlocksCount,
501                                 trigRecDebugBlocks, trigRecDebugBlocksCount,
502                                 hitBlocks, hitBlocksCount,
503                                 clusterBlocks, clusterBlocksCount,
504                                 channelBlocks, channelBlocksCount,
505                                 mansoTrackBlocks, mansoTrackBlocksCount,
506                                 mansoCandidateBlocks, mansoCandidateBlocksCount,
507                                 trackBlocks, trackBlocksCount,
508                                 singleDecisionBlocks, singleDecisionBlocksCount,
509                                 pairDecisionBlocks, pairDecisionBlocksCount
510                         );
511                 }
512                 
513                 // Forward the input data blocks if we have not been asked to drop them.
514                 // Also remember to filter for bad blocks if so specified.
515                 if (not fDontForward)
516                 {
517                         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
518                         {
519                                 if (fFilterBadBlocks and blockOk[n]) continue;
520                                 outputBlocks.push_back(blocks[n]);
521                         }
522                 }
523                 
524                 // Set dataProblems flag is there was at least one block with problems.
525                 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
526                 {
527                         if (not blockOk[n]) dataProblems = true;
528                 }
529         }
530         finally
531         (
532                 // make sure to cleanup memory
533                 delete [] blockOk;
534                 delete [] trigRecBlocks;
535                 delete [] trigRecDebugBlocks;
536                 delete [] hitBlocks;
537                 delete [] clusterBlocks;
538                 delete [] channelBlocks;
539                 delete [] mansoTrackBlocks;
540                 delete [] mansoCandidateBlocks;
541                 delete [] trackBlocks;
542                 delete [] singleDecisionBlocks;
543                 delete [] pairDecisionBlocks;
544         )
545         
546         // Finally we set the total size of output memory we consumed, which is
547         // zero since we just copied the input descriptors to output if anything.
548         size = 0;
549
550         if (dataProblems and DumpDataOnError()) DumpEvent(evtData, trigData);
551         
552         if (fReturnError)
553         {
554                 // If we were requested to return errors if there were integrity
555                 // problems then check if any data blocks had problems and return
556                 // an error code.
557                 if (dataProblems) return -EFAULT;
558         }
559         return 0;
560 }
561
562
563 bool AliHLTMUONDataCheckerComponent::IsSpecificationValid(
564                 const AliHLTComponentBlockData& block,
565                 AliHLTUInt32_t blockNumber,
566                 const char* name
567         ) const
568 {
569         /// Checks if the specification bits are valid.
570         /// \param  block The block whose specification should be checked.
571         /// \param  blockNumber The block index number being checked.
572         /// \param  name The name of the type of block being checked.
573         /// \returns true if the specification is valid and false otherwise.
574
575         if (AliHLTMUONUtils::IsSpecValid(block.fSpecification))
576                 return true;
577         
578         HLTError("Problem found with data block %d, fDataType = '%s',"
579                  " fPtr = %p and fSize = %u bytes."
580                  " Assuming this is a %s data block."
581                  " Problem: The specification does not contain a valid pattern,"
582                  " received 0x%8.8X for the specification.",
583                 blockNumber,
584                 DataType2Text(block.fDataType).c_str(),
585                 block.fPtr,
586                 block.fSize,
587                 name,
588                 block.fSpecification
589         );
590         return false;
591 }
592
593
594 bool AliHLTMUONDataCheckerComponent::IsFromTrackerOnly(
595                 const AliHLTComponentBlockData& block,
596                 AliHLTUInt32_t blockNumber,
597                 const char* name
598         ) const
599 {
600         /// Checks if the specification bits are valid and indicate the block
601         /// contains data or information only from the tracker DDLs.
602         /// \param  block The block whose specification should be checked.
603         /// \param  blockNumber The block index number being checked.
604         /// \param  name The name of the type of block being checked.
605         /// \returns true if the specification indicates data is only from tracker.
606         
607         bool result = IsSpecificationValid(block, blockNumber, name);
608         
609         if (AliHLTMUONUtils::ContainsDataFromTracker(block.fSpecification) and
610             not AliHLTMUONUtils::ContainsDataFromTrigger(block.fSpecification)
611            )
612         {
613                 return result;
614         }
615         
616         HLTError("Problem found with data block %d, fDataType = '%s',"
617                  " fPtr = %p and fSize = %u bytes."
618                  " Assuming this is a %s data block."
619                  " Problem: The data block does not contain data only from the"
620                  " tracker DDLs as expected."
621                  " Received 0x%8.8X for the specification.",
622                 blockNumber,
623                 DataType2Text(block.fDataType).c_str(),
624                 block.fPtr,
625                 block.fSize,
626                 name,
627                 block.fSpecification
628         );
629         return false;
630 }
631
632
633 bool AliHLTMUONDataCheckerComponent::IsFromTriggerOnly(
634                 const AliHLTComponentBlockData& block,
635                 AliHLTUInt32_t blockNumber,
636                 const char* name
637         ) const
638 {
639         /// Checks if the specification bits are valid and indicate the block
640         /// contains data or information only from the trigger DDLs.
641         /// \param  block The block whose specification should be checked.
642         /// \param  blockNumber The block index number being checked.
643         /// \param  name The name of the type of block being checked.
644         /// \returns true if the specification indicates data is only from trigger.
645         
646         bool result = IsSpecificationValid(block, blockNumber, name);
647         
648         if (AliHLTMUONUtils::ContainsDataFromTrigger(block.fSpecification) and
649             not AliHLTMUONUtils::ContainsDataFromTracker(block.fSpecification)
650            )
651         {
652                 return result;
653         }
654         
655         HLTError("Problem found with data block %d, fDataType = '%s',"
656                  " fPtr = %p and fSize = %u bytes."
657                  " Assuming this is a %s data block."
658                  " Problem: The data block does not contain data only from the"
659                  " trigger DDLs as expected."
660                  " Received 0x%8.8X for the specification.",
661                 blockNumber,
662                 DataType2Text(block.fDataType).c_str(),
663                 block.fPtr,
664                 block.fSize,
665                 name,
666                 block.fSpecification
667         );
668         return false;
669 }
670
671
672 bool AliHLTMUONDataCheckerComponent::IsMomentumVectorOk(
673                 const AliHLTComponentBlockData& block,
674                 AliHLTUInt32_t blockNumber,
675                 const char* name,
676                 AliHLTUInt32_t entryNumber,
677                 AliHLTFloat32_t px,
678                 AliHLTFloat32_t py,
679                 AliHLTFloat32_t pz
680         ) const
681 {
682         /// Checks if the momentum vector is reasonable.
683         /// \param  block The block from which the momentum vector data comes from.
684         /// \param  blockNumber The block index number.
685         /// \param  name The name of the type of block.
686         /// \param  entryNumber The entry index number of the structure holding
687         ///      the momentum vector data.
688         /// \param  px The X coordinate of the momentum vector (GeV/c).
689         /// \param  py The Y coordinate of the momentum vector (GeV/c).
690         /// \param  pz The Z coordinate of the momentum vector (GeV/c).
691         /// \returns true if the momentum vector is valid and false otherwise.
692         
693         // If the momentum vector is nil then ignore it.
694         if (px == 0 and py == 0 and pz == 0) return true;
695         
696         bool result = true;
697         
698         // If the momentum vector is sane then we should not have a particle with
699         // more energy than 14 TeV and momentum should be in the negative direction.
700         double momentum = sqrt(px*px + py*py + pz*pz);
701         if (momentum > 14e3)
702         {
703                 // Just warn since this is a data sanity problem rather
704                 // than a data integrity problem.
705                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
706                         " fPtr = %p and fSize = %u bytes."
707                         " Assuming this is a %s data block."
708                         " Problem with entry %d in block: The momentum vector"
709                         " p = {%f, %f, %f}, |p| = %f looks too big.",
710                         blockNumber,
711                         DataType2Text(block.fDataType).c_str(),
712                         block.fPtr,
713                         block.fSize,
714                         name,
715                         entryNumber,
716                         px, py, pz,
717                         momentum
718                 );
719                 result = false;
720         }
721         
722         if (pz > 0.)
723         {
724                 // Just warn since this is a data sanity problem rather
725                 // than a data integrity problem.
726                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
727                         " fPtr = %p and fSize = %u bytes."
728                         " Assuming this is a %s data block."
729                         " Problem with entry %d in block: The momentum vector"
730                         " p = {%f, %f, %f} points away from the dimuon"
731                         " spectrometer (p_z > 0).",
732                         blockNumber,
733                         DataType2Text(block.fDataType).c_str(),
734                         block.fPtr,
735                         block.fSize,
736                         name,
737                         entryNumber,
738                         px, py, pz
739                 );
740                 result = false;
741         }
742         
743         return result;
744 }
745
746
747 bool AliHLTMUONDataCheckerComponent::AreMomentumCalcParamsOk(
748                 const AliHLTComponentBlockData& block,
749                 AliHLTUInt32_t blockNumber,
750                 const char* name,
751                 AliHLTUInt32_t entryNumber,
752                 AliHLTFloat32_t zmiddle,
753                 AliHLTFloat32_t bl
754         ) const
755 {
756         /// Checks if the parameters for the momentum calculation are reasonable.
757         /// \param  block The block from which the parameter data comes from.
758         /// \param  blockNumber The block index number.
759         /// \param  name The name of the type of block.
760         /// \param  entryNumber The entry index number of the structure holding
761         ///      the parameter data data.
762         /// \param  zmiddle The z-coordinate of the middle of the magnetic field (cm).
763         /// \param  bl The integrated magnetic field (T.m).
764         /// \returns true if the parameters are valid and false otherwise.
765         
766         bool result = true;
767         
768         // Check that the value of the fZmiddle value is somewhere
769         // within the tracking / dipole magnetic field area.
770         if (zmiddle < AliMUONConstants::AbsZEnd() or
771                 zmiddle < AliMUONConstants::MuonFilterZBeg()
772                 )
773         {
774                 // Just warn since this is a data sanity problem rather
775                 // than a data integrity problem.
776                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
777                         " fPtr = %p and fSize = %u bytes."
778                         " Assuming this is a %s data block."
779                         " Problem with entry %d in block: The Z coordinate %f cm"
780                         " used as the middle of the magnetic field in the momentum"
781                         " calculation is outside the dimuon spectrometers dipole"
782                         " magnetic field volume.",
783                         blockNumber,
784                         DataType2Text(block.fDataType).c_str(),
785                         block.fPtr,
786                         block.fSize,
787                         name,
788                         entryNumber,
789                         zmiddle
790                 );
791                 result = false;
792         }
793         
794         // Also check that the value of the 'bl' value is within a
795         // reasonable range: |bl| < Lmax * Bmax, where
796         // Lmax = max length from vertex to end of spectrometer, and
797         // Bmax = max magnetic field of dipole, taken as 1 tesla.
798         // Approximating Lmax * Bmax as 20 T.m
799         if (fabs(bl) > 20.)
800         {
801                 // Just warn since this is a data sanity problem rather
802                 // than a data integrity problem.
803                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
804                         " fPtr = %p and fSize = %u bytes."
805                         " Assuming this is a %s data block."
806                         " Problem with entry %d in block: The integrated magnetic"
807                         " field value %f T.m used in the momentum calculation"
808                         " has an unreasonably large absolute value.",
809                         blockNumber,
810                         DataType2Text(block.fDataType).c_str(),
811                         block.fPtr,
812                         block.fSize,
813                         name,
814                         entryNumber,
815                         bl
816                 );
817                 result = false;
818         }
819         
820         return result;
821 }
822
823
824 bool AliHLTMUONDataCheckerComponent::IsHitCoordinateOk(
825                 const AliHLTComponentBlockData& block,
826                 AliHLTUInt32_t blockNumber,
827                 const char* name,
828                 AliHLTUInt32_t entryNumber,
829                 const AliHLTMUONRecHitStruct& hit,
830                 AliHLTInt32_t minChamber,
831                 AliHLTInt32_t maxChamber,
832                 AliHLTInt32_t expectedChamber,
833                 bool ddl[22]
834         ) const
835 {
836         /// Checks if the hit coordinate is compatible with a the location of a
837         /// dimuon spectrometer chamber. Also, if expectedChamber is not -1, then
838         /// the hit coordinate is checked if to comes from that chamber.
839         /// We also check if the fFlags containing the chamber number and detector
840         /// element ID are correct.
841         /// \param  block The block from which the hit data comes from.
842         /// \param  blockNumber The block index number.
843         /// \param  name The name of the type of block.
844         /// \param  entryNumber The entry index number of the hit.
845         /// \param  hit The hit data being checked.
846         /// \param  minChamber The minimum valid chamber number to check for.
847         /// \param  maxChamber The maximum valid chamber number to check for.
848         /// \param  expectedChamber If not -1 then this is the chamber number to
849         ///      check against.
850         /// \param  ddl  The array decoded by AliHLTMUONUtils::UnpackSpecBits.
851         /// \returns true if the hit is valid and false otherwise.
852         
853         assert( 0 <= minChamber and minChamber < 14 );
854         assert( 0 <= maxChamber and maxChamber < 14 );
855         
856         bool result = true;
857         
858         AliHLTUInt8_t chNum = 0xFF;
859         AliHLTUInt16_t detElemId = 0xFFFF;
860         AliHLTMUONUtils::UnpackRecHitFlags(hit.fFlags, chNum, detElemId);
861         
862         Int_t chamber = AliMUONConstants::ChamberNumber(hit.fZ, false); // false = do not warn.
863         if (chamber < minChamber or maxChamber < chamber)
864         {
865                 HLTError("Problem found with data block %d, fDataType = '%s',"
866                         " fPtr = %p and fSize = %u bytes."
867                         " Assuming this is a %s data block."
868                         " Problem with entry %d in block: The hit {x = %f, y = %f,"
869                         " z = %f} cm has a z-coordinate that does not correspond"
870                         " to the nominal position of any chambers in the range"
871                         " [%d..%d].",
872                         blockNumber,
873                         DataType2Text(block.fDataType).c_str(),
874                         block.fPtr,
875                         block.fSize,
876                         name,
877                         entryNumber,
878                         hit.fX, hit.fY, hit.fZ,
879                         minChamber+1,
880                         maxChamber+1
881                 );
882                 return false;
883         }
884         
885         if (chNum != chamber)
886         {
887                 HLTError("Problem found with data block %d, fDataType = '%s',"
888                         " fPtr = %p and fSize = %u bytes."
889                         " Assuming this is a %s data block."
890                         " Problem with entry %d in block: The hit {x = %f, y = %f,"
891                         " z = %f} cm has a chamber number %d that does not correspond"
892                         " to the expected chamber %d given by the z-coordinate.",
893                         blockNumber,
894                         DataType2Text(block.fDataType).c_str(),
895                         block.fPtr,
896                         block.fSize,
897                         name,
898                         entryNumber,
899                         hit.fX, hit.fY, hit.fZ,
900                         chNum+1,
901                         chamber+1
902                 );
903                 result = false;
904                 if (minChamber <= Int_t(chNum) and Int_t(chNum) <= maxChamber)
905                 {
906                         // Rather use the explicit value in the data if it
907                         // is in range.
908                         chamber = chNum;
909                 }
910         }
911         
912         if (expectedChamber != -1 and chamber != expectedChamber)
913         {
914                 HLTError("Problem found with data block %d, fDataType = '%s',"
915                         " fPtr = %p and fSize = %u bytes."
916                         " Assuming this is a %s data block."
917                         " Problem with entry %d in block: The hit {x = %f, y = %f,"
918                         " z = %f} cm has a position that corresponds to chamber %d,"
919                         " but expected it to be on chamber %d.",
920                         blockNumber,
921                         DataType2Text(block.fDataType).c_str(),
922                         block.fPtr,
923                         block.fSize,
924                         name,
925                         entryNumber,
926                         hit.fX, hit.fY, hit.fZ,
927                         chamber+1,
928                         expectedChamber+1
929                 );
930                 result = false;
931         }
932         
933         AliHLTFloat32_t rmin = AliMUONConstants::Rmin(chamber / 2);
934         AliHLTFloat32_t rmax = AliMUONConstants::Rmax(chamber / 2);
935         AliHLTFloat32_t radius = sqrt(hit.fX*hit.fX + hit.fY*hit.fY);
936         if (radius < rmin or rmax < radius)
937         {
938                 HLTError("Problem found with data block %d, fDataType = '%s',"
939                         " fPtr = %p and fSize = %u bytes."
940                         " Assuming this is a %s data block."
941                         " Problem with entry %d in block: The hit {x = %f, y = %f,"
942                         " z = %f} cm has a position in the X-Y plane that does not"
943                         " correspond to the nominal position of chamber %d.",
944                         blockNumber,
945                         DataType2Text(block.fDataType).c_str(),
946                         block.fPtr,
947                         block.fSize,
948                         name,
949                         entryNumber,
950                         hit.fX, hit.fY, hit.fZ,
951                         chamber+1
952                 );
953                 result = false;
954         }
955         
956         if (not fIgnoreSpec and not ChamberMarkedInDDLList(chamber, ddl))
957         {
958                 HLTError("Problem found with data block %d, fDataType = '%s',"
959                         " fPtr = %p and fSize = %u bytes."
960                         " Assuming this is a %s data block."
961                         " Problem with entry %d in block: The hit {x = %f, y = %f,"
962                         " z = %f} cm has a position that corresponds to chamber %d"
963                         " but the data block specification 0x%8.8X does have a"
964                         " corresponding DDL bit set.",
965                         blockNumber,
966                         DataType2Text(block.fDataType).c_str(),
967                         block.fPtr,
968                         block.fSize,
969                         name,
970                         entryNumber,
971                         hit.fX, hit.fY, hit.fZ,
972                         chamber+1,
973                         block.fSpecification
974                 );
975                 result = false;
976         }
977         
978         // Check that the detector element ID is valid and it corresponds to
979         // the chamber number.
980         if (FetchMappingStores() == 0)  // are stores loaded?
981         {
982                 Bool_t warn = kFALSE;
983                 AliMpDEStore* store = AliMpDEStore::Instance(warn);
984                 AliMpDetElement* de = store->GetDetElement(Int_t(detElemId), warn);
985                 if (de == NULL)
986                 {
987                         HLTError("Problem found with data block %d, fDataType = '%s',"
988                                 " fPtr = %p and fSize = %u bytes."
989                                 " Assuming this is a %s data block."
990                                 " Problem with entry %d in block: The hit {x = %f, y = %f,"
991                                 " z = %f} cm has a detector element ID %d,"
992                                 " which is not valid.",
993                                 blockNumber,
994                                 DataType2Text(block.fDataType).c_str(),
995                                 block.fPtr,
996                                 block.fSize,
997                                 name,
998                                 entryNumber,
999                                 hit.fX, hit.fY, hit.fZ,
1000                                 detElemId
1001                         );
1002                         result = false;
1003                 }
1004                         
1005                 // Check that the chamber number from the detector element number
1006                 // has the expected value.
1007                 Int_t ch = AliMpDEManager::GetChamberId(Int_t(detElemId), warn);
1008                 if (ch != chamber)
1009                 {
1010                         HLTError("Problem found with data block %d, fDataType = '%s',"
1011                                 " fPtr = %p and fSize = %u bytes."
1012                                 " Assuming this is a %s data block."
1013                                 " Problem with entry %d in block: The hit {x = %f, y = %f,"
1014                                 " z = %f} cm has a detector element ID %d,"
1015                                 " which does not correspond to the chamber %d.",
1016                                 blockNumber,
1017                                 DataType2Text(block.fDataType).c_str(),
1018                                 block.fPtr,
1019                                 block.fSize,
1020                                 name,
1021                                 entryNumber,
1022                                 hit.fX, hit.fY, hit.fZ,
1023                                 detElemId,
1024                                 chamber+1
1025                         );
1026                         result = false;
1027                 }
1028         }
1029         else
1030         {
1031                 HLTWarning("Cannot check a hit's detector element ID information"
1032                         " without being able to load the mapping from CDB."
1033                 );
1034                 result = false;
1035         }
1036         
1037         return result;
1038 }
1039
1040
1041 bool AliHLTMUONDataCheckerComponent::IsMansoTrackOk(
1042                 const AliHLTComponentBlockData& block,
1043                 AliHLTUInt32_t blockNumber,
1044                 const char* name,
1045                 AliHLTUInt32_t entryNumber,
1046                 const AliHLTMUONMansoTrackStruct& track,
1047                 bool ddl[22]
1048         ) const
1049 {
1050         /// Checks if the Manso track structure is Ok.
1051         /// \param  block The block from which the track data comes from.
1052         /// \param  blockNumber The block index number.
1053         /// \param  name The name of the type of block.
1054         /// \param  entryNumber The entry index number of the structure in the
1055         ///      block being checked.
1056         /// \param  track The Manso track data being checked.
1057         /// \param  ddl  The array decoded by AliHLTMUONUtils::UnpackSpecBits.
1058         /// \returns true if the Manso track is valid and false otherwise.
1059         
1060         bool result = true;
1061         
1062         // Chi^2 should not be greater than the worst fit possible, estimated
1063         // as the diameter of largest chamber times the number of points
1064         // findable in a track. Max points is 10 tracker chambers times
1065         // 2 cathodes + 4 trigger chambers.
1066         if (track.fChi2 > AliMUONConstants::Dmax(6)*AliMUONConstants::Dmax(6)*(10*2+4))
1067         {
1068                 // Just a warning since this is not technically an
1069                 // integrity problem.
1070                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
1071                         " fPtr = %p and fSize = %u bytes."
1072                         " Assuming this is a %s data block."
1073                         " Problem with entry %d in block: The Manso track has"
1074                         " the chi squared value of %f that is unreasonably big.",
1075                         blockNumber,
1076                         DataType2Text(block.fDataType).c_str(),
1077                         block.fPtr,
1078                         block.fSize,
1079                         name,
1080                         entryNumber,
1081                         track.fChi2
1082                 );
1083                 result = false;
1084         }
1085         
1086         // Check if the momentum vector is reasonable.
1087         bool momOk = IsMomentumVectorOk(
1088                         block, blockNumber, name, entryNumber,
1089                         track.fPx, track.fPy, track.fPz
1090                 );
1091         if (not momOk) result = false;
1092         
1093         AliHLTMUONParticleSign sign;
1094         bool hitset[4];
1095         AliHLTMUONUtils::UnpackMansoTrackFlags(track.fFlags, sign, hitset);
1096         
1097         // Min and max allowed chamber numbers for hits:
1098         Int_t minCh = 0;
1099         Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
1100         
1101         // Check that this hit coordinates are OK.
1102         for (AliHLTUInt32_t i = 0; i < 4; i++)
1103         {
1104                 if (not hitset[i]) continue; // ignore hits that are not initialised.
1105                 bool hitOk = IsHitCoordinateOk(
1106                                 block, blockNumber, name, entryNumber, track.fHit[i],
1107                                 minCh, maxCh, i+6, ddl
1108                         );
1109                 if (not hitOk) result = false;
1110         }
1111         
1112         return result;
1113 }
1114
1115
1116 bool AliHLTMUONDataCheckerComponent::IsTrackOk(
1117                 const AliHLTComponentBlockData& block,
1118                 AliHLTUInt32_t blockNumber,
1119                 const char* name,
1120                 AliHLTUInt32_t entryNumber,
1121                 const AliHLTMUONTrackStruct& track,
1122                 bool ddl[22]
1123         ) const
1124 {
1125         /// Checks if the full track structure is Ok.
1126         /// \param  block The block from which the track data comes from.
1127         /// \param  blockNumber The block index number.
1128         /// \param  name The name of the type of block.
1129         /// \param  entryNumber The entry index number of the structure in the
1130         ///      block being checked.
1131         /// \param  track The track data being checked.
1132         /// \param  ddl  The array decoded by AliHLTMUONUtils::UnpackSpecBits.
1133         /// \returns true if the full track structure is valid and false otherwise.
1134         
1135         bool result = true;
1136         
1137         // Chi^2 should not be greater than the worst fit possible, estimated
1138         // as the diameter of largest chamber times the number of points
1139         // findable in a track. Max points is 10 tracker chambers times
1140         // 2 cathodes + 4 trigger chambers.
1141         if (track.fChi2 > AliMUONConstants::Dmax(6)*AliMUONConstants::Dmax(6)*(10*2+4))
1142         {
1143                 // Just a warning since this is not technically an
1144                 // integrity problem.
1145                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
1146                         " fPtr = %p and fSize = %u bytes."
1147                         " Assuming this is a %s data block."
1148                         " Problem with entry %d in block: The track has"
1149                         " the chi squared value of %f that is unreasonably big.",
1150                         blockNumber,
1151                         DataType2Text(block.fDataType).c_str(),
1152                         block.fPtr,
1153                         block.fSize,
1154                         name,
1155                         entryNumber,
1156                         track.fChi2
1157                 );
1158                 result = false;
1159         }
1160         
1161         // Check if the momentum vector is reasonable.
1162         bool momOk = IsMomentumVectorOk(
1163                         block, blockNumber, name, entryNumber,
1164                         track.fPx, track.fPy, track.fPz
1165                 );
1166         if (not momOk) result = false;
1167         
1168         // Check that the momentum parameters correspond to the momentum vector.
1169         double momvalue = sqrt(track.fPy*track.fPy + track.fPz*track.fPz);
1170         double invMom = (momvalue != 0 ? 1. / momvalue : 0);
1171         if (TMath::Abs(invMom - TMath::Abs(track.fInverseBendingMomentum)) > 1e-12)
1172         {
1173                 HLTError("Problem found with data block %d, fDataType = '%s',"
1174                         " fPtr = %p and fSize = %u bytes."
1175                         " Assuming this is a %s data block."
1176                         " Problem with entry %d in block: The track's inverse bending"
1177                         " momentum %f does not correspond to the momentum vector.",
1178                         blockNumber,
1179                         DataType2Text(block.fDataType).c_str(),
1180                         block.fPtr,
1181                         block.fSize,
1182                         name,
1183                         entryNumber,
1184                         track.fInverseBendingMomentum
1185                 );
1186                 result = false;
1187         }
1188         if (track.fPz != 0 and TMath::Abs(track.fPx/track.fPz - track.fThetaX) > 1e-12)
1189         {
1190                 HLTError("Problem found with data block %d, fDataType = '%s',"
1191                         " fPtr = %p and fSize = %u bytes."
1192                         " Assuming this is a %s data block."
1193                         " Problem with entry %d in block: The track's non-bending plane"
1194                         " slope parameter %f does not correspond to the momentum vector.",
1195                         blockNumber,
1196                         DataType2Text(block.fDataType).c_str(),
1197                         block.fPtr,
1198                         block.fSize,
1199                         name,
1200                         entryNumber,
1201                         track.fThetaX
1202                 );
1203                 result = false;
1204         }
1205         if (track.fPz != 0 and TMath::Abs(track.fPy/track.fPz - track.fThetaY) > 1e-12)
1206         {
1207                 HLTError("Problem found with data block %d, fDataType = '%s',"
1208                         " fPtr = %p and fSize = %u bytes."
1209                         " Assuming this is a %s data block."
1210                         " Problem with entry %d in block: The track's bending plane"
1211                         " slope parameter %f does not correspond to the momentum vector.",
1212                         blockNumber,
1213                         DataType2Text(block.fDataType).c_str(),
1214                         block.fPtr,
1215                         block.fSize,
1216                         name,
1217                         entryNumber,
1218                         track.fThetaY
1219                 );
1220                 result = false;
1221         }
1222         
1223         // Check that the DCA vertex is reasonable. i.e. the vertex is within
1224         // a 1 meter cube of the origin.
1225         if (TMath::Abs(track.fX) > 100 or TMath::Abs(track.fY) > 100 or TMath::Abs(track.fZ) > 100)
1226         {
1227                 // Just a warning since this is not technically an integrity problem.
1228                 HLTWarning("Problem found with data block %d, fDataType = '%s',"
1229                         " fPtr = %p and fSize = %u bytes."
1230                         " Assuming this is a %s data block."
1231                         " Problem with entry %d in block: The track's distance of closest"
1232                         " approach (DCA) vertex (x, y, z) = (%f, %f, %f) is not a reasonable value.",
1233                         blockNumber,
1234                         DataType2Text(block.fDataType).c_str(),
1235                         block.fPtr,
1236                         block.fSize,
1237                         name,
1238                         entryNumber,
1239                         track.fX, track.fY, track.fZ
1240                 );
1241                 result = false;
1242         }
1243         
1244         AliHLTMUONParticleSign sign;
1245         bool hitset[16];
1246         AliHLTMUONUtils::UnpackTrackFlags(track.fFlags, sign, hitset);
1247         
1248         // Min and max allowed chamber numbers for hits:
1249         Int_t minCh = 0;
1250         Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
1251         
1252         // Check that this hit coordinates are OK.
1253         for (AliHLTUInt32_t i = 0; i < 16; i++)
1254         {
1255                 if (not hitset[i]) continue; // ignore hits that are not initialised.
1256                 bool hitOk = IsHitCoordinateOk(
1257                                 block, blockNumber, name, entryNumber, track.fHit[i],
1258                                 minCh, maxCh, -1, ddl
1259                         );
1260                 if (not hitOk) result = false;
1261         }
1262         
1263         return result;
1264 }
1265
1266
1267 bool AliHLTMUONDataCheckerComponent::CheckDetElemIds(
1268                 const AliHLTComponentBlockData& infoBlock,
1269                 AliHLTUInt32_t infoBlockNumber,
1270                 AliHLTUInt32_t infoEntryNumber,
1271                 const AliHLTMUONTrigRecInfoStruct& info,
1272                 const AliHLTComponentBlockData& trBlock,
1273                 AliHLTUInt32_t trBlockNumber,
1274                 AliHLTUInt32_t trEntryNumber,
1275                 const AliHLTMUONTriggerRecordStruct& tr
1276         ) const
1277 {
1278         /// Checks if the detector element IDs are the same in the debug
1279         /// information structure and the trigger record structure.
1280         /// \param  infoBlock The debug information block from which the 'info'
1281         ///      data comes from.
1282         /// \param  infoBlockNumber The debug information block index number.
1283         /// \param  infoEntryNumber The entry index number of the 'info'
1284         ///      structure in the debug information data block.
1285         /// \param  info  The debug information structure being checked.
1286         /// \param  trBlock The trigger record block from which the 'tr' data
1287         ///      comes from.
1288         /// \param  trBlockNumber The trigger record block index number.
1289         /// \param  trEntryNumber The entry index number of the 'tr' structure
1290         ///      in the trigger record data block.
1291         /// \param  tr  The trigger record structure being checked.
1292         /// \returns true if the detector element IDs are the same and false
1293         ///      otherwise.
1294         
1295         bool result = true;
1296         
1297         for (int i = 0; i < 4; i++)
1298         {
1299                 AliHLTUInt8_t chamber = 0xFF;
1300                 AliHLTUInt16_t detElemId = 0xFFFF;
1301                 AliHLTMUONUtils::UnpackRecHitFlags(tr.fHit[i].fFlags, chamber, detElemId);
1302                 if (info.fDetElemId[i] == detElemId) continue;
1303                 
1304                 HLTError("Problem found with trigger record debug information %d"
1305                         " in data block %d (fDataType = '%s', fPtr = %p, fSize"
1306                         " = %u bytes) and trigger record %d in data block %d"
1307                         " (fDataType = '%s', fPtr = %p, fSize = %u bytes):"
1308                         " The detection element ID %d for chamber %d in the debug"
1309                         " information, is not the same as %d"
1310                         " found in the trigger record.",
1311                         infoEntryNumber,
1312                         infoBlockNumber,
1313                         DataType2Text(infoBlock.fDataType).c_str(),
1314                         infoBlock.fPtr,
1315                         infoBlock.fSize,
1316                         trEntryNumber,
1317                         trBlockNumber,
1318                         DataType2Text(trBlock.fDataType).c_str(),
1319                         trBlock.fPtr,
1320                         trBlock.fSize,
1321                         info.fDetElemId[i],
1322                         i+11,
1323                         detElemId
1324                 );
1325                 result = false;
1326         }
1327         
1328         return result;
1329 }
1330
1331
1332 bool AliHLTMUONDataCheckerComponent::CheckDetElemIds(
1333                 const AliHLTComponentBlockData& clusterBlock,
1334                 AliHLTUInt32_t clusterBlockNumber,
1335                 AliHLTUInt32_t clusterEntryNumber,
1336                 const AliHLTMUONClusterStruct& cluster,
1337                 const AliHLTComponentBlockData& hitBlock,
1338                 AliHLTUInt32_t hitBlockNumber,
1339                 AliHLTUInt32_t hitEntryNumber,
1340                 const AliHLTMUONRecHitStruct& hit
1341         ) const
1342 {
1343         /// Checks if the detector element IDs are the same in the cluster
1344         /// structure and the reconstructed hit structure.
1345         /// \param  clusterBlock The cluster block from which the 'cluster' data
1346         ///      comes from.
1347         /// \param  clusterBlockNumber The cluster block index number.
1348         /// \param  clusterEntryNumber The entry index number of the 'cluster'
1349         ///      structure in the cluster data block.
1350         /// \param  cluster  The cluster structure being checked.
1351         /// \param  hitBlock The reconstructed hit block from which the 'hit'
1352         ///      data comes from.
1353         /// \param  hitBlockNumber The reconstructed hit block index number.
1354         /// \param  hitEntryNumber The entry index number of the 'hit' structure
1355         ///      in the reconstructed hit data block.
1356         /// \param  hit  The trigger record structure being checked.
1357         /// \returns true if the detector element IDs are the same and false
1358         ///      otherwise.
1359         
1360         bool result = true;
1361         
1362         AliHLTUInt8_t chamber = 0xFF;
1363         AliHLTUInt16_t detElemId = 0xFFFF;
1364         AliHLTMUONUtils::UnpackRecHitFlags(hit.fFlags, chamber, detElemId);
1365         if (cluster.fDetElemId != detElemId)
1366         {
1367                 HLTError("Problem found with cluster %d in data block %d"
1368                         " (fDataType = '%s', fPtr = %p, fSize = %u bytes)"
1369                         " and reconstructed hit %d in data block %d"
1370                         " (fDataType = '%s', fPtr = %p, fSize = %u bytes):"
1371                         " The detection element ID %d in the cluster, is not"
1372                         " the same as %d found in the reconstructed hit.",
1373                         clusterEntryNumber,
1374                         clusterBlockNumber,
1375                         DataType2Text(clusterBlock.fDataType).c_str(),
1376                         clusterBlock.fPtr,
1377                         clusterBlock.fSize,
1378                         hitEntryNumber,
1379                         hitBlockNumber,
1380                         DataType2Text(hitBlock.fDataType).c_str(),
1381                         hitBlock.fPtr,
1382                         hitBlock.fSize,
1383                         cluster.fDetElemId,
1384                         detElemId
1385                 );
1386                 result = false;
1387         }
1388         
1389         return result;
1390 }
1391
1392
1393 namespace
1394 {
1395         /**
1396          * Class for logging errors found in raw DDL data.
1397          */
1398         class AliHLTMUONDecoderHandler : public AliHLTLogging
1399         {
1400         public:
1401         
1402                 /// Default constructor
1403                 AliHLTMUONDecoderHandler() :
1404                         AliHLTLogging(),
1405                         fBufferStart(NULL),
1406                         fDescriptor(NULL),
1407                         fBlockNumber(0)
1408                 {
1409                 }
1410                 
1411                 /// Default destructor.
1412                 virtual ~AliHLTMUONDecoderHandler() {}
1413                 
1414                 /// Sets the DDL raw data block descriptor.
1415                 void SetDescriptor(const AliHLTComponentBlockData* b) { fDescriptor = b; }
1416                 
1417                 /// Sets the block number of the raw data block descriptor.
1418                 void SetBlockNumber(AliHLTUInt32_t n) { fBlockNumber = n; }
1419                 
1420                 /// Logs an error message describing the problem with the DDL raw data.
1421                 template <typename ErrorCode, class DecoderHandler>
1422                 void LogError(ErrorCode code, const void* location, DecoderHandler& handler);
1423         
1424         protected:
1425                 // Do not allow copying of this class.
1426                 /// Not implemented
1427                 AliHLTMUONDecoderHandler(const AliHLTMUONDecoderHandler& rhs); // copy constructor
1428                 /// Not implemented
1429                 AliHLTMUONDecoderHandler& operator = (const AliHLTMUONDecoderHandler& rhs); // assignment operator
1430                 
1431                 const void* fBufferStart; ///< Pointer to the start of the current DDL payload buffer.
1432                 const AliHLTComponentBlockData* fDescriptor; ///< Descriptor for the DDL raw data block corresponding to the buffer.
1433                 AliHLTUInt32_t fBlockNumber;  ///< The number / index of the block descriptor.
1434         };
1435         
1436         
1437         template <typename ErrorCode, class DecoderHandler>
1438         void AliHLTMUONDecoderHandler::LogError(ErrorCode code, const void* location, DecoderHandler& handler)
1439         {
1440                 /// Logs a HLT error message describing the problem with the raw DDL data.
1441                 /// \param code  The error code describing the problem.
1442                 /// \param location  A pointer to the location in the raw data buffer
1443                 ///      where the problem was found.
1444                 /// \param handler  The decoder handler object.
1445                 
1446                 long bytepos = long(location) - long(fBufferStart);
1447                 
1448                 // create data type string.
1449                 char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1450                 memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1451                 strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1452                 strncat( dataType, ":", 1 );
1453                 strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1454                 
1455                 HLTError("Problem found with data block %d, fDataType = '%s',"
1456                          " fPtr = %p and fSize = %u bytes."
1457                          " Assuming this is a DDL raw data block."
1458                          " Problem: %s (Error code: %d, at byte %d)",
1459                         fBlockNumber,
1460                         &dataType[0],
1461                         fDescriptor->fPtr,
1462                         fDescriptor->fSize,
1463                         handler.ErrorCodeToMessage(code),
1464                         code,
1465                         bytepos
1466                 );
1467         };
1468         
1469         
1470         /**
1471          * Class for logging decoding errors when checking tracker raw DDL data.
1472          * Used in the AliHLTMUONDataCheckerComponent::CheckRawDataBlock method.
1473          */
1474         class AliHLTMUONTrackerDecoderHandler :
1475                 public AliMUONTrackerDDLDecoderEventHandler, public AliHLTMUONDecoderHandler
1476         {
1477         public:
1478                 AliHLTMUONTrackerDecoderHandler() :
1479                         AliMUONTrackerDDLDecoderEventHandler(),
1480                         AliHLTMUONDecoderHandler(),
1481                         fMaxDigits(0),
1482                         fDigitCount(0),
1483                         fDigits(NULL),
1484                         fCurrentBusPatch(0),
1485                         fDataProblems(false)
1486                 {}
1487                 
1488                 virtual ~AliHLTMUONTrackerDecoderHandler()
1489                 {
1490                         if (fDigits != NULL) delete [] fDigits;
1491                 }
1492                 
1493                 /// Structure to store raw data words found in the raw data.
1494                 struct AliDigit
1495                 {
1496                         UInt_t fBusPatchId;  ///< Bus patch ID for the data word.
1497                         UInt_t fDataWord;   ///< Raw data word found in the DDL payload.
1498                 };
1499                 
1500                 /// Returns the number of digits found.
1501                 UInt_t DigitCount() const { return fDigitCount; }
1502                 
1503                 /// Returns the array of digits found.
1504                 const AliDigit* Digits() const { return fDigits; }
1505                 
1506                 /// Returns true if there were problems with the data.
1507                 bool DataProblems() const { return fDataProblems; }
1508                 
1509                 // Methods inherited from AliMUONTrackerDDLDecoderEventHandler:
1510                 
1511                 /// Called for each new buffer.
1512                 void OnNewBuffer(const void* buffer, UInt_t bufferSize);
1513                 
1514                 /// Called for each new DSP header.
1515                 void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/);
1516                 
1517                 /// Called for each new bus patch. Just marks the current bus patch ID.
1518                 void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* /*data*/)
1519                 {
1520                         fCurrentBusPatch = header->fBusPatchId;
1521                 }
1522                 
1523                 /// Called for each new data word found.
1524                 void OnData(UInt_t data, bool /*parityError*/);
1525                 
1526                 /// Logs an error message if there was a decoding problem with the DDL payload.
1527                 void OnError(ErrorCode code, const void* location)
1528                 {
1529                         fDataProblems = true;
1530                         LogError(code, location, *this);
1531                 }
1532         
1533         private:
1534         
1535                 // Do not allow copying of this object.
1536                 /// Not implemented.
1537                 AliHLTMUONTrackerDecoderHandler(const AliHLTMUONTrackerDecoderHandler& obj);
1538                 /// Not implemented.
1539                 AliHLTMUONTrackerDecoderHandler& operator = (const AliHLTMUONTrackerDecoderHandler& obj);
1540                 
1541                 UInt_t fMaxDigits;  ///< Maximum number of digits that can be stored in fDigits.
1542                 UInt_t fDigitCount;  ///< The number of digits currently stored in fDigits.
1543                 AliDigit* fDigits;  ///< The array of digits found in the DDL data.
1544                 UInt_t fCurrentBusPatch;  ///< The current bus patch ID being processed.
1545                 bool fDataProblems;  ///< flag indicating there were problems with the data.
1546         };
1547         
1548         
1549         void AliHLTMUONTrackerDecoderHandler::OnNewBuffer(const void* buffer, UInt_t bufferSize)
1550         {
1551                 /// Called for a new buffer. It will reset internal counters and
1552                 /// resize the digits array if necessary.
1553                 
1554                 fDataProblems = false;
1555                 fDigitCount = 0;
1556                 fBufferStart = buffer;
1557                 
1558                 // Resize the fDigits array to be able to store
1559                 // all the digits in the data buffer.
1560                 UInt_t maxSize = bufferSize / sizeof(UInt_t) + 1;
1561                 if (maxSize > fMaxDigits)
1562                 {
1563                         if (fDigits != NULL)
1564                         {
1565                                 delete [] fDigits;
1566                                 fDigits = NULL;
1567                                 fMaxDigits = 0;
1568                         }
1569                         try
1570                         {
1571                                 fDigits = new AliDigit[maxSize];
1572                                 fMaxDigits = maxSize;
1573                         }
1574                         catch (const std::bad_alloc&)
1575                         {
1576                                 HLTError("Could not allocate enough buffer space for internal arrays.");
1577                                 return;
1578                         }
1579                 }
1580         }
1581         
1582         
1583         void AliHLTMUONTrackerDecoderHandler::OnNewDSP(
1584                         const AliMUONDSPHeaderStruct* header, const void* /*data*/
1585                 )
1586         {
1587                 if (header->fPaddingWord != 0 and header->fPaddingWord != 1)
1588                 {
1589                         // create data type string.
1590                         char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1591                         memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1592                         strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1593                         strncat( dataType, ":", 1 );
1594                         strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1595                                 
1596                         HLTError("Problem found with data block %d, fDataType = '%s',"
1597                                 " fPtr = %p and fSize = %u bytes."
1598                                 " Assuming this is a tracker DDL raw data block."
1599                                 " Problem: Found padding word marker 0x%8.8X in DSP"
1600                                 " header with DSP ID %d which has an invalid value.",
1601                                 fBlockNumber,
1602                                 &dataType[0],
1603                                 fDescriptor->fPtr,
1604                                 fDescriptor->fSize,
1605                                 header->fPaddingWord,
1606                                 header->fDSPId
1607                         );
1608                         fDataProblems = true;
1609                         return;
1610                 }
1611         }
1612         
1613         
1614         void AliHLTMUONTrackerDecoderHandler::OnData(UInt_t data, bool /*parityError*/)
1615         {
1616                 /// Called for each new data word found. This method will add
1617                 /// these to the list of digits and check if they are not duplicated.
1618                 
1619                 assert( fDigits != NULL );
1620                 
1621                 if ((data & 0x60000000) != 0)
1622                 {
1623                         // create data type string.
1624                         char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1625                         memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1626                         strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1627                         strncat( dataType, ":", 1 );
1628                         strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1629                                 
1630                         HLTError("Problem found with data block %d, fDataType = '%s',"
1631                                 " fPtr = %p and fSize = %u bytes."
1632                                 " Assuming this is a tracker DDL raw data block."
1633                                 " Problem: Found a data word 0x%8.8X for bus patch %d"
1634                                 " whose bits 29 or 30 are not zero.",
1635                                 fBlockNumber,
1636                                 &dataType[0],
1637                                 fDescriptor->fPtr,
1638                                 fDescriptor->fSize,
1639                                 data,
1640                                 fCurrentBusPatch
1641                         );
1642                         fDataProblems = true;
1643                         return;
1644                 }
1645                 
1646                 // Check if the data word + bus patch have been duplicated.
1647                 for (UInt_t i = 0; i < fDigitCount; i++)
1648                 {
1649                         if (fDigits[i].fDataWord == data and fDigits[i].fBusPatchId == fCurrentBusPatch)
1650                         {
1651                                 // create data type string.
1652                                 char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1653                                 memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1654                                 strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1655                                 strncat( dataType, ":", 1 );
1656                                 strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1657                                 
1658                                 HLTError("Problem found with data block %d, fDataType = '%s',"
1659                                         " fPtr = %p and fSize = %u bytes."
1660                                         " Assuming this is a tracker DDL raw data block."
1661                                         " Problem: Found a duplicate data word 0x%8.8X for bus patch %d.",
1662                                         fBlockNumber,
1663                                         &dataType[0],
1664                                         fDescriptor->fPtr,
1665                                         fDescriptor->fSize,
1666                                         data,
1667                                         fCurrentBusPatch
1668                                 );
1669                                 fDataProblems = true;
1670                                 return;
1671                         }
1672                 }
1673                 
1674                 // Add the data word + bus patch to the list of decoded digits.
1675                 if (fDigitCount < fMaxDigits)
1676                 {
1677                         fDigits[fDigitCount].fBusPatchId = fCurrentBusPatch;
1678                         fDigits[fDigitCount].fDataWord = data;
1679                         fDigitCount++;
1680                 }
1681         }
1682         
1683         /**
1684          * Class for logging decoding errors when checking trigger raw DDL data.
1685          * Used in the AliHLTMUONDataCheckerComponent::CheckRawDataBlock method.
1686          */
1687         class AliHLTMUONTriggerDecoderHandler :
1688                 public AliMUONTriggerDDLDecoderEventHandler, public AliHLTMUONDecoderHandler
1689         {
1690         public:
1691                 // Methods inherited from AliMUONTriggerDDLDecoderEventHandler:
1692                 
1693                 /// Called for each new buffer.
1694                 void OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
1695                 {
1696                         fBufferStart = buffer;
1697                 }
1698                 
1699                 /// Logs an error message if there was a decoding problem with the DDL payload.
1700                 void OnError(ErrorCode code, const void* location)
1701                 {
1702                         LogError(code, location, *this);
1703                 }
1704         };
1705         
1706 } // end of namespace
1707
1708
1709 bool AliHLTMUONDataCheckerComponent::CheckRawDataBlock(
1710                 const AliHLTComponentBlockData& block,
1711                 AliHLTUInt32_t blockNumber
1712         ) const
1713 {
1714         /// Checks the validity of a raw data block.
1715         
1716         bool result = true;
1717
1718         if (fIgnoreSpec)
1719         {
1720                 HLTWarning("Not able to check DDL raw data if -ignorespec is specified.");
1721                 return false;
1722         }
1723         
1724         bool ddl[22];
1725         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1726         
1727         // Check that only one DDL was marked in the specification.
1728         int ddlIndex = -1;
1729         for (int i = 0; i < 22; i++)
1730         {
1731                 if (not ddl[i]) continue;
1732                 
1733                 if (ddlIndex == -1)
1734                 {
1735                         ddlIndex = i;
1736                         continue;
1737                 }
1738                 
1739                 HLTError("Problem found with data block %d, fDataType = '%s',"
1740                          " fPtr = %p and fSize = %u bytes."
1741                          " Assuming this is a DDL raw data block."
1742                          " Problem: The specification indicates multiple"
1743                          " DDL sources, DDL %d and %d.",
1744                         blockNumber,
1745                         DataType2Text(block.fDataType).c_str(),
1746                         block.fPtr,
1747                         block.fSize,
1748                         ddlIndex,
1749                         i
1750                 );
1751                 result = false;
1752         }
1753         
1754         // Check the DDL common data header.
1755         AliHLTUInt32_t totalDDLSize = block.fSize;
1756         AliHLTCDHWrapper header(block.fPtr);
1757         if (totalDDLSize < sizeof(AliRawDataHeader) &&
1758             totalDDLSize < header.GetHeaderSize()) // if cdh v3
1759         {
1760                 HLTError("Problem found with data block %d, fDataType = '%s',"
1761                          " fPtr = %p and fSize = %u bytes."
1762                          " Assuming this is a DDL raw data block."
1763                          " Problem: The size of the data block is too short to contain"
1764                          " a valid common DDL data header. Size of buffer is only %d"
1765                          " bytes.",
1766                         blockNumber,
1767                         DataType2Text(block.fDataType).c_str(),
1768                         block.fPtr,
1769                         block.fSize,
1770                         totalDDLSize
1771                 );
1772                 return false;
1773         }
1774         
1775         if (header.GetVersion() < 2)
1776         {
1777                 HLTError("Problem found with data block %d, fDataType = '%s',"
1778                          " fPtr = %p and fSize = %u bytes."
1779                          " Assuming this is a DDL raw data block."
1780                          " Problem: The common DDL data header indicates an"
1781                          " incorrect version number. Expected 2 but got %d.",
1782                         blockNumber,
1783                         DataType2Text(block.fDataType).c_str(),
1784                         block.fPtr,
1785                         block.fSize,
1786                         int( header.GetVersion() )
1787                 );
1788                 result = false;
1789         }
1790         
1791         if (header.GetDataSize() != 0xFFFFFFFF and header.GetDataSize() != block.fSize)
1792         {
1793                 HLTError("Problem found with data block %d, fDataType = '%s',"
1794                          " fPtr = %p and fSize = %u bytes."
1795                          " Assuming this is a DDL raw data block."
1796                          " Problem: The common DDL data header indicates an"
1797                          " incorrect DDL buffer size. Expected %d bytes but"
1798                          " size reported in header is %d bytes.",
1799                         blockNumber,
1800                         DataType2Text(block.fDataType).c_str(),
1801                         block.fPtr,
1802                         block.fSize,
1803                         block.fSize,
1804                         header.GetDataSize()
1805                 );
1806                 result = false;
1807         }
1808         
1809         AliHLTUInt32_t payloadSize = block.fSize - header.GetHeaderSize();
1810         const AliHLTUInt8_t* payload =
1811                 reinterpret_cast<const AliHLTUInt8_t*>(block.fPtr);
1812         payload += header.GetHeaderSize();
1813         
1814         if (AliHLTMUONUtils::IsTriggerDDL(block.fSpecification))
1815         {
1816                 bool scalarEvent = ((header.GetL1TriggerMessage() & 0x1) == 0x1);
1817                 AliMUONTriggerDDLDecoder<AliHLTMUONTriggerDecoderHandler> decoder;
1818                 decoder.ExitOnError(false);
1819                 decoder.TryRecover(false);
1820                 decoder.AutoDetectScalars(false);
1821                 decoder.GetHandler().SetDescriptor(&block);
1822                 decoder.GetHandler().SetBlockNumber(blockNumber);
1823                 result = decoder.Decode(payload, payloadSize, scalarEvent);
1824         }
1825         else if (AliHLTMUONUtils::IsTrackerDDL(block.fSpecification))
1826         {
1827                 AliMUONTrackerDDLDecoder<AliHLTMUONTrackerDecoderHandler> decoder;
1828                 decoder.ExitOnError(false);
1829                 decoder.TryRecover(false);
1830                 decoder.SendDataOnParityError(true);
1831                 decoder.AutoDetectTrailer(true);
1832                 decoder.CheckForTrailer(true);
1833                 decoder.GetHandler().SetDescriptor(&block);
1834                 decoder.GetHandler().SetBlockNumber(blockNumber);
1835                 result = decoder.Decode(payload, payloadSize);
1836                 if (decoder.GetHandler().DataProblems()) result = false;
1837                 
1838                 if (FetchMappingStores() == 0)  // are stores loaded?
1839                 {
1840                         Bool_t warn = kFALSE;
1841                         AliMpDDLStore* ddlStore = AliMpDDLStore::Instance(warn);
1842                         
1843                         // Check that the bus patch, manu ID and channel addresses are valid
1844                         // for each raw data word.
1845                         for (UInt_t i = 0; i < decoder.GetHandler().DigitCount(); i++)
1846                         {
1847                                 UInt_t busPatchId = decoder.GetHandler().Digits()[i].fBusPatchId;
1848                                 UInt_t dataWord = decoder.GetHandler().Digits()[i].fDataWord;
1849                                 
1850                                 UShort_t manuId; UChar_t channelId; UShort_t adc;
1851                                 AliMUONTrackerDDLDecoderEventHandler::UnpackADC(
1852                                                 dataWord, manuId, channelId, adc
1853                                         );
1854                                 
1855                                 // Check if the bus patch is valid.
1856                                 AliMpBusPatch* busPatch = ddlStore->GetBusPatch(busPatchId, warn);
1857                                 if (busPatch == NULL)
1858                                 {
1859                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1860                                                  " fPtr = %p and fSize = %u bytes."
1861                                                  " Assuming this is a tracker DDL raw data block."
1862                                                  " Problem: Found a bus patch identifier %d that"
1863                                                  " is not valid.",
1864                                                 blockNumber,
1865                                                 DataType2Text(block.fDataType).c_str(),
1866                                                 block.fPtr,
1867                                                 block.fSize,
1868                                                 busPatchId
1869                                         );
1870                                         result = false;
1871                                         continue;
1872                                 }
1873                                 
1874                                 // We can check that the bus patch is for the DDL
1875                                 // which is also indicated by the specification bits.
1876                                 if (not fIgnoreSpec and busPatch->GetDdlId() != ddlIndex)
1877                                 {
1878                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1879                                                  " fPtr = %p and fSize = %u bytes."
1880                                                  " Assuming this is a tracker DDL raw data block."
1881                                                  " Problem: Found a bus patch identifier %d for"
1882                                                  " DDL %d, but the data block specification 0x%8.8X"
1883                                                  " indicates a different DDL of %d.",
1884                                                 blockNumber,
1885                                                 DataType2Text(block.fDataType).c_str(),
1886                                                 block.fPtr,
1887                                                 block.fSize,
1888                                                 busPatchId,
1889                                                 busPatch->GetDdlId(),
1890                                                 block.fSpecification,
1891                                                 ddlIndex
1892                                         );
1893                                         result = false;
1894                                         continue;
1895                                 }
1896                                 
1897                                 // Check if the MANU ID is valid.
1898                                 if (not busPatch->HasManu(manuId))
1899                                 {
1900                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1901                                                  " fPtr = %p and fSize = %u bytes."
1902                                                  " Assuming this is a tracker DDL raw data block."
1903                                                  " Problem: Found a MANU identifier %d on bus patch %d"
1904                                                  " that is not valid.",
1905                                                 blockNumber,
1906                                                 DataType2Text(block.fDataType).c_str(),
1907                                                 block.fPtr,
1908                                                 block.fSize,
1909                                                 manuId,
1910                                                 busPatchId
1911                                         );
1912                                         result = false;
1913                                         continue;
1914                                 }
1915                                 
1916                                 // Now try to fetch the detector element to check the MANU channel.
1917                                 AliMpDetElement* de = ddlStore->GetDetElement(busPatch->GetDEId(), warn);
1918                                 if (de == NULL)
1919                                 {
1920                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1921                                                  " fPtr = %p and fSize = %u bytes."
1922                                                  " Assuming this is a tracker DDL raw data block."
1923                                                  " Problem: Found a bus patch identifier %d that"
1924                                                  " does not correspond to a detector element.",
1925                                                 blockNumber,
1926                                                 DataType2Text(block.fDataType).c_str(),
1927                                                 block.fPtr,
1928                                                 block.fSize,
1929                                                 busPatchId
1930                                         );
1931                                         result = false;
1932                                         continue;
1933                                 }
1934                                 
1935                                 if (not de->IsConnectedChannel(manuId, channelId))
1936                                 {
1937                                         // Just a warning because this is marked not
1938                                         // to be an error in the AliMUONDigitMaker.
1939                                         HLTWarning("Problem found with data block %d, fDataType = '%s',"
1940                                                  " fPtr = %p and fSize = %u bytes."
1941                                                  " Assuming this is a tracker DDL raw data block."
1942                                                  " Problem: Found a channel with address %d on"
1943                                                  " MANU ID %d and bus patch %d that is not connected.",
1944                                                 blockNumber,
1945                                                 DataType2Text(block.fDataType).c_str(),
1946                                                 block.fPtr,
1947                                                 block.fSize,
1948                                                 channelId,
1949                                                 manuId,
1950                                                 busPatchId
1951                                         );
1952                                         result = false;
1953                                         continue;
1954                                 }
1955                                 
1956                                 // Need to also load the correct segmentation to check the channel.
1957                                 const AliMpVSegmentation* seg =
1958                                         AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(
1959                                                 busPatch->GetDEId(), manuId
1960                                         );
1961                                 if (seg == NULL)
1962                                 {
1963                                         HLTError("Could not load segmentation for detector element %d"
1964                                                  " and MANU ID %d.",
1965                                                 busPatch->GetDEId(), manuId
1966                                         );
1967                                         result = false;
1968                                         continue;
1969                                 }
1970                                 
1971 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1972                                 AliMpPad pad = seg->PadByLocation(manuId, channelId, warn);
1973 #else // old AliMpPad functionality < r 31742
1974                                 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId, channelId), warn);
1975 #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1976                                 if (not pad.IsValid())
1977                                 {
1978                                         HLTError("Problem found with data block %d, fDataType = '%s',"
1979                                                  " fPtr = %p and fSize = %u bytes."
1980                                                  " Assuming this is a tracker DDL raw data block."
1981                                                  " Problem: Found a channel with address %d on"
1982                                                  " MANU ID %d and bus patch %d that is not valid.",
1983                                                 blockNumber,
1984                                                 DataType2Text(block.fDataType).c_str(),
1985                                                 block.fPtr,
1986                                                 block.fSize,
1987                                                 channelId,
1988                                                 manuId,
1989                                                 busPatchId
1990                                         );
1991                                         result = false;
1992                                         continue;
1993                                 }
1994                         }
1995                 }
1996                 else
1997                 {
1998                         HLTWarning("Cannot check if the bus patch IDs, MANU ID and"
1999                                 " channel addresses for DDL raw data are valid without"
2000                                 " being able to load the mapping from CDB."
2001                         );
2002                         result = false;
2003                 }
2004         }
2005         else
2006         {
2007                 HLTError("Problem found with data block %d, fDataType = '%s',"
2008                          " fPtr = %p and fSize = %u bytes."
2009                          " Assuming this is a DDL raw data block."
2010                          " Problem: The specification does not contain a valid pattern,"
2011                          " received 0x%8.8X for the specification.",
2012                         blockNumber,
2013                         DataType2Text(block.fDataType).c_str(),
2014                         block.fPtr,
2015                         block.fSize,
2016                         block.fSpecification
2017                 );
2018                 result = false;
2019         }
2020         
2021         return result;
2022 }
2023
2024
2025 bool AliHLTMUONDataCheckerComponent::CheckTriggerRecordsBlock(
2026                 const AliHLTComponentBlockData& block,
2027                 AliHLTUInt32_t blockNumber
2028         ) const
2029 {
2030         /// Checks the validity of a trigger records block.
2031
2032         bool result = true;
2033         const char* name = "trigger records";
2034         
2035         if (not fIgnoreSpec)
2036         {
2037                 if (not IsFromTriggerOnly(block, blockNumber, name))
2038                         result = false;
2039         }
2040         
2041         AliHLTMUONTriggerRecordsBlockReader inblock(block.fPtr, block.fSize);
2042         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2043                 return false;
2044         
2045         bool ddl[22];
2046         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2047         
2048         // Min and max allowed chamber numbers for hits:
2049         Int_t minCh = AliMUONConstants::NCh() - AliMUONConstants::NTriggerCh();
2050         Int_t maxCh = AliMUONConstants::NCh() - 1;
2051         
2052         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2053         {
2054                 // Check that each hit in each trigger record has a reasonable coordinate.
2055                 AliHLTMUONParticleSign sign;
2056                 bool hitset[4];
2057                 AliHLTMUONUtils::UnpackTriggerRecordFlags(inblock[i].fFlags, sign, hitset);
2058         
2059                 for (Int_t j = 0; j < 4; j++)  // loop over 4 trigger chamber hits.
2060                 {
2061                         if (not hitset[i]) continue; // ignore hits that are not initialised.
2062                         bool hitOk = IsHitCoordinateOk(
2063                                         block, blockNumber, name, i, inblock[i].fHit[j],
2064                                         minCh, maxCh, j+10, ddl
2065                                 );
2066                         if (not hitOk) result = false;
2067                 }
2068                 
2069                 // We can also check the momentum vector.
2070                 bool momOk = IsMomentumVectorOk(
2071                                 block, blockNumber, name, i,
2072                                 inblock[i].fPx, inblock[i].fPy, inblock[i].fPz
2073                         );
2074                 if (not momOk) result = false;
2075         }
2076         
2077         // Need to check that no entries have duplicated data but with a different
2078         // ID number.
2079         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2080         {
2081                 AliHLTMUONTriggerRecordStruct ti = inblock[i];
2082                 ti.fId = -1;
2083                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2084                 {
2085                         AliHLTMUONTriggerRecordStruct tj = inblock[j];
2086                         tj.fId = ti.fId;
2087                         
2088                         if (ti == tj)
2089                         {
2090                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2091                                         " fPtr = %p and fSize = %u bytes."
2092                                         " Assuming this is a %s data block."
2093                                         " Problem: The trigger records %d and %d contain the"
2094                                         " same data. The data might have been duplicated.",
2095                                         blockNumber,
2096                                         DataType2Text(block.fDataType).c_str(),
2097                                         block.fPtr,
2098                                         block.fSize,
2099                                         name,
2100                                         i, j
2101                                 );
2102                                 result = false;
2103                         }
2104                 }
2105         }
2106         
2107         return result;
2108 }
2109
2110
2111 bool AliHLTMUONDataCheckerComponent::CheckTrigRecsDebugBlock(
2112                 const AliHLTComponentBlockData& block,
2113                 AliHLTUInt32_t blockNumber
2114         ) const
2115 {
2116         /// Checks the validity of a trigger records debug block.
2117         
2118         bool result = true;
2119         const char* name = "trigger records debug information";
2120         
2121         if (not fIgnoreSpec)
2122         {
2123                 if (not IsFromTriggerOnly(block, blockNumber, name))
2124                         result = false;
2125         }
2126         
2127         AliHLTMUONTrigRecsDebugBlockReader inblock(block.fPtr, block.fSize);
2128         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2129                 return false;
2130         
2131         bool ddl[22];
2132         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2133         
2134         // Check that each detector element ID is valid and the corresponding DDL
2135         // bit is set in the data block specification.
2136         if (FetchMappingStores() == 0)  // are stores loaded?
2137         {
2138                 Bool_t warn = kFALSE;
2139                 AliMpDEStore* store = AliMpDEStore::Instance(warn);
2140                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2141                 for (AliHLTUInt32_t j = 0; j < 4; j++)
2142                 {
2143                         const AliHLTMUONTrigRecInfoStruct& trig = inblock[i];
2144                         AliMpDetElement* de = store->GetDetElement(trig.fDetElemId[j], warn);
2145                         if (de == NULL)
2146                         {
2147                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2148                                          " fPtr = %p and fSize = %u bytes."
2149                                          " Assuming this is a %s data block."
2150                                          " Problem: The detector element number %d on chamber"
2151                                          " %d for trigger record debug structure %d is not valid.",
2152                                         blockNumber,
2153                                         DataType2Text(block.fDataType).c_str(),
2154                                         block.fPtr,
2155                                         block.fSize,
2156                                         name,
2157                                         trig.fDetElemId[j],
2158                                         j+11,
2159                                         i
2160                                 );
2161                                 result = false;
2162                                 continue;
2163                         }
2164                         
2165                         // Check that the chamber number from the detector element number
2166                         // has the expected value.
2167                         Int_t chamber = AliMpDEManager::GetChamberId(trig.fDetElemId[j], warn);
2168                         if (chamber != Int_t(j+10))
2169                         {
2170                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2171                                          " fPtr = %p and fSize = %u bytes."
2172                                          " Assuming this is a %s data block."
2173                                          " Problem: The detector element number %d for trigger"
2174                                          " record debug structure %d, corresponds to chamber"
2175                                          " %d, but we expected a hit for chamber %d.",
2176                                         blockNumber,
2177                                         DataType2Text(block.fDataType).c_str(),
2178                                         block.fPtr,
2179                                         block.fSize,
2180                                         name,
2181                                         trig.fDetElemId[j],
2182                                         i,
2183                                         chamber+1,
2184                                         j+11
2185                                 );
2186                                 result = false;
2187                         }
2188                         
2189                         if (fIgnoreSpec) continue;
2190                         if (0 <= de->GetDdlId() and de->GetDdlId() < 22 and not ddl[de->GetDdlId()])
2191                         {
2192                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2193                                          " fPtr = %p and fSize = %u bytes."
2194                                          " Assuming this is a %s data block."
2195                                          " Problem: The detector element number %d for trigger"
2196                                          " record %d corresponds to DDL number %d, but the"
2197                                          " data block specification 0x%8.8X does not have the"
2198                                          " corresponding bit set.",
2199                                         blockNumber,
2200                                         DataType2Text(block.fDataType).c_str(),
2201                                         block.fPtr,
2202                                         block.fSize,
2203                                         name,
2204                                         trig.fDetElemId[j],
2205                                         i,
2206                                         de->GetDdlId(),
2207                                         block.fSpecification
2208                                 );
2209                                 result = false;
2210                         }
2211                 }
2212         }
2213         else
2214         {
2215                 HLTWarning("Cannot check trigger record debug information without"
2216                         " being able to load the mapping from CDB."
2217                 );
2218                 result = false;
2219         }
2220         
2221         // Need to check that no entries have duplicated data but with a different
2222         // ID number.
2223         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2224         {
2225                 AliHLTMUONTrigRecInfoStruct ti = inblock[i];
2226                 ti.fTrigRecId = -1;
2227                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2228                 {
2229                         AliHLTMUONTrigRecInfoStruct tj = inblock[j];
2230                         tj.fTrigRecId = ti.fTrigRecId;
2231                         
2232                         if (ti == tj)
2233                         {
2234                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2235                                         " fPtr = %p and fSize = %u bytes."
2236                                         " Assuming this is a %s data block."
2237                                         " Problem: The trigger record debug information"
2238                                         " structures %d and %d contain the same data."
2239                                         " The data might have been duplicated.",
2240                                         blockNumber,
2241                                         DataType2Text(block.fDataType).c_str(),
2242                                         block.fPtr,
2243                                         block.fSize,
2244                                         name,
2245                                         i, j
2246                                 );
2247                                 result = false;
2248                         }
2249                 }
2250                 
2251                 // Can also check that the value of the fZmiddle and fBl.
2252                 bool paramsOk = AreMomentumCalcParamsOk(
2253                                 block, blockNumber, name, i, ti.fZmiddle, ti.fBl
2254                         );
2255                 if (not paramsOk) result = false;
2256         }
2257         
2258         return result;
2259 }
2260
2261
2262 bool AliHLTMUONDataCheckerComponent::CheckRecHitsBlock(
2263                 const AliHLTComponentBlockData& block,
2264                 AliHLTUInt32_t blockNumber
2265         ) const
2266 {
2267         /// Checks the validity of a reconstructed hits block.
2268
2269         bool result = true;
2270         const char* name = "reconstructed hits";
2271         
2272         if (not fIgnoreSpec)
2273         {
2274                 if (not IsFromTrackerOnly(block, blockNumber, name))
2275                         result = false;
2276         }
2277         
2278         AliHLTMUONRecHitsBlockReader inblock(block.fPtr, block.fSize);
2279         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2280                 return false;
2281         
2282         bool ddl[22];
2283         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2284         
2285         // Check that each hit has a reasonable coordinate.
2286         Int_t minCh = 0;
2287         Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
2288         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2289         {
2290                 bool hitOk = IsHitCoordinateOk(
2291                                 block, blockNumber, name, i, inblock[i],
2292                                 minCh, maxCh, -1, ddl
2293                         );
2294                 if (not hitOk) result = false;
2295         }
2296         
2297         return result;
2298 }
2299
2300
2301 bool AliHLTMUONDataCheckerComponent::CheckClustersBlock(
2302                 const AliHLTComponentBlockData& block,
2303                 AliHLTUInt32_t blockNumber
2304         ) const
2305 {
2306         /// Checks the validity of a clusters block.
2307
2308         bool result = true;
2309         const char* name = "clusters";
2310         
2311         if (not fIgnoreSpec)
2312         {
2313                 if (not IsFromTrackerOnly(block, blockNumber, name))
2314                         result = false;
2315         }
2316         
2317         AliHLTMUONClustersBlockReader inblock(block.fPtr, block.fSize);
2318         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2319                 return false;
2320         
2321         bool ddl[22];
2322         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2323         
2324         if (FetchMappingStores() == 0)  // are stores loaded?
2325         {
2326                 Bool_t warn = kFALSE;
2327                 AliMpDEStore* store = AliMpDEStore::Instance(warn);
2328                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2329                 {
2330                         const AliHLTMUONClusterStruct& cluster = inblock[i];
2331                         
2332                         // Check that the detector element ID is valid.
2333                         AliMpDetElement* de = store->GetDetElement(cluster.fDetElemId, warn);
2334                         if (de == NULL)
2335                         {
2336                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2337                                          " fPtr = %p and fSize = %u bytes."
2338                                          " Assuming this is a %s data block."
2339                                          " Problem: The detector element number %d for cluster"
2340                                          " %d is not valid.",
2341                                         blockNumber,
2342                                         DataType2Text(block.fDataType).c_str(),
2343                                         block.fPtr,
2344                                         block.fSize,
2345                                         name,
2346                                         cluster.fDetElemId,
2347                                         i
2348                                 );
2349                                 result = false;
2350                                 continue;
2351                         }
2352                         
2353                         // Check that the chamber number found from the hit coordinate and
2354                         // that from the detector element number are the same.
2355                         Int_t chamberFromHit = AliMUONConstants::ChamberNumber(cluster.fHit.fZ, warn);
2356                         Int_t chamberFromDE = AliMpDEManager::GetChamberId(cluster.fDetElemId, warn);
2357                         if (chamberFromHit != chamberFromDE)
2358                         {
2359                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2360                                          " fPtr = %p and fSize = %u bytes."
2361                                          " Assuming this is a %s data block."
2362                                          " Problem: The detector element number %d for"
2363                                          " cluster %d, corresponds to chamber %d, but"
2364                                          " found a different chamber number %d for the"
2365                                          " corresponding hit coordinate {x = %f, y = %f,"
2366                                          " z = %f}.",
2367                                         blockNumber,
2368                                         DataType2Text(block.fDataType).c_str(),
2369                                         block.fPtr,
2370                                         block.fSize,
2371                                         name,
2372                                         cluster.fDetElemId,
2373                                         i,
2374                                         chamberFromDE+1,
2375                                         chamberFromHit+1,
2376                                         cluster.fHit.fX,
2377                                         cluster.fHit.fY,
2378                                         cluster.fHit.fZ
2379                                 );
2380                                 result = false;
2381                         }
2382                         
2383                         // Make sure the corresponding DDL bit is set in the data
2384                         // block specification.
2385                         if (fIgnoreSpec) continue;
2386                         if (0 <= de->GetDdlId() and de->GetDdlId() < 22 and not ddl[de->GetDdlId()])
2387                         {
2388                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2389                                          " fPtr = %p and fSize = %u bytes."
2390                                          " Assuming this is a %s data block."
2391                                          " Problem: The detector element number %d for cluster"
2392                                          " %d corresponds to DDL number %d, but the data"
2393                                          " block specification 0x%8.8X does not have the"
2394                                          " corresponding bit set.",
2395                                         blockNumber,
2396                                         DataType2Text(block.fDataType).c_str(),
2397                                         block.fPtr,
2398                                         block.fSize,
2399                                         name,
2400                                         cluster.fDetElemId,
2401                                         i,
2402                                         de->GetDdlId(),
2403                                         block.fSpecification
2404                                 );
2405                                 result = false;
2406                         }
2407                         
2408                         // Check that the total cluster charge is a reasonable value.
2409                         if ((cluster.fChargeB + cluster.fChargeNB)< 0 and 1e4 < (cluster.fChargeB + cluster.fChargeNB))
2410                         {
2411                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2412                                          " fPtr = %p and fSize = %u bytes."
2413                                          " Assuming this is a %s data block."
2414                                          " Problem: The total charge %f for the cluster"
2415                                          " %d is not in a reasonable range [0..1e4].",
2416                                         blockNumber,
2417                                         DataType2Text(block.fDataType).c_str(),
2418                                         block.fPtr,
2419                                         block.fSize,
2420                                         name,
2421                                         (cluster.fChargeB + cluster.fChargeNB),
2422                                         i
2423                                 );
2424                                 result = false;
2425                                 continue;
2426                         }
2427                 }
2428         }
2429         else
2430         {
2431                 HLTWarning("Cannot check cluster information without being able"
2432                         " to load the mapping from CDB."
2433                 );
2434                 result = false;
2435         }
2436         
2437         // Min and max chamber numbers allowed for the cluster hits.
2438         Int_t minCh = 0;
2439         Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
2440         
2441         for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2442         {
2443                 // Need to check that no cluster data has duplicated data but with
2444                 // a different ID number.
2445                 AliHLTMUONClusterStruct ci = inblock[i];
2446                 ci.fId = -1;
2447                 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2448                 {
2449                         AliHLTMUONClusterStruct cj = inblock[j];
2450                         cj.fId = ci.fId;
2451                         
2452                         if (ci == cj)
2453                         {
2454                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2455                                         " fPtr = %p and fSize = %u bytes."
2456                                         " Assuming this is a %s data block."
2457                                         " Problem: The cluster structures %d and %d contain"
2458                                         " the same data. The data might have been duplicated.",
2459                                         blockNumber,
2460                                         DataType2Text(block.fDataType).c_str(),
2461                                         block.fPtr,
2462                                         block.fSize,
2463                                         name,
2464                                         i, j
2465                                 );
2466                                 result = false;
2467                         }
2468                 }
2469                 
2470                 // Check that the hit structure in the cluster corresponds
2471                 // to a tracker chamber.
2472                 bool hitOk = IsHitCoordinateOk(
2473                                 block, blockNumber, name, i, ci.fHit,
2474                                 minCh, maxCh, -1, ddl
2475                         );
2476                 if (not hitOk) result = false;
2477         }
2478         
2479         return result;
2480 }
2481
2482
2483 bool AliHLTMUONDataCheckerComponent::CheckChannelsBlock(
2484                 const AliHLTComponentBlockData& block,
2485                 AliHLTUInt32_t blockNumber
2486         ) const
2487 {
2488         /// Checks the validity of a channels block.
2489
2490         bool result = true;
2491         const char* name = "channels";
2492         
2493         if (not fIgnoreSpec)
2494         {
2495                 if (not IsFromTrackerOnly(block, blockNumber, name))
2496                         result = false;
2497         }
2498         
2499         AliHLTMUONChannelsBlockReader inblock(block.fPtr, block.fSize);
2500         if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2501                 return false;
2502         
2503         bool ddl[22];
2504         AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2505         
2506         if (FetchMappingStores() == 0)  // are stores loaded?
2507         {
2508                 Bool_t warn = kFALSE;
2509                 AliMpDDLStore* store = AliMpDDLStore::Instance(warn);
2510                 
2511                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2512                 {
2513                         const AliHLTMUONChannelStruct& channel = inblock[i];
2514                         
2515                         // Check if the bus patch is valid.
2516                         AliMpBusPatch* busPatch = store->GetBusPatch(channel.fBusPatch, warn);
2517                         if (busPatch == NULL)
2518                         {
2519                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2520                                         " fPtr = %p and fSize = %u bytes."
2521                                         " Assuming this is a %s data block."
2522                                         " Problem: Found a bus patch identifier %d that"
2523                                         " is not valid.",
2524                                         blockNumber,
2525                                         DataType2Text(block.fDataType).c_str(),
2526                                         block.fPtr,
2527                                         block.fSize,
2528                                         name,
2529                                         channel.fBusPatch
2530                                 );
2531                                 result = false;
2532                                 continue;
2533                         }
2534                         
2535                         // We can check that the bus patch is for a DDL
2536                         // which is also indicated by the specification bits.
2537                         if (not fIgnoreSpec and (
2538                              not (0 <= busPatch->GetDdlId() and busPatch->GetDdlId() < 20)
2539                              or  (0 <= busPatch->GetDdlId() and busPatch->GetDdlId() < 20
2540                                   and not ddl[busPatch->GetDdlId()])
2541                            ))
2542                         {
2543                                 HLTError("Problem found with data block %d, fDataType = '%s',"
2544                                          " fPtr = %p and fSize = %u bytes."
2545                                          " Assuming this is a %s data block."
2546                                          " Problem: Found a bus patch identifier %d for"
2547                                          " DDL %d, but the data block specification 0x%8.8X"
2548                                          " does not have the corresponding bit set.",
2549                                         blockNumber,
2550                                         DataType2Text(block.fDataType).c_str(),
2551                                         block.fPtr,
2552                                         block.fSize,
2553                                         name,
2554