Line data Source code
1 : //-*- Mode: C++ -*-
2 : // @(#) $Id$
3 :
4 : #ifndef ALIHLTMODULEAGENT_H
5 : #define ALIHLTMODULEAGENT_H
6 : /* This file is property of and copyright by the ALICE HLT Project *
7 : * ALICE Experiment at CERN, All rights reserved. *
8 : * See cxx source for full Copyright notice */
9 :
10 : /** @file AliHLTModuleAgent.h
11 : @author Matthias Richter
12 : @date
13 : @brief Agent helper class for component libraries.
14 : @note The class is used in Offline (AliRoot) context
15 : */
16 :
17 : // see below for class documentation
18 : // or
19 : // refer to README to build package
20 : // or
21 : // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
22 :
23 : #include <string>
24 : #include <TObject.h>
25 : #include <TList.h>
26 : #include <TString.h>
27 : #include "AliHLTLogging.h"
28 : #include "AliHLTConfiguration.h"
29 : #include "AliHLTConfigurationHandler.h"
30 : #include "AliHLTComponentHandler.h"
31 :
32 : class AliRunLoader;
33 : class AliRawReader;
34 : class AliRawStream;
35 : class AliHLTOUTHandler;
36 : class AliHLTOUT;
37 : class AliHLTModulePreprocessor;
38 :
39 : /**
40 : * @class AliHLTModuleAgent
41 : * @brief Agent helper class for HLT sub modules, e.g. PHOS, TPC, Trigger
42 : *
43 : * This class implements the agent base class for the HLT sub modules.
44 : * The agent of a library gives information on the features of the library/
45 : * components, like the configurations to run and other component libraries
46 : * it depends on.
47 : * @note There must not be more than one agent per module/library.
48 : *
49 : * If a run loader is available, reconstruction is performed on simulated
50 : * data as part of <tt>AliSimulation</tt>, if only the raw reader is present,
51 : * on raw data as part of <tt>AliReconstruction</tt>. The configurations
52 : * can adapt to the two cases.
53 : *
54 : * All HLT component libraries are loaded on demand through the HLT steering
55 : * instance (@ref AliHLTSystem). A library can implement an agent derived
56 : * from this base class, and has to define one global object of this agent
57 : * in the code. The agent will be registered automatically, and the features
58 : * can be queried when required.
59 : *
60 : * This is usually done during running the AliRoot reconstruction (see AliRoot
61 : * documentation on <tt> AliSimulation </tt> and <tt> AliReconstruction </tt>).
62 : * The HLT implemets the @ref AliHLTSimulation and @ref
63 : * AliHLTReconstructor which hold the HLT steering object. Several flags can
64 : * be specified as options via the <tt>SetRunHLT</tt> method of
65 : * <tt>AliSimulation</tt> and the <tt>SetOption</tt> method of
66 : * <tt>AliReconstruction</tt>, including the component libraries to be loaded.
67 : *
68 : * @section alihltmoduleagent_interface Agent interface
69 : * The child can implement the following functions:
70 : * - @ref GetDetectorMask <br>
71 : * DetectorMask for which reconstruction is run.
72 : *
73 : * - @ref CreateConfigurations <br>
74 : * Create HLT configuration forming an HLT analysis chain. <br>
75 : * Reconstruction of raw data or simulated data from digits needs
76 : * usually different configurations. If a run loader is available,
77 : * reconstruction is performed on simulated data, on raw data if Run
78 : * loader is NULL and only the raw reader present.
79 : *
80 : * - @ref GetReconstructionChains <br>
81 : * Configurations run during event reconstruction. <br>
82 : * Define chains to be run during the recunstruction step,
83 : * Depending on the availability of AliRoot run loader or raw reader
84 : * <br>
85 : *
86 : * - @ref GetRequiredComponentLibraries <br>
87 : * can indicate further libraries which are required for running the
88 : * chains (e.g. if components of another library are used).
89 : *
90 : * - @ref RegisterComponents <br>
91 : * register componens, this can be used to avoid the component
92 : * registration via global objects
93 : * @see @ref alihltcomponent-handling
94 : * <br>
95 : * - @ref GetHandlerDescription <br>
96 : * the agent can announce which part of the HLTOUT data can be treated
97 : * by the library and through which method. Different types of handlers
98 : * are defined to fit the various formats of the HLTOUT data.
99 : * @see AliHLTOUTHandlerType
100 : *
101 : * - @ref GetOutputHandler <br>
102 : * Return AliHLTOUTHandler for a given data type and specification.
103 : * This is mainly intended to treat detector proprietary data.
104 : *
105 : * @section alihltmoduleagent_references References
106 : * @see @ref AliHLTReconstructor interface to the AliRoot reconstruction
107 : * @see @ref AliHLTAgentSample agent for the libAliHLTSample library
108 : *
109 : * @ingroup alihlt_system
110 : */
111 : class AliHLTModuleAgent : public TObject, public AliHLTLogging {
112 : public:
113 : /**
114 : * standard constructor. The agent is automatically registered in the
115 : * global agent manager
116 : */
117 : AliHLTModuleAgent(const char* id);
118 : /** destructor */
119 : virtual ~AliHLTModuleAgent();
120 :
121 : /**
122 : * Get module id.
123 : * The module id is a string specifying the detector, or module. The
124 : * library must follow the naming scheme \em libAliHLTModule.so, e.g.
125 : * \em libAliHLTTPC.so if the module is 'TPC'
126 : */
127 : const char* GetModuleId() const;
128 :
129 : /**
130 : * Print status info.
131 : * Short summary on registered agents. This function acts globally on the
132 : * list of agents if no specific agent is specified.
133 : */
134 : static void PrintStatus(const char* agent=NULL);
135 :
136 : /**
137 : * Get the first agent in the list
138 : * @return pointer to first agent in the list, NULL if empty
139 : */
140 : static AliHLTModuleAgent* GetFirstAgent();
141 :
142 : /**
143 : * Get the next agent in the list
144 : * @return pointer to next agent in the list, NULL if end of list
145 : */
146 : static AliHLTModuleAgent* GetNextAgent();
147 :
148 : /**
149 : * Get string of blank separated Module Ids
150 : */
151 : static string GetAgentIds();
152 :
153 : /**
154 : * Activate a component handler for this agent.
155 : * The @ref RegisterComponents method will be called in order to allow
156 : * the agent to register components. Once activated, the function can
157 : * be called repeatedly with the same handler and gently ignores the
158 : * invocation. In the current stage of development, only one handler
159 : * can be activated per agent. This is sufficient for the current
160 : * operation, but can be extended.
161 : * @param [in] pHandler the component handler instance
162 : */
163 : int ActivateComponentHandler(AliHLTComponentHandler* pHandler);
164 :
165 : /**
166 : * Return detector mask for which reconstruction is run in this module.
167 : */
168 : virtual UInt_t GetDetectorMask() const;
169 :
170 : /**
171 : * Register all configurations belonging to this module with the
172 : * AliHLTConfigurationHandler. The agent can adapt the configurations
173 : * to be registered to the current AliRoot setup by checking the
174 : * runloader and the raw reader. <br>
175 : * The presence of Run loader and raw reader determines the mode of the
176 : * HLT reconstruction. If a run loader is available, reconstruction is
177 : * performed on simulated data, a raw reader might be available in that
178 : * case also. When running embedded into AliReconstruction, the Run loader
179 : * is always NULL and the raw gives access to data. The configurations
180 : * can adapt to the two cases.
181 : *
182 : * @param [in] handler the configuration handler
183 : * @param [in] rawReader AliRoot RawReader instance
184 : * @param [in] runloader AliRoot runloader
185 : * @return neg. error code if failed
186 : */
187 : virtual int CreateConfigurations(AliHLTConfigurationHandler* handler,
188 : AliRawReader* rawReader=NULL,
189 : AliRunLoader* runloader=NULL) const;
190 :
191 : /**
192 : * Get the top configurations for event reconstruction.
193 : * A top configuration describes a processing chain. It can simply be
194 : * described by the last configuration(s) in the chain.
195 : * The agent can adapt the configurations to be registered to the current
196 : * AliRoot setup by checking the run loader and the raw reader.
197 : * @param [in] rawReader AliRoot RawReader instance
198 : * @param [in] runloader AliRoot runloader
199 : * @return string containing the top configurations separated by blanks
200 : */
201 : virtual const char* GetReconstructionChains(AliRawReader* rawReader=NULL,
202 : AliRunLoader* runloader=NULL) const;
203 :
204 : /**
205 : * Component libraries which the configurations of this agent depend on. <br>
206 : * @note This is not the right place to specify libraries which this component
207 : * library depends. Dependencies must be linked or loaded before.
208 : * @return list of component libraries as a blank-separated string.
209 : */
210 : virtual const char* GetRequiredComponentLibraries() const;
211 :
212 : /**
213 : * Register components.
214 : * This method can be used to register components for the module instead
215 : * of the 'static object approach'. Registration is done by passing a
216 : * sample object to the AliHLTComponentHandler via
217 : * - @ref AliHLTComponentHandler::RegisterComponent <br>
218 : * The sample object is owned by the agent, make sure to delete it.
219 : * - @ref AliHLTComponentHandler::AddComponent <br>
220 : * Same functionality but handler deletes the object at the end.
221 : *
222 : * @param [in] pHandler instance of the component handler
223 : */
224 : virtual int RegisterComponents(AliHLTComponentHandler* pHandler) const;
225 :
226 : /**
227 : * Define QA plugins
228 : * @return blank separated list of class names
229 : */
230 : virtual const char* GetQAPlugins() const;
231 :
232 : /**
233 : * IDs for output handlers.
234 : * The agent can provide output handlers in order to treat the output
235 : * data coming from the HLTOUT nodes.
236 : */
237 : enum AliHLTOUTHandlerType {
238 : kUnknownOutput =0,
239 :
240 : /** output is in ESD format */
241 : kEsd,
242 :
243 : /** agent provides data for a RawReader
244 : * From the data block one or more output blocks can be
245 : * created idenditcal to the ddl format. The blocks are
246 : * provided to subsequent analysis by a RawReader instance.
247 : * The data block can be processed in order to provide the
248 : * raw data, e.g. in case of lossless compression.
249 : */
250 : kRawReader,
251 :
252 : /** agent can create a raw stream
253 : * The agent directly generates a detector specific RawStream
254 : * object. This is used for pre-analyzed data which will not
255 : * be converted back to the raw format.
256 : */
257 : kRawStream,
258 :
259 : /** agent provides a chain
260 : * The data block is fed into an analysis chain, the treatment
261 : * depends on the components in the chain.
262 : */
263 : kChain,
264 :
265 : /** agent provides detector specific handler */
266 : kProprietary,
267 : kLastOutputHandler
268 : };
269 :
270 : /**
271 : * Output handler description.
272 : * \em fModule: module name specific for the handler type
273 : * - kRawReader: DDL no printed in ascii format
274 : * - kRawStream: class name of the RawStream class
275 : * - kChain: blank separated list of chains
276 : * - kProprietary: name of the handler class
277 : */
278 : class AliHLTOUTHandlerDesc {
279 : public:
280 252 : AliHLTOUTHandlerDesc() : fHType(kUnknownOutput), fDt(kAliHLTVoidDataType), fModule() {}
281 :
282 : AliHLTOUTHandlerDesc(AliHLTOUTHandlerType handlerType, AliHLTComponentDataType dt, const char* module)
283 0 : : fHType(handlerType), fDt(dt), fModule(module) {}
284 :
285 : AliHLTOUTHandlerDesc(const AliHLTOUTHandlerDesc& src)
286 0 : : fHType(src.fHType), fDt(src.fDt), fModule(src.fModule) {}
287 :
288 : AliHLTOUTHandlerDesc& operator=(const AliHLTOUTHandlerDesc& src) {
289 0 : if (this==&src) return *this;
290 0 : fHType=src.fHType; fDt=src.fDt; fModule=src.fModule; return *this;
291 0 : }
292 :
293 252 : ~AliHLTOUTHandlerDesc() {}
294 :
295 : bool operator==(const AliHLTOUTHandlerType handlerType) const {
296 0 : return fHType==handlerType;
297 : }
298 : /**
299 : * Two descriptors are equal if all members match.
300 : */
301 : bool operator==(const AliHLTOUTHandlerDesc& desc) const {
302 0 : return fDt==desc.fDt && fHType==desc.fHType && fModule==desc.fModule;
303 : }
304 :
305 0 : operator AliHLTOUTHandlerType() {return fHType;}
306 0 : operator AliHLTComponentDataType() {return fDt;}
307 :
308 : private:
309 : /** type of the handler */
310 : AliHLTOUTHandlerType fHType; //!transient
311 : /** data type treated by the handler */
312 : AliHLTComponentDataType fDt; //!transient
313 : /** class or chain name */
314 : TString fModule; //!transient
315 : };
316 :
317 : static const AliHLTOUTHandlerDesc fgkVoidHandlerDesc; //! initializer
318 :
319 : /**
320 : * Get handler description for a data block.
321 : * Depending on the data type and data specification the handler must
322 : * provide information
323 : * - if it can handle the data block, and
324 : * - details how it will handle it, mainly the type of the handler
325 : * @ref AliHLTOUTHandlerType
326 : *
327 : * @param [in] dt data type of the block
328 : * @param [in] spec specification of the block
329 : * @param [out] desc handler description
330 : * @return 1 if the agent can provide a handler, 0 if not
331 : */
332 : virtual int GetHandlerDescription(AliHLTComponentDataType dt,
333 : AliHLTUInt32_t spec,
334 : AliHLTOUTHandlerDesc& desc) const;
335 :
336 : /**
337 : * Get handler for a data block of the HLTOUT data.
338 : * The agent can also provide an overloaded @ref DeleteOutputHandler
339 : * function to implement customized clean up. It is also possible to
340 : * return the same instance of a handler for different data blocks.<br>
341 : *
342 : * The framework first collects the handlers for all data blocks, and
343 : * calls the @ref AliHLTOUTHandler::ProcessData method afterwords for
344 : * each handler.
345 : * @param [in] dt data type of the block
346 : * @param [in] spec specification of the block
347 : * @return pointer to handler
348 : */
349 : virtual AliHLTOUTHandler* GetOutputHandler(AliHLTComponentDataType dt,
350 : AliHLTUInt32_t spec);
351 :
352 : /**
353 : * Delete an HLTOUT handler.
354 : * This is the final cleanup. The framwork makes sure that the handler is
355 : * not used any further outside the agent. Even if the agent returned the
356 : * same handler several times, cleanup is invoked only once. The default
357 : * implementation just deletes the object.
358 : * @param pInstance pointer to handler
359 : */
360 : virtual int DeleteOutputHandler(AliHLTOUTHandler* pInstance);
361 :
362 : /**
363 : * Get raw stream for a data block.
364 : * @param [in] dt data type of the block
365 : * @param [in] spec specification of the block
366 : * @param [in] pData data control object
367 : * @return Rawstream object, NULL if no Rawstream available for data type/spec
368 : */
369 : // this method is likely to be moved to a specific implementation
370 : // of AliHLTOUTHandler
371 : // virtual AliRawStream* GetRawStream(AliHLTComponentDataType dt,
372 : // AliHLTUInt32_t spec,
373 : // const AliHLTOUT* pData);
374 :
375 : /**
376 : * Get the preprocessor for this component library.
377 : * Create an instance of the preprocessor for this component library.
378 : * The caller will delete it after useage.
379 : * @return pointer to AliHLTModulePreprocessor object.
380 : */
381 : virtual AliHLTModulePreprocessor* GetPreprocessor();
382 :
383 : /**
384 : * Old method kept for backward compatibility, redirected to @ref
385 : * GetReconstructionChains.
386 : */
387 : const char* GetTopConfigurations(AliRunLoader* runloader=NULL) const {
388 0 : return GetReconstructionChains(NULL,runloader);
389 : }
390 :
391 : /**
392 : * Get current component handler
393 : */
394 : AliHLTComponentHandler* GetComponentHandler() const {
395 60 : return fpComponentHandler;
396 : }
397 :
398 : protected:
399 :
400 : private:
401 : /** standard constructor prohibited */
402 : AliHLTModuleAgent();
403 : /** copy constructor prohibited */
404 : AliHLTModuleAgent(const AliHLTModuleAgent&);
405 : /** assignment operator prohibited */
406 : AliHLTModuleAgent& operator=(const AliHLTModuleAgent&);
407 :
408 : /**
409 : * Register agent in the global list.
410 : * @return neg. error code if failed
411 : */
412 : static int Register(AliHLTModuleAgent* pAgent);
413 :
414 : /**
415 : * Unregister agent in the global list.
416 : * @return neg. error code if failed
417 : */
418 : static int Unregister(AliHLTModuleAgent* pAgent);
419 :
420 : /** the list of active agents */
421 : static AliHLTModuleAgent* fgAnchor; //! transient
422 :
423 : /** next element in the list */
424 : AliHLTModuleAgent* fpNext; //! transient
425 :
426 : /** the current object link (list position) */
427 : static AliHLTModuleAgent* fgCurrent; //! transient
428 :
429 : /** number of agents */
430 : static int fgCount; //! transient
431 :
432 : /** instance of the active component handler */
433 : AliHLTComponentHandler* fpComponentHandler; //! transient
434 :
435 : /** id of the module */
436 : TString fModuleId; //! transient
437 :
438 126 : ClassDef(AliHLTModuleAgent, 3);
439 : };
440 :
441 : #endif
|