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