1 /**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
19 /// @file AliHLTMUONUtils.cxx
20 /// @author Artur Szostak <artursz@iafrica.com>
22 /// @brief Implementation of AliHLTMUONUtils utility routines.
25 #include "AliHLTMUONUtils.h"
26 #include "AliHLTMUONConstants.h"
27 #include "AliHLTMUONTriggerRecordsBlockStruct.h"
28 #include "AliHLTMUONTrigRecsDebugBlockStruct.h"
29 #include "AliHLTMUONTriggerChannelsBlockStruct.h"
30 #include "AliHLTMUONRecHitsBlockStruct.h"
31 #include "AliHLTMUONClustersBlockStruct.h"
32 #include "AliHLTMUONChannelsBlockStruct.h"
33 #include "AliHLTMUONMansoTracksBlockStruct.h"
34 #include "AliHLTMUONMansoCandidatesBlockStruct.h"
35 #include "AliHLTMUONSinglesDecisionBlockStruct.h"
36 #include "AliHLTMUONPairsDecisionBlockStruct.h"
40 AliHLTUInt32_t AliHLTMUONUtils::PackTriggerRecordFlags(
41 AliHLTMUONParticleSign sign, const bool hitset[4]
45 /// This packs the given parameters into the bits of a word appropriate
46 /// for AliHLTMUONTriggerRecordStruct::fFlags.
47 /// @param sign The particle sign.
48 /// @param hitset Flags to indicate if the corresponding fHits[i] elements
50 /// @return Returns the 32 bit packed word.
56 case kSignMinus: flags = 0x80000000; break;
57 case kSignPlus: flags = 0x40000000; break;
58 default: flags = 0x00000000; break;
61 return flags | (hitset[0] ? 0x1 : 0) | (hitset[1] ? 0x2 : 0)
62 | (hitset[2] ? 0x4 : 0) | (hitset[3] ? 0x8 : 0);
66 void AliHLTMUONUtils::UnpackTriggerRecordFlags(
67 AliHLTUInt32_t flags, AliHLTMUONParticleSign& sign, bool hitset[4]
71 /// This unpacks the AliHLTMUONTriggerRecordStruct::fFlags bits into
72 /// its component fields.
73 /// @param flags The flags from an AliHLTMUONTriggerRecordStruct structure.
74 /// @param sign Sets this to the particle sign.
75 /// @param hitset Sets the array elements to indicate if the corresponding
76 /// fHits[i] element was set/filled.
79 AliHLTUInt32_t signbits = flags & 0xC0000000;
82 case 0x80000000: sign = kSignMinus; break;
83 case 0x40000000: sign = kSignPlus; break;
84 default: sign = kSignUnknown; break;
86 hitset[0] = (flags & 0x1) == 0x1;
87 hitset[1] = (flags & 0x2) == 0x2;
88 hitset[2] = (flags & 0x4) == 0x4;
89 hitset[3] = (flags & 0x8) == 0x8;
93 AliHLTUInt32_t AliHLTMUONUtils::PackTrackDecisionBits(bool highPt, bool lowPt)
96 /// This packs the given parameters into the bits of a word appropriate
97 /// for AliHLTMUONTrackDecisionStruct::fTriggerBits.
98 /// @param highPt Has the track passed the high pt cut.
99 /// @param lowPt Has the track passed the low pt cut.
100 /// @return Returns the 32 bit packed word.
103 return (highPt ? 0x2 : 0) | (lowPt ? 0x1 : 0);
107 void AliHLTMUONUtils::UnpackTrackDecisionBits(
108 AliHLTUInt32_t bits, bool& highPt, bool& lowPt
112 /// This unpacks the AliHLTMUONTrackDecisionStruct::fTriggerBits bits into
113 /// its component fields.
114 /// @param bits The trigger bits from an AliHLTMUONTrackDecisionStruct
116 /// @param highPt Sets this to the value of the high pt cut bit.
117 /// @param lowPt Sets this to the value of the low pt cut bit.
120 lowPt = (bits & 0x1) == 1;
121 highPt = (bits & 0x2) == 1;
125 AliHLTUInt32_t AliHLTMUONUtils::PackPairDecisionBits(
126 bool highMass, bool lowMass, bool unlike,
127 AliHLTUInt8_t highPtCount, AliHLTUInt8_t lowPtCount
131 /// This packs the given parameters into the bits of a word appropriate
132 /// for AliHLTMUONPairDecisionStruct::fTriggerBits.
134 /// @param highMass Has the track pair passed the high invariant mass cut.
135 /// @param lowMass Has the track pair passed the low invariant mass cut.
136 /// @param unlike Does the track pair have unlike signs.
137 /// @param highPtCount The number of tracks that passed the high pt cut
139 /// @param lowPtCount The number of tracks that passed the low pt cut
141 /// @return Returns the 32 bit packed word.
143 /// Note: Must have highPtCount + lowPtCount <= 2 and unlike == true if
144 /// highMass or lowMass is true.
147 assert( highPtCount + lowPtCount <= 2 );
148 // highMass and lowMass must be false if unlike is false:
149 assert( not unlike ? (highMass == false and lowMass == false) : true );
151 return (highMass ? 0x40 : 0) | (lowMass ? 0x20 : 0) | (unlike ? 0x10 : 0)
152 | ((highPtCount & 0x3) << 2) | (lowPtCount & 0x3);
156 void AliHLTMUONUtils::UnpackPairDecisionBits(
157 AliHLTUInt32_t bits, bool& highMass, bool& lowMass, bool& unlike,
158 AliHLTUInt8_t& highPtCount, AliHLTUInt8_t& lowPtCount
162 /// This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
163 /// its component fields.
164 /// @param bits The trigger bits from an AliHLTMUONPairDecisionStruct
166 /// @param highMass Sets this to the value of the high invariant mass cut bit.
167 /// @param lowMass Sets this to the value of the low invariant mass cut bit.
168 /// @param unlike Sets this if the pair is unlike sign.
169 /// @param highPtCount Sets this to the high pt count bits.
170 /// @param lowPtCount Sets this to the low pt count bits.
173 highMass = (bits & 0x40) == 1;
174 lowMass = (bits & 0x20) == 1;
175 unlike = (bits & 0x10) == 1;
176 highPtCount = (bits & 0xC) >> 2;
177 lowPtCount = bits & 0x3;
181 AliHLTUInt32_t AliHLTMUONUtils::PackSpecBits(
186 /// This packs the given parameters into the 32bit Pub/Sub specification
187 /// word in the data block descriptor.
189 /// @param ddl The list of DDLs forming part of the readout. ddl[0]
190 /// indicates DDL number 2560, ddl[1] is for DDL 2561 and so
191 /// on up to ddl[19]. ddl[20] and ddl[21] will be for the
192 /// trigger DDLs 2816 and 2817 respectively.
193 /// @return Returns the 32 bit packed specification word.
196 // Pack the bits into the following format:
197 // bit: [ 31 - 22 ][ 21 ][ 20 ][ 19 - 0 ]
198 // field: [ reserved, set to zero ][ TRGDDL2817 ][ TRGDDL2816 ][ TRKDDLS ]
199 // Meaning of field acronyms:
200 // TRGDDL2816 - Trigger DDL number 2816.
201 // TRGDDL2817 - Trigger DDL number 2817.
202 // TRKDDLS - Tracking DDL flags where bit 0 will be for DDL number 2560,
203 // bit 1 for DDL no. 2561 etc. up to bit 19 which is for DDL 2579.
204 AliHLTUInt32_t bits = 0;
205 for (int i = 0; i < 22; i++)
206 bits |= (ddl[i] ? 0x1 : 0x0) << i;
211 void AliHLTMUONUtils::UnpackSpecBits(
212 AliHLTUInt32_t bits, bool ddl[22]
216 /// This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
217 /// its component fields.
218 /// @param bits The Pub/Sub specification word from a data block descriptor.
219 /// @param ddl The output list of DDLs forming part of the readout. ddl[0]
220 /// indicates DDL number 2560, ddl[1] is for DDL 2561 and so
221 /// on up to ddl[19]. ddl[20] and ddl[21] will be for the
222 /// trigger DDLs 2816 and 2817 respectively.
225 // Perform the inverse operation of PackSpecBits.
226 for (int i = 0; i < 22; i++)
227 ddl[i] = ((bits >> i) & 0x1) == 1;
231 bool AliHLTMUONUtils::HeaderOk(
232 const AliHLTMUONTriggerRecordsBlockStruct& block,
237 /// Methods used to check if the header information corresponds to the
238 /// supposed type of the data block.
239 /// If the 'reason' parameter is not NULL then these methods will fill the
240 /// memory pointed to by reason with a code describing of why the header
241 /// is not valid, if and only if a problem is found with the data.
244 // The block must have the correct type.
245 if (block.fHeader.fType != kTriggerRecordsDataBlock)
247 if (reason != NULL) *reason = kHeaderContainsWrongType;
251 // The block's record width must be the correct size.
252 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTriggerRecordStruct))
254 if (reason != NULL) *reason = kHeaderContainsWrongRecordWidth;
262 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONTrigRecsDebugBlockStruct& block)
265 /// Methods used to check if the header information corresponds to the
266 /// supposed type of the data block.
269 // The block must have the correct type.
270 if (block.fHeader.fType != kTrigRecsDebugDataBlock) return false;
271 // The block's record width must be the correct size.
272 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrigRecInfoStruct))
278 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONTriggerChannelsBlockStruct& block)
281 /// Methods used to check if the header information corresponds to the
282 /// supposed type of the data block.
285 // The block must have the correct type.
286 if (block.fHeader.fType != kTriggerChannelsDataBlock) return false;
287 // The block's record width must be the correct size.
288 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTriggerChannelStruct))
294 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONRecHitsBlockStruct& block)
297 /// Methods used to check if the header information corresponds to the
298 /// supposed type of the data block.
301 // The block must have the correct type.
302 if (block.fHeader.fType != kRecHitsDataBlock) return false;
303 // The block's record width must be the correct size.
304 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONRecHitStruct))
310 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONClustersBlockStruct& block)
313 /// Methods used to check if the header information corresponds to the
314 /// supposed type of the data block.
317 // The block must have the correct type.
318 if (block.fHeader.fType != kClustersDataBlock) return false;
319 // The block's record width must be the correct size.
320 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONClusterStruct))
326 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONChannelsBlockStruct& block)
329 /// Methods used to check if the header information corresponds to the
330 /// supposed type of the data block.
333 // The block must have the correct type.
334 if (block.fHeader.fType != kChannelsDataBlock) return false;
335 // The block's record width must be the correct size.
336 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONChannelStruct))
342 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONMansoTracksBlockStruct& block)
345 /// Methods used to check if the header information corresponds to the
346 /// supposed type of the data block.
349 // The block must have the correct type.
350 if (block.fHeader.fType != kMansoTracksDataBlock) return false;
351 // The block's record width must be the correct size.
352 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONMansoTrackStruct))
358 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONMansoCandidatesBlockStruct& block)
361 /// Methods used to check if the header information corresponds to the
362 /// supposed type of the data block.
365 // The block must have the correct type.
366 if (block.fHeader.fType != kMansoCandidatesDataBlock) return false;
367 // The block's record width must be the correct size.
368 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONMansoCandidateStruct))
374 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONSinglesDecisionBlockStruct& block)
377 /// Methods used to check if the header information corresponds to the
378 /// supposed type of the data block.
381 // The block must have the correct type.
382 if (block.fHeader.fType != kSinglesDecisionDataBlock) return false;
383 // The block's record width must be the correct size.
384 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrackDecisionStruct))
390 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONPairsDecisionBlockStruct& block)
393 /// Methods used to check if the header information corresponds to the
394 /// supposed type of the data block.
397 // The block must have the correct type.
398 if (block.fHeader.fType != kPairsDecisionDataBlock) return false;
399 // The block's record width must be the correct size.
400 if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONPairDecisionStruct))
406 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONTriggerRecordStruct& tr)
409 /// Methods used to check more extensively if the integrity of various
410 /// types of data blocks are Ok and returns true in that case.
411 /// These can be slow and should generally only be used for debugging.
414 // Make sure that the reserved bits in the fFlags field are set
416 if ((tr.fFlags & 0x3FFFFFF0) != 0) return false;
418 // Make sure the sign is not invalid.
419 if ((tr.fFlags & 0xC0000000) == 3) return false;
421 // Check that fHit[i] is nil if the corresponding bit in the
422 // flags word is zero.
423 const AliHLTMUONRecHitStruct& nilhit
424 = AliHLTMUONConstants::NilRecHitStruct();
425 if ((tr.fFlags & 0x1) == 0 and tr.fHit[0] != nilhit) return false;
426 if ((tr.fFlags & 0x2) == 0 and tr.fHit[1] != nilhit) return false;
427 if ((tr.fFlags & 0x4) == 0 and tr.fHit[2] != nilhit) return false;
428 if ((tr.fFlags & 0x8) == 0 and tr.fHit[3] != nilhit) return false;
434 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONTriggerRecordsBlockStruct& block)
437 /// Methods used to check more extensively if the integrity of various
438 /// types of data blocks are Ok and returns true in that case.
439 /// These can be slow and should generally only be used for debugging.
442 if (not HeaderOk(block)) return false;
444 // Check if any ID is duplicated.
445 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
447 AliHLTInt32_t id = block.fTriggerRecord[i].fId;
448 for (AliHLTUInt32_t j = i+1; i < block.fHeader.fNrecords; j++)
450 if (id == block.fTriggerRecord[j].fId)
455 // Check integrity of individual trigger records.
456 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
458 if (not IntegrityOk(block.fTriggerRecord[i])) return false;
465 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONTrigRecsDebugBlockStruct& block)
468 /// Methods used to check more extensively if the integrity of various
469 /// types of data blocks are Ok and returns true in that case.
470 /// These can be slow and should generally only be used for debugging.
473 if (not HeaderOk(block)) return false;
478 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONTriggerChannelsBlockStruct& block)
481 /// Methods used to check more extensively if the integrity of various
482 /// types of data blocks are Ok and returns true in that case.
483 /// These can be slow and should generally only be used for debugging.
486 if (not HeaderOk(block)) return false;
491 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONRecHitsBlockStruct& block)
494 /// Methods used to check more extensively if the integrity of various
495 /// types of data blocks are Ok and returns true in that case.
496 /// These can be slow and should generally only be used for debugging.
499 if (not HeaderOk(block)) return false;
504 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONClustersBlockStruct& block)
507 /// Methods used to check more extensively if the integrity of various
508 /// types of data blocks are Ok and returns true in that case.
509 /// These can be slow and should generally only be used for debugging.
512 if (not HeaderOk(block)) return false;
514 // Check if any ID is duplicated.
515 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
517 AliHLTInt32_t id = block.fCluster[i].fId;
518 for (AliHLTUInt32_t j = i+1; i < block.fHeader.fNrecords; j++)
520 if (id == block.fCluster[j].fId)
529 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONChannelsBlockStruct& block)
532 /// Methods used to check more extensively if the integrity of various
533 /// types of data blocks are Ok and returns true in that case.
534 /// These can be slow and should generally only be used for debugging.
537 if (not HeaderOk(block)) return false;
542 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONMansoTrackStruct& track)
545 /// Methods used to check more extensively if the integrity of various
546 /// types of data blocks are Ok and returns true in that case.
547 /// These can be slow and should generally only be used for debugging.
550 // Make sure that the reserved bits in the fFlags field are set
552 if ((track.fFlags & 0x3FFFFFF0) != 0) return false;
554 // Make sure the sign is not invalid.
555 if ((track.fFlags & 0xC0000000) == 0xC0000000) return false;
557 // Check that fHit[i] is nil if the corresponding bit in the
558 // flags word is zero.
559 const AliHLTMUONRecHitStruct& nilhit
560 = AliHLTMUONConstants::NilRecHitStruct();
561 if ((track.fFlags & 0x1) == 0 and track.fHit[0] != nilhit) return false;
562 if ((track.fFlags & 0x2) == 0 and track.fHit[1] != nilhit) return false;
563 if ((track.fFlags & 0x4) == 0 and track.fHit[2] != nilhit) return false;
564 if ((track.fFlags & 0x8) == 0 and track.fHit[3] != nilhit) return false;
570 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONMansoTracksBlockStruct& block)
573 /// Methods used to check more extensively if the integrity of various
574 /// types of data blocks are Ok and returns true in that case.
575 /// These can be slow and should generally only be used for debugging.
578 if (not HeaderOk(block)) return false;
580 // Check if any ID is duplicated.
581 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
583 AliHLTInt32_t id = block.fTrack[i].fId;
584 for (AliHLTUInt32_t j = i+1; i < block.fHeader.fNrecords; j++)
586 if (id == block.fTrack[j].fId)
591 // Check that the tracks have integrity.
592 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
594 if (not IntegrityOk(block.fTrack[i])) return false;
601 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONMansoCandidatesBlockStruct& block)
604 /// Methods used to check more extensively if the integrity of various
605 /// types of data blocks are Ok and returns true in that case.
606 /// These can be slow and should generally only be used for debugging.
609 if (not HeaderOk(block)) return false;
611 // Check that the tracks have integrity.
612 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
614 if (not IntegrityOk(block.fCandidate[i].fTrack)) return false;
621 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONTrackDecisionStruct& decision)
624 /// Methods used to check more extensively if the integrity of various
625 /// types of data blocks are Ok and returns true in that case.
626 /// These can be slow and should generally only be used for debugging.
629 // Make sure that the reserved bits in the fTriggerBits field are set
631 if ((decision.fTriggerBits & 0xFFFFFFFC) != 0) return false;
636 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONSinglesDecisionBlockStruct& block)
639 /// Methods used to check more extensively if the integrity of various
640 /// types of data blocks are Ok and returns true in that case.
641 /// These can be slow and should generally only be used for debugging.
644 if (not HeaderOk(block)) return false;
646 // Check that the trigger bits for each track have integrity.
647 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
649 if (not IntegrityOk(block.fDecision[i])) return false;
656 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONPairDecisionStruct& decision)
659 /// Methods used to check more extensively if the integrity of various
660 /// types of data blocks are Ok and returns true in that case.
661 /// These can be slow and should generally only be used for debugging.
664 // Make sure that the reserved bits in the fTriggerBits field are set
666 if ((decision.fTriggerBits & 0xFFFFFF80) != 0) return false;
668 // The high mass or low mass bits can only be set if unlike bit is set.
669 if ((decision.fTriggerBits & 0x00000010) == 0
670 and (decision.fTriggerBits & 0x00000060) != 0
674 // Neither the high pt (hipt) or low pt (lopt) count bits can be > 2.
675 // And the sum must not be > 2.
676 AliHLTUInt8_t lowPtCount = (decision.fTriggerBits & 0x00000003);
677 AliHLTUInt8_t highPtCount = (decision.fTriggerBits & 0x0000000C) >> 2;
678 if (lowPtCount + highPtCount > 2) return false;
684 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONPairsDecisionBlockStruct& block)
687 /// Methods used to check more extensively if the integrity of various
688 /// types of data blocks are Ok and returns true in that case.
689 /// These can be slow and should generally only be used for debugging.
692 if (not HeaderOk(block)) return false;
694 // Check that the trigger bits for each track pair have integrity.
695 for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
697 if (not IntegrityOk(block.fDecision[i])) return false;