]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/AliHLTMUONUtils.cxx
Preventing automatic compilation of trace statements into debug build.
[u/mrichter/AliRoot.git] / HLT / MUON / AliHLTMUONUtils.cxx
CommitLineData
26a4668d 1/**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/* $Id$ */
17
6253e09b 18///
19/// @file AliHLTMUONUtils.cxx
20/// @author Artur Szostak <artursz@iafrica.com>
dba14d7d 21/// @date 17 May 2007
6253e09b 22/// @brief Implementation of AliHLTMUONUtils utility routines.
23///
26a4668d 24
25#include "AliHLTMUONUtils.h"
b727f838 26#include "AliHLTMUONConstants.h"
c8ec7c7e 27#include "AliHLTMUONTriggerRecordsBlockStruct.h"
28#include "AliHLTMUONTrigRecsDebugBlockStruct.h"
c8ec7c7e 29#include "AliHLTMUONRecHitsBlockStruct.h"
30#include "AliHLTMUONClustersBlockStruct.h"
31#include "AliHLTMUONChannelsBlockStruct.h"
90a74d7a 32#include "AliHLTMUONMansoTracksBlockStruct.h"
33#include "AliHLTMUONMansoCandidatesBlockStruct.h"
34#include "AliHLTMUONSinglesDecisionBlockStruct.h"
b12fe461 35#include "AliHLTMUONPairsDecisionBlockStruct.h"
dba14d7d 36#include "AliMUONTrackerDDLDecoderEventHandler.h"
f68b4e0e 37#include <cstring>
dba14d7d 38#include <cmath>
90a74d7a 39#include <cassert>
26a4668d 40
33b1e2f2 41ClassImp(AliHLTMUONUtils);
42
26a4668d 43
b727f838 44AliHLTUInt32_t AliHLTMUONUtils::PackTriggerRecordFlags(
e6357f88 45 AliHLTMUONParticleSign sign, const bool hitset[4]
b727f838 46 )
26a4668d 47{
6253e09b 48 ///
49 /// This packs the given parameters into the bits of a word appropriate
50 /// for AliHLTMUONTriggerRecordStruct::fFlags.
51 /// @param sign The particle sign.
52 /// @param hitset Flags to indicate if the corresponding fHits[i] elements
53 /// was set/filled.
54 /// @return Returns the 32 bit packed word.
55 ///
56
b727f838 57 AliHLTUInt32_t flags;
58 switch (sign)
59 {
60 case kSignMinus: flags = 0x80000000; break;
61 case kSignPlus: flags = 0x40000000; break;
62 default: flags = 0x00000000; break;
63 }
26a4668d 64
b727f838 65 return flags | (hitset[0] ? 0x1 : 0) | (hitset[1] ? 0x2 : 0)
66 | (hitset[2] ? 0x4 : 0) | (hitset[3] ? 0x8 : 0);
67}
68
69
70void AliHLTMUONUtils::UnpackTriggerRecordFlags(
90a74d7a 71 AliHLTUInt32_t flags, AliHLTMUONParticleSign& sign, bool hitset[4]
b727f838 72 )
73{
6253e09b 74 ///
75 /// This unpacks the AliHLTMUONTriggerRecordStruct::fFlags bits into
76 /// its component fields.
77 /// @param flags The flags from an AliHLTMUONTriggerRecordStruct structure.
78 /// @param sign Sets this to the particle sign.
79 /// @param hitset Sets the array elements to indicate if the corresponding
80 /// fHits[i] element was set/filled.
81 ///
82
b727f838 83 AliHLTUInt32_t signbits = flags & 0xC0000000;
84 switch (signbits)
85 {
86 case 0x80000000: sign = kSignMinus; break;
87 case 0x40000000: sign = kSignPlus; break;
88 default: sign = kSignUnknown; break;
89 }
e6357f88 90 hitset[0] = (flags & 0x1) == 0x1;
91 hitset[1] = (flags & 0x2) == 0x2;
92 hitset[2] = (flags & 0x4) == 0x4;
93 hitset[3] = (flags & 0x8) == 0x8;
b727f838 94}
95
96
a090ff22 97AliHLTUInt32_t AliHLTMUONUtils::PackRecHitFlags(
98 AliHLTUInt8_t chamber, AliHLTUInt16_t detElemId
99 )
100{
101 /// This packs the given parameters into the bits of a word appropriate
102 /// for AliHLTMUONRecHitStruct::fFlags.
103 /// @param chamber The chamber number in the range [0..13].
104 /// @param detElemId Detector element ID number.
105 /// @return Returns the 32 bit packed word.
106
107 return ((chamber & 0xF) << 12) | (detElemId & 0xFFF);
108}
109
110
111void AliHLTMUONUtils::UnpackRecHitFlags(
112 AliHLTUInt32_t flags, // [in]
113 AliHLTUInt8_t& chamber, // [out]
114 AliHLTUInt16_t& detElemId // [out]
115 )
116{
117 /// This unpacks the AliHLTMUONRecHitStruct::fFlags bits into
118 /// its component fields.
119 /// [in] @param flags The flags from an AliHLTMUONRecHitStruct structure.
120 /// [out] @param chamber Sets the chamber number in the range [0..13].
121 /// [out] @param detElemId Sets the detector element ID number.
122
123 chamber = (flags >> 12) & 0xF;
124 detElemId = flags & 0xFFF;
125}
126
127
90a74d7a 128AliHLTUInt32_t AliHLTMUONUtils::PackTrackDecisionBits(bool highPt, bool lowPt)
129{
6253e09b 130 ///
131 /// This packs the given parameters into the bits of a word appropriate
132 /// for AliHLTMUONTrackDecisionStruct::fTriggerBits.
133 /// @param highPt Has the track passed the high pt cut.
134 /// @param lowPt Has the track passed the low pt cut.
135 /// @return Returns the 32 bit packed word.
136 ///
137
90a74d7a 138 return (highPt ? 0x2 : 0) | (lowPt ? 0x1 : 0);
139}
140
141
142void AliHLTMUONUtils::UnpackTrackDecisionBits(
143 AliHLTUInt32_t bits, bool& highPt, bool& lowPt
144 )
145{
6253e09b 146 ///
147 /// This unpacks the AliHLTMUONTrackDecisionStruct::fTriggerBits bits into
148 /// its component fields.
149 /// @param bits The trigger bits from an AliHLTMUONTrackDecisionStruct
150 /// structure.
151 /// @param highPt Sets this to the value of the high pt cut bit.
152 /// @param lowPt Sets this to the value of the low pt cut bit.
153 ///
154
fc310e19 155 lowPt = (bits & 0x1) == 0x1;
156 highPt = (bits & 0x2) == 0x2;
90a74d7a 157}
158
159
160AliHLTUInt32_t AliHLTMUONUtils::PackPairDecisionBits(
161 bool highMass, bool lowMass, bool unlike,
162 AliHLTUInt8_t highPtCount, AliHLTUInt8_t lowPtCount
163 )
164{
6253e09b 165 ///
166 /// This packs the given parameters into the bits of a word appropriate
167 /// for AliHLTMUONPairDecisionStruct::fTriggerBits.
168 ///
169 /// @param highMass Has the track pair passed the high invariant mass cut.
170 /// @param lowMass Has the track pair passed the low invariant mass cut.
171 /// @param unlike Does the track pair have unlike signs.
172 /// @param highPtCount The number of tracks that passed the high pt cut
173 /// in the pair.
174 /// @param lowPtCount The number of tracks that passed the low pt cut
175 /// in the pair.
176 /// @return Returns the 32 bit packed word.
177 ///
02f92a42 178 /// Note: Must have highPtCount <= 2, lowPtCount <= 2 and
179 /// unlike == true if highMass or lowMass is true.
6253e09b 180 ///
181
02f92a42 182 assert( lowPtCount <= 2 );
183 assert( highPtCount <= 2 );
90a74d7a 184 // highMass and lowMass must be false if unlike is false:
185 assert( not unlike ? (highMass == false and lowMass == false) : true );
186
187 return (highMass ? 0x40 : 0) | (lowMass ? 0x20 : 0) | (unlike ? 0x10 : 0)
188 | ((highPtCount & 0x3) << 2) | (lowPtCount & 0x3);
189}
190
191
192void AliHLTMUONUtils::UnpackPairDecisionBits(
193 AliHLTUInt32_t bits, bool& highMass, bool& lowMass, bool& unlike,
194 AliHLTUInt8_t& highPtCount, AliHLTUInt8_t& lowPtCount
195 )
196{
6253e09b 197 ///
198 /// This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
199 /// its component fields.
200 /// @param bits The trigger bits from an AliHLTMUONPairDecisionStruct
201 /// structure.
202 /// @param highMass Sets this to the value of the high invariant mass cut bit.
203 /// @param lowMass Sets this to the value of the low invariant mass cut bit.
204 /// @param unlike Sets this if the pair is unlike sign.
205 /// @param highPtCount Sets this to the high pt count bits.
206 /// @param lowPtCount Sets this to the low pt count bits.
207 ///
208
fc310e19 209 highMass = (bits & 0x40) == 0x40;
210 lowMass = (bits & 0x20) == 0x20;
211 unlike = (bits & 0x10) == 0x10;
90a74d7a 212 highPtCount = (bits & 0xC) >> 2;
213 lowPtCount = bits & 0x3;
214}
215
216
e6357f88 217AliHLTUInt32_t AliHLTMUONUtils::PackSpecBits(
218 const bool ddl[22]
219 )
220{
6253e09b 221 ///
222 /// This packs the given parameters into the 32bit Pub/Sub specification
223 /// word in the data block descriptor.
224 ///
225 /// @param ddl The list of DDLs forming part of the readout. ddl[0]
226 /// indicates DDL number 2560, ddl[1] is for DDL 2561 and so
227 /// on up to ddl[19]. ddl[20] and ddl[21] will be for the
228 /// trigger DDLs 2816 and 2817 respectively.
229 /// @return Returns the 32 bit packed specification word.
230 ///
231
e6357f88 232 // Pack the bits into the following format:
233 // bit: [ 31 - 22 ][ 21 ][ 20 ][ 19 - 0 ]
80606a9f 234 // field: [ reserved, set to zero ][ TRGDDL2817 ][ TRGDDL2816 ][ TRKDDLS ]
e6357f88 235 // Meaning of field acronyms:
236 // TRGDDL2816 - Trigger DDL number 2816.
237 // TRGDDL2817 - Trigger DDL number 2817.
238 // TRKDDLS - Tracking DDL flags where bit 0 will be for DDL number 2560,
239 // bit 1 for DDL no. 2561 etc. up to bit 19 which is for DDL 2579.
240 AliHLTUInt32_t bits = 0;
241 for (int i = 0; i < 22; i++)
242 bits |= (ddl[i] ? 0x1 : 0x0) << i;
243 return bits;
244}
245
246
247void AliHLTMUONUtils::UnpackSpecBits(
248 AliHLTUInt32_t bits, bool ddl[22]
249 )
250{
6253e09b 251 ///
252 /// This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
253 /// its component fields.
254 /// @param bits The Pub/Sub specification word from a data block descriptor.
255 /// @param ddl The output list of DDLs forming part of the readout. ddl[0]
256 /// indicates DDL number 2560, ddl[1] is for DDL 2561 and so
257 /// on up to ddl[19]. ddl[20] and ddl[21] will be for the
258 /// trigger DDLs 2816 and 2817 respectively.
259 ///
260
e6357f88 261 // Perform the inverse operation of PackSpecBits.
262 for (int i = 0; i < 22; i++)
263 ddl[i] = ((bits >> i) & 0x1) == 1;
264}
265
266
86b774d9 267AliHLTInt32_t AliHLTMUONUtils::DDLNumberToEquipId(AliHLTInt32_t ddlNo)
268{
269 ///
270 /// This method converts the DDL number for the muon spectrometer in the
271 /// range [0..21] to the equipment ID number.
272 /// @param ddlNo The DDL number in the range [0..21].
273 /// @return Returns the equipment ID number or -1 if ddlNo was invalid.
274 ///
275
276 if (0 <= ddlNo and ddlNo <= 19)
277 {
278 return 2560 + ddlNo;
279 }
280 else if (20 <= ddlNo and ddlNo <= 21)
281 {
282 return 2816 + (ddlNo - 20);
283 }
284 else
285 {
286 return -1;
287 }
288}
289
290
291AliHLTInt32_t AliHLTMUONUtils::EquipIdToDDLNumber(AliHLTInt32_t id)
292{
293 ///
294 /// This method converts the equipment ID number for a muon spectrometer
295 /// DDL to the DDL number in the range [0..21].
296 /// @param id The equipment ID of the DDL.
297 /// @return Returns the DDL number in the range [0..21] or -1 if the
298 /// equipment ID was invalid.
299 ///
300
301 if (2560 <= id and id <= 2560+19)
302 {
303 return id - 2560;
304 }
305 else if (2816 <= id and id <= 2817)
306 {
307 return id - 2816 + 20;
308 }
309 else
310 {
311 return -1;
312 }
313}
314
315
316AliHLTInt32_t AliHLTMUONUtils::SpecToEquipId(AliHLTUInt32_t spec)
317{
318 ///
319 /// This method converts a 32 bit data block specification for a MUON-HLT
320 /// data block into its corresponding DDL equipment ID number.
321 /// It is assumed that the specification is for a data block comming from
322 /// a single DDL source. If more than one DDL contributed to the data block
323 /// then -1 is returned.
324 /// @param spec The 32 bit specification for a data block.
325 /// @return Returns the equipment ID corresponding to the specification
326 /// or -1 if the specification was invalid.
327 ///
328
329 for (AliHLTInt32_t ddlNo = 0; ddlNo < 20; ddlNo++)
330 {
331 if (spec == AliHLTUInt32_t(0x1 << ddlNo))
332 return ddlNo + 2560;
333 }
334 for (AliHLTInt32_t ddlNo = 20; ddlNo < 22; ddlNo++)
335 {
336 if (spec == AliHLTUInt32_t(0x1 << ddlNo))
337 return ddlNo - 20 + 2816;
338 }
339 return -1;
340}
341
342
343AliHLTUInt32_t AliHLTMUONUtils::EquipIdToSpec(AliHLTInt32_t id)
344{
345 ///
346 /// This method converts a equipment ID number for a DDL into its corresponding
347 /// 32 bit data block specification for the MUON-HLT.
348 /// @param id The equipment ID number of the DDL.
349 /// @return Returns the 32 bit data block specification or 0x0 if the
350 /// equipment ID was invalid.
351 ///
352
353 if (2560 <= id and id <= 2560+19)
354 {
355 return 0x1 << (id - 2560);
356 }
357 else if (2816 <= id and id <= 2817)
358 {
359 return 0x1 << (id - 2816 + 20);
360 }
361 else
362 {
363 return 0x0;
364 }
365}
366
367
368AliHLTInt32_t AliHLTMUONUtils::SpecToDDLNumber(AliHLTUInt32_t spec)
369{
370 ///
371 /// This method converts a 32 bit data block specification for a MUON-HLT
372 /// data block into its corresponding DDL number in the range [0..21].
373 /// It is assumed that the specification is for a data block comming from
374 /// a single DDL source. If more than one DDL contributed to the data block
375 /// then -1 is returned.
376 /// @param spec The 32 bit specification for a data block.
377 /// @return Returns the corresponding DDL number for the specification
378 /// or -1 if the specification was invalid.
379 ///
380
381 for (AliHLTInt32_t ddlNo = 0; ddlNo < 22; ddlNo++)
382 {
383 if (spec == AliHLTUInt32_t(0x1 << ddlNo))
384 return ddlNo;
385 }
386 return -1;
387}
388
389
390AliHLTUInt32_t AliHLTMUONUtils::DDLNumberToSpec(AliHLTInt32_t ddlNo)
391{
392 ///
393 /// This method converts a DDL number in the range [0..21] into its
394 /// corresponding 32 bit data block specification for the MUON-HLT.
395 /// @param ddlNo The equipment ID number of the DDL.
396 /// @return Returns the 32 bit data block specification or 0x0 if the
397 /// DDL number was invalid (out of range).
398 ///
399
400 if (0 <= ddlNo and ddlNo <= 21)
401 {
402 return 0x1 << ddlNo;
403 }
404 else
405 {
406 return 0x0;
407 }
408}
409
410
f68b4e0e 411AliHLTMUONDataBlockType AliHLTMUONUtils::ParseCommandLineTypeString(const char* type)
412{
413 /// Parses the string containing the type name of a dHLT data block and
414 /// returns the corresponding AliHLTMUONDataBlockType value.
415 /// \param type The string containing the type name.
416 /// \returns The data block type or kUnknownDataBlock if the type name
417 /// is invalid.
418
419 if (strcmp(type, "trigrecs") == 0)
420 {
421 return kTriggerRecordsDataBlock;
422 }
423 else if (strcmp(type, "trigrecsdebug") == 0)
424 {
425 return kTrigRecsDebugDataBlock;
426 }
f68b4e0e 427 else if (strcmp(type, "rechits") == 0)
428 {
429 return kRecHitsDataBlock;
430 }
431 else if (strcmp(type,"channels") == 0)
432 {
433 return kChannelsDataBlock;
434 }
435 else if (strcmp(type,"clusters") == 0)
436 {
437 return kClustersDataBlock;
438 }
439 else if (strcmp(type, "mansotracks") == 0)
440 {
441 return kMansoTracksDataBlock;
442 }
443 else if (strcmp(type, "mansocandidates") == 0)
444 {
445 return kMansoCandidatesDataBlock;
446 }
447 else if (strcmp(type, "singlesdecision") == 0)
448 {
449 return kSinglesDecisionDataBlock;
450 }
451 else if (strcmp(type, "pairsdecision") == 0)
452 {
453 return kPairsDecisionDataBlock;
454 }
455
456 return kUnknownDataBlock;
457}
458
459
887a669c 460const char* AliHLTMUONUtils::DataBlockTypeToString(AliHLTMUONDataBlockType type)
461{
462 /// Converts a type ID to a type string compatible with
463 /// HLT data types.
464
465 static char str[kAliHLTComponentDataTypefIDsize+1];
466 AliHLTComponentDataType t;
467 switch (type)
468 {
469 case kTriggerRecordsDataBlock:
470 t = AliHLTMUONConstants::TriggerRecordsBlockDataType();
471 break;
472 case kTrigRecsDebugDataBlock:
473 t = AliHLTMUONConstants::TrigRecsDebugBlockDataType();
474 break;
887a669c 475 case kRecHitsDataBlock:
476 t = AliHLTMUONConstants::RecHitsBlockDataType();
477 break;
478 case kClustersDataBlock:
479 t = AliHLTMUONConstants::ClusterBlockDataType();
480 break;
481 case kChannelsDataBlock:
482 t = AliHLTMUONConstants::ChannelBlockDataType();
483 break;
484 case kMansoTracksDataBlock:
485 t = AliHLTMUONConstants::MansoTracksBlockDataType();
486 break;
487 case kMansoCandidatesDataBlock:
488 t = AliHLTMUONConstants::MansoCandidatesBlockDataType();
489 break;
490 case kSinglesDecisionDataBlock:
491 t = AliHLTMUONConstants::SinglesDecisionBlockDataType();
492 break;
493 case kPairsDecisionDataBlock:
494 t = AliHLTMUONConstants::PairsDecisionBlockDataType();
495 break;
496 default:
497 return "UNKNOWN";
498 }
499 memcpy(&str, &t.fID, kAliHLTComponentDataTypefIDsize);
500 // Must insert the NULL character to make this an ANSI C string.
501 str[kAliHLTComponentDataTypefIDsize] = '\0';
502 return &str[0];
503}
504
505
878cb83d 506const char* AliHLTMUONUtils::FailureReasonToString(WhyNotValid reason)
507{
508 /// This method converts the WhyNotValid enumeration to a string representation.
509
510 switch (reason)
511 {
512 case kNoReason: return "kNoReason";
513 case kHeaderContainsWrongType: return "kHeaderContainsWrongType";
514 case kHeaderContainsWrongRecordWidth: return "kHeaderContainsWrongRecordWidth";
dba14d7d 515 case kInvalidIdValue: return "kInvalidIdValue";
516 case kInvalidTriggerIdValue: return "kInvalidTriggerIdValue";
517 case kInvalidTrackIdValue: return "kInvalidTrackIdValue";
878cb83d 518 case kReservedBitsNotZero: return "kReservedBitsNotZero";
519 case kParticleSignBitsNotValid: return "kParticleSignBitsNotValid";
520 case kHitNotMarkedAsNil: return "kHitNotMarkedAsNil";
dba14d7d 521 case kInvalidDetElementNumber: return "kInvalidDetElementNumber";
a090ff22 522 case kInvalidChamberNumber: return "kInvalidChamberNumber";
dba14d7d 523 case kHitIsNil: return "kHitIsNil";
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.
66622a82 1627 // between 1 and the maximum number of channels per DDL / 2.
1628 // 1<<16 taken from the 11 bits MANU ID + 6 bits channel address
1629 // divided by 2 since we are counting bending and non bending
1630 // planes separately.
1631 if (cluster.fNchannelsB < 1 or (1<<16) < cluster.fNchannelsB)
dba14d7d 1632 {
1633 if (reason != NULL and reasonCount < maxCount)
1634 {
66622a82 1635 reason[reasonCount] = kInvalidChannelCountB;
dba14d7d 1636 reasonCount++;
1637 }
1638 result = false;
1639 }
66622a82 1640 if (cluster.fNchannelsNB < 1 or (1<<16) < cluster.fNchannelsNB)
1641 {
1642 if (reason != NULL and reasonCount < maxCount)
1643 {
1644 reason[reasonCount] = kInvalidChannelCountNB;
1645 reasonCount++;
1646 }
1647 result = false;
1648 }
1649
83d66053 1650
66622a82 1651 // The charge values must be a positive value or -1.
1652 if (not (cluster.fChargeB >= 0 or cluster.fChargeB == -1))
1653 {
1654 if (reason != NULL and reasonCount < maxCount)
1655 {
1656 reason[reasonCount] = kInvalidChargeB;
1657 reasonCount++;
1658 }
1659 result = false;
1660 }
1661 if (not (cluster.fChargeNB >= 0 or cluster.fChargeNB == -1))
83d66053 1662 {
1663 if (reason != NULL and reasonCount < maxCount)
1664 {
66622a82 1665 reason[reasonCount] = kInvalidChargeNB;
83d66053 1666 reasonCount++;
1667 }
1668 result = false;
1669 }
dba14d7d 1670
1671 return result;
b727f838 1672}
1673
1674
878cb83d 1675bool AliHLTMUONUtils::IntegrityOk(
1676 const AliHLTMUONClustersBlockStruct& block,
dba14d7d 1677 WhyNotValid* reason,
1678 AliHLTUInt32_t* recordNum,
1679 AliHLTUInt32_t& reasonCount
878cb83d 1680 )
b727f838 1681{
878cb83d 1682 /// This method is used to check more extensively if the integrity of the
dba14d7d 1683 /// dHLT internal clusters data block is OK and returns true in that case.
878cb83d 1684 /// [in] \param block The clusters data block to check.
dba14d7d 1685 /// [out] \param reason If this is not NULL, then it is assumed to point
1686 /// to an array of at least 'reasonCount' number of elements. It will
1687 /// be filled with the reason codes describing why the data block is
1688 /// not valid.
1689 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1690 /// to an array of at least 'reasonCount' number of elements. It will
1691 /// be filled with the number of the cluster structure that had a problem.
1692 /// The value 'recordNum[i]' will only contain a valid value if
1693 /// the corresponding 'reason[i]' contains one of:
1694 /// - kInvalidIdValue
1695 /// - kHitIsNil
1696 /// - kInvalidDetElementNumber
66622a82 1697 /// - kInvalidChannelCountB
1698 /// - kInvalidChannelCountNB
1699 /// - kInvalidChargeB
1700 /// - kInvalidChargeNB
dba14d7d 1701 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1702 /// was set and is valid or not.
1703 /// [in/out] \param reasonCount This should initially specify the size of
1704 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1705 /// with the number of items actually filled into the arrays upon exit
1706 /// from this method.
878cb83d 1707 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1708
dba14d7d 1709 AliHLTUInt32_t maxCount = reasonCount;
1710 bool result = HeaderOk(block, reason, reasonCount);
b727f838 1711
23ad6161 1712 const AliHLTMUONClusterStruct* cluster =
1713 reinterpret_cast<const AliHLTMUONClusterStruct*>(&block + 1);
1714
c8ec7c7e 1715 // Check if any ID is duplicated.
1716 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1717 {
23ad6161 1718 AliHLTInt32_t id = cluster[i].fId;
dba14d7d 1719 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
c8ec7c7e 1720 {
23ad6161 1721 if (id == cluster[j].fId)
878cb83d 1722 {
dba14d7d 1723 if (reason != NULL and reasonCount < maxCount)
1724 {
1725 reason[reasonCount] = kFoundDuplicateIDs;
1726 reasonCount++;
1727 }
1728 result = false;
1729 }
1730 }
1731 }
1732
1733 // Check if any hit structure has been duplicated.
1734 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1735 {
1736 const AliHLTMUONRecHitStruct& h = cluster[i].fHit;
1737 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1738 {
1739 if (h == cluster[j].fHit)
1740 {
1741 if (reason != NULL and reasonCount < maxCount)
1742 {
1743 reason[reasonCount] = kFoundDuplicateHits;
1744 reasonCount++;
1745 }
1746 result = false;
1747 }
1748 }
1749 }
1750
1751 // Check integrity of individual cluster structures.
1752 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1753 {
1754 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1755 if (not IntegrityOk(cluster[i], reason+reasonCount, filledCount))
1756 {
1757 // reasons filled in IntegrityOk, now we just need to adjust
1758 // reasonCount and fill the recordNum values.
1759 if (recordNum != NULL)
1760 {
1761 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1762 recordNum[reasonCount + n] = i;
878cb83d 1763 }
dba14d7d 1764 reasonCount += filledCount;
1765 result = false;
c8ec7c7e 1766 }
1767 }
1768
dba14d7d 1769 return result;
1770}
1771
1772
1773bool AliHLTMUONUtils::IntegrityOk(
1774 const AliHLTMUONChannelStruct& channel,
1775 WhyNotValid* reason,
1776 AliHLTUInt32_t& reasonCount
1777 )
1778{
1779 /// This method is used to check more extensively if the integrity of the
1780 /// channel structure is OK and returns true in that case.
1781 /// [in] \param cluster The channel structure to check.
1782 /// [out] \param reason If this is not NULL, then it is assumed to point
1783 /// to an array of at least 'reasonCount' number of elements. It will
1784 /// be filled with the reason codes describing why the structure is
1785 /// not valid.
1786 /// [in/out] \param reasonCount This should initially specify the size of
1787 /// the array pointed to by 'reason'. It will be filled with the number
1788 /// of items actually filled into the reason array upon exit from this
1789 /// method.
1790 /// \returns true if there is no problem with the structure and false otherwise.
1791
1792 AliHLTUInt32_t maxCount = reasonCount;
1793 reasonCount = 0;
1794 bool result = true;
1795
1796 // Check that the channel ID has a valid value.
1797 if (not (channel.fClusterId >= 0 or channel.fClusterId == -1))
1798 {
1799 if (reason != NULL and reasonCount < maxCount)
1800 {
1801 reason[reasonCount] = kInvalidIdValue;
1802 reasonCount++;
1803 }
1804 result = false;
1805 }
1806
1807 // Check that the bus patch ID has a valid value, which fits into 12 bits.
1808 if ((channel.fBusPatch & (~0xFFF)) != 0)
1809 {
1810 if (reason != NULL and reasonCount < maxCount)
1811 {
1812 reason[reasonCount] = kInvalidBusPatchId;
1813 reasonCount++;
1814 }
1815 result = false;
1816 }
1817
1818 // Check that the MANU ID has a valid value, which fits into 11 bits.
1819 if ((channel.fManu & (~0x7FF)) != 0)
1820 {
1821 if (reason != NULL and reasonCount < maxCount)
1822 {
1823 reason[reasonCount] = kInvalidManuId;
1824 reasonCount++;
1825 }
1826 result = false;
1827 }
1828
1829 // Check that the channel address has a valid value, which fits into 6 bits.
1830 if ((channel.fChannelAddress & (~0x3F)) != 0)
1831 {
1832 if (reason != NULL and reasonCount < maxCount)
1833 {
1834 reason[reasonCount] = kInvalidChannelAddress;
1835 reasonCount++;
1836 }
1837 result = false;
1838 }
1839
1840 // Check that the ADC signal has a valid value, which fits into 12 bits.
1841 if ((channel.fSignal & (~0xFFF)) != 0)
1842 {
1843 if (reason != NULL and reasonCount < maxCount)
1844 {
1845 reason[reasonCount] = kInvalidSignal;
1846 reasonCount++;
1847 }
1848 result = false;
1849 }
1850
1851 // Check that the raw data word corresponds to the unpacked values for
1852 // the ADC signal, MANU ID and channel address.
1853 UShort_t manuId; UChar_t channelId; UShort_t adc;
1854 AliMUONTrackerDDLDecoderEventHandler::UnpackADC(
1855 channel.fRawDataWord, manuId, channelId, adc
1856 );
1857 if (manuId != channel.fManu or channelId != channel.fChannelAddress
1858 or adc != channel.fSignal
1859 )
1860 {
1861 if (reason != NULL and reasonCount < maxCount)
1862 {
1863 reason[reasonCount] = kDataWordDifferent;
1864 reasonCount++;
1865 }
1866 result = false;
1867 }
1868
1869 return result;
b727f838 1870}
1871
90a74d7a 1872
878cb83d 1873bool AliHLTMUONUtils::IntegrityOk(
1874 const AliHLTMUONChannelsBlockStruct& block,
dba14d7d 1875 WhyNotValid* reason,
1876 AliHLTUInt32_t* recordNum,
1877 AliHLTUInt32_t& reasonCount
878cb83d 1878 )
b727f838 1879{
878cb83d 1880 /// This method is used to check more extensively if the integrity of the
dba14d7d 1881 /// dHLT internal channels data block is OK and returns true in that case.
1882 /// [in] \param block The channels data block to check.
1883 /// [out] \param reason If this is not NULL, then it is assumed to point
1884 /// to an array of at least 'reasonCount' number of elements. It will
1885 /// be filled with the reason codes describing why the data block is
1886 /// not valid.
1887 /// [out] \param recordNum If this is not NULL, then it is assumed to point
1888 /// to an array of at least 'reasonCount' number of elements. It will
1889 /// be filled with the number of the channel structure that had a problem.
1890 /// The value 'recordNum[i]' will only contain a valid value if
1891 /// the corresponding 'reason[i]' contains one of:
1892 /// - kInvalidIdValue
1893 /// - kInvalidBusPatchId
1894 /// - kInvalidManuId
1895 /// - kInvalidChannelAddress
1896 /// - kInvalidSignal
1897 /// - kDataWordDifferent
1898 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1899 /// was set and is valid or not.
1900 /// [in/out] \param reasonCount This should initially specify the size of
1901 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
1902 /// with the number of items actually filled into the arrays upon exit
1903 /// from this method.
878cb83d 1904 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 1905
dba14d7d 1906 AliHLTUInt32_t maxCount = reasonCount;
1907 bool result = HeaderOk(block, reason, reasonCount);
1908
1909 const AliHLTMUONChannelStruct* channel =
1910 reinterpret_cast<const AliHLTMUONChannelStruct*>(&block + 1);
dba14d7d 1911
1912 // Check integrity of individual channel structures.
1913 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1914 {
1915 AliHLTUInt32_t filledCount = maxCount - reasonCount;
1916 if (not IntegrityOk(channel[i], reason+reasonCount, filledCount))
1917 {
1918 // reasons filled in IntegrityOk, now we just need to adjust
1919 // reasonCount and fill the recordNum values.
1920 if (recordNum != NULL)
1921 {
1922 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1923 recordNum[reasonCount + n] = i;
1924 }
1925 reasonCount += filledCount;
1926 result = false;
1927 }
1928 }
1929
1930 return result;
26a4668d 1931}
90a74d7a 1932
1933
878cb83d 1934bool AliHLTMUONUtils::IntegrityOk(
1935 const AliHLTMUONMansoTrackStruct& track,
dba14d7d 1936 WhyNotValid* reason,
1937 AliHLTUInt32_t& reasonCount
878cb83d 1938 )
90a74d7a 1939{
878cb83d 1940 /// This method is used to check more extensively if the integrity of the
1941 /// Manso track structure is OK and returns true in that case.
1942 /// [in] \param track The track structure to check.
dba14d7d 1943 /// [out] \param reason If this is not NULL, then it is assumed to point
1944 /// to an array of at least 'reasonCount' number of elements. It will
1945 /// be filled with the reason codes describing why the structure is
1946 /// not valid.
1947 /// [in/out] \param reasonCount This should initially specify the size of
1948 /// the array pointed to by 'reason'. It will be filled with the number
1949 /// of items actually filled into the reason array upon exit from this
1950 /// method.
878cb83d 1951 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 1952
dba14d7d 1953 AliHLTUInt32_t maxCount = reasonCount;
1954 reasonCount = 0;
1955 bool result = true;
1956
1957 // Check that the Manso track ID has a valid value.
1958 if (not (track.fId >= 0 or track.fId == -1))
1959 {
1960 if (reason != NULL and reasonCount < maxCount)
1961 {
1962 reason[reasonCount] = kInvalidIdValue;
1963 reasonCount++;
1964 }
1965 result = false;
1966 }
1967
1968 // Check that the corresponding trigger record ID has a valid value.
1969 if (not (track.fTrigRec >= 0 or track.fTrigRec == -1))
1970 {
1971 if (reason != NULL and reasonCount < maxCount)
1972 {
1973 reason[reasonCount] = kInvalidTriggerIdValue;
1974 reasonCount++;
1975 }
1976 result = false;
1977 }
1978
90a74d7a 1979 // Make sure that the reserved bits in the fFlags field are set
1980 // to zero.
878cb83d 1981 if ((track.fFlags & 0x3FFFFFF0) != 0)
1982 {
dba14d7d 1983 if (reason != NULL and reasonCount < maxCount)
1984 {
1985 reason[reasonCount] = kReservedBitsNotZero;
1986 reasonCount++;
1987 }
1988 result = false;
878cb83d 1989 }
90a74d7a 1990
1991 // Make sure the sign is not invalid.
878cb83d 1992 if ((track.fFlags & 0xC0000000) == 0xC0000000)
1993 {
dba14d7d 1994 if (reason != NULL and reasonCount < maxCount)
1995 {
1996 reason[reasonCount] = kParticleSignBitsNotValid;
1997 reasonCount++;
1998 }
1999 result = false;
878cb83d 2000 }
90a74d7a 2001
2002 // Check that fHit[i] is nil if the corresponding bit in the
2003 // flags word is zero.
2004 const AliHLTMUONRecHitStruct& nilhit
2005 = AliHLTMUONConstants::NilRecHitStruct();
878cb83d 2006 if ( ((track.fFlags & 0x1) == 0 and track.fHit[0] != nilhit) or
2007 ((track.fFlags & 0x2) == 0 and track.fHit[1] != nilhit) or
2008 ((track.fFlags & 0x4) == 0 and track.fHit[2] != nilhit) or
2009 ((track.fFlags & 0x8) == 0 and track.fHit[3] != nilhit)
2010 )
2011 {
dba14d7d 2012 if (reason != NULL and reasonCount < maxCount)
2013 {
2014 reason[reasonCount] = kHitNotMarkedAsNil;
2015 reasonCount++;
2016 }
2017 result = false;
2018 }
2019
2020 // Check that the chi squared value is valid
2021 if (not (track.fChi2 >= 0 or track.fChi2 == -1))
2022 {
2023 if (reason != NULL and reasonCount < maxCount)
2024 {
2025 reason[reasonCount] = kChiSquareInvalid;
2026 reasonCount++;
2027 }
2028 result = false;
2029 }
2030
2031 // Check that if chi squared is -1 then the momentum vector is zero.
2032 if (track.fChi2 == -1 and
2033 not (track.fPx == 0 and track.fPy == 0 and track.fPz == 0)
2034 )
2035 {
2036 if (reason != NULL and reasonCount < maxCount)
2037 {
2038 reason[reasonCount] = kMomentumVectorNotZero;
2039 reasonCount++;
2040 }
2041 result = false;
878cb83d 2042 }
90a74d7a 2043
a090ff22 2044 // Check the individual hits
2045 for (int i = 0; i < 4; i++)
2046 {
2047 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2048 if (not IntegrityOk(track.fHit[i], reason + reasonCount, filledCount))
2049 {
2050 reasonCount += filledCount;
2051 result = false;
2052 }
2053 }
2054
dba14d7d 2055 return result;
90a74d7a 2056}
2057
2058
878cb83d 2059bool AliHLTMUONUtils::IntegrityOk(
2060 const AliHLTMUONMansoTracksBlockStruct& block,
2061 WhyNotValid* reason,
dba14d7d 2062 AliHLTUInt32_t* recordNum,
2063 AliHLTUInt32_t& reasonCount
878cb83d 2064 )
90a74d7a 2065{
878cb83d 2066 /// This method is used to check more extensively if the integrity of the
dba14d7d 2067 /// dHLT internal Manso track data block is OK and returns true in that case.
878cb83d 2068 /// [in] \param block The Manso track data block to check.
dba14d7d 2069 /// [out] \param reason If this is not NULL, then it is assumed to point
2070 /// to an array of at least 'reasonCount' number of elements. It will
2071 /// be filled with the reason codes describing why the data block is
2072 /// not valid.
2073 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2074 /// to an array of at least 'reasonCount' number of elements. It will
2075 /// be filled with the number of the Manso track that had a problem.
2076 /// The value 'recordNum[i]' will only contain a valid value if
2077 /// the corresponding 'reason[i]' contains one of:
2078 /// - kInvalidIdValue
2079 /// - kInvalidTriggerIdValue
878cb83d 2080 /// - kReservedBitsNotZero
2081 /// - kParticleSignBitsNotValid
2082 /// - kHitNotMarkedAsNil
dba14d7d 2083 /// - kChiSquareInvalid
2084 /// - kMomentumVectorNotZero
a090ff22 2085 /// - kInvalidDetElementNumber
2086 /// - kInvalidChamberNumber
dba14d7d 2087 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2088 /// was set and is valid or not.
2089 /// [in/out] \param reasonCount This should initially specify the size of
2090 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2091 /// with the number of items actually filled into the arrays upon exit
2092 /// from this method.
878cb83d 2093 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2094
dba14d7d 2095 AliHLTUInt32_t maxCount = reasonCount;
2096 bool result = HeaderOk(block, reason, reasonCount);
2097
23ad6161 2098 const AliHLTMUONMansoTrackStruct* track =
2099 reinterpret_cast<const AliHLTMUONMansoTrackStruct*>(&block + 1);
2100
878cb83d 2101 // Check if any track ID is duplicated.
90a74d7a 2102 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2103 {
23ad6161 2104 AliHLTInt32_t id = track[i].fId;
dba14d7d 2105 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
90a74d7a 2106 {
23ad6161 2107 if (id == track[j].fId)
878cb83d 2108 {
dba14d7d 2109 if (reason != NULL and reasonCount < maxCount)
2110 {
2111 reason[reasonCount] = kFoundDuplicateIDs;
2112 reasonCount++;
2113 }
2114 result = false;
878cb83d 2115 }
90a74d7a 2116 }
2117 }
dba14d7d 2118
2119 // Check that all the tracks have integrity.
90a74d7a 2120 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2121 {
dba14d7d 2122 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2123 if (not IntegrityOk(track[i], reason+reasonCount, filledCount))
878cb83d 2124 {
dba14d7d 2125 // reasons filled in IntegrityOk, now we just need to adjust
2126 // reasonCount and fill the recordNum values.
2127 if (recordNum != NULL)
2128 {
2129 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2130 recordNum[reasonCount + n] = i;
2131 }
2132 reasonCount += filledCount;
2133 result = false;
878cb83d 2134 }
90a74d7a 2135 }
dba14d7d 2136
2137 return result;
2138}
90a74d7a 2139
dba14d7d 2140
2141bool AliHLTMUONUtils::IntegrityOk(
2142 const AliHLTMUONMansoCandidateStruct& candidate,
2143 WhyNotValid* reason,
2144 AliHLTUInt32_t& reasonCount
2145 )
2146{
2147 /// This method is used to check more extensively if the integrity of the
2148 /// Manso track candidate structure is OK and returns true in that case.
2149 /// [in] \param track The track candidate structure to check.
2150 /// [out] \param reason If this is not NULL, then it is assumed to point
2151 /// to an array of at least 'reasonCount' number of elements. It will
2152 /// be filled with the reason codes describing why the structure is
2153 /// not valid.
2154 /// [in/out] \param reasonCount This should initially specify the size of
2155 /// the array pointed to by 'reason'. It will be filled with the number
2156 /// of items actually filled into the reason array upon exit from this
2157 /// method.
2158 /// \returns true if there is no problem with the structure and false otherwise.
2159
2160 // First check the integrity of the candidate track structure.
2161 AliHLTUInt32_t maxCount = reasonCount;
2162 bool result = IntegrityOk(candidate.fTrack, reason, reasonCount);
2163
2164 // Now check that the ROIs are reasonable.
2165 // The radius must be positive or -1 indicating computation error and
2166 // the corresponding hit in the track must be within the ROI.
2167 for (AliHLTUInt32_t i = 0; i < 4; i++)
2168 {
2169 if (not (candidate.fRoI[i].fRadius >= 0 or candidate.fRoI[i].fRadius == -1))
2170 {
2171 if (reason != NULL and reasonCount < maxCount)
2172 {
2173 reason[reasonCount] = kRoiRadiusInvalid;
2174 reasonCount++;
2175 }
2176 result = false;
2177 }
2178
2179 // Check if the corresponding hit was even found in the track.
2180 if ( (candidate.fTrack.fFlags & (0x1 << i)) == 0 ) continue;
2181
2182 double dx = candidate.fRoI[i].fX - candidate.fTrack.fHit[i].fX;
2183 double dy = candidate.fRoI[i].fY - candidate.fTrack.fHit[i].fY;
2184 double dz = candidate.fRoI[i].fZ - candidate.fTrack.fHit[i].fZ;
2185 double r = sqrt(dx*dx + dy*dy);
2186 // Check if the projected distance between ROI centre and hit is
2187 // bigger than the ROI radius. Also the difference between z
2188 // coordinates should not exceed 20 cm.
2189 if (r > candidate.fRoI[i].fRadius or fabs(dz) > 20.)
2190 {
2191 if (reason != NULL and reasonCount < maxCount)
2192 {
2193 reason[reasonCount] = kHitNotWithinRoi;
2194 reasonCount++;
2195 }
2196 result = false;
2197 }
2198 }
2199
2200 return result;
90a74d7a 2201}
2202
2203
878cb83d 2204bool AliHLTMUONUtils::IntegrityOk(
2205 const AliHLTMUONMansoCandidatesBlockStruct& block,
2206 WhyNotValid* reason,
dba14d7d 2207 AliHLTUInt32_t* recordNum,
2208 AliHLTUInt32_t& reasonCount
878cb83d 2209 )
90a74d7a 2210{
878cb83d 2211 /// This method is used to check more extensively if the integrity of the
dba14d7d 2212 /// dHLT internal Manso candidates data block is OK and returns true in
2213 /// that case.
878cb83d 2214 /// [in] \param block The Manso track candidate data block to check.
dba14d7d 2215 /// [out] \param reason If this is not NULL, then it is assumed to point
2216 /// to an array of at least 'reasonCount' number of elements. It will
2217 /// be filled with the reason codes describing why the data block is
2218 /// not valid.
2219 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2220 /// to an array of at least 'reasonCount' number of elements. It will
2221 /// be filled with the number of the track candidate that had a problem.
2222 /// The value 'recordNum[i]' will only contain a valid value if
2223 /// the corresponding 'reason[i]' contains one of:
2224 /// - kInvalidIdValue
2225 /// - kInvalidTriggerIdValue
878cb83d 2226 /// - kReservedBitsNotZero
2227 /// - kParticleSignBitsNotValid
2228 /// - kHitNotMarkedAsNil
dba14d7d 2229 /// - kChiSquareInvalid
2230 /// - kRoiRadiusInvalid
2231 /// - kHitNotWithinRoi
2232 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2233 /// was set and is valid or not.
2234 /// [in/out] \param reasonCount This should initially specify the size of
2235 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2236 /// with the number of items actually filled into the arrays upon exit
2237 /// from this method.
878cb83d 2238 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2239
dba14d7d 2240 AliHLTUInt32_t maxCount = reasonCount;
2241 bool result = HeaderOk(block, reason, reasonCount);
90a74d7a 2242
23ad6161 2243 const AliHLTMUONMansoCandidateStruct* candidate =
2244 reinterpret_cast<const AliHLTMUONMansoCandidateStruct*>(&block + 1);
2245
878cb83d 2246 // Check if any candidate track ID is duplicated.
2247 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2248 {
2249 AliHLTInt32_t id = candidate[i].fTrack.fId;
dba14d7d 2250 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
878cb83d 2251 {
2252 if (id == candidate[j].fTrack.fId)
2253 {
dba14d7d 2254 if (reason != NULL and reasonCount < maxCount)
2255 {
2256 reason[reasonCount] = kFoundDuplicateIDs;
2257 reasonCount++;
2258 }
2259 result = false;
878cb83d 2260 }
2261 }
2262 }
2263
dba14d7d 2264 // Check that all the track candidates have integrity.
90a74d7a 2265 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2266 {
dba14d7d 2267 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2268 if (not IntegrityOk(candidate[i], reason+reasonCount, filledCount))
878cb83d 2269 {
dba14d7d 2270 // reasons filled in IntegrityOk, now we just need to adjust
2271 // reasonCount and fill the recordNum values.
2272 if (recordNum != NULL)
2273 {
2274 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2275 recordNum[reasonCount + n] = i;
2276 }
2277 reasonCount += filledCount;
2278 result = false;
878cb83d 2279 }
90a74d7a 2280 }
2281
dba14d7d 2282 return result;
90a74d7a 2283}
2284
2285
878cb83d 2286bool AliHLTMUONUtils::IntegrityOk(
2287 const AliHLTMUONTrackDecisionStruct& decision,
dba14d7d 2288 WhyNotValid* reason,
2289 AliHLTUInt32_t& reasonCount
878cb83d 2290 )
90a74d7a 2291{
878cb83d 2292 /// This method is used to check more extensively if the integrity of the
2293 /// single track trigger decision structure is OK and returns true in that case.
2294 /// [in] \param decision The trigger decision structure to check.
dba14d7d 2295 /// [out] \param reason If this is not NULL, then it is assumed to point
2296 /// to an array of at least 'reasonCount' number of elements. It will
2297 /// be filled with the reason codes describing why the structure is not
2298 /// valid.
2299 /// [in/out] \param reasonCount This should initially specify the size of
2300 /// the array pointed to by 'reason'. It will be filled with the number
2301 /// of items actually filled into the reason array upon exit from this
2302 /// method.
878cb83d 2303 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 2304
dba14d7d 2305 AliHLTUInt32_t maxCount = reasonCount;
2306 reasonCount = 0;
2307 bool result = true;
2308
2309 // The track ID value must be positive or -1.
2310 if (not (decision.fTrackId >= 0 or decision.fTrackId == -1))
2311 {
2312 if (reason != NULL and reasonCount < maxCount)
2313 {
2314 reason[reasonCount] = kInvalidTrackIdValue;
2315 reasonCount++;
2316 }
2317 result = false;
2318 }
2319
90a74d7a 2320 // Make sure that the reserved bits in the fTriggerBits field are set
2321 // to zero.
878cb83d 2322 if ((decision.fTriggerBits & 0xFFFFFFFC) != 0)
2323 {
dba14d7d 2324 if (reason != NULL and reasonCount < maxCount)
2325 {
2326 reason[reasonCount] = kReservedBitsNotZero;
2327 reasonCount++;
2328 }
2329 result = false;
878cb83d 2330 }
2331
2332 // The pT should be -1 or a positive number.
2333 if (decision.fPt != -1. and decision.fPt < 0.)
2334 {
dba14d7d 2335 if (reason != NULL and reasonCount < maxCount)
2336 {
2337 reason[reasonCount] = kPtValueNotValid;
2338 reasonCount++;
2339 }
2340 result = false;
878cb83d 2341 }
2342
dba14d7d 2343 return result;
90a74d7a 2344}
2345
2346
878cb83d 2347bool AliHLTMUONUtils::IntegrityOk(
2348 const AliHLTMUONSinglesDecisionBlockStruct& block,
2349 WhyNotValid* reason,
dba14d7d 2350 AliHLTUInt32_t* recordNum,
2351 AliHLTUInt32_t& reasonCount
878cb83d 2352 )
90a74d7a 2353{
878cb83d 2354 /// This method is used to check more extensively if the integrity of the
dba14d7d 2355 /// dHLT internal single track trigger decision data block is OK and returns
2356 /// true in that case.
878cb83d 2357 /// [in] \param block The single track trigger decision data block to check.
dba14d7d 2358 /// [out] \param reason If this is not NULL, then it is assumed to point
2359 /// to an array of at least 'reasonCount' number of elements. It will
2360 /// be filled with the reason codes describing why the data block is
2361 /// not valid.
2362 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2363 /// to an array of at least 'reasonCount' number of elements. It will
2364 /// be filled with the number of the trigger decision that had a problem.
2365 /// The value 'recordNum[i]' will only contain a valid value if
2366 /// the corresponding 'reason[i]' contains one of:
2367 /// - kInvalidTrackIdValue
878cb83d 2368 /// - kReservedBitsNotZero
2369 /// - kPtValueNotValid
dba14d7d 2370 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2371 /// was set and is valid or not.
2372 /// [in/out] \param reasonCount This should initially specify the size of
2373 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2374 /// with the number of items actually filled into the arrays upon exit
2375 /// from this method.
878cb83d 2376 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2377
dba14d7d 2378 AliHLTUInt32_t maxCount = reasonCount;
2379 bool result = HeaderOk(block, reason, reasonCount);
23ad6161 2380
2381 const AliHLTMUONTrackDecisionStruct* decision =
2382 reinterpret_cast<const AliHLTMUONTrackDecisionStruct*>(&block + 1);
90a74d7a 2383
878cb83d 2384 // Check that there are no duplicate trigger entries.
2385 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2386 {
2387 AliHLTInt32_t id = decision[i].fTrackId;
dba14d7d 2388 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
878cb83d 2389 {
2390 if (id == decision[j].fTrackId)
2391 {
dba14d7d 2392 if (reason != NULL and reasonCount < maxCount)
2393 {
2394 reason[reasonCount] = kFoundDuplicateTriggers;
2395 reasonCount++;
2396 }
2397 result = false;
878cb83d 2398 }
2399 }
2400 }
2401
90a74d7a 2402 // Check that the trigger bits for each track have integrity.
2403 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2404 {
dba14d7d 2405 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2406 if (not IntegrityOk(decision[i], reason+reasonCount, filledCount))
878cb83d 2407 {
dba14d7d 2408 // Reasons filled in IntegrityOk, now we just need to adjust
2409 // reasonCount and fill the recordNum values.
2410 if (recordNum != NULL)
2411 {
2412 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2413 recordNum[reasonCount + n] = i;
2414 }
2415 reasonCount += filledCount;
2416 result = false;
878cb83d 2417 }
90a74d7a 2418 }
2419
dba14d7d 2420 return result;
90a74d7a 2421}
2422
2423
878cb83d 2424bool AliHLTMUONUtils::IntegrityOk(
2425 const AliHLTMUONPairDecisionStruct& decision,
dba14d7d 2426 WhyNotValid* reason,
2427 AliHLTUInt32_t& reasonCount
878cb83d 2428 )
90a74d7a 2429{
878cb83d 2430 /// This method is used to check more extensively if the integrity of the
2431 /// track pair trigger decision structure is OK and returns true in that case.
2432 /// [in] \param decision The trigger decision structure to check.
dba14d7d 2433 /// [out] \param reason If this is not NULL, then it is assumed to point
2434 /// to an array of at least 'reasonCount' number of elements. It will
2435 /// be filled with the reason codes describing why the structure is not
2436 /// valid.
2437 /// [in/out] \param reasonCount This should initially specify the size of
2438 /// the array pointed to by 'reason'. It will be filled with the number
2439 /// of items actually filled into the reason array upon exit from this
2440 /// method.
878cb83d 2441 /// \returns true if there is no problem with the structure and false otherwise.
6253e09b 2442
dba14d7d 2443 AliHLTUInt32_t maxCount = reasonCount;
2444 reasonCount = 0;
2445 bool result = true;
2446
2447 //kInvalidTrackIdValue
2448
2449 // The track IDs must have a positive value or -1.
2450 if (not (decision.fTrackAId >= 0 or decision.fTrackAId == -1) or
2451 not (decision.fTrackBId >= 0 or decision.fTrackBId == -1)
2452 )
2453 {
2454 if (reason != NULL and reasonCount < maxCount)
2455 {
2456 reason[reasonCount] = kInvalidTrackIdValue;
2457 reasonCount++;
2458 }
2459 result = false;
2460 }
2461
90a74d7a 2462 // Make sure that the reserved bits in the fTriggerBits field are set
2463 // to zero.
878cb83d 2464 if ((decision.fTriggerBits & 0xFFFFFF80) != 0)
2465 {
dba14d7d 2466 if (reason != NULL and reasonCount < maxCount)
2467 {
2468 reason[reasonCount] = kReservedBitsNotZero;
2469 reasonCount++;
2470 }
2471 result = false;
878cb83d 2472 }
90a74d7a 2473
878cb83d 2474 // Check that the track IDs are not the same.
2475 if (decision.fTrackAId == decision.fTrackBId)
2476 {
dba14d7d 2477 if (reason != NULL and reasonCount < maxCount)
2478 {
2479 reason[reasonCount] = kPairTrackIdsAreIdentical;
2480 reasonCount++;
2481 }
2482 result = false;
878cb83d 2483 }
2484
2485 // The invariant mass should be -1 or a positive number.
2486 if (decision.fInvMass != -1. and decision.fInvMass < 0.)
2487 {
dba14d7d 2488 if (reason != NULL and reasonCount < maxCount)
2489 {
2490 reason[reasonCount] = kMassValueNotValid;
2491 reasonCount++;
2492 }
2493 result = false;
878cb83d 2494 }
90a74d7a 2495
2496 // Neither the high pt (hipt) or low pt (lopt) count bits can be > 2.
90a74d7a 2497 AliHLTUInt8_t lowPtCount = (decision.fTriggerBits & 0x00000003);
2498 AliHLTUInt8_t highPtCount = (decision.fTriggerBits & 0x0000000C) >> 2;
878cb83d 2499 if (lowPtCount > 2)
2500 {
dba14d7d 2501 if (reason != NULL and reasonCount < maxCount)
2502 {
2503 reason[reasonCount] = kLowPtCountInvalid;
2504 reasonCount++;
2505 }
2506 result = false;
878cb83d 2507 }
2508 if (highPtCount > 2)
2509 {
dba14d7d 2510 if (reason != NULL and reasonCount < maxCount)
2511 {
2512 reason[reasonCount] = kHighPtCountInvalid;
2513 reasonCount++;
2514 }
2515 result = false;
878cb83d 2516 }
90a74d7a 2517
dba14d7d 2518 return result;
90a74d7a 2519}
2520
2521
878cb83d 2522bool AliHLTMUONUtils::IntegrityOk(
2523 const AliHLTMUONPairsDecisionBlockStruct& block,
2524 WhyNotValid* reason,
dba14d7d 2525 AliHLTUInt32_t* recordNum,
2526 AliHLTUInt32_t& reasonCount
878cb83d 2527 )
90a74d7a 2528{
878cb83d 2529 /// This method is used to check more extensively if the integrity of the
dba14d7d 2530 /// dHLT internal track pair trigger decision data block is OK and returns
2531 /// true in that case.
878cb83d 2532 /// [in] \param block The track pair trigger decision data block to check.
dba14d7d 2533 /// [out] \param reason If this is not NULL, then it is assumed to point
2534 /// to an array of at least 'reasonCount' number of elements. It will
2535 /// be filled with the reason codes describing why the data block is
2536 /// not valid.
2537 /// [out] \param recordNum If this is not NULL, then it is assumed to point
2538 /// to an array of at least 'reasonCount' number of elements. It will
2539 /// be filled with the number of the trigger decision that had a problem.
2540 /// The value 'recordNum[i]' will only contain a valid value if
2541 /// the corresponding 'reason[i]' contains one of:
2542 /// - kInvalidTrackIdValue
878cb83d 2543 /// - kReservedBitsNotZero
2544 /// - kPairTrackIdsAreIdentical
2545 /// - kMassValueNotValid
2546 /// - kLowPtCountInvalid
2547 /// - kHighPtCountInvalid
dba14d7d 2548 /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2549 /// was set and is valid or not.
2550 /// [in/out] \param reasonCount This should initially specify the size of
2551 /// the array pointed to by 'reason' and 'recordNum'. It will be filled
2552 /// with the number of items actually filled into the arrays upon exit
2553 /// from this method.
878cb83d 2554 /// \returns true if there is no problem with the data and false otherwise.
6253e09b 2555
dba14d7d 2556 AliHLTUInt32_t maxCount = reasonCount;
2557 bool result = HeaderOk(block, reason, reasonCount);
90a74d7a 2558
23ad6161 2559 const AliHLTMUONPairDecisionStruct* decision =
2560 reinterpret_cast<const AliHLTMUONPairDecisionStruct*>(&block + 1);
2561
878cb83d 2562 // Check that there are no duplicate trigger entries.
2563 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2564 {
2565 AliHLTInt32_t ta = decision[i].fTrackAId;
2566 AliHLTInt32_t tb = decision[i].fTrackBId;
dba14d7d 2567 for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
878cb83d 2568 {
2569 if (ta == decision[j].fTrackAId and tb == decision[j].fTrackBId)
2570 {
dba14d7d 2571 if (reason != NULL and reasonCount < maxCount)
2572 {
2573 reason[reasonCount] = kFoundDuplicateTriggers;
2574 reasonCount++;
2575 }
2576 result = false;
878cb83d 2577 }
2578 }
2579 }
2580
90a74d7a 2581 // Check that the trigger bits for each track pair have integrity.
2582 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2583 {
dba14d7d 2584 AliHLTUInt32_t filledCount = maxCount - reasonCount;
2585 if (not IntegrityOk(decision[i], reason+reasonCount, filledCount))
878cb83d 2586 {
dba14d7d 2587 // Reasons filled in IntegrityOk, now we just need to adjust
2588 // reasonCount and fill the recordNum values.
2589 if (recordNum != NULL)
2590 {
2591 for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2592 recordNum[reasonCount + n] = i;
2593 }
2594 reasonCount += filledCount;
2595 result = false;
878cb83d 2596 }
90a74d7a 2597 }
2598
dba14d7d 2599 return result;
90a74d7a 2600}
dba14d7d 2601