Added:
[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
17/* $Id: $ */
18
19///
20/// @file AliHLTMUONDataCheckerComponent.cxx
21/// @author Artur Szostak <artursz@iafrica.com>
22/// @date 2007-12-12
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),
98 fWarnForUnexpecedBlock(false)
99{
100 /// Default constructor.
101}
102
103
104AliHLTMUONDataCheckerComponent::~AliHLTMUONDataCheckerComponent()
105{
106 /// Default destructor.
107}
108
109const char* AliHLTMUONDataCheckerComponent::GetComponentID()
110{
111 /// Inherited from AliHLTComponent. Returns the component ID.
112
113 return AliHLTMUONConstants::DataCheckerComponentId();
114}
115
116
117void AliHLTMUONDataCheckerComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list)
118{
119 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
120 /// At the moment this list is "any data type" since it is not known before
121 /// hand what kind of input blocks we will get.
122
123 assert( list.empty() );
124 list.push_back( kAliHLTAnyDataType );
125}
126
127
128AliHLTComponentDataType AliHLTMUONDataCheckerComponent::GetOutputDataType()
129{
130 /// Inherited from AliHLTComponent. Returns the output data type of
131 /// "any data type" with MUON origin.
132
133 return kAliHLTAnyDataType | kAliHLTDataOriginMUON;
134}
135
136
137void AliHLTMUONDataCheckerComponent::GetOutputDataSize(
138 unsigned long& constBase, double& inputMultiplier
139 )
140{
141 /// Inherited from AliHLTComponent.
142 /// Returns an estimate of the expected output data size.
143
144 // Both of these are zero because we will only ever pass on input data blocks
145 // and never generate data in this component.
146 constBase = 0;
147 inputMultiplier = 0;
148}
149
150
151AliHLTComponent* AliHLTMUONDataCheckerComponent::Spawn()
152{
153 /// Inherited from AliHLTComponent. Creates a new object instance.
154
155 return new AliHLTMUONDataCheckerComponent;
156}
157
158
159int AliHLTMUONDataCheckerComponent::DoInit(int argc, const char** argv)
160{
161 /// Inherited from AliHLTComponent.
162 /// Parses the command line parameters and initialises the component.
163
164 HLTInfo("Initialising dHLT data checker component.");
165
166 // Initialise flags with default values.
167 fIgnoreType = false;
168 fIgnoreSpec = false;
169 fDontForward = false;
170 fFilterBadBlocks = false;
171 fNoGlobalChecks = false;
172 fWarnForUnexpecedBlock = false;
173
174 for (int i = 0; i < argc; i++)
175 {
176 if (strcmp(argv[i], "-ignoretype") == 0)
177 {
178 fIgnoreType = true;
179 HLTInfo("Ignoring data type of data blocks as given by framework.");
180 continue;
181 }
182 if (strcmp(argv[i], "-ignorespec") == 0)
183 {
184 fIgnoreSpec = true;
185 HLTInfo("Ignoring data specification of data blocks as given by framework.");
186 continue;
187 }
188 if (strcmp(argv[i], "-dontforward") == 0)
189 {
190 fDontForward = true;
191 HLTInfo("Not forwarding input data blocks.");
192 continue;
193 }
194 if (strcmp(argv[i], "-filter") == 0)
195 {
196 fFilterBadBlocks = true;
197 HLTInfo("Passing only bad blocks to output.");
198 continue;
199 }
200 if (strcmp(argv[i], "--no_global_check") == 0)
201 {
202 fNoGlobalChecks = true;
203 HLTInfo("Only per block data consistancy checks will be applied,"
204 "but no global checks will be made."
205 );
206 continue;
207 }
208 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
209 {
210 fWarnForUnexpecedBlock = true;
211 continue;
212 }
213
214 HLTError("Unknown option '%s'.", argv[i]);
215 return -EINVAL;
216 }
217
218 return 0;
219}
220
221
222int AliHLTMUONDataCheckerComponent::DoDeinit()
223{
224 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
225
226 HLTInfo("Deinitialising dHLT data checker component.");
227 return 0;
228}
229
230
231int AliHLTMUONDataCheckerComponent::DoEvent(
232 const AliHLTComponentEventData& evtData,
233 const AliHLTComponentBlockData* blocks,
234 AliHLTComponentTriggerData& /*trigData*/,
235 AliHLTUInt8_t* /*outputPtr*/,
236 AliHLTUInt32_t& size,
237 std::vector<AliHLTComponentBlockData>& outputBlocks
238 )
239{
240 /// Inherited from AliHLTProcessor. Processes the new event data.
241 /// Here we go through the list of input data blocks and apply extensive
242 /// data integrity checking on the data found.
243
244 HLTDebug("Processing event %llu with %u input data blocks.",
245 evtData.fEventID, evtData.fBlockCnt
246 );
247
248 // Allocate an array of flags indicating if the data block is OK or not,
249 // also arrays to store specific
250 bool* blockOk = NULL;
251 typedef const AliHLTComponentBlockData* PAliHLTComponentBlockData;
252 PAliHLTComponentBlockData* trigRecBlocks = NULL;
253 PAliHLTComponentBlockData* trigRecDebugBlocks = NULL;
254 PAliHLTComponentBlockData* hitBlocks = NULL;
255 PAliHLTComponentBlockData* clusterBlocks = NULL;
256 PAliHLTComponentBlockData* channelBlocks = NULL;
257 PAliHLTComponentBlockData* mansoTrackBlocks = NULL;
258 PAliHLTComponentBlockData* mansoCandidateBlocks = NULL;
259 PAliHLTComponentBlockData* singleDecisionBlocks = NULL;
260 PAliHLTComponentBlockData* pairDecisionBlocks = NULL;
261 AliHLTUInt32_t trigRecBlocksCount = 0;
262 AliHLTUInt32_t trigRecDebugBlocksCount = 0;
263 AliHLTUInt32_t hitBlocksCount = 0;
264 AliHLTUInt32_t clusterBlocksCount = 0;
265 AliHLTUInt32_t channelBlocksCount = 0;
266 AliHLTUInt32_t mansoTrackBlocksCount = 0;
267 AliHLTUInt32_t mansoCandidateBlocksCount = 0;
268 AliHLTUInt32_t singleDecisionBlocksCount = 0;
269 AliHLTUInt32_t pairDecisionBlocksCount = 0;
270 try
271 {
272 blockOk = new bool[evtData.fBlockCnt];
273 trigRecBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
274 trigRecDebugBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
275 hitBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
276 clusterBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
277 channelBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
278 mansoTrackBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
279 mansoCandidateBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
280 singleDecisionBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
281 pairDecisionBlocks = new PAliHLTComponentBlockData[evtData.fBlockCnt];
282 }
283 catch (const std::bad_alloc&)
284 {
285 HLTError("Could not allocate more memory for internal arrays.");
286 // Make sure to clean up if partially allocated memory.
287 if (blockOk != NULL) delete [] blockOk;
288 if (trigRecBlocks != NULL) delete [] trigRecBlocks;
289 if (trigRecDebugBlocks != NULL) delete [] trigRecDebugBlocks;
290 if (hitBlocks != NULL) delete [] hitBlocks;
291 if (clusterBlocks != NULL) delete [] clusterBlocks;
292 if (channelBlocks != NULL) delete [] channelBlocks;
293 if (mansoTrackBlocks != NULL) delete [] mansoTrackBlocks;
294 if (mansoCandidateBlocks != NULL) delete [] mansoCandidateBlocks;
295 if (singleDecisionBlocks != NULL) delete [] singleDecisionBlocks;
296 if (pairDecisionBlocks != NULL) delete [] pairDecisionBlocks;
297 return -ENOMEM;
298 }
299
300 try
301 {
302 // Clear all the flags indicating if the blocks are ok.
303 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
304 {
305 blockOk[n] = false;
306 }
307
308 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
309 {
310 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
311 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
312 );
313
314 AliHLTMUONDataBlockType blockType = kUnknownDataBlock;
315
316 if (fIgnoreType)
317 {
318 // Decode the block type of we must ignore the block type
319 // as given by the HLT framework.
320 if (blocks[n].fSize >= sizeof(AliHLTMUONDataBlockHeader))
321 {
322 const AliHLTMUONDataBlockHeader* header =
323 reinterpret_cast<const AliHLTMUONDataBlockHeader*>(blocks[n].fPtr);
324 blockType = AliHLTMUONDataBlockType(header->fType);
325 }
326 }
327 else
328 {
329 if (blocks[n].fDataType == AliHLTMUONConstants::DDLRawDataType())
330 {
331 blockOk[n] = CheckRawDataBlock(blocks[n], n);
332 continue;
333 }
334 else if (blocks[n].fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
335 {
336 blockType = kTriggerRecordsDataBlock;
337 }
338 else if (blocks[n].fDataType == AliHLTMUONConstants::TrigRecsDebugBlockDataType())
339 {
340 blockType = kTrigRecsDebugDataBlock;
341 }
342 else if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
343 {
344 blockType = kRecHitsDataBlock;
345 }
346 else if (blocks[n].fDataType == AliHLTMUONConstants::ClusterBlockDataType())
347 {
348 blockType = kClustersDataBlock;
349 }
350 else if (blocks[n].fDataType == AliHLTMUONConstants::ChannelBlockDataType())
351 {
352 blockType = kChannelsDataBlock;
353 }
354 else if (blocks[n].fDataType == AliHLTMUONConstants::MansoTracksBlockDataType())
355 {
356 blockType = kMansoTracksDataBlock;
357 }
358 else if (blocks[n].fDataType == AliHLTMUONConstants::MansoCandidatesBlockDataType())
359 {
360 blockType = kMansoCandidatesDataBlock;
361 }
362 else if (blocks[n].fDataType == AliHLTMUONConstants::SinglesDecisionBlockDataType())
363 {
364 blockType = kSinglesDecisionDataBlock;
365 }
366 else if (blocks[n].fDataType == AliHLTMUONConstants::PairsDecisionBlockDataType())
367 {
368 blockType = kPairsDecisionDataBlock;
369 }
370 else
371 {
372 // Log a message indicating that we got a data block that we
373 // do not know how to handle.
374 if (fWarnForUnexpecedBlock)
375 HLTWarning("Received a data block of a type we cannot"
376 " handle: '%s', spec: 0x%8.8X",
377 DataType2Text(blocks[n].fDataType).c_str(),
378 blocks[n].fSpecification
379 );
380 else
381 HLTDebug("Received a data block of a type we cannot"
382 " handle: '%s', spec: 0x%8.8X",
383 DataType2Text(blocks[n].fDataType).c_str(),
384 blocks[n].fSpecification
385 );
386 }
387 }
388
389 switch (blockType)
390 {
391 case kTriggerRecordsDataBlock:
392 blockOk[n] = CheckTriggerRecordsBlock(blocks[n], n);
393 trigRecBlocks[trigRecBlocksCount++] = &blocks[n];
394 break;
395 case kTrigRecsDebugDataBlock:
396 blockOk[n] = CheckTrigRecsDebugBlock(blocks[n], n);
397 trigRecDebugBlocks[trigRecDebugBlocksCount++] = &blocks[n];
398 break;
399 case kRecHitsDataBlock:
400 blockOk[n] = CheckRecHitsBlock(blocks[n], n);
401 hitBlocks[hitBlocksCount++] = &blocks[n];
402 break;
403 case kClustersDataBlock:
404 blockOk[n] = CheckClustersBlock(blocks[n], n);
405 clusterBlocks[clusterBlocksCount++] = &blocks[n];
406 break;
407 case kChannelsDataBlock:
408 blockOk[n] = CheckChannelsBlock(blocks[n], n);
409 channelBlocks[channelBlocksCount++] = &blocks[n];
410 break;
411 case kMansoTracksDataBlock:
412 blockOk[n] = CheckMansoTracksBlock(blocks[n], n);
413 mansoTrackBlocks[mansoTrackBlocksCount++] = &blocks[n];
414 break;
415 case kMansoCandidatesDataBlock:
416 blockOk[n] = CheckMansoCandidatesBlock(blocks[n], n);
417 mansoCandidateBlocks[mansoCandidateBlocksCount++] = &blocks[n];
418 break;
419 case kSinglesDecisionDataBlock:
420 blockOk[n] = CheckSinglesDecisionBlock(blocks[n], n);
421 singleDecisionBlocks[singleDecisionBlocksCount++] = &blocks[n];
422 break;
423 case kPairsDecisionDataBlock:
424 blockOk[n] = CheckPairsDecisionBlock(blocks[n], n);
425 pairDecisionBlocks[pairDecisionBlocksCount++] = &blocks[n];
426 break;
427 default:
428 HLTDebug("Received a data block for which we could not decode the data type."
429 " fDataType = '%s', fSpecification = 0x%8.8X, fSize = %u bytes.",
430 DataType2Text(blocks[n].fDataType).c_str(),
431 blocks[n].fSpecification,
432 blocks[n].fSize
433 );
434 break;
435 }
436 }
437
438 // Apply the global data consistancy checks if not suppressed by the user.
439 if (not fNoGlobalChecks)
440 {
441 MakeGlobalChecks(
442 blocks, blockOk, evtData.fBlockCnt,
443 trigRecBlocks, trigRecBlocksCount,
444 trigRecDebugBlocks, trigRecDebugBlocksCount,
445 hitBlocks, hitBlocksCount,
446 clusterBlocks, clusterBlocksCount,
447 channelBlocks, channelBlocksCount,
448 mansoTrackBlocks, mansoTrackBlocksCount,
449 mansoCandidateBlocks, mansoCandidateBlocksCount,
450 singleDecisionBlocks, singleDecisionBlocksCount,
451 pairDecisionBlocks, pairDecisionBlocksCount
452 );
453 }
454
455 // Forward the input data blocks if we have not been asked to drop them.
456 // Also remember to filter for bad blocks if so specified.
457 if (not fDontForward)
458 {
459 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
460 {
461 if (fFilterBadBlocks and blockOk[n]) continue;
462 outputBlocks.push_back(blocks[n]);
463 }
464 }
465 }
466 finally
467 (
468 // make sure to cleanup memory
469 delete [] blockOk;
470 delete [] trigRecBlocks;
471 delete [] trigRecDebugBlocks;
472 delete [] hitBlocks;
473 delete [] clusterBlocks;
474 delete [] channelBlocks;
475 delete [] mansoTrackBlocks;
476 delete [] mansoCandidateBlocks;
477 delete [] singleDecisionBlocks;
478 delete [] pairDecisionBlocks;
479 )
480
481 // Finally we set the total size of output memory we consumed, which is
482 // zero since we just copied the input descriptors to output if anything.
483 size = 0;
484 return 0;
485}
486
487
488bool AliHLTMUONDataCheckerComponent::IsSpecificationValid(
489 const AliHLTComponentBlockData& block,
490 AliHLTUInt32_t blockNumber,
491 const char* name
492 ) const
493{
494 /// Checks if the specification bits are valid.
495 /// \param block The block whose specification should be checked.
496 /// \param blockNumber The block index number being checked.
497 /// \param name The name of the type of block being checked.
498 /// \returns true if the specification is valid and false otherwise.
499
500 if (AliHLTMUONUtils::IsSpecValid(block.fSpecification))
501 return true;
502
503 HLTError("Problem found with data block %d, fDataType = '%s',"
504 " fPtr = %p and fSize = %u bytes."
505 " Assuming this is a %s data block."
506 " Problem: The specification does not contain a valid pattern,"
507 " received 0x%8.8X for the specification.",
508 blockNumber,
509 DataType2Text(block.fDataType).c_str(),
510 block.fPtr,
511 block.fSize,
512 name,
513 block.fSpecification
514 );
515 return false;
516}
517
518
519bool AliHLTMUONDataCheckerComponent::IsFromTrackerOnly(
520 const AliHLTComponentBlockData& block,
521 AliHLTUInt32_t blockNumber,
522 const char* name
523 ) const
524{
525 /// Checks if the specification bits are valid and indicate the block
526 /// contains data or information only from the tracker DDLs.
527 /// \param block The block whose specification should be checked.
528 /// \param blockNumber The block index number being checked.
529 /// \param name The name of the type of block being checked.
530 /// \returns true if the specification indicates data is only from tracker.
531
532 bool result = IsSpecificationValid(block, blockNumber, name);
533
534 if (AliHLTMUONUtils::ContainsDataFromTracker(block.fSpecification) and
535 not AliHLTMUONUtils::ContainsDataFromTrigger(block.fSpecification)
536 )
537 {
538 return result;
539 }
540
541 HLTError("Problem found with data block %d, fDataType = '%s',"
542 " fPtr = %p and fSize = %u bytes."
543 " Assuming this is a %s data block."
544 " Problem: The data block does not contain data only from the"
545 " tracker DDLs as expected."
546 " Received 0x%8.8X for the specification.",
547 blockNumber,
548 DataType2Text(block.fDataType).c_str(),
549 block.fPtr,
550 block.fSize,
551 name,
552 block.fSpecification
553 );
554 return false;
555}
556
557
558bool AliHLTMUONDataCheckerComponent::IsFromTriggerOnly(
559 const AliHLTComponentBlockData& block,
560 AliHLTUInt32_t blockNumber,
561 const char* name
562 ) const
563{
564 /// Checks if the specification bits are valid and indicate the block
565 /// contains data or information only from the trigger DDLs.
566 /// \param block The block whose specification should be checked.
567 /// \param blockNumber The block index number being checked.
568 /// \param name The name of the type of block being checked.
569 /// \returns true if the specification indicates data is only from trigger.
570
571 bool result = IsSpecificationValid(block, blockNumber, name);
572
573 if (AliHLTMUONUtils::ContainsDataFromTrigger(block.fSpecification) and
574 not AliHLTMUONUtils::ContainsDataFromTracker(block.fSpecification)
575 )
576 {
577 return result;
578 }
579
580 HLTError("Problem found with data block %d, fDataType = '%s',"
581 " fPtr = %p and fSize = %u bytes."
582 " Assuming this is a %s data block."
583 " Problem: The data block does not contain data only from the"
584 " trigger DDLs as expected."
585 " Received 0x%8.8X for the specification.",
586 blockNumber,
587 DataType2Text(block.fDataType).c_str(),
588 block.fPtr,
589 block.fSize,
590 name,
591 block.fSpecification
592 );
593 return false;
594}
595
596
597bool AliHLTMUONDataCheckerComponent::IsMomentumVectorOk(
598 const AliHLTComponentBlockData& block,
599 AliHLTUInt32_t blockNumber,
600 const char* name,
601 AliHLTUInt32_t entryNumber,
602 AliHLTFloat32_t px,
603 AliHLTFloat32_t py,
604 AliHLTFloat32_t pz
605 ) const
606{
607 /// Checks if the momentum vector is reasonable.
608 /// \param block The block from which the momentum vector data comes from.
609 /// \param blockNumber The block index number.
610 /// \param name The name of the type of block.
611 /// \param entryNumber The entry index number of the structure holding
612 /// the momentum vector data.
613 /// \param px The X coordinate of the momentum vector (GeV/c).
614 /// \param py The Y coordinate of the momentum vector (GeV/c).
615 /// \param pz The Z coordinate of the momentum vector (GeV/c).
616 /// \returns true if the momentum vector is valid and false otherwise.
617
618 // If the momentum vector is nil then ignore it.
619 if (px == 0 and py == 0 and pz == 0) return true;
620
621 bool result = true;
622
623 // If the momentum vector is sane then we should not have a particle with
624 // more energy than 14 TeV and momentum should be in the negative direction.
625 double momentum = sqrt(px*px + py*py + pz*pz);
626 if (momentum > 14e3)
627 {
628 // Just warn since this is a data sanity problem rather
629 // than a data integrity problem.
630 HLTWarning("Problem found with data block %d, fDataType = '%s',"
631 " fPtr = %p and fSize = %u bytes."
632 " Assuming this is a %s data block."
633 " Problem with entry %d in block: The momentum vector"
634 " p = {%f, %f, %f}, |p| = %f looks too big.",
635 blockNumber,
636 DataType2Text(block.fDataType).c_str(),
637 block.fPtr,
638 block.fSize,
639 name,
640 entryNumber,
641 px, py, pz,
642 momentum
643 );
644 result = false;
645 }
646
647 if (pz > 0.)
648 {
649 // Just warn since this is a data sanity problem rather
650 // than a data integrity problem.
651 HLTWarning("Problem found with data block %d, fDataType = '%s',"
652 " fPtr = %p and fSize = %u bytes."
653 " Assuming this is a %s data block."
654 " Problem with entry %d in block: The momentum vector"
655 " p = {%f, %f, %f} points away from the dimuon"
656 " spectrometer (p_z > 0).",
657 blockNumber,
658 DataType2Text(block.fDataType).c_str(),
659 block.fPtr,
660 block.fSize,
661 name,
662 entryNumber,
663 px, py, pz
664 );
665 result = false;
666 }
667
668 return result;
669}
670
671
672bool AliHLTMUONDataCheckerComponent::AreMomentumCalcParamsOk(
673 const AliHLTComponentBlockData& block,
674 AliHLTUInt32_t blockNumber,
675 const char* name,
676 AliHLTUInt32_t entryNumber,
677 AliHLTFloat32_t zmiddle,
678 AliHLTFloat32_t bl
679 ) const
680{
681 /// Checks if the parameters for the momentum calculation are reasonable.
682 /// \param block The block from which the parameter data comes from.
683 /// \param blockNumber The block index number.
684 /// \param name The name of the type of block.
685 /// \param entryNumber The entry index number of the structure holding
686 /// the parameter data data.
687 /// \param zmiddle The z-coordinate of the middle of the magnetic field (cm).
688 /// \param bl The integrated magnetic field (T.m).
689 /// \returns true if the parameters are valid and false otherwise.
690
691 bool result = true;
692
693 // Check that the value of the fZmiddle value is somewhere
694 // within the tracking / dipole magnetic field area.
695 if (zmiddle < AliMUONConstants::AbsZEnd() or
696 zmiddle < AliMUONConstants::MuonFilterZBeg()
697 )
698 {
699 // Just warn since this is a data sanity problem rather
700 // than a data integrity problem.
701 HLTWarning("Problem found with data block %d, fDataType = '%s',"
702 " fPtr = %p and fSize = %u bytes."
703 " Assuming this is a %s data block."
704 " Problem with entry %d in block: The Z coordinate %f cm"
705 " used as the middle of the magnetic field in the momentum"
706 " calculation is outside the dimuon spectrometers dipole"
707 " magnetic field volume.",
708 blockNumber,
709 DataType2Text(block.fDataType).c_str(),
710 block.fPtr,
711 block.fSize,
712 name,
713 entryNumber,
714 zmiddle
715 );
716 result = false;
717 }
718
719 // Also check that the value of the 'bl' value is within a
720 // reasonable range: |bl| < Lmax * Bmax, where
721 // Lmax = max length from vertex to end of spectrometer, and
722 // Bmax = max magnetic field of dipole, taken as 1 tesla.
723 // Approximating Lmax * Bmax as 20 T.m
724 if (fabs(bl) > 20.)
725 {
726 // Just warn since this is a data sanity problem rather
727 // than a data integrity problem.
728 HLTWarning("Problem found with data block %d, fDataType = '%s',"
729 " fPtr = %p and fSize = %u bytes."
730 " Assuming this is a %s data block."
731 " Problem with entry %d in block: The integrated magnetic"
732 " field value %f T.m used in the momentum calculation"
733 " has an unreasonably large absolute value.",
734 blockNumber,
735 DataType2Text(block.fDataType).c_str(),
736 block.fPtr,
737 block.fSize,
738 name,
739 entryNumber,
740 bl
741 );
742 result = false;
743 }
744
745 return result;
746}
747
748
749bool AliHLTMUONDataCheckerComponent::IsHitCoordinateOk(
750 const AliHLTComponentBlockData& block,
751 AliHLTUInt32_t blockNumber,
752 const char* name,
753 AliHLTUInt32_t entryNumber,
754 const AliHLTMUONRecHitStruct& hit,
755 AliHLTInt32_t minChamber,
756 AliHLTInt32_t maxChamber,
757 AliHLTInt32_t expectedChamber,
758 bool ddl[22]
759 ) const
760{
761 /// Checks if the hit coordinate is compatible with a the location of a
762 /// dimuon spectrometer chamber. Also, if expectedChamber is not -1, then
763 /// the hit coordinate is checked if to comes from that chamber.
764 /// \param block The block from which the hit data comes from.
765 /// \param blockNumber The block index number.
766 /// \param name The name of the type of block.
767 /// \param entryNumber The entry index number of the hit.
768 /// \param hit The hit data being checked.
769 /// \param minChamber The minimum valid chamber number to check for.
770 /// \param maxChamber The maximum valid chamber number to check for.
771 /// \param expectedChamber If not -1 then this is the chamber number to
772 /// check against.
773 /// \param ddl The array decoded by AliHLTMUONUtils::UnpackSpecBits.
774 /// \returns true if the hit is valid and false otherwise.
775
776 assert( 0 <= minChamber and minChamber < 14 );
777 assert( 0 <= maxChamber and maxChamber < 14 );
778
779 bool result = true;
780
781 Int_t chamber = AliMUONConstants::ChamberNumber(hit.fZ, false); // false = do not warn.
782 if (chamber < minChamber or maxChamber < chamber)
783 {
784 HLTError("Problem found with data block %d, fDataType = '%s',"
785 " fPtr = %p and fSize = %u bytes."
786 " Assuming this is a %s data block."
787 " Problem with entry %d in block: The hit {x = %f, y = %f,"
788 " z = %f} cm has a z-coordinate that does not correspond"
789 " to the nominal position of any chambers in the range"
790 " [%d..%d].",
791 blockNumber,
792 DataType2Text(block.fDataType).c_str(),
793 block.fPtr,
794 block.fSize,
795 name,
796 entryNumber,
797 hit.fX, hit.fY, hit.fZ,
798 minChamber+1,
799 maxChamber+1
800 );
801 return false;
802 }
803
804 if (expectedChamber != -1 and chamber != expectedChamber)
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 position that corresponds to chamber %d,"
811 " but expected it to be on chamber %d.",
812 blockNumber,
813 DataType2Text(block.fDataType).c_str(),
814 block.fPtr,
815 block.fSize,
816 name,
817 entryNumber,
818 hit.fX, hit.fY, hit.fZ,
819 chamber+1,
820 expectedChamber+1
821 );
822 result = false;
823 }
824
825 AliHLTFloat32_t rmin = AliMUONConstants::Rmin(chamber / 2);
826 AliHLTFloat32_t rmax = AliMUONConstants::Rmax(chamber / 2);
827 AliHLTFloat32_t radius = sqrt(hit.fX*hit.fX + hit.fY*hit.fY);
828 if (radius < rmin or rmax < radius)
829 {
830 HLTError("Problem found with data block %d, fDataType = '%s',"
831 " fPtr = %p and fSize = %u bytes."
832 " Assuming this is a %s data block."
833 " Problem with entry %d in block: The hit {x = %f, y = %f,"
834 " z = %f} cm has a position in the X-Y plane that does not"
835 " correspond to the nominal position of chamber %d.",
836 blockNumber,
837 DataType2Text(block.fDataType).c_str(),
838 block.fPtr,
839 block.fSize,
840 name,
841 entryNumber,
842 hit.fX, hit.fY, hit.fZ,
843 chamber+1
844 );
845 result = false;
846 }
847
848 if (not fIgnoreSpec and not ChamberMarkedInDDLList(chamber, ddl))
849 {
850 HLTError("Problem found with data block %d, fDataType = '%s',"
851 " fPtr = %p and fSize = %u bytes."
852 " Assuming this is a %s data block."
853 " Problem with entry %d in block: The hit {x = %f, y = %f,"
854 " z = %f} cm has a position that corresponds to chamber %d"
855 " but the data block specification 0x%8.8X does have a"
856 " corresponding DDL bit set.",
857 blockNumber,
858 DataType2Text(block.fDataType).c_str(),
859 block.fPtr,
860 block.fSize,
861 name,
862 entryNumber,
863 hit.fX, hit.fY, hit.fZ,
864 chamber+1,
865 block.fSpecification
866 );
867 result = false;
868 }
869
870 return result;
871}
872
873
874bool AliHLTMUONDataCheckerComponent::IsMansoTrackOk(
875 const AliHLTComponentBlockData& block,
876 AliHLTUInt32_t blockNumber,
877 const char* name,
878 AliHLTUInt32_t entryNumber,
879 const AliHLTMUONMansoTrackStruct& track,
880 bool ddl[22]
881 ) const
882{
883 /// Checks if the Manso track structure is Ok.
884 /// \param block The block from which the track data comes from.
885 /// \param blockNumber The block index number.
886 /// \param name The name of the type of block.
887 /// \param entryNumber The entry index number of the structure in the
888 /// block being checked.
889 /// \param track The Manso track data being checked.
890 /// \param ddl The array decoded by AliHLTMUONUtils::UnpackSpecBits.
891 /// \returns true if the hit is valid and false otherwise.
892
893 bool result = true;
894
895 // Chi^2 should not be greater than the worst fit possible, estimated
896 // as the diameter of largest chamber times the number of points
897 // findable in a track. Max points is 10 tracker chambers times
898 // 2 cathodes + 4 trigger chambers.
899 if (track.fChi2 > AliMUONConstants::Dmax(6)*AliMUONConstants::Dmax(6)*(10*2+4))
900 {
901 // Just a warning since this is not technically an
902 // integrity problem.
903 HLTWarning("Problem found with data block %d, fDataType = '%s',"
904 " fPtr = %p and fSize = %u bytes."
905 " Assuming this is a %s data block."
906 " Problem with entry %d in block: The Manso track has"
907 " the chi squared value of %f that unreasonably big.",
908 blockNumber,
909 DataType2Text(block.fDataType).c_str(),
910 block.fPtr,
911 block.fSize,
912 name,
913 entryNumber,
914 track.fChi2
915 );
916 result = false;
917 }
918
919 // Check if the momentum vector is reasonable.
920 bool momOk = IsMomentumVectorOk(
921 block, blockNumber, name, entryNumber,
922 track.fPx, track.fPy, track.fPz
923 );
924 if (not momOk) result = false;
925
926 AliHLTMUONParticleSign sign;
927 bool hitset[4];
928 AliHLTMUONUtils::UnpackMansoTrackFlags(track.fFlags, sign, hitset);
929
930 // Min and max allowed chamber numbers for hits:
931 Int_t minCh = 0;
932 Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
933
934 // Check that this hit coordinates are OK.
935 for (AliHLTUInt32_t i = 0; i < 4; i++)
936 {
937 if (not hitset[i]) continue; // ignore hits that are not initialised.
938 bool hitOk = IsHitCoordinateOk(
939 block, blockNumber, name, entryNumber, track.fHit[i],
940 minCh, maxCh, i+6, ddl
941 );
942 if (not hitOk) result = false;
943 }
944
945 return result;
946}
947
948
949namespace
950{
951 /**
952 * Class for logging errors found in raw DDL data.
953 */
954 class AliHLTMUONDecoderHandler : public AliHLTLogging
955 {
956 public:
957
958 /// Default constructor
959 AliHLTMUONDecoderHandler() :
960 AliHLTLogging(),
961 fBufferStart(NULL),
962 fDescriptor(NULL),
963 fBlockNumber(0)
964 {
965 }
966
967 /// Default destructor.
968 virtual ~AliHLTMUONDecoderHandler() {}
969
970 /// Sets the DDL raw data block descriptor.
971 void SetDescriptor(const AliHLTComponentBlockData* b) { fDescriptor = b; }
972
973 /// Sets the block number of the raw data block descriptor.
974 void SetBlockNumber(AliHLTUInt32_t n) { fBlockNumber = n; }
975
976 /// Logs an error message describing the problem with the DDL raw data.
977 template <typename ErrorCode, class DecoderHandler>
978 void LogError(ErrorCode code, const void* location, DecoderHandler& handler);
979
980 protected:
981 // Do not allow copying of this class.
982 /// Not implemented
983 AliHLTMUONDecoderHandler(const AliHLTMUONDecoderHandler& rhs); // copy constructor
984 /// Not implemented
985 AliHLTMUONDecoderHandler& operator = (const AliHLTMUONDecoderHandler& rhs); // assignment operator
986
987 const void* fBufferStart; ///< Pointer to the start of the current DDL payload buffer.
988 const AliHLTComponentBlockData* fDescriptor; ///< Descriptor for the DDL raw data block corresponding to the buffer.
989 AliHLTUInt32_t fBlockNumber; ///< The number / index of the block descriptor.
990 };
991
992
993 template <typename ErrorCode, class DecoderHandler>
994 void AliHLTMUONDecoderHandler::LogError(ErrorCode code, const void* location, DecoderHandler& handler)
995 {
996 /// Logs a HLT error message describing the problem with the raw DDL data.
997 /// \param code The error code describing the problem.
998 /// \param location A pointer to the location in the raw data buffer
999 /// where the problem was found.
1000 /// \param handler The decoder handler object.
1001
1002 long bytepos = long(location) - long(fBufferStart) + sizeof(AliRawDataHeader);
1003
1004 // create data type string.
1005 char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1006 memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1007 strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1008 strcat( dataType, ":" );
1009 strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1010
1011 HLTError("Problem found with data block %d, fDataType = '%s',"
1012 " fPtr = %p and fSize = %u bytes."
1013 " Assuming this is a DDL raw data block."
1014 " Problem: %s (Error code: %d, at byte %d)",
1015 fBlockNumber,
1016 &dataType[0],
1017 fDescriptor->fPtr,
1018 fDescriptor->fSize,
1019 handler.ErrorCodeToMessage(code),
1020 code,
1021 bytepos
1022 );
1023 };
1024
1025
1026 /**
1027 * Class for logging decoding errors when checking tracker raw DDL data.
1028 * Used in the AliHLTMUONDataCheckerComponent::CheckRawDataBlock method.
1029 */
1030 class AliHLTMUONTrackerDecoderHandler :
1031 public AliMUONTrackerDDLDecoderEventHandler, public AliHLTMUONDecoderHandler
1032 {
1033 public:
1034 AliHLTMUONTrackerDecoderHandler() :
1035 AliMUONTrackerDDLDecoderEventHandler(),
1036 AliHLTMUONDecoderHandler(),
1037 fMaxDigits(0),
1038 fDigitCount(0),
1039 fDigits(NULL),
1040 fCurrentBusPatch(0),
1041 fDataProblems(false)
1042 {}
1043
1044 virtual ~AliHLTMUONTrackerDecoderHandler()
1045 {
1046 if (fDigits != NULL) delete [] fDigits;
1047 }
1048
1049 /// Structure to store raw data words found in the raw data.
1050 struct AliDigit
1051 {
1052 UInt_t fBusPatchId; ///< Bus patch ID for the data word.
1053 UInt_t fDataWord; ///< Raw data word found in the DDL payload.
1054 };
1055
1056 /// Returns the number of digits found.
1057 UInt_t DigitCount() const { return fDigitCount; }
1058
1059 /// Returns the array of digits found.
1060 const AliDigit* Digits() const { return fDigits; }
1061
1062 /// Returns true if there were problems with the data.
1063 bool DataProblems() const { return fDataProblems; }
1064
1065 // Methods inherited from AliMUONTrackerDDLDecoderEventHandler:
1066
1067 /// Called for each new buffer.
1068 void OnNewBuffer(const void* buffer, UInt_t bufferSize);
1069
1070 /// Called for each new bus patch. Just marks the current bus patch ID.
1071 void OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* /*data*/)
1072 {
1073 fCurrentBusPatch = header->fBusPatchId;
1074 }
1075
1076 /// Called for each new data word found.
1077 void OnData(UInt_t data, bool /*parityError*/);
1078
1079 /// Logs an error message if there was a decoding problem with the DDL payload.
1080 void OnError(ErrorCode code, const void* location)
1081 {
1082 fDataProblems = true;
1083 LogError(code, location, *this);
1084 }
1085
1086 private:
1087
1088 // Do not allow copying of this object.
1089 /// Not implemented.
1090 AliHLTMUONTrackerDecoderHandler(const AliHLTMUONTrackerDecoderHandler& obj);
1091 /// Not implemented.
1092 AliHLTMUONTrackerDecoderHandler& operator = (const AliHLTMUONTrackerDecoderHandler& obj);
1093
1094 UInt_t fMaxDigits; ///< Maximum number of digits that can be stored in fDigits.
1095 UInt_t fDigitCount; ///< The number of digits currently stored in fDigits.
1096 AliDigit* fDigits; ///< The array of digits found in the DDL data.
1097 UInt_t fCurrentBusPatch; ///< The current bus patch ID being processed.
1098 bool fDataProblems; ///< flag indicating there were problems with the data.
1099 };
1100
1101
1102 void AliHLTMUONTrackerDecoderHandler::OnNewBuffer(const void* buffer, UInt_t bufferSize)
1103 {
1104 /// Called for a new buffer. It will reset internal counters and
1105 /// resize the digits array if necessary.
1106
1107 fDataProblems = false;
1108 fDigitCount = 0;
1109 fBufferStart = buffer;
1110
1111 // Resize the fDigits array to be able to store
1112 // all the digits in the data buffer.
1113 UInt_t maxSize = bufferSize / sizeof(UInt_t) + 1;
1114 if (maxSize > fMaxDigits)
1115 {
1116 if (fDigits != NULL)
1117 {
1118 delete [] fDigits;
1119 fDigits = NULL;
1120 fMaxDigits = 0;
1121 }
1122 try
1123 {
1124 fDigits = new AliDigit[maxSize];
1125 fMaxDigits = maxSize;
1126 }
1127 catch (const std::bad_alloc&)
1128 {
1129 HLTError("Could not allocate enough buffer space for internal arrays.");
1130 return;
1131 }
1132 }
1133 }
1134
1135
1136 void AliHLTMUONTrackerDecoderHandler::OnData(UInt_t data, bool /*parityError*/)
1137 {
1138 /// Called for each new data word found. This method will add
1139 /// these to the list of digits and check if they are not duplicated.
1140
1141 assert( fDigits != NULL );
1142
1143 // Check if the data word + bus patch have been duplicated.
1144 for (UInt_t i = 0; i < fDigitCount; i++)
1145 {
1146 if (fDigits[i].fDataWord == data and fDigits[i].fBusPatchId == fCurrentBusPatch)
1147 {
1148 // create data type string.
1149 char dataType[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2];
1150 memset( dataType, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
1151 strncat( dataType, fDescriptor->fDataType.fOrigin, kAliHLTComponentDataTypefOriginSize );
1152 strcat( dataType, ":" );
1153 strncat( dataType, fDescriptor->fDataType.fID, kAliHLTComponentDataTypefIDsize );
1154
1155 HLTError("Problem found with data block %d, fDataType = '%s',"
1156 " fPtr = %p and fSize = %u bytes."
1157 " Assuming this is a tracker DDL raw data block."
1158 " Problem: Found a duplicate data word 0x%8.8X for bus patch %d.",
1159 fBlockNumber,
1160 &dataType[0],
1161 fDescriptor->fPtr,
1162 fDescriptor->fSize,
1163 data,
1164 fCurrentBusPatch
1165 );
1166 fDataProblems = true;
1167 return;
1168 }
1169 }
1170
1171 // Add the data word + bus patch to the list of decoded digits.
1172 if (fDigitCount < fMaxDigits)
1173 {
1174 fDigits[fDigitCount].fBusPatchId = fCurrentBusPatch;
1175 fDigits[fDigitCount].fDataWord = data;
1176 fDigitCount++;
1177 }
1178 }
1179
1180 /**
1181 * Class for logging decoding errors when checking trigger raw DDL data.
1182 * Used in the AliHLTMUONDataCheckerComponent::CheckRawDataBlock method.
1183 */
1184 class AliHLTMUONTriggerDecoderHandler :
1185 public AliMUONTriggerDDLDecoderEventHandler, public AliHLTMUONDecoderHandler
1186 {
1187 public:
1188 // Methods inherited from AliMUONTriggerDDLDecoderEventHandler:
1189
1190 /// Called for each new buffer.
1191 void OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
1192 {
1193 fBufferStart = buffer;
1194 }
1195
1196 /// Logs an error message if there was a decoding problem with the DDL payload.
1197 void OnError(ErrorCode code, const void* location)
1198 {
1199 LogError(code, location, *this);
1200 }
1201 };
1202
1203} // end of namespace
1204
1205
1206bool AliHLTMUONDataCheckerComponent::CheckRawDataBlock(
1207 const AliHLTComponentBlockData& block,
1208 AliHLTUInt32_t blockNumber
1209 ) const
1210{
1211 /// Checks the validity of a raw data block.
1212
1213 bool result = true;
1214
1215 if (fIgnoreSpec)
1216 {
1217 HLTWarning("Not able to check DDL raw data if -ignorespec is specified.");
1218 return false;
1219 }
1220
1221 bool ddl[22];
1222 AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1223
1224 // Check that only one DDL was marked in the specification.
1225 int ddlIndex = -1;
1226 for (int i = 0; i < 22; i++)
1227 {
1228 if (not ddl[i]) continue;
1229
1230 if (ddlIndex == -1)
1231 {
1232 ddlIndex = i;
1233 continue;
1234 }
1235
1236 HLTError("Problem found with data block %d, fDataType = '%s',"
1237 " fPtr = %p and fSize = %u bytes."
1238 " Assuming this is a DDL raw data block."
1239 " Problem: The specification indicates multiple"
1240 " DDL sources, DDL %d and %d.",
1241 blockNumber,
1242 DataType2Text(block.fDataType).c_str(),
1243 block.fPtr,
1244 block.fSize,
1245 ddlIndex,
1246 i
1247 );
1248 result = false;
1249 }
1250
1251 // Check the DDL common data header.
1252 AliHLTUInt32_t totalDDLSize = block.fSize;
1253 if (totalDDLSize < sizeof(AliRawDataHeader))
1254 {
1255 HLTError("Problem found with data block %d, fDataType = '%s',"
1256 " fPtr = %p and fSize = %u bytes."
1257 " Assuming this is a DDL raw data block."
1258 " Problem: The size of the data block is too short to contain"
1259 " a valid common DDL data header. Size of buffer is only %d"
1260 " bytes, but expected at least %d bytes.",
1261 blockNumber,
1262 DataType2Text(block.fDataType).c_str(),
1263 block.fPtr,
1264 block.fSize,
1265 totalDDLSize,
1266 sizeof(AliRawDataHeader)
1267 );
1268 return false;
1269 }
1270
1271 const AliRawDataHeader* header =
1272 reinterpret_cast<const AliRawDataHeader*>(block.fPtr);
1273
1274 AliHLTUInt32_t payloadSize = block.fSize - sizeof(AliRawDataHeader);
1275 const AliHLTUInt8_t* payload =
1276 reinterpret_cast<const AliHLTUInt8_t*>(header + 1);
1277
1278 if (AliHLTMUONUtils::IsTriggerDDL(block.fSpecification))
1279 {
1280 bool scalarEvent = header->GetL1TriggerMessage() == 0x1;
1281 AliMUONTriggerDDLDecoder<AliHLTMUONTriggerDecoderHandler> decoder;
1282 decoder.ExitOnError(false);
1283 decoder.TryRecover(false);
1284 decoder.AutoDetectScalars(false);
1285 decoder.GetHandler().SetDescriptor(&block);
1286 decoder.GetHandler().SetBlockNumber(blockNumber);
1287 result = decoder.Decode(payload, payloadSize, scalarEvent);
1288 }
1289 else if (AliHLTMUONUtils::IsTrackerDDL(block.fSpecification))
1290 {
1291 AliMUONTrackerDDLDecoder<AliHLTMUONTrackerDecoderHandler> decoder;
1292 decoder.ExitOnError(false);
1293 decoder.TryRecover(false);
1294 decoder.SendDataOnParityError(true);
1295 decoder.AutoDetectTrailer(true);
1296 decoder.CheckForTrailer(true);
1297 decoder.GetHandler().SetDescriptor(&block);
1298 decoder.GetHandler().SetBlockNumber(blockNumber);
1299 result = decoder.Decode(payload, payloadSize);
1300 if (decoder.GetHandler().DataProblems()) result = false;
1301
1302 if (FetchMappingStores() == 0) // are stores loaded?
1303 {
1304 Bool_t warn = kFALSE;
1305 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance(warn);
1306
1307 // Check that the bus patch, manu ID and channel addresses are valid
1308 // for each raw data word.
1309 for (UInt_t i = 0; i < decoder.GetHandler().DigitCount(); i++)
1310 {
1311 UInt_t busPatchId = decoder.GetHandler().Digits()[i].fBusPatchId;
1312 UInt_t dataWord = decoder.GetHandler().Digits()[i].fDataWord;
1313
1314 UShort_t manuId; UChar_t channelId; UShort_t adc;
1315 AliMUONTrackerDDLDecoderEventHandler::UnpackADC(
1316 dataWord, manuId, channelId, adc
1317 );
1318
1319 // Check if the bus patch is valid.
1320 AliMpBusPatch* busPatch = ddlStore->GetBusPatch(busPatchId, warn);
1321 if (busPatch == NULL)
1322 {
1323 HLTError("Problem found with data block %d, fDataType = '%s',"
1324 " fPtr = %p and fSize = %u bytes."
1325 " Assuming this is a tracker DDL raw data block."
1326 " Problem: Found a bus patch identifier %d that"
1327 " is not valid.",
1328 blockNumber,
1329 DataType2Text(block.fDataType).c_str(),
1330 block.fPtr,
1331 block.fSize,
1332 busPatchId
1333 );
1334 result = false;
1335 continue;
1336 }
1337
1338 // We can check that the bus patch is for the DDL
1339 // which is also indicated by the specification bits.
1340 if (not fIgnoreSpec and busPatch->GetDdlId() != ddlIndex)
1341 {
1342 HLTError("Problem found with data block %d, fDataType = '%s',"
1343 " fPtr = %p and fSize = %u bytes."
1344 " Assuming this is a tracker DDL raw data block."
1345 " Problem: Found a bus patch identifier %d for"
1346 " DDL %d, but the data block specification 0x%8.8X"
1347 " indicates a different DDL of %d.",
1348 blockNumber,
1349 DataType2Text(block.fDataType).c_str(),
1350 block.fPtr,
1351 block.fSize,
1352 busPatchId,
1353 busPatch->GetDdlId(),
1354 block.fSpecification,
1355 ddlIndex
1356 );
1357 result = false;
1358 continue;
1359 }
1360
1361 // Check if the MANU ID is valid.
1362 if (not busPatch->HasManu(manuId))
1363 {
1364 HLTError("Problem found with data block %d, fDataType = '%s',"
1365 " fPtr = %p and fSize = %u bytes."
1366 " Assuming this is a tracker DDL raw data block."
1367 " Problem: Found a MANU identifier %d on bus patch %d"
1368 " that is not valid.",
1369 blockNumber,
1370 DataType2Text(block.fDataType).c_str(),
1371 block.fPtr,
1372 block.fSize,
1373 manuId,
1374 busPatchId
1375 );
1376 result = false;
1377 continue;
1378 }
1379
1380 // Now try to fetch the detector element to check the MANU channel.
1381 AliMpDetElement* de = ddlStore->GetDetElement(busPatch->GetDEId(), warn);
1382 if (de == NULL)
1383 {
1384 HLTError("Problem found with data block %d, fDataType = '%s',"
1385 " fPtr = %p and fSize = %u bytes."
1386 " Assuming this is a tracker DDL raw data block."
1387 " Problem: Found a bus patch identifier %d that"
1388 " does not correspond to a detector element.",
1389 blockNumber,
1390 DataType2Text(block.fDataType).c_str(),
1391 block.fPtr,
1392 block.fSize,
1393 busPatchId
1394 );
1395 result = false;
1396 continue;
1397 }
1398
1399 if (not de->IsConnectedChannel(manuId, channelId))
1400 {
1401 // Just a warning because this is marked not
1402 // to be an error in the AliMUONDigitMaker.
1403 HLTWarning("Problem found with data block %d, fDataType = '%s',"
1404 " fPtr = %p and fSize = %u bytes."
1405 " Assuming this is a tracker DDL raw data block."
1406 " Problem: Found a channel with address %d on"
1407 " MANU ID %d and bus patch %d that is not connected.",
1408 blockNumber,
1409 DataType2Text(block.fDataType).c_str(),
1410 block.fPtr,
1411 block.fSize,
1412 channelId,
1413 manuId,
1414 busPatchId
1415 );
1416 result = false;
1417 continue;
1418 }
1419
1420 // Need to also load the correct segmentation to check the channel.
1421 const AliMpVSegmentation* seg =
1422 AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(
1423 busPatch->GetDEId(), manuId
1424 );
1425 if (seg == NULL)
1426 {
1427 HLTError("Could not load segmentation for detector element %d"
1428 " and MANU ID %d.",
1429 busPatch->GetDEId(), manuId
1430 );
1431 result = false;
1432 continue;
1433 }
1434
1435 AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId, channelId), warn);
1436 if (not pad.IsValid())
1437 {
1438 HLTError("Problem found with data block %d, fDataType = '%s',"
1439 " fPtr = %p and fSize = %u bytes."
1440 " Assuming this is a tracker DDL raw data block."
1441 " Problem: Found a channel with address %d on"
1442 " MANU ID %d and bus patch %d that is not valid.",
1443 blockNumber,
1444 DataType2Text(block.fDataType).c_str(),
1445 block.fPtr,
1446 block.fSize,
1447 channelId,
1448 manuId,
1449 busPatchId
1450 );
1451 result = false;
1452 continue;
1453 }
1454 }
1455 }
1456 else
1457 {
1458 HLTWarning("Cannot check if the bus patch IDs, MANU ID and"
1459 " channel addresses for DDL raw data are valid without"
1460 " being able to load the mapping from CDB."
1461 );
1462 result = false;
1463 }
1464 }
1465 else
1466 {
1467 HLTError("Problem found with data block %d, fDataType = '%s',"
1468 " fPtr = %p and fSize = %u bytes."
1469 " Assuming this is a DDL raw data block."
1470 " Problem: The specification does not contain a valid pattern,"
1471 " received 0x%8.8X for the specification.",
1472 blockNumber,
1473 DataType2Text(block.fDataType).c_str(),
1474 block.fPtr,
1475 block.fSize,
1476 block.fSpecification
1477 );
1478 result = false;
1479 }
1480
1481 return result;
1482}
1483
1484
1485bool AliHLTMUONDataCheckerComponent::CheckTriggerRecordsBlock(
1486 const AliHLTComponentBlockData& block,
1487 AliHLTUInt32_t blockNumber
1488 ) const
1489{
1490 /// Checks the validity of a trigger records block.
1491
1492 bool result = true;
1493 const char* name = "trigger records";
1494
1495 if (not fIgnoreSpec)
1496 {
1497 if (not IsFromTriggerOnly(block, blockNumber, name))
1498 result = false;
1499 }
1500
1501 AliHLTMUONTriggerRecordsBlockReader inblock(block.fPtr, block.fSize);
1502 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
1503 return false;
1504
1505 bool ddl[22];
1506 AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1507
1508 // Min and max allowed chamber numbers for hits:
1509 Int_t minCh = AliMUONConstants::NCh() - AliMUONConstants::NTriggerCh();
1510 Int_t maxCh = AliMUONConstants::NCh() - 1;
1511
1512 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1513 {
1514 // Check that each hit in each trigger record has a reasonable coordinate.
1515 AliHLTMUONParticleSign sign;
1516 bool hitset[4];
1517 AliHLTMUONUtils::UnpackTriggerRecordFlags(inblock[i].fFlags, sign, hitset);
1518
1519 for (Int_t j = 0; j < 4; j++) // loop over 4 trigger chamber hits.
1520 {
1521 if (not hitset[i]) continue; // ignore hits that are not initialised.
1522 bool hitOk = IsHitCoordinateOk(
1523 block, blockNumber, name, i, inblock[i].fHit[j],
1524 minCh, maxCh, j+10, ddl
1525 );
1526 if (not hitOk) result = false;
1527 }
1528
1529 // We can also check the momentum vector.
1530 bool momOk = IsMomentumVectorOk(
1531 block, blockNumber, name, i,
1532 inblock[i].fPx, inblock[i].fPy, inblock[i].fPz
1533 );
1534 if (not momOk) result = false;
1535 }
1536
1537 // Need to check that no entries have duplicated data but with a different
1538 // ID number.
1539 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1540 {
1541 AliHLTMUONTriggerRecordStruct ti = inblock[i];
1542 ti.fId = -1;
1543 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
1544 {
1545 AliHLTMUONTriggerRecordStruct tj = inblock[j];
1546 tj.fId = ti.fId;
1547
1548 if (ti == tj)
1549 {
1550 HLTError("Problem found with data block %d, fDataType = '%s',"
1551 " fPtr = %p and fSize = %u bytes."
1552 " Assuming this is a %s data block."
1553 " Problem: The trigger records %d and %d contain the"
1554 " same data. The data might have been duplicated.",
1555 blockNumber,
1556 DataType2Text(block.fDataType).c_str(),
1557 block.fPtr,
1558 block.fSize,
1559 name,
1560 i, j
1561 );
1562 result = false;
1563 }
1564 }
1565 }
1566
1567 return result;
1568}
1569
1570
1571bool AliHLTMUONDataCheckerComponent::CheckTrigRecsDebugBlock(
1572 const AliHLTComponentBlockData& block,
1573 AliHLTUInt32_t blockNumber
1574 ) const
1575{
1576 /// Checks the validity of a trigger records debug block.
1577
1578 bool result = true;
1579 const char* name = "trigger records debug information";
1580
1581 if (not fIgnoreSpec)
1582 {
1583 if (not IsFromTriggerOnly(block, blockNumber, name))
1584 result = false;
1585 }
1586
1587 AliHLTMUONTrigRecsDebugBlockReader inblock(block.fPtr, block.fSize);
1588 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
1589 return false;
1590
1591 bool ddl[22];
1592 AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1593
1594 // Check that each detector element ID is valid and the corresponding DDL
1595 // bit is set in the data block specification.
1596 if (FetchMappingStores() == 0) // are stores loaded?
1597 {
1598 Bool_t warn = kFALSE;
1599 AliMpDEStore* store = AliMpDEStore::Instance(warn);
1600 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1601 for (AliHLTUInt32_t j = 0; j < 4; j++)
1602 {
1603 const AliHLTMUONTrigRecInfoStruct& trig = inblock[i];
1604 AliMpDetElement* de = store->GetDetElement(trig.fDetElemId[j], warn);
1605 if (de == NULL)
1606 {
1607 HLTError("Problem found with data block %d, fDataType = '%s',"
1608 " fPtr = %p and fSize = %u bytes."
1609 " Assuming this is a %s data block."
1610 " Problem: The detector element number %d on chamber"
1611 " %d for trigger record debug structure %d is not valid.",
1612 blockNumber,
1613 DataType2Text(block.fDataType).c_str(),
1614 block.fPtr,
1615 block.fSize,
1616 name,
1617 trig.fDetElemId[j],
1618 j+11,
1619 i
1620 );
1621 result = false;
1622 continue;
1623 }
1624
1625 // Check that the chamber number from the detector element number
1626 // has the expected value.
1627 Int_t chamber = AliMpDEManager::GetChamberId(trig.fDetElemId[j], warn);
1628 if (chamber != Int_t(j+10))
1629 {
1630 HLTError("Problem found with data block %d, fDataType = '%s',"
1631 " fPtr = %p and fSize = %u bytes."
1632 " Assuming this is a %s data block."
1633 " Problem: The detector element number %d for trigger"
1634 " record debug structure %d, corresponds to chamber"
1635 " %d, but we expected a hit for chamber %d.",
1636 blockNumber,
1637 DataType2Text(block.fDataType).c_str(),
1638 block.fPtr,
1639 block.fSize,
1640 name,
1641 trig.fDetElemId[j],
1642 i,
1643 chamber+1,
1644 j+11
1645 );
1646 result = false;
1647 }
1648
1649 if (fIgnoreSpec) continue;
1650 if (0 <= de->GetDdlId() and de->GetDdlId() < 22 and ddl[de->GetDdlId()])
1651 {
1652 HLTError("Problem found with data block %d, fDataType = '%s',"
1653 " fPtr = %p and fSize = %u bytes."
1654 " Assuming this is a %s data block."
1655 " Problem: The detector element number %d for trigger"
1656 " record %d corresponds to DDL number %d, but the"
1657 " data block specification 0x%8.8X does not have the"
1658 " corresponding bit set.",
1659 blockNumber,
1660 DataType2Text(block.fDataType).c_str(),
1661 block.fPtr,
1662 block.fSize,
1663 name,
1664 trig.fDetElemId[j],
1665 i,
1666 de->GetDdlId(),
1667 block.fSpecification
1668 );
1669 result = false;
1670 }
1671 }
1672 }
1673 else
1674 {
1675 HLTWarning("Cannot check trigger record debug information without"
1676 " being able to load the mapping from CDB."
1677 );
1678 result = false;
1679 }
1680
1681 // Need to check that no entries have duplicated data but with a different
1682 // ID number.
1683 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1684 {
1685 AliHLTMUONTrigRecInfoStruct ti = inblock[i];
1686 ti.fTrigRecId = -1;
1687 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
1688 {
1689 AliHLTMUONTrigRecInfoStruct tj = inblock[j];
1690 tj.fTrigRecId = ti.fTrigRecId;
1691
1692 if (ti == tj)
1693 {
1694 HLTError("Problem found with data block %d, fDataType = '%s',"
1695 " fPtr = %p and fSize = %u bytes."
1696 " Assuming this is a %s data block."
1697 " Problem: The trigger record debug information"
1698 " structures %d and %d contain the same data."
1699 " The data might have been duplicated.",
1700 blockNumber,
1701 DataType2Text(block.fDataType).c_str(),
1702 block.fPtr,
1703 block.fSize,
1704 name,
1705 i, j
1706 );
1707 result = false;
1708 }
1709 }
1710
1711 // Can also check that the value of the fZmiddle and fBl.
1712 bool paramsOk = AreMomentumCalcParamsOk(
1713 block, blockNumber, name, i, ti.fZmiddle, ti.fBl
1714 );
1715 if (not paramsOk) result = false;
1716 }
1717
1718 return result;
1719}
1720
1721
1722bool AliHLTMUONDataCheckerComponent::CheckRecHitsBlock(
1723 const AliHLTComponentBlockData& block,
1724 AliHLTUInt32_t blockNumber
1725 ) const
1726{
1727 /// Checks the validity of a reconstructed hits block.
1728
1729 bool result = true;
1730 const char* name = "reconstructed hits";
1731
1732 if (not fIgnoreSpec)
1733 {
1734 if (not IsFromTrackerOnly(block, blockNumber, name))
1735 result = false;
1736 }
1737
1738 AliHLTMUONRecHitsBlockReader inblock(block.fPtr, block.fSize);
1739 if (not CheckBlockHeaderOnly(block, blockNumber, inblock, name))
1740 return false;
1741
1742 bool ddl[22];
1743 AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1744
1745 // Check that each hit has a reasonable coordinate.
1746 Int_t minCh = 0;
1747 Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
1748 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1749 {
1750 bool hitOk = IsHitCoordinateOk(
1751 block, blockNumber, name, i, inblock[i],
1752 minCh, maxCh, -1, ddl
1753 );
1754 if (not hitOk) result = false;
1755 }
1756
1757 return result;
1758}
1759
1760
1761bool AliHLTMUONDataCheckerComponent::CheckClustersBlock(
1762 const AliHLTComponentBlockData& block,
1763 AliHLTUInt32_t blockNumber
1764 ) const
1765{
1766 /// Checks the validity of a clusters block.
1767
1768 bool result = true;
1769 const char* name = "clusters";
1770
1771 if (not fIgnoreSpec)
1772 {
1773 if (not IsFromTrackerOnly(block, blockNumber, name))
1774 result = false;
1775 }
1776
1777 AliHLTMUONClustersBlockReader inblock(block.fPtr, block.fSize);
1778 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
1779 return false;
1780
1781 bool ddl[22];
1782 AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1783
1784 if (FetchMappingStores() == 0) // are stores loaded?
1785 {
1786 Bool_t warn = kFALSE;
1787 AliMpDEStore* store = AliMpDEStore::Instance(warn);
1788 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1789 {
1790 const AliHLTMUONClusterStruct& cluster = inblock[i];
1791
1792 // Check that the detector element ID is valid.
1793 AliMpDetElement* de = store->GetDetElement(cluster.fDetElemId, warn);
1794 if (de == NULL)
1795 {
1796 HLTError("Problem found with data block %d, fDataType = '%s',"
1797 " fPtr = %p and fSize = %u bytes."
1798 " Assuming this is a %s data block."
1799 " Problem: The detector element number %d for cluster"
1800 " %d is not valid.",
1801 blockNumber,
1802 DataType2Text(block.fDataType).c_str(),
1803 block.fPtr,
1804 block.fSize,
1805 name,
1806 cluster.fDetElemId,
1807 i
1808 );
1809 result = false;
1810 continue;
1811 }
1812
1813 // Check that the chamber number found from the hit coordinate and
1814 // that from the detector element number are the same.
1815 Int_t chamberFromHit = AliMUONConstants::ChamberNumber(cluster.fHit.fZ, warn);
1816 Int_t chamberFromDE = AliMpDEManager::GetChamberId(cluster.fDetElemId, warn);
1817 if (chamberFromHit != chamberFromDE)
1818 {
1819 HLTError("Problem found with data block %d, fDataType = '%s',"
1820 " fPtr = %p and fSize = %u bytes."
1821 " Assuming this is a %s data block."
1822 " Problem: The detector element number %d for"
1823 " cluster %d, corresponds to chamber %d, but"
1824 " found a different chamber number %d for the"
1825 " corresponding hit coordinate {x = %f, y = %f,"
1826 " z = %f}.",
1827 blockNumber,
1828 DataType2Text(block.fDataType).c_str(),
1829 block.fPtr,
1830 block.fSize,
1831 name,
1832 cluster.fDetElemId,
1833 i,
1834 chamberFromDE+1,
1835 chamberFromHit+1,
1836 cluster.fHit.fX,
1837 cluster.fHit.fY,
1838 cluster.fHit.fZ
1839 );
1840 result = false;
1841 }
1842
1843 // Make sure the corresponding DDL bit is set in the data
1844 // block specification.
1845 if (fIgnoreSpec) continue;
1846 if (0 <= de->GetDdlId() and de->GetDdlId() < 22 and ddl[de->GetDdlId()])
1847 {
1848 HLTError("Problem found with data block %d, fDataType = '%s',"
1849 " fPtr = %p and fSize = %u bytes."
1850 " Assuming this is a %s data block."
1851 " Problem: The detector element number %d for cluster"
1852 " %d corresponds to DDL number %d, but the data"
1853 " block specification 0x%8.8X does not have the"
1854 " corresponding bit set.",
1855 blockNumber,
1856 DataType2Text(block.fDataType).c_str(),
1857 block.fPtr,
1858 block.fSize,
1859 name,
1860 cluster.fDetElemId,
1861 i,
1862 de->GetDdlId(),
1863 block.fSpecification
1864 );
1865 result = false;
1866 }
1867 }
1868 }
1869 else
1870 {
1871 HLTWarning("Cannot check cluster information without being able"
1872 " to load the mapping from CDB."
1873 );
1874 result = false;
1875 }
1876
1877 // Min and max chamber numbers allowed for the cluster hits.
1878 Int_t minCh = 0;
1879 Int_t maxCh = AliMUONConstants::NTrackingCh() - 1;
1880
1881 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1882 {
1883 // Need to check that no cluster data has duplicated data but with
1884 // a different ID number.
1885 AliHLTMUONClusterStruct ci = inblock[i];
1886 ci.fId = -1;
1887 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
1888 {
1889 AliHLTMUONClusterStruct cj = inblock[j];
1890 cj.fId = ci.fId;
1891
1892 if (ci == cj)
1893 {
1894 HLTError("Problem found with data block %d, fDataType = '%s',"
1895 " fPtr = %p and fSize = %u bytes."
1896 " Assuming this is a %s data block."
1897 " Problem: The cluster structures %d and %d contain"
1898 " the same data. The data might have been duplicated.",
1899 blockNumber,
1900 DataType2Text(block.fDataType).c_str(),
1901 block.fPtr,
1902 block.fSize,
1903 name,
1904 i, j
1905 );
1906 result = false;
1907 }
1908 }
1909
1910 // Check that the hit structure in the cluster corresponds
1911 // to a tracker chamber.
1912 bool hitOk = IsHitCoordinateOk(
1913 block, blockNumber, name, i, ci.fHit,
1914 minCh, maxCh, -1, ddl
1915 );
1916 if (not hitOk) result = false;
1917 }
1918
1919 return result;
1920}
1921
1922
1923bool AliHLTMUONDataCheckerComponent::CheckChannelsBlock(
1924 const AliHLTComponentBlockData& block,
1925 AliHLTUInt32_t blockNumber
1926 ) const
1927{
1928 /// Checks the validity of a channels block.
1929
1930 bool result = true;
1931 const char* name = "channels";
1932
1933 if (not fIgnoreSpec)
1934 {
1935 if (not IsFromTrackerOnly(block, blockNumber, name))
1936 result = false;
1937 }
1938
1939 AliHLTMUONChannelsBlockReader inblock(block.fPtr, block.fSize);
1940 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
1941 return false;
1942
1943 bool ddl[22];
1944 AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
1945
1946 if (FetchMappingStores() == 0) // are stores loaded?
1947 {
1948 Bool_t warn = kFALSE;
1949 AliMpDDLStore* store = AliMpDDLStore::Instance(warn);
1950
1951 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
1952 {
1953 const AliHLTMUONChannelStruct& channel = inblock[i];
1954
1955 // Check if the bus patch is valid.
1956 AliMpBusPatch* busPatch = store->GetBusPatch(channel.fBusPatch, warn);
1957 if (busPatch == NULL)
1958 {
1959 HLTError("Problem found with data block %d, fDataType = '%s',"
1960 " fPtr = %p and fSize = %u bytes."
1961 " Assuming this is a %s data block."
1962 " Problem: Found a bus patch identifier %d that"
1963 " is not valid.",
1964 blockNumber,
1965 DataType2Text(block.fDataType).c_str(),
1966 block.fPtr,
1967 block.fSize,
1968 name,
1969 channel.fBusPatch
1970 );
1971 result = false;
1972 continue;
1973 }
1974
1975 // We can check that the bus patch is for a DDL
1976 // which is also indicated by the specification bits.
1977 if (not fIgnoreSpec and (
1978 not (0 <= busPatch->GetDdlId() and busPatch->GetDdlId() < 20)
1979 or (0 <= busPatch->GetDdlId() and busPatch->GetDdlId() < 20
1980 and not ddl[busPatch->GetDdlId()])
1981 ))
1982 {
1983 HLTError("Problem found with data block %d, fDataType = '%s',"
1984 " fPtr = %p and fSize = %u bytes."
1985 " Assuming this is a %s data block."
1986 " Problem: Found a bus patch identifier %d for"
1987 " DDL %d, but the data block specification 0x%8.8X"
1988 " does not have the corresponding bit set.",
1989 blockNumber,
1990 DataType2Text(block.fDataType).c_str(),
1991 block.fPtr,
1992 block.fSize,
1993 name,
1994 channel.fBusPatch,
1995 busPatch->GetDdlId(),
1996 block.fSpecification
1997 );
1998 result = false;
1999 continue;
2000 }
2001
2002 // Check if the MANU ID is valid.
2003 if (not busPatch->HasManu(channel.fManu))
2004 {
2005 HLTError("Problem found with data block %d, fDataType = '%s',"
2006 " fPtr = %p and fSize = %u bytes."
2007 " Assuming this is a %s data block."
2008 " Problem: Found a MANU identifier %d on bus patch %d"
2009 " that is not valid.",
2010 blockNumber,
2011 DataType2Text(block.fDataType).c_str(),
2012 block.fPtr,
2013 block.fSize,
2014 name,
2015 channel.fManu,
2016 channel.fBusPatch
2017 );
2018 result = false;
2019 continue;
2020 }
2021
2022 // Now try to fetch the detector element to check the MANU channel.
2023 AliMpDetElement* de = store->GetDetElement(busPatch->GetDEId(), warn);
2024 if (de == NULL)
2025 {
2026 HLTError("Problem found with data block %d, fDataType = '%s',"
2027 " fPtr = %p and fSize = %u bytes."
2028 " Assuming this is a %s data block."
2029 " Problem: Found a bus patch identifier %d that"
2030 " does not correspond to a detector element.",
2031 blockNumber,
2032 DataType2Text(block.fDataType).c_str(),
2033 block.fPtr,
2034 block.fSize,
2035 name,
2036 channel.fBusPatch
2037 );
2038 result = false;
2039 continue;
2040 }
2041
2042 if (not de->IsConnectedChannel(channel.fManu, channel.fChannelAddress))
2043 {
2044 // Just a warning because this is marked not
2045 // to be an error in the AliMUONDigitMaker.
2046 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2047 " fPtr = %p and fSize = %u bytes."
2048 " Assuming this is a %s data block."
2049 " Problem: Found a channel with address %d on"
2050 " MANU ID %d and bus patch %d that is not connected.",
2051 blockNumber,
2052 DataType2Text(block.fDataType).c_str(),
2053 block.fPtr,
2054 block.fSize,
2055 name,
2056 channel.fChannelAddress,
2057 channel.fManu,
2058 channel.fBusPatch
2059 );
2060 result = false;
2061 continue;
2062 }
2063
2064 // Need to also load the correct segmentation to check the channel.
2065 const AliMpVSegmentation* seg =
2066 AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(
2067 busPatch->GetDEId(), channel.fManu
2068 );
2069 if (seg == NULL)
2070 {
2071 HLTError("Could not load segmentation for detector element %d"
2072 " and MANU ID %d.",
2073 busPatch->GetDEId(), channel.fManu
2074 );
2075 result = false;
2076 continue;
2077 }
2078
2079 AliMpPad pad = seg->PadByLocation(
2080 AliMpIntPair(channel.fManu, channel.fChannelAddress),
2081 warn
2082 );
2083 if (not pad.IsValid())
2084 {
2085 HLTError("Problem found with data block %d, fDataType = '%s',"
2086 " fPtr = %p and fSize = %u bytes."
2087 " Assuming this is a %s data block."
2088 " Problem: Found a channel with address %d on"
2089 " MANU ID %d and bus patch %d that is not valid.",
2090 blockNumber,
2091 DataType2Text(block.fDataType).c_str(),
2092 block.fPtr,
2093 block.fSize,
2094 name,
2095 channel.fChannelAddress,
2096 channel.fManu,
2097 channel.fBusPatch
2098 );
2099 result = false;
2100 continue;
2101 }
2102 }
2103 }
2104 else
2105 {
2106 HLTWarning("Cannot check channel information without being able"
2107 " to load the mapping from CDB."
2108 );
2109 result = false;
2110 }
2111
2112 // Need to check that no channel data has duplicated data but with
2113 // a different cluster ID number.
2114 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2115 {
2116 AliHLTMUONChannelStruct ci = inblock[i];
2117 ci.fClusterId = -1;
2118 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2119 {
2120 AliHLTMUONChannelStruct cj = inblock[j];
2121 cj.fClusterId = ci.fClusterId;
2122
2123 if (ci == cj)
2124 {
2125 HLTError("Problem found with data block %d, fDataType = '%s',"
2126 " fPtr = %p and fSize = %u bytes."
2127 " Assuming this is a %s data block."
2128 " Problem: The channel structures %d and %d contain"
2129 " the same data. The data might have been duplicated.",
2130 blockNumber,
2131 DataType2Text(block.fDataType).c_str(),
2132 block.fPtr,
2133 block.fSize,
2134 name,
2135 i, j
2136 );
2137 result = false;
2138 }
2139 }
2140 }
2141
2142 return result;
2143}
2144
2145
2146bool AliHLTMUONDataCheckerComponent::CheckMansoTracksBlock(
2147 const AliHLTComponentBlockData& block,
2148 AliHLTUInt32_t blockNumber
2149 ) const
2150{
2151 /// Checks the validity of a Manso tracks block.
2152
2153 bool result = true;
2154 const char* name = "Manso tracks";
2155
2156 if (not fIgnoreSpec)
2157 {
2158 if (not IsSpecificationValid(block, blockNumber, name))
2159 result = false;
2160 }
2161
2162 AliHLTMUONMansoTracksBlockReader inblock(block.fPtr, block.fSize);
2163 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2164 return false;
2165
2166 bool ddl[22];
2167 AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2168
2169 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2170 {
2171 // Need to check that no entries have duplicated data but with
2172 // a different track ID number.
2173 AliHLTMUONMansoTrackStruct ti = inblock[i];
2174 ti.fId = -1;
2175 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2176 {
2177 AliHLTMUONMansoTrackStruct tj = inblock[j];
2178 tj.fId = ti.fId;
2179
2180 if (ti == tj)
2181 {
2182 HLTError("Problem found with data block %d, fDataType = '%s',"
2183 " fPtr = %p and fSize = %u bytes."
2184 " Assuming this is a %s data block."
2185 " Problem: The Manso tracks %d and %d contain the"
2186 " same data. The data might have been duplicated.",
2187 blockNumber,
2188 DataType2Text(block.fDataType).c_str(),
2189 block.fPtr,
2190 block.fSize,
2191 name,
2192 i, j
2193 );
2194 result = false;
2195 }
2196 }
2197
2198 bool trackOk = IsMansoTrackOk(block, blockNumber, name, i, ti, ddl);
2199 if (not trackOk) result = false;
2200 }
2201
2202 return result;
2203}
2204
2205
2206bool AliHLTMUONDataCheckerComponent::CheckMansoCandidatesBlock(
2207 const AliHLTComponentBlockData& block,
2208 AliHLTUInt32_t blockNumber
2209 ) const
2210{
2211 /// Checks the validity of a Manso candidates block.
2212
2213 bool result = true;
2214 const char* name = "Manso track candidates";
2215
2216 if (not fIgnoreSpec)
2217 {
2218 if (not IsSpecificationValid(block, blockNumber, name))
2219 result = false;
2220 }
2221
2222 AliHLTMUONMansoCandidatesBlockReader inblock(block.fPtr, block.fSize);
2223 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2224 return false;
2225
2226 bool ddl[22];
2227 AliHLTMUONUtils::UnpackSpecBits(block.fSpecification, ddl);
2228
2229 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
2230 {
2231 // Need to check that no entries have duplicated data but with a
2232 // different track ID number.
2233 AliHLTMUONMansoCandidateStruct ti = inblock[i];
2234 ti.fTrack.fId = -1;
2235 for (AliHLTUInt32_t j = i+1; j < inblock.Nentries(); j++)
2236 {
2237 AliHLTMUONMansoCandidateStruct tj = inblock[j];
2238 tj.fTrack.fId = ti.fTrack.fId;
2239
2240 if (ti == tj)
2241 {
2242 HLTError("Problem found with data block %d, fDataType = '%s',"
2243 " fPtr = %p and fSize = %u bytes."
2244 " Assuming this is a %s data block."
2245 " Problem: The Manso track candidates %d and %d"
2246 " contain the same data."
2247 " The data might have been duplicated.",
2248 blockNumber,
2249 DataType2Text(block.fDataType).c_str(),
2250 block.fPtr,
2251 block.fSize,
2252 name,
2253 i, j
2254 );
2255 result = false;
2256 }
2257 }
2258
2259 bool trackOk = IsMansoTrackOk(block, blockNumber, name, i, ti.fTrack, ddl);
2260 if (not trackOk) result = false;
2261
2262 // Check that each ROI has a centre point somewhere on the correct
2263 // corresponding chamber and that the Radius is not bigger thant
2264 // the diameter of the chamber which would be pointless.
2265 for (AliHLTInt32_t j = 0; j < 4; j++)
2266 {
2267 if (ti.fRoI[j].fRadius == -1) continue; // Ignore invalid ROIs
2268
2269 Int_t chamber = AliMUONConstants::ChamberNumber(
2270 ti.fRoI[j].fZ, false // false = do not warn.
2271 );
2272 if (chamber != j+6)
2273 {
2274 HLTError("Problem found with data block %d, fDataType = '%s',"
2275 " fPtr = %p and fSize = %u bytes."
2276 " Assuming this is a %s data block."
2277 " Problem: The region of interest on chamber %d for"
2278 " Manso track candidate %d has a z-coordinate of %f"
2279 " cm that does not correspond to that chamber.",
2280 blockNumber,
2281 DataType2Text(block.fDataType).c_str(),
2282 block.fPtr,
2283 block.fSize,
2284 name,
2285 j+6+1,
2286 i,
2287 ti.fRoI[j].fZ
2288 );
2289 result = false;
2290 }
2291
2292 double x = ti.fRoI[j].fX;
2293 double y = ti.fRoI[j].fY;
2294 double r = sqrt(x*x + y*y);
2295 if (r > AliMUONConstants::Dmax((j+6)/2))
2296 {
2297 // Just a warning since this is not a data integrity problem
2298 // but rather just a data sanity problem.
2299 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2300 " fPtr = %p and fSize = %u bytes."
2301 " Assuming this is a %s data block."
2302 " Problem: The region of interest coordinate {x = %f,"
2303 " y = %f} cm on chamber %d for Manso track candidate %d"
2304 " does not correspond to that chamber.",
2305 blockNumber,
2306 DataType2Text(block.fDataType).c_str(),
2307 block.fPtr,
2308 block.fSize,
2309 name,
2310 ti.fRoI[j].fX,
2311 ti.fRoI[j].fY,
2312 j+6+1,
2313 i
2314 );
2315 result = false;
2316 }
2317
2318 if (ti.fRoI[j].fRadius > AliMUONConstants::Dmax((j+6)/2))
2319 {
2320 // Just a warning since this is not a data integrity problem
2321 // but rather just a data sanity problem.
2322 HLTWarning("Problem found with data block %d, fDataType = '%s',"
2323 " fPtr = %p and fSize = %u bytes."
2324 " Assuming this is a %s data block."
2325 " Problem: The region of interest radius of %f cm"
2326 " on chamber %d for Manso track candidate %d"
2327 " is bigger than the chamber diameter %f cm.",
2328 blockNumber,
2329 DataType2Text(block.fDataType).c_str(),
2330 block.fPtr,
2331 block.fSize,
2332 name,
2333 ti.fRoI[j].fRadius,
2334 j+6+1,
2335 i,
2336 AliMUONConstants::Dmax((j+6)/2)
2337 );
2338 result = false;
2339 }
2340 }
2341 }
2342
2343 return result;
2344}
2345
2346
2347bool AliHLTMUONDataCheckerComponent::CheckSinglesDecisionBlock(
2348 const AliHLTComponentBlockData& block,
2349 AliHLTUInt32_t blockNumber
2350 ) const
2351{
2352 /// Checks the validity of a single tracks trigger decision block.
2353
2354 bool result = true;
2355 const char* name = "singles decision";
2356
2357 if (not fIgnoreSpec)
2358 {
2359 if (not IsSpecificationValid(block, blockNumber, name))
2360 result = false;
2361 }
2362
2363 AliHLTMUONSinglesDecisionBlockReader inblock(block.fPtr, block.fSize);
2364 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2365 return false;
2366
2367 return result;
2368}
2369
2370
2371bool AliHLTMUONDataCheckerComponent::CheckPairsDecisionBlock(
2372 const AliHLTComponentBlockData& block,
2373 AliHLTUInt32_t blockNumber
2374 ) const
2375{
2376 /// Checks the validity of a track pairs trigger decision block.
2377
2378 bool result = true;
2379 const char* name = "pairs decision";
2380
2381 if (not fIgnoreSpec)
2382 {
2383 if (not IsSpecificationValid(block, blockNumber, name))
2384 result = false;
2385 }
2386
2387 AliHLTMUONPairsDecisionBlockReader inblock(block.fPtr, block.fSize);
2388 if (not CheckBlockIntegrity(block, blockNumber, inblock, name))
2389 return false;
2390
2391 return result;
2392}
2393
2394
2395bool AliHLTMUONDataCheckerComponent::AreMomentaCompatible(
2396 AliHLTFloat32_t px1,
2397 AliHLTFloat32_t py1,
2398 AliHLTFloat32_t pz1,
2399 AliHLTFloat32_t px2,
2400 AliHLTFloat32_t py2,
2401 AliHLTFloat32_t pz2
2402 ) const
2403{
2404 /// Checks to see if the two momenta vectors are compatible or not.
2405 /// The vectors should not have an angle more than 10 degrees between
2406 /// them and their magnitudes should not be more different than 50%.
2407
2408 double p1 = sqrt(px1*px1 + py1*py1 + pz1*pz1);
2409 double p2 = sqrt(px2*px2 + py2*py2 + pz2*pz2);
2410 if (p1 == 0 and p2 == 0) return true;
2411 if (fabs(p1 - p2) / ((p1 + p2)*0.5) > 0.5) return false;
2412 double denom = p1 * p2;
2413 if (denom == 0) return false;
2414 double angle = acos( (px1*px2 + py1*py2 + pz1*pz2) / denom );
2415 if (angle > 3.14159265358979323846 * 10. / 180.) return false;
2416 return true;
2417}
2418
2419
2420bool AliHLTMUONDataCheckerComponent::IsScalarTooLarge(
2421 const AliHLTComponentBlockData* block,
2422 AliHLTUInt32_t blockNumber,
2423 const char* blockTypeName,
2424 const char* scalarName,
2425 AliHLTUInt32_t scalarValue,
2426 AliHLTUInt32_t totalTrackCount
2427 ) const
2428{
2429 /// Checks if the scalar value is larger than the number of Manso
2430 /// tracks in the event.
2431
2432 if (scalarValue > totalTrackCount)
2433 {
2434 HLTError("Problem found with %s trigger decision"
2435 " data block %d, fDataType = '%s', fPtr = %p and"
2436 " fSize = %u bytes."
2437 " Problem: The %s scalar with value %d is larger"
2438 " than the total number of Manso tracks found for the"
2439 " event (%d tracks).",
2440 blockTypeName,
2441 blockNumber,
2442 DataType2Text(block->fDataType).c_str(),
2443 block->fPtr,
2444 block->fSize,
2445 scalarName,
2446 scalarValue,
2447 totalTrackCount
2448 );
2449 return true;
2450 }
2451 else
2452 {
2453 return false;
2454 }
2455}
2456
2457
2458bool AliHLTMUONDataCheckerComponent::IsScalarALargerThanB(
2459 const AliHLTComponentBlockData* block,
2460 AliHLTUInt32_t blockNumber,
2461 const char* blockTypeName,
2462 const char* scalarAName,
2463 AliHLTUInt32_t scalarAValue,
2464 const char* scalarBName,
2465 AliHLTUInt32_t scalarBValue
2466 ) const
2467{
2468 /// Checks if the scalar value is larger than the number of Manso
2469 /// tracks in the event.
2470
2471 if (scalarAValue > scalarBValue)
2472 {
2473 HLTError("Problem found with %s trigger decision"
2474 " data block %d, fDataType = '%s', fPtr = %p and"
2475 " fSize = %u bytes."
2476 " Problem: The %s scalar with value %d is larger"
2477 " than scalar %s with value %d, but is should not be.",
2478 blockTypeName,
2479 blockNumber,
2480 DataType2Text(block->fDataType).c_str(),
2481 block->fPtr,
2482 block->fSize,
2483 scalarAName,
2484 scalarAValue,
2485 scalarBName,
2486 scalarBValue
2487 );
2488 return true;
2489 }
2490 else
2491 {
2492 return false;
2493 }
2494}
2495
2496
2497void AliHLTMUONDataCheckerComponent::MarkBlock(
2498 const AliHLTComponentBlockData* blocks,
2499 bool* blockOk,
2500 AliHLTUInt32_t blockCount,
2501 const AliHLTComponentBlockData* blockToMark
2502 ) const
2503{
2504 /// Tries to find the 'blockToMark' in the list of blocks and sets the
2505 /// corresponding 'blockOk' flag to false.
2506
2507 for (AliHLTUInt32_t i = 0; i < blockCount; i++)
2508 {
2509 if (&blocks[i] == blockToMark)
2510 {
2511 blockOk[i] = false;
2512 return;
2513 }
2514 }
2515}
2516
2517
2518void AliHLTMUONDataCheckerComponent::MakeGlobalChecks(
2519 const AliHLTComponentBlockData* blocks,
2520 bool* blockOk,
2521 AliHLTUInt32_t blockCount,
2522 const AliHLTComponentBlockData** trigRecBlocks,
2523 AliHLTUInt32_t trigRecBlocksCount,
2524 const AliHLTComponentBlockData** trigRecDebugBlocks,
2525 AliHLTUInt32_t trigRecDebugBlocksCount,
2526 const AliHLTComponentBlockData** hitBlocks,
2527 AliHLTUInt32_t hitBlocksCount,
2528 const AliHLTComponentBlockData** clusterBlocks,
2529 AliHLTUInt32_t clusterBlocksCount,
2530 const AliHLTComponentBlockData** channelBlocks,
2531 AliHLTUInt32_t channelBlocksCount,
2532 const AliHLTComponentBlockData** mansoTrackBlocks,
2533 AliHLTUInt32_t mansoTrackBlocksCount,
2534 const AliHLTComponentBlockData** mansoCandidateBlocks,
2535 AliHLTUInt32_t mansoCandidateBlocksCount,
2536 const AliHLTComponentBlockData** singleDecisionBlocks,
2537 AliHLTUInt32_t singleDecisionBlocksCount,
2538 const AliHLTComponentBlockData** pairDecisionBlocks,
2539 AliHLTUInt32_t pairDecisionBlocksCount
2540 ) const
2541{
2542 /// The following set of global checks are performed:
2543 /// 1) Checks if all the ID numbers in all the blocks are unique.
2544 /// 2) Check if all the structures are unique up to their ID numbers,
2545 /// that it, make sure there are no structures with the same data but
2546 /// for a different ID number.
2547 /// 3) Check if the reference ID numbers are correct, i.e. are the
2548 /// trigger record ID numbers in the track structures found in any of
2549 /// the trigger record data blocks.
2550 /// 4) Do the number of channels claimed in the cluster correspond to
2551 /// the number of channel structures.
2552 /// 5) Check that the momentum vectors between the Manso tracks and
2553 /// the corresponding trigger record are compatible.
2554 /// 6) Check that the trigger decision scalars are reasonable.
2555
2556 // Check if all the trigger record identifiers and data are unique.
2557 for (AliHLTUInt32_t bi = 0; bi < trigRecBlocksCount; bi++)
2558 {
2559 AliHLTMUONTriggerRecordsBlockReader inblocki(trigRecBlocks[bi]->fPtr, trigRecBlocks[bi]->fSize);
2560 if (not inblocki.BufferSizeOk()) continue;
2561 for (AliHLTUInt32_t bj = bi+1; bj < trigRecBlocksCount; bj++)
2562 {
2563 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
2564 if (not inblockj.BufferSizeOk()) continue;
2565
2566 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2567 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2568 {
2569 if (inblocki[i].fId == inblockj[j].fId)
2570 {
2571 HLTError("Problem found with trigger record data block %d,"
2572 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
2573 " and trigger record data block %d,"
2574 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2575 " Problem: Trigger record %d in block %d and entry"
2576 " %d in block %d have the same identfier, but they"
2577 " should be unique.",
2578 bi,
2579 DataType2Text(trigRecBlocks[bi]->fDataType).c_str(),
2580 trigRecBlocks[bi]->fPtr,
2581 trigRecBlocks[bi]->fSize,
2582 bj,
2583 DataType2Text(trigRecBlocks[bj]->fDataType).c_str(),
2584 trigRecBlocks[bj]->fPtr,
2585 trigRecBlocks[bj]->fSize,
2586 bi, i,
2587 bj, j
2588 );
2589 MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bi]);
2590 MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
2591 }
2592
2593 AliHLTMUONTriggerRecordStruct a = inblocki[i];
2594 AliHLTMUONTriggerRecordStruct b = inblockj[j];
2595 a.fId = b.fId = -1;
2596 if (a == b)
2597 {
2598 HLTError("Problem found with trigger record data block %d,"
2599 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
2600 " and trigger record data block %d,"
2601 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2602 " Problem: Trigger record %d in block %d and entry"
2603 " %d in block %d have the same data."
2604 " The data may have been duplicated.",
2605 bi,
2606 DataType2Text(trigRecBlocks[bi]->fDataType).c_str(),
2607 trigRecBlocks[bi]->fPtr,
2608 trigRecBlocks[bi]->fSize,
2609 bj,
2610 DataType2Text(trigRecBlocks[bj]->fDataType).c_str(),
2611 trigRecBlocks[bj]->fPtr,
2612 trigRecBlocks[bj]->fSize,
2613 bi, i,
2614 bj, j
2615 );
2616 MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bi]);
2617 MarkBlock(blocks, blockOk, blockCount, trigRecBlocks[bj]);
2618 }
2619 }
2620 }
2621 }
2622
2623 for (AliHLTUInt32_t bi = 0; bi < trigRecDebugBlocksCount; bi++)
2624 {
2625 AliHLTMUONTrigRecsDebugBlockReader inblocki(trigRecDebugBlocks[bi]->fPtr, trigRecDebugBlocks[bi]->fSize);
2626 if (not inblocki.BufferSizeOk()) continue;
2627
2628 // Check if all the trigger record IDs in the debug information structures exist.
2629 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2630 {
2631 bool found = false;
2632
2633 for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
2634 {
2635 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
2636 if (not inblockj.BufferSizeOk()) continue;
2637
2638 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2639 {
2640 if (inblocki[i].fTrigRecId == inblockj[j].fId)
2641 {
2642 found = true;
2643 break;
2644 }
2645 }
2646 }
2647
2648 if (not found)
2649 {
2650 HLTError("Problem found with trigger record debug information"
2651 " data block %d, fDataType = '%s', fPtr = %p and"
2652 " fSize = %u bytes."
2653 " Problem with entry %d in block: The trigger record"
2654 " identifier %d does not exist in any trigger record"
2655 " data block.",
2656 bi,
2657 DataType2Text(trigRecDebugBlocks[bi]->fDataType).c_str(),
2658 trigRecDebugBlocks[bi]->fPtr,
2659 trigRecDebugBlocks[bi]->fSize,
2660 i, inblocki[i].fTrigRecId
2661 );
2662 MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
2663 }
2664 }
2665
2666 // Check if all the trigger record debug information structures are unique.
2667 for (AliHLTUInt32_t bj = bi+1; bj < trigRecDebugBlocksCount; bj++)
2668 {
2669 AliHLTMUONTrigRecsDebugBlockReader inblockj(trigRecDebugBlocks[bj]->fPtr, trigRecDebugBlocks[bj]->fSize);
2670 if (not inblockj.BufferSizeOk()) continue;
2671
2672 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2673 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2674 {
2675 AliHLTMUONTrigRecInfoStruct a = inblocki[i];
2676 AliHLTMUONTrigRecInfoStruct b = inblockj[j];
2677 a.fTrigRecId = b.fTrigRecId = -1;
2678 if (a == b)
2679 {
2680 HLTError("Problem found with trigger record debug information"
2681 " data block %d, fDataType = '%s', fPtr = %p and"
2682 " fSize = %u bytes, and trigger record debug"
2683 " information data block %d,"
2684 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2685 " Problem: The trigger record debug inforamtion"
2686 " structure %d in block %d and entry"
2687 " %d in block %d have the same data."
2688 " The data may have been duplicated.",
2689 bi,
2690 DataType2Text(trigRecDebugBlocks[bi]->fDataType).c_str(),
2691 trigRecDebugBlocks[bi]->fPtr,
2692 trigRecDebugBlocks[bi]->fSize,
2693 bj,
2694 DataType2Text(trigRecDebugBlocks[bj]->fDataType).c_str(),
2695 trigRecDebugBlocks[bj]->fPtr,
2696 trigRecDebugBlocks[bj]->fSize,
2697 bi, i,
2698 bj, j
2699 );
2700 MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bi]);
2701 MarkBlock(blocks, blockOk, blockCount, trigRecDebugBlocks[bj]);
2702 }
2703 }
2704 }
2705 }
2706
2707 // Check that all the reconstructed hits are unique.
2708 for (AliHLTUInt32_t bi = 0; bi < hitBlocksCount; bi++)
2709 {
2710 AliHLTMUONRecHitsBlockReader inblocki(hitBlocks[bi]->fPtr, hitBlocks[bi]->fSize);
2711 if (not inblocki.BufferSizeOk()) continue;
2712 for (AliHLTUInt32_t bj = bi+1; bj < hitBlocksCount; bj++)
2713 {
2714 AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
2715 if (not inblockj.BufferSizeOk()) continue;
2716
2717 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2718 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2719 {
2720 if (inblocki[i] == inblockj[j])
2721 {
2722 HLTError("Problem found with reconstructed hit data block %d,"
2723 " fDataType = '%s', fPtr = %p and fSize = %u bytes,"
2724 " and reconstructed hit data block %d,"
2725 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2726 " Problem: Reconstructed hit %d in block %d and entry"
2727 " %d in block %d are the same, but all hits"
2728 " should be unique.",
2729 bi,
2730 DataType2Text(hitBlocks[bi]->fDataType).c_str(),
2731 hitBlocks[bi]->fPtr,
2732 hitBlocks[bi]->fSize,
2733 bj,
2734 DataType2Text(hitBlocks[bj]->fDataType).c_str(),
2735 hitBlocks[bj]->fPtr,
2736 hitBlocks[bj]->fSize,
2737 bi, i,
2738 bj, j
2739 );
2740 MarkBlock(blocks, blockOk, blockCount, hitBlocks[bi]);
2741 MarkBlock(blocks, blockOk, blockCount, hitBlocks[bj]);
2742 }
2743 }
2744 }
2745 }
2746
2747 for (AliHLTUInt32_t bi = 0; bi < clusterBlocksCount; bi++)
2748 {
2749 AliHLTMUONClustersBlockReader inblocki(clusterBlocks[bi]->fPtr, clusterBlocks[bi]->fSize);
2750 if (not inblocki.BufferSizeOk()) continue;
2751
2752 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2753 {
2754 // Check if all the reconstructed hit coordinates in the cluster structures exist.
2755 bool found = false;
2756
2757 for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
2758 {
2759 AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
2760 if (not inblockj.BufferSizeOk()) continue;
2761
2762 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2763 {
2764 if (inblocki[i].fHit == inblockj[j])
2765 {
2766 found = true;
2767 break;
2768 }
2769 }
2770 }
2771
2772 // If the hit was not found then it should be nil.
2773 if (not found and (inblocki[i].fHit != AliHLTMUONConstants::NilRecHitStruct()))
2774 {
2775 HLTError("Problem found with cluster data block %d,"
2776 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2777 " Problem with entry %d in block: The cluster hit"
2778 " coordinate {x = %f, y = %f, z = %f} does not exist"
2779 " in any reconstructed hit data block.",
2780 bi,
2781 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
2782 clusterBlocks[bi]->fPtr,
2783 clusterBlocks[bi]->fSize,
2784 i,
2785 inblocki[i].fHit.fX,
2786 inblocki[i].fHit.fY,
2787 inblocki[i].fHit.fZ
2788 );
2789 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
2790 }
2791
2792 // Check that the fNchannels value is correct.
2793 AliHLTUInt32_t count = 0;
2794 for (AliHLTUInt32_t bj = 0; bj < channelBlocksCount and not found; bj++)
2795 {
2796 AliHLTMUONChannelsBlockReader inblockj(channelBlocks[bj]->fPtr, channelBlocks[bj]->fSize);
2797 if (not inblockj.BufferSizeOk()) continue;
2798
2799 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2800 {
2801 if (inblocki[i].fId == inblockj[j].fClusterId)
2802 {
2803 count++;
2804 }
2805 }
2806 }
2807
2808 if (inblocki[i].fNchannels != count)
2809 {
2810 HLTError("Problem found with cluster data block %d,"
2811 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2812 " Problem with entry %d in block: The number of"
2813 " channels in the cluster is reported as %d, but"
2814 " only %d channel structures were found.",
2815 bi,
2816 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
2817 clusterBlocks[bi]->fPtr,
2818 clusterBlocks[bi]->fSize,
2819 i,
2820 inblocki[i].fNchannels,
2821 count
2822 );
2823 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
2824 }
2825 }
2826
2827 // Check if all the cluster structures are unique up to the identifier
2828 // and have unique identifiers.
2829 for (AliHLTUInt32_t bj = bi+1; bj < clusterBlocksCount; bj++)
2830 {
2831 AliHLTMUONClustersBlockReader inblockj(clusterBlocks[bj]->fPtr, clusterBlocks[bj]->fSize);
2832 if (not inblockj.BufferSizeOk()) continue;
2833
2834 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2835 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2836 {
2837 if (inblocki[i].fId == inblockj[j].fId)
2838 {
2839 HLTError("Problem found with cluster"
2840 " data block %d, fDataType = '%s', fPtr = %p and"
2841 " fSize = %u bytes, and cluster data block %d,"
2842 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2843 " Problem: The cluster %d in block %d and entry"
2844 " %d in block %d have the same identifier, but they"
2845 " should be unique.",
2846 bi,
2847 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
2848 clusterBlocks[bi]->fPtr,
2849 clusterBlocks[bi]->fSize,
2850 bj,
2851 DataType2Text(clusterBlocks[bj]->fDataType).c_str(),
2852 clusterBlocks[bj]->fPtr,
2853 clusterBlocks[bj]->fSize,
2854 bi, i,
2855 bj, j
2856 );
2857 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
2858 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bj]);
2859 }
2860
2861 AliHLTMUONClusterStruct a = inblocki[i];
2862 AliHLTMUONClusterStruct b = inblockj[j];
2863 a.fId = b.fId = -1;
2864 if (a == b)
2865 {
2866 HLTError("Problem found with cluster"
2867 " data block %d, fDataType = '%s', fPtr = %p and"
2868 " fSize = %u bytes, and cluster data block %d,"
2869 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2870 " Problem: The cluster %d in block %d and entry"
2871 " %d in block %d have the same data."
2872 " The data may have been duplicated.",
2873 bi,
2874 DataType2Text(clusterBlocks[bi]->fDataType).c_str(),
2875 clusterBlocks[bi]->fPtr,
2876 clusterBlocks[bi]->fSize,
2877 bj,
2878 DataType2Text(clusterBlocks[bj]->fDataType).c_str(),
2879 clusterBlocks[bj]->fPtr,
2880 clusterBlocks[bj]->fSize,
2881 bi, i,
2882 bj, j
2883 );
2884 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bi]);
2885 MarkBlock(blocks, blockOk, blockCount, clusterBlocks[bj]);
2886 }
2887 }
2888 }
2889 }
2890
2891 for (AliHLTUInt32_t bi = 0; bi < channelBlocksCount; bi++)
2892 {
2893 AliHLTMUONChannelsBlockReader inblocki(channelBlocks[bi]->fPtr, channelBlocks[bi]->fSize);
2894 if (not inblocki.BufferSizeOk()) continue;
2895
2896 // Check if all the cluster IDs in the channel structures exist.
2897 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2898 {
2899 bool found = false;
2900
2901 for (AliHLTUInt32_t bj = 0; bj < clusterBlocksCount and not found; bj++)
2902 {
2903 AliHLTMUONClustersBlockReader inblockj(clusterBlocks[bj]->fPtr, clusterBlocks[bj]->fSize);
2904 if (not inblockj.BufferSizeOk()) continue;
2905
2906 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2907 {
2908 if (inblocki[i].fClusterId == inblockj[j].fId)
2909 {
2910 found = true;
2911 break;
2912 }
2913 }
2914 }
2915
2916 if (not found)
2917 {
2918 HLTError("Problem found with channel"
2919 " data block %d, fDataType = '%s', fPtr = %p and"
2920 " fSize = %u bytes."
2921 " Problem with entry %d in block: The cluster"
2922 " identifier %d does not exist in any cluster"
2923 " data block.",
2924 bi,
2925 DataType2Text(channelBlocks[bi]->fDataType).c_str(),
2926 channelBlocks[bi]->fPtr,
2927 channelBlocks[bi]->fSize,
2928 i, inblocki[i].fClusterId
2929 );
2930 MarkBlock(blocks, blockOk, blockCount, channelBlocks[bi]);
2931 }
2932 }
2933
2934 // Check if all the channel structures are unique up to the cluster ID.
2935 for (AliHLTUInt32_t bj = bi+1; bj < channelBlocksCount; bj++)
2936 {
2937 AliHLTMUONChannelsBlockReader inblockj(channelBlocks[bj]->fPtr, channelBlocks[bj]->fSize);
2938 if (not inblockj.BufferSizeOk()) continue;
2939
2940 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2941 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2942 {
2943 AliHLTMUONChannelStruct a = inblocki[i];
2944 AliHLTMUONChannelStruct b = inblockj[j];
2945 a.fClusterId = b.fClusterId = -1;
2946 if (a == b)
2947 {
2948 HLTError("Problem found with channel"
2949 " data block %d, fDataType = '%s', fPtr = %p and"
2950 " fSize = %u bytes, and channel data block %d,"
2951 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
2952 " Problem: The channel %d in block %d and entry"
2953 " %d in block %d have the same data."
2954 " The data may have been duplicated.",
2955 bi,
2956 DataType2Text(channelBlocks[bi]->fDataType).c_str(),
2957 channelBlocks[bi]->fPtr,
2958 channelBlocks[bi]->fSize,
2959 bj,
2960 DataType2Text(channelBlocks[bj]->fDataType).c_str(),
2961 channelBlocks[bj]->fPtr,
2962 channelBlocks[bj]->fSize,
2963 bi, i,
2964 bj, j
2965 );
2966 MarkBlock(blocks, blockOk, blockCount, channelBlocks[bi]);
2967 MarkBlock(blocks, blockOk, blockCount, channelBlocks[bj]);
2968 }
2969 }
2970 }
2971 }
2972
2973 // Will need the total number of tracks later for comparison to trigger scalars.
2974 AliHLTUInt32_t totalTrackCount = 0;
2975
2976 for (AliHLTUInt32_t bi = 0; bi < mansoTrackBlocksCount; bi++)
2977 {
2978 AliHLTMUONMansoTracksBlockReader inblocki(mansoTrackBlocks[bi]->fPtr, mansoTrackBlocks[bi]->fSize);
2979 if (not inblocki.BufferSizeOk()) continue;
2980
2981 totalTrackCount += inblocki.Nentries();
2982
2983 // Check if all the trigger record IDs in the Manso track structures exist.
2984 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
2985 {
2986 bool found = false;
2987
2988 for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
2989 {
2990 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
2991 if (not inblockj.BufferSizeOk()) continue;
2992
2993 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
2994 {
2995 if (inblocki[i].fTrigRec == inblockj[j].fId)
2996 {
2997 // At this point we can check if the momentum
2998 // is compatible with the trigger record.
2999 if (not AreMomentaCompatible(
3000 inblocki[i].fPx, inblocki[i].fPy, inblocki[i].fPz,
3001 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3002 )
3003 )
3004 {
3005 HLTWarning("Problem found with Manso track"
3006 " data block %d, fDataType = '%s', fPtr = %p and"
3007 " fSize = %u bytes."
3008 " Problem with Manso track %d in block: The momentum"
3009 " vector of the track p = {%f, %f, %f} GeV/c is not"
3010 " compatible with the momentum vector of the trigger"
3011 " record with p = {%f, %f, %f} GeV/c.",
3012 bi,
3013 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3014 mansoTrackBlocks[bi]->fPtr,
3015 mansoTrackBlocks[bi]->fSize,
3016 i, inblocki[i].fPx, inblocki[i].fPy, inblocki[i].fPz,
3017 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3018 );
3019 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3020 }
3021
3022 found = true;
3023 break;
3024 }
3025 }
3026 }
3027
3028 if (not found)
3029 {
3030 HLTError("Problem found with Manso track"
3031 " data block %d, fDataType = '%s', fPtr = %p and"
3032 " fSize = %u bytes."
3033 " Problem with Manso track %d in block: The trigger"
3034 " record identifier %d does not exist in any trigger"
3035 " record data block.",
3036 bi,
3037 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3038 mansoTrackBlocks[bi]->fPtr,
3039 mansoTrackBlocks[bi]->fSize,
3040 i, inblocki[i].fTrigRec
3041 );
3042 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3043 }
3044 }
3045
3046 // Check if all the hits in the Manso track structures exist.
3047 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3048 {
3049 AliHLTMUONParticleSign sign;
3050 bool hitset[4];
3051 AliHLTMUONUtils::UnpackMansoTrackFlags(inblocki[i].fFlags, sign, hitset);
3052
3053 for (AliHLTUInt32_t n = 0; n < 4; n++)
3054 {
3055 if (not hitset[n]) continue;
3056 bool found = false;
3057
3058 for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
3059 {
3060 AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3061 if (not inblockj.BufferSizeOk()) continue;
3062
3063 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3064 {
3065 if (inblocki[i].fHit[n] == inblockj[j])
3066 {
3067 found = true;
3068 break;
3069 }
3070 }
3071 }
3072
3073 if (not found)
3074 {
3075 HLTError("Problem found with Manso track"
3076 " data block %d, fDataType = '%s', fPtr = %p and"
3077 " fSize = %u bytes."
3078 " Problem with Manso track %d in block: The hit"
3079 " for chamber %d does not exist in any"
3080 " reconstructed hits data block.",
3081 bi,
3082 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3083 mansoTrackBlocks[bi]->fPtr,
3084 mansoTrackBlocks[bi]->fSize,
3085 i, n+6+1
3086 );
3087 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3088 }
3089 }
3090 }
3091
3092 // Check if all the Manso track structures are unique up to the ID and
3093 // have unique identifiers.
3094 for (AliHLTUInt32_t bj = bi+1; bj < mansoTrackBlocksCount; bj++)
3095 {
3096 AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3097 if (not inblockj.BufferSizeOk()) continue;
3098
3099 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3100 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3101 {
3102 if (inblocki[i].fId == inblockj[j].fId)
3103 {
3104 HLTError("Problem found with Manso track"
3105 " data block %d, fDataType = '%s', fPtr = %p and"
3106 " fSize = %u bytes, and Manso track data block %d,"
3107 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3108 " Problem: The Manso track %d in block %d and entry"
3109 " %d in block %d have the same identifier, but they"
3110 " should be unique.",
3111 bi,
3112 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3113 mansoTrackBlocks[bi]->fPtr,
3114 mansoTrackBlocks[bi]->fSize,
3115 bj,
3116 DataType2Text(mansoTrackBlocks[bj]->fDataType).c_str(),
3117 mansoTrackBlocks[bj]->fPtr,
3118 mansoTrackBlocks[bj]->fSize,
3119 bi, i,
3120 bj, j
3121 );
3122 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3123 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bj]);
3124 }
3125
3126 AliHLTMUONMansoTrackStruct a = inblocki[i];
3127 AliHLTMUONMansoTrackStruct b = inblockj[j];
3128 a.fId = b.fId = -1;
3129 if (a == b)
3130 {
3131 HLTError("Problem found with Manso track"
3132 " data block %d, fDataType = '%s', fPtr = %p and"
3133 " fSize = %u bytes, and Manso track data block %d,"
3134 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3135 " Problem: The Manso track %d in block %d and entry"
3136 " %d in block %d have the same data."
3137 " The data may have been duplicated.",
3138 bi,
3139 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3140 mansoTrackBlocks[bi]->fPtr,
3141 mansoTrackBlocks[bi]->fSize,
3142 bj,
3143 DataType2Text(mansoTrackBlocks[bj]->fDataType).c_str(),
3144 mansoTrackBlocks[bj]->fPtr,
3145 mansoTrackBlocks[bj]->fSize,
3146 bi, i,
3147 bj, j
3148 );
3149 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3150 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bj]);
3151 }
3152 }
3153 }
3154 }
3155
3156 for (AliHLTUInt32_t bi = 0; bi < mansoCandidateBlocksCount; bi++)
3157 {
3158 AliHLTMUONMansoCandidatesBlockReader inblocki(mansoCandidateBlocks[bi]->fPtr, mansoCandidateBlocks[bi]->fSize);
3159 if (not inblocki.BufferSizeOk()) continue;
3160
3161 // Check if all the trigger record IDs in the Manso track candidate structures exist.
3162 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3163 {
3164 bool found = false;
3165
3166 for (AliHLTUInt32_t bj = 0; bj < trigRecBlocksCount and not found; bj++)
3167 {
3168 AliHLTMUONTriggerRecordsBlockReader inblockj(trigRecBlocks[bj]->fPtr, trigRecBlocks[bj]->fSize);
3169 if (not inblockj.BufferSizeOk()) continue;
3170
3171 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3172 {
3173 if (inblocki[i].fTrack.fTrigRec == inblockj[j].fId)
3174 {
3175 // At this point we can check if the momentum
3176 // is compatible with the trigger record.
3177 if (not AreMomentaCompatible(
3178 inblocki[i].fTrack.fPx, inblocki[i].fTrack.fPy, inblocki[i].fTrack.fPz,
3179 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3180 )
3181 )
3182 {
3183 HLTWarning("Problem found with Manso track candidate"
3184 " data block %d, fDataType = '%s', fPtr = %p and"
3185 " fSize = %u bytes."
3186 " Problem with track candidate %d in block: The momentum"
3187 " vector of the candidate p = {%f, %f, %f} GeV/c is not"
3188 " compatible with the momentum vector of the trigger"
3189 " record with p = {%f, %f, %f} GeV/c.",
3190 bi,
3191 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3192 mansoTrackBlocks[bi]->fPtr,
3193 mansoTrackBlocks[bi]->fSize,
3194 i,
3195 inblocki[i].fTrack.fPx, inblocki[i].fTrack.fPy, inblocki[i].fTrack.fPz,
3196 inblockj[j].fPx, inblockj[j].fPy, inblockj[j].fPz
3197 );
3198 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3199 }
3200
3201 found = true;
3202 break;
3203 }
3204 }
3205 }
3206
3207 if (not found)
3208 {
3209 HLTError("Problem found with Manso track candidate"
3210 " data block %d, fDataType = '%s', fPtr = %p and"
3211 " fSize = %u bytes."
3212 " Problem with track candidate %d in block: The trigger"
3213 " record identifier %d does not exist in any trigger"
3214 " record data block.",
3215 bi,
3216 DataType2Text(mansoCandidateBlocks[bi]->fDataType).c_str(),
3217 mansoCandidateBlocks[bi]->fPtr,
3218 mansoCandidateBlocks[bi]->fSize,
3219 i, inblocki[i].fTrack.fTrigRec
3220 );
3221 MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bi]);
3222 }
3223 }
3224
3225 // Check if all the hits in the Manso track candidate structures exist.
3226 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3227 {
3228 AliHLTMUONParticleSign sign;
3229 bool hitset[4];
3230 AliHLTMUONUtils::UnpackMansoTrackFlags(inblocki[i].fTrack.fFlags, sign, hitset);
3231
3232 for (AliHLTUInt32_t n = 0; n < 4; n++)
3233 {
3234 if (not hitset[n]) continue;
3235 bool found = false;
3236
3237 for (AliHLTUInt32_t bj = 0; bj < hitBlocksCount and not found; bj++)
3238 {
3239 AliHLTMUONRecHitsBlockReader inblockj(hitBlocks[bj]->fPtr, hitBlocks[bj]->fSize);
3240 if (not inblockj.BufferSizeOk()) continue;
3241
3242 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3243 {
3244 if (inblocki[i].fTrack.fHit[n] == inblockj[j])
3245 {
3246 found = true;
3247 break;
3248 }
3249 }
3250 }
3251
3252 if (not found)
3253 {
3254 HLTError("Problem found with Manso track candidate"
3255 " data block %d, fDataType = '%s', fPtr = %p and"
3256 " fSize = %u bytes."
3257 " Problem with track candidate %d in block: The hit"
3258 " for chamber %d does not exist in any"
3259 " reconstructed hits data block.",
3260 bi,
3261 DataType2Text(mansoTrackBlocks[bi]->fDataType).c_str(),
3262 mansoTrackBlocks[bi]->fPtr,
3263 mansoTrackBlocks[bi]->fSize,
3264 i, n+6+1
3265 );
3266 MarkBlock(blocks, blockOk, blockCount, mansoTrackBlocks[bi]);
3267 }
3268 }
3269 }
3270
3271 // Check if all the Manso track candidate structures are unique up to the
3272 // track ID and have unique identifiers.
3273 for (AliHLTUInt32_t bj = bi+1; bj < mansoCandidateBlocksCount; bj++)
3274 {
3275 AliHLTMUONMansoCandidatesBlockReader inblockj(mansoCandidateBlocks[bj]->fPtr, mansoCandidateBlocks[bj]->fSize);
3276 if (not inblockj.BufferSizeOk()) continue;
3277
3278 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3279 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3280 {
3281 if (inblocki[i].fTrack.fId == inblockj[j].fTrack.fId)
3282 {
3283 HLTError("Problem found with Manso track candidate"
3284 " data block %d, fDataType = '%s', fPtr = %p and"
3285 " fSize = %u bytes, and Manso track candidate data block %d,"
3286 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3287 " Problem: The track candidate %d in block %d and entry"
3288 " %d in block %d have the same identifier, but they"
3289 " should be unique.",
3290 bi,
3291 DataType2Text(mansoCandidateBlocks[bi]->fDataType).c_str(),
3292 mansoCandidateBlocks[bi]->fPtr,
3293 mansoCandidateBlocks[bi]->fSize,
3294 bj,
3295 DataType2Text(mansoCandidateBlocks[bj]->fDataType).c_str(),
3296 mansoCandidateBlocks[bj]->fPtr,
3297 mansoCandidateBlocks[bj]->fSize,
3298 bi, i,
3299 bj, j
3300 );
3301 MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bi]);
3302 MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bj]);
3303 }
3304
3305 AliHLTMUONMansoCandidateStruct a = inblocki[i];
3306 AliHLTMUONMansoCandidateStruct b = inblockj[j];
3307 a.fTrack.fId = b.fTrack.fId = -1;
3308 if (a == b)
3309 {
3310 HLTError("Problem found with Manso track candidate"
3311 " data block %d, fDataType = '%s', fPtr = %p and"
3312 " fSize = %u bytes, and Manso track candidate data block %d,"
3313 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3314 " Problem: The track candidate %d in block %d and entry"
3315 " %d in block %d have the same data."
3316 " The data may have been duplicated.",
3317 bi,
3318 DataType2Text(mansoCandidateBlocks[bi]->fDataType).c_str(),
3319 mansoCandidateBlocks[bi]->fPtr,
3320 mansoCandidateBlocks[bi]->fSize,
3321 bj,
3322 DataType2Text(mansoCandidateBlocks[bj]->fDataType).c_str(),
3323 mansoCandidateBlocks[bj]->fPtr,
3324 mansoCandidateBlocks[bj]->fSize,
3325 bi, i,
3326 bj, j
3327 );
3328 MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bi]);
3329 MarkBlock(blocks, blockOk, blockCount, mansoCandidateBlocks[bj]);
3330 }
3331 }
3332 }
3333 }
3334
3335 for (AliHLTUInt32_t bi = 0; bi < singleDecisionBlocksCount; bi++)
3336 {
3337 AliHLTMUONSinglesDecisionBlockReader inblocki(singleDecisionBlocks[bi]->fPtr, singleDecisionBlocks[bi]->fSize);
3338 if (not inblocki.BufferSizeOk()) continue;
3339
3340 // Check that the scalars are within reasonable limits.
3341 const AliHLTMUONSinglesDecisionBlockStruct& hdr = inblocki.BlockHeader();
3342 const AliHLTComponentBlockData* block = singleDecisionBlocks[bi];
3343 if (IsScalarTooLarge(block, bi, "single track", "fNlowPt", hdr.fNlowPt, totalTrackCount) or
3344 IsScalarTooLarge(block, bi, "single track", "fNhighPt", hdr.fNhighPt, totalTrackCount) or
3345 IsScalarALargerThanB(block, bi, "single track", "fNlowPt", hdr.fNlowPt, "fNhighPt", hdr.fNhighPt)
3346 )
3347 {
3348 MarkBlock(blocks, blockOk, blockCount, block);
3349 }
3350
3351 // Check if all the Manso track IDs in the trigger decision structures exist.
3352 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3353 {
3354 bool found = false;
3355
3356 for (AliHLTUInt32_t bj = 0; bj < mansoTrackBlocksCount and not found; bj++)
3357 {
3358 AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3359 if (not inblockj.BufferSizeOk()) continue;
3360
3361 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3362 {
3363 if (inblocki[i].fTrackId == inblockj[j].fId)
3364 {
3365 found = true;
3366 break;
3367 }
3368 }
3369 }
3370
3371 if (not found)
3372 {
3373 HLTError("Problem found with single track trigger decision"
3374 " data block %d, fDataType = '%s', fPtr = %p and"
3375 " fSize = %u bytes."
3376 " Problem with decision %d in block: The track"
3377 " identifier %d does not exist in any Manso tracks"
3378 " data block.",
3379 bi,
3380 DataType2Text(singleDecisionBlocks[bi]->fDataType).c_str(),
3381 singleDecisionBlocks[bi]->fPtr,
3382 singleDecisionBlocks[bi]->fSize,
3383 i, inblocki[i].fTrackId
3384 );
3385 MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bi]);
3386 }
3387 }
3388
3389 // Check if all the trigger decision structures are unique up to the ID and
3390 // have unique Manso track identifiers.
3391 for (AliHLTUInt32_t bj = bi+1; bj < singleDecisionBlocksCount; bj++)
3392 {
3393 AliHLTMUONSinglesDecisionBlockReader inblockj(singleDecisionBlocks[bj]->fPtr, singleDecisionBlocks[bj]->fSize);
3394 if (not inblockj.BufferSizeOk()) continue;
3395
3396 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3397 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3398 {
3399 if (inblocki[i].fTrackId == inblockj[j].fTrackId)
3400 {
3401 HLTError("Problem found with single track trigger decision"
3402 " data block %d, fDataType = '%s', fPtr = %p and"
3403 " fSize = %u bytes, and single track trigger decision"
3404 " data block %d,"
3405 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3406 " Problem: The trigger decision %d in block %d and entry"
3407 " %d in block %d have the same Manso track identifier,"
3408 " but they should be unique.",
3409 bi,
3410 DataType2Text(singleDecisionBlocks[bi]->fDataType).c_str(),
3411 singleDecisionBlocks[bi]->fPtr,
3412 singleDecisionBlocks[bi]->fSize,
3413 bj,
3414 DataType2Text(singleDecisionBlocks[bj]->fDataType).c_str(),
3415 singleDecisionBlocks[bj]->fPtr,
3416 singleDecisionBlocks[bj]->fSize,
3417 bi, i,
3418 bj, j
3419 );
3420 MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bi]);
3421 MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bj]);
3422 }
3423
3424 AliHLTMUONTrackDecisionStruct a = inblocki[i];
3425 AliHLTMUONTrackDecisionStruct b = inblockj[j];
3426 a.fTrackId = b.fTrackId = -1;
3427 if (a == b)
3428 {
3429 HLTError("Problem found with single track trigger decision"
3430 " data block %d, fDataType = '%s', fPtr = %p and"
3431 " fSize = %u bytes, and single track trigger decision"
3432 " data block %d,"
3433 " fDataType = '%s', fPtr = %p and fSize = %u bytes."
3434 " Problem: The trigger decision %d in block %d and entry"
3435 " %d in block %d have the same data."
3436 " The data may have been duplicated.",
3437 bi,
3438 DataType2Text(singleDecisionBlocks[bi]->fDataType).c_str(),
3439 singleDecisionBlocks[bi]->fPtr,
3440 singleDecisionBlocks[bi]->fSize,
3441 bj,
3442 DataType2Text(singleDecisionBlocks[bj]->fDataType).c_str(),
3443 singleDecisionBlocks[bj]->fPtr,
3444 singleDecisionBlocks[bj]->fSize,
3445 bi, i,
3446 bj, j
3447 );
3448 MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bi]);
3449 MarkBlock(blocks, blockOk, blockCount, singleDecisionBlocks[bj]);
3450 }
3451 }
3452 }
3453 }
3454
3455 for (AliHLTUInt32_t bi = 0; bi < pairDecisionBlocksCount; bi++)
3456 {
3457 AliHLTMUONPairsDecisionBlockReader inblocki(pairDecisionBlocks[bi]->fPtr, pairDecisionBlocks[bi]->fSize);
3458 if (not inblocki.BufferSizeOk()) continue;
3459
3460 AliHLTUInt32_t maxPairs = totalTrackCount * (totalTrackCount-1) / 2;
3461 const AliHLTMUONPairsDecisionBlockStruct& hdr = inblocki.BlockHeader();
3462 const AliHLTComponentBlockData* block = pairDecisionBlocks[bi];
3463 if (IsScalarTooLarge(block, bi, "track pair", "fNunlikeAnyPt", hdr.fNunlikeAnyPt, maxPairs) or
3464 IsScalarTooLarge(block, bi, "track pair", "fNunlikeLowPt", hdr.fNunlikeLowPt, maxPairs) or
3465 IsScalarTooLarge(block, bi, "track pair", "fNunlikeHighPt", hdr.fNunlikeHighPt, maxPairs) or
3466 IsScalarTooLarge(block, bi, "track pair", "fNlikeAnyPt", hdr.fNlikeAnyPt, maxPairs) or
3467 IsScalarTooLarge(block, bi, "track pair", "fNlikeLowPt", hdr.fNlikeLowPt, maxPairs) or
3468 IsScalarTooLarge(block, bi, "track pair", "fNlikeHighPt", hdr.fNlikeHighPt, maxPairs) or
3469 IsScalarTooLarge(block, bi, "track pair", "fNmassAny", hdr.fNmassAny, maxPairs) or
3470 IsScalarTooLarge(block, bi, "track pair", "fNmassLow", hdr.fNmassLow, maxPairs) or
3471 IsScalarTooLarge(block, bi, "track pair", "fNmassHigh", hdr.fNmassHigh, maxPairs) or
3472 IsScalarALargerThanB(block, bi, "track pair", "fNunlikeLowPt", hdr.fNunlikeLowPt, "fNunlikeHighPt", hdr.fNunlikeHighPt) or
3473 IsScalarALargerThanB(block, bi, "track pair", "fNunlikeAnyPt", hdr.fNunlikeAnyPt, "fNunlikeLowPt", hdr.fNunlikeLowPt) or
3474 IsScalarALargerThanB(block, bi, "track pair", "fNlikeLowPt", hdr.fNlikeLowPt, "fNlikeHighPt", hdr.fNlikeHighPt) or
3475 IsScalarALargerThanB(block, bi, "track pair", "fNlikeAnyPt", hdr.fNlikeAnyPt, "fNlikeLowPt", hdr.fNlikeLowPt) or
3476 IsScalarALargerThanB(block, bi, "track pair", "fNmassLow", hdr.fNmassLow, "fNmassHigh", hdr.fNmassHigh) or
3477 IsScalarALargerThanB(block, bi, "track pair", "fNmassAny", hdr.fNmassAny, "fNmassLow", hdr.fNmassLow)
3478 )
3479 {
3480 MarkBlock(blocks, blockOk, blockCount, block);
3481 }
3482
3483 // Check if all the Manso track IDs in the trigger decision structures exist.
3484 for (AliHLTUInt32_t i = 0; i < inblocki.Nentries(); i++)
3485 {
3486 bool found = false;
3487
3488 for (AliHLTUInt32_t bj = 0; bj < mansoTrackBlocksCount and not found; bj++)
3489 {
3490 AliHLTMUONMansoTracksBlockReader inblockj(mansoTrackBlocks[bj]->fPtr, mansoTrackBlocks[bj]->fSize);
3491 if (not inblockj.BufferSizeOk()) continue;
3492
3493 for (AliHLTUInt32_t j = 0; j < inblockj.Nentries(); j++)
3494 {
3495 if (inblocki[i].fTrackAId