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