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