]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/AliHLTMUONUtils.cxx
Adding dictionary generation for AliHLTMUONConstants and AliHLTMUONUtils.
[u/mrichter/AliRoot.git] / HLT / MUON / AliHLTMUONUtils.cxx
CommitLineData
26a4668d 1/**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/* $Id$ */
17
6253e09b 18///
19/// @file AliHLTMUONUtils.cxx
20/// @author Artur Szostak <artursz@iafrica.com>
dba14d7d 21/// @date 17 May 2007
6253e09b 22/// @brief Implementation of AliHLTMUONUtils utility routines.
23///
26a4668d 24
25#include "AliHLTMUONUtils.h"
b727f838 26#include "AliHLTMUONConstants.h"
c8ec7c7e 27#include "AliHLTMUONTriggerRecordsBlockStruct.h"
28#include "AliHLTMUONTrigRecsDebugBlockStruct.h"
c8ec7c7e 29#include "AliHLTMUONRecHitsBlockStruct.h"
30#include "AliHLTMUONClustersBlockStruct.h"
31#include "AliHLTMUONChannelsBlockStruct.h"
90a74d7a 32#include "AliHLTMUONMansoTracksBlockStruct.h"
33#include "AliHLTMUONMansoCandidatesBlockStruct.h"
34#include "AliHLTMUONSinglesDecisionBlockStruct.h"
b12fe461 35#include "AliHLTMUONPairsDecisionBlockStruct.h"
dba14d7d 36#include "AliMUONTrackerDDLDecoderEventHandler.h"
f68b4e0e 37#include <cstring>
dba14d7d 38#include <cmath>
90a74d7a 39#include <cassert>
26a4668d 40
33b1e2f2 41ClassImp(AliHLTMUONUtils);
42
26a4668d 43
b727f838 44AliHLTUInt32_t AliHLTMUONUtils::PackTriggerRecordFlags(
e6357f88 45 AliHLTMUONParticleSign sign, const bool hitset[4]
b727f838 46 )
26a4668d 47{
6253e09b 48 ///
49 /// This packs the given parameters into the bits of a word appropriate
50 /// for AliHLTMUONTriggerRecordStruct::fFlags.
51 /// @param sign The particle sign.
52 /// @param hitset Flags to indicate if the corresponding fHits[i] elements
53 /// was set/filled.
54 /// @return Returns the 32 bit packed word.
55 ///
56
b727f838 57 AliHLTUInt32_t flags;
58 switch (sign)
59 {
60 case kSignMinus: flags = 0x80000000; break;
61 case kSignPlus: flags = 0x40000000; break;
62 default: flags = 0x00000000; break;
63 }
26a4668d 64
b727f838 65 return flags | (hitset[0] ? 0x1 : 0) | (hitset[1] ? 0x2 : 0)
66 | (hitset[2] ? 0x4 : 0) | (hitset[3] ? 0x8 : 0);
67}
68
69
70void AliHLTMUONUtils::UnpackTriggerRecordFlags(
90a74d7a 71 AliHLTUInt32_t flags, AliHLTMUONParticleSign& sign, bool hitset[4]
b727f838 72 )
73{
6253e09b 74 ///
75 /// This unpacks the AliHLTMUONTriggerRecordStruct::fFlags bits into
76 /// its component fields.
77 /// @param flags The flags from an AliHLTMUONTriggerRecordStruct structure.
78 /// @param sign Sets this to the particle sign.
79 /// @param hitset Sets the array elements to indicate if the corresponding
80 /// fHits[i] element was set/filled.
81 ///
82
b727f838 83 AliHLTUInt32_t signbits = flags & 0xC0000000;
84 switch (signbits)
85 {
86 case 0x80000000: sign = kSignMinus; break;
87 case 0x40000000: sign = kSignPlus; break;
88 default: sign = kSignUnknown; break;
89 }
e6357f88 90 hitset[0] = (flags & 0x1) == 0x1;
91 hitset[1] = (flags & 0x2) == 0x2;
92 hitset[2] = (flags & 0x4) == 0x4;
93 hitset[3] = (flags & 0x8) == 0x8;
b727f838 94}
95
96
a090ff22 97AliHLTUInt32_t AliHLTMUONUtils::PackRecHitFlags(
98 AliHLTUInt8_t chamber, AliHLTUInt16_t detElemId
99 )
100{
101 /// This packs the given parameters into the bits of a word appropriate
102 /// for AliHLTMUONRecHitStruct::fFlags.
103 /// @param chamber The chamber number in the range [0..13].
104 /// @param detElemId Detector element ID number.
105 /// @return Returns the 32 bit packed word.
106
107 return ((chamber & 0xF) << 12) | (detElemId & 0xFFF);
108}
109
110
111void AliHLTMUONUtils::UnpackRecHitFlags(
112 AliHLTUInt32_t flags, // [in]
113 AliHLTUInt8_t& chamber, // [out]
114 AliHLTUInt16_t& detElemId // [out]
115 )
116{
117 /// This unpacks the AliHLTMUONRecHitStruct::fFlags bits into
118 /// its component fields.
119 /// [in] @param flags The flags from an AliHLTMUONRecHitStruct structure.
120 /// [out] @param chamber Sets the chamber number in the range [0..13].
121 /// [out] @param detElemId Sets the detector element ID number.
122
123 chamber = (flags >> 12) & 0xF;
124 detElemId = flags & 0xFFF;
125}
126
127
90a74d7a 128AliHLTUInt32_t AliHLTMUONUtils::PackTrackDecisionBits(bool highPt, bool lowPt)
129{
6253e09b 130 ///
131 /// This packs the given parameters into the bits of a word appropriate
132 /// for AliHLTMUONTrackDecisionStruct::fTriggerBits.
133 /// @param highPt Has the track passed the high pt cut.
134 /// @param lowPt Has the track passed the low pt cut.
135 /// @return Returns the 32 bit packed word.
136 ///
137
90a74d7a 138 return (highPt ? 0x2 : 0) | (lowPt ? 0x1 : 0);
139}
140
141
142void AliHLTMUONUtils::UnpackTrackDecisionBits(
143 AliHLTUInt32_t bits, bool& highPt, bool& lowPt
144 )
145{
6253e09b 146 ///
147 /// This unpacks the AliHLTMUONTrackDecisionStruct::fTriggerBits bits into
148 /// its component fields.
149 /// @param bits The trigger bits from an AliHLTMUONTrackDecisionStruct
150 /// structure.
151 /// @param highPt Sets this to the value of the high pt cut bit.
152 /// @param lowPt Sets this to the value of the low pt cut bit.
153 ///
154
fc310e19 155 lowPt = (bits & 0x1) == 0x1;
156 highPt = (bits & 0x2) == 0x2;
90a74d7a 157}
158
159
160AliHLTUInt32_t AliHLTMUONUtils::PackPairDecisionBits(
161 bool highMass, bool lowMass, bool unlike,
162 AliHLTUInt8_t highPtCount, AliHLTUInt8_t lowPtCount
163 )
164{
6253e09b 165 ///
166 /// This packs the given parameters into the bits of a word appropriate
167 /// for AliHLTMUONPairDecisionStruct::fTriggerBits.
168 ///
169 /// @param highMass Has the track pair passed the high invariant mass cut.
170 /// @param lowMass Has the track pair passed the low invariant mass cut.
171 /// @param unlike Does the track pair have unlike signs.
172 /// @param highPtCount The number of tracks that passed the high pt cut
173 /// in the pair.
174 /// @param lowPtCount The number of tracks that passed the low pt cut
175 /// in the pair.
176 /// @return Returns the 32 bit packed word.
177 ///
02f92a42 178 /// Note: Must have highPtCount <= 2, lowPtCount <= 2 and
179 /// unlike == true if highMass or lowMass is true.
6253e09b 180 ///
181
02f92a42 182 assert( lowPtCount <= 2 );
183 assert( highPtCount <= 2 );
90a74d7a 184 // highMass and lowMass must be false if unlike is false:
185 assert( not unlike ? (highMass == false and lowMass == false) : true );
186
187 return (highMass ? 0x40 : 0) | (lowMass ? 0x20 : 0) | (unlike ? 0x10 : 0)
188 | ((highPtCount & 0x3) << 2) | (lowPtCount & 0x3);
189}
190
191
192void AliHLTMUONUtils::UnpackPairDecisionBits(
193 AliHLTUInt32_t bits, bool& highMass, bool& lowMass, bool& unlike,
194 AliHLTUInt8_t& highPtCount, AliHLTUInt8_t& lowPtCount
195 )
196{
6253e09b 197 ///
198 /// This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
199 /// its component fields.
200 /// @param bits The trigger bits from an AliHLTMUONPairDecisionStruct
201 /// structure.
202 /// @param highMass Sets this to the value of the high invariant mass cut bit.
203 /// @param lowMass Sets this to the value of the low invariant mass cut bit.
204 /// @param unlike Sets this if the pair is unlike sign.
205 /// @param highPtCount Sets this to the high pt count bits.
206 /// @param lowPtCount Sets this to the low pt count bits.
207 ///
208
fc310e19 209 highMass = (bits & 0x40) == 0x40;
210 lowMass = (bits & 0x20) == 0x20;
211 unlike = (bits & 0x10) == 0x10;
90a74d7a 212 highPtCount = (bits & 0xC) >> 2;
213 lowPtCount = bits & 0x3;
214}
215
216
e6357f88 217AliHLTUInt32_t AliHLTMUONUtils::PackSpecBits(
218 const bool ddl[22]
219 )
220{
6253e09b 221 ///
222 /// This packs the given parameters into the 32bit Pub/Sub specification
223 /// word in the data block descriptor.
224 ///
225 /// @param ddl The list of DDLs forming part of the readout. ddl[0]
226 /// indicates DDL number 2560, ddl[1] is for DDL 2561 and so
227 /// on up to ddl[19]. ddl[20] and ddl[21] will be for the
228 /// trigger DDLs 2816 and 2817 respectively.
229 /// @return Returns the 32 bit packed specification word.
230 ///
231
e6357f88 232 // Pack the bits into the following format:
233 // bit: [ 31 - 22 ][ 21 ][ 20 ][ 19 - 0 ]
80606a9f 234 // field: [ reserved, set to zero ][ TRGDDL2817 ][ TRGDDL2816 ][ TRKDDLS ]
e6357f88 235 // Meaning of field acronyms:
236 // TRGDDL2816 - Trigger DDL number 2816.
237 // TRGDDL2817 - Trigger DDL number 2817.
238 // TRKDDLS - Tracking DDL flags where bit 0 will be for DDL number 2560,
239 // bit 1 for DDL no. 2561 etc. up to bit 19 which is for DDL 2579.
240 AliHLTUInt32_t bits = 0;
241 for (int i = 0; i < 22; i++)
242 bits |= (ddl[i] ? 0x1 : 0x0) << i;
243 return bits;
244}
245
246
247void AliHLTMUONUtils::UnpackSpecBits(
248 AliHLTUInt32_t bits, bool ddl[22]
249 )
250{
6253e09b 251 ///
252 /// This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
253 /// its component fields.
254 /// @param bits The Pub/Sub specification word from a data block descriptor.
255 /// @param ddl The output list of DDLs forming part of the readout. ddl[0]
256 /// indicates DDL number 2560, ddl[1] is for DDL 2561 and so
257 /// on up to ddl[19]. ddl[20] and ddl[21] will be for the
258 /// trigger DDLs 2816 and 2817 respectively.
259 ///
260
e6357f88 261 // Perform the inverse operation of PackSpecBits.
262 for (int i = 0; i < 22; i++)
263 ddl[i] = ((bits >> i) & 0x1) == 1;
264}
265
266
86b774d9 267AliHLTInt32_t AliHLTMUONUtils::DDLNumberToEquipId(AliHLTInt32_t ddlNo)
268{
269 ///
270 /// This method converts the DDL number for the muon spectrometer in the
271 /// range [0..21] to the equipment ID number.
272 /// @param ddlNo The DDL number in the range [0..21].
273 /// @return Returns the equipment ID number or -1 if ddlNo was invalid.
274 ///
275
276 if (0 <= ddlNo and ddlNo <= 19)
277 {
278 return 2560 + ddlNo;
279 }
280 else if (20 <= ddlNo and ddlNo <= 21)
281 {
282 return 2816 + (ddlNo - 20);
283 }
284 else
285 {
286 return -1;
287 }
288}
289
290
291AliHLTInt32_t AliHLTMUONUtils::EquipIdToDDLNumber(AliHLTInt32_t id)
292{
293 ///
294 /// This method converts the equipment ID number for a muon spectrometer
295 /// DDL to the DDL number in the range [0..21].
296 /// @param id The equipment ID of the DDL.
297 /// @return Returns the DDL number in the range [0..21] or -1 if the
298 /// equipment ID was invalid.
299 ///
300
301 if (2560 <= id and id <= 2560+19)
302 {
303 return id - 2560;
304 }
305 else if (2816 <= id and id <= 2817)
306 {
307 return id - 2816 + 20;
308 }
309 else
310 {
311 return -1;
312 }
313}
314
315
316AliHLTInt32_t AliHLTMUONUtils::SpecToEquipId(AliHLTUInt32_t spec)
317{
318 ///
319 /// This method converts a 32 bit data block specification for a MUON-HLT
320 /// data block into its corresponding DDL equipment ID number.
321 /// It is assumed that the specification is for a data block comming from
322 /// a single DDL source. If more than one DDL contributed to the data block
323 /// then -1 is returned.
324 /// @param spec The 32 bit specification for a data block.
325 /// @return Returns the equipment ID corresponding to the specification
326 /// or -1 if the specification was invalid.
327 ///
328
329 for (AliHLTInt32_t ddlNo = 0; ddlNo < 20; ddlNo++)
330 {
331 if (spec == AliHLTUInt32_t(0x1 << ddlNo))
332 return ddlNo + 2560;
333 }
334 for (AliHLTInt32_t ddlNo = 20; ddlNo < 22; ddlNo++)
335 {
336 if (spec == AliHLTUInt32_t(0x1 << ddlNo))
337 return ddlNo - 20 + 2816;
338 }
339 return -1;
340}
341
342
343AliHLTUInt32_t AliHLTMUONUtils::EquipIdToSpec(AliHLTInt32_t id)
344{
345 ///
346 /// This method converts a equipment ID number for a DDL into its corresponding
347 /// 32 bit data block specification for the MUON-HLT.
348 /// @param id The equipment ID number of the DDL.
349 /// @return Returns the 32 bit data block specification or 0x0 if the
350 /// equipment ID was invalid.
351 ///
352
353 if (2560 <= id and id <= 2560+19)
354 {
355 return 0x1 << (id - 2560);
356 }
357 else if (2816 <= id and id <= 2817)
358 {
359 return 0x1 << (id - 2816 + 20);
360 }
361 else
362 {
363 return 0x0;
364 }
365}
366
367
368AliHLTInt32_t AliHLTMUONUtils::SpecToDDLNumber(AliHLTUInt32_t spec)
369{
370 ///
371 /// This method converts a 32 bit data block specification for a MUON-HLT
372 /// data block into its corresponding DDL number in the range [0..21].
373 /// It is assumed that the specification is for a data block comming from
374 /// a single DDL source. If more than one DDL contributed to the data block
375 /// then -1 is returned.
376 /// @param spec The 32 bit specification for a data block.
377 /// @return Returns the corresponding DDL number for the specification
378 /// or -1 if the specification was invalid.
379 ///
380
381 for (AliHLTInt32_t ddlNo = 0; ddlNo < 22; ddlNo++)
382 {
383 if (spec == AliHLTUInt32_t(0x1 << ddlNo))
384 return ddlNo;
385 }
386 return -1;
387}
388
389
390AliHLTUInt32_t AliHLTMUONUtils::DDLNumberToSpec(AliHLTInt32_t ddlNo)
391{
392 ///
393 /// This method converts a DDL number in the range [0..21] into its
394 /// corresponding 32 bit data block specification for the MUON-HLT.
395 /// @param ddlNo The equipment ID number of the DDL.
396 /// @return Returns the 32 bit data block specification or 0x0 if the
397 /// DDL number was invalid (out of range).
398 ///
399
400 if (0 <= ddlNo and ddlNo <= 21)
401 {
402 return 0x1 << ddlNo;
403 }
404 else
405 {
406 return 0x0;
407 }
408}
409
410
f68b4e0e 411AliHLTMUONDataBlockType AliHLTMUONUtils::ParseCommandLineTypeString(const char* type)
412{
413 /// Parses the string containing the type name of a dHLT data block and
414 /// returns the corresponding AliHLTMUONDataBlockType value.
415 /// \param type The string containing the type name.
416 /// \returns The data block type or kUnknownDataBlock if the type name
417 /// is invalid.
418
419 if (strcmp(type, "trigrecs") == 0)
420 {
421 return kTriggerRecordsDataBlock;
422 }
423 else if (strcmp(type, "trigrecsdebug") == 0)
424 {
425 return kTrigRecsDebugDataBlock;
426 }
f68b4e0e 427 else if (strcmp(type, "rechits") == 0)
428 {
429 return kRecHitsDataBlock;
430 }
431 else if (strcmp(type,"channels") == 0)
432 {
433 return kChannelsDataBlock;
434 }
435 else if (strcmp(type,"clusters") == 0)
436 {
437 return kClustersDataBlock;
438 }
439 else if (strcmp(type, "mansotracks") == 0)
440 {
441 return kMansoTracksDataBlock;
442 }
443 else if (strcmp(type, "mansocandidates") == 0)
444 {
445 return kMansoCandidatesDataBlock;
446 }
447 else if (strcmp(type, "singlesdecision") == 0)
448 {
449 return kSinglesDecisionDataBlock;
450 }
451 else if (strcmp(type, "pairsdecision") == 0)
452 {
453 return kPairsDecisionDataBlock;
454 }
455
456 return kUnknownDataBlock;
457}
458
459
887a669c 460const char* AliHLTMUONUtils::DataBlockTypeToString(AliHLTMUONDataBlockType type)
461{
462 /// Converts a type ID to a type string compatible with
463 /// HLT data types.
464
465 static char str[kAliHLTComponentDataTypefIDsize+1];
466 AliHLTComponentDataType t;
467 switch (type)
468 {
469 case kTriggerRecordsDataBlock:
470 t = AliHLTMUONConstants::TriggerRecordsBlockDataType();
471 break;
472 case kTrigRecsDebugDataBlock:
473 t = AliHLTMUONConstants::TrigRecsDebugBlockDataType();
474 break;
887a669c 475 case kRecHitsDataBlock:
476 t = AliHLTMUONConstants::RecHitsBlockDataType();
477 break;
478 case kClustersDataBlock:
479 t = AliHLTMUONConstants::ClusterBlockDataType();
480 break;
481 case kChannelsDataBlock:
482 t = AliHLTMUONConstants::ChannelBlockDataType();
483 break;
484 case kMansoTracksDataBlock:
485 t = AliHLTMUONConstants::MansoTracksBlockDataType();
486 break;
487 case kMansoCandidatesDataBlock:
488 t = AliHLTMUONConstants::MansoCandidatesBlockDataType();
489 break;
490 case kSinglesDecisionDataBlock:
491 t = AliHLTMUONConstants::SinglesDecisionBlockDataType();
492 break;
493 case kPairsDecisionDataBlock:
494 t = AliHLTMUONConstants::PairsDecisionBlockDataType();
495 break;
496 default:
497 return "UNKNOWN";
498 }
499 memcpy(&str, &t.fID, kAliHLTComponentDataTypefIDsize);
500 // Must insert the NULL character to make this an ANSI C string.
501 str[kAliHLTComponentDataTypefIDsize] = '\0';
502 return &str[0];
503}
504
505
878cb83d 506const char* AliHLTMUONUtils::FailureReasonToString(WhyNotValid reason)
507{
508 /// This method converts the WhyNotValid enumeration to a string representation.
509
510 switch (reason)
511 {
512 case kNoReason: return "kNoReason";
513 case kHeaderContainsWrongType: return "kHeaderContainsWrongType";
514 case kHeaderContainsWrongRecordWidth: return "kHeaderContainsWrongRecordWidth";
dba14d7d 515 case kInvalidIdValue: return "kInvalidIdValue";
516 case kInvalidTriggerIdValue: return "kInvalidTriggerIdValue";
517 case kInvalidTrackIdValue: return "kInvalidTrackIdValue";
878cb83d 518 case kReservedBitsNotZero: return "kReservedBitsNotZero";
519 case kParticleSignBitsNotValid: return "kParticleSignBitsNotValid";
520 case kHitNotMarkedAsNil: return "kHitNotMarkedAsNil";
dba14d7d 521 case kInvalidDetElementNumber: return "kInvalidDetElementNumber";
a090ff22 522 case kInvalidChamberNumber: return "kInvalidChamberNumber";
dba14d7d 523 case kHitIsNil: return "kHitIsNil";
524 case kInvalidChannelCount: return "kInvalidChannelCount";
525 case kInvalidBusPatchId: return "kInvalidBusPatchId";
526 case kInvalidManuId: return "kInvalidManuId";
527 case kInvalidChannelAddress: return "kInvalidChannelAddress";
528 case kInvalidSignal: return "kInvalidSignal";
529 case kDataWordDifferent: return "kDataWordDifferent";
530 case kChiSquareInvalid: return "kChiSquareInvalid";
531 case kMomentumVectorNotZero: return "kMomentumVectorNotZero";
532 case kRoiRadiusInvalid: return "kRoiRadiusInvalid";
533 case kHitNotWithinRoi: return "kHitNotWithinRoi";
878cb83d 534 case kPtValueNotValid: return "kPtValueNotValid";
878cb83d 535 case kPairTrackIdsAreIdentical: return "kPairTrackIdsAreIdentical";
536 case kMassValueNotValid: return "kMassValueNotValid";
537 case kLowPtCountInvalid: return "kLowPtCountInvalid";
538 case kHighPtCountInvalid: return "kHighPtCountInvalid";
dba14d7d 539 case kFoundDuplicateIDs: return "kFoundDuplicateIDs";
540 case kFoundDuplicateHits: return "kFoundDuplicateHits";
541 case kFoundDuplicateTriggers: return "kFoundDuplicateTriggers";
878cb83d 542 default: return "INVALID";
543 }
544}
545
546
547const char* AliHLTMUONUtils::FailureReasonToMessage(WhyNotValid reason)
548{
549 /// This method returns a string containing a user readable message explaining
550 /// the reason for failure described by the WhyNotValid enumeration.
551
552 switch (reason)
553 {
554 case kNoReason:
555 return "There was no problem with the data block.";
556 case kHeaderContainsWrongType:
dba14d7d 557 return "The common data header contains an incorrect type"
558 " identifier.";
878cb83d 559 case kHeaderContainsWrongRecordWidth:
dba14d7d 560 return "The common data header contains an incorrect data"
561 " record width.";
562 case kInvalidIdValue:
563 return "The structure identifier does not have a valid value.";
564 case kInvalidTriggerIdValue:
565 return "The trigger structure identifier does not have a valid"
566 " value.";
567 case kInvalidTrackIdValue:
568 return "The track structure identifier does not have a valid"
569 " value.";
878cb83d 570 case kReservedBitsNotZero:
571 return "Reserved bits have not been set to zero.";
572 case kParticleSignBitsNotValid:
573 return "The particle sign bits are not a valid value.";
574 case kHitNotMarkedAsNil:
575 return "A hit was marked as not found, but the corresponding hit"
576 " structure was not set to nil.";
dba14d7d 577 case kInvalidDetElementNumber:
578 return "An invalid detector element ID was found.";
a090ff22 579 case kInvalidChamberNumber:
580 return "An invalid chamber number was found.";
dba14d7d 581 case kHitIsNil:
582 return "The hit cannot be set to a nil value.";
583 case kInvalidChannelCount:
584 return "The number of channels indicated is zero or outside"
585 " the valid range.";
586 case kInvalidBusPatchId:
587 return "The bus patch identifier is outside the valid range.";
588 case kInvalidManuId:
589 return "The MANU identifier is outside the valid range.";
590 case kInvalidChannelAddress:
591 return "The MANU channel address is outside the valid range.";
592 case kInvalidSignal:
593 return "The ADC signal value is outside the valid range.";
594 case kDataWordDifferent:
595 return "The raw data word is different from the unpacked values.";
596 case kChiSquareInvalid:
597 return "The chi squared value must be a positive value or -1"
598 " indicating a fitting error.";
599 case kMomentumVectorNotZero:
600 return "The chi sqaured value is set to -1 indicating momentum"
601 " was not fitted, but the momentum vector was not zero.";
602 case kRoiRadiusInvalid:
603 return "The region of interest radius is invalid.";
604 case kHitNotWithinRoi:
605 return "A tracks hit is not within the corresponding region"
606 " of interest.";
878cb83d 607 case kPtValueNotValid:
dba14d7d 608 return "The pT value is not positive, nor -1 indicating an"
609 " invalid value.";
878cb83d 610 case kPairTrackIdsAreIdentical:
611 return "The track identifiers of the track pair are identical.";
612 case kMassValueNotValid:
dba14d7d 613 return "The invariant mass value is not positive, nor -1"
614 " indicating an invalid value.";
878cb83d 615 case kLowPtCountInvalid:
dba14d7d 616 return "The low pT trigger count is greater than 2,"
617 " which is invalid.";
878cb83d 618 case kHighPtCountInvalid:
dba14d7d 619 return "The high pT trigger count is greater than 2,"
620 " which is invalid.";
621 case kFoundDuplicateIDs:
622 return "Found duplicate data record identifiers, but they"
623 " should all be unique.";
624 case kFoundDuplicateHits:
625 return "Found duplicate hit structures, but they should all"
626 " be unique.";
627 case kFoundDuplicateTriggers:
628 return "Found duplicate trigger decisions.";
878cb83d 629 default:
630 return "UNKNOWN REASON CODE";
631 }
632}
633
634
dba14d7d 635bool AliHLTMUONUtils::RecordNumberWasSet(WhyNotValid reason)
636{
637 /// Returns true if the \em recordNum in the corresponding IntegrityOk method
638 /// would have been set, if it returned false and a reason was set.
639 /// This helper method makes it easy to test if the \em recordNum parameter
640 /// is filled with a valid value or not.
641 /// \param reason The reason code as returned by the IntegrityOk method.
642 /// \returns true if the \em recordNum parameter was set for the given
643 /// reason code.
644
645 switch (reason)
646 {
647 case kInvalidIdValue:
648 case kInvalidTriggerIdValue:
649 case kInvalidTrackIdValue:
650 case kReservedBitsNotZero:
651 case kParticleSignBitsNotValid:
652 case kHitNotMarkedAsNil:
653 case kInvalidDetElementNumber:
a090ff22 654 case kInvalidChamberNumber:
dba14d7d 655 case kHitIsNil:
656 case kInvalidChannelCount:
657 case kInvalidBusPatchId:
658 case kInvalidManuId:
659 case kInvalidChannelAddress:
660 case kInvalidSignal:
661 case kDataWordDifferent:
662 case kChiSquareInvalid:
663 case kPtValueNotValid:
664 case kPairTrackIdsAreIdentical:
665 case kMassValueNotValid:
666 case kLowPtCountInvalid:
667 case kHighPtCountInvalid:
668 return true;
669 default: return false;
670 }
671}
672
673
698c9498 674bool AliHLTMUONUtils::HeaderOk(
675 const AliHLTMUONTriggerRecordsBlockStruct& block,
dba14d7d 676 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
698c9498 677 )
b727f838 678{
878cb83d 679 /// Method used to check if the header information corresponds to the
680 /// supposed type of the raw dHLT data block.
681 /// [in] \param block The data block to check.
dba14d7d 682 /// [out] \param reason If this is not NULL, then it is assumed to point
683 /// to an array of at least 'reasonCount' number of elements. It will
684 /// be filled with the reason codes describing why the header is not
685 /// valid.
686 /// [in/out] \param reasonCount This should initially specify the size of
687 /// the array pointed to by 'reason'. It will be filled with the number
688 /// of items actually filled into the reason array upon exit from this
689 /// method.
878cb83d 690 /// \returns true if there is no problem with the header and false otherwise.
dba14d7d 691
692 AliHLTUInt32_t maxCount = reasonCount;
693 reasonCount = 0;
694 bool result = true;
695
b727f838 696 // The block must have the correct type.
698c9498 697 if (block.fHeader.fType != kTriggerRecordsDataBlock)
698 {
dba14d7d 699 if (reason != NULL and reasonCount < maxCount)
700 {
701 reason[reasonCount] = kHeaderContainsWrongType;
702 reasonCount++;
703 }
704 result = false;
698c9498 705 }
706
90a74d7a 707 // The block's record width must be the correct size.
b727f838 708 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTriggerRecordStruct))
698c9498 709 {
dba14d7d 710 if (reason != NULL and reasonCount < maxCount)
711 {
712 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
713 reasonCount++;
714 }
715 result = false;
698c9498 716 }
717
dba14d7d 718 return result;
b727f838 719}
26a4668d 720
90a74d7a 721
878cb83d 722bool AliHLTMUONUtils::HeaderOk(
723 const AliHLTMUONTrigRecsDebugBlockStruct& block,
dba14d7d 724 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 725 )
c8ec7c7e 726{
878cb83d 727 /// Method used to check if the header information corresponds to the
728 /// supposed type of the raw dHLT data block.
729 /// [in] \param block The data block to check.
dba14d7d 730 /// [out] \param reason If this is not NULL, then it is assumed to point
731 /// to an array of at least 'reasonCount' number of elements. It will
732 /// be filled with the reason codes describing why the header is not
733 /// valid.
734 /// [in/out] \param reasonCount This should initially specify the size of
735 /// the array pointed to by 'reason'. It will be filled with the number
736 /// of items actually filled into the reason array upon exit from this
737 /// method.
878cb83d 738 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 739
dba14d7d 740 AliHLTUInt32_t maxCount = reasonCount;
741 reasonCount = 0;
742 bool result = true;
743
c8ec7c7e 744 // The block must have the correct type.
878cb83d 745 if (block.fHeader.fType != kTrigRecsDebugDataBlock)
746 {
dba14d7d 747 if (reason != NULL and reasonCount < maxCount)
748 {
749 reason[reasonCount] = kHeaderContainsWrongType;
750 reasonCount++;
751 }
752 result = false;
878cb83d 753 }
754
90a74d7a 755 // The block's record width must be the correct size.
c8ec7c7e 756 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrigRecInfoStruct))
878cb83d 757 {
dba14d7d 758 if (reason != NULL and reasonCount < maxCount)
759 {
760 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
761 reasonCount++;
762 }
763 result = false;
878cb83d 764 }
765
dba14d7d 766 return result;
c8ec7c7e 767}
768
90a74d7a 769
878cb83d 770bool AliHLTMUONUtils::HeaderOk(
771 const AliHLTMUONRecHitsBlockStruct& block,
dba14d7d 772 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 773 )
b727f838 774{
878cb83d 775 /// Method used to check if the header information corresponds to the
776 /// supposed type of the raw dHLT data block.
777 /// [in] \param block The data block to check.
dba14d7d 778 /// [out] \param reason If this is not NULL, then it is assumed to point
779 /// to an array of at least 'reasonCount' number of elements. It will
780 /// be filled with the reason codes describing why the header is not
781 /// valid.
782 /// [in/out] \param reasonCount This should initially specify the size of
783 /// the array pointed to by 'reason'. It will be filled with the number
784 /// of items actually filled into the reason array upon exit from this
785 /// method.
878cb83d 786 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 787
dba14d7d 788 AliHLTUInt32_t maxCount = reasonCount;
789 reasonCount = 0;
790 bool result = true;
791
b727f838 792 // The block must have the correct type.
878cb83d 793 if (block.fHeader.fType != kRecHitsDataBlock)
794 {
dba14d7d 795 if (reason != NULL and reasonCount < maxCount)
796 {
797 reason[reasonCount] = kHeaderContainsWrongType;
798 reasonCount++;
799 }
800 result = false;
878cb83d 801 }
802
90a74d7a 803 // The block's record width must be the correct size.
b727f838 804 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONRecHitStruct))
878cb83d 805 {
dba14d7d 806 if (reason != NULL and reasonCount < maxCount)
807 {
808 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
809 reasonCount++;
810 }
811 result = false;
878cb83d 812 }
813
dba14d7d 814 return result;
b727f838 815}
26a4668d 816
90a74d7a 817
878cb83d 818bool AliHLTMUONUtils::HeaderOk(
819 const AliHLTMUONClustersBlockStruct& block,
dba14d7d 820 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 821 )
b727f838 822{
878cb83d 823 /// Method used to check if the header information corresponds to the
824 /// supposed type of the raw dHLT data block.
825 /// [in] \param block The data block to check.
dba14d7d 826 /// [out] \param reason If this is not NULL, then it is assumed to point
827 /// to an array of at least 'reasonCount' number of elements. It will
828 /// be filled with the reason codes describing why the header is not
829 /// valid.
830 /// [in/out] \param reasonCount This should initially specify the size of
831 /// the array pointed to by 'reason'. It will be filled with the number
832 /// of items actually filled into the reason array upon exit from this
833 /// method.
878cb83d 834 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 835
dba14d7d 836 AliHLTUInt32_t maxCount = reasonCount;
837 reasonCount = 0;
838 bool result = true;
839
b727f838 840 // The block must have the correct type.
878cb83d 841 if (block.fHeader.fType != kClustersDataBlock)
842 {
dba14d7d 843 if (reason != NULL and reasonCount < maxCount)
844 {
845 reason[reasonCount] = kHeaderContainsWrongType;
846 reasonCount++;
847 }
848 result = false;
878cb83d 849 }
850
90a74d7a 851 // The block's record width must be the correct size.
b727f838 852 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONClusterStruct))
878cb83d 853 {
dba14d7d 854 if (reason != NULL and reasonCount < maxCount)
855 {
856 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
857 reasonCount++;
858 }
859 result = false;
878cb83d 860 }
861
dba14d7d 862 return result;
b727f838 863}
26a4668d 864
90a74d7a 865
878cb83d 866bool AliHLTMUONUtils::HeaderOk(
867 const AliHLTMUONChannelsBlockStruct& block,
dba14d7d 868 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 869 )
b727f838 870{
878cb83d 871 /// Method used to check if the header information corresponds to the
872 /// supposed type of the raw dHLT data block.
873 /// [in] \param block The data block to check.
dba14d7d 874 /// [out] \param reason If this is not NULL, then it is assumed to point
875 /// to an array of at least 'reasonCount' number of elements. It will
876 /// be filled with the reason codes describing why the header is not
877 /// valid.
878 /// [in/out] \param reasonCount This should initially specify the size of
879 /// the array pointed to by 'reason'. It will be filled with the number
880 /// of items actually filled into the reason array upon exit from this
881 /// method.
878cb83d 882 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 883
dba14d7d 884 AliHLTUInt32_t maxCount = reasonCount;
885 reasonCount = 0;
886 bool result = true;
887
b727f838 888 // The block must have the correct type.
878cb83d 889 if (block.fHeader.fType != kChannelsDataBlock)
890 {
dba14d7d 891 if (reason != NULL and reasonCount < maxCount)
892 {
893 reason[reasonCount] = kHeaderContainsWrongType;
894 reasonCount++;
895 }
896 result = false;
878cb83d 897 }
898
90a74d7a 899 // The block's record width must be the correct size.
b727f838 900 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONChannelStruct))
878cb83d 901 {
dba14d7d 902 if (reason != NULL and reasonCount < maxCount)
903 {
904 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
905 reasonCount++;
906 }
907 result = false;
878cb83d 908 }
909
dba14d7d 910 return result;
b727f838 911}
912
913
878cb83d 914bool AliHLTMUONUtils::HeaderOk(
915 const AliHLTMUONMansoTracksBlockStruct& block,
dba14d7d 916 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 917 )
90a74d7a 918{
878cb83d 919 /// Method used to check if the header information corresponds to the
920 /// supposed type of the raw dHLT data block.
921 /// [in] \param block The data block to check.
dba14d7d 922 /// [out] \param reason If this is not NULL, then it is assumed to point
923 /// to an array of at least 'reasonCount' number of elements. It will
924 /// be filled with the reason codes describing why the header is not
925 /// valid.
926 /// [in/out] \param reasonCount This should initially specify the size of
927 /// the array pointed to by 'reason'. It will be filled with the number
928 /// of items actually filled into the reason array upon exit from this
929 /// method.
878cb83d 930 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 931
dba14d7d 932 AliHLTUInt32_t maxCount = reasonCount;
933 reasonCount = 0;
934 bool result = true;
935
90a74d7a 936 // The block must have the correct type.
878cb83d 937 if (block.fHeader.fType != kMansoTracksDataBlock)
938 {
dba14d7d 939 if (reason != NULL and reasonCount < maxCount)
940 {
941 reason[reasonCount] = kHeaderContainsWrongType;
942 reasonCount++;
943 }
944 result = false;
878cb83d 945 }
946
90a74d7a 947 // The block's record width must be the correct size.
948 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONMansoTrackStruct))
878cb83d 949 {
dba14d7d 950 if (reason != NULL and reasonCount < maxCount)
951 {
952 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
953 reasonCount++;
954 }
955 result = false;
878cb83d 956 }
957
dba14d7d 958 return result;
90a74d7a 959}
960
961
878cb83d 962bool AliHLTMUONUtils::HeaderOk(
963 const AliHLTMUONMansoCandidatesBlockStruct& block,
dba14d7d 964 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 965 )
90a74d7a 966{
878cb83d 967 /// Method used to check if the header information corresponds to the
968 /// supposed type of the raw dHLT data block.
969 /// [in] \param block The data block to check.
dba14d7d 970 /// [out] \param reason If this is not NULL, then it is assumed to point
971 /// to an array of at least 'reasonCount' number of elements. It will
972 /// be filled with the reason codes describing why the header is not
973 /// valid.
974 /// [in/out] \param reasonCount This should initially specify the size of
975 /// the array pointed to by 'reason'. It will be filled with the number
976 /// of items actually filled into the reason array upon exit from this
977 /// method.
878cb83d 978 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 979
dba14d7d 980 AliHLTUInt32_t maxCount = reasonCount;
981 reasonCount = 0;
982 bool result = true;
983
90a74d7a 984 // The block must have the correct type.
878cb83d 985 if (block.fHeader.fType != kMansoCandidatesDataBlock)
986 {
dba14d7d 987 if (reason != NULL and reasonCount < maxCount)
988 {
989 reason[reasonCount] = kHeaderContainsWrongType;
990 reasonCount++;
991 }
992 result = false;
878cb83d 993 }
994
90a74d7a 995 // The block's record width must be the correct size.
996 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONMansoCandidateStruct))
878cb83d 997 {
dba14d7d 998 if (reason != NULL and reasonCount < maxCount)
999 {
1000 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1001 reasonCount++;
1002 }
1003 result = false;
878cb83d 1004 }
1005
dba14d7d 1006 return result;
90a74d7a 1007}
1008
1009
878cb83d 1010bool AliHLTMUONUtils::HeaderOk(
1011 const AliHLTMUONSinglesDecisionBlockStruct& block,
dba14d7d 1012 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 1013 )
90a74d7a 1014{
878cb83d 1015 /// Method used to check if the header information corresponds to the
1016 /// supposed type of the raw dHLT data block.
1017 /// [in] \param block The data block to check.
dba14d7d 1018 /// [out] \param reason If this is not NULL, then it is assumed to point
1019 /// to an array of at least 'reasonCount' number of elements. It will
1020 /// be filled with the reason codes describing why the header is not
1021 /// valid.
1022 /// [in/out] \param reasonCount This should initially specify the size of
1023 /// the array pointed to by 'reason'. It will be filled with the number
1024 /// of items actually filled into the reason array upon exit from this
1025 /// method.
878cb83d 1026 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 1027
dba14d7d 1028 AliHLTUInt32_t maxCount = reasonCount;
1029 reasonCount = 0;
1030 bool result = true;
1031
90a74d7a 1032 // The block must have the correct type.
878cb83d 1033 if (block.fHeader.fType != kSinglesDecisionDataBlock)
1034 {
dba14d7d 1035 if (reason != NULL and reasonCount < maxCount)
1036 {
1037 reason[reasonCount] = kHeaderContainsWrongType;
1038 reasonCount++;
1039 }
1040 result = false;
878cb83d 1041 }
1042
90a74d7a 1043 // The block's record width must be the correct size.
1044 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrackDecisionStruct))
878cb83d 1045 {
dba14d7d 1046 if (reason != NULL and reasonCount < maxCount)
1047 {
1048 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1049 reasonCount++;
1050 }
1051 result = false;
878cb83d 1052 }
1053
dba14d7d 1054 return result;
90a74d7a 1055}
1056
1057
878cb83d 1058bool AliHLTMUONUtils::HeaderOk(
1059 const AliHLTMUONPairsDecisionBlockStruct& block,
dba14d7d 1060 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 1061 )
90a74d7a 1062{
878cb83d 1063 /// Method used to check if the header information corresponds to the
1064 /// supposed type of the raw dHLT data block.
1065 /// [in] \param block The data block to check.
dba14d7d 1066 /// [out] \param reason If this is not NULL, then it is assumed to point
1067 /// to an array of at least 'reasonCount' number of elements. It will
1068 /// be filled with the reason codes describing why the header is not
1069 /// valid.
1070 /// [in/out] \param reasonCount This should initially specify the size of
1071 /// the array pointed to by 'reason'. It will be filled with the number
1072 /// of items actually filled into the reason array upon exit from this
1073 /// method.
878cb83d 1074 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 1075
dba14d7d 1076 AliHLTUInt32_t maxCount = reasonCount;
1077 reasonCount = 0;
1078 bool result = true;
1079
90a74d7a 1080 // The block must have the correct type.
878cb83d 1081 if (block.fHeader.fType != kPairsDecisionDataBlock)
1082 {
dba14d7d 1083 if (reason != NULL and reasonCount < maxCount)
1084 {
1085 reason[reasonCount] = kHeaderContainsWrongType;
1086 reasonCount++;
1087 }
1088 result = false;
878cb83d 1089 }
1090
90a74d7a 1091 // The block's record width must be the correct size.
1092 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONPairDecisionStruct))
878cb83d 1093 {
dba14d7d 1094 if (reason != NULL and reasonCount < maxCount)
1095 {
1096 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1097 reasonCount++;
1098 }
1099 result = false;
878cb83d 1100 }
1101
dba14d7d 1102 return result;
90a74d7a 1103}
1104
1105
878cb83d 1106bool AliHLTMUONUtils::IntegrityOk(
1107 const AliHLTMUONTriggerRecordStruct& tr,
dba14d7d 1108 WhyNotValid* reason,
1109 AliHLTUInt32_t& reasonCount
878cb83d 1110 )
90a74d7a 1111{
878cb83d 1112 /// This method is used to check more extensively if the integrity of the
1113 /// trigger record structure is OK and returns true in that case.
1114 /// [in] \param tr The trigger record structure to check.
dba14d7d 1115 /// [out] \param reason If this is not NULL, then it is assumed to point
1116 /// to an array of at least 'reasonCount' number of elements. It will
1117 /// be filled with the reason codes describing why the structure is
1118 /// not valid.
1119 /// [in/out] \param reasonCount This should initially specify the size of
1120 /// the array pointed to by 'reason'. It will be filled with the number
1121 /// of items actually filled into the reason array upon exit from this
1122 /// method.
878cb83d 1123 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 1124
dba14d7d 1125 AliHLTUInt32_t maxCount = reasonCount;
1126 reasonCount = 0;
1127 bool result = true;
1128
1129 // Check that the ID has a valid value.
1130 if (not (tr.fId >= 0 or tr.fId == -1))
1131 {
1132 if (reason != NULL and reasonCount < maxCount)
1133 {
1134 reason[reasonCount] = kInvalidIdValue;
1135 reasonCount++;
1136 }
1137 result = false;
1138 }
1139
90a74d7a 1140 // Make sure that the reserved bits in the fFlags field are set
1141 // to zero.
878cb83d 1142 if ((tr.fFlags & 0x3FFFFFF0) != 0)
1143 {
dba14d7d 1144 if (reason != NULL and reasonCount < maxCount)
1145 {
1146 reason[reasonCount] = kReservedBitsNotZero;
1147 reasonCount++;
1148 }
1149 result = false;
878cb83d 1150 }
90a74d7a 1151
1152 // Make sure the sign is not invalid.
878cb83d 1153 if ((tr.fFlags & 0xC0000000) == 0xC0000000)
1154 {
dba14d7d 1155 if (reason != NULL and reasonCount < maxCount)
1156 {
1157 reason[reasonCount] = kParticleSignBitsNotValid;
1158 reasonCount++;
1159 }
1160 result = false;
878cb83d 1161 }
90a74d7a 1162
1163 // Check that fHit[i] is nil if the corresponding bit in the
1164 // flags word is zero.
1165 const AliHLTMUONRecHitStruct& nilhit
1166 = AliHLTMUONConstants::NilRecHitStruct();
878cb83d 1167 if ( ((tr.fFlags & 0x1) == 0 and tr.fHit[0] != nilhit) or
1168 ((tr.fFlags & 0x2) == 0 and tr.fHit[1] != nilhit) or
1169 ((tr.fFlags & 0x4) == 0 and tr.fHit[2] != nilhit) or
1170 ((tr.fFlags & 0x8) == 0 and tr.fHit[3] != nilhit)
1171 )
1172 {
dba14d7d 1173 if (reason != NULL and reasonCount < maxCount)
1174 {
1175 reason[reasonCount] = kHitNotMarkedAsNil;
1176 reasonCount++;
1177 }
1178 result = false;
878cb83d 1179 }
a090ff22 1180
1181 // Check the individual hits
1182 for (int i = 0; i < 4; i++)
1183 {
1184 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1185 if (not IntegrityOk(tr.fHit[i], reason + reasonCount, filledCount))
1186 {
1187 reasonCount += filledCount;
1188 result = false;
1189 }
1190 }
90a74d7a 1191
dba14d7d 1192 return result;
90a74d7a 1193}
1194
1195
878cb83d 1196bool AliHLTMUONUtils::IntegrityOk(
1197 const AliHLTMUONTriggerRecordsBlockStruct& block,
1198 WhyNotValid* reason,
dba14d7d 1199 AliHLTUInt32_t* recordNum,
1200 AliHLTUInt32_t& reasonCount
878cb83d 1201 )
b727f838 1202{
878cb83d 1203 /// This method is used to check more extensively if the integrity of the
1204 /// dHLT raw internal data block is OK and returns true in that case.
1205 /// [in] \param block The trigger record data block to check.
dba14d7d 1206 /// [out] \param reason If this is not NULL, then it is assumed to point
1207 /// to an array of at least 'reasonCount' number of elements. It will
1208 /// be filled with the reason codes describing why the data block is
1209 /// not valid.
1210 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1211 /// to an array of at least 'reasonCount' number of elements. It will
1212 /// be filled with the number of the trigger record that had a problem.
1213 /// The value 'recordNum[i]' will only contain a valid value if
1214 /// the corresponding 'reason[i]' contains one of:
1215 /// - kInvalidIdValue
878cb83d 1216 /// - kReservedBitsNotZero
1217 /// - kParticleSignBitsNotValid
1218 /// - kHitNotMarkedAsNil
a090ff22 1219 /// - kInvalidDetElementNumber
1220 /// - kInvalidChamberNumber
dba14d7d 1221 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1222 /// was set and is valid or not.
1223 /// [in/out] \param reasonCount This should initially specify the size of
1224 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1225 /// with the number of items actually filled into the arrays upon exit
1226 /// from this method.
878cb83d 1227 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1228
dba14d7d 1229 AliHLTUInt32_t maxCount = reasonCount;
1230 bool result = HeaderOk(block, reason, reasonCount);
23ad6161 1231
1232 const AliHLTMUONTriggerRecordStruct* triggerRecord =
1233 reinterpret_cast<const AliHLTMUONTriggerRecordStruct*>(&block + 1);
26a4668d 1234
b727f838 1235 // Check if any ID is duplicated.
1236 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1237 {
23ad6161 1238 AliHLTInt32_t id = triggerRecord[i].fId;
dba14d7d 1239 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
b727f838 1240 {
23ad6161 1241 if (id == triggerRecord[j].fId)
878cb83d 1242 {
dba14d7d 1243 if (reason != NULL and reasonCount < maxCount)
1244 {
1245 reason[reasonCount] = kFoundDuplicateIDs;
1246 reasonCount++;
1247 }
1248 result = false;
878cb83d 1249 }
b727f838 1250 }
1251 }
1252
90a74d7a 1253 // Check integrity of individual trigger records.
b727f838 1254 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1255 {
dba14d7d 1256 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1257 if (not IntegrityOk(triggerRecord[i], reason+reasonCount, filledCount))
878cb83d 1258 {
dba14d7d 1259 // reasons filled in IntegrityOk, now we just need to adjust
1260 // reasonCount and fill the recordNum values.
1261 if (recordNum != NULL)
1262 {
1263 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1264 recordNum[reasonCount + n] = i;
1265 }
1266 reasonCount += filledCount;
1267 result = false;
878cb83d 1268 }
b727f838 1269 }
1270
dba14d7d 1271 return result;
1272}
1273
1274
1275bool AliHLTMUONUtils::IntegrityOk(
1276 const AliHLTMUONTrigRecInfoStruct& trigInfo,
1277 WhyNotValid* reason,
1278 AliHLTUInt32_t& reasonCount
1279 )
1280{
1281 /// This method is used to check more extensively if the integrity of the
1282 /// trigger record debug information structure is OK and returns true in that case.
1283 /// [in] \param trigInfo The trigger record debug information structure to check.
1284 /// [out] \param reason If this is not NULL, then it is assumed to point
1285 /// to an array of at least 'reasonCount' number of elements. It will
1286 /// be filled with the reason codes describing why the structure is not
1287 /// valid.
1288 /// [in/out] \param reasonCount This should initially specify the size of
1289 /// the array pointed to by 'reason'. It will be filled with the number
1290 /// of items actually filled into the reason array upon exit from this
1291 /// method.
1292 /// \returns true if there is no problem with the structure and false otherwise.
1293
1294 AliHLTUInt32_t maxCount = reasonCount;
1295 reasonCount = 0;
1296 bool result = true;
1297
1298 // Check that the trigger ID has a valid value.
1299 if (not (trigInfo.fTrigRecId >= 0 or trigInfo.fTrigRecId == -1))
1300 {
1301 if (reason != NULL and reasonCount < maxCount)
1302 {
1303 reason[reasonCount] = kInvalidIdValue;
1304 reasonCount++;
1305 }
1306 result = false;
1307 }
1308
1309 // Check that the fDetElemId[i] numbers are valid.
a090ff22 1310 if ( not ((trigInfo.fDetElemId[0] >= 100 and trigInfo.fDetElemId[0] < 1500)
1311 or trigInfo.fDetElemId[0] == -1)
1312 or not ((trigInfo.fDetElemId[1] >= 100 and trigInfo.fDetElemId[1] < 1500)
1313 or trigInfo.fDetElemId[1] == -1)
1314 or not ((trigInfo.fDetElemId[2] >= 100 and trigInfo.fDetElemId[2] < 1500)
1315 or trigInfo.fDetElemId[2] == -1)
1316 or not ((trigInfo.fDetElemId[3] >= 100 and trigInfo.fDetElemId[3] < 1500)
1317 or trigInfo.fDetElemId[3] == -1)
dba14d7d 1318 )
1319 {
1320 if (reason != NULL and reasonCount < maxCount)
1321 {
1322 reason[reasonCount] = kInvalidDetElementNumber;
1323 reasonCount++;
1324 }
1325 result = false;
1326 }
1327
1328 return result;
b727f838 1329}
1330
90a74d7a 1331
878cb83d 1332bool AliHLTMUONUtils::IntegrityOk(
1333 const AliHLTMUONTrigRecsDebugBlockStruct& block,
dba14d7d 1334 WhyNotValid* reason,
1335 AliHLTUInt32_t* recordNum,
1336 AliHLTUInt32_t& reasonCount
878cb83d 1337 )
c8ec7c7e 1338{
878cb83d 1339 /// This method is used to check more extensively if the integrity of the
1340 /// dHLT raw internal data block is OK and returns true in that case.
dba14d7d 1341 /// [in] \param block The trigger record debugging information data block
1342 /// to check.
1343 /// [out] \param reason If this is not NULL, then it is assumed to point
1344 /// to an array of at least 'reasonCount' number of elements. It will
1345 /// be filled with the reason codes describing why the data block is
1346 /// not valid.
1347 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1348 /// to an array of at least 'reasonCount' number of elements. It will
1349 /// be filled with the number of the trigger record debug information
1350 /// structure that had a problem.
1351 /// The value 'recordNum[i]' will only contain a valid value if
1352 /// the corresponding 'reason[i]' contains one of:
1353 /// - kInvalidIdValue
1354 /// - kInvalidDetElementNumber
1355 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1356 /// was set and is valid or not.
1357 /// [in/out] \param reasonCount This should initially specify the size of
1358 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1359 /// with the number of items actually filled into the arrays upon exit
1360 /// from this method.
878cb83d 1361 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1362
dba14d7d 1363 AliHLTUInt32_t maxCount = reasonCount;
1364 bool result = HeaderOk(block, reason, reasonCount);
1365
1366 const AliHLTMUONTrigRecInfoStruct* triggerInfo =
1367 reinterpret_cast<const AliHLTMUONTrigRecInfoStruct*>(&block + 1);
1368
1369 // Check if any trigger debug info structure has duplicated trigger IDs.
1370 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1371 {
1372 AliHLTInt32_t id = triggerInfo[i].fTrigRecId;
1373 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1374 {
1375 if (id == triggerInfo[j].fTrigRecId)
1376 {
1377 if (reason != NULL and reasonCount < maxCount)
1378 {
1379 reason[reasonCount] = kFoundDuplicateIDs;
1380 reasonCount++;
1381 }
1382 result = false;
1383 }
1384 }
1385 }
1386
1387 // Check integrity of individual trigger records.
1388 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1389 {
1390 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1391 if (not IntegrityOk(triggerInfo[i], reason+reasonCount, filledCount))
1392 {
1393 // reasons filled in IntegrityOk, now we just need to adjust
1394 // reasonCount and fill the recordNum values.
1395 if (recordNum != NULL)
1396 {
1397 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1398 recordNum[reasonCount + n] = i;
1399 }
1400 reasonCount += filledCount;
1401 result = false;
1402 }
1403 }
1404
1405 return result;
c8ec7c7e 1406}
1407
90a74d7a 1408
878cb83d 1409bool AliHLTMUONUtils::IntegrityOk(
a090ff22 1410 const AliHLTMUONRecHitStruct& hit,
1411 WhyNotValid* reason,
1412 AliHLTUInt32_t& reasonCount
878cb83d 1413 )
c8ec7c7e 1414{
878cb83d 1415 /// This method is used to check more extensively if the integrity of the
a090ff22 1416 /// reconstructed hit structure is OK and returns true in that case.
1417 /// [in] \param hit The reconstructed hit structure to check.
1418 /// [out] \param reason If this is not NULL, then it is assumed to point
1419 /// to an array of at least 'reasonCount' number of elements. It will
1420 /// be filled with the reason codes describing why the structure is
1421 /// not valid.
1422 /// [in/out] \param reasonCount This should initially specify the size of
1423 /// the array pointed to by 'reason'. It will be filled with the number
1424 /// of items actually filled into the reason array upon exit from this
1425 /// method.
1426 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 1427
a090ff22 1428 AliHLTUInt32_t maxCount = reasonCount;
1429 reasonCount = 0;
1430 bool result = true;
1431
1432 // If this is a NIL hit then skip all other checks.
1433 if (hit == AliHLTMUONConstants::NilRecHitStruct())
1434 {
1435 return true;
1436 }
1437
1438 // Make sure that the reserved bits in the fFlags field are set
1439 // to zero.
1440 if ((hit.fFlags & 0x3FFF0000) != 0)
1441 {
1442 if (reason != NULL and reasonCount < maxCount)
1443 {
1444 reason[reasonCount] = kReservedBitsNotZero;
1445 reasonCount++;
1446 }
1447 result = false;
1448 }
1449
1450 AliHLTUInt32_t detElemId = hit.fFlags & 0x00000FFF;
1451 AliHLTUInt32_t chamber = (hit.fFlags & 0x0000F000) >> 12;
1452
1453 // Make sure the detector element ID number is valid.
1454 if (not (detElemId >= 100 and detElemId < 1500))
1455 {
1456 if (reason != NULL and reasonCount < maxCount)
1457 {
1458 reason[reasonCount] = kInvalidDetElementNumber;
1459 reasonCount++;
1460 }
1461 result = false;
1462 }
1463
1464 // Make sure the chamber number is valid.
1465 if (((detElemId / 100) - 1) != chamber or chamber >= 14)
1466 {
1467 if (reason != NULL and reasonCount < maxCount)
1468 {
1469 reason[reasonCount] = kInvalidChamberNumber;
1470 reasonCount++;
1471 }
1472 result = false;
1473 }
1474
1475 return result;
c8ec7c7e 1476}
b727f838 1477
90a74d7a 1478
878cb83d 1479bool AliHLTMUONUtils::IntegrityOk(
1480 const AliHLTMUONRecHitsBlockStruct& block,
dba14d7d 1481 WhyNotValid* reason,
a090ff22 1482 AliHLTUInt32_t* recordNum,
dba14d7d 1483 AliHLTUInt32_t& reasonCount
878cb83d 1484 )
b727f838 1485{
878cb83d 1486 /// This method is used to check more extensively if the integrity of the
a090ff22 1487 /// dHLT raw internal hits data block is OK and returns true in that case.
878cb83d 1488 /// [in] \param block The reconstructed hits data block to check.
dba14d7d 1489 /// [out] \param reason If this is not NULL, then it is assumed to point
1490 /// to an array of at least 'reasonCount' number of elements. It will
1491 /// be filled with the reason codes describing why the data block is
1492 /// not valid.
a090ff22 1493 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1494 /// to an array of at least 'reasonCount' number of elements. It will
1495 /// be filled with the number of the reconstructed hits that had a problem.
1496 /// The value 'recordNum[i]' will only contain a valid value if
1497 /// the corresponding 'reason[i]' contains one of:
1498 /// - kReservedBitsNotZero
1499 /// - kInvalidDetElementNumber
1500 /// - kInvalidChamberNumber
1501 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1502 /// was set and is valid or not.
dba14d7d 1503 /// [in/out] \param reasonCount This should initially specify the size of
a090ff22 1504 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1505 /// with the number of items actually filled into the arrays upon exit
1506 /// from this method.
878cb83d 1507 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1508
dba14d7d 1509 AliHLTUInt32_t maxCount = reasonCount;
1510 bool result = HeaderOk(block, reason, reasonCount);
1511
1512 const AliHLTMUONRecHitStruct* hit =
1513 reinterpret_cast<const AliHLTMUONRecHitStruct*>(&block + 1);
1514
1515 // Check if any hit structure has been duplicated.
1516 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1517 {
1518 const AliHLTMUONRecHitStruct& h = hit[i];
1519 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1520 {
1521 if (h == hit[j])
1522 {
1523 if (reason != NULL and reasonCount < maxCount)
1524 {
1525 reason[reasonCount] = kFoundDuplicateHits;
1526 reasonCount++;
1527 }
1528 result = false;
1529 }
1530 }
1531 }
a090ff22 1532
1533 // Check integrity of the individual hit structures.
1534 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1535 {
1536 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1537 if (not IntegrityOk(hit[i], reason+reasonCount, filledCount))
1538 {
1539 // reasons filled in IntegrityOk, now we just need to adjust
1540 // reasonCount and fill the recordNum values.
1541 if (recordNum != NULL)
1542 {
1543 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1544 recordNum[reasonCount + n] = i;
1545 }
1546 reasonCount += filledCount;
1547 result = false;
1548 }
1549 }
dba14d7d 1550
1551 return result;
1552}
1553
1554
1555bool AliHLTMUONUtils::IntegrityOk(
1556 const AliHLTMUONClusterStruct& cluster,
1557 WhyNotValid* reason,
1558 AliHLTUInt32_t& reasonCount
1559 )
1560{
1561 /// This method is used to check more extensively if the integrity of the
1562 /// cluster structure is OK and returns true in that case.
1563 /// [in] \param cluster The cluster structure to check.
1564 /// [out] \param reason If this is not NULL, then it is assumed to point
1565 /// to an array of at least 'reasonCount' number of elements. It will
1566 /// be filled with the reason codes describing why the structure is
1567 /// not valid.
1568 /// [in/out] \param reasonCount This should initially specify the size of
1569 /// the array pointed to by 'reason'. It will be filled with the number
1570 /// of items actually filled into the reason array upon exit from this
1571 /// method.
1572 /// \returns true if there is no problem with the structure and false otherwise.
1573
1574 AliHLTUInt32_t maxCount = reasonCount;
1575 reasonCount = 0;
1576 bool result = true;
1577
1578 // Check that the cluster ID has a valid value.
1579 if (not (cluster.fId >= 0 or cluster.fId == -1))
1580 {
1581 if (reason != NULL and reasonCount < maxCount)
1582 {
1583 reason[reasonCount] = kInvalidIdValue;
1584 reasonCount++;
1585 }
1586 result = false;
1587 }
1588
1589 // Check that the cluster does not have a nil value for its hit.
1590 if (cluster.fHit == AliHLTMUONConstants::NilRecHitStruct())
1591 {
1592 if (reason != NULL and reasonCount < maxCount)
1593 {
1594 reason[reasonCount] = kHitIsNil;
1595 reasonCount++;
1596 }
1597 result = false;
1598 }
1599
1600 // Make sure the detector element is a valid value.
a090ff22 1601 if (not ((cluster.fDetElemId >= 100 and cluster.fDetElemId < 1500)
1602 or cluster.fDetElemId == -1)
1603 )
dba14d7d 1604 {
1605 if (reason != NULL and reasonCount < maxCount)
1606 {
1607 reason[reasonCount] = kInvalidDetElementNumber;
1608 reasonCount++;
1609 }
1610 result = false;
1611 }
1612
1613 // The number of channels should be in a reasonable range.
1614 // between 1 and the maximum number of channels per DDL.
1615 // 1<<17 taken from the 11 bits MANU ID + 6 bits channel address.
1616 if (cluster.fNchannels < 1 or (1<<17) < cluster.fNchannels)
1617 {
1618 if (reason != NULL and reasonCount < maxCount)
1619 {
1620 reason[reasonCount] = kInvalidChannelCount;
1621 reasonCount++;
1622 }
1623 result = false;
1624 }
1625
1626 return result;
b727f838 1627}
1628
1629
878cb83d 1630bool AliHLTMUONUtils::IntegrityOk(
1631 const AliHLTMUONClustersBlockStruct& block,
dba14d7d 1632 WhyNotValid* reason,
1633 AliHLTUInt32_t* recordNum,
1634 AliHLTUInt32_t& reasonCount
878cb83d 1635 )
b727f838 1636{
878cb83d 1637 /// This method is used to check more extensively if the integrity of the
dba14d7d 1638 /// dHLT internal clusters data block is OK and returns true in that case.
878cb83d 1639 /// [in] \param block The clusters data block to check.
dba14d7d 1640 /// [out] \param reason If this is not NULL, then it is assumed to point
1641 /// to an array of at least 'reasonCount' number of elements. It will
1642 /// be filled with the reason codes describing why the data block is
1643 /// not valid.
1644 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1645 /// to an array of at least 'reasonCount' number of elements. It will
1646 /// be filled with the number of the cluster structure that had a problem.
1647 /// The value 'recordNum[i]' will only contain a valid value if
1648 /// the corresponding 'reason[i]' contains one of:
1649 /// - kInvalidIdValue
1650 /// - kHitIsNil
1651 /// - kInvalidDetElementNumber
1652 /// - kInvalidChannelCount
1653 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1654 /// was set and is valid or not.
1655 /// [in/out] \param reasonCount This should initially specify the size of
1656 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1657 /// with the number of items actually filled into the arrays upon exit
1658 /// from this method.
878cb83d 1659 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1660
dba14d7d 1661 AliHLTUInt32_t maxCount = reasonCount;
1662 bool result = HeaderOk(block, reason, reasonCount);
b727f838 1663
23ad6161 1664 const AliHLTMUONClusterStruct* cluster =
1665 reinterpret_cast<const AliHLTMUONClusterStruct*>(&block + 1);
1666
c8ec7c7e 1667 // Check if any ID is duplicated.
1668 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1669 {
23ad6161 1670 AliHLTInt32_t id = cluster[i].fId;
dba14d7d 1671 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
c8ec7c7e 1672 {
23ad6161 1673 if (id == cluster[j].fId)
878cb83d 1674 {
dba14d7d 1675 if (reason != NULL and reasonCount < maxCount)
1676 {
1677 reason[reasonCount] = kFoundDuplicateIDs;
1678 reasonCount++;
1679 }
1680 result = false;
1681 }
1682 }
1683 }
1684
1685 // Check if any hit structure has been duplicated.
1686 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1687 {
1688 const AliHLTMUONRecHitStruct& h = cluster[i].fHit;
1689 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1690 {
1691 if (h == cluster[j].fHit)
1692 {
1693 if (reason != NULL and reasonCount < maxCount)
1694 {
1695 reason[reasonCount] = kFoundDuplicateHits;
1696 reasonCount++;
1697 }
1698 result = false;
1699 }
1700 }
1701 }
1702
1703 // Check integrity of individual cluster structures.
1704 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1705 {
1706 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1707 if (not IntegrityOk(cluster[i], reason+reasonCount, filledCount))
1708 {
1709 // reasons filled in IntegrityOk, now we just need to adjust
1710 // reasonCount and fill the recordNum values.
1711 if (recordNum != NULL)
1712 {
1713 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1714 recordNum[reasonCount + n] = i;
878cb83d 1715 }
dba14d7d 1716 reasonCount += filledCount;
1717 result = false;
c8ec7c7e 1718 }
1719 }
1720
dba14d7d 1721 return result;
1722}
1723
1724
1725bool AliHLTMUONUtils::IntegrityOk(
1726 const AliHLTMUONChannelStruct& channel,
1727 WhyNotValid* reason,
1728 AliHLTUInt32_t& reasonCount
1729 )
1730{
1731 /// This method is used to check more extensively if the integrity of the
1732 /// channel structure is OK and returns true in that case.
1733 /// [in] \param cluster The channel structure to check.
1734 /// [out] \param reason If this is not NULL, then it is assumed to point
1735 /// to an array of at least 'reasonCount' number of elements. It will
1736 /// be filled with the reason codes describing why the structure is
1737 /// not valid.
1738 /// [in/out] \param reasonCount This should initially specify the size of
1739 /// the array pointed to by 'reason'. It will be filled with the number
1740 /// of items actually filled into the reason array upon exit from this
1741 /// method.
1742 /// \returns true if there is no problem with the structure and false otherwise.
1743
1744 AliHLTUInt32_t maxCount = reasonCount;
1745 reasonCount = 0;
1746 bool result = true;
1747
1748 // Check that the channel ID has a valid value.
1749 if (not (channel.fClusterId >= 0 or channel.fClusterId == -1))
1750 {
1751 if (reason != NULL and reasonCount < maxCount)
1752 {
1753 reason[reasonCount] = kInvalidIdValue;
1754 reasonCount++;
1755 }
1756 result = false;
1757 }
1758
1759 // Check that the bus patch ID has a valid value, which fits into 12 bits.
1760 if ((channel.fBusPatch & (~0xFFF)) != 0)
1761 {
1762 if (reason != NULL and reasonCount < maxCount)
1763 {
1764 reason[reasonCount] = kInvalidBusPatchId;
1765 reasonCount++;
1766 }
1767 result = false;
1768 }
1769
1770 // Check that the MANU ID has a valid value, which fits into 11 bits.
1771 if ((channel.fManu & (~0x7FF)) != 0)
1772 {
1773 if (reason != NULL and reasonCount < maxCount)
1774 {
1775 reason[reasonCount] = kInvalidManuId;
1776 reasonCount++;
1777 }
1778 result = false;
1779 }
1780
1781 // Check that the channel address has a valid value, which fits into 6 bits.
1782 if ((channel.fChannelAddress & (~0x3F)) != 0)
1783 {
1784 if (reason != NULL and reasonCount < maxCount)
1785 {
1786 reason[reasonCount] = kInvalidChannelAddress;
1787 reasonCount++;
1788 }
1789 result = false;
1790 }
1791
1792 // Check that the ADC signal has a valid value, which fits into 12 bits.
1793 if ((channel.fSignal & (~0xFFF)) != 0)
1794 {
1795 if (reason != NULL and reasonCount < maxCount)
1796 {
1797 reason[reasonCount] = kInvalidSignal;
1798 reasonCount++;
1799 }
1800 result = false;
1801 }
1802
1803 // Check that the raw data word corresponds to the unpacked values for
1804 // the ADC signal, MANU ID and channel address.
1805 UShort_t manuId; UChar_t channelId; UShort_t adc;
1806 AliMUONTrackerDDLDecoderEventHandler::UnpackADC(
1807 channel.fRawDataWord, manuId, channelId, adc
1808 );
1809 if (manuId != channel.fManu or channelId != channel.fChannelAddress
1810 or adc != channel.fSignal
1811 )
1812 {
1813 if (reason != NULL and reasonCount < maxCount)
1814 {
1815 reason[reasonCount] = kDataWordDifferent;
1816 reasonCount++;
1817 }
1818 result = false;
1819 }
1820
1821 return result;
b727f838 1822}
1823
90a74d7a 1824
878cb83d 1825bool AliHLTMUONUtils::IntegrityOk(
1826 const AliHLTMUONChannelsBlockStruct& block,
dba14d7d 1827 WhyNotValid* reason,
1828 AliHLTUInt32_t* recordNum,
1829 AliHLTUInt32_t& reasonCount
878cb83d 1830 )
b727f838 1831{
878cb83d 1832 /// This method is used to check more extensively if the integrity of the
dba14d7d 1833 /// dHLT internal channels data block is OK and returns true in that case.
1834 /// [in] \param block The channels data block to check.
1835 /// [out] \param reason If this is not NULL, then it is assumed to point
1836 /// to an array of at least 'reasonCount' number of elements. It will
1837 /// be filled with the reason codes describing why the data block is
1838 /// not valid.
1839 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1840 /// to an array of at least 'reasonCount' number of elements. It will
1841 /// be filled with the number of the channel structure that had a problem.
1842 /// The value 'recordNum[i]' will only contain a valid value if
1843 /// the corresponding 'reason[i]' contains one of:
1844 /// - kInvalidIdValue
1845 /// - kInvalidBusPatchId
1846 /// - kInvalidManuId
1847 /// - kInvalidChannelAddress
1848 /// - kInvalidSignal
1849 /// - kDataWordDifferent
1850 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1851 /// was set and is valid or not.
1852 /// [in/out] \param reasonCount This should initially specify the size of
1853 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1854 /// with the number of items actually filled into the arrays upon exit
1855 /// from this method.
878cb83d 1856 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1857
dba14d7d 1858 AliHLTUInt32_t maxCount = reasonCount;
1859 bool result = HeaderOk(block, reason, reasonCount);
1860
1861 const AliHLTMUONChannelStruct* channel =
1862 reinterpret_cast<const AliHLTMUONChannelStruct*>(&block + 1);
1863
1864 // Check if any cluster ID is duplicated.
1865 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1866 {
1867 AliHLTInt32_t id = channel[i].fClusterId;
1868 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1869 {
1870 if (id == channel[j].fClusterId)
1871 {
1872 if (reason != NULL and reasonCount < maxCount)
1873 {
1874 reason[reasonCount] = kFoundDuplicateIDs;
1875 reasonCount++;
1876 }
1877 result = false;
1878 }
1879 }
1880 }
1881
1882 // Check integrity of individual channel structures.
1883 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1884 {
1885 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1886 if (not IntegrityOk(channel[i], reason+reasonCount, filledCount))
1887 {
1888 // reasons filled in IntegrityOk, now we just need to adjust
1889 // reasonCount and fill the recordNum values.
1890 if (recordNum != NULL)
1891 {
1892 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1893 recordNum[reasonCount + n] = i;
1894 }
1895 reasonCount += filledCount;
1896 result = false;
1897 }
1898 }
1899
1900 return result;
26a4668d 1901}
90a74d7a 1902
1903
878cb83d 1904bool AliHLTMUONUtils::IntegrityOk(
1905 const AliHLTMUONMansoTrackStruct& track,
dba14d7d 1906 WhyNotValid* reason,
1907 AliHLTUInt32_t& reasonCount
878cb83d 1908 )
90a74d7a 1909{
878cb83d 1910 /// This method is used to check more extensively if the integrity of the
1911 /// Manso track structure is OK and returns true in that case.
1912 /// [in] \param track The track structure to check.
dba14d7d 1913 /// [out] \param reason If this is not NULL, then it is assumed to point
1914 /// to an array of at least 'reasonCount' number of elements. It will
1915 /// be filled with the reason codes describing why the structure is
1916 /// not valid.
1917 /// [in/out] \param reasonCount This should initially specify the size of
1918 /// the array pointed to by 'reason'. It will be filled with the number
1919 /// of items actually filled into the reason array upon exit from this
1920 /// method.
878cb83d 1921 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 1922
dba14d7d 1923 AliHLTUInt32_t maxCount = reasonCount;
1924 reasonCount = 0;
1925 bool result = true;
1926
1927 // Check that the Manso track ID has a valid value.
1928 if (not (track.fId >= 0 or track.fId == -1))
1929 {
1930 if (reason != NULL and reasonCount < maxCount)
1931 {
1932 reason[reasonCount] = kInvalidIdValue;
1933 reasonCount++;
1934 }
1935 result = false;
1936 }
1937
1938 // Check that the corresponding trigger record ID has a valid value.
1939 if (not (track.fTrigRec >= 0 or track.fTrigRec == -1))
1940 {
1941 if (reason != NULL and reasonCount < maxCount)
1942 {
1943 reason[reasonCount] = kInvalidTriggerIdValue;
1944 reasonCount++;
1945 }
1946 result = false;
1947 }
1948
90a74d7a 1949 // Make sure that the reserved bits in the fFlags field are set
1950 // to zero.
878cb83d 1951 if ((track.fFlags & 0x3FFFFFF0) != 0)
1952 {
dba14d7d 1953 if (reason != NULL and reasonCount < maxCount)
1954 {
1955 reason[reasonCount] = kReservedBitsNotZero;
1956 reasonCount++;
1957 }
1958 result = false;
878cb83d 1959 }
90a74d7a 1960
1961 // Make sure the sign is not invalid.
878cb83d 1962 if ((track.fFlags & 0xC0000000) == 0xC0000000)
1963 {
dba14d7d 1964 if (reason != NULL and reasonCount < maxCount)
1965 {
1966 reason[reasonCount] = kParticleSignBitsNotValid;
1967 reasonCount++;
1968 }
1969 result = false;
878cb83d 1970 }
90a74d7a 1971
1972 // Check that fHit[i] is nil if the corresponding bit in the
1973 // flags word is zero.
1974 const AliHLTMUONRecHitStruct& nilhit
1975 = AliHLTMUONConstants::NilRecHitStruct();
878cb83d 1976 if ( ((track.fFlags & 0x1) == 0 and track.fHit[0] != nilhit) or
1977 ((track.fFlags & 0x2) == 0 and track.fHit[1] != nilhit) or
1978 ((track.fFlags & 0x4) == 0 and track.fHit[2] != nilhit) or
1979 ((track.fFlags & 0x8) == 0 and track.fHit[3] != nilhit)
1980 )
1981 {
dba14d7d 1982 if (reason != NULL and reasonCount < maxCount)
1983 {
1984 reason[reasonCount] = kHitNotMarkedAsNil;
1985 reasonCount++;
1986 }
1987 result = false;
1988 }
1989
1990 // Check that the chi squared value is valid
1991 if (not (track.fChi2 >= 0 or track.fChi2 == -1))
1992 {
1993 if (reason != NULL and reasonCount < maxCount)
1994 {
1995 reason[reasonCount] = kChiSquareInvalid;
1996 reasonCount++;
1997 }
1998 result = false;
1999 }
2000
2001 // Check that if chi squared is -1 then the momentum vector is zero.
2002 if (track.fChi2 == -1 and
2003 not (track.fPx == 0 and track.fPy == 0 and track.fPz == 0)
2004 )
2005 {
2006 if (reason != NULL and reasonCount < maxCount)
2007 {
2008 reason[reasonCount] = kMomentumVectorNotZero;
2009 reasonCount++;
2010 }
2011 result = false;
878cb83d 2012 }
90a74d7a 2013
a090ff22 2014 // Check the individual hits
2015 for (int i = 0; i < 4; i++)
2016 {
2017 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2018 if (not IntegrityOk(track.fHit[i], reason + reasonCount, filledCount))
2019 {
2020 reasonCount += filledCount;
2021 result = false;
2022 }
2023 }
2024
dba14d7d 2025 return result;
90a74d7a 2026}
2027
2028
878cb83d 2029bool AliHLTMUONUtils::IntegrityOk(
2030 const AliHLTMUONMansoTracksBlockStruct& block,
2031 WhyNotValid* reason,
dba14d7d 2032 AliHLTUInt32_t* recordNum,
2033 AliHLTUInt32_t& reasonCount
878cb83d 2034 )
90a74d7a 2035{
878cb83d 2036 /// This method is used to check more extensively if the integrity of the
dba14d7d 2037 /// dHLT internal Manso track data block is OK and returns true in that case.
878cb83d 2038 /// [in] \param block The Manso track data block to check.
dba14d7d 2039 /// [out] \param reason If this is not NULL, then it is assumed to point
2040 /// to an array of at least 'reasonCount' number of elements. It will
2041 /// be filled with the reason codes describing why the data block is
2042 /// not valid.
2043 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2044 /// to an array of at least 'reasonCount' number of elements. It will
2045 /// be filled with the number of the Manso track that had a problem.
2046 /// The value 'recordNum[i]' will only contain a valid value if
2047 /// the corresponding 'reason[i]' contains one of:
2048 /// - kInvalidIdValue
2049 /// - kInvalidTriggerIdValue
878cb83d 2050 /// - kReservedBitsNotZero
2051 /// - kParticleSignBitsNotValid
2052 /// - kHitNotMarkedAsNil
dba14d7d 2053 /// - kChiSquareInvalid
2054 /// - kMomentumVectorNotZero
a090ff22 2055 /// - kInvalidDetElementNumber
2056 /// - kInvalidChamberNumber
dba14d7d 2057 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2058 /// was set and is valid or not.
2059 /// [in/out] \param reasonCount This should initially specify the size of
2060 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2061 /// with the number of items actually filled into the arrays upon exit
2062 /// from this method.
878cb83d 2063 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2064
dba14d7d 2065 AliHLTUInt32_t maxCount = reasonCount;
2066 bool result = HeaderOk(block, reason, reasonCount);
2067
23ad6161 2068 const AliHLTMUONMansoTrackStruct* track =
2069 reinterpret_cast<const AliHLTMUONMansoTrackStruct*>(&block + 1);
2070
878cb83d 2071 // Check if any track ID is duplicated.
90a74d7a 2072 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2073 {
23ad6161 2074 AliHLTInt32_t id = track[i].fId;
dba14d7d 2075 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
90a74d7a 2076 {
23ad6161 2077 if (id == track[j].fId)
878cb83d 2078 {
dba14d7d 2079 if (reason != NULL and reasonCount < maxCount)
2080 {
2081 reason[reasonCount] = kFoundDuplicateIDs;
2082 reasonCount++;
2083 }
2084 result = false;
878cb83d 2085 }
90a74d7a 2086 }
2087 }
dba14d7d 2088
2089 // Check that all the tracks have integrity.
90a74d7a 2090 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2091 {
dba14d7d 2092 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2093 if (not IntegrityOk(track[i], reason+reasonCount, filledCount))
878cb83d 2094 {
dba14d7d 2095 // reasons filled in IntegrityOk, now we just need to adjust
2096 // reasonCount and fill the recordNum values.
2097 if (recordNum != NULL)
2098 {
2099 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2100 recordNum[reasonCount + n] = i;
2101 }
2102 reasonCount += filledCount;
2103 result = false;
878cb83d 2104 }
90a74d7a 2105 }
dba14d7d 2106
2107 return result;
2108}
90a74d7a 2109
dba14d7d 2110
2111bool AliHLTMUONUtils::IntegrityOk(
2112 const AliHLTMUONMansoCandidateStruct& candidate,
2113 WhyNotValid* reason,
2114 AliHLTUInt32_t& reasonCount
2115 )
2116{
2117 /// This method is used to check more extensively if the integrity of the
2118 /// Manso track candidate structure is OK and returns true in that case.
2119 /// [in] \param track The track candidate structure to check.
2120 /// [out] \param reason If this is not NULL, then it is assumed to point
2121 /// to an array of at least 'reasonCount' number of elements. It will
2122 /// be filled with the reason codes describing why the structure is
2123 /// not valid.
2124 /// [in/out] \param reasonCount This should initially specify the size of
2125 /// the array pointed to by 'reason'. It will be filled with the number
2126 /// of items actually filled into the reason array upon exit from this
2127 /// method.
2128 /// \returns true if there is no problem with the structure and false otherwise.
2129
2130 // First check the integrity of the candidate track structure.
2131 AliHLTUInt32_t maxCount = reasonCount;
2132 bool result = IntegrityOk(candidate.fTrack, reason, reasonCount);
2133
2134 // Now check that the ROIs are reasonable.
2135 // The radius must be positive or -1 indicating computation error and
2136 // the corresponding hit in the track must be within the ROI.
2137 for (AliHLTUInt32_t i = 0; i < 4; i++)
2138 {
2139 if (not (candidate.fRoI[i].fRadius >= 0 or candidate.fRoI[i].fRadius == -1))
2140 {
2141 if (reason != NULL and reasonCount < maxCount)
2142 {
2143 reason[reasonCount] = kRoiRadiusInvalid;
2144 reasonCount++;
2145 }
2146 result = false;
2147 }
2148
2149 // Check if the corresponding hit was even found in the track.
2150 if ( (candidate.fTrack.fFlags & (0x1 << i)) == 0 ) continue;
2151
2152 double dx = candidate.fRoI[i].fX - candidate.fTrack.fHit[i].fX;
2153 double dy = candidate.fRoI[i].fY - candidate.fTrack.fHit[i].fY;
2154 double dz = candidate.fRoI[i].fZ - candidate.fTrack.fHit[i].fZ;
2155 double r = sqrt(dx*dx + dy*dy);
2156 // Check if the projected distance between ROI centre and hit is
2157 // bigger than the ROI radius. Also the difference between z
2158 // coordinates should not exceed 20 cm.
2159 if (r > candidate.fRoI[i].fRadius or fabs(dz) > 20.)
2160 {
2161 if (reason != NULL and reasonCount < maxCount)
2162 {
2163 reason[reasonCount] = kHitNotWithinRoi;
2164 reasonCount++;
2165 }
2166 result = false;
2167 }
2168 }
2169
2170 return result;
90a74d7a 2171}
2172
2173
878cb83d 2174bool AliHLTMUONUtils::IntegrityOk(
2175 const AliHLTMUONMansoCandidatesBlockStruct& block,
2176 WhyNotValid* reason,
dba14d7d 2177 AliHLTUInt32_t* recordNum,
2178 AliHLTUInt32_t& reasonCount
878cb83d 2179 )
90a74d7a 2180{
878cb83d 2181 /// This method is used to check more extensively if the integrity of the
dba14d7d 2182 /// dHLT internal Manso candidates data block is OK and returns true in
2183 /// that case.
878cb83d 2184 /// [in] \param block The Manso track candidate data block to check.
dba14d7d 2185 /// [out] \param reason If this is not NULL, then it is assumed to point
2186 /// to an array of at least 'reasonCount' number of elements. It will
2187 /// be filled with the reason codes describing why the data block is
2188 /// not valid.
2189 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2190 /// to an array of at least 'reasonCount' number of elements. It will
2191 /// be filled with the number of the track candidate that had a problem.
2192 /// The value 'recordNum[i]' will only contain a valid value if
2193 /// the corresponding 'reason[i]' contains one of:
2194 /// - kInvalidIdValue
2195 /// - kInvalidTriggerIdValue
878cb83d 2196 /// - kReservedBitsNotZero
2197 /// - kParticleSignBitsNotValid
2198 /// - kHitNotMarkedAsNil
dba14d7d 2199 /// - kChiSquareInvalid
2200 /// - kRoiRadiusInvalid
2201 /// - kHitNotWithinRoi
2202 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2203 /// was set and is valid or not.
2204 /// [in/out] \param reasonCount This should initially specify the size of
2205 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2206 /// with the number of items actually filled into the arrays upon exit
2207 /// from this method.
878cb83d 2208 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2209
dba14d7d 2210 AliHLTUInt32_t maxCount = reasonCount;
2211 bool result = HeaderOk(block, reason, reasonCount);
90a74d7a 2212
23ad6161 2213 const AliHLTMUONMansoCandidateStruct* candidate =
2214 reinterpret_cast<const AliHLTMUONMansoCandidateStruct*>(&block + 1);
2215
878cb83d 2216 // Check if any candidate track ID is duplicated.
2217 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2218 {
2219 AliHLTInt32_t id = candidate[i].fTrack.fId;
dba14d7d 2220 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
878cb83d 2221 {
2222 if (id == candidate[j].fTrack.fId)
2223 {
dba14d7d 2224 if (reason != NULL and reasonCount < maxCount)
2225 {
2226 reason[reasonCount] = kFoundDuplicateIDs;
2227 reasonCount++;
2228 }
2229 result = false;
878cb83d 2230 }
2231 }
2232 }
2233
dba14d7d 2234 // Check that all the track candidates have integrity.
90a74d7a 2235 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2236 {
dba14d7d 2237 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2238 if (not IntegrityOk(candidate[i], reason+reasonCount, filledCount))
878cb83d 2239 {
dba14d7d 2240 // reasons filled in IntegrityOk, now we just need to adjust
2241 // reasonCount and fill the recordNum values.
2242 if (recordNum != NULL)
2243 {
2244 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2245 recordNum[reasonCount + n] = i;
2246 }
2247 reasonCount += filledCount;
2248 result = false;
878cb83d 2249 }
90a74d7a 2250 }
2251
dba14d7d 2252 return result;
90a74d7a 2253}
2254
2255
878cb83d 2256bool AliHLTMUONUtils::IntegrityOk(
2257 const AliHLTMUONTrackDecisionStruct& decision,
dba14d7d 2258 WhyNotValid* reason,
2259 AliHLTUInt32_t& reasonCount
878cb83d 2260 )
90a74d7a 2261{
878cb83d 2262 /// This method is used to check more extensively if the integrity of the
2263 /// single track trigger decision structure is OK and returns true in that case.
2264 /// [in] \param decision The trigger decision structure to check.
dba14d7d 2265 /// [out] \param reason If this is not NULL, then it is assumed to point
2266 /// to an array of at least 'reasonCount' number of elements. It will
2267 /// be filled with the reason codes describing why the structure is not
2268 /// valid.
2269 /// [in/out] \param reasonCount This should initially specify the size of
2270 /// the array pointed to by 'reason'. It will be filled with the number
2271 /// of items actually filled into the reason array upon exit from this
2272 /// method.
878cb83d 2273 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 2274
dba14d7d 2275 AliHLTUInt32_t maxCount = reasonCount;
2276 reasonCount = 0;
2277 bool result = true;
2278
2279 // The track ID value must be positive or -1.
2280 if (not (decision.fTrackId >= 0 or decision.fTrackId == -1))
2281 {
2282 if (reason != NULL and reasonCount < maxCount)
2283 {
2284 reason[reasonCount] = kInvalidTrackIdValue;
2285 reasonCount++;
2286 }
2287 result = false;
2288 }
2289
90a74d7a 2290 // Make sure that the reserved bits in the fTriggerBits field are set
2291 // to zero.
878cb83d 2292 if ((decision.fTriggerBits & 0xFFFFFFFC) != 0)
2293 {
dba14d7d 2294 if (reason != NULL and reasonCount < maxCount)
2295 {
2296 reason[reasonCount] = kReservedBitsNotZero;
2297 reasonCount++;
2298 }
2299 result = false;
878cb83d 2300 }
2301
2302 // The pT should be -1 or a positive number.
2303 if (decision.fPt != -1. and decision.fPt < 0.)
2304 {
dba14d7d 2305 if (reason != NULL and reasonCount < maxCount)
2306 {
2307 reason[reasonCount] = kPtValueNotValid;
2308 reasonCount++;
2309 }
2310 result = false;
878cb83d 2311 }
2312
dba14d7d 2313 return result;
90a74d7a 2314}
2315
2316
878cb83d 2317bool AliHLTMUONUtils::IntegrityOk(
2318 const AliHLTMUONSinglesDecisionBlockStruct& block,
2319 WhyNotValid* reason,
dba14d7d 2320 AliHLTUInt32_t* recordNum,
2321 AliHLTUInt32_t& reasonCount
878cb83d 2322 )
90a74d7a 2323{
878cb83d 2324 /// This method is used to check more extensively if the integrity of the
dba14d7d 2325 /// dHLT internal single track trigger decision data block is OK and returns
2326 /// true in that case.
878cb83d 2327 /// [in] \param block The single track trigger decision data block to check.
dba14d7d 2328 /// [out] \param reason If this is not NULL, then it is assumed to point
2329 /// to an array of at least 'reasonCount' number of elements. It will
2330 /// be filled with the reason codes describing why the data block is
2331 /// not valid.
2332 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2333 /// to an array of at least 'reasonCount' number of elements. It will
2334 /// be filled with the number of the trigger decision that had a problem.
2335 /// The value 'recordNum[i]' will only contain a valid value if
2336 /// the corresponding 'reason[i]' contains one of:
2337 /// - kInvalidTrackIdValue
878cb83d 2338 /// - kReservedBitsNotZero
2339 /// - kPtValueNotValid
dba14d7d 2340 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2341 /// was set and is valid or not.
2342 /// [in/out] \param reasonCount This should initially specify the size of
2343 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2344 /// with the number of items actually filled into the arrays upon exit
2345 /// from this method.
878cb83d 2346 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2347
dba14d7d 2348 AliHLTUInt32_t maxCount = reasonCount;
2349 bool result = HeaderOk(block, reason, reasonCount);
23ad6161 2350
2351 const AliHLTMUONTrackDecisionStruct* decision =
2352 reinterpret_cast<const AliHLTMUONTrackDecisionStruct*>(&block + 1);
90a74d7a 2353
878cb83d 2354 // Check that there are no duplicate trigger entries.
2355 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2356 {
2357 AliHLTInt32_t id = decision[i].fTrackId;
dba14d7d 2358 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
878cb83d 2359 {
2360 if (id == decision[j].fTrackId)
2361 {
dba14d7d 2362 if (reason != NULL and reasonCount < maxCount)
2363 {
2364 reason[reasonCount] = kFoundDuplicateTriggers;
2365 reasonCount++;
2366 }
2367 result = false;
878cb83d 2368 }
2369 }
2370 }
2371
90a74d7a 2372 // Check that the trigger bits for each track have integrity.
2373 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2374 {
dba14d7d 2375 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2376 if (not IntegrityOk(decision[i], reason+reasonCount, filledCount))
878cb83d 2377 {
dba14d7d 2378 // Reasons filled in IntegrityOk, now we just need to adjust
2379 // reasonCount and fill the recordNum values.
2380 if (recordNum != NULL)
2381 {
2382 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2383 recordNum[reasonCount + n] = i;
2384 }
2385 reasonCount += filledCount;
2386 result = false;
878cb83d 2387 }
90a74d7a 2388 }
2389
dba14d7d 2390 return result;
90a74d7a 2391}
2392
2393
878cb83d 2394bool AliHLTMUONUtils::IntegrityOk(
2395 const AliHLTMUONPairDecisionStruct& decision,
dba14d7d 2396 WhyNotValid* reason,
2397 AliHLTUInt32_t& reasonCount
878cb83d 2398 )
90a74d7a 2399{
878cb83d 2400 /// This method is used to check more extensively if the integrity of the
2401 /// track pair trigger decision structure is OK and returns true in that case.
2402 /// [in] \param decision The trigger decision structure to check.
dba14d7d 2403 /// [out] \param reason If this is not NULL, then it is assumed to point
2404 /// to an array of at least 'reasonCount' number of elements. It will
2405 /// be filled with the reason codes describing why the structure is not
2406 /// valid.
2407 /// [in/out] \param reasonCount This should initially specify the size of
2408 /// the array pointed to by 'reason'. It will be filled with the number
2409 /// of items actually filled into the reason array upon exit from this
2410 /// method.
878cb83d 2411 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 2412
dba14d7d 2413 AliHLTUInt32_t maxCount = reasonCount;
2414 reasonCount = 0;
2415 bool result = true;
2416
2417 //kInvalidTrackIdValue
2418
2419 // The track IDs must have a positive value or -1.
2420 if (not (decision.fTrackAId >= 0 or decision.fTrackAId == -1) or
2421 not (decision.fTrackBId >= 0 or decision.fTrackBId == -1)
2422 )
2423 {
2424 if (reason != NULL and reasonCount < maxCount)
2425 {
2426 reason[reasonCount] = kInvalidTrackIdValue;
2427 reasonCount++;
2428 }
2429 result = false;
2430 }
2431
90a74d7a 2432 // Make sure that the reserved bits in the fTriggerBits field are set
2433 // to zero.
878cb83d 2434 if ((decision.fTriggerBits & 0xFFFFFF80) != 0)
2435 {
dba14d7d 2436 if (reason != NULL and reasonCount < maxCount)
2437 {
2438 reason[reasonCount] = kReservedBitsNotZero;
2439 reasonCount++;
2440 }
2441 result = false;
878cb83d 2442 }
90a74d7a 2443
878cb83d 2444 // Check that the track IDs are not the same.
2445 if (decision.fTrackAId == decision.fTrackBId)
2446 {
dba14d7d 2447 if (reason != NULL and reasonCount < maxCount)
2448 {
2449 reason[reasonCount] = kPairTrackIdsAreIdentical;
2450 reasonCount++;
2451 }
2452 result = false;
878cb83d 2453 }
2454
2455 // The invariant mass should be -1 or a positive number.
2456 if (decision.fInvMass != -1. and decision.fInvMass < 0.)
2457 {
dba14d7d 2458 if (reason != NULL and reasonCount < maxCount)
2459 {
2460 reason[reasonCount] = kMassValueNotValid;
2461 reasonCount++;
2462 }
2463 result = false;
878cb83d 2464 }
90a74d7a 2465
2466 // Neither the high pt (hipt) or low pt (lopt) count bits can be > 2.
90a74d7a 2467 AliHLTUInt8_t lowPtCount = (decision.fTriggerBits & 0x00000003);
2468 AliHLTUInt8_t highPtCount = (decision.fTriggerBits & 0x0000000C) >> 2;
878cb83d 2469 if (lowPtCount > 2)
2470 {
dba14d7d 2471 if (reason != NULL and reasonCount < maxCount)
2472 {
2473 reason[reasonCount] = kLowPtCountInvalid;
2474 reasonCount++;
2475 }
2476 result = false;
878cb83d 2477 }
2478 if (highPtCount > 2)
2479 {
dba14d7d 2480 if (reason != NULL and reasonCount < maxCount)
2481 {
2482 reason[reasonCount] = kHighPtCountInvalid;
2483 reasonCount++;
2484 }
2485 result = false;
878cb83d 2486 }
90a74d7a 2487
dba14d7d 2488 return result;
90a74d7a 2489}
2490
2491
878cb83d 2492bool AliHLTMUONUtils::IntegrityOk(
2493 const AliHLTMUONPairsDecisionBlockStruct& block,
2494 WhyNotValid* reason,
dba14d7d 2495 AliHLTUInt32_t* recordNum,
2496 AliHLTUInt32_t& reasonCount
878cb83d 2497 )
90a74d7a 2498{
878cb83d 2499 /// This method is used to check more extensively if the integrity of the
dba14d7d 2500 /// dHLT internal track pair trigger decision data block is OK and returns
2501 /// true in that case.
878cb83d 2502 /// [in] \param block The track pair trigger decision data block to check.
dba14d7d 2503 /// [out] \param reason If this is not NULL, then it is assumed to point
2504 /// to an array of at least 'reasonCount' number of elements. It will
2505 /// be filled with the reason codes describing why the data block is
2506 /// not valid.
2507 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2508 /// to an array of at least 'reasonCount' number of elements. It will
2509 /// be filled with the number of the trigger decision that had a problem.
2510 /// The value 'recordNum[i]' will only contain a valid value if
2511 /// the corresponding 'reason[i]' contains one of:
2512 /// - kInvalidTrackIdValue
878cb83d 2513 /// - kReservedBitsNotZero
2514 /// - kPairTrackIdsAreIdentical
2515 /// - kMassValueNotValid
2516 /// - kLowPtCountInvalid
2517 /// - kHighPtCountInvalid
dba14d7d 2518 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2519 /// was set and is valid or not.
2520 /// [in/out] \param reasonCount This should initially specify the size of
2521 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2522 /// with the number of items actually filled into the arrays upon exit
2523 /// from this method.
878cb83d 2524 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2525
dba14d7d 2526 AliHLTUInt32_t maxCount = reasonCount;
2527 bool result = HeaderOk(block, reason, reasonCount);
90a74d7a 2528
23ad6161 2529 const AliHLTMUONPairDecisionStruct* decision =
2530 reinterpret_cast<const AliHLTMUONPairDecisionStruct*>(&block + 1);
2531
878cb83d 2532 // Check that there are no duplicate trigger entries.
2533 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2534 {
2535 AliHLTInt32_t ta = decision[i].fTrackAId;
2536 AliHLTInt32_t tb = decision[i].fTrackBId;
dba14d7d 2537 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
878cb83d 2538 {
2539 if (ta == decision[j].fTrackAId and tb == decision[j].fTrackBId)
2540 {
dba14d7d 2541 if (reason != NULL and reasonCount < maxCount)
2542 {
2543 reason[reasonCount] = kFoundDuplicateTriggers;
2544 reasonCount++;
2545 }
2546 result = false;
878cb83d 2547 }
2548 }
2549 }
2550
90a74d7a 2551 // Check that the trigger bits for each track pair have integrity.
2552 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2553 {
dba14d7d 2554 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2555 if (not IntegrityOk(decision[i], reason+reasonCount, filledCount))
878cb83d 2556 {
dba14d7d 2557 // Reasons filled in IntegrityOk, now we just need to adjust
2558 // reasonCount and fill the recordNum values.
2559 if (recordNum != NULL)
2560 {
2561 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2562 recordNum[reasonCount + n] = i;
2563 }
2564 reasonCount += filledCount;
2565 result = false;
878cb83d 2566 }
90a74d7a 2567 }
2568
dba14d7d 2569 return result;
90a74d7a 2570}
dba14d7d 2571