60302d71801179ec33287c98fadd4d05309e2261
[u/mrichter/AliRoot.git] / HLT / MUON / AliHLTMUONUtils.cxx
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   
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 "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"
37 #include <cassert>
38
39
40 AliHLTUInt32_t AliHLTMUONUtils::PackTriggerRecordFlags(
41                 AliHLTMUONParticleSign sign, const bool hitset[4]
42         )
43 {
44         ///
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
49         ///                was set/filled.
50         /// @return  Returns the 32 bit packed word.
51         ///
52         
53         AliHLTUInt32_t flags;
54         switch (sign)
55         {
56         case kSignMinus: flags = 0x80000000; break;
57         case kSignPlus:  flags = 0x40000000; break;
58         default:         flags = 0x00000000; break;
59         }
60
61         return flags | (hitset[0] ? 0x1 : 0) | (hitset[1] ? 0x2 : 0)
62                 | (hitset[2] ? 0x4 : 0) | (hitset[3] ? 0x8 : 0);
63 }
64
65
66 void AliHLTMUONUtils::UnpackTriggerRecordFlags(
67                 AliHLTUInt32_t flags, AliHLTMUONParticleSign& sign, bool hitset[4]
68         )
69 {
70         ///
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.
77         ///
78         
79         AliHLTUInt32_t signbits = flags & 0xC0000000;
80         switch (signbits)
81         {
82         case 0x80000000: sign = kSignMinus;   break;
83         case 0x40000000: sign = kSignPlus;    break;
84         default:         sign = kSignUnknown; break;
85         }
86         hitset[0] = (flags & 0x1) == 0x1;
87         hitset[1] = (flags & 0x2) == 0x2;
88         hitset[2] = (flags & 0x4) == 0x4;
89         hitset[3] = (flags & 0x8) == 0x8;
90 }
91
92
93 AliHLTUInt32_t AliHLTMUONUtils::PackTrackDecisionBits(bool highPt, bool lowPt)
94 {
95         ///
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.
101         ///
102         
103         return (highPt ? 0x2 : 0) | (lowPt ? 0x1 : 0);
104 }
105
106
107 void AliHLTMUONUtils::UnpackTrackDecisionBits(
108                 AliHLTUInt32_t bits, bool& highPt, bool& lowPt
109         )
110 {
111         ///
112         /// This unpacks the AliHLTMUONTrackDecisionStruct::fTriggerBits bits into
113         /// its component fields.
114         /// @param bits  The trigger bits from an AliHLTMUONTrackDecisionStruct
115         ///              structure.
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.
118         ///
119         
120         lowPt  = (bits & 0x1) == 1;
121         highPt = (bits & 0x2) == 1;
122 }
123
124
125 AliHLTUInt32_t AliHLTMUONUtils::PackPairDecisionBits(
126                 bool highMass, bool lowMass, bool unlike,
127                 AliHLTUInt8_t highPtCount, AliHLTUInt8_t lowPtCount
128         )
129 {
130         ///
131         /// This packs the given parameters into the bits of a word appropriate
132         /// for AliHLTMUONPairDecisionStruct::fTriggerBits.
133         ///
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
138         ///                    in the pair.
139         /// @param lowPtCount  The number of tracks that passed the low pt cut
140         ///                    in the pair.
141         /// @return  Returns the 32 bit packed word.
142         ///
143         /// Note: Must have highPtCount + lowPtCount <= 2 and unlike == true if
144         /// highMass or lowMass is true.
145         ///
146         
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 );
150         
151         return (highMass ? 0x40 : 0) | (lowMass ? 0x20 : 0) | (unlike ? 0x10 : 0)
152                 | ((highPtCount & 0x3) << 2) | (lowPtCount & 0x3);
153 }
154
155
156 void AliHLTMUONUtils::UnpackPairDecisionBits(
157                 AliHLTUInt32_t bits, bool& highMass, bool& lowMass, bool& unlike,
158                 AliHLTUInt8_t& highPtCount, AliHLTUInt8_t& lowPtCount
159         )
160 {
161         ///
162         /// This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
163         /// its component fields.
164         /// @param bits  The trigger bits from an AliHLTMUONPairDecisionStruct
165         ///              structure.
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.
171         ///
172         
173         highMass = (bits & 0x40) == 1;
174         lowMass  = (bits & 0x20) == 1;
175         unlike   = (bits & 0x10) == 1;
176         highPtCount = (bits & 0xC) >> 2;
177         lowPtCount = bits & 0x3;
178 }
179
180
181 AliHLTUInt32_t AliHLTMUONUtils::PackSpecBits(
182                 const bool ddl[22]
183         )
184 {
185         ///
186         /// This packs the given parameters into the 32bit Pub/Sub specification
187         /// word in the data block descriptor.
188         ///
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.
194         ///
195         
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;
207         return bits;
208 }
209
210
211 void AliHLTMUONUtils::UnpackSpecBits(
212                 AliHLTUInt32_t bits, bool ddl[22]
213         )
214 {
215         ///
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.
223         ///
224         
225         // Perform the inverse operation of PackSpecBits.
226         for (int i = 0; i < 22; i++)
227                 ddl[i] = ((bits >> i) & 0x1) == 1;
228 }
229
230
231 AliHLTInt32_t AliHLTMUONUtils::DDLNumberToEquipId(AliHLTInt32_t ddlNo)
232 {
233         ///
234         /// This method converts the DDL number for the muon spectrometer in the
235         /// range [0..21] to the equipment ID number.
236         /// @param ddlNo  The DDL number in the range [0..21].
237         /// @return  Returns the equipment ID number or -1 if ddlNo was invalid.
238         ///
239         
240         if (0 <= ddlNo and ddlNo <= 19)
241         {
242                 return 2560 + ddlNo;
243         }
244         else if (20 <= ddlNo and ddlNo <= 21)
245         {
246                 return 2816 + (ddlNo - 20);
247         }
248         else
249         {
250                 return -1;
251         }
252 }
253
254
255 AliHLTInt32_t AliHLTMUONUtils::EquipIdToDDLNumber(AliHLTInt32_t id)
256 {
257         ///
258         /// This method converts the equipment ID number for a muon spectrometer
259         /// DDL to the DDL number in the range [0..21].
260         /// @param id  The equipment ID of the DDL.
261         /// @return  Returns the DDL number in the range [0..21] or -1 if the
262         ///          equipment ID was invalid.
263         ///
264         
265         if (2560 <= id and id <= 2560+19)
266         {
267                 return id - 2560;
268         }
269         else if (2816 <= id and id <= 2817)
270         {
271                 return id - 2816 + 20;
272         }
273         else
274         {
275                 return -1;
276         }
277 }
278
279
280 AliHLTInt32_t AliHLTMUONUtils::SpecToEquipId(AliHLTUInt32_t spec)
281 {
282         ///
283         /// This method converts a 32 bit data block specification for a MUON-HLT
284         /// data block into its corresponding DDL equipment ID number.
285         /// It is assumed that the specification is for a data block comming from
286         /// a single DDL source. If more than one DDL contributed to the data block
287         /// then -1 is returned.
288         /// @param spec  The 32 bit specification for a data block.
289         /// @return  Returns the equipment ID corresponding to the specification
290         ///          or -1 if the specification was invalid.
291         ///
292         
293         for (AliHLTInt32_t ddlNo = 0; ddlNo < 20; ddlNo++)
294         {
295                 if (spec == AliHLTUInt32_t(0x1 << ddlNo))
296                         return ddlNo + 2560;
297         }
298         for (AliHLTInt32_t ddlNo = 20; ddlNo < 22; ddlNo++)
299         {
300                 if (spec == AliHLTUInt32_t(0x1 << ddlNo))
301                         return ddlNo - 20 + 2816;
302         }
303         return -1;
304 }
305
306
307 AliHLTUInt32_t AliHLTMUONUtils::EquipIdToSpec(AliHLTInt32_t id)
308 {
309         ///
310         /// This method converts a equipment ID number for a DDL into its corresponding
311         /// 32 bit data block specification for the MUON-HLT.
312         /// @param id  The equipment ID number of the DDL.
313         /// @return  Returns the 32 bit data block specification or 0x0 if the
314         ///          equipment ID was invalid.
315         ///
316         
317         if (2560 <= id and id <= 2560+19)
318         {
319                 return 0x1 << (id - 2560);
320         }
321         else if (2816 <= id and id <= 2817)
322         {
323                 return 0x1 << (id - 2816 + 20);
324         }
325         else
326         {
327                 return 0x0;
328         }
329 }
330
331
332 AliHLTInt32_t AliHLTMUONUtils::SpecToDDLNumber(AliHLTUInt32_t spec)
333 {
334         ///
335         /// This method converts a 32 bit data block specification for a MUON-HLT
336         /// data block into its corresponding DDL number in the range [0..21].
337         /// It is assumed that the specification is for a data block comming from
338         /// a single DDL source. If more than one DDL contributed to the data block
339         /// then -1 is returned.
340         /// @param spec  The 32 bit specification for a data block.
341         /// @return  Returns the corresponding DDL number for the specification
342         ///          or -1 if the specification was invalid.
343         ///
344         
345         for (AliHLTInt32_t ddlNo = 0; ddlNo < 22; ddlNo++)
346         {
347                 if (spec == AliHLTUInt32_t(0x1 << ddlNo))
348                         return ddlNo;
349         }
350         return -1;
351 }
352
353
354 AliHLTUInt32_t AliHLTMUONUtils::DDLNumberToSpec(AliHLTInt32_t ddlNo)
355 {
356         ///
357         /// This method converts a DDL number in the range [0..21] into its
358         /// corresponding 32 bit data block specification for the MUON-HLT.
359         /// @param ddlNo  The equipment ID number of the DDL.
360         /// @return  Returns the 32 bit data block specification or 0x0 if the
361         ///          DDL number was invalid (out of range).
362         ///
363         
364         if (0 <= ddlNo and ddlNo <= 21)
365         {
366                 return 0x1 << ddlNo;
367         }
368         else
369         {
370                 return 0x0;
371         }
372 }
373
374
375 bool AliHLTMUONUtils::HeaderOk(
376                 const AliHLTMUONTriggerRecordsBlockStruct& block,
377                 WhyNotValid* reason
378         )
379 {
380         ///
381         /// Methods used to check if the header information corresponds to the
382         /// supposed type of the data block.
383         /// If the 'reason' parameter is not NULL then these methods will fill the
384         /// memory pointed to by reason with a code describing of why the header
385         /// is not valid, if and only if a problem is found with the data.
386         ///
387          
388         // The block must have the correct type.
389         if (block.fHeader.fType != kTriggerRecordsDataBlock)
390         {
391                 if (reason != NULL) *reason = kHeaderContainsWrongType;
392                 return false;
393         }
394         
395         // The block's record width must be the correct size.
396         if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTriggerRecordStruct))
397         {
398                 if (reason != NULL) *reason = kHeaderContainsWrongRecordWidth;
399                 return false;
400         }
401         
402         return true;
403 }
404
405
406 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONTrigRecsDebugBlockStruct& block)
407 {
408         ///
409         /// Methods used to check if the header information corresponds to the
410         /// supposed type of the data block.
411         ///
412         
413         // The block must have the correct type.
414         if (block.fHeader.fType != kTrigRecsDebugDataBlock) return false;
415         // The block's record width must be the correct size.
416         if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrigRecInfoStruct))
417                 return false;
418         return true;
419 }
420
421
422 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONTriggerChannelsBlockStruct& block)
423 {
424         ///
425         /// Methods used to check if the header information corresponds to the
426         /// supposed type of the data block.
427         ///
428         
429         // The block must have the correct type.
430         if (block.fHeader.fType != kTriggerChannelsDataBlock) return false;
431         // The block's record width must be the correct size.
432         if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTriggerChannelStruct))
433                 return false;
434         return true;
435 }
436
437
438 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONRecHitsBlockStruct& block)
439 {
440         ///
441         /// Methods used to check if the header information corresponds to the
442         /// supposed type of the data block.
443         ///
444         
445         // The block must have the correct type.
446         if (block.fHeader.fType != kRecHitsDataBlock) return false;
447         // The block's record width must be the correct size.
448         if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONRecHitStruct))
449                 return false;
450         return true;
451 }
452
453
454 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONClustersBlockStruct& block)
455 {
456         ///
457         /// Methods used to check if the header information corresponds to the
458         /// supposed type of the data block.
459         ///
460         
461         // The block must have the correct type.
462         if (block.fHeader.fType != kClustersDataBlock) return false;
463         // The block's record width must be the correct size.
464         if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONClusterStruct))
465                 return false;
466         return true;
467 }
468
469
470 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONChannelsBlockStruct& block)
471 {
472         ///
473         /// Methods used to check if the header information corresponds to the
474         /// supposed type of the data block.
475         ///
476         
477         // The block must have the correct type.
478         if (block.fHeader.fType != kChannelsDataBlock) return false;
479         // The block's record width must be the correct size.
480         if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONChannelStruct))
481                 return false;
482         return true;
483 }
484
485
486 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONMansoTracksBlockStruct& block)
487 {
488         ///
489         /// Methods used to check if the header information corresponds to the
490         /// supposed type of the data block.
491         ///
492         
493         // The block must have the correct type.
494         if (block.fHeader.fType != kMansoTracksDataBlock) return false;
495         // The block's record width must be the correct size.
496         if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONMansoTrackStruct))
497                 return false;
498         return true;
499 }
500
501
502 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONMansoCandidatesBlockStruct& block)
503 {
504         ///
505         /// Methods used to check if the header information corresponds to the
506         /// supposed type of the data block.
507         ///
508         
509         // The block must have the correct type.
510         if (block.fHeader.fType != kMansoCandidatesDataBlock) return false;
511         // The block's record width must be the correct size.
512         if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONMansoCandidateStruct))
513                 return false;
514         return true;
515 }
516
517
518 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONSinglesDecisionBlockStruct& block)
519 {
520         ///
521         /// Methods used to check if the header information corresponds to the
522         /// supposed type of the data block.
523         ///
524         
525         // The block must have the correct type.
526         if (block.fHeader.fType != kSinglesDecisionDataBlock) return false;
527         // The block's record width must be the correct size.
528         if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONTrackDecisionStruct))
529                 return false;
530         return true;
531 }
532
533
534 bool AliHLTMUONUtils::HeaderOk(const AliHLTMUONPairsDecisionBlockStruct& block)
535 {
536         ///
537         /// Methods used to check if the header information corresponds to the
538         /// supposed type of the data block.
539         ///
540         
541         // The block must have the correct type.
542         if (block.fHeader.fType != kPairsDecisionDataBlock) return false;
543         // The block's record width must be the correct size.
544         if (block.fHeader.fRecordWidth != sizeof(AliHLTMUONPairDecisionStruct))
545                 return false;
546         return true;
547 }
548
549
550 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONTriggerRecordStruct& tr)
551 {
552         ///
553         /// Methods used to check more extensively if the integrity of various
554         /// types of data blocks are Ok and returns true in that case.
555         /// These can be slow and should generally only be used for debugging.
556         ///
557         
558         // Make sure that the reserved bits in the fFlags field are set
559         // to zero.
560         if ((tr.fFlags & 0x3FFFFFF0) != 0) return false;
561
562         // Make sure the sign is not invalid.
563         if ((tr.fFlags & 0xC0000000) == 3) return false;
564
565         // Check that fHit[i] is nil if the corresponding bit in the
566         // flags word is zero.
567         const AliHLTMUONRecHitStruct& nilhit
568                 = AliHLTMUONConstants::NilRecHitStruct();
569         if ((tr.fFlags & 0x1) == 0 and tr.fHit[0] != nilhit) return false;
570         if ((tr.fFlags & 0x2) == 0 and tr.fHit[1] != nilhit) return false;
571         if ((tr.fFlags & 0x4) == 0 and tr.fHit[2] != nilhit) return false;
572         if ((tr.fFlags & 0x8) == 0 and tr.fHit[3] != nilhit) return false;
573
574         return true;
575 }
576
577
578 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONTriggerRecordsBlockStruct& block)
579 {
580         ///
581         /// Methods used to check more extensively if the integrity of various
582         /// types of data blocks are Ok and returns true in that case.
583         /// These can be slow and should generally only be used for debugging.
584         ///
585         
586         if (not HeaderOk(block)) return false;
587         
588         const AliHLTMUONTriggerRecordStruct* triggerRecord =
589                 reinterpret_cast<const AliHLTMUONTriggerRecordStruct*>(&block + 1);
590
591         // Check if any ID is duplicated.
592         for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
593         {
594                 AliHLTInt32_t id = triggerRecord[i].fId;
595                 for (AliHLTUInt32_t j = i+1; i < block.fHeader.fNrecords; j++)
596                 {
597                         if (id == triggerRecord[j].fId)
598                                 return false;
599                 }
600         }
601
602         // Check integrity of individual trigger records.
603         for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
604         {
605                 if (not IntegrityOk(triggerRecord[i])) return false;
606         }
607
608         return true;
609 }
610
611
612 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONTrigRecsDebugBlockStruct& block)
613 {
614         ///
615         /// Methods used to check more extensively if the integrity of various
616         /// types of data blocks are Ok and returns true in that case.
617         /// These can be slow and should generally only be used for debugging.
618         ///
619         
620         if (not HeaderOk(block)) return false;
621         return true;
622 }
623
624
625 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONTriggerChannelsBlockStruct& block)
626 {
627         ///
628         /// Methods used to check more extensively if the integrity of various
629         /// types of data blocks are Ok and returns true in that case.
630         /// These can be slow and should generally only be used for debugging.
631         ///
632         
633         if (not HeaderOk(block)) return false;
634         return true;
635 }
636
637
638 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONRecHitsBlockStruct& block)
639 {
640         ///
641         /// Methods used to check more extensively if the integrity of various
642         /// types of data blocks are Ok and returns true in that case.
643         /// These can be slow and should generally only be used for debugging.
644         ///
645         
646         if (not HeaderOk(block)) return false;
647         return true;
648 }
649
650
651 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONClustersBlockStruct& block)
652 {
653         ///
654         /// Methods used to check more extensively if the integrity of various
655         /// types of data blocks are Ok and returns true in that case.
656         /// These can be slow and should generally only be used for debugging.
657         ///
658         
659         if (not HeaderOk(block)) return false;
660
661         const AliHLTMUONClusterStruct* cluster =
662                 reinterpret_cast<const AliHLTMUONClusterStruct*>(&block + 1);
663         
664         // Check if any ID is duplicated.
665         for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
666         {
667                 AliHLTInt32_t id = cluster[i].fId;
668                 for (AliHLTUInt32_t j = i+1; i < block.fHeader.fNrecords; j++)
669                 {
670                         if (id == cluster[j].fId)
671                                 return false;
672                 }
673         }
674         
675         return true;
676 }
677
678
679 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONChannelsBlockStruct& block)
680 {
681         ///
682         /// Methods used to check more extensively if the integrity of various
683         /// types of data blocks are Ok and returns true in that case.
684         /// These can be slow and should generally only be used for debugging.
685         ///
686         
687         if (not HeaderOk(block)) return false;
688         return true;
689 }
690
691
692 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONMansoTrackStruct& track)
693 {
694         ///
695         /// Methods used to check more extensively if the integrity of various
696         /// types of data blocks are Ok and returns true in that case.
697         /// These can be slow and should generally only be used for debugging.
698         ///
699         
700         // Make sure that the reserved bits in the fFlags field are set
701         // to zero.
702         if ((track.fFlags & 0x3FFFFFF0) != 0) return false;
703
704         // Make sure the sign is not invalid.
705         if ((track.fFlags & 0xC0000000) == 0xC0000000) return false;
706
707         // Check that fHit[i] is nil if the corresponding bit in the
708         // flags word is zero.
709         const AliHLTMUONRecHitStruct& nilhit
710                 = AliHLTMUONConstants::NilRecHitStruct();
711         if ((track.fFlags & 0x1) == 0 and track.fHit[0] != nilhit) return false;
712         if ((track.fFlags & 0x2) == 0 and track.fHit[1] != nilhit) return false;
713         if ((track.fFlags & 0x4) == 0 and track.fHit[2] != nilhit) return false;
714         if ((track.fFlags & 0x8) == 0 and track.fHit[3] != nilhit) return false;
715         
716         return true;
717 }
718
719
720 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONMansoTracksBlockStruct& block)
721 {
722         ///
723         /// Methods used to check more extensively if the integrity of various
724         /// types of data blocks are Ok and returns true in that case.
725         /// These can be slow and should generally only be used for debugging.
726         ///
727         
728         if (not HeaderOk(block)) return false;
729
730         const AliHLTMUONMansoTrackStruct* track =
731                 reinterpret_cast<const AliHLTMUONMansoTrackStruct*>(&block + 1);
732         
733         // Check if any ID is duplicated.
734         for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
735         {
736                 AliHLTInt32_t id = track[i].fId;
737                 for (AliHLTUInt32_t j = i+1; i < block.fHeader.fNrecords; j++)
738                 {
739                         if (id == track[j].fId)
740                                 return false;
741                 }
742         }
743
744         // Check that the tracks have integrity.
745         for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
746         {
747                 if (not IntegrityOk(track[i])) return false;
748         }
749
750         return true;
751 }
752
753
754 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONMansoCandidatesBlockStruct& block)
755 {
756         ///
757         /// Methods used to check more extensively if the integrity of various
758         /// types of data blocks are Ok and returns true in that case.
759         /// These can be slow and should generally only be used for debugging.
760         ///
761         
762         if (not HeaderOk(block)) return false;
763
764         const AliHLTMUONMansoCandidateStruct* candidate =
765                 reinterpret_cast<const AliHLTMUONMansoCandidateStruct*>(&block + 1);
766         
767         // Check that the tracks have integrity.
768         for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
769         {
770                 if (not IntegrityOk(candidate[i].fTrack)) return false;
771         }
772         
773         return true;
774 }
775
776
777 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONTrackDecisionStruct& decision)
778 {
779         ///
780         /// Methods used to check more extensively if the integrity of various
781         /// types of data blocks are Ok and returns true in that case.
782         /// These can be slow and should generally only be used for debugging.
783         ///
784         
785         // Make sure that the reserved bits in the fTriggerBits field are set
786         // to zero.
787         if ((decision.fTriggerBits & 0xFFFFFFFC) != 0) return false;
788         return true;
789 }
790
791
792 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONSinglesDecisionBlockStruct& block)
793 {
794         ///
795         /// Methods used to check more extensively if the integrity of various
796         /// types of data blocks are Ok and returns true in that case.
797         /// These can be slow and should generally only be used for debugging.
798         ///
799         
800         if (not HeaderOk(block)) return false;
801         
802         const AliHLTMUONTrackDecisionStruct* decision =
803                 reinterpret_cast<const AliHLTMUONTrackDecisionStruct*>(&block + 1);
804
805         // Check that the trigger bits for each track have integrity.
806         for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
807         {
808                 if (not IntegrityOk(decision[i])) return false;
809         }
810         
811         return true;
812 }
813
814
815 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONPairDecisionStruct& decision)
816 {
817         ///
818         /// Methods used to check more extensively if the integrity of various
819         /// types of data blocks are Ok and returns true in that case.
820         /// These can be slow and should generally only be used for debugging.
821         ///
822         
823         // Make sure that the reserved bits in the fTriggerBits field are set
824         // to zero.
825         if ((decision.fTriggerBits & 0xFFFFFF80) != 0) return false;
826         
827         // The high mass or low mass bits can only be set if unlike bit is set.
828         if ((decision.fTriggerBits & 0x00000010) == 0
829             and (decision.fTriggerBits & 0x00000060) != 0
830            )
831                 return false;
832         
833         // Neither the high pt (hipt) or low pt (lopt) count bits can be > 2.
834         // And the sum must not be > 2.
835         AliHLTUInt8_t lowPtCount = (decision.fTriggerBits & 0x00000003);
836         AliHLTUInt8_t highPtCount = (decision.fTriggerBits & 0x0000000C) >> 2;
837         if (lowPtCount + highPtCount > 2) return false;
838         
839         return true;
840 }
841
842
843 bool AliHLTMUONUtils::IntegrityOk(const AliHLTMUONPairsDecisionBlockStruct& block)
844 {
845         ///
846         /// Methods used to check more extensively if the integrity of various
847         /// types of data blocks are Ok and returns true in that case.
848         /// These can be slow and should generally only be used for debugging.
849         ///
850         
851         if (not HeaderOk(block)) return false;
852
853         const AliHLTMUONPairDecisionStruct* decision =
854                 reinterpret_cast<const AliHLTMUONPairDecisionStruct*>(&block + 1);
855         
856         // Check that the trigger bits for each track pair have integrity.
857         for (AliHLTUInt32_t i = 0; i < block.fHeader.fNrecords; i++)
858         {
859                 if (not IntegrityOk(decision[i])) return false;
860         }
861         
862         return true;
863 }