Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 : // $Id$
17 :
18 : ///
19 : /// @file AliHLTMUONUtils.cxx
20 : /// @author Artur Szostak <artursz@iafrica.com>
21 : /// @date 17 May 2007
22 : /// @brief Implementation of AliHLTMUONUtils utility routines.
23 : ///
24 :
25 : #include "AliHLTMUONUtils.h"
26 : #include "AliHLTMUONConstants.h"
27 : #include "AliHLTMUONTriggerRecordsBlockStruct.h"
28 : #include "AliHLTMUONTrigRecsDebugBlockStruct.h"
29 : #include "AliHLTMUONRecHitsBlockStruct.h"
30 : #include "AliHLTMUONClustersBlockStruct.h"
31 : #include "AliHLTMUONChannelsBlockStruct.h"
32 : #include "AliHLTMUONMansoTracksBlockStruct.h"
33 : #include "AliHLTMUONMansoCandidatesBlockStruct.h"
34 : #include "AliHLTMUONTracksBlockStruct.h"
35 : #include "AliHLTMUONSinglesDecisionBlockStruct.h"
36 : #include "AliHLTMUONPairsDecisionBlockStruct.h"
37 : #include "AliMUONTrackerDDLDecoderEventHandler.h"
38 : #include <cstring>
39 : #include <cmath>
40 : #include <cassert>
41 :
42 6 : ClassImp(AliHLTMUONUtils);
43 :
44 :
45 : AliHLTUInt32_t AliHLTMUONUtils::PackTriggerRecordFlags(
46 : AliHLTMUONParticleSign sign, const bool hitset[4]
47 : )
48 : {
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 :
58 : AliHLTUInt32_t flags;
59 0 : switch (sign)
60 : {
61 0 : case kSignMinus: flags = 0x80000000; break;
62 0 : case kSignPlus: flags = 0x40000000; break;
63 0 : default: flags = 0x00000000; break;
64 : }
65 :
66 0 : return flags | (hitset[0] ? 0x1 : 0) | (hitset[1] ? 0x2 : 0)
67 0 : | (hitset[2] ? 0x4 : 0) | (hitset[3] ? 0x8 : 0);
68 : }
69 :
70 :
71 : void AliHLTMUONUtils::UnpackTriggerRecordFlags(
72 : AliHLTUInt32_t flags, AliHLTMUONParticleSign& sign, bool hitset[4]
73 : )
74 : {
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 :
84 0 : AliHLTUInt32_t signbits = flags & 0xC0000000;
85 0 : switch (signbits)
86 : {
87 0 : case 0x80000000: sign = kSignMinus; break;
88 0 : case 0x40000000: sign = kSignPlus; break;
89 0 : default: sign = kSignUnknown; break;
90 : }
91 0 : hitset[0] = (flags & 0x1) == 0x1;
92 0 : hitset[1] = (flags & 0x2) == 0x2;
93 0 : hitset[2] = (flags & 0x4) == 0x4;
94 0 : hitset[3] = (flags & 0x8) == 0x8;
95 0 : }
96 :
97 :
98 : AliHLTUInt32_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 0 : return ((chamber & 0xF) << 12) | (detElemId & 0xFFF);
109 : }
110 :
111 :
112 : void 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 : /// @param [in] flags The flags from an AliHLTMUONRecHitStruct structure.
121 : /// @param [out] chamber Sets the chamber number in the range [0..13].
122 : /// @param [out] detElemId Sets the detector element ID number.
123 :
124 0 : chamber = (flags >> 12) & 0xF;
125 0 : detElemId = flags & 0xFFF;
126 0 : }
127 :
128 :
129 : AliHLTUInt32_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 0 : switch (sign)
142 : {
143 0 : case kSignMinus: flags = 0x80000000; break;
144 0 : case kSignPlus: flags = 0x40000000; break;
145 0 : default: flags = 0x00000000; break;
146 : }
147 :
148 0 : for (AliHLTUInt32_t i = 0; i < 16; i++)
149 : {
150 0 : flags |= (hitset[i] ? (0x1 << i) : 0);
151 : }
152 0 : return flags;
153 : }
154 :
155 :
156 : void 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 0 : AliHLTUInt32_t signbits = flags & 0xC0000000;
168 0 : switch (signbits)
169 : {
170 0 : case 0x80000000: sign = kSignMinus; break;
171 0 : case 0x40000000: sign = kSignPlus; break;
172 0 : default: sign = kSignUnknown; break;
173 : }
174 :
175 0 : for (AliHLTUInt32_t i = 0; i < 16; i++)
176 : {
177 0 : hitset[i] = ((flags & (0x1u << i)) == (0x1u << i));
178 : }
179 0 : }
180 :
181 :
182 : AliHLTUInt32_t AliHLTMUONUtils::PackTrackDecisionBits(bool highPt, bool lowPt)
183 : {
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 :
192 0 : return (highPt ? 0x2 : 0) | (lowPt ? 0x1 : 0);
193 : }
194 :
195 :
196 : void AliHLTMUONUtils::UnpackTrackDecisionBits(
197 : AliHLTUInt32_t bits, bool& highPt, bool& lowPt
198 : )
199 : {
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 :
209 0 : lowPt = (bits & 0x1) == 0x1;
210 0 : highPt = (bits & 0x2) == 0x2;
211 0 : }
212 :
213 :
214 : AliHLTUInt32_t AliHLTMUONUtils::PackPairDecisionBits(
215 : bool highMass, bool lowMass, bool unlike,
216 : AliHLTUInt8_t highPtCount, AliHLTUInt8_t lowPtCount
217 : )
218 : {
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 : ///
232 : /// Note: Must have highPtCount <= 2, lowPtCount <= 2 and
233 : /// unlike == true if highMass or lowMass is true.
234 : ///
235 :
236 0 : assert( lowPtCount <= 2 );
237 0 : assert( highPtCount <= 2 );
238 : // highMass and lowMass must be false if unlike is false:
239 0 : assert( not unlike ? (highMass == false and lowMass == false) : true );
240 :
241 0 : return (highMass ? 0x40 : 0) | (lowMass ? 0x20 : 0) | (unlike ? 0x10 : 0)
242 0 : | ((highPtCount & 0x3) << 2) | (lowPtCount & 0x3);
243 : }
244 :
245 :
246 : void AliHLTMUONUtils::UnpackPairDecisionBits(
247 : AliHLTUInt32_t bits, bool& highMass, bool& lowMass, bool& unlike,
248 : AliHLTUInt8_t& highPtCount, AliHLTUInt8_t& lowPtCount
249 : )
250 : {
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 :
263 0 : highMass = (bits & 0x40) == 0x40;
264 0 : lowMass = (bits & 0x20) == 0x20;
265 0 : unlike = (bits & 0x10) == 0x10;
266 0 : highPtCount = (bits & 0xC) >> 2;
267 0 : lowPtCount = bits & 0x3;
268 0 : }
269 :
270 :
271 : AliHLTUInt32_t AliHLTMUONUtils::PackSpecBits(
272 : const bool ddl[22]
273 : )
274 : {
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 :
286 : // Pack the bits into the following format:
287 : // bit: [ 31 - 22 ][ 21 ][ 20 ][ 19 - 0 ]
288 : // field: [ reserved, set to zero ][ TRGDDL2817 ][ TRGDDL2816 ][ TRKDDLS ]
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 0 : for (int i = 0; i < 22; i++)
296 0 : bits |= (ddl[i] ? 0x1 : 0x0) << i;
297 0 : return bits;
298 : }
299 :
300 :
301 : void AliHLTMUONUtils::UnpackSpecBits(
302 : AliHLTUInt32_t bits, bool ddl[22]
303 : )
304 : {
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 :
315 : // Perform the inverse operation of PackSpecBits.
316 0 : for (int i = 0; i < 22; i++)
317 0 : ddl[i] = ((bits >> i) & 0x1) == 1;
318 0 : }
319 :
320 :
321 : AliHLTInt32_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 0 : if (0 <= ddlNo and ddlNo <= 19)
331 : {
332 0 : return 2560 + ddlNo;
333 : }
334 0 : else if (20 <= ddlNo and ddlNo <= 21)
335 : {
336 0 : return 2816 + (ddlNo - 20);
337 : }
338 : else
339 : {
340 0 : return -1;
341 : }
342 0 : }
343 :
344 :
345 : AliHLTInt32_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 0 : if (2560 <= id and id <= 2560+19)
356 : {
357 0 : return id - 2560;
358 : }
359 0 : else if (2816 <= id and id <= 2817)
360 : {
361 0 : return id - 2816 + 20;
362 : }
363 : else
364 : {
365 0 : return -1;
366 : }
367 0 : }
368 :
369 :
370 : AliHLTInt32_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 0 : for (AliHLTInt32_t ddlNo = 0; ddlNo < 20; ddlNo++)
384 : {
385 0 : if (spec == AliHLTUInt32_t(0x1 << ddlNo))
386 0 : return ddlNo + 2560;
387 : }
388 0 : for (AliHLTInt32_t ddlNo = 20; ddlNo < 22; ddlNo++)
389 : {
390 0 : if (spec == AliHLTUInt32_t(0x1 << ddlNo))
391 0 : return ddlNo - 20 + 2816;
392 : }
393 0 : return -1;
394 0 : }
395 :
396 :
397 : AliHLTUInt32_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 0 : if (2560 <= id and id <= 2560+19)
408 : {
409 0 : return 0x1 << (id - 2560);
410 : }
411 0 : else if (2816 <= id and id <= 2817)
412 : {
413 0 : return 0x1 << (id - 2816 + 20);
414 : }
415 : else
416 : {
417 0 : return 0x0;
418 : }
419 0 : }
420 :
421 :
422 : AliHLTInt32_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 0 : for (AliHLTInt32_t ddlNo = 0; ddlNo < 22; ddlNo++)
436 : {
437 0 : if (spec == AliHLTUInt32_t(0x1 << ddlNo))
438 0 : return ddlNo;
439 : }
440 0 : return -1;
441 0 : }
442 :
443 :
444 : AliHLTUInt32_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 0 : if (0 <= ddlNo and ddlNo <= 21)
455 : {
456 0 : return 0x1 << ddlNo;
457 : }
458 : else
459 : {
460 0 : return 0x0;
461 : }
462 0 : }
463 :
464 :
465 : AliHLTMUONDataBlockType 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 0 : if (strcmp(type, "trigrecs") == 0)
474 : {
475 0 : return kTriggerRecordsDataBlock;
476 : }
477 0 : else if (strcmp(type, "trigrecsdebug") == 0)
478 : {
479 0 : return kTrigRecsDebugDataBlock;
480 : }
481 0 : else if (strcmp(type, "rechits") == 0)
482 : {
483 0 : return kRecHitsDataBlock;
484 : }
485 0 : else if (strcmp(type,"channels") == 0)
486 : {
487 0 : return kChannelsDataBlock;
488 : }
489 0 : else if (strcmp(type,"clusters") == 0)
490 : {
491 0 : return kClustersDataBlock;
492 : }
493 0 : else if (strcmp(type, "mansotracks") == 0)
494 : {
495 0 : return kMansoTracksDataBlock;
496 : }
497 0 : else if (strcmp(type, "mansocandidates") == 0)
498 : {
499 0 : return kMansoCandidatesDataBlock;
500 : }
501 0 : else if (strcmp(type, "tracks") == 0)
502 : {
503 0 : return kTracksDataBlock;
504 : }
505 0 : else if (strcmp(type, "singlesdecision") == 0)
506 : {
507 0 : return kSinglesDecisionDataBlock;
508 : }
509 0 : else if (strcmp(type, "pairsdecision") == 0)
510 : {
511 0 : return kPairsDecisionDataBlock;
512 : }
513 :
514 0 : return kUnknownDataBlock;
515 0 : }
516 :
517 :
518 : const 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 0 : AliHLTComponentDataType t;
525 0 : switch (type)
526 : {
527 : case kTriggerRecordsDataBlock:
528 0 : t = AliHLTMUONConstants::TriggerRecordsBlockDataType();
529 0 : break;
530 : case kTrigRecsDebugDataBlock:
531 0 : t = AliHLTMUONConstants::TrigRecsDebugBlockDataType();
532 0 : break;
533 : case kRecHitsDataBlock:
534 0 : t = AliHLTMUONConstants::RecHitsBlockDataType();
535 0 : break;
536 : case kClustersDataBlock:
537 0 : t = AliHLTMUONConstants::ClusterBlockDataType();
538 0 : break;
539 : case kChannelsDataBlock:
540 0 : t = AliHLTMUONConstants::ChannelBlockDataType();
541 0 : break;
542 : case kMansoTracksDataBlock:
543 0 : t = AliHLTMUONConstants::MansoTracksBlockDataType();
544 0 : break;
545 : case kMansoCandidatesDataBlock:
546 0 : t = AliHLTMUONConstants::MansoCandidatesBlockDataType();
547 0 : break;
548 : case kTracksDataBlock:
549 0 : t = AliHLTMUONConstants::TracksBlockDataType();
550 0 : break;
551 : case kSinglesDecisionDataBlock:
552 0 : t = AliHLTMUONConstants::SinglesDecisionBlockDataType();
553 0 : break;
554 : case kPairsDecisionDataBlock:
555 0 : t = AliHLTMUONConstants::PairsDecisionBlockDataType();
556 0 : break;
557 : default:
558 0 : return "UNKNOWN";
559 : }
560 0 : memcpy(&str, &t.fID, kAliHLTComponentDataTypefIDsize);
561 : // Must insert the NULL character to make this an ANSI C string.
562 0 : str[kAliHLTComponentDataTypefIDsize] = '\0';
563 0 : return &str[0];
564 0 : }
565 :
566 :
567 : const char* AliHLTMUONUtils::FailureReasonToString(WhyNotValid reason)
568 : {
569 : /// This method converts the WhyNotValid enumeration to a string representation.
570 :
571 0 : switch (reason)
572 : {
573 0 : case kNoReason: return "kNoReason";
574 0 : case kHeaderContainsWrongType: return "kHeaderContainsWrongType";
575 0 : case kHeaderContainsWrongRecordWidth: return "kHeaderContainsWrongRecordWidth";
576 0 : case kInvalidIdValue: return "kInvalidIdValue";
577 0 : case kInvalidTriggerIdValue: return "kInvalidTriggerIdValue";
578 0 : case kInvalidTrackIdValue: return "kInvalidTrackIdValue";
579 0 : case kReservedBitsNotZero: return "kReservedBitsNotZero";
580 0 : case kParticleSignBitsNotValid: return "kParticleSignBitsNotValid";
581 0 : case kHitNotMarkedAsNil: return "kHitNotMarkedAsNil";
582 0 : case kInvalidDetElementNumber: return "kInvalidDetElementNumber";
583 0 : case kInvalidChamberNumber: return "kInvalidChamberNumber";
584 0 : case kHitIsNil: return "kHitIsNil";
585 0 : case kInvalidChannelCountB: return "kInvalidChannelCountB";
586 0 : case kInvalidChannelCountNB: return "kInvalidChannelCountNB";
587 0 : case kInvalidChargeB: return "kInvalidChargeB";
588 0 : case kInvalidChargeNB: return "kInvalidChargeNB";
589 0 : case kInvalidBusPatchId: return "kInvalidBusPatchId";
590 0 : case kInvalidManuId: return "kInvalidManuId";
591 0 : case kInvalidChannelAddress: return "kInvalidChannelAddress";
592 0 : case kInvalidSignal: return "kInvalidSignal";
593 0 : case kDataWordDifferent: return "kDataWordDifferent";
594 0 : case kChiSquareInvalid: return "kChiSquareInvalid";
595 0 : case kMomentumVectorNotZero: return "kMomentumVectorNotZero";
596 0 : case kMomentumParamsNotZero: return "kMomentumParamsNotZero";
597 0 : case kDCAVertexNotZero: return "kDCAVertexNotZero";
598 0 : case kRoiRadiusInvalid: return "kRoiRadiusInvalid";
599 0 : case kHitNotWithinRoi: return "kHitNotWithinRoi";
600 0 : case kPtValueNotValid: return "kPtValueNotValid";
601 0 : case kPairTrackIdsAreIdentical: return "kPairTrackIdsAreIdentical";
602 0 : case kMassValueNotValid: return "kMassValueNotValid";
603 0 : case kLowPtCountInvalid: return "kLowPtCountInvalid";
604 0 : case kHighPtCountInvalid: return "kHighPtCountInvalid";
605 0 : case kFoundDuplicateIDs: return "kFoundDuplicateIDs";
606 0 : case kFoundDuplicateHits: return "kFoundDuplicateHits";
607 0 : case kFoundDuplicateTriggers: return "kFoundDuplicateTriggers";
608 0 : default: return "INVALID";
609 : }
610 0 : }
611 :
612 :
613 : const 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 0 : switch (reason)
619 : {
620 : case kNoReason:
621 0 : return "There was no problem with the data block.";
622 : case kHeaderContainsWrongType:
623 0 : return "The common data header contains an incorrect type"
624 : " identifier.";
625 : case kHeaderContainsWrongRecordWidth:
626 0 : return "The common data header contains an incorrect data"
627 : " record width.";
628 : case kInvalidIdValue:
629 0 : return "The structure identifier does not have a valid value.";
630 : case kInvalidTriggerIdValue:
631 0 : return "The trigger structure identifier does not have a valid"
632 : " value.";
633 : case kInvalidTrackIdValue:
634 0 : return "The track structure identifier does not have a valid"
635 : " value.";
636 : case kReservedBitsNotZero:
637 0 : return "Reserved bits have not been set to zero.";
638 : case kParticleSignBitsNotValid:
639 0 : return "The particle sign bits are not a valid value.";
640 : case kHitNotMarkedAsNil:
641 0 : return "A hit was marked as not found, but the corresponding hit"
642 : " structure was not set to nil.";
643 : case kInvalidDetElementNumber:
644 0 : return "An invalid detector element ID was found.";
645 : case kInvalidChamberNumber:
646 0 : return "An invalid chamber number was found.";
647 : case kHitIsNil:
648 0 : return "The hit cannot be set to a nil value.";
649 : case kInvalidChannelCountB:
650 0 : return "The number of channels in the bending plane indicated"
651 : " is zero or outside the valid range.";
652 : case kInvalidChannelCountNB:
653 0 : return "The number of channels in the non-bending plane indicated"
654 : " is zero or outside the valid range.";
655 : case kInvalidChargeB:
656 0 : return "The charge in the bending plane does not have a valid value.";
657 : case kInvalidChargeNB:
658 0 : return "The charge in the non-bending plane does not have a valid value.";
659 : case kInvalidBusPatchId:
660 0 : return "The bus patch identifier is outside the valid range.";
661 : case kInvalidManuId:
662 0 : return "The MANU identifier is outside the valid range.";
663 : case kInvalidChannelAddress:
664 0 : return "The MANU channel address is outside the valid range.";
665 : case kInvalidSignal:
666 0 : return "The ADC signal value is outside the valid range.";
667 : case kDataWordDifferent:
668 0 : return "The raw data word is different from the unpacked values.";
669 : case kChiSquareInvalid:
670 0 : return "The chi squared value must be a positive value or -1"
671 : " indicating no fit or a fitting error.";
672 : case kMomentumVectorNotZero:
673 0 : return "The chi sqaured value is set to -1 indicating momentum"
674 : " was not fitted, but the momentum vector was not zero.";
675 : case kMomentumParamsNotZero:
676 0 : 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 0 : return "The chi sqaured value is set to -1 indicating the track"
680 : " was not fitted, but the DCA vertex is not zero.";
681 : case kRoiRadiusInvalid:
682 0 : return "The region of interest radius is invalid.";
683 : case kHitNotWithinRoi:
684 0 : return "A tracks hit is not within the corresponding region"
685 : " of interest.";
686 : case kPtValueNotValid:
687 0 : return "The pT value is not positive, nor -1 indicating an"
688 : " invalid value.";
689 : case kPairTrackIdsAreIdentical:
690 0 : return "The track identifiers of the track pair are identical.";
691 : case kMassValueNotValid:
692 0 : return "The invariant mass value is not positive, nor -1"
693 : " indicating an invalid value.";
694 : case kLowPtCountInvalid:
695 0 : return "The low pT trigger count is greater than 2,"
696 : " which is invalid.";
697 : case kHighPtCountInvalid:
698 0 : return "The high pT trigger count is greater than 2,"
699 : " which is invalid.";
700 : case kFoundDuplicateIDs:
701 0 : return "Found duplicate data record identifiers, but they"
702 : " should all be unique.";
703 : case kFoundDuplicateHits:
704 0 : return "Found duplicate hit structures, but they should all"
705 : " be unique.";
706 : case kFoundDuplicateTriggers:
707 0 : return "Found duplicate trigger decisions.";
708 : default:
709 0 : return "UNKNOWN REASON CODE";
710 : }
711 0 : }
712 :
713 :
714 : bool 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 0 : switch (reason)
725 : {
726 : case kInvalidIdValue:
727 : case kInvalidTriggerIdValue:
728 : case kInvalidTrackIdValue:
729 : case kReservedBitsNotZero:
730 : case kParticleSignBitsNotValid:
731 : case kHitNotMarkedAsNil:
732 : case kInvalidDetElementNumber:
733 : case kInvalidChamberNumber:
734 : case kHitIsNil:
735 : case kInvalidChannelCountB:
736 : case kInvalidChannelCountNB:
737 : case kInvalidChargeB:
738 : case kInvalidChargeNB:
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 0 : return true;
751 0 : default: return false;
752 : }
753 0 : }
754 :
755 :
756 : bool AliHLTMUONUtils::HeaderOk(
757 : const AliHLTMUONTriggerRecordsBlockStruct& block,
758 : WhyNotValid* reason, AliHLTUInt32_t& reasonCount
759 : )
760 : {
761 : /// Method used to check if the header information corresponds to the
762 : /// supposed type of the raw dHLT data block.
763 : /// \param [in] block The data block to check.
764 : /// \param [out] 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 : /// \param [in,out] 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.
772 : /// \returns true if there is no problem with the header and false otherwise.
773 :
774 0 : AliHLTUInt32_t maxCount = reasonCount;
775 0 : reasonCount = 0;
776 : bool result = true;
777 :
778 : // The block must have the correct type.
779 0 : if (block.fHeader.fType != kTriggerRecordsDataBlock)
780 : {
781 0 : if (reason != NULL and reasonCount < maxCount)
782 : {
783 0 : reason[reasonCount] = kHeaderContainsWrongType;
784 0 : reasonCount++;
785 0 : }
786 : result = false;
787 0 : }
788 :
789 : // The block's record width must be the correct size.
790 0 : if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTriggerRecordStruct))
791 : {
792 0 : if (reason != NULL and reasonCount < maxCount)
793 : {
794 0 : reason[reasonCount] = kHeaderContainsWrongRecordWidth;
795 0 : reasonCount++;
796 0 : }
797 : result = false;
798 0 : }
799 :
800 0 : return result;
801 : }
802 :
803 :
804 : bool AliHLTMUONUtils::HeaderOk(
805 : const AliHLTMUONTrigRecsDebugBlockStruct& block,
806 : WhyNotValid* reason, AliHLTUInt32_t& reasonCount
807 : )
808 : {
809 : /// Method used to check if the header information corresponds to the
810 : /// supposed type of the raw dHLT data block.
811 : /// \param [in] block The data block to check.
812 : /// \param [out] 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 : /// \param [in,out] 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.
820 : /// \returns true if there is no problem with the header and false otherwise.
821 :
822 0 : AliHLTUInt32_t maxCount = reasonCount;
823 0 : reasonCount = 0;
824 : bool result = true;
825 :
826 : // The block must have the correct type.
827 0 : if (block.fHeader.fType != kTrigRecsDebugDataBlock)
828 : {
829 0 : if (reason != NULL and reasonCount < maxCount)
830 : {
831 0 : reason[reasonCount] = kHeaderContainsWrongType;
832 0 : reasonCount++;
833 0 : }
834 : result = false;
835 0 : }
836 :
837 : // The block's record width must be the correct size.
838 0 : if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrigRecInfoStruct))
839 : {
840 0 : if (reason != NULL and reasonCount < maxCount)
841 : {
842 0 : reason[reasonCount] = kHeaderContainsWrongRecordWidth;
843 0 : reasonCount++;
844 0 : }
845 : result = false;
846 0 : }
847 :
848 0 : return result;
849 : }
850 :
851 :
852 : bool AliHLTMUONUtils::HeaderOk(
853 : const AliHLTMUONRecHitsBlockStruct& block,
854 : WhyNotValid* reason, AliHLTUInt32_t& reasonCount
855 : )
856 : {
857 : /// Method used to check if the header information corresponds to the
858 : /// supposed type of the raw dHLT data block.
859 : /// \param [in] block The data block to check.
860 : /// \param [out] 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 : /// \param [in,out] 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.
868 : /// \returns true if there is no problem with the header and false otherwise.
869 :
870 0 : AliHLTUInt32_t maxCount = reasonCount;
871 0 : reasonCount = 0;
872 : bool result = true;
873 :
874 : // The block must have the correct type.
875 0 : if (block.fHeader.fType != kRecHitsDataBlock)
876 : {
877 0 : if (reason != NULL and reasonCount < maxCount)
878 : {
879 0 : reason[reasonCount] = kHeaderContainsWrongType;
880 0 : reasonCount++;
881 0 : }
882 : result = false;
883 0 : }
884 :
885 : // The block's record width must be the correct size.
886 0 : if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONRecHitStruct))
887 : {
888 0 : if (reason != NULL and reasonCount < maxCount)
889 : {
890 0 : reason[reasonCount] = kHeaderContainsWrongRecordWidth;
891 0 : reasonCount++;
892 0 : }
893 : result = false;
894 0 : }
895 :
896 0 : return result;
897 : }
898 :
899 :
900 : bool AliHLTMUONUtils::HeaderOk(
901 : const AliHLTMUONClustersBlockStruct& block,
902 : WhyNotValid* reason, AliHLTUInt32_t& reasonCount
903 : )
904 : {
905 : /// Method used to check if the header information corresponds to the
906 : /// supposed type of the raw dHLT data block.
907 : /// \param [in] block The data block to check.
908 : /// \param [out] 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 : /// \param [in,out] 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.
916 : /// \returns true if there is no problem with the header and false otherwise.
917 :
918 0 : AliHLTUInt32_t maxCount = reasonCount;
919 0 : reasonCount = 0;
920 : bool result = true;
921 :
922 : // The block must have the correct type.
923 0 : if (block.fHeader.fType != kClustersDataBlock)
924 : {
925 0 : if (reason != NULL and reasonCount < maxCount)
926 : {
927 0 : reason[reasonCount] = kHeaderContainsWrongType;
928 0 : reasonCount++;
929 0 : }
930 : result = false;
931 0 : }
932 :
933 : // The block's record width must be the correct size.
934 0 : if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONClusterStruct))
935 : {
936 0 : if (reason != NULL and reasonCount < maxCount)
937 : {
938 0 : reason[reasonCount] = kHeaderContainsWrongRecordWidth;
939 0 : reasonCount++;
940 0 : }
941 : result = false;
942 0 : }
943 :
944 0 : return result;
945 : }
946 :
947 :
948 : bool AliHLTMUONUtils::HeaderOk(
949 : const AliHLTMUONChannelsBlockStruct& block,
950 : WhyNotValid* reason, AliHLTUInt32_t& reasonCount
951 : )
952 : {
953 : /// Method used to check if the header information corresponds to the
954 : /// supposed type of the raw dHLT data block.
955 : /// \param [in] block The data block to check.
956 : /// \param [out] 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 : /// \param [in,out] 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.
964 : /// \returns true if there is no problem with the header and false otherwise.
965 :
966 0 : AliHLTUInt32_t maxCount = reasonCount;
967 0 : reasonCount = 0;
968 : bool result = true;
969 :
970 : // The block must have the correct type.
971 0 : if (block.fHeader.fType != kChannelsDataBlock)
972 : {
973 0 : if (reason != NULL and reasonCount < maxCount)
974 : {
975 0 : reason[reasonCount] = kHeaderContainsWrongType;
976 0 : reasonCount++;
977 0 : }
978 : result = false;
979 0 : }
980 :
981 : // The block's record width must be the correct size.
982 0 : if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONChannelStruct))
983 : {
984 0 : if (reason != NULL and reasonCount < maxCount)
985 : {
986 0 : reason[reasonCount] = kHeaderContainsWrongRecordWidth;
987 0 : reasonCount++;
988 0 : }
989 : result = false;
990 0 : }
991 :
992 0 : return result;
993 : }
994 :
995 :
996 : bool AliHLTMUONUtils::HeaderOk(
997 : const AliHLTMUONMansoTracksBlockStruct& block,
998 : WhyNotValid* reason, AliHLTUInt32_t& reasonCount
999 : )
1000 : {
1001 : /// Method used to check if the header information corresponds to the
1002 : /// supposed type of the raw dHLT data block.
1003 : /// \param [in] block The data block to check.
1004 : /// \param [out] 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 : /// \param [in,out] 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.
1012 : /// \returns true if there is no problem with the header and false otherwise.
1013 :
1014 0 : AliHLTUInt32_t maxCount = reasonCount;
1015 0 : reasonCount = 0;
1016 : bool result = true;
1017 :
1018 : // The block must have the correct type.
1019 0 : if (block.fHeader.fType != kMansoTracksDataBlock)
1020 : {
1021 0 : if (reason != NULL and reasonCount < maxCount)
1022 : {
1023 0 : reason[reasonCount] = kHeaderContainsWrongType;
1024 0 : reasonCount++;
1025 0 : }
1026 : result = false;
1027 0 : }
1028 :
1029 : // The block's record width must be the correct size.
1030 0 : if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONMansoTrackStruct))
1031 : {
1032 0 : if (reason != NULL and reasonCount < maxCount)
1033 : {
1034 0 : reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1035 0 : reasonCount++;
1036 0 : }
1037 : result = false;
1038 0 : }
1039 :
1040 0 : return result;
1041 : }
1042 :
1043 :
1044 : bool AliHLTMUONUtils::HeaderOk(
1045 : const AliHLTMUONMansoCandidatesBlockStruct& block,
1046 : WhyNotValid* reason, AliHLTUInt32_t& reasonCount
1047 : )
1048 : {
1049 : /// Method used to check if the header information corresponds to the
1050 : /// supposed type of the raw dHLT data block.
1051 : /// \param [in] block The data block to check.
1052 : /// \param [out] 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 : /// \param [in,out] 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.
1060 : /// \returns true if there is no problem with the header and false otherwise.
1061 :
1062 0 : AliHLTUInt32_t maxCount = reasonCount;
1063 0 : reasonCount = 0;
1064 : bool result = true;
1065 :
1066 : // The block must have the correct type.
1067 0 : if (block.fHeader.fType != kMansoCandidatesDataBlock)
1068 : {
1069 0 : if (reason != NULL and reasonCount < maxCount)
1070 : {
1071 0 : reason[reasonCount] = kHeaderContainsWrongType;
1072 0 : reasonCount++;
1073 0 : }
1074 : result = false;
1075 0 : }
1076 :
1077 : // The block's record width must be the correct size.
1078 0 : if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONMansoCandidateStruct))
1079 : {
1080 0 : if (reason != NULL and reasonCount < maxCount)
1081 : {
1082 0 : reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1083 0 : reasonCount++;
1084 0 : }
1085 : result = false;
1086 0 : }
1087 :
1088 0 : return result;
1089 : }
1090 :
1091 :
1092 : bool AliHLTMUONUtils::HeaderOk(
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 : /// \param [in] block The data block to check.
1100 : /// \param [out] 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 : /// \param [in,out] 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 0 : AliHLTUInt32_t maxCount = reasonCount;
1111 0 : reasonCount = 0;
1112 : bool result = true;
1113 :
1114 : // The block must have the correct type.
1115 0 : if (block.fHeader.fType != kTracksDataBlock)
1116 : {
1117 0 : if (reason != NULL and reasonCount < maxCount)
1118 : {
1119 0 : reason[reasonCount] = kHeaderContainsWrongType;
1120 0 : reasonCount++;
1121 0 : }
1122 : result = false;
1123 0 : }
1124 :
1125 : // The block's record width must be the correct size.
1126 0 : if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrackStruct))
1127 : {
1128 0 : if (reason != NULL and reasonCount < maxCount)
1129 : {
1130 0 : reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1131 0 : reasonCount++;
1132 0 : }
1133 : result = false;
1134 0 : }
1135 :
1136 0 : return result;
1137 : }
1138 :
1139 :
1140 : bool AliHLTMUONUtils::HeaderOk(
1141 : const AliHLTMUONSinglesDecisionBlockStruct& block,
1142 : WhyNotValid* reason, AliHLTUInt32_t& reasonCount
1143 : )
1144 : {
1145 : /// Method used to check if the header information corresponds to the
1146 : /// supposed type of the raw dHLT data block.
1147 : /// \param [in] block The data block to check.
1148 : /// \param [out] 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 : /// \param [in,out] 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.
1156 : /// \returns true if there is no problem with the header and false otherwise.
1157 :
1158 0 : AliHLTUInt32_t maxCount = reasonCount;
1159 0 : reasonCount = 0;
1160 : bool result = true;
1161 :
1162 : // The block must have the correct type.
1163 0 : if (block.fHeader.fType != kSinglesDecisionDataBlock)
1164 : {
1165 0 : if (reason != NULL and reasonCount < maxCount)
1166 : {
1167 0 : reason[reasonCount] = kHeaderContainsWrongType;
1168 0 : reasonCount++;
1169 0 : }
1170 : result = false;
1171 0 : }
1172 :
1173 : // The block's record width must be the correct size.
1174 0 : if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrackDecisionStruct))
1175 : {
1176 0 : if (reason != NULL and reasonCount < maxCount)
1177 : {
1178 0 : reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1179 0 : reasonCount++;
1180 0 : }
1181 : result = false;
1182 0 : }
1183 :
1184 0 : return result;
1185 : }
1186 :
1187 :
1188 : bool AliHLTMUONUtils::HeaderOk(
1189 : const AliHLTMUONPairsDecisionBlockStruct& block,
1190 : WhyNotValid* reason, AliHLTUInt32_t& reasonCount
1191 : )
1192 : {
1193 : /// Method used to check if the header information corresponds to the
1194 : /// supposed type of the raw dHLT data block.
1195 : /// \param [in] block The data block to check.
1196 : /// \param [out] 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 : /// \param [in,out] 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.
1204 : /// \returns true if there is no problem with the header and false otherwise.
1205 :
1206 0 : AliHLTUInt32_t maxCount = reasonCount;
1207 0 : reasonCount = 0;
1208 : bool result = true;
1209 :
1210 : // The block must have the correct type.
1211 0 : if (block.fHeader.fType != kPairsDecisionDataBlock)
1212 : {
1213 0 : if (reason != NULL and reasonCount < maxCount)
1214 : {
1215 0 : reason[reasonCount] = kHeaderContainsWrongType;
1216 0 : reasonCount++;
1217 0 : }
1218 : result = false;
1219 0 : }
1220 :
1221 : // The block's record width must be the correct size.
1222 0 : if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONPairDecisionStruct))
1223 : {
1224 0 : if (reason != NULL and reasonCount < maxCount)
1225 : {
1226 0 : reason[reasonCount] = kHeaderContainsWrongRecordWidth;
1227 0 : reasonCount++;
1228 0 : }
1229 : result = false;
1230 0 : }
1231 :
1232 0 : return result;
1233 : }
1234 :
1235 :
1236 : bool AliHLTMUONUtils::IntegrityOk(
1237 : const AliHLTMUONTriggerRecordStruct& tr,
1238 : WhyNotValid* reason,
1239 : AliHLTUInt32_t& reasonCount
1240 : )
1241 : {
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 : /// \param [in] tr The trigger record structure to check.
1245 : /// \param [out] 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 : /// \param [in,out] 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.
1253 : /// \returns true if there is no problem with the structure and false otherwise.
1254 :
1255 0 : AliHLTUInt32_t maxCount = reasonCount;
1256 0 : reasonCount = 0;
1257 : bool result = true;
1258 :
1259 : // Check that the ID has a valid value.
1260 0 : if (not (tr.fId >= 0 or tr.fId == -1))
1261 : {
1262 0 : if (reason != NULL and reasonCount < maxCount)
1263 : {
1264 0 : reason[reasonCount] = kInvalidIdValue;
1265 0 : reasonCount++;
1266 0 : }
1267 : result = false;
1268 0 : }
1269 :
1270 : // Make sure that the reserved bits in the fFlags field are set
1271 : // to zero.
1272 0 : if ((tr.fFlags & 0x3FFFFFF0) != 0)
1273 : {
1274 0 : if (reason != NULL and reasonCount < maxCount)
1275 : {
1276 0 : reason[reasonCount] = kReservedBitsNotZero;
1277 0 : reasonCount++;
1278 0 : }
1279 : result = false;
1280 0 : }
1281 :
1282 : // Make sure the sign is not invalid.
1283 0 : if ((tr.fFlags & 0xC0000000) == 0xC0000000)
1284 : {
1285 0 : if (reason != NULL and reasonCount < maxCount)
1286 : {
1287 0 : reason[reasonCount] = kParticleSignBitsNotValid;
1288 0 : reasonCount++;
1289 0 : }
1290 : result = false;
1291 0 : }
1292 :
1293 : // Check that fHit[i] is nil if the corresponding bit in the
1294 : // flags word is zero.
1295 : const AliHLTMUONRecHitStruct& nilhit
1296 0 : = AliHLTMUONConstants::NilRecHitStruct();
1297 0 : if ( ((tr.fFlags & 0x1) == 0 and tr.fHit[0] != nilhit) or
1298 0 : ((tr.fFlags & 0x2) == 0 and tr.fHit[1] != nilhit) or
1299 0 : ((tr.fFlags & 0x4) == 0 and tr.fHit[2] != nilhit) or
1300 0 : ((tr.fFlags & 0x8) == 0 and tr.fHit[3] != nilhit)
1301 : )
1302 : {
1303 0 : if (reason != NULL and reasonCount < maxCount)
1304 : {
1305 0 : reason[reasonCount] = kHitNotMarkedAsNil;
1306 0 : reasonCount++;
1307 0 : }
1308 : result = false;
1309 0 : }
1310 :
1311 : // Check the individual hits
1312 0 : for (int i = 0; i < 4; i++)
1313 : {
1314 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
1315 0 : if (not IntegrityOk(tr.fHit[i], reason + reasonCount, filledCount))
1316 : {
1317 0 : reasonCount += filledCount;
1318 : result = false;
1319 0 : }
1320 0 : }
1321 :
1322 0 : return result;
1323 : }
1324 :
1325 :
1326 : bool AliHLTMUONUtils::IntegrityOk(
1327 : const AliHLTMUONTriggerRecordsBlockStruct& block,
1328 : WhyNotValid* reason,
1329 : AliHLTUInt32_t* recordNum,
1330 : AliHLTUInt32_t& reasonCount
1331 : )
1332 : {
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 : /// \param [in] block The trigger record data block to check.
1336 : /// \param [out] 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 : /// \param [out] 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
1346 : /// - kReservedBitsNotZero
1347 : /// - kParticleSignBitsNotValid
1348 : /// - kHitNotMarkedAsNil
1349 : /// - kInvalidDetElementNumber
1350 : /// - kInvalidChamberNumber
1351 : /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1352 : /// was set and is valid or not.
1353 : /// \param [in,out] 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.
1357 : /// \returns true if there is no problem with the data and false otherwise.
1358 :
1359 0 : AliHLTUInt32_t maxCount = reasonCount;
1360 0 : bool result = HeaderOk(block, reason, reasonCount);
1361 :
1362 : const AliHLTMUONTriggerRecordStruct* triggerRecord =
1363 0 : reinterpret_cast<const AliHLTMUONTriggerRecordStruct*>(&block + 1);
1364 :
1365 : // Check if any ID is duplicated.
1366 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1367 : {
1368 0 : AliHLTInt32_t id = triggerRecord[i].fId;
1369 0 : for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1370 : {
1371 0 : if (id == triggerRecord[j].fId)
1372 : {
1373 0 : if (reason != NULL and reasonCount < maxCount)
1374 : {
1375 0 : reason[reasonCount] = kFoundDuplicateIDs;
1376 0 : reasonCount++;
1377 0 : }
1378 : result = false;
1379 0 : }
1380 : }
1381 : }
1382 :
1383 : // Check integrity of individual trigger records.
1384 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1385 : {
1386 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
1387 0 : if (not IntegrityOk(triggerRecord[i], reason+reasonCount, filledCount))
1388 : {
1389 : // reasons filled in IntegrityOk, now we just need to adjust
1390 : // reasonCount and fill the recordNum values.
1391 0 : if (recordNum != NULL)
1392 : {
1393 0 : for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1394 0 : recordNum[reasonCount + n] = i;
1395 0 : }
1396 0 : reasonCount += filledCount;
1397 : result = false;
1398 0 : }
1399 0 : }
1400 :
1401 0 : return result;
1402 : }
1403 :
1404 :
1405 : bool 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 : /// \param [in] trigInfo The trigger record debug information structure to check.
1414 : /// \param [out] 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 : /// \param [in,out] 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 0 : AliHLTUInt32_t maxCount = reasonCount;
1425 0 : reasonCount = 0;
1426 : bool result = true;
1427 :
1428 : // Check that the trigger ID has a valid value.
1429 0 : if (not (trigInfo.fTrigRecId >= 0 or trigInfo.fTrigRecId == -1))
1430 : {
1431 0 : if (reason != NULL and reasonCount < maxCount)
1432 : {
1433 0 : reason[reasonCount] = kInvalidIdValue;
1434 0 : reasonCount++;
1435 0 : }
1436 : result = false;
1437 0 : }
1438 :
1439 : // Check that the fDetElemId[i] numbers are valid.
1440 0 : if ( not ((trigInfo.fDetElemId[0] >= 100 and trigInfo.fDetElemId[0] < 1500)
1441 0 : or trigInfo.fDetElemId[0] == -1)
1442 0 : or not ((trigInfo.fDetElemId[1] >= 100 and trigInfo.fDetElemId[1] < 1500)
1443 0 : or trigInfo.fDetElemId[1] == -1)
1444 0 : or not ((trigInfo.fDetElemId[2] >= 100 and trigInfo.fDetElemId[2] < 1500)
1445 0 : or trigInfo.fDetElemId[2] == -1)
1446 0 : or not ((trigInfo.fDetElemId[3] >= 100 and trigInfo.fDetElemId[3] < 1500)
1447 0 : or trigInfo.fDetElemId[3] == -1)
1448 : )
1449 : {
1450 0 : if (reason != NULL and reasonCount < maxCount)
1451 : {
1452 0 : reason[reasonCount] = kInvalidDetElementNumber;
1453 0 : reasonCount++;
1454 0 : }
1455 : result = false;
1456 0 : }
1457 :
1458 0 : return result;
1459 : }
1460 :
1461 :
1462 : bool AliHLTMUONUtils::IntegrityOk(
1463 : const AliHLTMUONTrigRecsDebugBlockStruct& block,
1464 : WhyNotValid* reason,
1465 : AliHLTUInt32_t* recordNum,
1466 : AliHLTUInt32_t& reasonCount
1467 : )
1468 : {
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.
1471 : /// \param [in] block The trigger record debugging information data block
1472 : /// to check.
1473 : /// \param [out] 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 : /// \param [out] 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 : /// \param [in,out] 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.
1491 : /// \returns true if there is no problem with the data and false otherwise.
1492 :
1493 0 : AliHLTUInt32_t maxCount = reasonCount;
1494 0 : bool result = HeaderOk(block, reason, reasonCount);
1495 :
1496 : const AliHLTMUONTrigRecInfoStruct* triggerInfo =
1497 0 : reinterpret_cast<const AliHLTMUONTrigRecInfoStruct*>(&block + 1);
1498 :
1499 : // Check if any trigger debug info structure has duplicated trigger IDs.
1500 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1501 : {
1502 0 : AliHLTInt32_t id = triggerInfo[i].fTrigRecId;
1503 0 : for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1504 : {
1505 0 : if (id == triggerInfo[j].fTrigRecId)
1506 : {
1507 0 : if (reason != NULL and reasonCount < maxCount)
1508 : {
1509 0 : reason[reasonCount] = kFoundDuplicateIDs;
1510 0 : reasonCount++;
1511 0 : }
1512 : result = false;
1513 0 : }
1514 : }
1515 : }
1516 :
1517 : // Check integrity of individual trigger records.
1518 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1519 : {
1520 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
1521 0 : 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 0 : if (recordNum != NULL)
1526 : {
1527 0 : for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1528 0 : recordNum[reasonCount + n] = i;
1529 0 : }
1530 0 : reasonCount += filledCount;
1531 : result = false;
1532 0 : }
1533 0 : }
1534 :
1535 0 : return result;
1536 : }
1537 :
1538 :
1539 : bool AliHLTMUONUtils::IntegrityOk(
1540 : const AliHLTMUONRecHitStruct& hit,
1541 : WhyNotValid* reason,
1542 : AliHLTUInt32_t& reasonCount
1543 : )
1544 : {
1545 : /// This method is used to check more extensively if the integrity of the
1546 : /// reconstructed hit structure is OK and returns true in that case.
1547 : /// \param [in] hit The reconstructed hit structure to check.
1548 : /// \param [out] 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 : /// \param [in,out] 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.
1557 :
1558 0 : AliHLTUInt32_t maxCount = reasonCount;
1559 0 : reasonCount = 0;
1560 : bool result = true;
1561 :
1562 : // If this is a NIL hit then skip all other checks.
1563 0 : if (hit == AliHLTMUONConstants::NilRecHitStruct())
1564 : {
1565 0 : return true;
1566 : }
1567 :
1568 : // Make sure that the reserved bits in the fFlags field are set
1569 : // to zero.
1570 0 : if ((hit.fFlags & 0x3FFF0000) != 0)
1571 : {
1572 0 : if (reason != NULL and reasonCount < maxCount)
1573 : {
1574 0 : reason[reasonCount] = kReservedBitsNotZero;
1575 0 : reasonCount++;
1576 0 : }
1577 : result = false;
1578 0 : }
1579 :
1580 0 : AliHLTUInt32_t detElemId = hit.fFlags & 0x00000FFF;
1581 0 : AliHLTUInt32_t chamber = (hit.fFlags & 0x0000F000) >> 12;
1582 :
1583 : // Make sure the detector element ID number is valid.
1584 0 : if (not (detElemId >= 100 and detElemId < 1500))
1585 : {
1586 0 : if (reason != NULL and reasonCount < maxCount)
1587 : {
1588 0 : reason[reasonCount] = kInvalidDetElementNumber;
1589 0 : reasonCount++;
1590 0 : }
1591 : result = false;
1592 0 : }
1593 :
1594 : // Make sure the chamber number is valid.
1595 0 : if (((detElemId / 100) - 1) != chamber or chamber >= 14)
1596 : {
1597 0 : if (reason != NULL and reasonCount < maxCount)
1598 : {
1599 0 : reason[reasonCount] = kInvalidChamberNumber;
1600 0 : reasonCount++;
1601 0 : }
1602 : result = false;
1603 0 : }
1604 :
1605 0 : return result;
1606 0 : }
1607 :
1608 :
1609 : bool AliHLTMUONUtils::IntegrityOk(
1610 : const AliHLTMUONRecHitsBlockStruct& block,
1611 : WhyNotValid* reason,
1612 : AliHLTUInt32_t* recordNum,
1613 : AliHLTUInt32_t& reasonCount
1614 : )
1615 : {
1616 : /// This method is used to check more extensively if the integrity of the
1617 : /// dHLT raw internal hits data block is OK and returns true in that case.
1618 : /// \param [in] block The reconstructed hits data block to check.
1619 : /// \param [out] 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.
1623 : /// \param [out] 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.
1633 : /// \param [in,out] reasonCount This should initially specify the size of
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.
1637 : /// \returns true if there is no problem with the data and false otherwise.
1638 :
1639 0 : AliHLTUInt32_t maxCount = reasonCount;
1640 0 : bool result = HeaderOk(block, reason, reasonCount);
1641 :
1642 : const AliHLTMUONRecHitStruct* hit =
1643 0 : reinterpret_cast<const AliHLTMUONRecHitStruct*>(&block + 1);
1644 :
1645 : // Check if any hit structure has been duplicated.
1646 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1647 : {
1648 0 : const AliHLTMUONRecHitStruct& h = hit[i];
1649 0 : for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1650 : {
1651 0 : if (h == hit[j])
1652 : {
1653 0 : if (reason != NULL and reasonCount < maxCount)
1654 : {
1655 0 : reason[reasonCount] = kFoundDuplicateHits;
1656 0 : reasonCount++;
1657 0 : }
1658 : result = false;
1659 0 : }
1660 : }
1661 : }
1662 :
1663 : // Check integrity of the individual hit structures.
1664 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1665 : {
1666 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
1667 0 : 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 0 : if (recordNum != NULL)
1672 : {
1673 0 : for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1674 0 : recordNum[reasonCount + n] = i;
1675 0 : }
1676 0 : reasonCount += filledCount;
1677 : result = false;
1678 0 : }
1679 0 : }
1680 :
1681 0 : return result;
1682 : }
1683 :
1684 :
1685 : bool 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 : /// \param [in] cluster The cluster structure to check.
1694 : /// \param [out] 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 : /// \param [in,out] 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 0 : AliHLTUInt32_t maxCount = reasonCount;
1705 0 : reasonCount = 0;
1706 : bool result = true;
1707 :
1708 : // Check that the cluster ID has a valid value.
1709 0 : if (not (cluster.fId >= 0 or cluster.fId == -1))
1710 : {
1711 0 : if (reason != NULL and reasonCount < maxCount)
1712 : {
1713 0 : reason[reasonCount] = kInvalidIdValue;
1714 0 : reasonCount++;
1715 0 : }
1716 : result = false;
1717 0 : }
1718 :
1719 : // Check that the cluster does not have a nil value for its hit.
1720 0 : if (cluster.fHit == AliHLTMUONConstants::NilRecHitStruct())
1721 : {
1722 0 : if (reason != NULL and reasonCount < maxCount)
1723 : {
1724 0 : reason[reasonCount] = kHitIsNil;
1725 0 : reasonCount++;
1726 0 : }
1727 : result = false;
1728 0 : }
1729 :
1730 : // Make sure the detector element is a valid value.
1731 0 : if (not ((cluster.fDetElemId >= 100 and cluster.fDetElemId < 1500)
1732 0 : or cluster.fDetElemId == -1)
1733 : )
1734 : {
1735 0 : if (reason != NULL and reasonCount < maxCount)
1736 : {
1737 0 : reason[reasonCount] = kInvalidDetElementNumber;
1738 0 : reasonCount++;
1739 0 : }
1740 : result = false;
1741 0 : }
1742 :
1743 : // The number of channels should be in a reasonable range.
1744 : // Using a value of 5*5*2, 5 pads by 5 pads by 2 cathode planes.
1745 0 : if (int(cluster.fNchannelsB) < 1 or (5*5*2) < int(cluster.fNchannelsB))
1746 : {
1747 0 : if (reason != NULL and reasonCount < maxCount)
1748 : {
1749 0 : reason[reasonCount] = kInvalidChannelCountB;
1750 0 : reasonCount++;
1751 0 : }
1752 : result = false;
1753 0 : }
1754 0 : if (int(cluster.fNchannelsNB) < 1 or (5*5*2) < int(cluster.fNchannelsNB))
1755 : {
1756 0 : if (reason != NULL and reasonCount < maxCount)
1757 : {
1758 0 : reason[reasonCount] = kInvalidChannelCountNB;
1759 0 : reasonCount++;
1760 0 : }
1761 : result = false;
1762 0 : }
1763 :
1764 :
1765 : // The charge values must be a positive value or -1.
1766 0 : if (not (cluster.fChargeB >= 0 or cluster.fChargeB == -1))
1767 : {
1768 0 : if (reason != NULL and reasonCount < maxCount)
1769 : {
1770 0 : reason[reasonCount] = kInvalidChargeB;
1771 0 : reasonCount++;
1772 0 : }
1773 : result = false;
1774 0 : }
1775 0 : if (not (cluster.fChargeNB >= 0 or cluster.fChargeNB == -1))
1776 : {
1777 0 : if (reason != NULL and reasonCount < maxCount)
1778 : {
1779 0 : reason[reasonCount] = kInvalidChargeNB;
1780 0 : reasonCount++;
1781 0 : }
1782 : result = false;
1783 0 : }
1784 :
1785 0 : return result;
1786 : }
1787 :
1788 :
1789 : bool AliHLTMUONUtils::IntegrityOk(
1790 : const AliHLTMUONClustersBlockStruct& block,
1791 : WhyNotValid* reason,
1792 : AliHLTUInt32_t* recordNum,
1793 : AliHLTUInt32_t& reasonCount
1794 : )
1795 : {
1796 : /// This method is used to check more extensively if the integrity of the
1797 : /// dHLT internal clusters data block is OK and returns true in that case.
1798 : /// \param [in] block The clusters data block to check.
1799 : /// \param [out] 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 : /// \param [out] 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
1811 : /// - kInvalidChannelCountB
1812 : /// - kInvalidChannelCountNB
1813 : /// - kInvalidChargeB
1814 : /// - kInvalidChargeNB
1815 : /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
1816 : /// was set and is valid or not.
1817 : /// \param [in,out] 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.
1821 : /// \returns true if there is no problem with the data and false otherwise.
1822 :
1823 0 : AliHLTUInt32_t maxCount = reasonCount;
1824 0 : bool result = HeaderOk(block, reason, reasonCount);
1825 :
1826 : const AliHLTMUONClusterStruct* cluster =
1827 0 : reinterpret_cast<const AliHLTMUONClusterStruct*>(&block + 1);
1828 :
1829 : // Check if any ID is duplicated.
1830 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1831 : {
1832 0 : AliHLTInt32_t id = cluster[i].fId;
1833 0 : for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1834 : {
1835 0 : if (id == cluster[j].fId)
1836 : {
1837 0 : if (reason != NULL and reasonCount < maxCount)
1838 : {
1839 0 : reason[reasonCount] = kFoundDuplicateIDs;
1840 0 : reasonCount++;
1841 0 : }
1842 : result = false;
1843 0 : }
1844 : }
1845 : }
1846 :
1847 : // Check if any hit structure has been duplicated.
1848 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1849 : {
1850 0 : const AliHLTMUONRecHitStruct& h = cluster[i].fHit;
1851 0 : for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
1852 : {
1853 0 : if (h == cluster[j].fHit)
1854 : {
1855 0 : if (reason != NULL and reasonCount < maxCount)
1856 : {
1857 0 : reason[reasonCount] = kFoundDuplicateHits;
1858 0 : reasonCount++;
1859 0 : }
1860 : result = false;
1861 0 : }
1862 : }
1863 : }
1864 :
1865 : // Check integrity of individual cluster structures.
1866 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
1867 : {
1868 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
1869 0 : 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 0 : if (recordNum != NULL)
1874 : {
1875 0 : for (AliHLTUInt32_t n = 0; n < filledCount; n++)
1876 0 : recordNum[reasonCount + n] = i;
1877 0 : }
1878 0 : reasonCount += filledCount;
1879 : result = false;
1880 0 : }
1881 0 : }
1882 :
1883 0 : return result;
1884 : }
1885 :
1886 :
1887 : bool 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 : /// \param [in] cluster The channel structure to check.
1896 : /// \param [out] 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 : /// \param [in,out] 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 0 : AliHLTUInt32_t maxCount = reasonCount;
1907 0 : reasonCount = 0;
1908 : bool result = true;
1909 :
1910 : // Check that the channel ID has a valid value.
1911 0 : if (not (channel.fClusterId >= 0 or channel.fClusterId == -1))
1912 : {
1913 0 : if (reason != NULL and reasonCount < maxCount)
1914 : {
1915 0 : reason[reasonCount] = kInvalidIdValue;
1916 0 : reasonCount++;
1917 0 : }
1918 : result = false;
1919 0 : }
1920 :
1921 : // Check that the bus patch ID has a valid value, which fits into 12 bits.
1922 0 : if ((channel.fBusPatch & (~0xFFF)) != 0)
1923 : {
1924 0 : if (reason != NULL and reasonCount < maxCount)
1925 : {
1926 0 : reason[reasonCount] = kInvalidBusPatchId;
1927 0 : reasonCount++;
1928 0 : }
1929 : result = false;
1930 0 : }
1931 :
1932 : // Check that the MANU ID has a valid value, which fits into 11 bits.
1933 0 : if ((channel.fManu & (~0x7FF)) != 0)
1934 : {
1935 0 : if (reason != NULL and reasonCount < maxCount)
1936 : {
1937 0 : reason[reasonCount] = kInvalidManuId;
1938 0 : reasonCount++;
1939 0 : }
1940 : result = false;
1941 0 : }
1942 :
1943 : // Check that the channel address has a valid value, which fits into 6 bits.
1944 0 : if ((channel.fChannelAddress & (~0x3F)) != 0)
1945 : {
1946 0 : if (reason != NULL and reasonCount < maxCount)
1947 : {
1948 0 : reason[reasonCount] = kInvalidChannelAddress;
1949 0 : reasonCount++;
1950 0 : }
1951 : result = false;
1952 0 : }
1953 :
1954 : // Check that the ADC signal has a valid value, which fits into 12 bits.
1955 0 : if ((channel.fSignal & (~0xFFF)) != 0)
1956 : {
1957 0 : if (reason != NULL and reasonCount < maxCount)
1958 : {
1959 0 : reason[reasonCount] = kInvalidSignal;
1960 0 : reasonCount++;
1961 0 : }
1962 : result = false;
1963 0 : }
1964 :
1965 : // Check that the raw data word corresponds to the unpacked values for
1966 : // the ADC signal, MANU ID and channel address.
1967 0 : UShort_t manuId; UChar_t channelId; UShort_t adc;
1968 0 : AliMUONTrackerDDLDecoderEventHandler::UnpackADC(
1969 0 : channel.fRawDataWord, manuId, channelId, adc
1970 : );
1971 0 : if (manuId != channel.fManu or channelId != channel.fChannelAddress
1972 0 : or adc != channel.fSignal
1973 : )
1974 : {
1975 0 : if (reason != NULL and reasonCount < maxCount)
1976 : {
1977 0 : reason[reasonCount] = kDataWordDifferent;
1978 0 : reasonCount++;
1979 0 : }
1980 : result = false;
1981 0 : }
1982 :
1983 0 : return result;
1984 0 : }
1985 :
1986 :
1987 : bool AliHLTMUONUtils::IntegrityOk(
1988 : const AliHLTMUONChannelsBlockStruct& block,
1989 : WhyNotValid* reason,
1990 : AliHLTUInt32_t* recordNum,
1991 : AliHLTUInt32_t& reasonCount
1992 : )
1993 : {
1994 : /// This method is used to check more extensively if the integrity of the
1995 : /// dHLT internal channels data block is OK and returns true in that case.
1996 : /// \param [in] block The channels data block to check.
1997 : /// \param [out] 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 : /// \param [out] 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 : /// \param [in,out] 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.
2018 : /// \returns true if there is no problem with the data and false otherwise.
2019 :
2020 0 : AliHLTUInt32_t maxCount = reasonCount;
2021 0 : bool result = HeaderOk(block, reason, reasonCount);
2022 :
2023 : const AliHLTMUONChannelStruct* channel =
2024 0 : reinterpret_cast<const AliHLTMUONChannelStruct*>(&block + 1);
2025 :
2026 : // Check integrity of individual channel structures.
2027 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2028 : {
2029 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
2030 0 : 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 0 : if (recordNum != NULL)
2035 : {
2036 0 : for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2037 0 : recordNum[reasonCount + n] = i;
2038 0 : }
2039 0 : reasonCount += filledCount;
2040 : result = false;
2041 0 : }
2042 0 : }
2043 :
2044 0 : return result;
2045 : }
2046 :
2047 :
2048 : bool AliHLTMUONUtils::IntegrityOk(
2049 : const AliHLTMUONMansoTrackStruct& track,
2050 : WhyNotValid* reason,
2051 : AliHLTUInt32_t& reasonCount
2052 : )
2053 : {
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 : /// \param [in] track The track structure to check.
2057 : /// \param [out] 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 : /// \param [in,out] 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.
2065 : /// \returns true if there is no problem with the structure and false otherwise.
2066 :
2067 0 : AliHLTUInt32_t maxCount = reasonCount;
2068 0 : reasonCount = 0;
2069 : bool result = true;
2070 :
2071 : // Check that the Manso track ID has a valid value.
2072 0 : if (not (track.fId >= 0 or track.fId == -1))
2073 : {
2074 0 : if (reason != NULL and reasonCount < maxCount)
2075 : {
2076 0 : reason[reasonCount] = kInvalidIdValue;
2077 0 : reasonCount++;
2078 0 : }
2079 : result = false;
2080 0 : }
2081 :
2082 : // Check that the corresponding trigger record ID has a valid value.
2083 0 : if (not (track.fTrigRec >= 0 or track.fTrigRec == -1))
2084 : {
2085 0 : if (reason != NULL and reasonCount < maxCount)
2086 : {
2087 0 : reason[reasonCount] = kInvalidTriggerIdValue;
2088 0 : reasonCount++;
2089 0 : }
2090 : result = false;
2091 0 : }
2092 :
2093 : // Make sure that the reserved bits in the fFlags field are set
2094 : // to zero.
2095 0 : if ((track.fFlags & 0x3FFFFFF0) != 0)
2096 : {
2097 0 : if (reason != NULL and reasonCount < maxCount)
2098 : {
2099 0 : reason[reasonCount] = kReservedBitsNotZero;
2100 0 : reasonCount++;
2101 0 : }
2102 : result = false;
2103 0 : }
2104 :
2105 : // Make sure the sign is not invalid.
2106 0 : if ((track.fFlags & 0xC0000000) == 0xC0000000)
2107 : {
2108 0 : if (reason != NULL and reasonCount < maxCount)
2109 : {
2110 0 : reason[reasonCount] = kParticleSignBitsNotValid;
2111 0 : reasonCount++;
2112 0 : }
2113 : result = false;
2114 0 : }
2115 :
2116 : // Check that fHit[i] is nil if the corresponding bit in the
2117 : // flags word is zero.
2118 : const AliHLTMUONRecHitStruct& nilhit
2119 0 : = AliHLTMUONConstants::NilRecHitStruct();
2120 0 : if ( ((track.fFlags & 0x1) == 0 and track.fHit[0] != nilhit) or
2121 0 : ((track.fFlags & 0x2) == 0 and track.fHit[1] != nilhit) or
2122 0 : ((track.fFlags & 0x4) == 0 and track.fHit[2] != nilhit) or
2123 0 : ((track.fFlags & 0x8) == 0 and track.fHit[3] != nilhit)
2124 : )
2125 : {
2126 0 : if (reason != NULL and reasonCount < maxCount)
2127 : {
2128 0 : reason[reasonCount] = kHitNotMarkedAsNil;
2129 0 : reasonCount++;
2130 0 : }
2131 : result = false;
2132 0 : }
2133 :
2134 : // Check that the chi squared value is valid
2135 0 : if (not (track.fChi2 >= 0 or track.fChi2 == -1))
2136 : {
2137 0 : if (reason != NULL and reasonCount < maxCount)
2138 : {
2139 0 : reason[reasonCount] = kChiSquareInvalid;
2140 0 : reasonCount++;
2141 0 : }
2142 : result = false;
2143 0 : }
2144 :
2145 : // Check that if chi squared is -1 then the momentum vector is zero.
2146 0 : if (track.fChi2 == -1 and
2147 0 : not (track.fPx == 0 and track.fPy == 0 and track.fPz == 0)
2148 : )
2149 : {
2150 0 : if (reason != NULL and reasonCount < maxCount)
2151 : {
2152 0 : reason[reasonCount] = kMomentumVectorNotZero;
2153 0 : reasonCount++;
2154 0 : }
2155 : result = false;
2156 0 : }
2157 :
2158 : // Check the individual hits
2159 0 : for (int i = 0; i < 4; i++)
2160 : {
2161 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
2162 0 : if (not IntegrityOk(track.fHit[i], reason + reasonCount, filledCount))
2163 : {
2164 0 : reasonCount += filledCount;
2165 : result = false;
2166 0 : }
2167 0 : }
2168 :
2169 0 : return result;
2170 : }
2171 :
2172 :
2173 : bool AliHLTMUONUtils::IntegrityOk(
2174 : const AliHLTMUONMansoTracksBlockStruct& block,
2175 : WhyNotValid* reason,
2176 : AliHLTUInt32_t* recordNum,
2177 : AliHLTUInt32_t& reasonCount
2178 : )
2179 : {
2180 : /// This method is used to check more extensively if the integrity of the
2181 : /// dHLT internal Manso track data block is OK and returns true in that case.
2182 : /// \param [in] block The Manso track data block to check.
2183 : /// \param [out] 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 : /// \param [out] 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
2194 : /// - kReservedBitsNotZero
2195 : /// - kParticleSignBitsNotValid
2196 : /// - kHitNotMarkedAsNil
2197 : /// - kChiSquareInvalid
2198 : /// - kMomentumVectorNotZero
2199 : /// - kInvalidDetElementNumber
2200 : /// - kInvalidChamberNumber
2201 : /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2202 : /// was set and is valid or not.
2203 : /// \param [in,out] 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.
2207 : /// \returns true if there is no problem with the data and false otherwise.
2208 :
2209 0 : AliHLTUInt32_t maxCount = reasonCount;
2210 0 : bool result = HeaderOk(block, reason, reasonCount);
2211 :
2212 : const AliHLTMUONMansoTrackStruct* track =
2213 0 : reinterpret_cast<const AliHLTMUONMansoTrackStruct*>(&block + 1);
2214 :
2215 : // Check if any track ID is duplicated.
2216 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2217 : {
2218 0 : AliHLTInt32_t id = track[i].fId;
2219 0 : for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
2220 : {
2221 0 : if (id == track[j].fId)
2222 : {
2223 0 : if (reason != NULL and reasonCount < maxCount)
2224 : {
2225 0 : reason[reasonCount] = kFoundDuplicateIDs;
2226 0 : reasonCount++;
2227 0 : }
2228 : result = false;
2229 0 : }
2230 : }
2231 : }
2232 :
2233 : // Check that all the tracks have integrity.
2234 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2235 : {
2236 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
2237 0 : if (not IntegrityOk(track[i], reason+reasonCount, filledCount))
2238 : {
2239 : // reasons filled in IntegrityOk, now we just need to adjust
2240 : // reasonCount and fill the recordNum values.
2241 0 : if (recordNum != NULL)
2242 : {
2243 0 : for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2244 0 : recordNum[reasonCount + n] = i;
2245 0 : }
2246 0 : reasonCount += filledCount;
2247 : result = false;
2248 0 : }
2249 0 : }
2250 :
2251 0 : return result;
2252 : }
2253 :
2254 :
2255 : bool 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 : /// \param [in] track The track candidate structure to check.
2264 : /// \param [out] 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 : /// \param [in,out] 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 0 : AliHLTUInt32_t maxCount = reasonCount;
2276 0 : 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 0 : for (AliHLTUInt32_t i = 0; i < 4; i++)
2282 : {
2283 0 : if (not (candidate.fRoI[i].fRadius >= 0 or candidate.fRoI[i].fRadius == -1))
2284 : {
2285 0 : if (reason != NULL and reasonCount < maxCount)
2286 : {
2287 0 : reason[reasonCount] = kRoiRadiusInvalid;
2288 0 : reasonCount++;
2289 0 : }
2290 : result = false;
2291 0 : }
2292 :
2293 : // Check if the corresponding hit was even found in the track.
2294 0 : if ( (candidate.fTrack.fFlags & (0x1 << i)) == 0 ) continue;
2295 :
2296 0 : double dx = candidate.fRoI[i].fX - candidate.fTrack.fHit[i].fX;
2297 0 : double dy = candidate.fRoI[i].fY - candidate.fTrack.fHit[i].fY;
2298 0 : double dz = candidate.fRoI[i].fZ - candidate.fTrack.fHit[i].fZ;
2299 0 : 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 0 : if (r > candidate.fRoI[i].fRadius or fabs(dz) > 20.)
2304 : {
2305 0 : if (reason != NULL and reasonCount < maxCount)
2306 : {
2307 0 : reason[reasonCount] = kHitNotWithinRoi;
2308 0 : reasonCount++;
2309 0 : }
2310 : result = false;
2311 0 : }
2312 0 : }
2313 :
2314 0 : return result;
2315 : }
2316 :
2317 :
2318 : bool AliHLTMUONUtils::IntegrityOk(
2319 : const AliHLTMUONMansoCandidatesBlockStruct& block,
2320 : WhyNotValid* reason,
2321 : AliHLTUInt32_t* recordNum,
2322 : AliHLTUInt32_t& reasonCount
2323 : )
2324 : {
2325 : /// This method is used to check more extensively if the integrity of the
2326 : /// dHLT internal Manso candidates data block is OK and returns true in
2327 : /// that case.
2328 : /// \param [in] block The Manso track candidate data block to check.
2329 : /// \param [out] 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 : /// \param [out] 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
2340 : /// - kReservedBitsNotZero
2341 : /// - kParticleSignBitsNotValid
2342 : /// - kHitNotMarkedAsNil
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 : /// \param [in,out] 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.
2352 : /// \returns true if there is no problem with the data and false otherwise.
2353 :
2354 0 : AliHLTUInt32_t maxCount = reasonCount;
2355 0 : bool result = HeaderOk(block, reason, reasonCount);
2356 :
2357 : const AliHLTMUONMansoCandidateStruct* candidate =
2358 0 : reinterpret_cast<const AliHLTMUONMansoCandidateStruct*>(&block + 1);
2359 :
2360 : // Check if any candidate track ID is duplicated.
2361 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2362 : {
2363 0 : AliHLTInt32_t id = candidate[i].fTrack.fId;
2364 0 : for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
2365 : {
2366 0 : if (id == candidate[j].fTrack.fId)
2367 : {
2368 0 : if (reason != NULL and reasonCount < maxCount)
2369 : {
2370 0 : reason[reasonCount] = kFoundDuplicateIDs;
2371 0 : reasonCount++;
2372 0 : }
2373 : result = false;
2374 0 : }
2375 : }
2376 : }
2377 :
2378 : // Check that all the track candidates have integrity.
2379 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2380 : {
2381 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
2382 0 : if (not IntegrityOk(candidate[i], reason+reasonCount, filledCount))
2383 : {
2384 : // reasons filled in IntegrityOk, now we just need to adjust
2385 : // reasonCount and fill the recordNum values.
2386 0 : if (recordNum != NULL)
2387 : {
2388 0 : for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2389 0 : recordNum[reasonCount + n] = i;
2390 0 : }
2391 0 : reasonCount += filledCount;
2392 : result = false;
2393 0 : }
2394 0 : }
2395 :
2396 0 : return result;
2397 : }
2398 :
2399 :
2400 : bool AliHLTMUONUtils::IntegrityOk(
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 : /// \param [in] track The track structure to check.
2409 : /// \param [out] 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 : /// \param [in,out] 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 0 : AliHLTUInt32_t maxCount = reasonCount;
2420 0 : reasonCount = 0;
2421 : bool result = true;
2422 :
2423 : // Check that the track ID has a valid value.
2424 0 : if (not (track.fId >= 0 or track.fId == -1))
2425 : {
2426 0 : if (reason != NULL and reasonCount < maxCount)
2427 : {
2428 0 : reason[reasonCount] = kInvalidIdValue;
2429 0 : reasonCount++;
2430 0 : }
2431 : result = false;
2432 0 : }
2433 :
2434 : // Check that the corresponding trigger record ID has a valid value.
2435 0 : if (not (track.fTrigRec >= 0 or track.fTrigRec == -1))
2436 : {
2437 0 : if (reason != NULL and reasonCount < maxCount)
2438 : {
2439 0 : reason[reasonCount] = kInvalidTriggerIdValue;
2440 0 : reasonCount++;
2441 0 : }
2442 : result = false;
2443 0 : }
2444 :
2445 : // Make sure that the reserved bits in the fFlags field are set
2446 : // to zero.
2447 0 : if ((track.fFlags & 0x3FFF0000) != 0)
2448 : {
2449 0 : if (reason != NULL and reasonCount < maxCount)
2450 : {
2451 0 : reason[reasonCount] = kReservedBitsNotZero;
2452 0 : reasonCount++;
2453 0 : }
2454 : result = false;
2455 0 : }
2456 :
2457 : // Make sure the sign is not invalid.
2458 0 : if ((track.fFlags & 0xC0000000) == 0xC0000000)
2459 : {
2460 0 : if (reason != NULL and reasonCount < maxCount)
2461 : {
2462 0 : reason[reasonCount] = kParticleSignBitsNotValid;
2463 0 : reasonCount++;
2464 0 : }
2465 : result = false;
2466 0 : }
2467 :
2468 : // Check that fHit[i] is nil if the corresponding bit in the
2469 : // flags word is zero.
2470 0 : const AliHLTMUONRecHitStruct& nilhit = AliHLTMUONConstants::NilRecHitStruct();
2471 0 : for (int i = 0; i < 16; i++)
2472 : {
2473 0 : if ((track.fFlags & (0x1 << i)) == 0 and track.fHit[i] != nilhit)
2474 : {
2475 0 : if (reason != NULL and reasonCount < maxCount)
2476 : {
2477 0 : reason[reasonCount] = kHitNotMarkedAsNil;
2478 0 : reasonCount++;
2479 0 : }
2480 : result = false;
2481 0 : break;
2482 : }
2483 : }
2484 :
2485 : // Check that the chi squared value is valid
2486 0 : if (not (track.fChi2 >= 0 or track.fChi2 == -1))
2487 : {
2488 0 : if (reason != NULL and reasonCount < maxCount)
2489 : {
2490 0 : reason[reasonCount] = kChiSquareInvalid;
2491 0 : reasonCount++;
2492 0 : }
2493 : result = false;
2494 0 : }
2495 :
2496 : // Check that if chi squared is -1 then the momentum vector is zero.
2497 0 : if (track.fChi2 == -1 and
2498 0 : not (track.fPx == 0 and track.fPy == 0 and track.fPz == 0)
2499 : )
2500 : {
2501 0 : if (reason != NULL and reasonCount < maxCount)
2502 : {
2503 0 : reason[reasonCount] = kMomentumVectorNotZero;
2504 0 : reasonCount++;
2505 0 : }
2506 : result = false;
2507 0 : }
2508 :
2509 : // Check that if chi squared is -1 then the momentum parameters are zero.
2510 0 : if (track.fChi2 == -1 and
2511 0 : not (track.fInverseBendingMomentum == 0 and track.fThetaX == 0 and track.fThetaY == 0)
2512 : )
2513 : {
2514 0 : if (reason != NULL and reasonCount < maxCount)
2515 : {
2516 0 : reason[reasonCount] = kMomentumParamsNotZero;
2517 0 : reasonCount++;
2518 0 : }
2519 : result = false;
2520 0 : }
2521 :
2522 : // Check that if chi squared is -1 then the momentum parameters are zero.
2523 0 : if (track.fChi2 == -1 and
2524 0 : not (track.fX == 0 and track.fY == 0 and track.fZ == 0)
2525 : )
2526 : {
2527 0 : if (reason != NULL and reasonCount < maxCount)
2528 : {
2529 0 : reason[reasonCount] = kDCAVertexNotZero;
2530 0 : reasonCount++;
2531 0 : }
2532 : result = false;
2533 0 : }
2534 :
2535 : // Check the individual hits
2536 0 : for (int i = 0; i < 16; i++)
2537 : {
2538 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
2539 0 : if (not IntegrityOk(track.fHit[i], reason + reasonCount, filledCount))
2540 : {
2541 0 : reasonCount += filledCount;
2542 : result = false;
2543 0 : }
2544 0 : }
2545 :
2546 0 : return result;
2547 : }
2548 :
2549 :
2550 : bool 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 : /// \param [in] block The track data block to check.
2560 : /// \param [out] 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 : /// \param [out] 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 : /// \param [in,out] 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 0 : AliHLTUInt32_t maxCount = reasonCount;
2589 0 : bool result = HeaderOk(block, reason, reasonCount);
2590 :
2591 : const AliHLTMUONTrackStruct* track =
2592 0 : reinterpret_cast<const AliHLTMUONTrackStruct*>(&block + 1);
2593 :
2594 : // Check if any track ID is duplicated.
2595 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2596 : {
2597 0 : AliHLTInt32_t id = track[i].fId;
2598 0 : for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
2599 : {
2600 0 : if (id == track[j].fId)
2601 : {
2602 0 : if (reason != NULL and reasonCount < maxCount)
2603 : {
2604 0 : reason[reasonCount] = kFoundDuplicateIDs;
2605 0 : reasonCount++;
2606 0 : }
2607 : result = false;
2608 0 : }
2609 : }
2610 : }
2611 :
2612 : // Check that all the tracks have integrity.
2613 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2614 : {
2615 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
2616 0 : 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 0 : if (recordNum != NULL)
2621 : {
2622 0 : for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2623 0 : recordNum[reasonCount + n] = i;
2624 0 : }
2625 0 : reasonCount += filledCount;
2626 : result = false;
2627 0 : }
2628 0 : }
2629 :
2630 0 : return result;
2631 : }
2632 :
2633 :
2634 : bool AliHLTMUONUtils::IntegrityOk(
2635 : const AliHLTMUONTrackDecisionStruct& decision,
2636 : WhyNotValid* reason,
2637 : AliHLTUInt32_t& reasonCount
2638 : )
2639 : {
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 : /// \param [in] decision The trigger decision structure to check.
2643 : /// \param [out] 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 : /// \param [in,out] 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.
2651 : /// \returns true if there is no problem with the structure and false otherwise.
2652 :
2653 0 : AliHLTUInt32_t maxCount = reasonCount;
2654 0 : reasonCount = 0;
2655 : bool result = true;
2656 :
2657 : // The track ID value must be positive or -1.
2658 0 : if (not (decision.fTrackId >= 0 or decision.fTrackId == -1))
2659 : {
2660 0 : if (reason != NULL and reasonCount < maxCount)
2661 : {
2662 0 : reason[reasonCount] = kInvalidTrackIdValue;
2663 0 : reasonCount++;
2664 0 : }
2665 : result = false;
2666 0 : }
2667 :
2668 : // Make sure that the reserved bits in the fTriggerBits field are set
2669 : // to zero.
2670 0 : if ((decision.fTriggerBits & 0xFFFFFFFC) != 0)
2671 : {
2672 0 : if (reason != NULL and reasonCount < maxCount)
2673 : {
2674 0 : reason[reasonCount] = kReservedBitsNotZero;
2675 0 : reasonCount++;
2676 0 : }
2677 : result = false;
2678 0 : }
2679 :
2680 : // The pT should be -1 or a positive number.
2681 0 : if (decision.fPt != -1. and decision.fPt < 0.)
2682 : {
2683 0 : if (reason != NULL and reasonCount < maxCount)
2684 : {
2685 0 : reason[reasonCount] = kPtValueNotValid;
2686 0 : reasonCount++;
2687 0 : }
2688 : result = false;
2689 0 : }
2690 :
2691 0 : return result;
2692 : }
2693 :
2694 :
2695 : bool AliHLTMUONUtils::IntegrityOk(
2696 : const AliHLTMUONSinglesDecisionBlockStruct& block,
2697 : WhyNotValid* reason,
2698 : AliHLTUInt32_t* recordNum,
2699 : AliHLTUInt32_t& reasonCount
2700 : )
2701 : {
2702 : /// This method is used to check more extensively if the integrity of the
2703 : /// dHLT internal single track trigger decision data block is OK and returns
2704 : /// true in that case.
2705 : /// \param [in] block The single track trigger decision data block to check.
2706 : /// \param [out] 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 : /// \param [out] 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
2716 : /// - kReservedBitsNotZero
2717 : /// - kPtValueNotValid
2718 : /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2719 : /// was set and is valid or not.
2720 : /// \param [in,out] 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.
2724 : /// \returns true if there is no problem with the data and false otherwise.
2725 :
2726 0 : AliHLTUInt32_t maxCount = reasonCount;
2727 0 : bool result = HeaderOk(block, reason, reasonCount);
2728 :
2729 : const AliHLTMUONTrackDecisionStruct* decision =
2730 0 : reinterpret_cast<const AliHLTMUONTrackDecisionStruct*>(&block + 1);
2731 :
2732 : // Check that there are no duplicate trigger entries.
2733 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2734 : {
2735 0 : AliHLTInt32_t id = decision[i].fTrackId;
2736 0 : for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
2737 : {
2738 0 : if (id == decision[j].fTrackId)
2739 : {
2740 0 : if (reason != NULL and reasonCount < maxCount)
2741 : {
2742 0 : reason[reasonCount] = kFoundDuplicateTriggers;
2743 0 : reasonCount++;
2744 0 : }
2745 : result = false;
2746 0 : }
2747 : }
2748 : }
2749 :
2750 : // Check that the trigger bits for each track have integrity.
2751 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2752 : {
2753 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
2754 0 : if (not IntegrityOk(decision[i], reason+reasonCount, filledCount))
2755 : {
2756 : // Reasons filled in IntegrityOk, now we just need to adjust
2757 : // reasonCount and fill the recordNum values.
2758 0 : if (recordNum != NULL)
2759 : {
2760 0 : for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2761 0 : recordNum[reasonCount + n] = i;
2762 0 : }
2763 0 : reasonCount += filledCount;
2764 : result = false;
2765 0 : }
2766 0 : }
2767 :
2768 0 : return result;
2769 : }
2770 :
2771 :
2772 : bool AliHLTMUONUtils::IntegrityOk(
2773 : const AliHLTMUONPairDecisionStruct& decision,
2774 : WhyNotValid* reason,
2775 : AliHLTUInt32_t& reasonCount
2776 : )
2777 : {
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 : /// \param [in] decision The trigger decision structure to check.
2781 : /// \param [out] 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 : /// \param [in,out] 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.
2789 : /// \returns true if there is no problem with the structure and false otherwise.
2790 :
2791 0 : AliHLTUInt32_t maxCount = reasonCount;
2792 0 : reasonCount = 0;
2793 : bool result = true;
2794 :
2795 : //kInvalidTrackIdValue
2796 :
2797 : // The track IDs must have a positive value or -1.
2798 0 : if (not (decision.fTrackAId >= 0 or decision.fTrackAId == -1) or
2799 0 : not (decision.fTrackBId >= 0 or decision.fTrackBId == -1)
2800 : )
2801 : {
2802 0 : if (reason != NULL and reasonCount < maxCount)
2803 : {
2804 0 : reason[reasonCount] = kInvalidTrackIdValue;
2805 0 : reasonCount++;
2806 0 : }
2807 : result = false;
2808 0 : }
2809 :
2810 : // Make sure that the reserved bits in the fTriggerBits field are set
2811 : // to zero.
2812 0 : if ((decision.fTriggerBits & 0xFFFFFF80) != 0)
2813 : {
2814 0 : if (reason != NULL and reasonCount < maxCount)
2815 : {
2816 0 : reason[reasonCount] = kReservedBitsNotZero;
2817 0 : reasonCount++;
2818 0 : }
2819 : result = false;
2820 0 : }
2821 :
2822 : // Check that the track IDs are not the same.
2823 0 : if (decision.fTrackAId == decision.fTrackBId)
2824 : {
2825 0 : if (reason != NULL and reasonCount < maxCount)
2826 : {
2827 0 : reason[reasonCount] = kPairTrackIdsAreIdentical;
2828 0 : reasonCount++;
2829 0 : }
2830 : result = false;
2831 0 : }
2832 :
2833 : // The invariant mass should be -1 or a positive number.
2834 0 : if (decision.fInvMass != -1. and decision.fInvMass < 0.)
2835 : {
2836 0 : if (reason != NULL and reasonCount < maxCount)
2837 : {
2838 0 : reason[reasonCount] = kMassValueNotValid;
2839 0 : reasonCount++;
2840 0 : }
2841 : result = false;
2842 0 : }
2843 :
2844 : // Neither the high pt (hipt) or low pt (lopt) count bits can be > 2.
2845 0 : AliHLTUInt8_t lowPtCount = (decision.fTriggerBits & 0x00000003);
2846 0 : AliHLTUInt8_t highPtCount = (decision.fTriggerBits & 0x0000000C) >> 2;
2847 0 : if (lowPtCount > 2)
2848 : {
2849 0 : if (reason != NULL and reasonCount < maxCount)
2850 : {
2851 0 : reason[reasonCount] = kLowPtCountInvalid;
2852 0 : reasonCount++;
2853 0 : }
2854 : result = false;
2855 0 : }
2856 0 : if (highPtCount > 2)
2857 : {
2858 0 : if (reason != NULL and reasonCount < maxCount)
2859 : {
2860 0 : reason[reasonCount] = kHighPtCountInvalid;
2861 0 : reasonCount++;
2862 0 : }
2863 : result = false;
2864 0 : }
2865 :
2866 0 : return result;
2867 : }
2868 :
2869 :
2870 : bool AliHLTMUONUtils::IntegrityOk(
2871 : const AliHLTMUONPairsDecisionBlockStruct& block,
2872 : WhyNotValid* reason,
2873 : AliHLTUInt32_t* recordNum,
2874 : AliHLTUInt32_t& reasonCount
2875 : )
2876 : {
2877 : /// This method is used to check more extensively if the integrity of the
2878 : /// dHLT internal track pair trigger decision data block is OK and returns
2879 : /// true in that case.
2880 : /// \param [in] block The track pair trigger decision data block to check.
2881 : /// \param [out] 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 : /// \param [out] 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
2891 : /// - kReservedBitsNotZero
2892 : /// - kPairTrackIdsAreIdentical
2893 : /// - kMassValueNotValid
2894 : /// - kLowPtCountInvalid
2895 : /// - kHighPtCountInvalid
2896 : /// \note You can use RecordNumberWasSet(reason[i]) to check if 'recordNum[i]'
2897 : /// was set and is valid or not.
2898 : /// \param [in,out] 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.
2902 : /// \returns true if there is no problem with the data and false otherwise.
2903 :
2904 0 : AliHLTUInt32_t maxCount = reasonCount;
2905 0 : bool result = HeaderOk(block, reason, reasonCount);
2906 :
2907 : const AliHLTMUONPairDecisionStruct* decision =
2908 0 : reinterpret_cast<const AliHLTMUONPairDecisionStruct*>(&block + 1);
2909 :
2910 : // Check that there are no duplicate trigger entries.
2911 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2912 : {
2913 0 : AliHLTInt32_t ta = decision[i].fTrackAId;
2914 0 : AliHLTInt32_t tb = decision[i].fTrackBId;
2915 0 : for (AliHLTUInt32_t j = i+1; j < block.fHeader.fNrecords; j++)
2916 : {
2917 0 : if (ta == decision[j].fTrackAId and tb == decision[j].fTrackBId)
2918 : {
2919 0 : if (reason != NULL and reasonCount < maxCount)
2920 : {
2921 0 : reason[reasonCount] = kFoundDuplicateTriggers;
2922 0 : reasonCount++;
2923 0 : }
2924 : result = false;
2925 0 : }
2926 : }
2927 : }
2928 :
2929 : // Check that the trigger bits for each track pair have integrity.
2930 0 : for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
2931 : {
2932 0 : AliHLTUInt32_t filledCount = maxCount - reasonCount;
2933 0 : if (not IntegrityOk(decision[i], reason+reasonCount, filledCount))
2934 : {
2935 : // Reasons filled in IntegrityOk, now we just need to adjust
2936 : // reasonCount and fill the recordNum values.
2937 0 : if (recordNum != NULL)
2938 : {
2939 0 : for (AliHLTUInt32_t n = 0; n < filledCount; n++)
2940 0 : recordNum[reasonCount + n] = i;
2941 0 : }
2942 0 : reasonCount += filledCount;
2943 : result = false;
2944 0 : }
2945 0 : }
2946 :
2947 0 : return result;
2948 : }
2949 :
|