First version of the analysis QA
[u/mrichter/AliRoot.git] / HLT / MUON / utils / AliHLTMUONDataCheckerComponent.cxx
CommitLineData
dba14d7d 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
887a669c 17/* $Id: AliHLTMUONDataCheckerComponent.cxx 26179 2008-05-29 22:27:27Z aszostak $ */
dba14d7d 18
19///
20/// @file AliHLTMUONDataCheckerComponent.cxx
21/// @author Artur Szostak <artursz@iafrica.com>
887a669c 22/// @date 27 May 2008
dba14d7d 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
56namespace
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
88ClassImp(AliHLTMUONDataCheckerComponent)
89
90
91AliHLTMUONDataCheckerComponent::AliHLTMUONDataCheckerComponent() :
92 AliHLTMUONProcessor(),
93 fIgnoreType(false),
94 fIgnoreSpec(false),
95 fDontForward(false),
96 fFilterBadBlocks(false),
97 fNoGlobalChecks(false),
887a669c 98 fWarnForUnexpecedBlock(false),
99 fReturnError(false)
dba14d7d 100{
101 /// Default constructor.
102}
103
104
105AliHLTMUONDataCheckerComponent::~AliHLTMUONDataCheckerComponent()
106{
107 /// Default destructor.
108}
109
110const char* AliHLTMUONDataCheckerComponent::GetComponentID()
111{
112 /// Inherited from AliHLTComponent. Returns the component ID.
113
114 return AliHLTMUONConstants::DataCheckerComponentId();
115}
116
117
118void 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
129AliHLTComponentDataType 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
138void 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
152AliHLTComponent* AliHLTMUONDataCheckerComponent::Spawn()
153{
154 /// Inherited from AliHLTComponent. Creates a new object instance.
155
156 return new AliHLTMUONDataCheckerComponent;
157}
158
159
160int 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;
887a669c 174 fReturnError = false;
dba14d7d 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 }
887a669c 202 if (strcmp(argv[i], "-no_global_check") == 0)
dba14d7d 203 {
204 fNoGlobalChecks = true;
205 HLTInfo("Only per block data consistancy checks will be applied,"
887a669c 206 " but no global checks will be made."
dba14d7d 207 );
208 continue;
209 }
210 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
211 {
212 fWarnForUnexpecedBlock = true;
213 continue;
214 }
887a669c 215 if (strcmp(argv[i], "-return_error") == 0)
216 {
217 fReturnError = true;
218 continue;
219 }
dba14d7d 220
221 HLTError("Unknown option '%s'.", argv[i]);
222 return -EINVAL;
223 }
224
225 return 0;
226}
227
228
229int 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
238int 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,
887a669c 256 // also arrays to store specific.
257 bool dataProblems = false;
dba14d7d 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 }
887a669c 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 }
dba14d7d 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;
887a669c 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 }
dba14d7d 506 return 0;
507}
508
509
510bool 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
541bool 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
580bool 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
619bool 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
694bool 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
771bool 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.
a090ff22 786 /// We also check if the fFlags containing the chamber number and detector
787 /// element ID are correct.
dba14d7d 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
a090ff22 805 AliHLTUInt8_t chNum = 0xFF;
806 AliHLTUInt16_t detElemId = 0xFFFF;
807 AliHLTMUONUtils::UnpackRecHitFlags(hit.fFlags, chNum, detElemId);
808
dba14d7d 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
a090ff22 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;
8a9e21f6 851 if (minChamber <= Int_t(chNum) and Int_t(chNum) <= maxChamber)
a090ff22 852 {
853 // Rather use the explicit value in the data if it
854 // is in range.
855 chamber = chNum;
856 }
857 }
858
dba14d7d 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
a090ff22 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,
8a9e21f6 970 detElemId,
a090ff22 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
dba14d7d 984 return result;
985}
986
987
988bool 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
a090ff22 1063bool 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
1128bool 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
dba14d7d 1189namespace
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
a090ff22 1310 /// Called for each new DSP header.
1311 void OnNewDSP(const AliMUONDSPHeaderStruct* header, const void* /*data*/);
1312
dba14d7d 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
a090ff22 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
dba14d7d 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
a090ff22 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
dba14d7d 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
1505bool 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
887a669c 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
dba14d7d 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 {
a090ff22 1651 bool scalarEvent = ((header->GetL1TriggerMessage() & 0x1) == 0x1);
dba14d7d 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
1856bool 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
1942bool 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
2093bool 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);
a090ff22 2110 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
dba14d7d 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
2132bool 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
2294bool 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
2517bool AliHLTMUONDataCheckerComponent::CheckMansoTracksBlock(
2518 const AliHLTComponentBlockData& block,
2519 AliHLTUInt32_t blockNumber
2520 ) const
2521{
2522 /// Checks the validity of a Manso tracks block.
2523
2524 bool result = true;
2525 const char* name = "Manso tracks";
2526
2527 if (not fIgnoreSpec)
2528 {
2529 if (not IsSpecificationValid(block, blockNumber, name))
2530 result = false;
2531 }
2532
2533 AliHLTMUONMansoTracksBlockReader inblock(block.fPtr, block.fSize);
2534 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2535 return false;
2536
2537 bool ddl[22];
2538 AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2539
2540 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2541 {
2542 // Need to check that no entries have duplicated data but with
2543 // a different track ID number.
2544 AliHLTMUONMansoTrackStruct ti = inblock[i];
2545 ti.fId = -1;
2546 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2547 {
2548 AliHLTMUONMansoTrackStruct tj = inblock[j];
2549 tj.fId = ti.fId;
2550
2551 if (ti == tj)
2552 {
2553 HLTError("Problem found with data block %d, fDataType = '%s',"
2554 " fPtr = %p and fSize = %u bytes."
2555 " Assuming this is a %s data block."
2556 " Problem: The Manso tracks %d and %d contain the"
2557 " same data. The data might have been duplicated.",
2558 blockNumber,
2559 DataType2Text(block.fDataType).c_str(),
2560 block.fPtr,
2561 block.fSize,
2562 name,
2563 i, j
2564 );
2565 result = false;
2566 }
2567 }
2568
2569 bool trackOk = IsMansoTrackOk(block, blockNumber, name, i, ti, ddl);
2570 if (not trackOk) result = false;
2571 }
2572
2573 return result;
2574}
2575
2576
2577bool AliHLTMUONDataCheckerComponent::CheckMansoCandidatesBlock(
2578 const AliHLTComponentBlockData& block,
2579 AliHLTUInt32_t blockNumber
2580 ) const
2581{
2582 /// Checks the validity of a Manso candidates block.
2583
2584 bool result = true;
2585 const char* name = "Manso track candidates";
2586
2587 if (not fIgnoreSpec)
2588 {
2589 if (not IsSpecificationValid(block, blockNumber, name))
2590 result = false;
2591 }
2592
2593 AliHLTMUONMansoCandidatesBlockReader inblock(block.fPtr, block.fSize);
2594 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2595 return false;
2596
2597 bool ddl[22];
2598 AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2599
2600 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2601 {
2602 // Need to check that no entries have duplicated data but with a
2603 // different track ID number.
2604 AliHLTMUONMansoCandidateStruct ti = inblock[i];
2605 ti.fTrack.fId = -1;
2606 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2607 {
2608 AliHLTMUONMansoCandidateStruct tj = inblock[j];
2609 tj.fTrack.fId = ti.fTrack.fId;
2610
2611 if (ti == tj)
2612 {
2613 HLTError("Problem found with data block %d, fDataType = '%s',"
2614 " fPtr = %p and fSize = %u bytes."
2615 " Assuming this is a %s data block."
2616 " Problem: The Manso track candidates %d and %d"
2617 " contain the same data."
2618 " The data might have been duplicated.",
2619 blockNumber,
2620 DataType2Text(block.fDataType).c_str(),
2621 block.fPtr,
2622 block.fSize,
2623 name,
2624 i, j
2625 );
2626 result = false;
2627 }
2628 }
2629
2630 bool trackOk = IsMansoTrackOk(block, blockNumber, name, i, ti.fTrack, ddl);
2631 if (not trackOk) result = false;
2632
2633 // Check that each ROI has a centre point somewhere on the correct
2634 // corresponding chamber and that the Radius is not bigger thant
2635 // the diameter of the chamber which would be pointless.
2636 for (AliHLTInt32_t j = 0; j < 4; j++)
2637 {
2638 if (ti.fRoI[j].fRadius == -1) continue; // Ignore invalid ROIs
2639
2640 Int_t chamber = AliMUONConstants::ChamberNumber(
2641 ti.fRoI[j].fZ, false // false = do not warn.
2642 );
2643 if (chamber != j+6)
2644 {
2645 HLTError("Problem found with data block %d, fDataType = '%s',"
2646 " fPtr = %p and fSize = %u bytes."
2647 " Assuming this is a %s data block."
2648 " Problem: The region of interest on chamber %d for"
2649 " Manso track candidate %d has a z-coordinate of %f"
2650 " cm that does not correspond to that chamber.",
2651 blockNumber,
2652 DataType2Text(block.fDataType).c_str(),
2653 block.fPtr,
2654 block.fSize,
2655 name,
2656 j+6+1,
2657 i,
2658 ti.fRoI[j].fZ
2659 );
2660 result = false;
2661 }
2662
2663 double x = ti.fRoI[j].fX;
2664 double y = ti.fRoI[j].fY;
2665 double r = sqrt(x*x + y*y);
2666 if (r > AliMUONConstants::Dmax((j+6)/2))
2667 {
2668 // Just a warning since this is not a data integrity problem
2669 // but rather just a data sanity problem.
2670 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2671 " fPtr = %p and fSize = %u bytes."
2672 " Assuming this is a %s data block."
2673 " Problem: The region of interest coordinate {x = %f,"
2674 " y = %f} cm on chamber %d for Manso track candidate %d"
2675 " does not correspond to that chamber.",
2676 blockNumber,
2677 DataType2Text(block.fDataType).c_str(),
2678 block.fPtr,
2679 block.fSize,
2680 name,
2681 ti.fRoI[j].fX,
2682 ti.fRoI[j].fY,
2683 j+6+1,
2684 i
2685 );
2686 result = false;
2687 }
2688
2689 if (ti.fRoI[j].fRadius > AliMUONConstants::Dmax((j+6)/2))
2690 {
2691 // Just a warning since this is not a data integrity problem
2692 // but rather just a data sanity problem.
2693 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2694 " fPtr = %p and fSize = %u bytes."
2695 " Assuming this is a %s data block."
2696 " Problem: The region of interest radius of %f cm"
2697 " on chamber %d for Manso track candidate %d"
2698 " is bigger than the chamber diameter %f cm.",
2699 blockNumber,
2700 DataType2Text(block.fDataType).c_str(),
2701 block.fPtr,
2702 block.fSize,
2703 name,
2704 ti.fRoI[j].fRadius,
2705 j+6+1,
2706 i,
2707 AliMUONConstants::Dmax((j+6)/2)
2708 );
2709 result = false;
2710 }
2711 }
2712 }
2713
2714 return result;
2715}
2716
2717
2718bool AliHLTMUONDataCheckerComponent::CheckSinglesDecisionBlock(
2719 const AliHLTComponentBlockData& block,
2720 AliHLTUInt32_t blockNumber
2721 ) const
2722{
2723 /// Checks the validity of a single tracks trigger decision block.
2724
2725 bool result = true;
2726 const char* name = "singles decision";
2727
2728 if (not fIgnoreSpec)
2729 {
2730 if (not IsSpecificationValid(block, blockNumber, name))
2731 result = false;
2732 }
2733
2734 AliHLTMUONSinglesDecisionBlockReader inblock(block.fPtr, block.fSize);
2735 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2736 return false;
2737
2738 return result;
2739}
2740
2741
2742bool AliHLTMUONDataCheckerComponent::CheckPairsDecisionBlock(
2743 const AliHLTComponentBlockData& block,
2744 AliHLTUInt32_t blockNumber
2745 ) const
2746{
2747 /// Checks the validity of a track pairs trigger decision block.
2748
2749 bool result = true;
2750 const char* name = "pairs decision";
2751
2752 if (not fIgnoreSpec)
2753 {
2754 if (not IsSpecificationValid(block, blockNumber, name))
2755 result = false;
2756 }
2757
2758 AliHLTMUONPairsDecisionBlockReader inblock(block.fPtr, block.fSize);
2759 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2760 return false;
2761
2762 return result;
2763}
2764
2765
2766bool AliHLTMUONDataCheckerComponent::AreMomentaCompatible(
2767 AliHLTFloat32_t px1,
2768 AliHLTFloat32_t py1,
2769 AliHLTFloat32_t pz1,
2770 AliHLTFloat32_t px2,
2771 AliHLTFloat32_t py2,
2772 AliHLTFloat32_t pz2
2773 ) const
2774{
2775 /// Checks to see if the two momenta vectors are compatible or not.
2776 /// The vectors should not have an angle more than 10 degrees between
2777 /// them and their magnitudes should not be more different than 50%.
2778
a3d4b6ba 2779 double p1 = sqrt(double(px1)*double(px1) + double(py1)*double(py1) + double(pz1)*double(pz1));
2780 double p2 = sqrt(double(px2)*double(px2) + double(py2)*double(py2) + double(pz2)*double(pz2));
dba14d7d 2781 if (p1 == 0 and p2 == 0) return true;
2782 if (fabs(p1 - p2) / ((p1 + p2)*0.5) > 0.5) return false;
2783 double denom = p1 * p2;
2784 if (denom == 0) return false;
a3d4b6ba 2785 double ratio = (double(px1)*double(px2) + double(py1)*double(py2) + double(pz1)*double(pz2)) / denom;
2786 if (ratio < -1) return true;
2787 if (ratio > 1) return true;
2788 double angle = acos(ratio);
dba14d7d 2789 if (angle > 3.14159265358979323846 * 10. / 180.) return false;
2790 return true;
2791}
2792
2793
2794bool AliHLTMUONDataCheckerComponent::IsScalarTooLarge(
2795 const AliHLTComponentBlockData* block,
2796 AliHLTUInt32_t blockNumber,
2797 const char* blockTypeName,
2798 const char* scalarName,
2799 AliHLTUInt32_t scalarValue,
2800 AliHLTUInt32_t totalTrackCount
2801 ) const
2802{
2803 /// Checks if the scalar value is larger than the number of Manso
2804 /// tracks in the event.
2805
2806 if (scalarValue > totalTrackCount)
2807 {
2808 HLTError("Problem found with %s trigger decision"
2809 " data block %d, fDataType = '%s', fPtr = %p and"
2810 " fSize = %u bytes."
2811 " Problem: The %s scalar with value %d is larger"
2812 " than the total number of Manso tracks found for the"
2813 " event (%d tracks).",
2814 blockTypeName,
2815 blockNumber,
2816 DataType2Text(block->fDataType).c_str(),
2817 block->fPtr,
2818 block->fSize,
2819 scalarName,
2820 scalarValue,
2821 totalTrackCount
2822 );
2823 return true;
2824 }
2825 else
2826 {
2827 return false;
2828 }
2829}
2830
2831
2832bool AliHLTMUONDataCheckerComponent::IsScalarALargerThanB(
2833 const AliHLTComponentBlockData* block,
2834 AliHLTUInt32_t blockNumber,
2835 const char* blockTypeName,
2836 const char* scalarAName,
2837 AliHLTUInt32_t scalarAValue,
2838 const char* scalarBName,
2839 AliHLTUInt32_t scalarBValue
2840 ) const
2841{
2842 /// Checks if the scalar value is larger than the number of Manso
2843 /// tracks in the event.
2844
2845 if (scalarAValue > scalarBValue)
2846 {
2847 HLTError("Problem found with %s trigger decision"
2848 " data block %d, fDataType = '%s', fPtr = %p and"
2849 " fSize = %u bytes."
2850 " Problem: The %s scalar with value %d is larger"
2851 " than scalar %s with value %d, but is should not be.",
2852 blockTypeName,
2853 blockNumber,
2854 DataType2Text(block->fDataType).c_str(),
2855 block->fPtr,
2856 block->fSize,
2857 scalarAName,
2858 scalarAValue,
2859 scalarBName,
2860 scalarBValue
2861 );
2862 return true;
2863 }
2864 else
2865 {
2866 return false;
2867 }
2868}
2869
2870
2871void AliHLTMUONDataCheckerComponent::MarkBlock(
2872 const AliHLTComponentBlockData* blocks,
2873 bool* blockOk,
2874 AliHLTUInt32_t blockCount,
2875 const AliHLTComponentBlockData* blockToMark
2876 ) const
2877{
2878 /// Tries to find the 'blockToMark' in the list of blocks and sets the
2879 /// corresponding 'blockOk' flag to false.
2880
2881 for (AliHLTUInt32_t i = 0; i < blockCount; i++)
2882 {
2883 if (&blocks[i] == blockToMark)
2884 {
2885 blockOk[i] = false;
2886 return;
2887 }
2888 }
2889}
2890
2891
2892void AliHLTMUONDataCheckerComponent::MakeGlobalChecks(
2893 const AliHLTComponentBlockData* blocks,
2894 bool* blockOk,
2895 AliHLTUInt32_t blockCount,
2896 const AliHLTComponentBlockData** trigRecBlocks,
2897 AliHLTUInt32_t trigRecBlocksCount,
2898 const AliHLTComponentBlockData** trigRecDebugBlocks,
2899 AliHLTUInt32_t trigRecDebugBlocksCount,
2900 const AliHLTComponentBlockData** hitBlocks,
2901 AliHLTUInt32_t hitBlocksCount,
2902 const AliHLTComponentBlockData** clusterBlocks,
2903 AliHLTUInt32_t clusterBlocksCount,
2904 const AliHLTComponentBlockData** channelBlocks,
2905 AliHLTUInt32_t channelBlocksCount,
2906 const AliHLTComponentBlockData** mansoTrackBlocks,
2907 AliHLTUInt32_t mansoTrackBlocksCount,
2908 const AliHLTComponentBlockData** mansoCandidateBlocks,
2909 AliHLTUInt32_t mansoCandidateBlocksCount,
2910 const AliHLTComponentBlockData** singleDecisionBlocks,
2911 AliHLTUInt32_t singleDecisionBlocksCount,
2912 const AliHLTComponentBlockData** pairDecisionBlocks,
2913 AliHLTUInt32_t pairDecisionBlocksCount
2914 ) const
2915{
2916 /// The following set of global checks are performed:
2917 /// 1) Checks if all the ID numbers in all the blocks are unique.
2918 /// 2) Check if all the structures are unique up to their ID numbers,
2919 /// that it, make sure there are no structures with the same data but
2920 /// for a different ID number.
2921 /// 3) Check if the reference ID numbers are correct, i.e. are the
2922 /// trigger record ID numbers in the track structures found in any of
2923 /// the trigger record data blocks.
2924 /// 4) Do the number of channels claimed in the cluster correspond to
2925 /// the number of channel structures.
2926 /// 5) Check that the momentum vectors between the Manso tracks and
2927 /// the corresponding trigger record are compatible.
2928 /// 6) Check that the trigger decision scalars are reasonable.
a090ff22 2929 /// 7) Check that the detector element IDs are the same between rec
2930 /// hits and clusters / trigger record debug blocks.
dba14d7d 2931
2932 // Check if all the trigger record identifiers and data are unique.
2933 for (AliHLTUInt32_t bi = 0; bi < trigRecBlocksCount; bi++)
2934 {
2935 AliHLTMUONTriggerRecordsBlockReader inblocki(trigRecBlocks[bi]->fPtr, trigRecBlocks[bi]->fSize);
2936 if (not inblocki.BufferSizeOk()) continue;
2937 for (AliHLTUInt32_t bj = bi+1; bj < trigRecBlocksCount; bj++)
2938 {
2939 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
2940 if (not inblockj.BufferSizeOk()) continue;
2941
2942 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2943 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2944 {
2945 if (inblocki[i].fId == inblockj[j].fId)
2946 {
2947 HLTError("Problem found with trigger record data block %d,"
2948 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
2949 " and trigger record data block %d,"
2950 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2951 " Problem: Trigger record %d in block %d and entry"
2952 " %d in block %d have the same identfier, but they"
2953 " should be unique.",
2954 bi,
2955 DataType2Text(trigRecBlocks[bi]->fDataType).c_str(),
2956 trigRecBlocks[bi]->fPtr,
2957 trigRecBlocks[bi]->fSize,
2958 bj,
2959 DataType2Text(trigRecBlocks[bj]->fDataType).c_str(),
2960 trigRecBlocks[bj]->fPtr,
2961 trigRecBlocks[bj]->fSize,
2962 bi, i,
2963 bj, j
2964 );
2965 MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bi]);
2966 MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
2967 }
2968
2969 AliHLTMUONTriggerRecordStruct a = inblocki[i];
2970 AliHLTMUONTriggerRecordStruct b = inblockj[j];
2971 a.fId = b.fId = -1;
2972 if (a == b)
2973 {
2974 HLTError("Problem found with trigger record data block %d,"
2975 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
2976 " and trigger record data block %d,"
2977 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2978 " Problem: Trigger record %d in block %d and entry"
2979 " %d in block %d have the same data."
2980 " The data may have been duplicated.",
2981 bi,
2982 DataType2Text(trigRecBlocks[bi]->fDataType).c_str(),
2983 trigRecBlocks[bi]->fPtr,
2984 trigRecBlocks[bi]->fSize,
2985 bj,
2986 DataType2Text(trigRecBlocks[bj]->fDataType).c_str(),
2987 trigRecBlocks[bj]->fPtr,
2988 trigRecBlocks[bj]->fSize,
2989 bi, i,
2990 bj, j
2991 );
2992 MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bi]);
2993 MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
2994 }
2995 }
2996 }
2997 }
2998
2999 for (AliHLTUInt32_t bi = 0; bi < trigRecDebugBlocksCount; bi++)
3000 {
3001 AliHLTMUONTrigRecsDebugBlockReader inblocki(trigRecDebugBlocks[bi]->fPtr, trigRecDebugBlocks[bi]->fSize);
3002 if (not inblocki.BufferSizeOk()) continue;
3003
dba14d7d 3004 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3005 {
a090ff22 3006 // Check if all the trigger record IDs in the debug information structures exist.
dba14d7d 3007 bool found = false;
3008
3009 for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
3010 {
3011 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
3012 if (not inblockj.BufferSizeOk()) continue;
3013
3014 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3015 {
3016 if (inblocki[i].fTrigRecId == inblockj[j].fId)
3017 {
3018 found = true;
a090ff22 3019
3020 // Since we found the corresponding trigger record,
3021 // check if the detector element IDs are the same.
3022 bool deOk = CheckDetElemIds(
3023 *trigRecDebugBlocks[bi], bi, i, inblocki[i],
3024 *trigRecBlocks[bj], bj, j, inblockj[j]
3025 );
3026 if (not deOk)
3027 {
3028 MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
3029 MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
3030 }
3031
dba14d7d 3032 break;
3033 }
3034 }
3035 }
3036
3037 if (not found)
3038 {
3039 HLTError("Problem found with trigger record debug information"
3040 " data block %d, fDataType = '%s', fPtr = %p and"
3041 " fSize = %u bytes."
3042 " Problem with entry %d in block: The trigger record"
3043 " identifier %d does not exist in any trigger record"
3044 " data block.",
3045 bi,
3046 DataType2Text(trigRecDebugBlocks[bi]->fDataType).c_str(),
3047 trigRecDebugBlocks[bi]->fPtr,
3048 trigRecDebugBlocks[bi]->fSize,
3049 i, inblocki[i].fTrigRecId
3050 );
3051 MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
3052 }
3053 }
3054
3055 // Check if all the trigger record debug information structures are unique.
3056 for (AliHLTUInt32_t bj = bi+1; bj < trigRecDebugBlocksCount; bj++)
3057 {
3058 AliHLTMUONTrigRecsDebugBlockReader inblockj(trigRecDebugBlocks[bj]->fPtr, trigRecDebugBlocks[bj]->fSize);
3059 if (not inblockj.BufferSizeOk()) continue;
3060
3061 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3062 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3063 {
3064 AliHLTMUONTrigRecInfoStruct a = inblocki[i];
3065 AliHLTMUONTrigRecInfoStruct b = inblockj[j];
3066 a.fTrigRecId = b.fTrigRecId = -1;
3067 if (a == b)
3068 {
3069 HLTError("Problem found with trigger record debug information"
3070 " data block %d, fDataType = '%s', fPtr = %p and"
3071 " fSize = %u bytes, and trigger record debug"
3072 " information data block %d,"
3073 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3074 " Problem: The trigger record debug inforamtion"
3075 " structure %d in block %d and entry"
3076 " %d in block %d have the same data."
3077 " The data may have been duplicated.",
3078 bi,
3079 DataType2Text(trigRecDebugBlocks[bi]->fDataType).c_str(),
3080 trigRecDebugBlocks[bi]->fPtr,
3081 trigRecDebugBlocks[bi]->fSize,
3082 bj,
3083 DataType2Text(trigRecDebugBlocks[bj]->fDataType).c_str(),
3084 trigRecDebugBlocks[bj]->fPtr,
3085 trigRecDebugBlocks[bj]->fSize,
3086 bi, i,
3087 bj, j
3088 );
3089 MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
3090 MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bj]);
3091 }
3092 }
3093 }
3094 }
3095
3096 // Check that all the reconstructed hits are unique.
3097 for (AliHLTUInt32_t bi = 0; bi < hitBlocksCount; bi++)
3098 {
3099 AliHLTMUONRecHitsBlockReader inblocki(hitBlocks[bi]->fPtr, hitBlocks[bi]->fSize);
3100 if (not inblocki.BufferSizeOk()) continue;
3101 for (AliHLTUInt32_t bj = bi+1; bj < hitBlocksCount; bj++)
3102 {
3103 AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3104 if (not inblockj.BufferSizeOk()) continue;
3105
3106 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3107 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3108 {
3109 if (inblocki[i] == inblockj[j])
3110 {
3111 HLTError("Problem found with reconstructed hit data block %d,"
3112 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
3113 " and reconstructed hit data block %d,"
3114 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3115 " Problem: Reconstructed hit %d in block %d and entry"
3116 " %d in block %d are the same, but all hits"
3117 " should be unique.",
3118 bi,
3119 DataType2Text(hitBlocks[bi]->fDataType).c_str(),
3120 hitBlocks[bi]->fPtr,
3121 hitBlocks[bi]->fSize,
3122 bj,
3123 DataType2Text(hitBlocks[bj]->fDataType).c_str(),
3124 hitBlocks[bj]->fPtr,
3125 hitBlocks[bj]->fSize,
3126 bi, i,
3127 bj, j
3128 );
3129 MarkBlock(blocks, blockOk, blockCount, hitBlocks[bi]);
3130 MarkBlock(blocks, blockOk, blockCount, hitBlocks[bj]);
3131 }
3132 }
3133 }
3134 }
3135
3136 for (AliHLTUInt32_t bi = 0; bi < clusterBlocksCount; bi++)
3137 {
3138 AliHLTMUONClustersBlockReader inblocki(clusterBlocks[bi]->fPtr, clusterBlocks[bi]->fSize);
3139 if (not inblocki.BufferSizeOk()) continue;
3140
3141 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3142 {
3143 // Check if all the reconstructed hit coordinates in the cluster structures exist.
3144 bool found = false;
3145
3146 for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
3147 {
3148 AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3149 if (not inblockj.BufferSizeOk()) continue;
3150
3151 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3152 {
3153 if (inblocki[i].fHit == inblockj[j])
3154 {
3155 found = true;
a090ff22 3156
3157 // Since we found the corresponding cluster,
3158 // check if the detector element IDs are the same.
3159 bool deOk = CheckDetElemIds(
3160 *clusterBlocks[bi], bi, i, inblocki[i],
3161 *hitBlocks[bj], bj, j, inblockj[j]
3162 );
3163 if (not deOk)
3164 {
3165 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3166 MarkBlock(blocks, blockOk, blockCount, hitBlocks[bj]);
3167 }
3168
dba14d7d 3169 break;
3170 }
3171 }
3172 }
3173
3174 // If the hit was not found then it should be nil.
3175 if (not found and (inblocki[i].fHit != AliHLTMUONConstants::NilRecHitStruct()))
3176 {
3177 HLTError("Problem found with cluster data block %d,"
3178 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3179 " Problem with entry %d in block: The cluster hit"
3180 " coordinate {x = %f, y = %f, z = %f} does not exist"
3181 " in any reconstructed hit data block.",
3182 bi,
3183 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3184 clusterBlocks[bi]->fPtr,
3185 clusterBlocks[bi]->fSize,
3186 i,
3187 inblocki[i].fHit.fX,
3188 inblocki[i].fHit.fY,
3189 inblocki[i].fHit.fZ
3190 );
3191 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3192 }
3193
3194 // Check that the fNchannels value is correct.
3195 AliHLTUInt32_t count = 0;
3196 for (AliHLTUInt32_t bj = 0; bj < channelBlocksCount and not found; bj++)
3197 {
3198 AliHLTMUONChannelsBlockReader inblockj(channelBlocks[bj]->fPtr, channelBlocks[bj]->fSize);
3199 if (not inblockj.BufferSizeOk()) continue;
3200
3201 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3202 {
3203 if (inblocki[i].fId == inblockj[j].fClusterId)
3204 {
3205 count++;
3206 }
3207 }
3208 }
3209
3210 if (inblocki[i].fNchannels != count)
3211 {
3212 HLTError("Problem found with cluster data block %d,"
3213 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3214 " Problem with entry %d in block: The number of"
3215 " channels in the cluster is reported as %d, but"
3216 " only %d channel structures were found.",
3217 bi,
3218 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3219 clusterBlocks[bi]->fPtr,
3220 clusterBlocks[bi]->fSize,
3221 i,
3222 inblocki[i].fNchannels,
3223 count
3224 );
3225 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3226 }
3227 }
3228
3229 // Check if all the cluster structures are unique up to the identifier
3230 // and have unique identifiers.
3231 for (AliHLTUInt32_t bj = bi+1; bj < clusterBlocksCount; bj++)
3232 {
3233 AliHLTMUONClustersBlockReader inblockj(clusterBlocks[bj]->fPtr, clusterBlocks[bj]->fSize);
3234 if (not inblockj.BufferSizeOk()) continue;
3235
3236 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3237 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3238 {
3239 if (inblocki[i].fId == inblockj[j].fId)
3240 {
3241 HLTError("Problem found with cluster"
3242 " data block %d, fDataType = '%s', fPtr = %p and"
3243 " fSize = %u bytes, and cluster data block %d,"
3244 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3245 " Problem: The cluster %d in block %d and entry"
3246 " %d in block %d have the same identifier, but they"
3247 " should be unique.",
3248 bi,
3249 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3250 clusterBlocks[bi]->fPtr,
3251 clusterBlocks[bi]->fSize,
3252 bj,
3253 DataType2Text(clusterBlocks[bj]->fDataType).c_str(),
3254 clusterBlocks[bj]->fPtr,
3255 clusterBlocks[bj]->fSize,
3256 bi, i,
3257 bj, j
3258 );
3259 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3260 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bj]);
3261 }
3262
3263 AliHLTMUONClusterStruct a = inblocki[i];
3264 AliHLTMUONClusterStruct b = inblockj[j];
3265 a.fId = b.fId = -1;
3266 if (a == b)
3267 {
3268 HLTError("Problem found with cluster"
3269 " data block %d, fDataType = '%s', fPtr = %p and"
3270 " fSize = %u bytes, and cluster data block %d,"
3271 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3272 " Problem: The cluster %d in block %d and entry"
3273 " %d in block %d have the same data."
3274 " The data may have been duplicated.",
3275 bi,
3276 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
3277 clusterBlocks[bi]->fPtr,
3278 clusterBlocks[bi]->fSize,
3279 bj,
3280 DataType2Text(clusterBlocks[bj]->fDataType).c_str(),
3281 clusterBlocks[bj]->fPtr,
3282 clusterBlocks[bj]->fSize,
3283 bi, i,
3284 bj, j
3285 );
3286 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
3287 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bj]);
3288 }
3289 }
3290 }
3291 }
3292
3293 for (AliHLTUInt32_t bi = 0; bi < channelBlocksCount; bi++)
3294 {
3295 AliHLTMUONChannelsBlockReader inblocki(channelBlocks[bi]->fPtr, channelBlocks[bi]->fSize);
3296 if (not inblocki.BufferSizeOk()) continue;
3297
3298 // Check if all the cluster IDs in the channel structures exist.
3299 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3300 {
3301 bool found = false;
3302
3303 for (AliHLTUInt32_t bj = 0; bj < clusterBlocksCount and not found; bj++)
3304 {
3305 AliHLTMUONClustersBlockReader inblockj(clusterBlocks[bj]->fPtr, clusterBlocks[bj]->fSize);
3306 if (not inblockj.BufferSizeOk()) continue;
3307
3308 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3309 {
3310 if (inblocki[i].fClusterId == inblockj[j].fId)
3311 {
3312 found = true;
3313 break;
3314 }
3315 }
3316 }
3317
3318 if (not found)
3319 {
3320 HLTError("Problem found with channel"
3321 " data block %d, fDataType = '%s', fPtr = %p and"
3322 " fSize = %u bytes."
3323 " Problem with entry %d in block: The cluster"
3324 " identifier %d does not exist in any cluster"
3325 " data block.",
3326 bi,
3327 DataType2Text(channelBlocks[bi]->fDataType).c_str(),
3328 channelBlocks[bi]->fPtr,
3329 channelBlocks[bi]->fSize,
3330 i, inblocki[i].fClusterId
3331 );
3332 MarkBlock(blocks, blockOk, blockCount, channelBlocks[bi]);
3333 }
3334 }
3335
3336 // Check if all the channel structures are unique up to the cluster ID.
3337 for (AliHLTUInt32_t bj = bi+1; bj < channelBlocksCount; bj++)
3338 {
3339 AliHLTMUONChannelsBlockReader inblockj(channelBlocks[bj]->fPtr, channelBlocks[bj]->fSize);
3340 if (not inblockj.BufferSizeOk()) continue;
3341
3342 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3343 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3344 {
3345 AliHLTMUONChannelStruct a = inblocki[i];
3346 AliHLTMUONChannelStruct b = inblockj[j];
3347 a.fClusterId = b.fClusterId = -1;
3348 if (a == b)
3349 {
3350 HLTError("Problem found with channel"
3351 " data block %d, fDataType = '%s', fPtr = %p and"
3352 " fSize = %u bytes, and channel data block %d,"
3353 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3354 " Problem: The channel %d in block %d and entry"
3355 " %d in block %d have the same data."
3356 " The data may have been duplicated.",
3357 bi,
3358 DataType2Text(channelBlocks[bi]->fDataType).c_str(),
3359 channelBlocks[bi]->fPtr,
3360 channelBlocks[bi]->fSize,
3361 bj,
3362 DataType2Text(channelBlocks[bj]->fDataType).c_str(),
3363 channelBlocks[bj]->fPtr,
3364 channelBlocks[bj]->fSize,
3365 bi, i,
3366 bj, j
3367 );
3368 MarkBlock(blocks, blockOk, blockCount, channelBlocks[bi]);
3369 MarkBlock(blocks, blockOk, blockCount, channelBlocks[bj]);
3370 }
3371 }
3372 }
3373 }
3374
3375 // Will need the total number of tracks later for comparison to trigger scalars.
3376 AliHLTUInt32_t totalTrackCount = 0;
3377
3378 for (AliHLTUInt32_t bi = 0; bi < mansoTrackBlocksCount; bi++)
3379 {
3380 AliHLTMUONMansoTracksBlockReader inblocki(mansoTrackBlocks[bi]->fPtr, mansoTrackBlocks[bi]->fSize);
3381 if (not inblocki.BufferSizeOk()) continue;
3382
3383 totalTrackCount += inblocki.Nentries();
3384
3385 // Check if all the trigger record IDs in the Manso track structures exist.
3386 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3387 {
3388 bool found = false;
3389
3390 for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
3391 {
3392 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
3393 if (not inblockj.BufferSizeOk()) continue;
3394
3395 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3396 {
3397 if (inblocki[i].fTrigRec == inblockj[j].fId)
3398 {
3399 // At this point we can check if the momentum
3400 // is compatible with the trigger record.
3401 if (not AreMomentaCompatible(
3402 inblocki[i].fPx, inblocki[i].fPy, inblocki[i].fPz,
3403 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3404 )
3405 )
3406 {
3407 HLTWarning("Problem found with Manso track"
3408 " data block %d, fDataType = '%s', fPtr = %p and"
3409 " fSize = %u bytes."
3410 " Problem with Manso track %d in block: The momentum"
3411 " vector of the track p = {%f, %f, %f} GeV/c is not"
3412 " compatible with the momentum vector of the trigger"
3413 " record with p = {%f, %f, %f} GeV/c.",
3414 bi,
3415 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3416 mansoTrackBlocks[bi]->fPtr,
3417 mansoTrackBlocks[bi]->fSize,
3418 i, inblocki[i].fPx, inblocki[i].fPy, inblocki[i].fPz,
3419 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3420 );
3421 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3422 }
3423
3424 found = true;
3425 break;
3426 }
3427 }
3428 }
3429
3430 if (not found)
3431 {
3432 HLTError("Problem found with Manso track"
3433 " data block %d, fDataType = '%s', fPtr = %p and"
3434 " fSize = %u bytes."
3435 " Problem with Manso track %d in block: The trigger"
3436 " record identifier %d does not exist in any trigger"
3437 " record data block.",
3438 bi,
3439 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3440 mansoTrackBlocks[bi]->fPtr,
3441 mansoTrackBlocks[bi]->fSize,
3442 i, inblocki[i].fTrigRec
3443 );
3444 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3445 }
3446 }
3447
3448 // Check if all the hits in the Manso track structures exist.
3449 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3450 {
3451 AliHLTMUONParticleSign sign;
3452 bool hitset[4];
3453 AliHLTMUONUtils::UnpackMansoTrackFlags(inblocki[i].fFlags, sign, hitset);
3454
3455 for (AliHLTUInt32_t n = 0; n < 4; n++)
3456 {
3457 if (not hitset[n]) continue;
3458 bool found = false;
3459
3460 for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
3461 {
3462 AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3463 if (not inblockj.BufferSizeOk()) continue;
3464
3465 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3466 {
3467 if (inblocki[i].fHit[n] == inblockj[j])
3468 {
3469 found = true;
3470 break;
3471 }
3472 }
3473 }</