Fixing memory handling of AliHLTMUONHitReconstructorComponent during error conditions...
[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   
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 AliHLTMUONTrigRecsDebugBlockStruct;
23 struct AliHLTMUONTriggerChannelsBlockStruct;
24 struct AliHLTMUONRecHitsBlockStruct;
25 struct AliHLTMUONClustersBlockStruct;
26 struct AliHLTMUONChannelsBlockStruct;
27 struct AliHLTMUONMansoTrackStruct;
28 struct AliHLTMUONMansoTracksBlockStruct;
29 struct AliHLTMUONMansoCandidatesBlockStruct;
30 struct AliHLTMUONTrackDecisionStruct;
31 struct AliHLTMUONSinglesDecisionBlockStruct;
32 struct AliHLTMUONPairDecisionStruct;
33 struct AliHLTMUONPairsDecisionBlockStruct;
34 } // extern "C"
35
36 /**
37  * AliHLTMUONUtils contains arbitrary utility methods to be used in various
38  * parts of the dimuon HLT system.
39  * These include methods to perform basic sanity checks on the integrity of
40  * data blocks.
41  */
42 class AliHLTMUONUtils
43 {
44 public:
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         static AliHLTUInt32_t PackTriggerRecordFlags(
54                         AliHLTMUONParticleSign sign, const bool hitset[4]
55                 );
56
57         /**
58          * This unpacks the AliHLTMUONTriggerRecordStruct::fFlags bits into
59          * its component fields.
60          * @param flags  The flags from an AliHLTMUONTriggerRecordStruct structure.
61          * @param sign    Sets this to the particle sign.
62          * @param hitset  Sets the array elements to indicate if the corresponding
63          *                fHits[i] element was set/filled.
64          */
65         static void UnpackTriggerRecordFlags(
66                         AliHLTUInt32_t flags, // [in]
67                         AliHLTMUONParticleSign& sign, // [out]
68                         bool hitset[4] // [out]
69                 );
70
71         /**
72          * This packs the given parameters into the bits of a word appropriate
73          * for AliHLTMUONMansoTrackStruct::fFlags.
74          * @param sign    The particle sign.
75          * @param hitset  Flags to indicate if the corresponding fHits[i] elements
76          *                was set/filled.
77          * @return  Returns the 32 bit packed word.
78          */
79         static AliHLTUInt32_t PackMansoTrackFlags(
80                         AliHLTMUONParticleSign sign, const bool hitset[4]
81                 )
82         {
83                 return PackTriggerRecordFlags(sign, hitset);
84         }
85
86         /**
87          * This unpacks the AliHLTMUONMansoTrackStruct::fFlags bits into
88          * its component fields.
89          * @param flags  The flags from an AliHLTMUONMansoTrackStruct structure.
90          * @param sign    Sets this to the particle sign.
91          * @param hitset  Sets the array elements to indicate if the corresponding
92          *                fHits[i] element was set/filled.
93          */
94         static void UnpackMansoTrackFlags(
95                         AliHLTUInt32_t flags, // [in]
96                         AliHLTMUONParticleSign& sign, // [out]
97                         bool hitset[4] // [out]
98                 )
99         {
100                 UnpackTriggerRecordFlags(flags, sign, hitset);
101         }
102         
103         /**
104          * This packs the given parameters into the bits of a word appropriate
105          * for AliHLTMUONTrackDecisionStruct::fTriggerBits.
106          * @param highPt  Has the track passed the high pt cut.
107          * @param lowPt   Has the track passed the low pt cut.
108          * @return  Returns the 32 bit packed word.
109          */
110         static AliHLTUInt32_t PackTrackDecisionBits(bool highPt, bool lowPt);
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         static void UnpackTrackDecisionBits(
121                         AliHLTUInt32_t bits, // [in]
122                         bool& highPt, // [out]
123                         bool& lowPt // [out]
124                 );
125         
126         /**
127          * This packs the given parameters into the bits of a word appropriate
128          * for AliHLTMUONPairDecisionStruct::fTriggerBits.
129          *
130          * @param highMass Has the track pair passed the high invariant mass cut.
131          * @param lowMass  Has the track pair passed the low invariant mass cut.
132          * @param unlike   Does the track pair have unlike signs.
133          * @param highPtCount The number of tracks that passed the high pt cut
134          *                    in the pair.
135          * @param lowPtCount  The number of tracks that passed the low pt cut
136          *                    in the pair.
137          * @return  Returns the 32 bit packed word.
138          *
139          * Note: Must have highPtCount + lowPtCount <= 2 and unlike == true if
140          * highMass or lowMass is true.
141          */
142         static AliHLTUInt32_t PackPairDecisionBits(
143                         bool highMass, bool lowMass, bool unlike,
144                         AliHLTUInt8_t highPtCount, AliHLTUInt8_t lowPtCount
145                 );
146         
147         /**
148          * This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
149          * its component fields.
150          * @param bits  The trigger bits from an AliHLTMUONPairDecisionStruct
151          *              structure.
152          * @param highMass Sets this to the value of the high invariant mass cut bit.
153          * @param lowMass  Sets this to the value of the low invariant mass cut bit.
154          * @param unlike   Sets this if the pair is unlike sign.
155          * @param highPtCount Sets this to the high pt count bits.
156          * @param lowPtCount  Sets this to the low pt count bits.
157          */
158         static void UnpackPairDecisionBits(
159                         AliHLTUInt32_t bits, // [in]
160                         bool& highMass, // [out]
161                         bool& lowMass, // [out]
162                         bool& unlike, // [out]
163                         AliHLTUInt8_t& highPtCount, // [out]
164                         AliHLTUInt8_t& lowPtCount // [out]
165                 );
166         
167         /**
168          * This packs the given parameters into the 32bit Pub/Sub specification
169          * word in the data block descriptor.
170          *
171          * @param ddl  The list of DDLs forming part of the readout. ddl[0]
172          *             indicates DDL number 2560, ddl[1] is for DDL 2561 and so
173          *             on up to ddl[19]. ddl[20] and ddl[21] will be for the
174          *             trigger DDLs 2816 and 2817 respectively.
175          * @return  Returns the 32 bit packed specification word.
176          */
177         static AliHLTUInt32_t PackSpecBits(
178                         const bool ddl[22]
179                 );
180         
181         /**
182          * This unpacks the AliHLTMUONPairDecisionStruct::fTriggerBits bits into
183          * its component fields.
184          * @param bits  The Pub/Sub specification word from a data block descriptor.
185          * @param ddl  The output list of DDLs forming part of the readout. ddl[0]
186          *             indicates DDL number 2560, ddl[1] is for DDL 2561 and so
187          *             on up to ddl[19]. ddl[20] and ddl[21] will be for the
188          *             trigger DDLs 2816 and 2817 respectively.
189          */
190         static void UnpackSpecBits(
191                         AliHLTUInt32_t bits, // [in]
192                         bool ddl[22] // [out]
193                 );
194
195         /**
196          * This method converts the DDL number for the muon spectrometer in the
197          * range [0..21] to the equipment ID number.
198          * @param ddlNo  The DDL number in the range [0..21].
199          * @return  Returns the equipment ID number or -1 if ddlNo was invalid.
200          */
201         static AliHLTInt32_t DDLNumberToEquipId(AliHLTInt32_t ddlNo);
202         
203         /**
204          * This method converts the equipment ID number for a muon spectrometer
205          * DDL to the DDL number in the range [0..21].
206          * @param id  The equipment ID of the DDL.
207          * @return  Returns the DDL number in the range [0..21] or -1 if the
208          *          equipment ID was invalid.
209          */
210         static AliHLTInt32_t EquipIdToDDLNumber(AliHLTInt32_t id);
211         
212         /**
213          * This method converts a 32 bit data block specification for a MUON-HLT
214          * data block into its corresponding DDL equipment ID number.
215          * It is assumed that the specification is for a data block comming from
216          * a single DDL source. If more than one DDL contributed to the data block
217          * then -1 is returned.
218          * @param spec  The 32 bit specification for a data block.
219          * @return  Returns the equipment ID corresponding to the specification
220          *          or -1 if the specification was invalid.
221          */
222         static AliHLTInt32_t SpecToEquipId(AliHLTUInt32_t spec);
223         
224         /**
225          * This method converts a equipment ID number for a DDL into its corresponding
226          * 32 bit data block specification for the MUON-HLT.
227          * @param id  The equipment ID number of the DDL.
228          * @return  Returns the 32 bit data block specification or 0x0 if the
229          *          equipment ID was invalid.
230          */
231         static AliHLTUInt32_t EquipIdToSpec(AliHLTInt32_t id);
232         
233         /**
234          * This method converts a 32 bit data block specification for a MUON-HLT
235          * data block into its corresponding DDL number in the range [0..21].
236          * It is assumed that the specification is for a data block comming from
237          * a single DDL source. If more than one DDL contributed to the data block
238          * then -1 is returned.
239          * @param spec  The 32 bit specification for a data block.
240          * @return  Returns the corresponding DDL number for the specification
241          *          or -1 if the specification was invalid.
242          */
243         static AliHLTInt32_t SpecToDDLNumber(AliHLTUInt32_t spec);
244         
245         /**
246          * This method converts a DDL number in the range [0..21] into its
247          * corresponding 32 bit data block specification for the MUON-HLT.
248          * @param ddlNo  The equipment ID number of the DDL.
249          * @return  Returns the 32 bit data block specification or 0x0 if the
250          *          DDL number was invalid (out of range).
251          */
252         static AliHLTUInt32_t DDLNumberToSpec(AliHLTInt32_t ddlNo);
253
254         /**
255          * Returns true if the given specification was for a single trigger DDL.
256          */
257         static bool IsTriggerDDL(AliHLTUInt32_t spec)
258         {
259                 AliHLTInt32_t ddl = SpecToDDLNumber(spec);
260                 return (20 <= ddl and ddl <= 21);
261         }
262
263         /**
264          * Returns true if the given specification was for a single tracker DDL.
265          */
266         static bool IsTrackerDDL(AliHLTUInt32_t spec)
267         {
268                 AliHLTInt32_t ddl = SpecToDDLNumber(spec);
269                 return (0 <= ddl and ddl <= 19);
270         }
271         
272         /**
273         * Parses the string containing the type name of a dHLT data block and
274         * returns the corresponding AliHLTMUONDataBlockType value.
275         * \param  type  The string containing the type name.
276         * \returns  The data block type or kUnknownDataBlock if the type name
277         *      is invalid.
278         */
279         static AliHLTMUONDataBlockType ParseCommandLineTypeString(const char* type);
280
281         /**
282          * These codes indicate the reason why a data block failed its
283          * validity check.
284          */
285         enum WhyNotValid
286         {
287                 kNoReason,   ///< There was no reason for failure.
288                 kHeaderContainsWrongType,  ///< The common header contains an incorrect type ID.
289                 kHeaderContainsWrongRecordWidth,  ///< The common header contains an incorrect data record width.
290                 kReservedBitsNotZero,  ///< Reserved bits have not been set to zero.
291                 kParticleSignBitsNotValid,  ///< The particle sign bits are not a valid value.
292                 kHitNotMarkedAsNil,  ///< A hit was marked as not found, but the corresponding hit structure was not set to nil.
293                 kFoundDuplicateIDs,  ///< Found duplicate identifiers, but they should all be unique.
294                 kPtValueNotValid,  ///< The pT value is not positive nor -1 indicating an invalid value.
295                 kFoundDuplicateTriggers,  ///< Found duplicate trigger decisions.
296                 kPairTrackIdsAreIdentical,  ///< The track IDs of the track pair are identical.
297                 kMassValueNotValid,  ///< The invariant mass value is not positive nor -1 indicating an invalid value.
298                 kLowPtCountInvalid,  ///< The low pT trigger count is greater than 2, which is invalid.
299                 kHighPtCountInvalid  ///< The high pT trigger count is greater than 2, which is invalid.
300         };
301         
302         /**
303          * This method converts the WhyNotValid enumeration to a string representation.
304          */
305         static const char* FailureReasonToString(WhyNotValid reason);
306         
307         /**
308          * This method returns a string containing a user readable message explaining
309          * the reason for failure described by the WhyNotValid enumeration.
310          */
311         static const char* FailureReasonToMessage(WhyNotValid reason);
312
313         /**
314          * Methods used to check if the header information corresponds to the
315          * supposed type of the data block.
316          * If the 'reason' parameter is not NULL then these methods will fill the
317          * memory pointed to by reason with a code describing why the header is
318          * not valid, if and only if a problem is found with the data.
319          * These methods will return either kHeaderContainsWrongType or
320          * kHeaderContainsWrongRecordWidth as the reason.
321          */
322         static bool HeaderOk(const AliHLTMUONTriggerRecordsBlockStruct& block, WhyNotValid* reason = NULL);
323         static bool HeaderOk(const AliHLTMUONTrigRecsDebugBlockStruct& block, WhyNotValid* reason = NULL);
324         static bool HeaderOk(const AliHLTMUONTriggerChannelsBlockStruct& block, WhyNotValid* reason = NULL);
325         static bool HeaderOk(const AliHLTMUONRecHitsBlockStruct& block, WhyNotValid* reason = NULL);
326         static bool HeaderOk(const AliHLTMUONClustersBlockStruct& block, WhyNotValid* reason = NULL);
327         static bool HeaderOk(const AliHLTMUONChannelsBlockStruct& block, WhyNotValid* reason = NULL);
328         static bool HeaderOk(const AliHLTMUONMansoTracksBlockStruct& block, WhyNotValid* reason = NULL);
329         static bool HeaderOk(const AliHLTMUONMansoCandidatesBlockStruct& block, WhyNotValid* reason = NULL);
330         static bool HeaderOk(const AliHLTMUONSinglesDecisionBlockStruct& block, WhyNotValid* reason = NULL);
331         static bool HeaderOk(const AliHLTMUONPairsDecisionBlockStruct& block, WhyNotValid* reason = NULL);
332
333         /**
334          * Methods used to check more extensively if the integrity of various
335          * types of data blocks are Ok and returns true in that case.
336          * These can be slow and should generally only be used for debugging.
337          */
338         static bool IntegrityOk(const AliHLTMUONTriggerRecordStruct& tr, WhyNotValid* reason = NULL);
339         
340         static bool IntegrityOk(
341                         const AliHLTMUONTriggerRecordsBlockStruct& block,
342                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
343                 );
344                 
345         static bool IntegrityOk(const AliHLTMUONTrigRecsDebugBlockStruct& block, WhyNotValid* reason = NULL);
346         static bool IntegrityOk(const AliHLTMUONTriggerChannelsBlockStruct& block, WhyNotValid* reason = NULL);
347         static bool IntegrityOk(const AliHLTMUONRecHitsBlockStruct& block, WhyNotValid* reason = NULL);
348         static bool IntegrityOk(const AliHLTMUONClustersBlockStruct& block, WhyNotValid* reason = NULL);
349         static bool IntegrityOk(const AliHLTMUONChannelsBlockStruct& block, WhyNotValid* reason = NULL);
350         static bool IntegrityOk(const AliHLTMUONMansoTrackStruct& track, WhyNotValid* reason = NULL);
351         
352         static bool IntegrityOk(
353                         const AliHLTMUONMansoTracksBlockStruct& block,
354                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
355                 );
356         
357         static bool IntegrityOk(
358                         const AliHLTMUONMansoCandidatesBlockStruct& block,
359                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
360                 );
361         
362         static bool IntegrityOk(const AliHLTMUONTrackDecisionStruct& decision, WhyNotValid* reason = NULL);
363         
364         static bool IntegrityOk(
365                         const AliHLTMUONSinglesDecisionBlockStruct& block,
366                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
367                 );
368         
369         static bool IntegrityOk(const AliHLTMUONPairDecisionStruct& decision, WhyNotValid* reason = NULL);
370         
371         static bool IntegrityOk(
372                         const AliHLTMUONPairsDecisionBlockStruct& block,
373                         WhyNotValid* reason = NULL, AliHLTUInt32_t* recordNum = NULL
374                 );
375
376 private:
377         // Should never have to create or destroy this object.
378         AliHLTMUONUtils();
379         ~AliHLTMUONUtils();
380 };
381
382 //_____________________________________________________________________________
383
384 inline std::ostream& operator << (std::ostream& stream, AliHLTMUONUtils::WhyNotValid reason)
385 {
386         /// Stream operator for the WhyNotValid enumeration for usage with
387         /// std::ostream classes. Allows usages such as:
388         /// AliHLTMUONUtils::WhyNotValid r; std::cout << r;
389         
390         stream << AliHLTMUONUtils::FailureReasonToString(reason);
391         return stream;
392 }
393
394 //_____________________________________________________________________________
395
396 // Since c++ is missing a finally "keyword" we define one. Its usage is identical
397 // to a try..finally statement in Java etc.. however, since it is officialy a macro
398 // one must use the ( ) brackets instead of { }
399 // If the compiler supports __finally use it otherwise make our own.
400 #if defined(__BORLANDC__)
401 #       define finally(str) __finally{str}
402 #else
403 #       define finally(code) \
404                 catch(...) \
405                 { \
406                         code \
407                         throw; \
408                 }; \
409                 code
410 #endif // __BORLANDC__
411
412 // Here we define the DebugTrace(message) macro for easy embedding of debug
413 // information into the dimuon HLT code. Its usage is meant to be for generating
414 // traces of the program which are only useful during full scale debugging.
415 // Log messages should use the standard HLT logging mechanisms.
416 // The output is only generated in programs compiled with the DEBUG directive
417 // defined. Here is a usage example:
418 //
419 //  // statements...
420 //  DebugTrace("some debug information.");
421 //  // statements...
422 //
423 // One can also use C++ ostream operators and manipulators like so:
424 //
425 //  // statements...
426 //  int x, y;
427 //  DebugTrace("x = " << x << " and y = 0x" << std::hex << y );
428 //  // statements...
429 //
430 #ifdef DEBUG
431 #       include <iostream>
432 #       define DebugTrace(message) {std::cout << message << std::endl;}
433 #else // DEBUG
434 #       define DebugTrace(message)
435 #endif // DEBUG
436
437
438 #endif // ALIHLTMUONUTILS_H