]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/AliHLTMUONUtils.h
Adding functionality to generate AliESDEvent objects from dHLT raw data during offlin...
[u/mrichter/AliRoot.git] / HLT / MUON / AliHLTMUONUtils.h
1 #ifndef ALIHLTMUONUTILS_H
2 #define ALIHLTMUONUTILS_H
3 /* Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4  * See cxx source for full Copyright notice                               */
5
6 /* $Id$ */
7
8 ///
9 /// @file   AliHLTMUONUtils.h
10 /// @author Artur Szostak <artursz@iafrica.com>
11 /// @date   17 May 2007
12 /// @brief  Class containing various dimuon HLT utility routines and macros.
13 ///
14
15 #include "AliHLTMUONDataTypes.h"
16 #include <ostream>
17
18 // Forward declare structures.
19 extern "C" {
20 struct AliHLTMUONTriggerRecordStruct;
21 struct AliHLTMUONTriggerRecordsBlockStruct;
22 struct AliHLTMUONTrigRecInfoStruct;
23 struct AliHLTMUONTrigRecsDebugBlockStruct;
24 struct AliHLTMUONRecHitStruct;
25 struct AliHLTMUONRecHitsBlockStruct;
26 struct AliHLTMUONClusterStruct;
27 struct AliHLTMUONClustersBlockStruct;
28 struct AliHLTMUONChannelStruct;
29 struct AliHLTMUONChannelsBlockStruct;
30 struct AliHLTMUONMansoTrackStruct;
31 struct AliHLTMUONMansoTracksBlockStruct;
32 struct AliHLTMUONMansoCandidateStruct;
33 struct AliHLTMUONMansoCandidatesBlockStruct;
34 struct AliHLTMUONTrackDecisionStruct;
35 struct AliHLTMUONSinglesDecisionBlockStruct;
36 struct AliHLTMUONPairDecisionStruct;
37 struct AliHLTMUONPairsDecisionBlockStruct;
38 } // extern "C"
39
40 /**
41  * AliHLTMUONUtils contains arbitrary utility methods to be used in various
42  * parts of the dimuon HLT system.
43  * These include methods to perform basic sanity checks on the integrity of
44  * data blocks.
45  */
46 class AliHLTMUONUtils
47 {
48 public:
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         static AliHLTUInt32_t PackTriggerRecordFlags(
58                         AliHLTMUONParticleSign sign, const bool hitset[4]
59                 );
60
61         /**
62          * This unpacks the AliHLTMUONTriggerRecordStruct::fFlags bits into
63          * its component fields.
64          * @param flags  The flags from an AliHLTMUONTriggerRecordStruct structure.
65          * @param sign    Sets this to the particle sign.
66          * @param hitset  Sets the array elements to indicate if the corresponding
67          *                fHits[i] element was set/filled.
68          */
69         static void UnpackTriggerRecordFlags(
70                         AliHLTUInt32_t flags, // [in]
71                         AliHLTMUONParticleSign& sign, // [out]
72                         bool hitset[4] // [out]
73                 );
74         
75         /**
76          * This packs the given parameters into the bits of a word appropriate
77          * for AliHLTMUONRecHitStruct::fFlags.
78          * @param chamber    The chamber number in the range [0..13].
79          * @param detElemId  Detector element ID number.
80          * @return  Returns the 32 bit packed word.
81          */
82         static AliHLTUInt32_t PackRecHitFlags(
83                         AliHLTUInt8_t chamber, AliHLTUInt16_t detElemId
84                 );
85
86         /**
87          * This unpacks the AliHLTMUONRecHitStruct::fFlags bits into
88          * its component fields.
89          * [in]  @param flags  The flags from an AliHLTMUONRecHitStruct structure.
90          * [out] @param chamber    Sets the chamber number in the range [0..13].
91          * [out] @param detElemId  Sets the detector element ID number.
92          */
93         static void UnpackRecHitFlags(
94                         AliHLTUInt32_t flags, // [in]
95                         AliHLTUInt8_t& chamber, // [out]
96                         AliHLTUInt16_t& detElemId // [out]
97                 );
98
99         /**
100          * This packs the given parameters into the bits of a word appropriate
101          * for AliHLTMUONMansoTrackStruct::fFlags.
102          * @param sign    The particle sign.
103          * @param hitset  Flags to indicate if the corresponding fHits[i] elements
104          *                was set/filled.
105          * @return  Returns the 32 bit packed word.
106          */
107         static AliHLTUInt32_t PackMansoTrackFlags(
108                         AliHLTMUONParticleSign sign, const bool hitset[4]
109                 )
110         {
111                 return PackTriggerRecordFlags(sign, hitset);
112         }
113
114         /**
115          * This unpacks the AliHLTMUONMansoTrackStruct::fFlags bits into
116          * its component fields.
117          * @param flags  The flags from an AliHLTMUONMansoTrackStruct structure.
118          * @param sign    Sets this to the particle sign.
119          * @param hitset  Sets the array elements to indicate if the corresponding
120          *                fHits[i] element was set/filled.
121          */
122         static void UnpackMansoTrackFlags(
123                         AliHLTUInt32_t flags, // [in]
124                         AliHLTMUONParticleSign& sign, // [out]
125                         bool hitset[4] // [out]
126                 )
127         {
128                 UnpackTriggerRecordFlags(flags, sign, hitset);
129         }
130         
131         /**
132          * This packs the given parameters into the bits of a word appropriate
133          * for AliHLTMUONTrackDecisionStruct::fTriggerBits.
134          * @param highPt  Has the track passed the high pt cut.
135          * @param lowPt   Has the track passed the low pt cut.
136          * @return  Returns the 32 bit packed word.
137          */
138         static AliHLTUInt32_t PackTrackDecisionBits(bool highPt, bool lowPt);
139         
140         /**
141          * This unpacks the AliHLTMUONTrackDecisionStruct::fTriggerBits bits into
142          * its component fields.
143          * @param bits  The trigger bits from an AliHLTMUONTrackDecisionStruct
144          *              structure.
145          * @param highPt Sets this to the value of the high pt cut bit.
146          * @param lowPt  Sets this to the value of the low pt cut bit.
147          */
148         static void UnpackTrackDecisionBits(
149                         AliHLTUInt32_t bits, // [in]
150                         bool& highPt, // [out]
151                         bool& lowPt // [out]
152                 );
153         
154         /**
155          * This packs the given parameters into the bits of a word appropriate
156          * for AliHLTMUONPairDecisionStruct::fTriggerBits.
157          *
158          * @param highMass Has the track pair passed the high invariant mass cut.
159          * @param lowMass  Has the track pair passed the low invariant mass cut.
160          * @param unlike   Does the track pair have unlike signs.
161          * @param highPtCount The number of tracks that passed the high pt cut
162          *                    in the pair.
163          * @param lowPtCount  The number of tracks that passed the low pt cut
164          *                    in the pair.
165          * @return  Returns the 32 bit packed word.
166          *
167          * Note: Must have highPtCount + lowPtCount <= 2 and unlike == true if
168          * highMass or lowMass is true.
169          */
170         static AliHLTUInt32_t PackPairDecisionBits(
171                         bool highMass, bool lowMass, bool unlike,
172                         AliHLTUInt8_t highPtCount, AliHLTUInt8_t lowPtCount
173                 );
174         
175         /**
176          * This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
177          * its component fields.
178          * @param bits  The trigger bits from an AliHLTMUONPairDecisionStruct
179          *              structure.
180          * @param highMass Sets this to the value of the high invariant mass cut bit.
181          * @param lowMass  Sets this to the value of the low invariant mass cut bit.
182          * @param unlike   Sets this if the pair is unlike sign.
183          * @param highPtCount Sets this to the high pt count bits.
184          * @param lowPtCount  Sets this to the low pt count bits.
185          */
186         static void UnpackPairDecisionBits(
187                         AliHLTUInt32_t bits, // [in]
188                         bool& highMass, // [out]
189                         bool& lowMass, // [out]
190                         bool& unlike, // [out]
191                         AliHLTUInt8_t& highPtCount, // [out]
192                         AliHLTUInt8_t& lowPtCount // [out]
193                 );
194         
195         /**
196          * This packs the given parameters into the 32bit Pub/Sub specification
197          * word in the data block descriptor.
198          *
199          * @param ddl  The list of DDLs forming part of the readout. ddl[0]
200          *             indicates DDL number 2560, ddl[1] is for DDL 2561 and so
201          *             on up to ddl[19]. ddl[20] and ddl[21] will be for the
202          *             trigger DDLs 2816 and 2817 respectively.
203          * @return  Returns the 32 bit packed specification word.
204          */
205         static AliHLTUInt32_t PackSpecBits(
206                         const bool ddl[22]
207                 );
208         
209         /**
210          * This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
211          * its component fields.
212          * @param bits  The Pub/Sub specification word from a data block descriptor.
213          * @param ddl  The output list of DDLs forming part of the readout. ddl[0]
214          *             indicates DDL number 2560, ddl[1] is for DDL 2561 and so
215          *             on up to ddl[19]. ddl[20] and ddl[21] will be for the
216          *             trigger DDLs 2816 and 2817 respectively.
217          */
218         static void UnpackSpecBits(
219                         AliHLTUInt32_t bits, // [in]
220                         bool ddl[22] // [out]
221                 );
222
223         /**
224          * This method converts the DDL number for the muon spectrometer in the
225          * range [0..21] to the equipment ID number.
226          * @param ddlNo  The DDL number in the range [0..21].
227          * @return  Returns the equipment ID number or -1 if ddlNo was invalid.
228          */
229         static AliHLTInt32_t DDLNumberToEquipId(AliHLTInt32_t ddlNo);
230         
231         /**
232          * This method converts the equipment ID number for a muon spectrometer
233          * DDL to the DDL number in the range [0..21].
234          * @param id  The equipment ID of the DDL.
235          * @return  Returns the DDL number in the range [0..21] or -1 if the
236          *          equipment ID was invalid.
237          */
238         static AliHLTInt32_t EquipIdToDDLNumber(AliHLTInt32_t id);
239         
240         /**
241          * This method converts a 32 bit data block specification for a MUON-HLT
242          * data block into its corresponding DDL equipment ID number.
243          * It is assumed that the specification is for a data block comming from
244          * a single DDL source. If more than one DDL contributed to the data block
245          * then -1 is returned.
246          * @param spec  The 32 bit specification for a data block.
247          * @return  Returns the equipment ID corresponding to the specification
248          *          or -1 if the specification was invalid.
249          */
250         static AliHLTInt32_t SpecToEquipId(AliHLTUInt32_t spec);
251         
252         /**
253          * This method converts a equipment ID number for a DDL into its corresponding
254          * 32 bit data block specification for the MUON-HLT.
255          * @param id  The equipment ID number of the DDL.
256          * @return  Returns the 32 bit data block specification or 0x0 if the
257          *          equipment ID was invalid.
258          */
259         static AliHLTUInt32_t EquipIdToSpec(AliHLTInt32_t id);
260         
261         /**
262          * This method converts a 32 bit data block specification for a MUON-HLT
263          * data block into its corresponding DDL number in the range [0..21].
264          * It is assumed that the specification is for a data block comming from
265          * a single DDL source. If more than one DDL contributed to the data block
266          * then -1 is returned.
267          * @param spec  The 32 bit specification for a data block.
268          * @return  Returns the corresponding DDL number for the specification
269          *          or -1 if the specification was invalid.
270          */
271         static AliHLTInt32_t SpecToDDLNumber(AliHLTUInt32_t spec);
272         
273         /**
274          * This method converts a DDL number in the range [0..21] into its
275          * corresponding 32 bit data block specification for the MUON-HLT.
276          * @param ddlNo  The equipment ID number of the DDL.
277          * @return  Returns the 32 bit data block specification or 0x0 if the
278          *          DDL number was invalid (out of range).
279          */
280         static AliHLTUInt32_t DDLNumberToSpec(AliHLTInt32_t ddlNo);
281
282         /**
283          * Returns true if the given specification was for a single trigger DDL.
284          */
285         static bool IsTriggerDDL(AliHLTUInt32_t spec)
286         {
287                 AliHLTInt32_t ddl = SpecToDDLNumber(spec);
288                 return (20 <= ddl and ddl <= 21);
289         }
290
291         /**
292          * Returns true if the given specification was for a single tracker DDL.
293          */
294         static bool IsTrackerDDL(AliHLTUInt32_t spec)
295         {
296                 AliHLTInt32_t ddl = SpecToDDLNumber(spec);
297                 return (0 <= ddl and ddl <= 19);
298         }
299
300         /**
301          * Returns true if the given specification is in principle valid.
302          * It checks if the bits that should be zero are indeed zero.
303          */
304         static bool IsSpecValid(AliHLTUInt32_t spec)
305         {
306                 AliHLTUInt32_t mask = ~((1 << 22) - 1);  // First 22 bits indicate DDL number.
307                 return (spec & mask) == 0x0;
308         }
309
310         /**
311          * Returns true if the data specification indicates the data block contains
312          * information generated from a trigger DDL or data fragments thereof.
313          */
314         static bool ContainsDataFromTrigger(AliHLTUInt32_t spec)
315         {
316                 AliHLTUInt32_t mask = ((1 << 22) - 1) & ~((1 << 20) - 1);
317                 return (spec & mask) != 0x0;
318         }
319
320         /**
321          * Returns true if the data specification indicates the data block contains
322          * information generated from a tracker DDL or data fragments thereof.
323          */
324         static bool ContainsDataFromTracker(AliHLTUInt32_t spec)
325         {
326                 AliHLTUInt32_t mask = ((1 << 20) - 1);
327                 return (spec & mask) != 0x0;
328         }
329         
330         /**
331          * Parses the string containing the type name of a dHLT data block and
332          * returns the corresponding AliHLTMUONDataBlockType value.
333          * \param  type  The string containing the type name.
334          * \returns  The data block type or kUnknownDataBlock if the type name
335          *      is invalid.
336          */
337         static AliHLTMUONDataBlockType ParseCommandLineTypeString(const char* type);
338         
339         /**
340          * Converts a type ID to a type string to be used for the dHLT FilePublisher
341          * component configuration parameters for example.
342          */
343         static const char* DataBlockTypeToString(AliHLTMUONDataBlockType type);
344         
345         /**
346          * These codes indicate the reason why a data block failed its
347          * validity check.
348          */
349         enum WhyNotValid
350         {
351                 kNoReason,   ///< There was no reason for failure.
352                 kHeaderContainsWrongType,  ///< The common header contains an incorrect type ID.
353                 kHeaderContainsWrongRecordWidth,  ///< The common header contains an incorrect data record width.
354                 kInvalidIdValue,  ///< The structure identifier does not have a valid value.
355                 kInvalidTriggerIdValue,  ///< The trigger structure identifier does not have a valid value.
356                 kInvalidTrackIdValue,  ///< The track structure identifier does not have a valid value.
357                 kReservedBitsNotZero,  ///< Reserved bits have not been set to zero.
358                 kParticleSignBitsNotValid,  ///< The particle sign bits are not a valid value.
359                 kHitNotMarkedAsNil,  ///< A hit was marked as not found, but the corresponding hit structure was not set to nil.
360                 kInvalidDetElementNumber,  ///< An invalid detector element ID was found.
361                 kInvalidChamberNumber,  ///< An invalid chamber number was found.
362                 kHitIsNil,  ///< The hit cannot be set to a nil value.
363                 kInvalidChannelCount,  ///< The number of channels indicated is zero or outside the valid range.
364                 kInvalidBusPatchId,  ///< The bus patch ID is outside the valid range.
365                 kInvalidManuId,  ///< The MANU ID is outside the valid range.
366                 kInvalidChannelAddress,  ///< The MANU channel address is outside the valid range.
367                 kInvalidSignal,  ///< The ADC signal value is outside the valid range.
368                 kDataWordDifferent, ///< The raw data word is different from the unpacked values.
369                 kChiSquareInvalid,  ///< The chi squared value must be a positive value or -1 indicating a fitting error.
370                 kMomentumVectorNotZero, ///< The chi sqaured value is set to -1, but momentum vector not zero.
371                 kRoiRadiusInvalid, ///< The region of interest radius is invalid.
372                 kHitNotWithinRoi, ///< A tracks hit is not within the corresponding region of interest.
373                 kPtValueNotValid,  ///< The pT value is not positive nor -1 indicating an invalid value.
374                 kPairTrackIdsAreIdentical,  ///< The track IDs of the track pair are identical.
375                 kMassValueNotValid,  ///< The invariant mass value is not positive nor -1 indicating an invalid value.
376                 kLowPtCountInvalid,  ///< The low pT trigger count is greater than 2, which is invalid.
377                 kHighPtCountInvalid,  ///< The high pT trigger count is greater than 2, which is invalid.
378                 kFoundDuplicateIDs,  ///< Found duplicate identifiers, but they should all be unique.
379                 kFoundDuplicateHits,  ///< Found duplicate hits.
380                 kFoundDuplicateTriggers  ///< Found duplicate trigger decisions.
381         };
382         
383         /**
384          * This method converts the WhyNotValid enumeration to a string representation.
385          */
386         static const char* FailureReasonToString(WhyNotValid reason);
387         
388         /**
389          * This method returns a string containing a user readable message explaining
390          * the reason for failure described by the WhyNotValid enumeration.
391          */
392         static const char* FailureReasonToMessage(WhyNotValid reason);
393
394         /**
395          * Method used to check if the header information corresponds to the
396          * supposed type of the trigger records data block.
397          * This method will return either kHeaderContainsWrongType or
398          * kHeaderContainsWrongRecordWidth as the reason code.
399          * [in]  \param block  The data block to check.
400          * [out] \param reason  If this is not NULL, then the variable pointed to
401          *      by this pointer will be filled with the reason code describing why
402          *      the header is not valid, if and only if a problem is found with
403          *      the data.
404          * \returns  true if there is no problem with the header and false otherwise.
405          */
406         static bool HeaderOk(const AliHLTMUONTriggerRecordsBlockStruct& block, WhyNotValid* reason = NULL)
407         {
408                 AliHLTUInt32_t count = 1;
409                 return HeaderOk(block, reason, count);
410         }
411         
412         /**
413          * Method used to check if the header information corresponds to the
414          * supposed type of the trigger debug information data block.
415          * This method will return either kHeaderContainsWrongType or
416          * kHeaderContainsWrongRecordWidth as the reason code.
417          * [in]  \param block  The data block to check.
418          * [out] \param reason  If this is not NULL, then the variable pointed to
419          *      by this pointer will be filled with the reason code describing why
420          *      the header is not valid, if and only if a problem is found with
421          *      the data.
422          * \returns  true if there is no problem with the header and false otherwise.
423          */
424         static bool HeaderOk(const AliHLTMUONTrigRecsDebugBlockStruct& block, WhyNotValid* reason = NULL)
425         {
426                 AliHLTUInt32_t count = 1;
427                 return HeaderOk(block, reason, count);
428         }
429         
430         /**
431          * Method used to check if the header information corresponds to the
432          * supposed type of the reconstructed hits data block.
433          * This method will return either kHeaderContainsWrongType or
434          * kHeaderContainsWrongRecordWidth as the reason code.
435          * [in]  \param block  The data block to check.
436          * [out] \param reason  If this is not NULL, then the variable pointed to
437          *      by this pointer will be filled with the reason code describing why
438          *      the header is not valid, if and only if a problem is found with
439          *      the data.
440          * \returns  true if there is no problem with the header and false otherwise.
441          */
442         static bool HeaderOk(const AliHLTMUONRecHitsBlockStruct& block, WhyNotValid* reason = NULL)
443         {
444                 AliHLTUInt32_t count = 1;
445                 return HeaderOk(block, reason, count);
446         }
447         
448         /**
449          * Method used to check if the header information corresponds to the
450          * supposed type of the clusters data block.
451          * This method will return either kHeaderContainsWrongType or
452          * kHeaderContainsWrongRecordWidth as the reason code.
453          * [in]  \param block  The data block to check.
454          * [out] \param reason  If this is not NULL, then the variable pointed to
455          *      by this pointer will be filled with the reason code describing why
456          *      the header is not valid, if and only if a problem is found with
457          *      the data.
458          * \returns  true if there is no problem with the header and false otherwise.
459          */
460         static bool HeaderOk(const AliHLTMUONClustersBlockStruct& block, WhyNotValid* reason = NULL)
461         {
462                 AliHLTUInt32_t count = 1;
463                 return HeaderOk(block, reason, count);
464         }
465         
466         /**
467          * Method used to check if the header information corresponds to the
468          * supposed type of the channels data block.
469          * This method will return either kHeaderContainsWrongType or
470          * kHeaderContainsWrongRecordWidth as the reason code.
471          * [in]  \param block  The data block to check.
472          * [out] \param reason  If this is not NULL, then the variable pointed to
473          *      by this pointer will be filled with the reason code describing why
474          *      the header is not valid, if and only if a problem is found with
475          *      the data.
476          * \returns  true if there is no problem with the header and false otherwise.
477          */
478         static bool HeaderOk(const AliHLTMUONChannelsBlockStruct& block, WhyNotValid* reason = NULL)
479         {
480                 AliHLTUInt32_t count = 1;
481                 return HeaderOk(block, reason, count);
482         }
483         
484         /**
485          * Method used to check if the header information corresponds to the
486          * supposed type of the Manso tracks data block.
487          * This method will return either kHeaderContainsWrongType or
488          * kHeaderContainsWrongRecordWidth as the reason code.
489          * [in]  \param block  The data block to check.
490          * [out] \param reason  If this is not NULL, then the variable pointed to
491          *      by this pointer will be filled with the reason code describing why
492          *      the header is not valid, if and only if a problem is found with
493          *      the data.
494          * \returns  true if there is no problem with the header and false otherwise.
495          */
496         static bool HeaderOk(const AliHLTMUONMansoTracksBlockStruct& block, WhyNotValid* reason = NULL)
497         {
498                 AliHLTUInt32_t count = 1;
499                 return HeaderOk(block, reason, count);
500         }
501         
502         /**
503          * Method used to check if the header information corresponds to the
504          * supposed type of the Manso candidates data block.
505          * This method will return either kHeaderContainsWrongType or
506          * kHeaderContainsWrongRecordWidth as the reason code.
507          * [in]  \param block  The data block to check.
508          * [out] \param reason  If this is not NULL, then the variable pointed to
509          *      by this pointer will be filled with the reason code describing why
510          *      the header is not valid, if and only if a problem is found with
511          *      the data.
512          * \returns  true if there is no problem with the header and false otherwise.
513          */
514         static bool HeaderOk(const AliHLTMUONMansoCandidatesBlockStruct& block, WhyNotValid* reason = NULL)
515         {
516                 AliHLTUInt32_t count = 1;
517                 return HeaderOk(block, reason, count);
518         }
519         
520         /**
521          * Method used to check if the header information corresponds to the
522          * supposed type of the single tracks dHLT trigger decision data block.
523          * This method will return either kHeaderContainsWrongType or
524          * kHeaderContainsWrongRecordWidth as the reason code.
525          * [in]  \param block  The data block to check.
526          * [out] \param reason  If this is not NULL, then the variable pointed to
527          *      by this pointer will be filled with the reason code describing why
528          *      the header is not valid, if and only if a problem is found with
529          *      the data.
530          * \returns  true if there is no problem with the header and false otherwise.
531          */
532         static bool HeaderOk(const AliHLTMUONSinglesDecisionBlockStruct& block, WhyNotValid* reason = NULL)
533         {
534                 AliHLTUInt32_t count = 1;
535                 return HeaderOk(block, reason, count);
536         }
537         
538         /**
539          * Method used to check if the header information corresponds to the
540          * supposed type of the track pairs dHLT trigger decision data block.
541          * This method will return either kHeaderContainsWrongType or
542          * kHeaderContainsWrongRecordWidth as the reason code.
543          * [in]  \param block  The data block to check.
544          * [out] \param reason  If this is not NULL, then the variable pointed to
545          *      by this pointer will be filled with the reason code describing why
546          *      the header is not valid, if and only if a problem is found with
547          *      the data.
548          * \returns  true if there is no problem with the header and false otherwise.
549          */
550         static bool HeaderOk(const AliHLTMUONPairsDecisionBlockStruct& block, WhyNotValid* reason = NULL)
551         {
552                 AliHLTUInt32_t count = 1;
553                 return HeaderOk(block, reason, count);
554         }
555
556         /**
557          * Methods used to check if the header information corresponds to the
558          * supposed type of the data block.
559          * If the 'reason' parameter should point to an array which will store
560          * the reason codes indicating the problems with the data block.
561          * The 'reasonCount' parameter should initialy contain the number of
562          * elements that can be stored in reason. When the method exits it will
563          * store the number of elements in the 'reason' array actually filled.
564          */
565         static bool HeaderOk(
566                         const AliHLTMUONTriggerRecordsBlockStruct& block,
567                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
568                 );
569         
570         static bool HeaderOk(
571                         const AliHLTMUONTrigRecsDebugBlockStruct& block,
572                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
573                 );
574         
575         static bool HeaderOk(
576                         const AliHLTMUONRecHitsBlockStruct& block,
577                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
578                 );
579         
580         static bool HeaderOk(
581                         const AliHLTMUONClustersBlockStruct& block,
582                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
583                 );
584         
585         static bool HeaderOk(
586                         const AliHLTMUONChannelsBlockStruct& block,
587                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
588                 );
589         
590         static bool HeaderOk(
591                         const AliHLTMUONMansoTracksBlockStruct& block,
592                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
593                 );
594         
595         static bool HeaderOk(
596                         const AliHLTMUONMansoCandidatesBlockStruct& block,
597                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
598                 );
599         
600         static bool HeaderOk(
601                         const AliHLTMUONSinglesDecisionBlockStruct& block,
602                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
603                 );
604         
605         static bool HeaderOk(
606                         const AliHLTMUONPairsDecisionBlockStruct& block,
607                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
608                 );
609         
610         /**
611          * This method is used to check more extensively if the integrity of the
612          * trigger record structure is OK and returns true in that case.
613          * [in] \param tr  The trigger record structure to check.
614          * [out] \param reason  If this is not NULL, then it will be filled with
615          *      the reason code describing why the structure is not valid, if and
616          *      only if a problem is found with the data.
617          * \returns  true if there is no problem with the structure and false otherwise.
618          */
619         static bool IntegrityOk(
620                         const AliHLTMUONTriggerRecordStruct& tr,
621                         WhyNotValid* reason = NULL
622                 )
623         {
624                 AliHLTUInt32_t count = 1;
625                 return IntegrityOk(tr, reason, count);
626         }
627         
628         /**
629          * This method is used to check more extensively if the integrity of the
630          * dHLT raw internal data block is OK and returns true in that case.
631          * [in] \param block  The trigger record data block to check.
632          * [out] \param reason  If this is not NULL, then it will be filled with
633          *      the reason code describing why the data block is not valid, if and
634          *      only if a problem is found with the data.
635          * [out] \param recordNum  If this is not NULL, then it will be filled with
636          *      the number of the trigger record that had a problem. This value will
637          *      only contain a valid value if the method RecordNumberWasSet(*reason)
638          *      returns true. Thus, 'reason' must be set.
639          * \returns  true if there is no problem with the data and false otherwise.
640          */
641         static bool IntegrityOk(
642                         const AliHLTMUONTriggerRecordsBlockStruct& block,
643                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
644                 )
645         {
646                 AliHLTUInt32_t count = 1;
647                 return IntegrityOk(block, reason, recordNum, count);
648         }
649         
650         /**
651          * This method is used to check more extensively if the integrity of the
652          * trigger record debug information structure is OK and returns true in that case.
653          * [in] \param trigInfo  The trigger record debug information structure to check.
654          * [out] \param reason  If this is not NULL, then it will be filled with
655          *      the reason code describing why the structure is not valid, if and
656          *      only if a problem is found with the data.
657          * \returns  true if there is no problem with the structure and false otherwise.
658          */
659         static bool IntegrityOk(
660                         const AliHLTMUONTrigRecInfoStruct& trigInfo,
661                         WhyNotValid* reason = NULL
662                 )
663         {
664                 AliHLTUInt32_t count = 1;
665                 return IntegrityOk(trigInfo, reason, count);
666         }
667         
668         /**
669          * This method is used to check more extensively if the integrity of the
670          * dHLT raw internal data block is OK and returns true in that case.
671          * [in] \param block  The trigger record debugging information data block to check.
672          * [out] \param reason  If this is not NULL, then it will be filled with
673          *      the reason code describing why the data block is not valid, if and
674          *      only if a problem is found with the data.
675          * [out] \param recordNum  If this is not NULL, then it will be filled with
676          *      the number of the trigger record debug information structure that had
677          *      a problem. This value will only contain a valid value if the method
678          *      RecordNumberWasSet(*reason) returns true. Thus, 'reason' must be set.
679          * \returns  true if there is no problem with the data and false otherwise.
680          */
681         static bool IntegrityOk(
682                         const AliHLTMUONTrigRecsDebugBlockStruct& block,
683                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
684                 )
685         {
686                 AliHLTUInt32_t count = 1;
687                 return IntegrityOk(block, reason, recordNum, count);
688         }
689         
690         /**
691          * This method is used to check more extensively if the integrity of the
692          * reconstructed hit structure is OK and returns true in that case.
693          * [in] \param hit  The reconstructed hit structure to check.
694          * [out] \param reason  If this is not NULL, then it will be filled with
695          *      the reason code describing why the structure is not valid, if and
696          *      only if a problem is found with the data.
697          * \returns  true if there is no problem with the data and false otherwise.
698          */
699         static bool IntegrityOk(
700                         const AliHLTMUONRecHitStruct& hit,
701                         WhyNotValid* reason = NULL
702                 )
703         {
704                 AliHLTUInt32_t count = 1;
705                 return IntegrityOk(hit, reason, count);
706         }
707         
708         /**
709          * This method is used to check more extensively if the integrity of the
710          * dHLT raw internal data block is OK and returns true in that case.
711          * [in] \param block  The reconstructed hits data block to check.
712          * [out] \param reason  If this is not NULL, then it will be filled with
713          *      the reason code describing why the data block is not valid, if and
714          *      only if a problem is found with the data.
715          * [out] \param recordNum  If this is not NULL, then it will be filled with
716          *      the number of the cluster structure that had a problem. This value
717          *      will only contain a valid value if the method
718          *      RecordNumberWasSet(*reason) returns true. Thus, 'reason' must be set.
719          * \returns  true if there is no problem with the data and false otherwise.
720          */
721         static bool IntegrityOk(
722                         const AliHLTMUONRecHitsBlockStruct& block,
723                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
724                 )
725         {
726                 AliHLTUInt32_t count = 1;
727                 return IntegrityOk(block, reason, recordNum, count);
728         }
729         
730         /**
731          * This method is used to check more extensively if the integrity of the
732          * cluster data structure is OK and returns true in that case.
733          * [in] \param cluster  The cluster structure to check.
734          * [out] \param reason  If this is not NULL, then it will be filled with
735          *      the reason code describing why the structure is not valid, if and
736          *      only if a problem is found with the data.
737          * \returns  true if there is no problem with the data and false otherwise.
738          */
739         static bool IntegrityOk(
740                         const AliHLTMUONClusterStruct& cluster,
741                         WhyNotValid* reason = NULL
742                 )
743         {
744                 AliHLTUInt32_t count = 1;
745                 return IntegrityOk(cluster, reason, count);
746         }
747         
748         /**
749          * This method is used to check more extensively if the integrity of the
750          * dHLT raw internal data block is OK and returns true in that case.
751          * [in] \param block  The clusters data block to check.
752          * [out] \param reason  If this is not NULL, then it will be filled with
753          *      the reason code describing why the data block is not valid, if and
754          *      only if a problem is found with the data.
755          * [out] \param recordNum  If this is not NULL, then it will be filled with
756          *      the number of the cluster structure that had a problem. This value
757          *      will only contain a valid value if the method
758          *      RecordNumberWasSet(*reason) returns true. Thus, 'reason' must be set.
759          * \returns  true if there is no problem with the data and false otherwise.
760          */
761         static bool IntegrityOk(
762                         const AliHLTMUONClustersBlockStruct& block,
763                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
764                 )
765         {
766                 AliHLTUInt32_t count = 1;
767                 return IntegrityOk(block, reason, recordNum, count);
768         }
769         
770         /**
771          * This method is used to check more extensively if the integrity of the
772          * channel data structure is OK and returns true in that case.
773          * [in] \param cluster  The channel structure to check.
774          * [out] \param reason  If this is not NULL, then it will be filled with
775          *      the reason code describing why the structure is not valid, if and
776          *      only if a problem is found with the data.
777          * \returns  true if there is no problem with the data and false otherwise.
778          */
779         static bool IntegrityOk(
780                         const AliHLTMUONChannelStruct& channel,
781                         WhyNotValid* reason = NULL
782                 )
783         {
784                 AliHLTUInt32_t count = 1;
785                 return IntegrityOk(channel, reason, count);
786         }
787         
788         /**
789          * This method is used to check more extensively if the integrity of the
790          * dHLT raw internal data block is OK and returns true in that case.
791          * [in] \param block  The ADC channels data block to check.
792          * [out] \param reason  If this is not NULL, then it will be filled with
793          *      the reason code describing why the data block is not valid, if and
794          *      only if a problem is found with the data.
795          * [out] \param recordNum  If this is not NULL, then it will be filled with
796          *      the number of the channel structure that had a problem. This value
797          *      will only contain a valid value if the method
798          *      RecordNumberWasSet(*reason) returns true. Thus, 'reason' must be set.
799          * \returns  true if there is no problem with the data and false otherwise.
800          */
801         static bool IntegrityOk(
802                         const AliHLTMUONChannelsBlockStruct& block,
803                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
804                 )
805         {
806                 AliHLTUInt32_t count = 1;
807                 return IntegrityOk(block, reason, recordNum, count);
808         }
809         
810         /**
811          * This method is used to check more extensively if the integrity of the
812          * Manso track structure is OK and returns true in that case.
813          * [in] \param track  The Manso track structure to check.
814          * [out] \param reason  If this is not NULL, then it will be filled with
815          *      the reason code describing why the structure is not valid, if and
816          *      only if a problem is found with the data.
817          * \returns  true if there is no problem with the structure and false otherwise.
818          */
819         static bool IntegrityOk(
820                         const AliHLTMUONMansoTrackStruct& track,
821                         WhyNotValid* reason = NULL
822                 )
823         {
824                 AliHLTUInt32_t count = 1;
825                 return IntegrityOk(track, reason, count);
826         }
827         
828         /**
829          * This method is used to check more extensively if the integrity of the
830          * dHLT raw internal data block is OK and returns true in that case.
831          * [in] \param block  The Manso track data block to check.
832          * [out] \param reason  If this is not NULL, then it will be filled with
833          *      the reason code describing why the data block is not valid, if and
834          *      only if a problem is found with the data.
835          * [out] \param recordNum  If this is not NULL, then it will be filled with
836          *      the number of the Manso track structure that had a problem.
837          *      This value will only contain a valid value if the method
838          *      RecordNumberWasSet(*reason) returns true. Thus, 'reason' must be set.
839          * \returns  true if there is no problem with the data and false otherwise.
840          */
841         static bool IntegrityOk(
842                         const AliHLTMUONMansoTracksBlockStruct& block,
843                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
844                 )
845         {
846                 AliHLTUInt32_t count = 1;
847                 return IntegrityOk(block, reason, recordNum, count);
848         }
849         
850         /**
851          * This method is used to check more extensively if the integrity of the
852          * Manso track candidate structure is OK and returns true in that case.
853          * [in] \param candidate  The Manso track candidate structure to check.
854          * [out] \param reason  If this is not NULL, then it will be filled with
855          *      the reason code describing why the structure is not valid, if and
856          *      only if a problem is found with the data.
857          * \returns  true if there is no problem with the structure and false otherwise.
858          */
859         static bool IntegrityOk(
860                         const AliHLTMUONMansoCandidateStruct& candidate,
861                         WhyNotValid* reason = NULL
862                 )
863         {
864                 AliHLTUInt32_t count = 1;
865                 return IntegrityOk(candidate, reason, count);
866         }
867         
868         /**
869          * This method is used to check more extensively if the integrity of the
870          * dHLT raw internal data block is OK and returns true in that case.
871          * [in] \param block  The Manso track candidate data block to check.
872          * [out] \param reason  If this is not NULL, then it will be filled with
873          *      the reason code describing why the data block is not valid, if and
874          *      only if a problem is found with the data.
875          * [out] \param recordNum  If this is not NULL, then it will be filled with
876          *      the number of the Manso track candidate structure that had a problem.
877          *      This value will only contain a valid value if the method
878          *      RecordNumberWasSet(*reason) returns true. Thus, 'reason' must be set.
879          * \returns  true if there is no problem with the data and false otherwise.
880          */
881         static bool IntegrityOk(
882                         const AliHLTMUONMansoCandidatesBlockStruct& block,
883                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
884                 )
885         {
886                 AliHLTUInt32_t count = 1;
887                 return IntegrityOk(block, reason, recordNum, count);
888         }
889         
890         /**
891          * This method is used to check more extensively if the integrity of the
892          * single track trigger decision structure is OK and returns true in that case.
893          * [in] \param decision  The trigger decision structure to check.
894          * [out] \param reason  If this is not NULL, then it will be filled with
895          *      the reason code describing why the structure is not valid, if and
896          *      only if a problem is found with the data.
897          * \returns  true if there is no problem with the structure and false otherwise.
898          */
899         static bool IntegrityOk(
900                         const AliHLTMUONTrackDecisionStruct& decision,
901                         WhyNotValid* reason = NULL
902                 )
903         {
904                 AliHLTUInt32_t count = 1;
905                 return IntegrityOk(decision, reason, count);
906         }
907         
908         /**
909          * This method is used to check more extensively if the integrity of the
910          * dHLT raw internal data block is OK and returns true in that case.
911          * [in] \param block  The single track trigger decision data block to check.
912          * [out] \param reason  If this is not NULL, then it will be filled with
913          *      the reason code describing why the data block is not valid, if and
914          *      only if a problem is found with the data.
915          * [out] \param recordNum  If this is not NULL, then it will be filled with
916          *      the number of the single track trigger decision structure that had
917          *      a problem. This value will only contain a valid value if the method
918          *      RecordNumberWasSet(*reason) returns true. Thus, 'reason' must be set.
919          * \returns  true if there is no problem with the data and false otherwise.
920          */
921         static bool IntegrityOk(
922                         const AliHLTMUONSinglesDecisionBlockStruct& block,
923                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
924                 )
925         {
926                 AliHLTUInt32_t count = 1;
927                 return IntegrityOk(block, reason, recordNum, count);
928         }
929         
930         /**
931          * This method is used to check more extensively if the integrity of the
932          * track pair trigger decision structure is OK and returns true in that case.
933          * [in] \param decision  The trigger decision structure to check.
934          * [out] \param reason  If this is not NULL, then it will be filled with
935          *      the reason code describing why the structure is not valid, if and
936          *      only if a problem is found with the data.
937          * \returns  true if there is no problem with the structure and false otherwise.
938          */
939         static bool IntegrityOk(
940                         const AliHLTMUONPairDecisionStruct& decision,
941                         WhyNotValid* reason = NULL
942                 )
943         {
944                 AliHLTUInt32_t count = 1;
945                 return IntegrityOk(decision, reason, count);
946         }
947         
948         /**
949          * This method is used to check more extensively if the integrity of the
950          * dHLT raw internal data block is OK and returns true in that case.
951          * [in] \param block  The track pair trigger decision data block to check.
952          * [out] \param reason  If this is not NULL, then it will be filled with
953          *      the reason code describing why the data block is not valid, if and
954          *      only if a problem is found with the data.
955          * [out] \param recordNum  If this is not NULL, then it will be filled with
956          *      the number of the track pairs trigger decision structure that had
957          *      a problem. This value will only contain a valid value if the method
958          *      RecordNumberWasSet(*reason) returns true. Thus, 'reason' must be set.
959          * \returns  true if there is no problem with the data and false otherwise.
960          */
961         static bool IntegrityOk(
962                         const AliHLTMUONPairsDecisionBlockStruct& block,
963                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
964                 )
965         {
966                 AliHLTUInt32_t count = 1;
967                 return IntegrityOk(block, reason, recordNum, count);
968         }
969
970         /**
971          * Methods used to check more extensively if the integrity of various
972          * types of data blocks are Ok and returns true in that case.
973          * These can be slow and should generally only be used for debugging.
974          * The methods are able to return multiple reasons for the problems related
975          * to the data block under test.
976          */
977         static bool IntegrityOk(
978                         const AliHLTMUONTriggerRecordStruct& tr,
979                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
980                 );
981         
982         static bool IntegrityOk(
983                         const AliHLTMUONTriggerRecordsBlockStruct& block,
984                         WhyNotValid* reason, AliHLTUInt32_t* recordNum,
985                         AliHLTUInt32_t& reasonCount
986                 );
987         
988         static bool IntegrityOk(
989                         const AliHLTMUONTrigRecInfoStruct& trigInfo,
990                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
991                 );
992         
993         static bool IntegrityOk(
994                         const AliHLTMUONTrigRecsDebugBlockStruct& block,
995                         WhyNotValid* reason, AliHLTUInt32_t* recordNum,
996                         AliHLTUInt32_t& reasonCount
997                 );
998         
999         static bool IntegrityOk(
1000                         const AliHLTMUONRecHitStruct& hit,
1001                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
1002                 );
1003         
1004         static bool IntegrityOk(
1005                         const AliHLTMUONRecHitsBlockStruct& block,
1006                         WhyNotValid* reason, AliHLTUInt32_t* recordNum,
1007                         AliHLTUInt32_t& reasonCount
1008                 );
1009         
1010         static bool IntegrityOk(
1011                         const AliHLTMUONClusterStruct& cluster,
1012                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
1013                 );
1014         
1015         static bool IntegrityOk(
1016                         const AliHLTMUONClustersBlockStruct& block,
1017                         WhyNotValid* reason, AliHLTUInt32_t* recordNum,
1018                         AliHLTUInt32_t& reasonCount
1019                 );
1020         
1021         static bool IntegrityOk(
1022                         const AliHLTMUONChannelStruct& channel,
1023                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
1024                 );
1025         
1026         static bool IntegrityOk(
1027                         const AliHLTMUONChannelsBlockStruct& block,
1028                         WhyNotValid* reason, AliHLTUInt32_t* recordNum,
1029                         AliHLTUInt32_t& reasonCount
1030                 );
1031         
1032         static bool IntegrityOk(
1033                         const AliHLTMUONMansoTrackStruct& track,
1034                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
1035                 );
1036         
1037         static bool IntegrityOk(
1038                         const AliHLTMUONMansoTracksBlockStruct& block,
1039                         WhyNotValid* reason, AliHLTUInt32_t* recordNum,
1040                         AliHLTUInt32_t& reasonCount
1041                 );
1042         
1043         static bool IntegrityOk(
1044                         const AliHLTMUONMansoCandidateStruct& candidate,
1045                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
1046                 );
1047         
1048         static bool IntegrityOk(
1049                         const AliHLTMUONMansoCandidatesBlockStruct& block,
1050                         WhyNotValid* reason, AliHLTUInt32_t* recordNum,
1051                         AliHLTUInt32_t& reasonCount
1052                 );
1053         
1054         static bool IntegrityOk(
1055                         const AliHLTMUONTrackDecisionStruct& decision,
1056                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
1057                 );
1058         
1059         static bool IntegrityOk(
1060                         const AliHLTMUONSinglesDecisionBlockStruct& block,
1061                         WhyNotValid* reason, AliHLTUInt32_t* recordNum,
1062                         AliHLTUInt32_t& reasonCount
1063                 );
1064         
1065         static bool IntegrityOk(
1066                         const AliHLTMUONPairDecisionStruct& decision,
1067                         WhyNotValid* reason, AliHLTUInt32_t& reasonCount
1068                 );
1069         
1070         static bool IntegrityOk(
1071                         const AliHLTMUONPairsDecisionBlockStruct& block,
1072                         WhyNotValid* reason, AliHLTUInt32_t* recordNum,
1073                         AliHLTUInt32_t& reasonCount
1074                 );
1075         
1076         /**
1077          * Returns true if the \em recordNum in the corresponding IntegrityOk method
1078          * would have been set, if it returned false and a reason was set.
1079          * This helper method makes it easy to test if the \em recordNum parameter
1080          * is filled with a valid value or not.
1081          */
1082         static bool RecordNumberWasSet(WhyNotValid reason);
1083
1084 private:
1085         // Should never have to create or destroy this object.
1086         AliHLTMUONUtils();
1087         ~AliHLTMUONUtils();
1088 };
1089
1090 //_____________________________________________________________________________
1091
1092 inline std::ostream& operator << (std::ostream& stream, AliHLTMUONUtils::WhyNotValid reason)
1093 {
1094         /// Stream operator for the WhyNotValid enumeration for usage with
1095         /// std::ostream classes. Allows usages such as:
1096         /// AliHLTMUONUtils::WhyNotValid r; std::cout << r;
1097         
1098         stream << AliHLTMUONUtils::FailureReasonToString(reason);
1099         return stream;
1100 }
1101
1102 //_____________________________________________________________________________
1103
1104 // Since c++ is missing a finally "keyword" we define one. Its usage is identical
1105 // to a try..finally statement in Java etc.. however, since it is officialy a macro
1106 // one must use the ( ) brackets instead of { }
1107 // If the compiler supports __finally use it otherwise make our own.
1108 #if defined(__BORLANDC__)
1109 #       define finally(str) __finally{str}
1110 #else
1111 #       define finally(code) \
1112                 catch(...) \
1113                 { \
1114                         code \
1115                         throw; \
1116                 }; \
1117                 code
1118 #endif // __BORLANDC__
1119
1120 // Here we define the DebugTrace(message) macro for easy embedding of debug
1121 // information into the dimuon HLT code. Its usage is meant to be for generating
1122 // traces of the program which are only useful during full scale debugging.
1123 // Log messages should use the standard HLT logging mechanisms.
1124 // The output is only generated in programs compiled with the DEBUG directive
1125 // defined. Here is a usage example:
1126 //
1127 //  // statements...
1128 //  DebugTrace("some debug information.");
1129 //  // statements...
1130 //
1131 // One can also use C++ ostream operators and manipulators like so:
1132 //
1133 //  // statements...
1134 //  int x, y;
1135 //  DebugTrace("x = " << x << " and y = 0x" << std::hex << y );
1136 //  // statements...
1137 //
1138 #ifdef DEBUG
1139 #       include <iostream>
1140 #       define DebugTrace(message) {std::cout << message << std::endl;}
1141 #else // DEBUG
1142 #       define DebugTrace(message)
1143 #endif // DEBUG
1144
1145
1146 #endif // ALIHLTMUONUTILS_H