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