]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/AliHLTMUONUtils.cxx
Improving documentation and macros.
[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
1d8ae082 16// $Id$
26a4668d 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";
66622a82 524 case kInvalidChannelCountB: return "kInvalidChannelCountB";
525 case kInvalidChannelCountNB: return "kInvalidChannelCountNB";
526 case kInvalidChargeB: return "kInvalidChargeB";
527 case kInvalidChargeNB: return "kInvalidChargeNB";
dba14d7d 528 case kInvalidBusPatchId: return "kInvalidBusPatchId";
529 case kInvalidManuId: return "kInvalidManuId";
530 case kInvalidChannelAddress: return "kInvalidChannelAddress";
531 case kInvalidSignal: return "kInvalidSignal";
532 case kDataWordDifferent: return "kDataWordDifferent";
533 case kChiSquareInvalid: return "kChiSquareInvalid";
534 case kMomentumVectorNotZero: return "kMomentumVectorNotZero";
535 case kRoiRadiusInvalid: return "kRoiRadiusInvalid";
536 case kHitNotWithinRoi: return "kHitNotWithinRoi";
878cb83d 537 case kPtValueNotValid: return "kPtValueNotValid";
878cb83d 538 case kPairTrackIdsAreIdentical: return "kPairTrackIdsAreIdentical";
539 case kMassValueNotValid: return "kMassValueNotValid";
540 case kLowPtCountInvalid: return "kLowPtCountInvalid";
541 case kHighPtCountInvalid: return "kHighPtCountInvalid";
dba14d7d 542 case kFoundDuplicateIDs: return "kFoundDuplicateIDs";
543 case kFoundDuplicateHits: return "kFoundDuplicateHits";
544 case kFoundDuplicateTriggers: return "kFoundDuplicateTriggers";
878cb83d 545 default: return "INVALID";
546 }
547}
548
549
550const char* AliHLTMUONUtils::FailureReasonToMessage(WhyNotValid reason)
551{
552 /// This method returns a string containing a user readable message explaining
553 /// the reason for failure described by the WhyNotValid enumeration.
554
555 switch (reason)
556 {
557 case kNoReason:
558 return "There was no problem with the data block.";
559 case kHeaderContainsWrongType:
dba14d7d 560 return "The common data header contains an incorrect type"
561 " identifier.";
878cb83d 562 case kHeaderContainsWrongRecordWidth:
dba14d7d 563 return "The common data header contains an incorrect data"
564 " record width.";
565 case kInvalidIdValue:
566 return "The structure identifier does not have a valid value.";
567 case kInvalidTriggerIdValue:
568 return "The trigger structure identifier does not have a valid"
569 " value.";
570 case kInvalidTrackIdValue:
571 return "The track structure identifier does not have a valid"
572 " value.";
878cb83d 573 case kReservedBitsNotZero:
574 return "Reserved bits have not been set to zero.";
575 case kParticleSignBitsNotValid:
576 return "The particle sign bits are not a valid value.";
577 case kHitNotMarkedAsNil:
578 return "A hit was marked as not found, but the corresponding hit"
579 " structure was not set to nil.";
dba14d7d 580 case kInvalidDetElementNumber:
581 return "An invalid detector element ID was found.";
a090ff22 582 case kInvalidChamberNumber:
583 return "An invalid chamber number was found.";
dba14d7d 584 case kHitIsNil:
585 return "The hit cannot be set to a nil value.";
66622a82 586 case kInvalidChannelCountB:
587 return "The number of channels in the bending plane indicated"
588 " is zero or outside the valid range.";
589 case kInvalidChannelCountNB:
590 return "The number of channels in the non-bending plane indicated"
591 " is zero or outside the valid range.";
592 case kInvalidChargeB:
593 return "The charge in the bending plane does not have a valid value.";
594 case kInvalidChargeNB:
595 return "The charge in the non-bending plane does not have a valid value.";
dba14d7d 596 case kInvalidBusPatchId:
597 return "The bus patch identifier is outside the valid range.";
598 case kInvalidManuId:
599 return "The MANU identifier is outside the valid range.";
600 case kInvalidChannelAddress:
601 return "The MANU channel address is outside the valid range.";
602 case kInvalidSignal:
603 return "The ADC signal value is outside the valid range.";
604 case kDataWordDifferent:
605 return "The raw data word is different from the unpacked values.";
606 case kChiSquareInvalid:
607 return "The chi squared value must be a positive value or -1"
608 " indicating a fitting error.";
609 case kMomentumVectorNotZero:
610 return "The chi sqaured value is set to -1 indicating momentum"
611 " was not fitted, but the momentum vector was not zero.";
612 case kRoiRadiusInvalid:
613 return "The region of interest radius is invalid.";
614 case kHitNotWithinRoi:
615 return "A tracks hit is not within the corresponding region"
616 " of interest.";
878cb83d 617 case kPtValueNotValid:
dba14d7d 618 return "The pT value is not positive, nor -1 indicating an"
619 " invalid value.";
878cb83d 620 case kPairTrackIdsAreIdentical:
621 return "The track identifiers of the track pair are identical.";
622 case kMassValueNotValid:
dba14d7d 623 return "The invariant mass value is not positive, nor -1"
624 " indicating an invalid value.";
878cb83d 625 case kLowPtCountInvalid:
dba14d7d 626 return "The low pT trigger count is greater than 2,"
627 " which is invalid.";
878cb83d 628 case kHighPtCountInvalid:
dba14d7d 629 return "The high pT trigger count is greater than 2,"
630 " which is invalid.";
631 case kFoundDuplicateIDs:
632 return "Found duplicate data record identifiers, but they"
633 " should all be unique.";
634 case kFoundDuplicateHits:
635 return "Found duplicate hit structures, but they should all"
636 " be unique.";
637 case kFoundDuplicateTriggers:
638 return "Found duplicate trigger decisions.";
878cb83d 639 default:
640 return "UNKNOWN REASON CODE";
641 }
642}
643
644
dba14d7d 645bool AliHLTMUONUtils::RecordNumberWasSet(WhyNotValid reason)
646{
647 /// Returns true if the \em recordNum in the corresponding IntegrityOk method
648 /// would have been set, if it returned false and a reason was set.
649 /// This helper method makes it easy to test if the \em recordNum parameter
650 /// is filled with a valid value or not.
651 /// \param reason The reason code as returned by the IntegrityOk method.
652 /// \returns true if the \em recordNum parameter was set for the given
653 /// reason code.
654
655 switch (reason)
656 {
657 case kInvalidIdValue:
658 case kInvalidTriggerIdValue:
659 case kInvalidTrackIdValue:
660 case kReservedBitsNotZero:
661 case kParticleSignBitsNotValid:
662 case kHitNotMarkedAsNil:
663 case kInvalidDetElementNumber:
a090ff22 664 case kInvalidChamberNumber:
dba14d7d 665 case kHitIsNil:
66622a82 666 case kInvalidChannelCountB:
667 case kInvalidChannelCountNB:
668 case kInvalidChargeB:
669 case kInvalidChargeNB:
dba14d7d 670 case kInvalidBusPatchId:
671 case kInvalidManuId:
672 case kInvalidChannelAddress:
673 case kInvalidSignal:
674 case kDataWordDifferent:
675 case kChiSquareInvalid:
676 case kPtValueNotValid:
677 case kPairTrackIdsAreIdentical:
678 case kMassValueNotValid:
679 case kLowPtCountInvalid:
680 case kHighPtCountInvalid:
681 return true;
682 default: return false;
683 }
684}
685
686
698c9498 687bool AliHLTMUONUtils::HeaderOk(
688 const AliHLTMUONTriggerRecordsBlockStruct& block,
dba14d7d 689 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
698c9498 690 )
b727f838 691{
878cb83d 692 /// Method used to check if the header information corresponds to the
693 /// supposed type of the raw dHLT data block.
694 /// [in] \param block The data block to check.
dba14d7d 695 /// [out] \param reason If this is not NULL, then it is assumed to point
696 /// to an array of at least 'reasonCount' number of elements. It will
697 /// be filled with the reason codes describing why the header is not
698 /// valid.
699 /// [in/out] \param reasonCount This should initially specify the size of
700 /// the array pointed to by 'reason'. It will be filled with the number
701 /// of items actually filled into the reason array upon exit from this
702 /// method.
878cb83d 703 /// \returns true if there is no problem with the header and false otherwise.
dba14d7d 704
705 AliHLTUInt32_t maxCount = reasonCount;
706 reasonCount = 0;
707 bool result = true;
708
b727f838 709 // The block must have the correct type.
698c9498 710 if (block.fHeader.fType != kTriggerRecordsDataBlock)
711 {
dba14d7d 712 if (reason != NULL and reasonCount < maxCount)
713 {
714 reason[reasonCount] = kHeaderContainsWrongType;
715 reasonCount++;
716 }
717 result = false;
698c9498 718 }
719
90a74d7a 720 // The block's record width must be the correct size.
b727f838 721 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTriggerRecordStruct))
698c9498 722 {
dba14d7d 723 if (reason != NULL and reasonCount < maxCount)
724 {
725 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
726 reasonCount++;
727 }
728 result = false;
698c9498 729 }
730
dba14d7d 731 return result;
b727f838 732}
26a4668d 733
90a74d7a 734
878cb83d 735bool AliHLTMUONUtils::HeaderOk(
736 const AliHLTMUONTrigRecsDebugBlockStruct& block,
dba14d7d 737 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 738 )
c8ec7c7e 739{
878cb83d 740 /// Method used to check if the header information corresponds to the
741 /// supposed type of the raw dHLT data block.
742 /// [in] \param block The data block to check.
dba14d7d 743 /// [out] \param reason If this is not NULL, then it is assumed to point
744 /// to an array of at least 'reasonCount' number of elements. It will
745 /// be filled with the reason codes describing why the header is not
746 /// valid.
747 /// [in/out] \param reasonCount This should initially specify the size of
748 /// the array pointed to by 'reason'. It will be filled with the number
749 /// of items actually filled into the reason array upon exit from this
750 /// method.
878cb83d 751 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 752
dba14d7d 753 AliHLTUInt32_t maxCount = reasonCount;
754 reasonCount = 0;
755 bool result = true;
756
c8ec7c7e 757 // The block must have the correct type.
878cb83d 758 if (block.fHeader.fType != kTrigRecsDebugDataBlock)
759 {
dba14d7d 760 if (reason != NULL and reasonCount < maxCount)
761 {
762 reason[reasonCount] = kHeaderContainsWrongType;
763 reasonCount++;
764 }
765 result = false;
878cb83d 766 }
767
90a74d7a 768 // The block's record width must be the correct size.
c8ec7c7e 769 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrigRecInfoStruct))
878cb83d 770 {
dba14d7d 771 if (reason != NULL and reasonCount < maxCount)
772 {
773 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
774 reasonCount++;
775 }
776 result = false;
878cb83d 777 }
778
dba14d7d 779 return result;
c8ec7c7e 780}
781
90a74d7a 782
878cb83d 783bool AliHLTMUONUtils::HeaderOk(
784 const AliHLTMUONRecHitsBlockStruct& block,
dba14d7d 785 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 786 )
b727f838 787{
878cb83d 788 /// Method used to check if the header information corresponds to the
789 /// supposed type of the raw dHLT data block.
790 /// [in] \param block The data block to check.
dba14d7d 791 /// [out] \param reason If this is not NULL, then it is assumed to point
792 /// to an array of at least 'reasonCount' number of elements. It will
793 /// be filled with the reason codes describing why the header is not
794 /// valid.
795 /// [in/out] \param reasonCount This should initially specify the size of
796 /// the array pointed to by 'reason'. It will be filled with the number
797 /// of items actually filled into the reason array upon exit from this
798 /// method.
878cb83d 799 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 800
dba14d7d 801 AliHLTUInt32_t maxCount = reasonCount;
802 reasonCount = 0;
803 bool result = true;
804
b727f838 805 // The block must have the correct type.
878cb83d 806 if (block.fHeader.fType != kRecHitsDataBlock)
807 {
dba14d7d 808 if (reason != NULL and reasonCount < maxCount)
809 {
810 reason[reasonCount] = kHeaderContainsWrongType;
811 reasonCount++;
812 }
813 result = false;
878cb83d 814 }
815
90a74d7a 816 // The block's record width must be the correct size.
b727f838 817 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONRecHitStruct))
878cb83d 818 {
dba14d7d 819 if (reason != NULL and reasonCount < maxCount)
820 {
821 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
822 reasonCount++;
823 }
824 result = false;
878cb83d 825 }
826
dba14d7d 827 return result;
b727f838 828}
26a4668d 829
90a74d7a 830
878cb83d 831bool AliHLTMUONUtils::HeaderOk(
832 const AliHLTMUONClustersBlockStruct& block,
dba14d7d 833 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 834 )
b727f838 835{
878cb83d 836 /// Method used to check if the header information corresponds to the
837 /// supposed type of the raw dHLT data block.
838 /// [in] \param block The data block to check.
dba14d7d 839 /// [out] \param reason If this is not NULL, then it is assumed to point
840 /// to an array of at least 'reasonCount' number of elements. It will
841 /// be filled with the reason codes describing why the header is not
842 /// valid.
843 /// [in/out] \param reasonCount This should initially specify the size of
844 /// the array pointed to by 'reason'. It will be filled with the number
845 /// of items actually filled into the reason array upon exit from this
846 /// method.
878cb83d 847 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 848
dba14d7d 849 AliHLTUInt32_t maxCount = reasonCount;
850 reasonCount = 0;
851 bool result = true;
852
b727f838 853 // The block must have the correct type.
878cb83d 854 if (block.fHeader.fType != kClustersDataBlock)
855 {
dba14d7d 856 if (reason != NULL and reasonCount < maxCount)
857 {
858 reason[reasonCount] = kHeaderContainsWrongType;
859 reasonCount++;
860 }
861 result = false;
878cb83d 862 }
863
90a74d7a 864 // The block's record width must be the correct size.
b727f838 865 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONClusterStruct))
878cb83d 866 {
dba14d7d 867 if (reason != NULL and reasonCount < maxCount)
868 {
869 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
870 reasonCount++;
871 }
872 result = false;
878cb83d 873 }
874
dba14d7d 875 return result;
b727f838 876}
26a4668d 877
90a74d7a 878
878cb83d 879bool AliHLTMUONUtils::HeaderOk(
880 const AliHLTMUONChannelsBlockStruct& block,
dba14d7d 881 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 882 )
b727f838 883{
878cb83d 884 /// Method used to check if the header information corresponds to the
885 /// supposed type of the raw dHLT data block.
886 /// [in] \param block The data block to check.
dba14d7d 887 /// [out] \param reason If this is not NULL, then it is assumed to point
888 /// to an array of at least 'reasonCount' number of elements. It will
889 /// be filled with the reason codes describing why the header is not
890 /// valid.
891 /// [in/out] \param reasonCount This should initially specify the size of
892 /// the array pointed to by 'reason'. It will be filled with the number
893 /// of items actually filled into the reason array upon exit from this
894 /// method.
878cb83d 895 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 896
dba14d7d 897 AliHLTUInt32_t maxCount = reasonCount;
898 reasonCount = 0;
899 bool result = true;
900
b727f838 901 // The block must have the correct type.
878cb83d 902 if (block.fHeader.fType != kChannelsDataBlock)
903 {
dba14d7d 904 if (reason != NULL and reasonCount < maxCount)
905 {
906 reason[reasonCount] = kHeaderContainsWrongType;
907 reasonCount++;
908 }
909 result = false;
878cb83d 910 }
911
90a74d7a 912 // The block's record width must be the correct size.
b727f838 913 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONChannelStruct))
878cb83d 914 {
dba14d7d 915 if (reason != NULL and reasonCount < maxCount)
916 {
917 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
918 reasonCount++;
919 }
920 result = false;
878cb83d 921 }
922
dba14d7d 923 return result;
b727f838 924}
925
926
878cb83d 927bool AliHLTMUONUtils::HeaderOk(
928 const AliHLTMUONMansoTracksBlockStruct& block,
dba14d7d 929 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 930 )
90a74d7a 931{
878cb83d 932 /// Method used to check if the header information corresponds to the
933 /// supposed type of the raw dHLT data block.
934 /// [in] \param block The data block to check.
dba14d7d 935 /// [out] \param reason If this is not NULL, then it is assumed to point
936 /// to an array of at least 'reasonCount' number of elements. It will
937 /// be filled with the reason codes describing why the header is not
938 /// valid.
939 /// [in/out] \param reasonCount This should initially specify the size of
940 /// the array pointed to by 'reason'. It will be filled with the number
941 /// of items actually filled into the reason array upon exit from this
942 /// method.
878cb83d 943 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 944
dba14d7d 945 AliHLTUInt32_t maxCount = reasonCount;
946 reasonCount = 0;
947 bool result = true;
948
90a74d7a 949 // The block must have the correct type.
878cb83d 950 if (block.fHeader.fType != kMansoTracksDataBlock)
951 {
dba14d7d 952 if (reason != NULL and reasonCount < maxCount)
953 {
954 reason[reasonCount] = kHeaderContainsWrongType;
955 reasonCount++;
956 }
957 result = false;
878cb83d 958 }
959
90a74d7a 960 // The block's record width must be the correct size.
961 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONMansoTrackStruct))
878cb83d 962 {
dba14d7d 963 if (reason != NULL and reasonCount < maxCount)
964 {
965 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
966 reasonCount++;
967 }
968 result = false;
878cb83d 969 }
970
dba14d7d 971 return result;
90a74d7a 972}
973
974
878cb83d 975bool AliHLTMUONUtils::HeaderOk(
976 const AliHLTMUONMansoCandidatesBlockStruct& block,
dba14d7d 977 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 978 )
90a74d7a 979{
878cb83d 980 /// Method used to check if the header information corresponds to the
981 /// supposed type of the raw dHLT data block.
982 /// [in] \param block The data block to check.
dba14d7d 983 /// [out] \param reason If this is not NULL, then it is assumed to point
984 /// to an array of at least 'reasonCount' number of elements. It will
985 /// be filled with the reason codes describing why the header is not
986 /// valid.
987 /// [in/out] \param reasonCount This should initially specify the size of
988 /// the array pointed to by 'reason'. It will be filled with the number
989 /// of items actually filled into the reason array upon exit from this
990 /// method.
878cb83d 991 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 992
dba14d7d 993 AliHLTUInt32_t maxCount = reasonCount;
994 reasonCount = 0;
995 bool result = true;
996
90a74d7a 997 // The block must have the correct type.
878cb83d 998 if (block.fHeader.fType != kMansoCandidatesDataBlock)
999 {
dba14d7d 1000 if (reason != NULL and reasonCount < maxCount)
1001 {
1002 reason[reasonCount] = kHeaderContainsWrongType;
1003 reasonCount++;
1004 }
1005 result = false;
878cb83d 1006 }
1007
90a74d7a 1008 // The block's record width must be the correct size.
1009 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONMansoCandidateStruct))
878cb83d 1010 {
dba14d7d 1011 if (reason != NULL and reasonCount < maxCount)
1012 {
1013 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1014 reasonCount++;
1015 }
1016 result = false;
878cb83d 1017 }
1018
dba14d7d 1019 return result;
90a74d7a 1020}
1021
1022
878cb83d 1023bool AliHLTMUONUtils::HeaderOk(
1024 const AliHLTMUONSinglesDecisionBlockStruct& block,
dba14d7d 1025 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 1026 )
90a74d7a 1027{
878cb83d 1028 /// Method used to check if the header information corresponds to the
1029 /// supposed type of the raw dHLT data block.
1030 /// [in] \param block The data block to check.
dba14d7d 1031 /// [out] \param reason If this is not NULL, then it is assumed to point
1032 /// to an array of at least 'reasonCount' number of elements. It will
1033 /// be filled with the reason codes describing why the header is not
1034 /// valid.
1035 /// [in/out] \param reasonCount This should initially specify the size of
1036 /// the array pointed to by 'reason'. It will be filled with the number
1037 /// of items actually filled into the reason array upon exit from this
1038 /// method.
878cb83d 1039 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 1040
dba14d7d 1041 AliHLTUInt32_t maxCount = reasonCount;
1042 reasonCount = 0;
1043 bool result = true;
1044
90a74d7a 1045 // The block must have the correct type.
878cb83d 1046 if (block.fHeader.fType != kSinglesDecisionDataBlock)
1047 {
dba14d7d 1048 if (reason != NULL and reasonCount < maxCount)
1049 {
1050 reason[reasonCount] = kHeaderContainsWrongType;
1051 reasonCount++;
1052 }
1053 result = false;
878cb83d 1054 }
1055
90a74d7a 1056 // The block's record width must be the correct size.
1057 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrackDecisionStruct))
878cb83d 1058 {
dba14d7d 1059 if (reason != NULL and reasonCount < maxCount)
1060 {
1061 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1062 reasonCount++;
1063 }
1064 result = false;
878cb83d 1065 }
1066
dba14d7d 1067 return result;
90a74d7a 1068}
1069
1070
878cb83d 1071bool AliHLTMUONUtils::HeaderOk(
1072 const AliHLTMUONPairsDecisionBlockStruct& block,
dba14d7d 1073 WhyNotValid* reason, AliHLTUInt32_t& reasonCount
878cb83d 1074 )
90a74d7a 1075{
878cb83d 1076 /// Method used to check if the header information corresponds to the
1077 /// supposed type of the raw dHLT data block.
1078 /// [in] \param block The data block to check.
dba14d7d 1079 /// [out] \param reason If this is not NULL, then it is assumed to point
1080 /// to an array of at least 'reasonCount' number of elements. It will
1081 /// be filled with the reason codes describing why the header is not
1082 /// valid.
1083 /// [in/out] \param reasonCount This should initially specify the size of
1084 /// the array pointed to by 'reason'. It will be filled with the number
1085 /// of items actually filled into the reason array upon exit from this
1086 /// method.
878cb83d 1087 /// \returns true if there is no problem with the header and false otherwise.
6253e09b 1088
dba14d7d 1089 AliHLTUInt32_t maxCount = reasonCount;
1090 reasonCount = 0;
1091 bool result = true;
1092
90a74d7a 1093 // The block must have the correct type.
878cb83d 1094 if (block.fHeader.fType != kPairsDecisionDataBlock)
1095 {
dba14d7d 1096 if (reason != NULL and reasonCount < maxCount)
1097 {
1098 reason[reasonCount] = kHeaderContainsWrongType;
1099 reasonCount++;
1100 }
1101 result = false;
878cb83d 1102 }
1103
90a74d7a 1104 // The block's record width must be the correct size.
1105 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONPairDecisionStruct))
878cb83d 1106 {
dba14d7d 1107 if (reason != NULL and reasonCount < maxCount)
1108 {
1109 reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1110 reasonCount++;
1111 }
1112 result = false;
878cb83d 1113 }
1114
dba14d7d 1115 return result;
90a74d7a 1116}
1117
1118
878cb83d 1119bool AliHLTMUONUtils::IntegrityOk(
1120 const AliHLTMUONTriggerRecordStruct& tr,
dba14d7d 1121 WhyNotValid* reason,
1122 AliHLTUInt32_t& reasonCount
878cb83d 1123 )
90a74d7a 1124{
878cb83d 1125 /// This method is used to check more extensively if the integrity of the
1126 /// trigger record structure is OK and returns true in that case.
1127 /// [in] \param tr The trigger record structure to check.
dba14d7d 1128 /// [out] \param reason If this is not NULL, then it is assumed to point
1129 /// to an array of at least 'reasonCount' number of elements. It will
1130 /// be filled with the reason codes describing why the structure is
1131 /// not valid.
1132 /// [in/out] \param reasonCount This should initially specify the size of
1133 /// the array pointed to by 'reason'. It will be filled with the number
1134 /// of items actually filled into the reason array upon exit from this
1135 /// method.
878cb83d 1136 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 1137
dba14d7d 1138 AliHLTUInt32_t maxCount = reasonCount;
1139 reasonCount = 0;
1140 bool result = true;
1141
1142 // Check that the ID has a valid value.
1143 if (not (tr.fId >= 0 or tr.fId == -1))
1144 {
1145 if (reason != NULL and reasonCount < maxCount)
1146 {
1147 reason[reasonCount] = kInvalidIdValue;
1148 reasonCount++;
1149 }
1150 result = false;
1151 }
1152
90a74d7a 1153 // Make sure that the reserved bits in the fFlags field are set
1154 // to zero.
878cb83d 1155 if ((tr.fFlags & 0x3FFFFFF0) != 0)
1156 {
dba14d7d 1157 if (reason != NULL and reasonCount < maxCount)
1158 {
1159 reason[reasonCount] = kReservedBitsNotZero;
1160 reasonCount++;
1161 }
1162 result = false;
878cb83d 1163 }
90a74d7a 1164
1165 // Make sure the sign is not invalid.
878cb83d 1166 if ((tr.fFlags & 0xC0000000) == 0xC0000000)
1167 {
dba14d7d 1168 if (reason != NULL and reasonCount < maxCount)
1169 {
1170 reason[reasonCount] = kParticleSignBitsNotValid;
1171 reasonCount++;
1172 }
1173 result = false;
878cb83d 1174 }
90a74d7a 1175
1176 // Check that fHit[i] is nil if the corresponding bit in the
1177 // flags word is zero.
1178 const AliHLTMUONRecHitStruct& nilhit
1179 = AliHLTMUONConstants::NilRecHitStruct();
878cb83d 1180 if ( ((tr.fFlags & 0x1) == 0 and tr.fHit[0] != nilhit) or
1181 ((tr.fFlags & 0x2) == 0 and tr.fHit[1] != nilhit) or
1182 ((tr.fFlags & 0x4) == 0 and tr.fHit[2] != nilhit) or
1183 ((tr.fFlags & 0x8) == 0 and tr.fHit[3] != nilhit)
1184 )
1185 {
dba14d7d 1186 if (reason != NULL and reasonCount < maxCount)
1187 {
1188 reason[reasonCount] = kHitNotMarkedAsNil;
1189 reasonCount++;
1190 }
1191 result = false;
878cb83d 1192 }
a090ff22 1193
1194 // Check the individual hits
1195 for (int i = 0; i < 4; i++)
1196 {
1197 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1198 if (not IntegrityOk(tr.fHit[i], reason + reasonCount, filledCount))
1199 {
1200 reasonCount += filledCount;
1201 result = false;
1202 }
1203 }
90a74d7a 1204
dba14d7d 1205 return result;
90a74d7a 1206}
1207
1208
878cb83d 1209bool AliHLTMUONUtils::IntegrityOk(
1210 const AliHLTMUONTriggerRecordsBlockStruct& block,
1211 WhyNotValid* reason,
dba14d7d 1212 AliHLTUInt32_t* recordNum,
1213 AliHLTUInt32_t& reasonCount
878cb83d 1214 )
b727f838 1215{
878cb83d 1216 /// This method is used to check more extensively if the integrity of the
1217 /// dHLT raw internal data block is OK and returns true in that case.
1218 /// [in] \param block The trigger record data block to check.
dba14d7d 1219 /// [out] \param reason If this is not NULL, then it is assumed to point
1220 /// to an array of at least 'reasonCount' number of elements. It will
1221 /// be filled with the reason codes describing why the data block is
1222 /// not valid.
1223 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1224 /// to an array of at least 'reasonCount' number of elements. It will
1225 /// be filled with the number of the trigger record that had a problem.
1226 /// The value 'recordNum[i]' will only contain a valid value if
1227 /// the corresponding 'reason[i]' contains one of:
1228 /// - kInvalidIdValue
878cb83d 1229 /// - kReservedBitsNotZero
1230 /// - kParticleSignBitsNotValid
1231 /// - kHitNotMarkedAsNil
a090ff22 1232 /// - kInvalidDetElementNumber
1233 /// - kInvalidChamberNumber
dba14d7d 1234 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1235 /// was set and is valid or not.
1236 /// [in/out] \param reasonCount This should initially specify the size of
1237 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1238 /// with the number of items actually filled into the arrays upon exit
1239 /// from this method.
878cb83d 1240 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1241
dba14d7d 1242 AliHLTUInt32_t maxCount = reasonCount;
1243 bool result = HeaderOk(block, reason, reasonCount);
23ad6161 1244
1245 const AliHLTMUONTriggerRecordStruct* triggerRecord =
1246 reinterpret_cast<const AliHLTMUONTriggerRecordStruct*>(&block + 1);
26a4668d 1247
b727f838 1248 // Check if any ID is duplicated.
1249 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1250 {
23ad6161 1251 AliHLTInt32_t id = triggerRecord[i].fId;
dba14d7d 1252 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
b727f838 1253 {
23ad6161 1254 if (id == triggerRecord[j].fId)
878cb83d 1255 {
dba14d7d 1256 if (reason != NULL and reasonCount < maxCount)
1257 {
1258 reason[reasonCount] = kFoundDuplicateIDs;
1259 reasonCount++;
1260 }
1261 result = false;
878cb83d 1262 }
b727f838 1263 }
1264 }
1265
90a74d7a 1266 // Check integrity of individual trigger records.
b727f838 1267 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1268 {
dba14d7d 1269 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1270 if (not IntegrityOk(triggerRecord[i], reason+reasonCount, filledCount))
878cb83d 1271 {
dba14d7d 1272 // reasons filled in IntegrityOk, now we just need to adjust
1273 // reasonCount and fill the recordNum values.
1274 if (recordNum != NULL)
1275 {
1276 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1277 recordNum[reasonCount + n] = i;
1278 }
1279 reasonCount += filledCount;
1280 result = false;
878cb83d 1281 }
b727f838 1282 }
1283
dba14d7d 1284 return result;
1285}
1286
1287
1288bool AliHLTMUONUtils::IntegrityOk(
1289 const AliHLTMUONTrigRecInfoStruct& trigInfo,
1290 WhyNotValid* reason,
1291 AliHLTUInt32_t& reasonCount
1292 )
1293{
1294 /// This method is used to check more extensively if the integrity of the
1295 /// trigger record debug information structure is OK and returns true in that case.
1296 /// [in] \param trigInfo The trigger record debug information structure to check.
1297 /// [out] \param reason If this is not NULL, then it is assumed to point
1298 /// to an array of at least 'reasonCount' number of elements. It will
1299 /// be filled with the reason codes describing why the structure is not
1300 /// valid.
1301 /// [in/out] \param reasonCount This should initially specify the size of
1302 /// the array pointed to by 'reason'. It will be filled with the number
1303 /// of items actually filled into the reason array upon exit from this
1304 /// method.
1305 /// \returns true if there is no problem with the structure and false otherwise.
1306
1307 AliHLTUInt32_t maxCount = reasonCount;
1308 reasonCount = 0;
1309 bool result = true;
1310
1311 // Check that the trigger ID has a valid value.
1312 if (not (trigInfo.fTrigRecId >= 0 or trigInfo.fTrigRecId == -1))
1313 {
1314 if (reason != NULL and reasonCount < maxCount)
1315 {
1316 reason[reasonCount] = kInvalidIdValue;
1317 reasonCount++;
1318 }
1319 result = false;
1320 }
1321
1322 // Check that the fDetElemId[i] numbers are valid.
a090ff22 1323 if ( not ((trigInfo.fDetElemId[0] >= 100 and trigInfo.fDetElemId[0] < 1500)
1324 or trigInfo.fDetElemId[0] == -1)
1325 or not ((trigInfo.fDetElemId[1] >= 100 and trigInfo.fDetElemId[1] < 1500)
1326 or trigInfo.fDetElemId[1] == -1)
1327 or not ((trigInfo.fDetElemId[2] >= 100 and trigInfo.fDetElemId[2] < 1500)
1328 or trigInfo.fDetElemId[2] == -1)
1329 or not ((trigInfo.fDetElemId[3] >= 100 and trigInfo.fDetElemId[3] < 1500)
1330 or trigInfo.fDetElemId[3] == -1)
dba14d7d 1331 )
1332 {
1333 if (reason != NULL and reasonCount < maxCount)
1334 {
1335 reason[reasonCount] = kInvalidDetElementNumber;
1336 reasonCount++;
1337 }
1338 result = false;
1339 }
1340
1341 return result;
b727f838 1342}
1343
90a74d7a 1344
878cb83d 1345bool AliHLTMUONUtils::IntegrityOk(
1346 const AliHLTMUONTrigRecsDebugBlockStruct& block,
dba14d7d 1347 WhyNotValid* reason,
1348 AliHLTUInt32_t* recordNum,
1349 AliHLTUInt32_t& reasonCount
878cb83d 1350 )
c8ec7c7e 1351{
878cb83d 1352 /// This method is used to check more extensively if the integrity of the
1353 /// dHLT raw internal data block is OK and returns true in that case.
dba14d7d 1354 /// [in] \param block The trigger record debugging information data block
1355 /// to check.
1356 /// [out] \param reason If this is not NULL, then it is assumed to point
1357 /// to an array of at least 'reasonCount' number of elements. It will
1358 /// be filled with the reason codes describing why the data block is
1359 /// not valid.
1360 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1361 /// to an array of at least 'reasonCount' number of elements. It will
1362 /// be filled with the number of the trigger record debug information
1363 /// structure that had a problem.
1364 /// The value 'recordNum[i]' will only contain a valid value if
1365 /// the corresponding 'reason[i]' contains one of:
1366 /// - kInvalidIdValue
1367 /// - kInvalidDetElementNumber
1368 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1369 /// was set and is valid or not.
1370 /// [in/out] \param reasonCount This should initially specify the size of
1371 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1372 /// with the number of items actually filled into the arrays upon exit
1373 /// from this method.
878cb83d 1374 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1375
dba14d7d 1376 AliHLTUInt32_t maxCount = reasonCount;
1377 bool result = HeaderOk(block, reason, reasonCount);
1378
1379 const AliHLTMUONTrigRecInfoStruct* triggerInfo =
1380 reinterpret_cast<const AliHLTMUONTrigRecInfoStruct*>(&block + 1);
1381
1382 // Check if any trigger debug info structure has duplicated trigger IDs.
1383 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1384 {
1385 AliHLTInt32_t id = triggerInfo[i].fTrigRecId;
1386 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1387 {
1388 if (id == triggerInfo[j].fTrigRecId)
1389 {
1390 if (reason != NULL and reasonCount < maxCount)
1391 {
1392 reason[reasonCount] = kFoundDuplicateIDs;
1393 reasonCount++;
1394 }
1395 result = false;
1396 }
1397 }
1398 }
1399
1400 // Check integrity of individual trigger records.
1401 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1402 {
1403 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1404 if (not IntegrityOk(triggerInfo[i], reason+reasonCount, filledCount))
1405 {
1406 // reasons filled in IntegrityOk, now we just need to adjust
1407 // reasonCount and fill the recordNum values.
1408 if (recordNum != NULL)
1409 {
1410 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1411 recordNum[reasonCount + n] = i;
1412 }
1413 reasonCount += filledCount;
1414 result = false;
1415 }
1416 }
1417
1418 return result;
c8ec7c7e 1419}
1420
90a74d7a 1421
878cb83d 1422bool AliHLTMUONUtils::IntegrityOk(
a090ff22 1423 const AliHLTMUONRecHitStruct& hit,
1424 WhyNotValid* reason,
1425 AliHLTUInt32_t& reasonCount
878cb83d 1426 )
c8ec7c7e 1427{
878cb83d 1428 /// This method is used to check more extensively if the integrity of the
a090ff22 1429 /// reconstructed hit structure is OK and returns true in that case.
1430 /// [in] \param hit The reconstructed hit structure to check.
1431 /// [out] \param reason If this is not NULL, then it is assumed to point
1432 /// to an array of at least 'reasonCount' number of elements. It will
1433 /// be filled with the reason codes describing why the structure is
1434 /// not valid.
1435 /// [in/out] \param reasonCount This should initially specify the size of
1436 /// the array pointed to by 'reason'. It will be filled with the number
1437 /// of items actually filled into the reason array upon exit from this
1438 /// method.
1439 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 1440
a090ff22 1441 AliHLTUInt32_t maxCount = reasonCount;
1442 reasonCount = 0;
1443 bool result = true;
1444
1445 // If this is a NIL hit then skip all other checks.
1446 if (hit == AliHLTMUONConstants::NilRecHitStruct())
1447 {
1448 return true;
1449 }
1450
1451 // Make sure that the reserved bits in the fFlags field are set
1452 // to zero.
1453 if ((hit.fFlags & 0x3FFF0000) != 0)
1454 {
1455 if (reason != NULL and reasonCount < maxCount)
1456 {
1457 reason[reasonCount] = kReservedBitsNotZero;
1458 reasonCount++;
1459 }
1460 result = false;
1461 }
1462
1463 AliHLTUInt32_t detElemId = hit.fFlags & 0x00000FFF;
1464 AliHLTUInt32_t chamber = (hit.fFlags & 0x0000F000) >> 12;
1465
1466 // Make sure the detector element ID number is valid.
1467 if (not (detElemId >= 100 and detElemId < 1500))
1468 {
1469 if (reason != NULL and reasonCount < maxCount)
1470 {
1471 reason[reasonCount] = kInvalidDetElementNumber;
1472 reasonCount++;
1473 }
1474 result = false;
1475 }
1476
1477 // Make sure the chamber number is valid.
1478 if (((detElemId / 100) - 1) != chamber or chamber >= 14)
1479 {
1480 if (reason != NULL and reasonCount < maxCount)
1481 {
1482 reason[reasonCount] = kInvalidChamberNumber;
1483 reasonCount++;
1484 }
1485 result = false;
1486 }
1487
1488 return result;
c8ec7c7e 1489}
b727f838 1490
90a74d7a 1491
878cb83d 1492bool AliHLTMUONUtils::IntegrityOk(
1493 const AliHLTMUONRecHitsBlockStruct& block,
dba14d7d 1494 WhyNotValid* reason,
a090ff22 1495 AliHLTUInt32_t* recordNum,
dba14d7d 1496 AliHLTUInt32_t& reasonCount
878cb83d 1497 )
b727f838 1498{
878cb83d 1499 /// This method is used to check more extensively if the integrity of the
a090ff22 1500 /// dHLT raw internal hits data block is OK and returns true in that case.
878cb83d 1501 /// [in] \param block The reconstructed hits data block to check.
dba14d7d 1502 /// [out] \param reason If this is not NULL, then it is assumed to point
1503 /// to an array of at least 'reasonCount' number of elements. It will
1504 /// be filled with the reason codes describing why the data block is
1505 /// not valid.
a090ff22 1506 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1507 /// to an array of at least 'reasonCount' number of elements. It will
1508 /// be filled with the number of the reconstructed hits that had a problem.
1509 /// The value 'recordNum[i]' will only contain a valid value if
1510 /// the corresponding 'reason[i]' contains one of:
1511 /// - kReservedBitsNotZero
1512 /// - kInvalidDetElementNumber
1513 /// - kInvalidChamberNumber
1514 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1515 /// was set and is valid or not.
dba14d7d 1516 /// [in/out] \param reasonCount This should initially specify the size of
a090ff22 1517 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1518 /// with the number of items actually filled into the arrays upon exit
1519 /// from this method.
878cb83d 1520 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1521
dba14d7d 1522 AliHLTUInt32_t maxCount = reasonCount;
1523 bool result = HeaderOk(block, reason, reasonCount);
1524
1525 const AliHLTMUONRecHitStruct* hit =
1526 reinterpret_cast<const AliHLTMUONRecHitStruct*>(&block + 1);
1527
1528 // Check if any hit structure has been duplicated.
1529 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1530 {
1531 const AliHLTMUONRecHitStruct& h = hit[i];
1532 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1533 {
1534 if (h == hit[j])
1535 {
1536 if (reason != NULL and reasonCount < maxCount)
1537 {
1538 reason[reasonCount] = kFoundDuplicateHits;
1539 reasonCount++;
1540 }
1541 result = false;
1542 }
1543 }
1544 }
a090ff22 1545
1546 // Check integrity of the individual hit structures.
1547 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1548 {
1549 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1550 if (not IntegrityOk(hit[i], reason+reasonCount, filledCount))
1551 {
1552 // reasons filled in IntegrityOk, now we just need to adjust
1553 // reasonCount and fill the recordNum values.
1554 if (recordNum != NULL)
1555 {
1556 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1557 recordNum[reasonCount + n] = i;
1558 }
1559 reasonCount += filledCount;
1560 result = false;
1561 }
1562 }
dba14d7d 1563
1564 return result;
1565}
1566
1567
1568bool AliHLTMUONUtils::IntegrityOk(
1569 const AliHLTMUONClusterStruct& cluster,
1570 WhyNotValid* reason,
1571 AliHLTUInt32_t& reasonCount
1572 )
1573{
1574 /// This method is used to check more extensively if the integrity of the
1575 /// cluster structure is OK and returns true in that case.
1576 /// [in] \param cluster The cluster structure to check.
1577 /// [out] \param reason If this is not NULL, then it is assumed to point
1578 /// to an array of at least 'reasonCount' number of elements. It will
1579 /// be filled with the reason codes describing why the structure is
1580 /// not valid.
1581 /// [in/out] \param reasonCount This should initially specify the size of
1582 /// the array pointed to by 'reason'. It will be filled with the number
1583 /// of items actually filled into the reason array upon exit from this
1584 /// method.
1585 /// \returns true if there is no problem with the structure and false otherwise.
1586
1587 AliHLTUInt32_t maxCount = reasonCount;
1588 reasonCount = 0;
1589 bool result = true;
1590
1591 // Check that the cluster ID has a valid value.
1592 if (not (cluster.fId >= 0 or cluster.fId == -1))
1593 {
1594 if (reason != NULL and reasonCount < maxCount)
1595 {
1596 reason[reasonCount] = kInvalidIdValue;
1597 reasonCount++;
1598 }
1599 result = false;
1600 }
1601
1602 // Check that the cluster does not have a nil value for its hit.
1603 if (cluster.fHit == AliHLTMUONConstants::NilRecHitStruct())
1604 {
1605 if (reason != NULL and reasonCount < maxCount)
1606 {
1607 reason[reasonCount] = kHitIsNil;
1608 reasonCount++;
1609 }
1610 result = false;
1611 }
1612
1613 // Make sure the detector element is a valid value.
a090ff22 1614 if (not ((cluster.fDetElemId >= 100 and cluster.fDetElemId < 1500)
1615 or cluster.fDetElemId == -1)
1616 )
dba14d7d 1617 {
1618 if (reason != NULL and reasonCount < maxCount)
1619 {
1620 reason[reasonCount] = kInvalidDetElementNumber;
1621 reasonCount++;
1622 }
1623 result = false;
1624 }
1625
1626 // The number of channels should be in a reasonable range.
59c42973 1627 // Using a value of 5*5*2, 5 pads by 5 pads by 2 cathode planes.
1628 if (int(cluster.fNchannelsB) < 1 or (5*5*2) < int(cluster.fNchannelsB))
dba14d7d 1629 {
1630 if (reason != NULL and reasonCount < maxCount)
1631 {
66622a82 1632 reason[reasonCount] = kInvalidChannelCountB;
dba14d7d 1633 reasonCount++;
1634 }
1635 result = false;
1636 }
59c42973 1637 if (int(cluster.fNchannelsNB) < 1 or (5*5*2) < int(cluster.fNchannelsNB))
66622a82 1638 {
1639 if (reason != NULL and reasonCount < maxCount)
1640 {
1641 reason[reasonCount] = kInvalidChannelCountNB;
1642 reasonCount++;
1643 }
1644 result = false;
1645 }
1646
83d66053 1647
66622a82 1648 // The charge values must be a positive value or -1.
1649 if (not (cluster.fChargeB >= 0 or cluster.fChargeB == -1))
1650 {
1651 if (reason != NULL and reasonCount < maxCount)
1652 {
1653 reason[reasonCount] = kInvalidChargeB;
1654 reasonCount++;
1655 }
1656 result = false;
1657 }
1658 if (not (cluster.fChargeNB >= 0 or cluster.fChargeNB == -1))
83d66053 1659 {
1660 if (reason != NULL and reasonCount < maxCount)
1661 {
66622a82 1662 reason[reasonCount] = kInvalidChargeNB;
83d66053 1663 reasonCount++;
1664 }
1665 result = false;
1666 }
dba14d7d 1667
1668 return result;
b727f838 1669}
1670
1671
878cb83d 1672bool AliHLTMUONUtils::IntegrityOk(
1673 const AliHLTMUONClustersBlockStruct& block,
dba14d7d 1674 WhyNotValid* reason,
1675 AliHLTUInt32_t* recordNum,
1676 AliHLTUInt32_t& reasonCount
878cb83d 1677 )
b727f838 1678{
878cb83d 1679 /// This method is used to check more extensively if the integrity of the
dba14d7d 1680 /// dHLT internal clusters data block is OK and returns true in that case.
878cb83d 1681 /// [in] \param block The clusters data block to check.
dba14d7d 1682 /// [out] \param reason If this is not NULL, then it is assumed to point
1683 /// to an array of at least 'reasonCount' number of elements. It will
1684 /// be filled with the reason codes describing why the data block is
1685 /// not valid.
1686 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1687 /// to an array of at least 'reasonCount' number of elements. It will
1688 /// be filled with the number of the cluster structure that had a problem.
1689 /// The value 'recordNum[i]' will only contain a valid value if
1690 /// the corresponding 'reason[i]' contains one of:
1691 /// - kInvalidIdValue
1692 /// - kHitIsNil
1693 /// - kInvalidDetElementNumber
66622a82 1694 /// - kInvalidChannelCountB
1695 /// - kInvalidChannelCountNB
1696 /// - kInvalidChargeB
1697 /// - kInvalidChargeNB
dba14d7d 1698 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1699 /// was set and is valid or not.
1700 /// [in/out] \param reasonCount This should initially specify the size of
1701 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1702 /// with the number of items actually filled into the arrays upon exit
1703 /// from this method.
878cb83d 1704 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1705
dba14d7d 1706 AliHLTUInt32_t maxCount = reasonCount;
1707 bool result = HeaderOk(block, reason, reasonCount);
b727f838 1708
23ad6161 1709 const AliHLTMUONClusterStruct* cluster =
1710 reinterpret_cast<const AliHLTMUONClusterStruct*>(&block + 1);
1711
c8ec7c7e 1712 // Check if any ID is duplicated.
1713 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1714 {
23ad6161 1715 AliHLTInt32_t id = cluster[i].fId;
dba14d7d 1716 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
c8ec7c7e 1717 {
23ad6161 1718 if (id == cluster[j].fId)
878cb83d 1719 {
dba14d7d 1720 if (reason != NULL and reasonCount < maxCount)
1721 {
1722 reason[reasonCount] = kFoundDuplicateIDs;
1723 reasonCount++;
1724 }
1725 result = false;
1726 }
1727 }
1728 }
1729
1730 // Check if any hit structure has been duplicated.
1731 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1732 {
1733 const AliHLTMUONRecHitStruct& h = cluster[i].fHit;
1734 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1735 {
1736 if (h == cluster[j].fHit)
1737 {
1738 if (reason != NULL and reasonCount < maxCount)
1739 {
1740 reason[reasonCount] = kFoundDuplicateHits;
1741 reasonCount++;
1742 }
1743 result = false;
1744 }
1745 }
1746 }
1747
1748 // Check integrity of individual cluster structures.
1749 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1750 {
1751 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1752 if (not IntegrityOk(cluster[i], reason+reasonCount, filledCount))
1753 {
1754 // reasons filled in IntegrityOk, now we just need to adjust
1755 // reasonCount and fill the recordNum values.
1756 if (recordNum != NULL)
1757 {
1758 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1759 recordNum[reasonCount + n] = i;
878cb83d 1760 }
dba14d7d 1761 reasonCount += filledCount;
1762 result = false;
c8ec7c7e 1763 }
1764 }
1765
dba14d7d 1766 return result;
1767}
1768
1769
1770bool AliHLTMUONUtils::IntegrityOk(
1771 const AliHLTMUONChannelStruct& channel,
1772 WhyNotValid* reason,
1773 AliHLTUInt32_t& reasonCount
1774 )
1775{
1776 /// This method is used to check more extensively if the integrity of the
1777 /// channel structure is OK and returns true in that case.
1778 /// [in] \param cluster The channel structure to check.
1779 /// [out] \param reason If this is not NULL, then it is assumed to point
1780 /// to an array of at least 'reasonCount' number of elements. It will
1781 /// be filled with the reason codes describing why the structure is
1782 /// not valid.
1783 /// [in/out] \param reasonCount This should initially specify the size of
1784 /// the array pointed to by 'reason'. It will be filled with the number
1785 /// of items actually filled into the reason array upon exit from this
1786 /// method.
1787 /// \returns true if there is no problem with the structure and false otherwise.
1788
1789 AliHLTUInt32_t maxCount = reasonCount;
1790 reasonCount = 0;
1791 bool result = true;
1792
1793 // Check that the channel ID has a valid value.
1794 if (not (channel.fClusterId >= 0 or channel.fClusterId == -1))
1795 {
1796 if (reason != NULL and reasonCount < maxCount)
1797 {
1798 reason[reasonCount] = kInvalidIdValue;
1799 reasonCount++;
1800 }
1801 result = false;
1802 }
1803
1804 // Check that the bus patch ID has a valid value, which fits into 12 bits.
1805 if ((channel.fBusPatch & (~0xFFF)) != 0)
1806 {
1807 if (reason != NULL and reasonCount < maxCount)
1808 {
1809 reason[reasonCount] = kInvalidBusPatchId;
1810 reasonCount++;
1811 }
1812 result = false;
1813 }
1814
1815 // Check that the MANU ID has a valid value, which fits into 11 bits.
1816 if ((channel.fManu & (~0x7FF)) != 0)
1817 {
1818 if (reason != NULL and reasonCount < maxCount)
1819 {
1820 reason[reasonCount] = kInvalidManuId;
1821 reasonCount++;
1822 }
1823 result = false;
1824 }
1825
1826 // Check that the channel address has a valid value, which fits into 6 bits.
1827 if ((channel.fChannelAddress & (~0x3F)) != 0)
1828 {
1829 if (reason != NULL and reasonCount < maxCount)
1830 {
1831 reason[reasonCount] = kInvalidChannelAddress;
1832 reasonCount++;
1833 }
1834 result = false;
1835 }
1836
1837 // Check that the ADC signal has a valid value, which fits into 12 bits.
1838 if ((channel.fSignal & (~0xFFF)) != 0)
1839 {
1840 if (reason != NULL and reasonCount < maxCount)
1841 {
1842 reason[reasonCount] = kInvalidSignal;
1843 reasonCount++;
1844 }
1845 result = false;
1846 }
1847
1848 // Check that the raw data word corresponds to the unpacked values for
1849 // the ADC signal, MANU ID and channel address.
1850 UShort_t manuId; UChar_t channelId; UShort_t adc;
1851 AliMUONTrackerDDLDecoderEventHandler::UnpackADC(
1852 channel.fRawDataWord, manuId, channelId, adc
1853 );
1854 if (manuId != channel.fManu or channelId != channel.fChannelAddress
1855 or adc != channel.fSignal
1856 )
1857 {
1858 if (reason != NULL and reasonCount < maxCount)
1859 {
1860 reason[reasonCount] = kDataWordDifferent;
1861 reasonCount++;
1862 }
1863 result = false;
1864 }
1865
1866 return result;
b727f838 1867}
1868
90a74d7a 1869
878cb83d 1870bool AliHLTMUONUtils::IntegrityOk(
1871 const AliHLTMUONChannelsBlockStruct& block,
dba14d7d 1872 WhyNotValid* reason,
1873 AliHLTUInt32_t* recordNum,
1874 AliHLTUInt32_t& reasonCount
878cb83d 1875 )
b727f838 1876{
878cb83d 1877 /// This method is used to check more extensively if the integrity of the
dba14d7d 1878 /// dHLT internal channels data block is OK and returns true in that case.
1879 /// [in] \param block The channels data block to check.
1880 /// [out] \param reason If this is not NULL, then it is assumed to point
1881 /// to an array of at least 'reasonCount' number of elements. It will
1882 /// be filled with the reason codes describing why the data block is
1883 /// not valid.
1884 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1885 /// to an array of at least 'reasonCount' number of elements. It will
1886 /// be filled with the number of the channel structure that had a problem.
1887 /// The value 'recordNum[i]' will only contain a valid value if
1888 /// the corresponding 'reason[i]' contains one of:
1889 /// - kInvalidIdValue
1890 /// - kInvalidBusPatchId
1891 /// - kInvalidManuId
1892 /// - kInvalidChannelAddress
1893 /// - kInvalidSignal
1894 /// - kDataWordDifferent
1895 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1896 /// was set and is valid or not.
1897 /// [in/out] \param reasonCount This should initially specify the size of
1898 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1899 /// with the number of items actually filled into the arrays upon exit
1900 /// from this method.
878cb83d 1901 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1902
dba14d7d 1903 AliHLTUInt32_t maxCount = reasonCount;
1904 bool result = HeaderOk(block, reason, reasonCount);
1905
1906 const AliHLTMUONChannelStruct* channel =
1907 reinterpret_cast<const AliHLTMUONChannelStruct*>(&block + 1);
dba14d7d 1908
1909 // Check integrity of individual channel structures.
1910 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1911 {
1912 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1913 if (not IntegrityOk(channel[i], reason+reasonCount, filledCount))
1914 {
1915 // reasons filled in IntegrityOk, now we just need to adjust
1916 // reasonCount and fill the recordNum values.
1917 if (recordNum != NULL)
1918 {
1919 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1920 recordNum[reasonCount + n] = i;
1921 }
1922 reasonCount += filledCount;
1923 result = false;
1924 }
1925 }
1926
1927 return result;
26a4668d 1928}
90a74d7a 1929
1930
878cb83d 1931bool AliHLTMUONUtils::IntegrityOk(
1932 const AliHLTMUONMansoTrackStruct& track,
dba14d7d 1933 WhyNotValid* reason,
1934 AliHLTUInt32_t& reasonCount
878cb83d 1935 )
90a74d7a 1936{
878cb83d 1937 /// This method is used to check more extensively if the integrity of the
1938 /// Manso track structure is OK and returns true in that case.
1939 /// [in] \param track The track structure to check.
dba14d7d 1940 /// [out] \param reason If this is not NULL, then it is assumed to point
1941 /// to an array of at least 'reasonCount' number of elements. It will
1942 /// be filled with the reason codes describing why the structure is
1943 /// not valid.
1944 /// [in/out] \param reasonCount This should initially specify the size of
1945 /// the array pointed to by 'reason'. It will be filled with the number
1946 /// of items actually filled into the reason array upon exit from this
1947 /// method.
878cb83d 1948 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 1949
dba14d7d 1950 AliHLTUInt32_t maxCount = reasonCount;
1951 reasonCount = 0;
1952 bool result = true;
1953
1954 // Check that the Manso track ID has a valid value.
1955 if (not (track.fId >= 0 or track.fId == -1))
1956 {
1957 if (reason != NULL and reasonCount < maxCount)
1958 {
1959 reason[reasonCount] = kInvalidIdValue;
1960 reasonCount++;
1961 }
1962 result = false;
1963 }
1964
1965 // Check that the corresponding trigger record ID has a valid value.
1966 if (not (track.fTrigRec >= 0 or track.fTrigRec == -1))
1967 {
1968 if (reason != NULL and reasonCount < maxCount)
1969 {
1970 reason[reasonCount] = kInvalidTriggerIdValue;
1971 reasonCount++;
1972 }
1973 result = false;
1974 }
1975
90a74d7a 1976 // Make sure that the reserved bits in the fFlags field are set
1977 // to zero.
878cb83d 1978 if ((track.fFlags & 0x3FFFFFF0) != 0)
1979 {
dba14d7d 1980 if (reason != NULL and reasonCount < maxCount)
1981 {
1982 reason[reasonCount] = kReservedBitsNotZero;
1983 reasonCount++;
1984 }
1985 result = false;
878cb83d 1986 }
90a74d7a 1987
1988 // Make sure the sign is not invalid.
878cb83d 1989 if ((track.fFlags & 0xC0000000) == 0xC0000000)
1990 {
dba14d7d 1991 if (reason != NULL and reasonCount < maxCount)
1992 {
1993 reason[reasonCount] = kParticleSignBitsNotValid;
1994 reasonCount++;
1995 }
1996 result = false;
878cb83d 1997 }
90a74d7a 1998
1999 // Check that fHit[i] is nil if the corresponding bit in the
2000 // flags word is zero.
2001 const AliHLTMUONRecHitStruct& nilhit
2002 = AliHLTMUONConstants::NilRecHitStruct();
878cb83d 2003 if ( ((track.fFlags & 0x1) == 0 and track.fHit[0] != nilhit) or
2004 ((track.fFlags & 0x2) == 0 and track.fHit[1] != nilhit) or
2005 ((track.fFlags & 0x4) == 0 and track.fHit[2] != nilhit) or
2006 ((track.fFlags & 0x8) == 0 and track.fHit[3] != nilhit)
2007 )
2008 {
dba14d7d 2009 if (reason != NULL and reasonCount < maxCount)
2010 {
2011 reason[reasonCount] = kHitNotMarkedAsNil;
2012 reasonCount++;
2013 }
2014 result = false;
2015 }
2016
2017 // Check that the chi squared value is valid
2018 if (not (track.fChi2 >= 0 or track.fChi2 == -1))
2019 {
2020 if (reason != NULL and reasonCount < maxCount)
2021 {
2022 reason[reasonCount] = kChiSquareInvalid;
2023 reasonCount++;
2024 }
2025 result = false;
2026 }
2027
2028 // Check that if chi squared is -1 then the momentum vector is zero.
2029 if (track.fChi2 == -1 and
2030 not (track.fPx == 0 and track.fPy == 0 and track.fPz == 0)
2031 )
2032 {
2033 if (reason != NULL and reasonCount < maxCount)
2034 {
2035 reason[reasonCount] = kMomentumVectorNotZero;
2036 reasonCount++;
2037 }
2038 result = false;
878cb83d 2039 }
90a74d7a 2040
a090ff22 2041 // Check the individual hits
2042 for (int i = 0; i < 4; i++)
2043 {
2044 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2045 if (not IntegrityOk(track.fHit[i], reason + reasonCount, filledCount))
2046 {
2047 reasonCount += filledCount;
2048 result = false;
2049 }
2050 }
2051
dba14d7d 2052 return result;
90a74d7a 2053}
2054
2055
878cb83d 2056bool AliHLTMUONUtils::IntegrityOk(
2057 const AliHLTMUONMansoTracksBlockStruct& block,
2058 WhyNotValid* reason,
dba14d7d 2059 AliHLTUInt32_t* recordNum,
2060 AliHLTUInt32_t& reasonCount
878cb83d 2061 )
90a74d7a 2062{
878cb83d 2063 /// This method is used to check more extensively if the integrity of the
dba14d7d 2064 /// dHLT internal Manso track data block is OK and returns true in that case.
878cb83d 2065 /// [in] \param block The Manso track data block to check.
dba14d7d 2066 /// [out] \param reason If this is not NULL, then it is assumed to point
2067 /// to an array of at least 'reasonCount' number of elements. It will
2068 /// be filled with the reason codes describing why the data block is
2069 /// not valid.
2070 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2071 /// to an array of at least 'reasonCount' number of elements. It will
2072 /// be filled with the number of the Manso track that had a problem.
2073 /// The value 'recordNum[i]' will only contain a valid value if
2074 /// the corresponding 'reason[i]' contains one of:
2075 /// - kInvalidIdValue
2076 /// - kInvalidTriggerIdValue
878cb83d 2077 /// - kReservedBitsNotZero
2078 /// - kParticleSignBitsNotValid
2079 /// - kHitNotMarkedAsNil
dba14d7d 2080 /// - kChiSquareInvalid
2081 /// - kMomentumVectorNotZero
a090ff22 2082 /// - kInvalidDetElementNumber
2083 /// - kInvalidChamberNumber
dba14d7d 2084 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2085 /// was set and is valid or not.
2086 /// [in/out] \param reasonCount This should initially specify the size of
2087 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2088 /// with the number of items actually filled into the arrays upon exit
2089 /// from this method.
878cb83d 2090 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2091
dba14d7d 2092 AliHLTUInt32_t maxCount = reasonCount;
2093 bool result = HeaderOk(block, reason, reasonCount);
2094
23ad6161 2095 const AliHLTMUONMansoTrackStruct* track =
2096 reinterpret_cast<const AliHLTMUONMansoTrackStruct*>(&block + 1);
2097
878cb83d 2098 // Check if any track ID is duplicated.
90a74d7a 2099 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2100 {
23ad6161 2101 AliHLTInt32_t id = track[i].fId;
dba14d7d 2102 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
90a74d7a 2103 {
23ad6161 2104 if (id == track[j].fId)
878cb83d 2105 {
dba14d7d 2106 if (reason != NULL and reasonCount < maxCount)
2107 {
2108 reason[reasonCount] = kFoundDuplicateIDs;
2109 reasonCount++;
2110 }
2111 result = false;
878cb83d 2112 }
90a74d7a 2113 }
2114 }
dba14d7d 2115
2116 // Check that all the tracks have integrity.
90a74d7a 2117 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2118 {
dba14d7d 2119 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2120 if (not IntegrityOk(track[i], reason+reasonCount, filledCount))
878cb83d 2121 {
dba14d7d 2122 // reasons filled in IntegrityOk, now we just need to adjust
2123 // reasonCount and fill the recordNum values.
2124 if (recordNum != NULL)
2125 {
2126 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2127 recordNum[reasonCount + n] = i;
2128 }
2129 reasonCount += filledCount;
2130 result = false;
878cb83d 2131 }
90a74d7a 2132 }
dba14d7d 2133
2134 return result;
2135}
90a74d7a 2136
dba14d7d 2137
2138bool AliHLTMUONUtils::IntegrityOk(
2139 const AliHLTMUONMansoCandidateStruct& candidate,
2140 WhyNotValid* reason,
2141 AliHLTUInt32_t& reasonCount
2142 )
2143{
2144 /// This method is used to check more extensively if the integrity of the
2145 /// Manso track candidate structure is OK and returns true in that case.
2146 /// [in] \param track The track candidate structure to check.
2147 /// [out] \param reason If this is not NULL, then it is assumed to point
2148 /// to an array of at least 'reasonCount' number of elements. It will
2149 /// be filled with the reason codes describing why the structure is
2150 /// not valid.
2151 /// [in/out] \param reasonCount This should initially specify the size of
2152 /// the array pointed to by 'reason'. It will be filled with the number
2153 /// of items actually filled into the reason array upon exit from this
2154 /// method.
2155 /// \returns true if there is no problem with the structure and false otherwise.
2156
2157 // First check the integrity of the candidate track structure.
2158 AliHLTUInt32_t maxCount = reasonCount;
2159 bool result = IntegrityOk(candidate.fTrack, reason, reasonCount);
2160
2161 // Now check that the ROIs are reasonable.
2162 // The radius must be positive or -1 indicating computation error and
2163 // the corresponding hit in the track must be within the ROI.
2164 for (AliHLTUInt32_t i = 0; i < 4; i++)
2165 {
2166 if (not (candidate.fRoI[i].fRadius >= 0 or candidate.fRoI[i].fRadius == -1))
2167 {
2168 if (reason != NULL and reasonCount < maxCount)
2169 {
2170 reason[reasonCount] = kRoiRadiusInvalid;
2171 reasonCount++;
2172 }
2173 result = false;
2174 }
2175
2176 // Check if the corresponding hit was even found in the track.
2177 if ( (candidate.fTrack.fFlags & (0x1 << i)) == 0 ) continue;
2178
2179 double dx = candidate.fRoI[i].fX - candidate.fTrack.fHit[i].fX;
2180 double dy = candidate.fRoI[i].fY - candidate.fTrack.fHit[i].fY;
2181 double dz = candidate.fRoI[i].fZ - candidate.fTrack.fHit[i].fZ;
2182 double r = sqrt(dx*dx + dy*dy);
2183 // Check if the projected distance between ROI centre and hit is
2184 // bigger than the ROI radius. Also the difference between z
2185 // coordinates should not exceed 20 cm.
2186 if (r > candidate.fRoI[i].fRadius or fabs(dz) > 20.)
2187 {
2188 if (reason != NULL and reasonCount < maxCount)
2189 {
2190 reason[reasonCount] = kHitNotWithinRoi;
2191 reasonCount++;
2192 }
2193 result = false;
2194 }
2195 }
2196
2197 return result;
90a74d7a 2198}
2199
2200
878cb83d 2201bool AliHLTMUONUtils::IntegrityOk(
2202 const AliHLTMUONMansoCandidatesBlockStruct& block,
2203 WhyNotValid* reason,
dba14d7d 2204 AliHLTUInt32_t* recordNum,
2205 AliHLTUInt32_t& reasonCount
878cb83d 2206 )
90a74d7a 2207{
878cb83d 2208 /// This method is used to check more extensively if the integrity of the
dba14d7d 2209 /// dHLT internal Manso candidates data block is OK and returns true in
2210 /// that case.
878cb83d 2211 /// [in] \param block The Manso track candidate data block to check.
dba14d7d 2212 /// [out] \param reason If this is not NULL, then it is assumed to point
2213 /// to an array of at least 'reasonCount' number of elements. It will
2214 /// be filled with the reason codes describing why the data block is
2215 /// not valid.
2216 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2217 /// to an array of at least 'reasonCount' number of elements. It will
2218 /// be filled with the number of the track candidate that had a problem.
2219 /// The value 'recordNum[i]' will only contain a valid value if
2220 /// the corresponding 'reason[i]' contains one of:
2221 /// - kInvalidIdValue
2222 /// - kInvalidTriggerIdValue
878cb83d 2223 /// - kReservedBitsNotZero
2224 /// - kParticleSignBitsNotValid
2225 /// - kHitNotMarkedAsNil
dba14d7d 2226 /// - kChiSquareInvalid
2227 /// - kRoiRadiusInvalid
2228 /// - kHitNotWithinRoi
2229 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2230 /// was set and is valid or not.
2231 /// [in/out] \param reasonCount This should initially specify the size of
2232 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2233 /// with the number of items actually filled into the arrays upon exit
2234 /// from this method.
878cb83d 2235 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2236
dba14d7d 2237 AliHLTUInt32_t maxCount = reasonCount;
2238 bool result = HeaderOk(block, reason, reasonCount);
90a74d7a 2239
23ad6161 2240 const AliHLTMUONMansoCandidateStruct* candidate =
2241 reinterpret_cast<const AliHLTMUONMansoCandidateStruct*>(&block + 1);
2242
878cb83d 2243 // Check if any candidate track ID is duplicated.
2244 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2245 {
2246 AliHLTInt32_t id = candidate[i].fTrack.fId;
dba14d7d 2247 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
878cb83d 2248 {
2249 if (id == candidate[j].fTrack.fId)
2250 {
dba14d7d 2251 if (reason != NULL and reasonCount < maxCount)
2252 {
2253 reason[reasonCount] = kFoundDuplicateIDs;
2254 reasonCount++;
2255 }
2256 result = false;
878cb83d 2257 }
2258 }
2259 }
2260
dba14d7d 2261 // Check that all the track candidates have integrity.
90a74d7a 2262 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2263 {
dba14d7d 2264 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2265 if (not IntegrityOk(candidate[i], reason+reasonCount, filledCount))
878cb83d 2266 {
dba14d7d 2267 // reasons filled in IntegrityOk, now we just need to adjust
2268 // reasonCount and fill the recordNum values.
2269 if (recordNum != NULL)
2270 {
2271 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2272 recordNum[reasonCount + n] = i;
2273 }
2274 reasonCount += filledCount;
2275 result = false;
878cb83d 2276 }
90a74d7a 2277 }
2278
dba14d7d 2279 return result;
90a74d7a 2280}
2281
2282
878cb83d 2283bool AliHLTMUONUtils::IntegrityOk(
2284 const AliHLTMUONTrackDecisionStruct& decision,
dba14d7d 2285 WhyNotValid* reason,
2286 AliHLTUInt32_t& reasonCount
878cb83d 2287 )
90a74d7a 2288{
878cb83d 2289 /// This method is used to check more extensively if the integrity of the
2290 /// single track trigger decision structure is OK and returns true in that case.
2291 /// [in] \param decision The trigger decision structure to check.
dba14d7d 2292 /// [out] \param reason If this is not NULL, then it is assumed to point
2293 /// to an array of at least 'reasonCount' number of elements. It will
2294 /// be filled with the reason codes describing why the structure is not
2295 /// valid.
2296 /// [in/out] \param reasonCount This should initially specify the size of
2297 /// the array pointed to by 'reason'. It will be filled with the number
2298 /// of items actually filled into the reason array upon exit from this
2299 /// method.
878cb83d 2300 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 2301
dba14d7d 2302 AliHLTUInt32_t maxCount = reasonCount;
2303 reasonCount = 0;
2304 bool result = true;
2305
2306 // The track ID value must be positive or -1.
2307 if (not (decision.fTrackId >= 0 or decision.fTrackId == -1))
2308 {
2309 if (reason != NULL and reasonCount < maxCount)
2310 {
2311 reason[reasonCount] = kInvalidTrackIdValue;
2312 reasonCount++;
2313 }
2314 result = false;
2315 }
2316
90a74d7a 2317 // Make sure that the reserved bits in the fTriggerBits field are set
2318 // to zero.
878cb83d 2319 if ((decision.fTriggerBits & 0xFFFFFFFC) != 0)
2320 {
dba14d7d 2321 if (reason != NULL and reasonCount < maxCount)
2322 {
2323 reason[reasonCount] = kReservedBitsNotZero;
2324 reasonCount++;
2325 }
2326 result = false;
878cb83d 2327 }
2328
2329 // The pT should be -1 or a positive number.
2330 if (decision.fPt != -1. and decision.fPt < 0.)
2331 {
dba14d7d 2332 if (reason != NULL and reasonCount < maxCount)
2333 {
2334 reason[reasonCount] = kPtValueNotValid;
2335 reasonCount++;
2336 }
2337 result = false;
878cb83d 2338 }
2339
dba14d7d 2340 return result;
90a74d7a 2341}
2342
2343
878cb83d 2344bool AliHLTMUONUtils::IntegrityOk(
2345 const AliHLTMUONSinglesDecisionBlockStruct& block,
2346 WhyNotValid* reason,
dba14d7d 2347 AliHLTUInt32_t* recordNum,
2348 AliHLTUInt32_t& reasonCount
878cb83d 2349 )
90a74d7a 2350{
878cb83d 2351 /// This method is used to check more extensively if the integrity of the
dba14d7d 2352 /// dHLT internal single track trigger decision data block is OK and returns
2353 /// true in that case.
878cb83d 2354 /// [in] \param block The single track trigger decision data block to check.
dba14d7d 2355 /// [out] \param reason If this is not NULL, then it is assumed to point
2356 /// to an array of at least 'reasonCount' number of elements. It will
2357 /// be filled with the reason codes describing why the data block is
2358 /// not valid.
2359 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2360 /// to an array of at least 'reasonCount' number of elements. It will
2361 /// be filled with the number of the trigger decision that had a problem.
2362 /// The value 'recordNum[i]' will only contain a valid value if
2363 /// the corresponding 'reason[i]' contains one of:
2364 /// - kInvalidTrackIdValue
878cb83d 2365 /// - kReservedBitsNotZero
2366 /// - kPtValueNotValid
dba14d7d 2367 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2368 /// was set and is valid or not.
2369 /// [in/out] \param reasonCount This should initially specify the size of
2370 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2371 /// with the number of items actually filled into the arrays upon exit
2372 /// from this method.
878cb83d 2373 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2374
dba14d7d 2375 AliHLTUInt32_t maxCount = reasonCount;
2376 bool result = HeaderOk(block, reason, reasonCount);
23ad6161 2377
2378 const AliHLTMUONTrackDecisionStruct* decision =
2379 reinterpret_cast<const AliHLTMUONTrackDecisionStruct*>(&block + 1);
90a74d7a 2380
878cb83d 2381 // Check that there are no duplicate trigger entries.
2382 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2383 {
2384 AliHLTInt32_t id = decision[i].fTrackId;
dba14d7d 2385 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
878cb83d 2386 {
2387 if (id == decision[j].fTrackId)
2388 {
dba14d7d 2389 if (reason != NULL and reasonCount < maxCount)
2390 {
2391 reason[reasonCount] = kFoundDuplicateTriggers;
2392 reasonCount++;
2393 }
2394 result = false;
878cb83d 2395 }
2396 }
2397 }
2398
90a74d7a 2399 // Check that the trigger bits for each track have integrity.
2400 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2401 {
dba14d7d 2402 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2403 if (not IntegrityOk(decision[i], reason+reasonCount, filledCount))
878cb83d 2404 {
dba14d7d 2405 // Reasons filled in IntegrityOk, now we just need to adjust
2406 // reasonCount and fill the recordNum values.
2407 if (recordNum != NULL)
2408 {
2409 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2410 recordNum[reasonCount + n] = i;
2411 }
2412 reasonCount += filledCount;
2413 result = false;
878cb83d 2414 }
90a74d7a 2415 }
2416
dba14d7d 2417 return result;
90a74d7a 2418}
2419
2420
878cb83d 2421bool AliHLTMUONUtils::IntegrityOk(
2422 const AliHLTMUONPairDecisionStruct& decision,
dba14d7d 2423 WhyNotValid* reason,
2424 AliHLTUInt32_t& reasonCount
878cb83d 2425 )
90a74d7a 2426{
878cb83d 2427 /// This method is used to check more extensively if the integrity of the
2428 /// track pair trigger decision structure is OK and returns true in that case.
2429 /// [in] \param decision The trigger decision structure to check.
dba14d7d 2430 /// [out] \param reason If this is not NULL, then it is assumed to point
2431 /// to an array of at least 'reasonCount' number of elements. It will
2432 /// be filled with the reason codes describing why the structure is not
2433 /// valid.
2434 /// [in/out] \param reasonCount This should initially specify the size of
2435 /// the array pointed to by 'reason'. It will be filled with the number
2436 /// of items actually filled into the reason array upon exit from this
2437 /// method.
878cb83d 2438 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 2439
dba14d7d 2440 AliHLTUInt32_t maxCount = reasonCount;
2441 reasonCount = 0;
2442 bool result = true;
2443
2444 //kInvalidTrackIdValue
2445
2446 // The track IDs must have a positive value or -1.
2447 if (not (decision.fTrackAId >= 0 or decision.fTrackAId == -1) or
2448 not (decision.fTrackBId >= 0 or decision.fTrackBId == -1)
2449 )
2450 {
2451 if (reason != NULL and reasonCount < maxCount)
2452 {
2453 reason[reasonCount] = kInvalidTrackIdValue;
2454 reasonCount++;
2455 }
2456 result = false;
2457 }
2458
90a74d7a 2459 // Make sure that the reserved bits in the fTriggerBits field are set
2460 // to zero.
878cb83d 2461 if ((decision.fTriggerBits & 0xFFFFFF80) != 0)
2462 {
dba14d7d 2463 if (reason != NULL and reasonCount < maxCount)
2464 {
2465 reason[reasonCount] = kReservedBitsNotZero;
2466 reasonCount++;
2467 }
2468 result = false;
878cb83d 2469 }
90a74d7a 2470
878cb83d 2471 // Check that the track IDs are not the same.
2472 if (decision.fTrackAId == decision.fTrackBId)
2473 {
dba14d7d 2474 if (reason != NULL and reasonCount < maxCount)
2475 {
2476 reason[reasonCount] = kPairTrackIdsAreIdentical;
2477 reasonCount++;
2478 }
2479 result = false;
878cb83d 2480 }
2481
2482 // The invariant mass should be -1 or a positive number.
2483 if (decision.fInvMass != -1. and decision.fInvMass < 0.)
2484 {
dba14d7d 2485 if (reason != NULL and reasonCount < maxCount)
2486 {
2487 reason[reasonCount] = kMassValueNotValid;
2488 reasonCount++;
2489 }
2490 result = false;
878cb83d 2491 }
90a74d7a 2492
2493 // Neither the high pt (hipt) or low pt (lopt) count bits can be > 2.
90a74d7a 2494 AliHLTUInt8_t lowPtCount = (decision.fTriggerBits & 0x00000003);
2495 AliHLTUInt8_t highPtCount = (decision.fTriggerBits & 0x0000000C) >> 2;
878cb83d 2496 if (lowPtCount > 2)
2497 {
dba14d7d 2498 if (reason != NULL and reasonCount < maxCount)
2499 {
2500 reason[reasonCount] = kLowPtCountInvalid;
2501 reasonCount++;
2502 }
2503 result = false;
878cb83d 2504 }
2505 if (highPtCount > 2)
2506 {
dba14d7d 2507 if (reason != NULL and reasonCount < maxCount)
2508 {
2509 reason[reasonCount] = kHighPtCountInvalid;
2510 reasonCount++;
2511 }
2512 result = false;
878cb83d 2513 }
90a74d7a 2514
dba14d7d 2515 return result;
90a74d7a 2516}
2517
2518
878cb83d 2519bool AliHLTMUONUtils::IntegrityOk(
2520 const AliHLTMUONPairsDecisionBlockStruct& block,
2521 WhyNotValid* reason,
dba14d7d 2522 AliHLTUInt32_t* recordNum,
2523 AliHLTUInt32_t& reasonCount
878cb83d 2524 )
90a74d7a 2525{
878cb83d 2526 /// This method is used to check more extensively if the integrity of the
dba14d7d 2527 /// dHLT internal track pair trigger decision data block is OK and returns
2528 /// true in that case.
878cb83d 2529 /// [in] \param block The track pair trigger decision data block to check.
dba14d7d 2530 /// [out] \param reason If this is not NULL, then it is assumed to point
2531 /// to an array of at least 'reasonCount' number of elements. It will
2532 /// be filled with the reason codes describing why the data block is
2533 /// not valid.
2534 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2535 /// to an array of at least 'reasonCount' number of elements. It will
2536 /// be filled with the number of the trigger decision that had a problem.
2537 /// The value 'recordNum[i]' will only contain a valid value if
2538 /// the corresponding 'reason[i]' contains one of:
2539 /// - kInvalidTrackIdValue
878cb83d 2540 /// - kReservedBitsNotZero
2541 /// - kPairTrackIdsAreIdentical
2542 /// - kMassValueNotValid
2543 /// - kLowPtCountInvalid
2544 /// - kHighPtCountInvalid
dba14d7d 2545 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2546 /// was set and is valid or not.
2547 /// [in/out] \param reasonCount This should initially specify the size of
2548 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2549 /// with the number of items actually filled into the arrays upon exit
2550 /// from this method.
878cb83d 2551 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2552
dba14d7d 2553 AliHLTUInt32_t maxCount = reasonCount;
2554 bool result = HeaderOk(block, reason, reasonCount);
90a74d7a 2555
23ad6161 2556 const AliHLTMUONPairDecisionStruct* decision =
2557 reinterpret_cast<const AliHLTMUONPairDecisionStruct*>(&block + 1);
2558
878cb83d 2559 // Check that there are no duplicate trigger entries.
2560 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2561 {
2562 AliHLTInt32_t ta = decision[i].fTrackAId;
2563 AliHLTInt32_t tb = decision[i].fTrackBId;
dba14d7d 2564 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
878cb83d 2565 {
2566 if (ta == decision[j].fTrackAId and tb == decision[j].fTrackBId)
2567 {
dba14d7d 2568 if (reason != NULL and reasonCount < maxCount)
2569 {
2570 reason[reasonCount] = kFoundDuplicateTriggers;
2571 reasonCount++;
2572 }
2573 result = false;
878cb83d 2574 }
2575 }
2576 }
2577
90a74d7a 2578 // Check that the trigger bits for each track pair have integrity.
2579 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2580 {
dba14d7d 2581 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2582 if (not IntegrityOk(decision[i], reason+reasonCount, filledCount))
878cb83d 2583 {
dba14d7d 2584 // Reasons filled in IntegrityOk, now we just need to adjust
2585 // reasonCount and fill the recordNum values.
2586 if (recordNum != NULL)
2587 {
2588 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2589 recordNum[reasonCount + n] = i;
2590 }
2591 reasonCount += filledCount;
2592 result = false;
878cb83d 2593 }
90a74d7a 2594 }
2595
dba14d7d 2596 return result;
90a74d7a 2597}
dba14d7d 2598