ALIROOT-5433 Transition to CDHv3 in HLT
[u/mrichter/AliRoot.git] / HLT / MUON / AliHLTMUONProcessor.h
1 #ifndef ALIHLTMUONPROCESSOR_H
2 #define ALIHLTMUONPROCESSOR_H
3 /* This file is property of and copyright by the ALICE HLT Project        *
4  * ALICE Experiment at CERN, All rights reserved.                         *
5  * See cxx source for full Copyright notice                               */
6
7 // $Id: $
8
9 ///
10 /// @file   AliHLTMUONProcessor.h
11 /// @author Artur Szostak <artursz@iafrica.com>
12 /// @date   19 May 2008
13 /// @brief  Declaration of a common processor component abstract interface for dHLT components.
14 ///
15
16 #include "AliHLTProcessor.h"
17 #include "AliHLTMUONDataBlockReader.h"
18 #include "AliHLTMUONUtils.h"
19
20 class TMap;
21 class AliMUONRecoParam;
22
23 /**
24  * @class AliHLTMUONProcessor
25  * This component class is an abstract base class for dHLT components.
26  * Some common methods useful to all dHLT specific components are implemented
27  * by this class.
28  *
29  * The following argument can be inherited by components derived from the
30  * AliHLTMUONProcessor class, as long as the protected methods provided are used
31  * properly and the argument evaluation is handled as indicated in DoInit.
32  * \li -cdbpath <i>path</i> <br>
33  *      This allows one to override the path to use for the CDB location.
34  *      <i>path</i> must be a valid CDB URI. By default the HLT system framework
35  *      sets the CDB path. <br>
36  * \li -run <i>number</i> <br>
37  *      This allows one to override the run number to use. <i>number</i> must be
38  *      a positive integer number. By default the HLT system framework sets the
39  *      run number. <br>
40  * \li -delaysetup <br>
41  *      If indicated then part of the initialisation of the component is forcefully
42  *      delayed to the first event received, i.e. the Start-of-Run event. <br>
43  * \li -dumponerror <br>
44  *      This flag will cause the component to dump the data blocks it received if
45  *      an error occurs during the processing of an event. <br>
46  * \li -dumppath <i>path</i> <br>
47  *      Allows one to specify the path in which to dump the received data blocks
48  *      if an error occurs. <br>
49  *
50  * @ingroup alihlt_muon_components
51  */
52 class AliHLTMUONProcessor : public AliHLTProcessor
53 {
54 public:
55         /// Default constructor.
56         AliHLTMUONProcessor();
57         
58         /// Default destructor.
59         virtual ~AliHLTMUONProcessor() {}
60
61 protected:
62
63         /**
64          * This method parses the common arguments for dHLT processing components
65          * and initialises the common internal state.
66          * Deriving classes can use the ArgumentAlreadyHandled method to check if
67          * the parent class has processed a particular argument. The following is
68          * an example of this:
69          *
70          * \code
71          * int DerivedClass::DoInit(int argc, const char** argv)
72          * {
73          *   int result = AliHLTMUONProcessor::DoInit(argc, argv);
74          *   if (result != 0) return result;
75          *   for (int i = 0; i < argc; i++)
76          *   {
77          *     if (ArgumentAlreadyHandled(i, argv[i])) continue;
78          *     // ... handle custom arguments here ...
79          *   }
80          * }
81          * \endcode
82          */
83         virtual int DoInit(int argc, const char** argv);
84
85         /**
86          * This method can be used by the derivind child class to check if a particular
87          * argument in argv was already processed.
88          * \note This assumes that the deriving class called the DoInit method of the
89          * parent class in its own DoInit method.
90          */
91         virtual bool ArgumentAlreadyHandled(int& i, const char* argi) const;
92         
93         /**
94          * This method returns the command line arguments that should not be parsed
95          * by this class. This method can be used by child classes that derive from
96          * AliHLTMUONProcessor, to indicate which arguments should not be handled by
97          * the AliHLTMUONProcessor::DoInit method. Default return value is false.
98          */
99         virtual bool IgnoreArgument(const char* /*arg*/) const { return false; }
100         
101         /**
102          * Returns true if the component was told to delay initialisation from
103          * CDB until the first start of run event. This gets set by the -delaysetup
104          * flag which is processed in AliHLTMUONProcessor::DoInit.
105          */
106         bool DelaySetup() const { return fDelaySetup; }
107
108         /**
109          * This method should be called when a derived component has handled a
110          * delayed setup requested on the command line with -delaysetup and indicated
111          * by the flag returned by the DelaySetup method.
112          */
113         void DoneDelayedSetup() { fDelaySetup = false; }
114         
115         /**
116          * Returns true if the component has the flag set indicating to dump raw
117          * data when an error occurs. The DumpEvent method should be used by the
118          * deriving components to actually dump data at the appropriate point.
119          * \note This facility is intended for debugging.
120          */
121         bool DumpDataOnError() const { return fDumpDataOnError; }
122
123         /**
124          * Returns the path where the dump files will be written to by the Dump*
125          * methods. Defaults to the current working directory.
126          * \note This facility is intended for debugging.
127          */
128         const char* DumpPath() const { return fDumpPath; }
129
130         /**
131          * Method to check the block structure and log appropriate error messages.
132          * If a problem is found with the data block then an appropriate HLT error
133          * message is logged and the method returns false.
134          * \param block  The lightweight block reader whose data block should be checked.
135          * \param name  A string containing a descriptive name of the data block
136          *          type. This name is used in the logged error messages.
137          * \param checkHeader  Indicates if the common data block header should be checked.
138          * \returns  true if the structure of the block looks OK and false otherwise.
139          * \note  The BlockType should be a class deriving from AliHLTMUONDataBlockReader.
140          */
141         template <class BlockType>
142         bool BlockStructureOk(
143                         const BlockType& block, const char* name,
144                         bool checkHeader = true
145                 ) const;
146         
147         /// Checks the structure of a trigger records data block.
148         bool BlockStructureOk(
149                         const AliHLTMUONTriggerRecordsBlockReader& block,
150                         bool checkHeader = true
151                 ) const
152         {
153                 return BlockStructureOk(block, "trigger records", checkHeader);
154         }
155         
156         /// Checks the structure of a trigger records debug information data block.
157         bool BlockStructureOk(
158                         const AliHLTMUONTrigRecsDebugBlockReader& block,
159                         bool checkHeader = true
160                 ) const
161         {
162                 return BlockStructureOk(block, "trigger records debug information", checkHeader);
163         }
164
165         /// Checks the structure of a reconstructed hits data block.
166         bool BlockStructureOk(
167                         const AliHLTMUONRecHitsBlockReader& block,
168                         bool checkHeader = true
169                 ) const
170         {
171                 return BlockStructureOk(block, "reconstructed hits", checkHeader);
172         }
173         
174         /// Checks the structure of a clusters data block.
175         bool BlockStructureOk(
176                         const AliHLTMUONClustersBlockReader& block,
177                         bool checkHeader = true
178                 ) const
179         {
180                 return BlockStructureOk(block, "clusters", checkHeader);
181         }
182         
183         /// Checks the structure of a ADC channels data block.
184         bool BlockStructureOk(
185                         const AliHLTMUONChannelsBlockReader& block,
186                         bool checkHeader = true
187                 ) const
188         {
189                 return BlockStructureOk(block, "channels", checkHeader);
190         }
191
192         /// Checks the structure of a Manso tracks data block.
193         bool BlockStructureOk(
194                         const AliHLTMUONMansoTracksBlockReader& block,
195                         bool checkHeader = true
196                 ) const
197         {
198                 return BlockStructureOk(block, "Manso tracks", checkHeader);
199         }
200         
201         /// Checks the structure of a Manso track candidates data block.
202         bool BlockStructureOk(
203                         const AliHLTMUONMansoCandidatesBlockReader& block,
204                         bool checkHeader = true
205                 ) const
206         {
207                 return BlockStructureOk(block, "Manso track candidates", checkHeader);
208         }
209
210         /// Checks the structure of a tracks data block.
211         bool BlockStructureOk(
212                         const AliHLTMUONTracksBlockReader& block,
213                         bool checkHeader = true
214                 ) const
215         {
216                 return BlockStructureOk(block, "tracks", checkHeader);
217         }
218
219         /// Checks the structure of a single track trigger decision data block.
220         bool BlockStructureOk(
221                         const AliHLTMUONSinglesDecisionBlockReader& block,
222                         bool checkHeader = true
223                 ) const
224         {
225                 return BlockStructureOk(block, "singles decision", checkHeader);
226         }
227
228         /// Checks the structure of a track pairs trigger decision data block.
229         bool BlockStructureOk(
230                         const AliHLTMUONPairsDecisionBlockReader& block,
231                         bool checkHeader = true
232                 ) const
233         {
234                 return BlockStructureOk(block, "pairs decision", checkHeader);
235         }
236         
237         /**
238          * Sets the CDB path and run number to read from.
239          * \param cdbPath  The CDB path to use. If set to NULL and the path has
240          *      not been set in the CDB manager then the default path
241          *      "local://$ALICE_ROOT/OCDB" is used if the 'useDefault' flag is also true.
242          * \param run  The run number to use. If set to -1 and the run number has
243          *      not been set in the CDB manager then a value of zero is used if
244          *      the 'useDefault' flag is also true.
245          * \param useDefault  If set to true then a default CDB path and/or run number
246          *      is used if they have not been set and 'cdbPath' == NULL or
247          *      'run' == -1. (false by default).
248          * \return Zero if the object could be loaded. Otherwise an error code,
249          *      compatible with the HLT framework, is returned.
250          */
251         int SetCDBPathAndRunNo(
252                         const char* cdbPath, Int_t run, bool useDefault = false
253                 ) const;
254         
255         /**
256          * Fetches the DDL and detector element store objects for MUON mapping.
257          * \return Zero if the objects could be loaded. Otherwise an error code,
258          *      which is compatible with the HLT framework, is returned.
259          * \note AliMpDDLStore::Instance() and AliMpDEStore::Instance() must be used
260          *      to fetch the objects after this method returns a code equal to zero.
261          */
262         int FetchMappingStores() const;
263         
264         /**
265          * Fetches a TMap object from the CDB.
266          * \param [in] pathToEntry  The relative path to the entry in the CDB to fetch.
267          * \param [out] map  This will be filled with the TMap object found if
268          *      a successful status code is returned. Otherwise it will be unchanged.
269          * \return Zero if the object could be found. Otherwise an error code,
270          *      which is compatible with the HLT framework, is returned.
271          */
272         int FetchTMapFromCDB(const char* pathToEntry, TMap*& map) const;
273         
274         /**
275          * Tries to find the string value associated with a certain parameter in a TMap.
276          * \param [in] map  The TMap object to search in.
277          * \param [in] paramName  The name of the parameter to search for.
278          * \param [out] value  Will be filled with the object found.
279          * \param [in] prettyName  Should be the name of the parameter which will
280          *      be used when printing error messages. If this is set to NULL then
281          *      the paramName will be used instead (default is NULL).
282          * \return Zero if the object could be found. Otherwise an error code,
283          *      which is compatible with the HLT framework, is returned.
284          */
285         int GetValueFromTMap(
286                         TMap* map, const char* paramName, TString& value,
287                         const char* pathToEntry = NULL, const char* prettyName = NULL
288                 ) const;
289         
290         /**
291          * Tries to find a certain parameter in the TMap object and convert it to
292          * an integer value.
293          * \param [in] map  The TMap object to search in.
294          * \param [in] paramName  The name of the parameter to search for.
295          * \param [out] value  Will be filled with the integer value for the parameter,
296          *       if it was found and it was an integer value.
297          * \param [in] prettyName  Should be the name of the parameter which will
298          *      be used when printing error messages. If this is set to NULL then
299          *      the paramName will be used instead (default is NULL).
300          * \return Zero if the object could be found and is valid. Otherwise an
301          *       error code, which is compatible with the HLT framework, is returned.
302          */
303         int GetIntFromTMap(
304                         TMap* map, const char* paramName, Int_t& value,
305                         const char* pathToEntry = NULL, const char* prettyName = NULL
306                 ) const;
307         
308         /**
309          * Tries to find a certain parameter in the TMap object and convert it to
310          * a positive integer value.
311          * \param [in] map  The TMap object to search in.
312          * \param [in] paramName  The name of the parameter to search for.
313          * \param [out] value  Will be filled with the integer value for the parameter,
314          *       if it was found and it was a positive integer value.
315          * \param [in] prettyName  Should be the name of the parameter which will
316          *      be used when printing error messages. If this is set to NULL then
317          *      the paramName will be used instead (default is NULL).
318          * \return Zero if the object could be found and is valid. Otherwise an
319          *       error code, which is compatible with the HLT framework, is returned.
320          */
321         int GetPositiveIntFromTMap(
322                         TMap* map, const char* paramName, Int_t& value,
323                         const char* pathToEntry = NULL, const char* prettyName = NULL
324                 ) const;
325         
326         /**
327          * Tries to find a certain parameter in the TMap object and convert it to
328          * an floating point value.
329          * \param [in] map  The TMap object to search in.
330          * \param [in] paramName  The name of the parameter to search for.
331          * \param [out] value  Will be filled with the floating point value for the
332          *       parameter, if it was found and it was a floating point value.
333          * \param [in] prettyName  Should be the name of the parameter which will
334          *      be used when printing error messages. If this is set to NULL then
335          *      the paramName will be used instead (default is NULL).
336          * \return Zero if the object could be found and is valid. Otherwise an
337          *       error code, which is compatible with the HLT framework, is returned.
338          */
339         int GetFloatFromTMap(
340                         TMap* map, const char* paramName, Double_t& value,
341                         const char* pathToEntry = NULL, const char* prettyName = NULL
342                 ) const;
343         
344         /**
345          * Tries to find a certain parameter in the TMap object and convert it to
346          * an positive floating point value.
347          * \param [in] map  The TMap object to search in.
348          * \param [in] paramName  The name of the parameter to search for.
349          * \param [out] value  Will be filled with the floating point value for the
350          *       parameter, if it was found and it was a positive floating point value.
351          * \param [in] prettyName  Should be the name of the parameter which will
352          *      be used when printing error messages. If this is set to NULL then
353          *      the paramName will be used instead (default is NULL).
354          * \return Zero if the object could be found and is valid. Otherwise an
355          *       error code, which is compatible with the HLT framework, is returned.
356          */
357         int GetPositiveFloatFromTMap(
358                         TMap* map, const char* paramName, Double_t& value,
359                         const char* pathToEntry = NULL, const char* prettyName = NULL
360                 ) const;
361         
362         /**
363          * Loads the appropriate field integral from the CDB based on the currently
364          * loaded global magnetic field in TGeoGlobalMagField. If the global field is
365          * not loaded then we try load the GRP entry to figure out the correct integral.
366          * \param [out] bfieldintegral  Will be filled with the dipole magnetic field
367          *       integral value to use.
368          * \return Zero if the field integral could be found and is valid. Otherwise an
369          *       error code is returned, which is compatible with the HLT framework.
370          */
371         int FetchFieldIntegral(Double_t& bfieldintegral) const;
372         
373         /**
374          * Fetches the reconstruction parameters object from the CDB for MUON.
375          * \param [out]  params  This will be filled with the reconstruction
376          *      parameters object found if a successful status code is returned.
377          *      Otherwise it will be unchanged.
378          * \return Zero if the object could be found. Otherwise an error code,
379          *      which is compatible with the HLT framework, is returned.
380          */
381         int LoadRecoParamsFromCDB(AliMUONRecoParam*& params) const;
382
383         /**
384          * Dumps the data contained in a buffer to file as is.
385          */
386         void DumpBuffer(
387                         const void* buffer, AliHLTUInt32_t size,
388                         const char* filename
389                 ) const;
390
391         /**
392          * Dumps the data block to file.
393          */
394         void DumpBlock(
395                         const AliHLTComponentBlockData* block,
396                         const char* fileNamePrefix
397                 ) const;
398         
399         /**
400          * Dumps the event information to files in the dump path given by the
401          * method DumpPath, which can be set by the command line argument -dumppath.
402          */
403         void DumpEvent(
404                         const AliHLTComponentEventData& evtData,
405                         const AliHLTComponentBlockData* blocks,
406                         AliHLTComponentTriggerData& trigData,
407                         AliHLTUInt8_t* outputPtr,
408                         AliHLTUInt32_t& size,
409                         AliHLTComponentBlockDataList& outputBlocks
410                 ) const;
411         
412         /**
413          * Dumps the event information to files in the dump path given by the
414          * method DumpPath, which can be set by the command line argument -dumppath.
415          */
416         void DumpEvent(
417                         const AliHLTComponentEventData& evtData,
418                         AliHLTComponentTriggerData& trigData
419                 ) const;
420
421 private:
422
423         // Do not allow copying of this class.
424         /// Not implemented.
425         AliHLTMUONProcessor(const AliHLTMUONProcessor& /*obj*/);
426         /// Not implemented.
427         AliHLTMUONProcessor& operator = (const AliHLTMUONProcessor& /*obj*/);
428
429         bool fWarnForUnexpecedBlock;  ///< Flag indicating if we should log a warning if we got a block of an unexpected type.
430         bool fDelaySetup;  ///< Indicates if the component should delay loading and initialising from the CDB to the start of run event.
431         bool fDumpDataOnError; ///< Flag indicating if we should dump data when an error occurs in the reconstruction class.
432         const char* fDumpPath; ///< This is the path prefix to use to dump event data too when an error occurs.
433         
434         ClassDef(AliHLTMUONProcessor, 0)  // Abstract base class for dHLT specific components.
435 };
436
437 //______________________________________________________________________________
438
439 template <class BlockType>
440 bool AliHLTMUONProcessor::BlockStructureOk(
441                 const BlockType& block, const char* name, bool checkHeader
442         ) const
443 {
444         /// Performs basic checks to see if the input data block structure is OK,
445         /// that it is not corrupt, too short etc...
446         
447         if (not block.BufferSizeOk())
448         {
449                 size_t headerSize = sizeof(typename BlockType::HeaderType);
450                 if (block.BufferSize() < headerSize)
451                 {
452                         HLTError("Received a %s data block with a size of %d bytes,"
453                                 " which is smaller than the minimum valid header size of %d bytes."
454                                 " The block must be corrupt.",
455                                 name, block.BufferSize(), headerSize
456                         );
457                         return false;
458                 }
459                 
460                 size_t expectedWidth = sizeof(typename BlockType::ElementType);
461                 if (block.CommonBlockHeader().fRecordWidth != expectedWidth)
462                 {
463                         HLTError("Received a %s data block with a record"
464                                 " width of %d bytes, but the expected value is %d bytes."
465                                 " The block might be corrupt.",
466                                 name,
467                                 block.CommonBlockHeader().fRecordWidth,
468                                 expectedWidth
469                         );
470                         return false;
471                 }
472                 
473                 HLTError("Received a %s data block with a size of %d bytes,"
474                         " but the block header claims the block should be %d bytes."
475                         " The block might be corrupt.",
476                         name, block.BufferSize(), block.BytesUsed()
477                 );
478                 return false;
479         }
480         
481         if (checkHeader)
482         {
483                 AliHLTMUONUtils::WhyNotValid reason;
484                 if (not AliHLTMUONUtils::HeaderOk(block.BlockHeader(), &reason))
485                 {
486                         HLTError("Received a %s data block which might be corrupt. %s",
487                                 name, AliHLTMUONUtils::FailureReasonToMessage(reason)
488                         );
489                         return false;
490                 }
491         }
492         
493         return true;
494 }
495
496 #endif // ALIHLTMUONPROCESSOR_H