]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTComponent.cxx
excluding D0Trigger from the inputs of the HLTGlobalTrigger because of a rare segfaul...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponent.cxx
CommitLineData
f23a6e1a 1// $Id$
2
3dd8541e 3//**************************************************************************
4//* This file is property of and copyright by the ALICE HLT Project *
5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8//* Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9//* for The ALICE HLT Project. *
10//* *
11//* Permission to use, copy, modify and distribute this software and its *
12//* documentation strictly for non-commercial purposes is hereby granted *
13//* without fee, provided that the above copyright notice appears in all *
14//* copies and that both the copyright notice and this permission notice *
15//* appear in the supporting documentation. The authors make no claims *
16//* about the suitability of this software for any purpose. It is *
17//* provided "as is" without express or implied warranty. *
18//**************************************************************************
f23a6e1a 19
0007ed52 20// @file AliHLTComponent.cxx
21// @author Matthias Richter, Timm Steinbeck
22// @date
23// @brief Base class implementation for HLT components. */
24// @note The class is both used in Online (PubSub) and Offline (AliRoot)
25// context
26
f23a6e1a 27
0c0c9d99 28#if __GNUC__>= 3
f23a6e1a 29using namespace std;
30#endif
31
66043029 32//#include "AliHLTStdIncludes.h"
f23a6e1a 33#include "AliHLTComponent.h"
34#include "AliHLTComponentHandler.h"
a655eae3 35#include "AliHLTMessage.h"
adb91bc3 36#include "AliHLTCTPData.h"
89413559 37#include "AliRawDataHeader.h"
70ed7d01 38#include "TString.h"
ed504011 39#include "TMath.h"
a655eae3 40#include "TObjArray.h"
79c114b5 41#include "TObjectTable.h"
a655eae3 42#include "TClass.h"
90ebac25 43#include "TStopwatch.h"
cf9cf07e 44#include "TFormula.h"
cc095616 45#include "TUUID.h"
46#include "TMD5.h"
47#include "TRandom3.h"
79c114b5 48#include "AliHLTMemoryFile.h"
579d9eb7 49#include "AliHLTMisc.h"
ec25e4ca 50#include <cassert>
bee8f777 51#include <ctime>
0da432fa 52#include <stdint.h>
f23a6e1a 53
9ace7282 54/**
55 * default compression level for ROOT objects
56 */
57#define ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION 5
2e3fd14f 58#define ALIHLTCOMPONENT_STATTIME_SCALER 1000000
9ace7282 59
b22e91eb 60/** ROOT macro for the implementation of ROOT specific class methods */
90ebac25 61ClassImp(AliHLTComponent);
62
63/** stopwatch macro using the stopwatch guard */
64#define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
65//#define ALIHLTCOMPONENT_STOPWATCH(type)
66
67/** stopwatch macro for operations of the base class */
68#define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
69/** stopwatch macro for operations of the detector algorithm (DA) */
70#define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
f23a6e1a 71
f23a6e1a 72AliHLTComponent::AliHLTComponent()
85869391 73 :
53feaef5 74 fEnvironment(),
3cde846d 75 fCurrentEvent(0),
a655eae3 76 fEventCount(-1),
77 fFailedEvents(0),
78 fCurrentEventData(),
79 fpInputBlocks(NULL),
80 fCurrentInputBlock(-1),
81 fSearchDataType(kAliHLTVoidDataType),
82 fClassName(),
83 fpInputObjects(NULL),
84 fpOutputBuffer(NULL),
85 fOutputBufferSize(0),
86 fOutputBufferFilled(0),
90ebac25 87 fOutputBlocks(),
79c114b5 88 fpStopwatches(new TObjArray(kSWTypeCount)),
559631d5 89 fMemFiles(),
90 fpRunDesc(NULL),
82c58a87 91 fCDBSetRunNoFunc(false),
a0aeb701 92 fChainId(),
48abe484 93 fChainIdCrc(0),
a0aeb701 94 fpBenchmark(NULL),
78d29060 95 fFlags(0),
abb52c8f 96 fEventType(gkAliEventTypeUnknown),
eafbc306 97 fComponentArgs(),
98 fEventDoneData(NULL),
9ace7282 99 fEventDoneDataSize(0),
100 fCompressionLevel(ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION)
b3f4766b 101 , fLastObjectSize(0)
adb91bc3 102 , fpCTPData(NULL)
9d4d4b02 103 , fPushbackPeriod(0)
104 , fLastPushBackTime(-1)
70ed7d01 105{
106 // see header file for class documentation
107 // or
108 // refer to README to build package
109 // or
110 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
a3c9b745 111 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
70ed7d01 112 if (fgpComponentHandler)
113 fgpComponentHandler->ScheduleRegister(this);
7c781d33 114 //SetLocalLoggingLevel(kHLTLogDefault);
70ed7d01 115}
116
f23a6e1a 117AliHLTComponent::~AliHLTComponent()
118{
70ed7d01 119 // see header file for function documentation
a0aeb701 120 if (fpBenchmark) delete fpBenchmark;
121 fpBenchmark=NULL;
122
8451168b 123 CleanupInputObjects();
4498d7d1 124 if (fpStopwatches!=NULL) delete fpStopwatches;
125 fpStopwatches=NULL;
2be3f004 126 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 127 while (element!=fMemFiles.end()) {
128 if (*element) {
129 if ((*element)->IsClosed()==0) {
130 HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
131 // close but do not flush as we dont know whether the buffer is still valid
29312178 132 (*element)->CloseMemoryFile(0);
79c114b5 133 }
134 delete *element;
135 *element=NULL;
136 }
137 element++;
138 }
45c0a780 139 if (fpRunDesc) {
140 delete fpRunDesc;
141 fpRunDesc=NULL;
142 }
eafbc306 143 if (fEventDoneData)
144 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
cf9cf07e 145 fEventDoneData=NULL;
146
adb91bc3 147 if (fpCTPData) {
148 delete fpCTPData;
cf9cf07e 149 }
adb91bc3 150 fpCTPData=NULL;
f23a6e1a 151}
152
70ed7d01 153AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
b22e91eb 154
85869391 155int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite)
156{
70ed7d01 157 // see header file for function documentation
85869391 158 int iResult=0;
70ed7d01 159 if (fgpComponentHandler==NULL || bOverwrite!=0)
160 fgpComponentHandler=pCH;
85869391 161 else
162 iResult=-EPERM;
163 return iResult;
164}
165
70ed7d01 166int AliHLTComponent::UnsetGlobalComponentHandler()
167{
168 // see header file for function documentation
85869391 169 return SetGlobalComponentHandler(NULL,1);
170}
171
c528fdc6 172int AliHLTComponent::SetComponentEnvironment(const AliHLTAnalysisEnvironment* comenv, void* environParam)
f23a6e1a 173{
70ed7d01 174 // see header file for function documentation
66108417 175 HLTLogKeyword(fChainId.c_str());
f23a6e1a 176 int iResult=0;
f7561f8d 177 if (comenv) {
a3c9b745 178 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
179 memcpy(&fEnvironment, comenv, comenv->fStructSize<sizeof(AliHLTAnalysisEnvironment)?comenv->fStructSize:sizeof(AliHLTAnalysisEnvironment));
180 fEnvironment.fStructSize=sizeof(AliHLTAnalysisEnvironment);
70ed7d01 181 fEnvironment.fParam=environParam;
f23a6e1a 182 }
c528fdc6 183 return iResult;
184}
185
186int AliHLTComponent::Init(const AliHLTAnalysisEnvironment* comenv, void* environParam, int argc, const char** argv )
187{
188 // see header file for function documentation
189 HLTLogKeyword(fChainId.c_str());
190 int iResult=0;
191 if (comenv) {
192 SetComponentEnvironment(comenv, environParam);
193 }
9d4d4b02 194 fPushbackPeriod=0;
195 fLastPushBackTime=-1;
196
abb52c8f 197 fComponentArgs="";
8451168b 198 const char** pArguments=NULL;
199 int iNofChildArgs=0;
200 TString argument="";
201 int bMissingParam=0;
202 if (argc>0) {
203 pArguments=new const char*[argc];
204 if (pArguments) {
205 for (int i=0; i<argc && iResult>=0; i++) {
abb52c8f 206 if (fComponentArgs.size()>0) fComponentArgs+=" ";
207 fComponentArgs+=argv[i];
8451168b 208 argument=argv[i];
209 if (argument.IsNull()) continue;
210
211 // benchmark
66108417 212 if (argument.CompareTo("-benchmark")==0) {
8451168b 213
66108417 214 // -loglevel=
215 } else if (argument.BeginsWith("-loglevel=")) {
216 TString parameter=argument.ReplaceAll("-loglevel=", "");
8451168b 217 parameter.Remove(TString::kLeading, ' '); // remove all blanks
218 if (parameter.BeginsWith("0x") &&
219 parameter.Replace(0,2,"",0).IsHex()) {
bd6cac58 220 unsigned int loglevel=kHLTLogNone;
221 sscanf(parameter.Data(),"%x", &loglevel);
222 SetLocalLoggingLevel((AliHLTComponentLogSeverity)loglevel);
8451168b 223 } else {
224 HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
225 iResult=-EINVAL;
226 }
9ace7282 227 // -object-compression=
228 } else if (argument.BeginsWith("-object-compression=")) {
229 argument.ReplaceAll("-object-compression=", "");
230 if (argument.IsDigit()) {
231 fCompressionLevel=argument.Atoi();
232 if (fCompressionLevel<0 || fCompressionLevel>9) {
233 HLTWarning("invalid compression level %d, setting to default %d", fCompressionLevel, ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION);
234 fCompressionLevel=ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION;
235 }
236 } else {
237 HLTError("wrong parameter for argument -object-compression, number expected");
238 }
9d4d4b02 239 // -pushback-period=
240 } else if (argument.BeginsWith("-pushback-period=")) {
241 argument.ReplaceAll("-pushback-period=", "");
242 if (argument.IsDigit()) {
243 fPushbackPeriod=argument.Atoi();
244 } else {
245 HLTError("wrong parameter for argument -pushback-period, number expected");
246 }
78d29060 247 // -disable-component-stat
248 } else if (argument.CompareTo("-disable-component-stat")==0) {
249 fFlags|=kDisableComponentStat;
8451168b 250 } else {
251 pArguments[iNofChildArgs++]=argv[i];
252 }
253 }
254 } else {
255 iResult=-ENOMEM;
256 }
257 }
258 if (bMissingParam) {
259 HLTError("missing parameter for argument %s", argument.Data());
260 iResult=-EINVAL;
261 }
5ef2a37b 262 if (iResult>=0) {
263 iResult=CheckOCDBEntries();
264 }
8451168b 265 if (iResult>=0) {
266 iResult=DoInit(iNofChildArgs, pArguments);
267 }
a0aeb701 268 if (iResult>=0) {
269 fEventCount=0;
270
271 // find out if the component wants to get the steering events
272 // explicitly
273 AliHLTComponentDataTypeList inputDt;
274 GetInputDataTypes(inputDt);
78d29060 275 bool bRequireSteeringBlocks=false;
a0aeb701 276 for (AliHLTComponentDataTypeList::iterator dt=inputDt.begin();
78d29060 277 dt!=inputDt.end() && !bRequireSteeringBlocks;
a0aeb701 278 dt++) {
78d29060 279 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeSOR);
280 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeRunType);
281 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeEOR);
282 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeDDL);
283 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeComponentStatistics);
a0aeb701 284 }
78d29060 285 if (bRequireSteeringBlocks) fFlags|=kRequireSteeringBlocks;
a0aeb701 286 }
8451168b 287 if (pArguments) delete [] pArguments;
a0aeb701 288
78d29060 289#if defined(HLT_COMPONENT_STATISTICS)
a0aeb701 290 // benchmarking stopwatch for the component statistics
291 fpBenchmark=new TStopwatch;
78d29060 292#endif // HLT_COMPONENT_STATISTICS
a0aeb701 293
f23a6e1a 294 return iResult;
295}
296
297int AliHLTComponent::Deinit()
298{
70ed7d01 299 // see header file for function documentation
66108417 300 HLTLogKeyword(fChainId.c_str());
f23a6e1a 301 int iResult=0;
302 iResult=DoDeinit();
559631d5 303 if (fpRunDesc) {
cf9cf07e 304 // TODO: the warning should be kept, but the condition is wrong since the
305 // AliHLTRunDesc is set before the SOR event in the SetRunDescription
306 // method. A couple of state flags should be defined but that is a bit more
307 // work to do. For the moment disable the warning (2009-07-01)
bee8f777 308 // 2009-09-08: now, the info is not cleared in the ProcessEvent, because it
309 // might be needed by components during the event processing.
cf9cf07e 310 //HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
559631d5 311 AliHLTRunDesc* pRunDesc=fpRunDesc;
312 fpRunDesc=NULL;
313 delete pRunDesc;
314 }
adb91bc3 315 if (fpCTPData) {
316 delete fpCTPData;
cf9cf07e 317 }
adb91bc3 318 fpCTPData=NULL;
cf9cf07e 319
579d9eb7 320 fEventCount=0;
78d29060 321 fFlags=0;
f23a6e1a 322 return iResult;
323}
fa2e9b7c 324
82c58a87 325int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
53feaef5 326{
82c58a87 327 // see header file for function documentation
579d9eb7 328 int iResult=0;
c528fdc6 329 HLTInfo("Using CDB: %s", cdbPath);
703bcca6 330 if (pHandler) {
82c58a87 331 // I have to think about separating the library handling from the
c528fdc6 332 // component handler. Requiring the component handler here is not
82c58a87 333 // the cleanest solution.
c528fdc6 334 // We presume the library already to be loaded, which is the case
335 // because it is loaded in the initialization of the logging functionality
336 //
579d9eb7 337 // find the symbol
82c58a87 338 AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
579d9eb7 339 if (pFunc) {
703bcca6 340 TString path;
341 if (cdbPath && cdbPath[0]!=0) {
342 path=cdbPath;
343 // very temporary fix, have to check for other formats
344 if (!path.BeginsWith("local://")) {
345 path="local://";
346 path+=cdbPath;
347 }
8f30c1ea 348 }
349 if ((iResult=(*pFunc)(path.Data()))>=0) {
82c58a87 350 if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
351 Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
352 "can not find function to set CDB run no");
353 }
354 }
579d9eb7 355 } else {
356 Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
357 "can not find initialization function");
358 iResult=-ENOSYS;
53feaef5 359 }
82c58a87 360 } else {
361 iResult=-EINVAL;
362 }
579d9eb7 363 return iResult;
364}
365
366int AliHLTComponent::SetCDBRunNo(int runNo)
367{
82c58a87 368 // see header file for function documentation
369 if (!fCDBSetRunNoFunc) return 0;
370 return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
579d9eb7 371}
372
45c0a780 373int AliHLTComponent::SetRunDescription(const AliHLTRunDesc* desc, const char* /*runType*/)
374{
375 // see header file for function documentation
376 if (!desc) return -EINVAL;
377 if (desc->fStructSize!=sizeof(AliHLTRunDesc)) {
378 HLTError("invalid size of RunDesc struct (%ul)", desc->fStructSize);
379 return -EINVAL;
380 }
381
382 if (!fpRunDesc) {
383 fpRunDesc=new AliHLTRunDesc;
384 if (!fpRunDesc) return -ENOMEM;
385 *fpRunDesc=kAliHLTVoidRunDesc;
386 }
387
388 if (fpRunDesc->fRunNo!=kAliHLTVoidRunNo && fpRunDesc->fRunNo!=desc->fRunNo) {
389 HLTWarning("Run description has already been set");
390 }
391 *fpRunDesc=*desc;
392 SetCDBRunNo(fpRunDesc->fRunNo);
393 // TODO: we have to decide about the runType
394 return 0;
395}
396
9a0ef890 397int AliHLTComponent::SetComponentDescription(const char* desc)
398{
48abe484 399 // see header file for function documentation
9a0ef890 400 int iResult=0;
401 if (!desc) return 0;
402
403 TString descriptor=desc;
404 TObjArray* pTokens=descriptor.Tokenize(" ");
405 if (pTokens) {
77fd699f 406 for (int i=0; i<pTokens->GetEntriesFast() && iResult>=0; i++) {
704972af 407 TString argument=pTokens->At(i++)->GetName();
9a0ef890 408 if (!argument || argument.IsNull()) continue;
409
a3c9b745 410 // chainid
411 if (argument.BeginsWith("chainid")) {
412 argument.ReplaceAll("chainid", "");
9a0ef890 413 if (argument.BeginsWith("=")) {
414 fChainId=argument.Replace(0,1,"");
48abe484 415 fChainIdCrc=CalculateChecksum((const AliHLTUInt8_t*)fChainId.c_str(), fChainId.length());
416 HLTDebug("setting component description: chain id %s crc 0x%8x", fChainId.c_str(), fChainIdCrc);
9a0ef890 417 } else {
418 fChainId="";
419 }
420 } else {
48abe484 421 HLTWarning("unknown component description %s", argument.Data());
9a0ef890 422 }
423 }
b09d01b5 424 delete pTokens;
9a0ef890 425 }
426
427 return iResult;
428}
429
02bc7a5f 430int AliHLTComponent::ConfigureFromArgumentString(int argc, const char** argv)
431{
704972af 432 // Configure from an array of argument strings
433 // Function supports individual arguments in the argv array and arguments
434 // separated by blanks.
435 //
436 // Each argv entry can contain blanks, quotes and newlines. Newlines are interpreted
437 // as blanks. Enclosing quotes deactivate blank as delimiter.
438 // The separated arguments are stored in an array of strings, and the pointers to
439 // those strings in an array of pointers. The latter is used in the custom argument
440 // scan of the component.
441
02bc7a5f 442 int iResult=0;
704972af 443 vector<string> stringarray; // array of argument copies
444 // array of pointers to the argument copies
445 // note: not necessarily in sync with the entries in stringarray
446 // can contain any pointer to valid arguments in arbitrary sequence
447 vector<const char*> ptrarray;
448
02bc7a5f 449 TString argument="";
450 int i=0;
451 for (i=0; i<argc && iResult>=0; i++) {
d9b2cd1d 452 argument=argv[i];
ba91c7bd 453 if (argument.IsWhitespace()) continue;
454
58f0fd47 455 // special handling for single component arguments ending with
704972af 456 // a sequence of blanks. All characters until the first occurence
457 // of a blank are removed. If the remainder contains only whitespaces
458 // the argument is a single argument, just having whitespaces at the end.
58f0fd47 459 argument.Remove(0, argument.First(' '));
460 if (argument.IsWhitespace()) {
704972af 461 ptrarray.push_back(argv[i]);
58f0fd47 462 continue;
463 }
464
704972af 465 // outer loop checks for enclosing quotes
466 // extra blank to insert blank token before leading quotes, then
467 // quoted arguments are always the even ones
58f0fd47 468 argument=" ";
469 argument+=argv[i];
470 // insert blank in consecutive quotes to correctly tokenize
471 argument.ReplaceAll("''", "' '");
472 // replace newlines by blanks
473 argument.ReplaceAll("\n", " ");
02bc7a5f 474 if (argument.IsNull()) continue;
58f0fd47 475 TObjArray* pTokensQuote=argument.Tokenize("'");
476 if (pTokensQuote) {
477 if (pTokensQuote->GetEntriesFast()>0) {
478 for (int k=0; k<pTokensQuote->GetEntriesFast(); k++) {
704972af 479 argument=pTokensQuote->At(k)->GetName();
58f0fd47 480 if (argument.IsWhitespace()) continue;
481 if (k%2) {
482 // every second entry is enclosed by quotes and thus
483 // one single argument
704972af 484 stringarray.push_back(argument.Data());
485 ptrarray.push_back(stringarray.back().c_str());
58f0fd47 486 } else {
02bc7a5f 487 TObjArray* pTokens=argument.Tokenize(" ");
488 if (pTokens) {
44869670 489 if (pTokens->GetEntriesFast()>0) {
02bc7a5f 490 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
704972af 491 TString data=pTokens->At(n)->GetName();
492 if (!data.IsNull() && !data.IsWhitespace()) {
493 stringarray.push_back(data.Data());
494 ptrarray.push_back(stringarray.back().c_str());
44869670 495 }
02bc7a5f 496 }
02bc7a5f 497 }
498 delete pTokens;
58f0fd47 499 }
500 }
501 }
58f0fd47 502 }
503 delete pTokensQuote;
02bc7a5f 504 }
505 }
506
704972af 507 for (i=0; (unsigned)i<ptrarray.size() && iResult>=0;) {
508 int result=ScanConfigurationArgument(ptrarray.size()-i, &ptrarray[i]);
02bc7a5f 509 if (result==0) {
704972af 510 HLTWarning("unknown component argument %s", ptrarray[i]);
02bc7a5f 511 i++;
512 } else if (result>0) {
513 i+=result;
514 } else {
515 iResult=result;
516 if (iResult==-EINVAL) {
704972af 517 HLTError("unknown argument %s", ptrarray[i]);
02bc7a5f 518 } else if (iResult==-EPROTO) {
704972af 519 HLTError("missing/wrong parameter for argument %s (%s)", ptrarray[i], (ptrarray.size()>(unsigned)i+1)?ptrarray[i+1]:"missing");
02bc7a5f 520 } else {
704972af 521 HLTError("scan of argument %s failed (%d)", ptrarray[i], iResult);
02bc7a5f 522 }
523 }
524 }
525
526 return iResult;
527}
528
f651054f 529int AliHLTComponent::ConfigureFromCDBTObjString(const char* entries, const char* key)
02bc7a5f 530{
f651054f 531 // load a list of OCDB objects and configure from the objects
532 // can either be a TObjString or a TMap with a TObjString:TObjString key-value pair
02bc7a5f 533 int iResult=0;
534 TString arguments;
535 TString confEntries=entries;
536 TObjArray* pTokens=confEntries.Tokenize(" ");
537 if (pTokens) {
538 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
704972af 539 const char* path=pTokens->At(n)->GetName();
02bc7a5f 540 const char* chainId=GetChainId();
f651054f 541 HLTInfo("configure from entry \"%s\"%s%s, chain id %s", path, key?" key ":"",key?key:"", (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
542 TObject* pOCDBObject = LoadAndExtractOCDBObject(path, key);
02bc7a5f 543 if (pOCDBObject) {
544 TObjString* pString=dynamic_cast<TObjString*>(pOCDBObject);
f651054f 545 if (!pString) {
546 TMap* pMap=dynamic_cast<TMap*>(pOCDBObject);
547 if (pMap) {
548 // this is the case where no key has been specified and the OCDB
549 // object is a TMap, search for the default key
550 TObject* pObject=pMap->GetValue("default");
551 if (pObject && (pString=dynamic_cast<TObjString*>(pObject))!=NULL) {
552 HLTInfo("using default key of TMap of configuration object \"%s\"", path);
553 } else {
554 HLTError("no default key available in TMap of configuration object \"%s\"", path);
555 iResult=-ENOENT;
556 break;
557 }
558 }
559 }
560
02bc7a5f 561 if (pString) {
562 HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
563 arguments+=pString->GetString().Data();
564 arguments+=" ";
565 } else {
f651054f 566 HLTError("configuration object \"%s\"%s%s has wrong type, required TObjString", path, key?" key ":"",key?key:"");
02bc7a5f 567 iResult=-EINVAL;
568 }
569 } else {
570 HLTError("can not fetch object \"%s\" from OCDB", path);
571 iResult=-ENOENT;
572 }
573 }
574 delete pTokens;
575 }
576 if (iResult>=0 && !arguments.IsNull()) {
577 const char* array=arguments.Data();
578 iResult=ConfigureFromArgumentString(1, &array);
579 }
580 return iResult;
581}
582
f651054f 583TObject* AliHLTComponent::LoadAndExtractOCDBObject(const char* path, int version, int subVersion, const char* key)
02bc7a5f 584{
585 // see header file for function documentation
586 AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry(path, GetRunNo(), version, subVersion);
587 if (!pEntry) return NULL;
f651054f 588 TObject* pObject=AliHLTMisc::Instance().ExtractObject(pEntry);
589 TMap* pMap=dynamic_cast<TMap*>(pObject);
590 if (pMap && key) {
591 pObject=pMap->GetValue(key);
592 if (!pObject) {
593 pObject=pMap->GetValue("default");
594 if (pObject) {
595 HLTWarning("can not find object for key \"%s\" in TMap of configuration object \"%s\", using key \"default\"", key, path);
596 }
597 }
598 if (!pObject) {
599 HLTError("can not find object for key \"%s\" in TMap of configuration object \"%s\"", key, path);
600 return NULL;
601 }
602 }
603 return pObject;
02bc7a5f 604}
605
579d9eb7 606int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
607{
608 // default implementation, childs can overload
b543e186 609 HLTLogKeyword("dummy");
53feaef5 610 return 0;
611}
612
613int AliHLTComponent::DoDeinit()
614{
579d9eb7 615 // default implementation, childs can overload
b543e186 616 HLTLogKeyword("dummy");
579d9eb7 617 return 0;
618}
619
620int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
621{
622 // default implementation, childs can overload
b543e186 623 HLTLogKeyword("dummy");
624 return 0;
625}
626
627int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/)
628{
629 // default implementation, childs can overload
630 HLTLogKeyword("dummy");
53feaef5 631 return 0;
632}
633
02bc7a5f 634int AliHLTComponent::ScanConfigurationArgument(int /*argc*/, const char** /*argv*/)
635{
636 // default implementation, childs can overload
637 HLTLogKeyword("dummy");
638 HLTWarning("The function needs to be implemented by the component");
639 return 0;
640}
641
45c0a780 642int AliHLTComponent::StartOfRun()
643{
644 // default implementation, childs can overload
645 HLTLogKeyword("dummy");
646 return 0;
647}
648
649int AliHLTComponent::EndOfRun()
650{
651 // default implementation, childs can overload
652 HLTLogKeyword("dummy");
653 return 0;
654}
655
656
2be3f004 657int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
de6593d0 658{
82c58a87 659 // default implementation, childs can overload
3a7c0444 660 HLTLogKeyword("dummy");
de6593d0 661 return 0;
662}
663
5ef2a37b 664void AliHLTComponent::GetOCDBObjectDescription( TMap* const /*targetArray*/)
665{
666 // default implementation, childs can overload
667 HLTLogKeyword("dummy");
668}
669
670int AliHLTComponent::CheckOCDBEntries(const TMap* const externList)
671{
672 // check the availability of the OCDB entry descriptions in the TMap
673 // key : complete OCDB path of the entry
674 // value : auxiliary object - short description
675 // if the external map was not provided the function invokes
676 // interface function GetOCDBObjectDescription() to retrieve the list.
677 int iResult=0;
678 if (externList) {
679 iResult=AliHLTMisc::Instance().CheckOCDBEntries(externList);
680 } else {
681 TMap* pMap=new TMap;
682 if (pMap) {
683 pMap->SetOwnerKeyValue(kTRUE);
684 GetOCDBObjectDescription(pMap);
685 iResult=AliHLTMisc::Instance().CheckOCDBEntries(pMap);
686 delete pMap;
687 pMap=NULL;
688 }
689 }
690
691 return iResult;
692}
693
70ed7d01 694void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
695{
696 // see header file for function documentation
9ce4bf4a 697 memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
698 strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
699 strcat( output, ":" );
700 strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
fa2e9b7c 701}
702
fbdb63fd 703string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
9ce4bf4a 704{
70ed7d01 705 // see header file for function documentation
9ce4bf4a 706 string out("");
fbdb63fd 707
58f0fd47 708 // 'typeid' 'origin'
709 // aligned to 8 and 4 chars respectively, blocks enclosed in quotes and
710 // separated by blank e.g.
711 // 'DDL_RAW ' 'TPC '
712 if (mode==3) {
713 int i=0;
714 char tmp[8];
715 out+="'";
716 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
717 unsigned char* puc=(unsigned char*)type.fID;
718 if (puc[i]<32)
719 sprintf(tmp, "\\%x", type.fID[i]);
720 else
721 sprintf(tmp, "%c", type.fID[i]);
722 out+=tmp;
723 }
724 out+="' '";
725 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
726 unsigned char* puc=(unsigned char*)type.fOrigin;
727 if ((puc[i])<32)
728 sprintf(tmp, "\\%x", type.fOrigin[i]);
729 else
730 sprintf(tmp, "%c", type.fOrigin[i]);
731 out+=tmp;
732 }
733 out+="'";
734 return out;
735 }
736
737 // origin typeid as numbers separated by colon e.g.
738 // aligned to 8 and 4 chars respectively, all characters separated by
739 // quotes, e.g.
740 // '84'80'67'32':'68'68'76'95'82'65'87'32'
fbdb63fd 741 if (mode==2) {
742 int i=0;
743 char tmp[8];
744 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
745 sprintf(tmp, "'%d", type.fOrigin[i]);
746 out+=tmp;
747 }
748 out+="':'";
749 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
750 sprintf(tmp, "%d'", type.fID[i]);
751 out+=tmp;
752 }
753 return out;
754 }
755
58f0fd47 756 // origin typeid separated by colon e.g.
757 // aligned to 8 and 4 chars respectively, all characters separated by
758 // quotes, e.g.
759 // 'T'P'C' ':'D'D'L'_'R'A'W' '
fbdb63fd 760 if (mode==1) {
761 int i=0;
762 char tmp[8];
763 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
764 unsigned char* puc=(unsigned char*)type.fOrigin;
765 if ((puc[i])<32)
766 sprintf(tmp, "'\\%x", type.fOrigin[i]);
767 else
768 sprintf(tmp, "'%c", type.fOrigin[i]);
769 out+=tmp;
770 }
771 out+="':'";
772 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
773 unsigned char* puc=(unsigned char*)type.fID;
774 if (puc[i]<32)
775 sprintf(tmp, "\\%x'", type.fID[i]);
776 else
777 sprintf(tmp, "%c'", type.fID[i]);
778 out+=tmp;
779 }
780 return out;
781 }
782
58f0fd47 783 // origin typeid
784 // aligned to 8 and 4 chars respectively, separated by colon e.g.
785 // TPC :DDL_RAW
9ce4bf4a 786 if (type==kAliHLTVoidDataType) {
787 out="VOID:VOID";
788 } else {
3cde846d 789 // some gymnastics in order to avoid a '0' which is part of either or both
790 // ID and origin terminating the whole string. Unfortunately, string doesn't
791 // stop appending at the '0' if the number of elements to append was
792 // explicitely specified
793 string tmp("");
794 tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
795 out.append(tmp.c_str());
9ce4bf4a 796 out.append(":");
3cde846d 797 tmp="";
798 tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
799 out.append(tmp.c_str());
9ce4bf4a 800 }
801 return out;
802}
803
804
70ed7d01 805void* AliHLTComponent::AllocMemory( unsigned long size )
806{
807 // see header file for function documentation
85869391 808 if (fEnvironment.fAllocMemoryFunc)
809 return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
9ce4bf4a 810 HLTFatal("no memory allocation handler registered");
85869391 811 return NULL;
812}
813
2be3f004 814int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
70ed7d01 815 AliHLTComponentBlockData** outputBlocks )
816{
817 // see header file for function documentation
9ce4bf4a 818 if ( blockCount==NULL || outputBlocks==NULL )
2d7ff710 819 return -EFAULT;
fa2e9b7c 820 AliHLTUInt32_t count = blocks.size();
821 if ( !count )
822 {
823 *blockCount = 0;
824 *outputBlocks = NULL;
825 return 0;
826 }
8ede8717 827 *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
fa2e9b7c 828 if ( !*outputBlocks )
2d7ff710 829 return -ENOMEM;
ca8524df 830 for ( unsigned long i = 0; i < count; i++ ) {
fa2e9b7c 831 (*outputBlocks)[i] = blocks[i];
732e8f50 832 if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
5f5b708b 833 (*outputBlocks)[i].fDataType=GetOutputDataType();
834 /* data type was set to the output data type by the PubSub AliRoot
835 Wrapper component, if data type of the block was ********:****.
836 Now handled by the component base class in order to have same
837 behavior when running embedded in AliRoot
ca8524df 838 memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
839 memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
5f5b708b 840 */
ca8524df 841 }
842 }
fa2e9b7c 843 *blockCount = count;
844 return 0;
845
846}
0c0c9d99 847
0007ed52 848int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd ) const
70ed7d01 849{
850 // see header file for function documentation
85869391 851 if (fEnvironment.fGetEventDoneDataFunc)
852 return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
853 return -ENOSYS;
854}
855
eafbc306 856int AliHLTComponent::ReserveEventDoneData( unsigned long size )
857{
858 // see header file for function documentation
859 int iResult=0;
860
6f4231a1 861 unsigned long capacity=fEventDoneDataSize;
862 if (fEventDoneData) capacity-=sizeof(AliHLTComponentEventDoneData)+fEventDoneData->fDataSize;
863 if (size>capacity) {
864 unsigned long newSize=sizeof(AliHLTComponentEventDoneData)+size+(fEventDoneDataSize-capacity);
865 AliHLTComponentEventDoneData* newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[newSize] );
eafbc306 866 if (!newEDD)
867 return -ENOMEM;
868 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
869 newEDD->fDataSize = 0;
870 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
871 if (fEventDoneData) {
872 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
873 newEDD->fDataSize = fEventDoneData->fDataSize;
874 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
875 }
876 fEventDoneData = newEDD;
6f4231a1 877 fEventDoneDataSize = newSize;
eafbc306 878 }
879 return iResult;
880
881}
882
883int AliHLTComponent::PushEventDoneData( AliHLTUInt32_t eddDataWord )
884{
0007ed52 885 // see header file for function documentation
eafbc306 886 if (!fEventDoneData)
887 return -ENOMEM;
888 if (fEventDoneData->fDataSize+sizeof(AliHLTUInt32_t)>fEventDoneDataSize)
889 return -ENOSPC;
890 *reinterpret_cast<AliHLTUInt32_t*>((reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize)) = eddDataWord;
891 fEventDoneData->fDataSize += sizeof(AliHLTUInt32_t);
892 return 0;
893}
894
895void AliHLTComponent::ReleaseEventDoneData()
896{
0007ed52 897 // see header file for function documentation
898 if (fEventDoneData)
eafbc306 899 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
900 fEventDoneData = NULL;
901 fEventDoneDataSize = 0;
902}
903
904
2be3f004 905int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList)
0c0c9d99 906{
70ed7d01 907 // see header file for function documentation
0c0c9d99 908 int iResult=0;
909 if (pConsumer) {
8a106878 910 AliHLTComponentDataTypeList itypes;
911 AliHLTComponentDataTypeList otypes;
912 otypes.push_back(GetOutputDataType());
c57201be 913 if (MatchExactly(otypes[0],kAliHLTMultipleDataType)) {
8a106878 914 otypes.clear();
915 int count=0;
916 if ((count=GetOutputDataTypes(otypes))>0) {
917 } else if (GetComponentType()!=kSink) {
918 HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
919 }
920 }
0007ed52 921 pConsumer->GetInputDataTypes(itypes);
48abe484 922 AliHLTComponentDataTypeList::iterator otype=otypes.begin();
923 for (;otype!=otypes.end();otype++) {
924 //PrintDataTypeContent((*otype), "publisher \'%s\'");
925 if ((*otype)==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate)) {
926 if (tgtList) tgtList->push_back(*otype);
927 iResult++;
928 continue;
929 }
930
931 AliHLTComponentDataTypeList::iterator itype=itypes.begin();
32f88fc5 932 for ( ; itype!=itypes.end() && (*itype)!=(*otype) ; itype++) {/* empty body */};
48abe484 933 //if (itype!=itypes.end()) PrintDataTypeContent(*itype, "consumer \'%s\'");
934 if (itype!=itypes.end()) {
935 if (tgtList) tgtList->push_back(*otype);
0c0c9d99 936 iResult++;
0c0c9d99 937 }
0c0c9d99 938 }
939 } else {
940 iResult=-EINVAL;
941 }
942 return iResult;
943}
2d7ff710 944
8b97f4f1 945void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format)
5f5b708b 946{
66043029 947 // see header file for function documentation
8b97f4f1 948 const char* fmt="\'%s\'";
5f5b708b 949 if (format) fmt=format;
8b97f4f1 950 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, Form(fmt, (DataType2Text(dt)).c_str()));
951 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL,
952 Form("%x %x %x %x %x %x %x %x : %x %x %x %x",
953 dt.fID[0],
954 dt.fID[1],
955 dt.fID[2],
956 dt.fID[3],
957 dt.fID[4],
958 dt.fID[5],
959 dt.fID[6],
960 dt.fID[7],
961 dt.fOrigin[0],
962 dt.fOrigin[1],
963 dt.fOrigin[2],
964 dt.fOrigin[3]));
5f5b708b 965}
966
fbdb63fd 967void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
70ed7d01 968{
969 // see header file for function documentation
2d7ff710 970 blockData.fStructSize = sizeof(blockData);
971 FillShmData( blockData.fShmKey );
972 blockData.fOffset = ~(AliHLTUInt32_t)0;
973 blockData.fPtr = NULL;
974 blockData.fSize = 0;
975 FillDataType( blockData.fDataType );
a655eae3 976 blockData.fSpecification = kAliHLTVoidDataSpec;
2d7ff710 977}
978
fbdb63fd 979void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
70ed7d01 980{
981 // see header file for function documentation
2d7ff710 982 shmData.fStructSize = sizeof(shmData);
983 shmData.fShmType = gkAliHLTComponentInvalidShmType;
984 shmData.fShmID = gkAliHLTComponentInvalidShmID;
985}
986
fbdb63fd 987void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
70ed7d01 988{
989 // see header file for function documentation
ca8524df 990 dataType=kAliHLTAnyDataType;
2d7ff710 991}
992
70ed7d01 993void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt)
994{
995 // see header file for function documentation
2d7ff710 996 memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
997 memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
998}
999
70ed7d01 1000void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin)
1001{
1002 // see header file for function documentation
7e3efc8f 1003 tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
1004 if (id) {
1005 memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
d76bc02a 1006 strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
7e3efc8f 1007 }
1008 if (origin) {
1009 memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
d76bc02a 1010 strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
7e3efc8f 1011 }
2d7ff710 1012}
9ce4bf4a 1013
18b56222 1014void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin)
1015{
1016 // see header file for function documentation
1017 dt.fStructSize=sizeof(AliHLTComponentDataType);
1018 assert(kAliHLTComponentDataTypefIDsize==sizeof(id));
1019 assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin));
1020 memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize);
1021 memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize);
1022}
1023
9ce4bf4a 1024void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
1025{
70ed7d01 1026 // see header file for function documentation
9ce4bf4a 1027 memset(&evtData, 0, sizeof(AliHLTComponentEventData));
1028 evtData.fStructSize=sizeof(AliHLTComponentEventData);
48abe484 1029 evtData.fEventID=kAliHLTVoidEventID;
9ce4bf4a 1030}
1031
70ed7d01 1032void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
1033{
1034 // see header file for function documentation
9ce4bf4a 1035 TString msg;
1036 msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
1037 for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
1038 if (dt.fID[i]!=0) msg+=dt.fID[i];
1039 else msg+="\\0";
1040 }
1041 msg+="\" Origin=\"";
1042 for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
1043 if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
1044 else msg+="\\0";
1045 }
1046 msg+="\"";
3cde846d 1047 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
9ce4bf4a 1048}
1049
70ed7d01 1050int AliHLTComponent::GetEventCount() const
3cde846d 1051{
70ed7d01 1052 // see header file for function documentation
3cde846d 1053 return fEventCount;
1054}
1055
1056int AliHLTComponent::IncrementEventCounter()
1057{
70ed7d01 1058 // see header file for function documentation
3cde846d 1059 if (fEventCount>=0) fEventCount++;
1060 return fEventCount;
1061}
1062
66043029 1063int AliHLTComponent::GetNumberOfInputBlocks() const
a655eae3 1064{
1065 // see header file for function documentation
1066 if (fpInputBlocks!=NULL) {
1067 return fCurrentEventData.fBlockCnt;
1068 }
1069 return 0;
1070}
1071
4646c6e3 1072AliHLTEventID_t AliHLTComponent::GetEventId() const
1073{
1074 // see header file for function documentation
1075 if (fpInputBlocks!=NULL) {
1076 return fCurrentEventData.fEventID;
1077 }
1078 return 0;
1079}
1080
a655eae3 1081const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
1082 const char* classname,
1083 int bForce)
1084{
1085 // see header file for function documentation
90ebac25 1086 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1087 fSearchDataType=dt;
1088 if (classname) fClassName=classname;
1089 else fClassName.clear();
1edbbe49 1090 int idx=FindInputBlock(fSearchDataType, 0, 1);
a655eae3 1091 TObject* pObj=NULL;
1092 if (idx>=0) {
79c114b5 1093 HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
a655eae3 1094 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
1095 fCurrentInputBlock=idx;
1096 } else {
1097 }
1098 }
1099 return pObj;
1100}
1101
1102const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
1103 const char* dtOrigin,
1104 const char* classname,
1105 int bForce)
1106{
1107 // see header file for function documentation
90ebac25 1108 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1109 AliHLTComponentDataType dt;
1110 SetDataType(dt, dtID, dtOrigin);
1111 return GetFirstInputObject(dt, classname, bForce);
1112}
1113
1114const TObject* AliHLTComponent::GetNextInputObject(int bForce)
1115{
1116 // see header file for function documentation
90ebac25 1117 ALIHLTCOMPONENT_BASE_STOPWATCH();
1edbbe49 1118 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
a655eae3 1119 //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
1120 TObject* pObj=NULL;
1121 if (idx>=0) {
1122 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
1123 fCurrentInputBlock=idx;
1124 }
1125 }
1126 return pObj;
1127}
1128
1edbbe49 1129int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
a655eae3 1130{
1131 // see header file for function documentation
1132 int iResult=-ENOENT;
1133 if (fpInputBlocks!=NULL) {
1134 int idx=startIdx<0?0:startIdx;
4b98eadb 1135 for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
3dd8541e 1136 if (dt!=fpInputBlocks[idx].fDataType) continue;
1137
1edbbe49 1138 if (bObject!=0) {
1139 if (fpInputBlocks[idx].fPtr==NULL) continue;
3294f81a 1140 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
1141 if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
1edbbe49 1142 }
3dd8541e 1143 iResult=idx;
a655eae3 1144 }
1145 }
1146 return iResult;
1147}
1148
1149TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
1150{
1151 // see header file for function documentation
1152 TObject* pObj=NULL;
1153 if (fpInputBlocks!=NULL) {
4b98eadb 1154 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 1155 if (fpInputBlocks[idx].fPtr) {
3294f81a 1156 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
a655eae3 1157 if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
8451168b 1158 HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
3294f81a 1159 AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
66043029 1160 TClass* objclass=msg.GetClass();
1161 pObj=msg.ReadObject(objclass);
1162 if (pObj && objclass) {
1163 HLTDebug("object %p type %s created", pObj, objclass->GetName());
a655eae3 1164 } else {
1165 }
1edbbe49 1166 //} else {
1167 } else if (bForce!=0) {
c5123824 1168 HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
a655eae3 1169 }
1170 } else {
1171 HLTFatal("block descriptor empty");
1172 }
1173 } else {
1174 HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
1175 }
1176 } else {
1177 HLTError("no input blocks available");
1178 }
1179
1180 return pObj;
1181}
1182
298ef463 1183TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
a655eae3 1184{
1185 // see header file for function documentation
1186 if (fpInputObjects==NULL) {
1187 fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
1188 }
1189 TObject* pObj=NULL;
1190 if (fpInputObjects) {
1191 pObj=fpInputObjects->At(idx);
1192 if (pObj==NULL) {
1193 pObj=CreateInputObject(idx, bForce);
1194 if (pObj) {
1195 fpInputObjects->AddAt(pObj, idx);
1196 }
1197 }
1198 } else {
1199 HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
1200 }
1201 return pObj;
1202}
1203
8451168b 1204int AliHLTComponent::CleanupInputObjects()
1205{
66043029 1206 // see header file for function documentation
8451168b 1207 if (!fpInputObjects) return 0;
1208 TObjArray* array=fpInputObjects;
1209 fpInputObjects=NULL;
3ecb06e2 1210 for (int i=0; i<array->GetEntriesFast(); i++) {
8451168b 1211 TObject* pObj=array->At(i);
79c114b5 1212 // grrr, garbage collection strikes back: When read via AliHLTMessage
1213 // (CreateInputObject), and written to a TFile afterwards, the
1214 // TFile::Close calls ROOOT's garbage collection. No clue why the
1215 // object ended up in the key list and needs to be deleted
a6c7a8bc 1216 //
1217 // Matthias 09.11.2008 follow up
1218 // This approach doesn't actually work in all cases: the object table
1219 // can be switched off globally, the flag needs to be checked here as
1220 // well in order to avoid memory leaks.
1221 // This means we have to find another solution for the problem if it
1222 // pops up again.
1223 if (pObj &&
1224 (!TObject::GetObjectStat() || gObjectTable->PtrIsValid(pObj))) {
1225 delete pObj;
1226 }
8451168b 1227 }
1228 delete array;
90ebac25 1229 return 0;
8451168b 1230}
1231
a655eae3 1232AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
1233{
1234 // see header file for function documentation
90ebac25 1235 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1236 AliHLTComponentDataType dt=kAliHLTVoidDataType;
1237 int idx=fCurrentInputBlock;
1238 if (pObject) {
1239 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1240 } else {
1241 HLTError("unknown object %p", pObject);
1242 }
1243 }
1244 if (idx>=0) {
4b98eadb 1245 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 1246 dt=fpInputBlocks[idx].fDataType;
1247 } else {
1248 HLTFatal("severe internal error, index out of range");
1249 }
1250 }
1251 return dt;
1252}
1253
1254AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
1255{
1256 // see header file for function documentation
90ebac25 1257 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1258 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1259 int idx=fCurrentInputBlock;
1260 if (pObject) {
1261 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1262 } else {
1263 HLTError("unknown object %p", pObject);
1264 }
1265 }
1266 if (idx>=0) {
4b98eadb 1267 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 1268 iSpec=fpInputBlocks[idx].fSpecification;
1269 } else {
1270 HLTFatal("severe internal error, index out of range");
1271 }
1272 }
1273 return iSpec;
1274}
1275
c7e9e2f2 1276int AliHLTComponent::Forward(const TObject* pObject)
1277{
1278 // see header file for function documentation
1279 int iResult=0;
1280 int idx=fCurrentInputBlock;
1281 if (pObject) {
1282 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1283 } else {
1284 HLTError("unknown object %p", pObject);
1285 iResult=-ENOENT;
1286 }
1287 }
1288 if (idx>=0) {
1289 fOutputBlocks.push_back(fpInputBlocks[idx]);
1290 }
1291 return iResult;
1292}
1293
1294int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
1295{
1296 // see header file for function documentation
1297 int iResult=0;
1298 int idx=fCurrentInputBlock;
1299 if (pBlock) {
2f52bfcd 1300 if ((idx=FindInputBlock(pBlock))>=0) {
c7e9e2f2 1301 } else {
1302 HLTError("unknown Block %p", pBlock);
1303 iResult=-ENOENT;
1304 }
1305 }
1306 if (idx>=0) {
1307 // check for fpInputBlocks pointer done in FindInputBlock
1308 fOutputBlocks.push_back(fpInputBlocks[idx]);
1309 }
1310 return iResult;
1311}
1312
a655eae3 1313const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
1314{
1315 // see header file for function documentation
90ebac25 1316 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1317 fSearchDataType=dt;
1318 fClassName.clear();
1319 int idx=FindInputBlock(fSearchDataType, 0);
1320 const AliHLTComponentBlockData* pBlock=NULL;
1321 if (idx>=0) {
1322 // check for fpInputBlocks pointer done in FindInputBlock
1323 pBlock=&fpInputBlocks[idx];
1edbbe49 1324 fCurrentInputBlock=idx;
a655eae3 1325 }
1326 return pBlock;
1327}
1328
1329const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
1330 const char* dtOrigin)
1331{
1332 // see header file for function documentation
90ebac25 1333 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1334 AliHLTComponentDataType dt;
1335 SetDataType(dt, dtID, dtOrigin);
1336 return GetFirstInputBlock(dt);
1337}
1338
10b9cbf9 1339const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index) const
ec25e4ca 1340{
1341 // see header file for function documentation
1342 ALIHLTCOMPONENT_BASE_STOPWATCH();
13398559 1343 assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
ec25e4ca 1344 return &fpInputBlocks[index];
1345}
1346
a655eae3 1347const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
1348{
1349 // see header file for function documentation
90ebac25 1350 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1351 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
1352 const AliHLTComponentBlockData* pBlock=NULL;
1353 if (idx>=0) {
1354 // check for fpInputBlocks pointer done in FindInputBlock
1355 pBlock=&fpInputBlocks[idx];
1edbbe49 1356 fCurrentInputBlock=idx;
a655eae3 1357 }
1358 return pBlock;
1359}
1360
66043029 1361int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
a655eae3 1362{
1363 // see header file for function documentation
1364 int iResult=-ENOENT;
1365 if (fpInputBlocks!=NULL) {
1366 if (pBlock) {
1367 if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
132ca004 1368 iResult=(int)(pBlock-fpInputBlocks);
a655eae3 1369 }
1370 } else {
1371 iResult=-EINVAL;
1372 }
1373 }
1374 return iResult;
1375}
1376
1377AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
1378{
1379 // see header file for function documentation
90ebac25 1380 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1381 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1382 int idx=fCurrentInputBlock;
1383 if (pBlock) {
1384 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
1385 } else {
1386 HLTError("unknown Block %p", pBlock);
1387 }
1388 }
1389 if (idx>=0) {
1390 // check for fpInputBlocks pointer done in FindInputBlock
1391 iSpec=fpInputBlocks[idx].fSpecification;
1392 }
1393 return iSpec;
1394}
1395
79c114b5 1396int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1397 void* pHeader, int headerSize)
a655eae3 1398{
1399 // see header file for function documentation
90ebac25 1400 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1401 int iResult=0;
b3f4766b 1402 fLastObjectSize=0;
9d4d4b02 1403 if (fPushbackPeriod>0) {
1404 // suppress the output
1405 TDatime time;
1406 if (fLastPushBackTime<0 || (int)time.Get()-fLastPushBackTime<fPushbackPeriod) return 0;
1407 }
a655eae3 1408 if (pObject) {
1409 AliHLTMessage msg(kMESS_OBJECT);
9ace7282 1410 msg.SetCompressionLevel(fCompressionLevel);
a655eae3 1411 msg.WriteObject(pObject);
1412 Int_t iMsgLength=msg.Length();
1413 if (iMsgLength>0) {
9ace7282 1414 // Matthias Sep 2008
1415 // NOTE: AliHLTMessage does implement it's own SetLength method
1416 // which is not architecture independent. The original SetLength
1417 // stores the size always in network byte order.
1418 // I'm trying to remember the rational for that, might be that
1419 // it was just some lack of knowledge. Want to change this, but
1420 // has to be done carefullt to be backward compatible.
a655eae3 1421 msg.SetLength(); // sets the length to the first (reserved) word
9ace7282 1422
1423 // does nothing if the level is 0
1424 msg.Compress();
1425
1426 char *mbuf = msg.Buffer();
1427 if (msg.CompBuffer()) {
1428 msg.SetLength(); // set once more to have to byte order
1429 mbuf = msg.CompBuffer();
1430 iMsgLength = msg.CompLength();
1431 }
1432 assert(mbuf!=NULL);
1433 iResult=InsertOutputBlock(mbuf, iMsgLength, dt, spec, pHeader, headerSize);
a655eae3 1434 if (iResult>=0) {
9ace7282 1435 HLTDebug("object %s (%p) size %d compression %d inserted to output", pObject->ClassName(), pObject, iMsgLength, msg.GetCompressionLevel());
a655eae3 1436 }
b3f4766b 1437 fLastObjectSize=iMsgLength;
a655eae3 1438 } else {
1439 HLTError("object serialization failed for object %p", pObject);
1440 iResult=-ENOMSG;
1441 }
1442 } else {
1443 iResult=-EINVAL;
1444 }
1445 return iResult;
1446}
1447
79c114b5 1448int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1449 void* pHeader, int headerSize)
a655eae3 1450{
1451 // see header file for function documentation
90ebac25 1452 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1453 AliHLTComponentDataType dt;
1454 SetDataType(dt, dtID, dtOrigin);
79c114b5 1455 return PushBack(pObject, dt, spec, pHeader, headerSize);
a655eae3 1456}
1457
438635e3 1458int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1459 const void* pHeader, int headerSize)
a655eae3 1460{
1461 // see header file for function documentation
90ebac25 1462 ALIHLTCOMPONENT_BASE_STOPWATCH();
9d4d4b02 1463 if (fPushbackPeriod>0) {
1464 // suppress the output
1465 TDatime time;
1466 if (fLastPushBackTime<0 || (int)time.Get()-fLastPushBackTime<fPushbackPeriod) return 0;
1467 }
1468
9d9ffd37 1469 return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1470}
1471
438635e3 1472int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1473 const void* pHeader, int headerSize)
a655eae3 1474{
1475 // see header file for function documentation
90ebac25 1476 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1477 AliHLTComponentDataType dt;
1478 SetDataType(dt, dtID, dtOrigin);
9d9ffd37 1479 return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1480}
1481
438635e3 1482int AliHLTComponent::InsertOutputBlock(const void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1483 const void* pHeader, int iHeaderSize)
a655eae3 1484{
1485 // see header file for function documentation
1486 int iResult=0;
79c114b5 1487 int iBlkSize = iBufferSize + iHeaderSize;
438635e3 1488
1489 if ((pBuffer!=NULL && iBufferSize>0) || (pHeader!=NULL && iHeaderSize>0)) {
79c114b5 1490 if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
a655eae3 1491 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
438635e3 1492
1493 // copy header if provided but skip if the header is the target location
1494 // in that case it has already been copied
79c114b5 1495 if (pHeader!=NULL && pHeader!=pTgt) {
1496 memcpy(pTgt, pHeader, iHeaderSize);
1497 }
1498
1499 pTgt += (AliHLTUInt8_t) iHeaderSize;
1500
438635e3 1501 // copy buffer if provided but skip if buffer is the target location
1502 // in that case it has already been copied
a655eae3 1503 if (pBuffer!=NULL && pBuffer!=pTgt) {
79c114b5 1504 memcpy(pTgt, pBuffer, iBufferSize);
1505
4b98eadb 1506 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
79c114b5 1507 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
a655eae3 1508 }
79c114b5 1509 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
a655eae3 1510 } else {
1511 if (fpOutputBuffer) {
b3f4766b 1512 HLTError("too little space in output buffer: %d of %d, required %d", fOutputBufferSize-fOutputBufferFilled, fOutputBufferSize, iBlkSize);
a655eae3 1513 } else {
1514 HLTError("output buffer not available");
1515 }
1516 iResult=-ENOSPC;
1517 }
a655eae3 1518 }
438635e3 1519 if (iResult>=0) {
1520 AliHLTComponentBlockData bd;
1521 FillBlockData( bd );
1522 bd.fOffset = fOutputBufferFilled;
1523 bd.fSize = iBlkSize;
1524 bd.fDataType = dt;
1525 bd.fSpecification = spec;
1526 fOutputBlocks.push_back( bd );
1527 fOutputBufferFilled+=bd.fSize;
1528 }
1529
a655eae3 1530 return iResult;
1531}
1532
8451168b 1533int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
1534{
66043029 1535 // see header file for function documentation
cc63ef09 1536 if (!pObject) return 0;
1537
1538 AliHLTMessage msg(kMESS_OBJECT);
1539 msg.WriteObject(pObject);
1540 return msg.Length();
8451168b 1541}
1542
79c114b5 1543AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1544 const char* dtOrigin,
1545 AliHLTUInt32_t spec)
1546{
1547 // see header file for function documentation
1548 ALIHLTCOMPONENT_BASE_STOPWATCH();
1549 AliHLTComponentDataType dt;
1550 SetDataType(dt, dtID, dtOrigin);
1551 return CreateMemoryFile(capacity, dt, spec);
1552}
1553
1554AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1555 const AliHLTComponentDataType& dt,
1556 AliHLTUInt32_t spec)
1557{
1558 // see header file for function documentation
1559 ALIHLTCOMPONENT_BASE_STOPWATCH();
1560 AliHLTMemoryFile* pFile=NULL;
83fec083 1561 if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
79c114b5 1562 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1563 pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1564 if (pFile) {
83fec083 1565 unsigned int nofBlocks=fOutputBlocks.size();
79c114b5 1566 if (nofBlocks+1>fMemFiles.size()) {
1567 fMemFiles.resize(nofBlocks+1, NULL);
1568 }
1569 if (nofBlocks<fMemFiles.size()) {
1570 fMemFiles[nofBlocks]=pFile;
1571 AliHLTComponentBlockData bd;
1572 FillBlockData( bd );
1573 bd.fOffset = fOutputBufferFilled;
79c114b5 1574 bd.fSize = capacity;
1575 bd.fDataType = dt;
1576 bd.fSpecification = spec;
1577 fOutputBufferFilled+=bd.fSize;
1578 fOutputBlocks.push_back( bd );
1579 } else {
1580 HLTError("can not allocate/grow object array");
29312178 1581 pFile->CloseMemoryFile(0);
79c114b5 1582 delete pFile;
1583 pFile=NULL;
1584 }
1585 }
1586 } else {
1587 HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1588 }
1589 return pFile;
1590}
1591
1592AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1593 const char* dtOrigin,
1594 AliHLTUInt32_t spec,
1595 float capacity)
1596{
1597 // see header file for function documentation
1598 ALIHLTCOMPONENT_BASE_STOPWATCH();
1599 AliHLTComponentDataType dt;
1600 SetDataType(dt, dtID, dtOrigin);
1601 int size=fOutputBufferSize-fOutputBufferFilled;
1602 if (capacity<0 || capacity>1.0) {
1603 HLTError("invalid parameter: capacity %f", capacity);
1604 return NULL;
1605 }
1606 size=(int)(size*capacity);
1607 return CreateMemoryFile(size, dt, spec);
1608}
1609
1610AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1611 AliHLTUInt32_t spec,
1612 float capacity)
1613{
1614 // see header file for function documentation
1615 ALIHLTCOMPONENT_BASE_STOPWATCH();
1616 int size=fOutputBufferSize-fOutputBufferFilled;
1617 if (capacity<0 || capacity>1.0) {
1618 HLTError("invalid parameter: capacity %f", capacity);
1619 return NULL;
1620 }
1621 size=(int)(size*capacity);
1622 return CreateMemoryFile(size, dt, spec);
1623}
1624
1625int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1626 const char* key, int option)
1627{
3a7c0444 1628 // see header file for function documentation
79c114b5 1629 int iResult=0;
1630 if (pFile && pObject) {
1631 pFile->cd();
1632 iResult=pObject->Write(key, option);
1633 if (iResult>0) {
1634 // success
1635 } else {
1636 iResult=-pFile->GetErrno();
1637 if (iResult==-ENOSPC) {
1638 HLTError("error writing memory file, buffer too small");
1639 }
1640 }
1641 } else {
1642 iResult=-EINVAL;
1643 }
1644 return iResult;
1645}
1646
1647int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1648{
3a7c0444 1649 // see header file for function documentation
79c114b5 1650 int iResult=0;
1651 if (pFile) {
2be3f004 1652 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1653 int i=0;
1654 while (element!=fMemFiles.end() && iResult>=0) {
1655 if (*element && *element==pFile) {
29312178 1656 iResult=pFile->CloseMemoryFile();
79c114b5 1657
1658 // sync memory files and descriptors
1659 if (iResult>=0) {
1660 fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1661 }
1662 delete *element;
1663 *element=NULL;
1664 return iResult;
1665 }
1666 element++; i++;
1667 }
1668 HLTError("can not find memory file %p", pFile);
1669 iResult=-ENOENT;
1670 } else {
1671 iResult=-EINVAL;
1672 }
1673 return iResult;
1674}
1675
eafbc306 1676int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
a655eae3 1677{
1678 // see header file for function documentation
eafbc306 1679 int iResult=0;
1680
1681 AliHLTComponentEventDoneData* newEDD = NULL;
1682
1683 unsigned long newSize=edd.fDataSize;
1684 if (fEventDoneData)
1685 newSize += fEventDoneData->fDataSize;
1686
1687 if (newSize>fEventDoneDataSize) {
1688 newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+newSize ] );
1689 if (!newEDD)
1690 return -ENOMEM;
1691 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
1692 newEDD->fDataSize = newSize;
1693 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
1694 unsigned long long offset = 0;
1695 if (fEventDoneData) {
1696 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
1697 offset += fEventDoneData->fDataSize;
1698 }
1699 memcpy( reinterpret_cast<AliHLTUInt8_t*>(newEDD->fData)+offset, edd.fData, edd.fDataSize );
1700 if (fEventDoneData)
1701 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
1702 fEventDoneData = newEDD;
1703 fEventDoneDataSize = newSize;
1704 }
1705 else {
1706 memcpy( reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize, edd.fData, edd.fDataSize );
1707 fEventDoneData->fDataSize += edd.fDataSize;
1708 }
a655eae3 1709 return iResult;
1710}
1711
3cde846d 1712int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1713 const AliHLTComponentBlockData* blocks,
1714 AliHLTComponentTriggerData& trigData,
1715 AliHLTUInt8_t* outputPtr,
1716 AliHLTUInt32_t& size,
1717 AliHLTUInt32_t& outputBlockCnt,
1718 AliHLTComponentBlockData*& outputBlocks,
1719 AliHLTComponentEventDoneData*& edd )
1720{
70ed7d01 1721 // see header file for function documentation
66108417 1722 HLTLogKeyword(fChainId.c_str());
90ebac25 1723 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1724 int iResult=0;
1725 fCurrentEvent=evtData.fEventID;
a655eae3 1726 fCurrentEventData=evtData;
1727 fpInputBlocks=blocks;
1728 fCurrentInputBlock=-1;
1729 fSearchDataType=kAliHLTAnyDataType;
1730 fpOutputBuffer=outputPtr;
1731 fOutputBufferSize=size;
1732 fOutputBufferFilled=0;
1733 fOutputBlocks.clear();
96f9673a 1734 outputBlockCnt=0;
1735 outputBlocks=NULL;
438635e3 1736
1737 AliHLTComponentBlockDataList forwardedBlocks;
1738
1739 // optional component statistics
a0aeb701 1740 AliHLTComponentStatisticsList compStats;
438635e3 1741 bool bAddComponentTableEntry=false;
abb52c8f 1742 vector<AliHLTUInt32_t> parentComponentTables;
78d29060 1743#if defined(HLT_COMPONENT_STATISTICS)
1744 if ((fFlags&kDisableComponentStat)==0) {
1745 AliHLTComponentStatistics outputStat;
1746 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
1747 outputStat.fStructSize=sizeof(AliHLTComponentStatistics);
1748 outputStat.fId=fChainIdCrc;
1749 if (fpBenchmark) {
1750 fpBenchmark->Stop();
1751 outputStat.fComponentCycleTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1752 fpBenchmark->Reset();
1753 fpBenchmark->Start();
1754 }
1755 compStats.push_back(outputStat);
a0aeb701 1756 }
78d29060 1757#endif // HLT_COMPONENT_STATISTICS
559631d5 1758
48abe484 1759 // data processing is skipped
1760 // - if there are only steering events in the block list.
1761 // For the sake of data source components data processing
1762 // is not skipped if there is no block list at all or if it
1763 // just contains the eventType block
1764 // - always skipped if the event is of type
1765 // - gkAliEventTypeConfiguration
1766 // - gkAliEventTypeReadPreprocessor
45c0a780 1767 const unsigned int skipModeDefault=0x1;
1768 const unsigned int skipModeForce=0x2;
1769 unsigned int bSkipDataProcessing=skipModeDefault;
1770
559631d5 1771 // find special events
45c0a780 1772 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1773 // first look for all special events and execute in the appropriate
1774 // sequence afterwords
1775 int indexComConfEvent=-1;
b543e186 1776 int indexUpdtDCSEvent=-1;
579d9eb7 1777 int indexSOREvent=-1;
1778 int indexEOREvent=-1;
cf9cf07e 1779 int indexECSParamBlock=-1;
83fec083 1780 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1781 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1782 indexSOREvent=i;
45c0a780 1783 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1784 bSkipDataProcessing&=~skipModeDefault;
1785 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1786 // run type string
1787 // handling is not clear yet
1788 if (fpInputBlocks[i].fPtr) {
1789 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1790 }
579d9eb7 1791 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1792 indexEOREvent=i;
45c0a780 1793 // the calibration processor relies on the SOR and EOR events
1794 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1795 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1796 // DDL list
1797 // this event is most likely deprecated
1798 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1799 indexComConfEvent=i;
b543e186 1800 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1801 indexUpdtDCSEvent=i;
1802 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1803 fEventType=fpInputBlocks[i].fSpecification;
9e14734f 1804 if (fEventType != gkAliEventTypeConfiguration and
1805 fEventType != gkAliEventTypeReadPreprocessor
1806 )
1807 {
1808 // We can actually get the event type from the CDH if it is valid.
1809 // Otherwise just use the specification of the input block.
1810 const AliRawDataHeader* cdh;
1811 if (ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL) == 0)
1812 {
1813 fEventType = ExtractEventTypeFromCDH(cdh);
1814 }
1815 }
48abe484 1816
1817 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1818 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1819
1820 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1821 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1822
1823 // never skip if the event type block is the only block
1824 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1825
a0aeb701 1826 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1827 if (compStats.size()>0) {
1828 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1829 for (AliHLTUInt32_t offset=0;
1830 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1831 offset+=sizeof(AliHLTComponentStatistics)) {
1832 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1833 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1834 compStats[0].fLevel=pStat->fLevel+1;
1835 }
1836 compStats.push_back(*pStat);
1837 }
1838 }
438635e3 1839 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
1840 forwardedBlocks.push_back(fpInputBlocks[i]);
abb52c8f 1841 parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
cf9cf07e 1842 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeECSParam) {
1843 indexECSParamBlock=i;
45c0a780 1844 } else {
1845 // the processing function is called if there is at least one
1846 // non-steering data block. Steering blocks are not filtered out
1847 // for sake of performance
1848 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1849 if (compStats.size()>0) {
1850 compStats[0].fInputBlockCount++;
1851 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1852 }
579d9eb7 1853 }
1854 }
45c0a780 1855
579d9eb7 1856 if (indexSOREvent>=0) {
1857 // start of run
438635e3 1858 bAddComponentTableEntry=true;
579d9eb7 1859 if (fpRunDesc==NULL) {
1860 fpRunDesc=new AliHLTRunDesc;
48abe484 1861 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1862 }
1863 if (fpRunDesc) {
1864 AliHLTRunDesc rundesc;
1865 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1866 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1867 *fpRunDesc=rundesc;
579d9eb7 1868 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1869 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1870 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1871 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1872 }
559631d5 1873 }
579d9eb7 1874 } else {
45c0a780 1875 iResult=-ENOMEM;
579d9eb7 1876 }
cf9cf07e 1877
1878 if (indexECSParamBlock>=0) {
1879 if (fpInputBlocks[indexECSParamBlock].fSize>0) {
1880 const char* param=reinterpret_cast<const char*>(fpInputBlocks[indexECSParamBlock].fPtr);
1881 TString paramString;
1882 if (param[fpInputBlocks[indexECSParamBlock].fSize-1]!=0) {
1883 HLTWarning("ECS parameter string not terminated");
1884 paramString.Insert(0, param, fpInputBlocks[indexECSParamBlock].fSize);
1885 paramString+="";
1886 } else {
1887 paramString=param;
1888 }
1889 ScanECSParam(paramString.Data());
1890 } else {
1891 HLTWarning("empty ECS parameter received");
1892 }
1893 } else {
1894 // TODO: later on we might throw a warning here since the CTP trigger classes
1895 // should be mandatory
1896 }
579d9eb7 1897 }
1898 if (indexEOREvent>=0) {
9d4d4b02 1899 fLastPushBackTime=0; // always send at EOR
438635e3 1900 bAddComponentTableEntry=true;
579d9eb7 1901 if (fpRunDesc!=NULL) {
1902 if (fpRunDesc) {
1903 AliHLTRunDesc rundesc;
1904 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1905 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 1906 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 1907 } else {
1908 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 1909 }
559631d5 1910 }
bee8f777 1911 // we do not unload the fpRunDesc struct here in order to have the run information
1912 // available during the event processing
1913 // https://savannah.cern.ch/bugs/?39711
1914 // the info will be cleared in DeInit
559631d5 1915 }
579d9eb7 1916 } else {
1917 HLTWarning("did not receive SOR, ignoring EOR");
1918 }
1919 }
48abe484 1920 if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
579d9eb7 1921 TString cdbEntry;
b543e186 1922 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 1923 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1924 }
1925 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1926 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1927 if (tmpResult<0) {
1928 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 1929 }
1930 }
48abe484 1931 if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
b543e186 1932 TString modules;
1933 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1934 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1935 }
d6b69874 1936 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1937 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 1938 if (tmpResult<0) {
1939 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1940 }
1941 }
45c0a780 1942 } else {
1943 // processing function needs to be called if there are no input data
1944 // blocks in order to make data source components working.
1945 bSkipDataProcessing&=~skipModeDefault;
559631d5 1946 }
a0aeb701 1947
1948 // data processing is not skipped if the component explicitly asks
1949 // for the private blocks
78d29060 1950 if ((fFlags&kRequireSteeringBlocks)!=0) bSkipDataProcessing=0;
a0aeb701 1951
edd72347 1952 if (fpCTPData) {
1953 // set the active triggers for this event
1954 fpCTPData->SetTriggers(trigData);
1955 // increment CTP trigger counters if available
1956 if (IsDataEvent()) fpCTPData->Increment(trigData);
1957 }
adb91bc3 1958
2be3f004 1959 AliHLTComponentBlockDataList blockData;
45c0a780 1960 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 1961 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 1962 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
1963 // in order to avoid 'shadowed variable' warning
1964 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
90ebac25 1965 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1966 } // end of the scope of the stopwatch guard
b543e186 1967 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 1968 if (fOutputBlocks.size()>0) {
df61f928 1969 // High Level interface
1970
1971 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 1972 // sync memory files and descriptors
2be3f004 1973 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1974 int i=0;
1975 while (element!=fMemFiles.end() && iResult>=0) {
1976 if (*element) {
1977 if ((*element)->IsClosed()==0) {
1978 HLTWarning("memory file has not been closed, force flush");
1979 iResult=CloseMemoryFile(*element);
1980 }
1981 }
1982 element++; i++;
1983 }
1984
1985 if (iResult>=0) {
1986 // create the descriptor list
1987 if (blockData.size()>0) {
1988 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1989 iResult=-EFAULT;
1990 } else {
abb52c8f 1991 if (compStats.size()>0 && IsDataEvent()) {
a0aeb701 1992 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
1993 if (offset>0) fOutputBufferFilled+=offset;
1994 }
438635e3 1995 if (bAddComponentTableEntry) {
abb52c8f 1996 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables);
438635e3 1997 if (offset>0) size+=offset;
1998 }
1999 if (forwardedBlocks.size()>0) {
2000 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
2001 }
79c114b5 2002 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
2003 size=fOutputBufferFilled;
2004 }
a655eae3 2005 }
2006 } else {
df61f928 2007 // Low Level interface
a0aeb701 2008 if (compStats.size()>0) {
2009 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
2010 if (offset>0) size+=offset;
2011 }
438635e3 2012 if (bAddComponentTableEntry) {
abb52c8f 2013 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables);
438635e3 2014 if (offset>0) size+=offset;
2015 }
2016 if (forwardedBlocks.size()>0) {
2017 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
2018 }
a655eae3 2019 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
2020 }
2021 if (iResult<0) {
2022 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
2023 }
2024 }
b543e186 2025 if (iResult<0 || bSkipDataProcessing) {
a655eae3 2026 outputBlockCnt=0;
2027 outputBlocks=NULL;
2028 }
8451168b 2029 CleanupInputObjects();
48abe484 2030 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 2031 IncrementEventCounter();
2032 }
96f9673a 2033 if (outputBlockCnt==0) {
2034 // no output blocks, set size to 0
2035 size=0;
2036 }
6f4231a1 2037
2038 // reset the internal EventData struct
4646c6e3 2039 FillEventData(fCurrentEventData);
edd72347 2040
2041 // reset the active triggers
2042 if (fpCTPData) fpCTPData->SetTriggers(0);
9d4d4b02 2043
2044 // set the time for the pushback period
2045 if (fPushbackPeriod>0) {
2046 // suppress the output
2047 TDatime time;
2048 if (fLastPushBackTime<0 || (int)time.Get()-fLastPushBackTime>=fPushbackPeriod) {
2049 fLastPushBackTime=time.Get();
2050 }
2051 }
2052
3cde846d 2053 return iResult;
2054}
a655eae3 2055
a0aeb701 2056int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
2057 AliHLTUInt8_t* buffer,
2058 AliHLTUInt32_t bufferSize,
2059 AliHLTUInt32_t offset,
2060 AliHLTComponentStatisticsList& stats) const
2061{
2062 // see header file for function documentation
2063 int iResult=0;
78d29060 2064 if ((fFlags&kDisableComponentStat)!=0) return 0;
2065#if defined(HLT_COMPONENT_STATISTICS)
a0aeb701 2066 if (stats.size()==0) return -ENOENT;
ae962989 2067 // check if there is space for at least one entry
2068 if (offset+sizeof(AliHLTComponentStatistics)>bufferSize) return 0;
a0aeb701 2069 stats[0].fTotalOutputSize=offset;
2070 stats[0].fOutputBlockCount=blocks.size();
2071 if (fpBenchmark) {
2e3fd14f 2072 fpBenchmark->Stop();
2073 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
2074 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
2075 fpBenchmark->Continue();
a0aeb701 2076 }
ae962989 2077 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize) {
2078 AliHLTUInt32_t removedLevel=0;
2079 do {
2080 // remove all entries of the level of the last entry
2081 removedLevel=stats.back().fLevel;
2082 AliHLTComponentStatisticsList::iterator element=stats.begin();
2083 element++;
2084 while (element!=stats.end()) {
2085 if (element->fLevel<=removedLevel) {
2086 element=stats.erase(element);
2087 } else {
2088 element++;
2089 }
2090 }
2091 } while (stats.size()>1 &&
2092 (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize));
2093 }
2094 assert(stats.size()>0);
2095 if (stats.size()==0) return 0;
2096
a0aeb701 2097 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
2098 AliHLTComponentBlockData bd;
2099 FillBlockData( bd );
2100 bd.fOffset = offset;
2101 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
2102 bd.fDataType = kAliHLTDataTypeComponentStatistics;
2103 bd.fSpecification = kAliHLTVoidDataSpec;
2104 unsigned int master=0;
2105 for (unsigned int i=1; i<blocks.size(); i++) {
2106 if (blocks[i].fSize>blocks[master].fSize &&
2107 !MatchExactly(blocks[i].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate))
2108 master=i;
2109 }
2110 if (blocks.size()>0 && !MatchExactly(blocks[master].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) {
2111 // take the data origin of the biggest block as specification
2112 // this is similar to the treatment in the HOMER interface. For traditional
2113 // reasons, the bytes are swapped there on a little endian architecture, so
2114 // we do it as well.
2115 memcpy(&bd.fSpecification, &blocks[master].fDataType.fOrigin, sizeof(bd.fSpecification));
2116#ifdef R__BYTESWAP // set on little endian architectures
2117 bd.fSpecification=((bd.fSpecification & 0xFFULL) << 24) |
2118 ((bd.fSpecification & 0xFF00ULL) << 8) |
2119 ((bd.fSpecification & 0xFF0000ULL) >> 8) |
2120 ((bd.fSpecification & 0xFF000000ULL) >> 24);
2121#endif
2122 }
2123 memcpy(buffer+offset, &(stats[0]), bd.fSize);
2124 blocks.push_back(bd);
2125 iResult=bd.fSize;
2126 }
bd6cac58 2127#else
2128 if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
2129 // get rid of warning
2130 }
78d29060 2131#endif // HLT_COMPONENT_STATISTICS
438635e3 2132 return iResult;
2133}
2134
2135int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
2136 AliHLTUInt8_t* buffer,
2137 AliHLTUInt32_t bufferSize,
abb52c8f 2138 AliHLTUInt32_t offset,
2139 const vector<AliHLTUInt32_t>& parents) const
438635e3 2140{
2141 // see header file for function documentation
2142 int iResult=0;
78d29060 2143 if ((fFlags&kDisableComponentStat)!=0) return 0;
2144#if defined(HLT_COMPONENT_STATISTICS)
abb52c8f 2145 // the payload consists of the AliHLTComponentTableEntry struct,
2146 // followed by a an array of 32bit crc chain ids and the component
2147 // description string
2148 unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
2149 payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
2150
2151 // the component description has the following format:
2152 // chain-id{component-id:arguments}
2153 const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
2154 unsigned int descriptionSize=fChainId.size()+1;
2155 descriptionSize+=2; // the '{}' around the component id
2156 descriptionSize+=strlen(componentId);
2157 descriptionSize+=1; // the ':' between component id and arguments
2158 descriptionSize+=fComponentArgs.size();
2159
2160 payloadSize+=descriptionSize;
2161 if (buffer && (offset+payloadSize<=bufferSize)) {
2162 AliHLTUInt8_t* pTgt=buffer+offset;
2163 memset(pTgt, 0, payloadSize);
2164
2165 // write entry
2166 AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
2167 pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
2168 pEntry->fNofParents=parents.size();
2169 pEntry->fSizeDescription=descriptionSize;
2170 pTgt=pEntry->fBuffer;
2171
2172 // write array of parents
2173 if (parents.size()>0) {
2174 unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
2175 memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
2176 pTgt+=copy;
2177 }
2178
2179 // write component description
2180 memcpy(pTgt, fChainId.c_str(), fChainId.size());
2181 pTgt+=fChainId.size();
2182 *pTgt++='{';
2183 memcpy(pTgt, componentId, strlen(componentId));
2184 pTgt+=strlen(componentId);
2185 *pTgt++=':';
2186 memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
2187 pTgt+=fComponentArgs.size();
2188 *pTgt++='}';
2189 *pTgt++=0;
2190
438635e3 2191 AliHLTComponentBlockData bd;
2192 FillBlockData( bd );
2193 bd.fOffset = offset;
abb52c8f 2194 bd.fSize = payloadSize;
438635e3 2195 bd.fDataType = kAliHLTDataTypeComponentTable;
2196 bd.fSpecification = fChainIdCrc;
438635e3 2197 blocks.push_back(bd);
2198 iResult=bd.fSize;
2199 }
bd6cac58 2200#else
2201 if (blocks.size() && buffer && bufferSize && offset && parents.size()) {
2202 // get rid of warning
2203 }
78d29060 2204#endif // HLT_COMPONENT_STATISTICS
a0aeb701 2205 return iResult;
2206}
2207
90ebac25 2208AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
2209 :
2210 fpStopwatch(NULL),
2211 fpPrec(NULL)
2212{
2213 // standard constructor (not for use)
2214}
2215
2216AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
2217 :
2218 fpStopwatch(pStopwatch),
2219 fpPrec(NULL)
2220{
2221 // constructor
2222
2223 // check for already existing guard
2224 if (fgpCurrent) fpPrec=fgpCurrent;
2225 fgpCurrent=this;
2226
2227 // stop the preceeding guard if it controls a different stopwatch
2228 int bStart=1;
2229 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
2230
2231 // start the stopwatch if the current guard controls a different one
2232 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
2233}
2234
e419b223 2235AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 2236 :
2237 fpStopwatch(NULL),
2238 fpPrec(NULL)
2239{
e419b223 2240 //
2241 // copy constructor not for use
2242 //
2243}
2244
2245AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
2246{
2247 //
2248 // assignment operator not for use
2249 //
2250 fpStopwatch=NULL;
2251 fpPrec=NULL;
2252 return *this;
90ebac25 2253}
2254
2255AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
2256
2257AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
2258{
2259 // destructor
2260
2261 // resume the preceeding guard if it controls a different stopwatch
2262 int bStop=1;
2263 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
2264
2265 // stop the stopwatch if the current guard controls a different one
2266 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
2267
2268 // resume to the preceeding guard
2269 fgpCurrent=fpPrec;
2270}
2271
0007ed52 2272int AliHLTComponent::AliHLTStopwatchGuard::Hold(const TStopwatch* pSucc)
90ebac25 2273{
2274 // see header file for function documentation
2275 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
2276 return fpStopwatch!=pSucc?1:0;
2277}
2278
0007ed52 2279int AliHLTComponent::AliHLTStopwatchGuard::Resume(const TStopwatch* pSucc)
90ebac25 2280{
2281 // see header file for function documentation
2282 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
2283 return fpStopwatch!=pSucc?1:0;
2284}
2285
2286int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
2287{
2288 // see header file for function documentation
2289 int iResult=0;
2290 if (pSW!=NULL && type<kSWTypeCount) {
2291 if (fpStopwatches) {
2292 TObject* pObj=fpStopwatches->At((int)type);
2293 if (pSW==NULL // explicit reset
2294 || pObj==NULL) { // explicit set
2295 fpStopwatches->AddAt(pSW, (int)type);
2296 } else if (pObj!=pSW) {
2297 HLTWarning("stopwatch %d already set, reset first", (int)type);
2298 iResult=-EBUSY;
2299 }
2300 }
2301 } else {
2302 iResult=-EINVAL;
2303 }
2304 return iResult;
2305}
2306
2307int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
2308{
2309 // see header file for function documentation
2310 if (pStopwatches==NULL) return -EINVAL;
2311
2312 int iResult=0;
77fd699f 2313 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntriesFast(); i++)
90ebac25 2314 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
2315 return iResult;
2316}
559631d5 2317
2318AliHLTUInt32_t AliHLTComponent::GetRunNo() const
2319{
29312178 2320 // see header file for function documentation
6e289790 2321
2322 // 2010-02-11 OCDB is now the reliable source for the run number, it is
2323 // initialized either by aliroot or the external interface depending
2324 // on the environment. It turned out that the rundescriptor is not set
2325 // in the aliroot mode, resulting in an invalid run number. However this
2326 // did not cause problems until now. OCDB initialization has been revised
2327 // already in 10/2009. This was a remnant.
2328 // Have to check whether we get rid of the rundescriptor at some point.
2329 if (fpRunDesc==NULL) return AliHLTMisc::Instance().GetCDBRunNo();
2330 if (fpRunDesc->fRunNo!=(unsigned)AliHLTMisc::Instance().GetCDBRunNo()) {
2331 HLTWarning("run number mismatch: ocdb %d run descriptor %d", AliHLTMisc::Instance().GetCDBRunNo(), fpRunDesc->fRunNo);
2332 }
559631d5 2333 return fpRunDesc->fRunNo;
2334}
2335
2336AliHLTUInt32_t AliHLTComponent::GetRunType() const
2337{
29312178 2338 // see header file for function documentation
45c0a780 2339 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 2340 return fpRunDesc->fRunType;
2341}
2342
6700298e 2343AliHLTUInt32_t AliHLTComponent::GetTimeStamp() const
2344{
2345 // see header file for function documentation
bee8f777 2346 if (fCurrentEventData.fEventCreation_s) {
2347 return fCurrentEventData.fEventCreation_s;
2348 }
2349 // using the actual UTC if the time stamp was not set by the framework
2350 return static_cast<AliHLTUInt32_t>(time(NULL));
6700298e 2351}
2352
2353AliHLTUInt32_t AliHLTComponent::GetPeriodNumber() const
2354{
2355 // see header file for function documentation
2356 return (GetEventId()>>36)&0xfffffff;
2357}
2358
2359AliHLTUInt32_t AliHLTComponent::GetOrbitNumber() const
2360{
2361 // see header file for function documentation
2362 return (GetEventId()>>12)&0xffffff;
2363}
2364
2365AliHLTUInt16_t AliHLTComponent::GetBunchCrossNumber() const
2366{
2367 // see header file for function documentation
2368 return GetEventId()&0xfff;
2369}
2370
0007ed52 2371bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt) const
48abe484 2372{
2373 // see header file for function documentation
2374 if (pTgt) *pTgt=fEventType;
2375 return (fEventType==gkAliEventTypeData ||
9e14734f 2376 fEventType==gkAliEventTypeDataReplay);
48abe484 2377}
2378
83fec083 2379int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 2380 const char* structname, const char* eventname)
2381{
29312178 2382 // see header file for function documentation
559631d5 2383 int iResult=0;
2384 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
2385 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
2386 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
2387 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 2388 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 2389 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 2390 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 2391 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
2392 }
2393 if (copy!=iStructSize) {
c5123824 2394 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 2395 if (copy>iStructSize) {
2396 copy=iStructSize;
2397 } else {
2398 memset(pTgt, 0, iStructSize);
2399 }
2400 }
3294f81a 2401 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 2402 *pTgt=iStructSize;
2403 iResult=copy;
2404 } else {
2405 HLTWarning("%s event: missing data block", eventname);
2406 }
2407 } else {
2408 iResult=-ENODATA;
2409 }
2410 } else {
2411 HLTError("invalid struct");
2412 iResult=-EINVAL;
2413 }
2414 return iResult;
2415}
ed504011 2416
48abe484 2417AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
2418{
2419 // see header file for function documentation
2420 AliHLTUInt32_t remainder = 0;
2421 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
2422 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
2423 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
2424
2425 // code from
2426 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
2427
2428 /*
2429 * Perform modulo-2 division, a byte at a time.
2430 */
2431 for (int byte = 0; byte < size; ++byte)
2432 {
2433 /*
2434 * Bring the next byte into the remainder.
2435 */
2436 remainder ^= (buffer[byte] << (crcwidth - 8));
2437
2438 /*
2439 * Perform modulo-2 division, a bit at a time.
2440 */
2441 for (uint8_t bit = 8; bit > 0; --bit)
2442 {
2443 /*
2444 * Try to divide the current data bit.
2445 */
2446 if (remainder & topbit)
2447 {
2448 remainder = (remainder << 1) ^ polynomial;
2449 }
2450 else
2451 {
2452 remainder = (remainder << 1);
2453 }
2454 }
2455 }
2456
2457 /*
2458 * The final remainder is the CRC result.
2459 */
2460 return (remainder);
2461}
abb52c8f 2462
2463int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
2464 string& retChainId, string& retCompId, string& retCompArgs,
2465 vector<AliHLTUInt32_t>& parents)
2466{
2467 // see header file for function documentation
2468 retChainId.clear();
2469 retCompId.clear();
2470 retCompArgs.clear();
2471 parents.clear();
2472 if (!pBuffer || size==0) return 0;
2473
2474 const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
2475 if (size<8/* the initial size of the structure*/ ||
2476 pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
2477 const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
2478 const AliHLTUInt8_t* pEnd=pBuffer+size;
2479
2480 if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
2481 for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
2482 parents.push_back(*pParents);
2483 }
2484
2485 const char* pDescription=reinterpret_cast<const char*>(pParents);
2486 if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
2487 *(pDescription+pEntry->fSizeDescription)!=0) {
2488 return -EBADF;
2489 }
2490
2491 TString descriptor=reinterpret_cast<const char*>(pDescription);
2492 TString chainId;
2493 TString compId;
2494 TString compArgs;
2495 TObjArray* pTokens=descriptor.Tokenize("{");
2496 if (pTokens) {
2497 int n=0;
77fd699f 2498 if (pTokens->GetEntriesFast()>n) {
704972af 2499 retChainId=pTokens->At(n++)->GetName();
abb52c8f 2500 }
77fd699f 2501 if (pTokens->GetEntriesFast()>n) {
704972af 2502 compId=pTokens->At(n++)->GetName();
abb52c8f 2503 }
2504 delete pTokens;
2505 }
2506 if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
2507 int n=0;
77fd699f 2508 if (pTokens->GetEntriesFast()>n) {
704972af 2509 compId=pTokens->At(n++)->GetName();
abb52c8f 2510 }
77fd699f 2511 if (pTokens->GetEntriesFast()>n) {
704972af 2512 compArgs=pTokens->At(n++)->GetName();
abb52c8f 2513 }
2514 delete pTokens;
2515 }
2516 compId.ReplaceAll("}", "");
2517 compArgs.ReplaceAll("}", "");
2518
2519 retCompId=compId;
2520 retCompArgs=compArgs;
2521
2522 if (retChainId.size()==0) return -ENODATA;
2523
2524 return 1;
2525}
97d2b87a 2526
89413559 2527int AliHLTComponent::ExtractTriggerData(
2528 const AliHLTComponentTriggerData& trigData,
2529 const AliHLTUInt8_t (**attributes)[gkAliHLTBlockDAttributeCount],
2530 AliHLTUInt64_t* status,
2531 const AliRawDataHeader** cdh,
2532 AliHLTReadoutList* readoutlist,
2533 bool printErrors
2534 )
2535{
2536 // see header file for function documentation
2537
2538 // Check that the trigger data structure is the correct size.
2539 if (trigData.fStructSize != sizeof(AliHLTComponentTriggerData))
2540 {
2541 if (printErrors)
2542 {
2543 AliHLTLogging log;
2544 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2545 "Invalid trigger structure size: %d but expected %d.", trigData.fStructSize, sizeof(AliHLTComponentTriggerData)
2546 );
2547 }
2548 return -ENOENT;
2549 }
2550
e4d966f5 2551 // Get the size of the AliHLTEventTriggerData structure without the readout list part.
2552 // The way we do this here should also handle memory alignment correctly.
2553 AliHLTEventTriggerData* dummy = NULL;
2554 size_t sizeWithoutReadout = (char*)(&dummy->fReadoutList) - (char*)(dummy);
2555
89413559 2556 // Check that the trigger data pointer points to data of a size we can handle.
e4d966f5 2557 // Either it is the size of AliHLTEventTriggerData or the size of the old
2558 // version of AliHLTEventTriggerData using AliHLTEventDDLV0.
89413559 2559 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData) and
e4d966f5 2560 trigData.fDataSize != sizeWithoutReadout + sizeof(AliHLTEventDDLV0)
89413559 2561 )
2562 {
2563 if (printErrors)
2564 {
2565 AliHLTLogging log;
2566 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2567 "Invalid trigger data size: %d but expected %d.", trigData.fDataSize, sizeof(AliHLTEventTriggerData)
2568 );
2569 }
2570 return -EBADF;
2571 }
2572
2573 AliHLTEventTriggerData* evtData = reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
2574 assert(evtData != NULL);
2575
2576 // Check that the CDH has 8 words.
2577 if (cdh != NULL and evtData->fCommonHeaderWordCnt != 8)
2578 {
2579 if (printErrors)
2580 {
2581 AliHLTLogging log;
2582 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2583 "Common Data Header (CDH) has wrong number of data words: %d but expected %d",
2584 evtData->fCommonHeaderWordCnt, sizeof(AliRawDataHeader)/sizeof(AliHLTUInt32_t)
2585 );
2586 }
2587 return -EBADMSG;
2588 }
2589
2590 // Check that the readout list has the correct count of words. i.e. something we can handle,
2591 if (readoutlist != NULL and
2592 evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV0 and
2593 evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV1
2594 )
2595 {
2596 if (printErrors)
2597 {
2598 AliHLTLogging log;
2599 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2600 "Readout list structure has wrong number of data words: %d but expected %d",
2601 evtData->fReadoutList.fCount, gkAliHLTDDLListSize
2602 );
2603 }
2604 return -EPROTO;
2605 }
2606
2607 if (attributes != NULL)
2608 {
2609 *attributes = &evtData->fAttributes;
2610 }
2611 if (status != NULL)
2612 {
2613 *status = evtData->fHLTStatus;
2614 }
2615 if (cdh != NULL)
2616 {
2617 const AliRawDataHeader* cdhptr = reinterpret_cast<const AliRawDataHeader*>(&evtData->fCommonHeader);
2618 *cdh = cdhptr;
2619 }
2620 if (readoutlist != NULL)
2621 {
2622 *readoutlist = AliHLTReadoutList(evtData->fReadoutList);
2623 }
2624 return 0;
2625}
2626
9e14734f 2627AliHLTUInt32_t AliHLTComponent::ExtractEventTypeFromCDH(const AliRawDataHeader* cdh)
2628{
2629 // see header file for function documentation
2630
2631 UChar_t l1msg = cdh->GetL1TriggerMessage();
2632 if ((l1msg & 0x1) == 0x0) return gkAliEventTypeData;
2633 // The L2SwC bit must be one if we got here, i.e. l1msg & 0x1 == 0x1.
2634 if (((l1msg >> 2) & 0xF) == 0xE) return gkAliEventTypeStartOfRun;
2635 if (((l1msg >> 2) & 0xF) == 0xF) return gkAliEventTypeEndOfRun;
2636 // Check the C1T bit to see if this is a calibration event,
2637 // if not then it must be some other software trigger event.
2638 if (((l1msg >> 6) & 0x1) == 0x1) return gkAliEventTypeCalibration;
2639 return gkAliEventTypeSoftware;
2640}
2641
97d2b87a 2642int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity,
2643 const char* originClass, const char* originFunc,
2644 const char* file, int line, ... ) const
2645{
2646 // see header file for function documentation
2647 int iResult=0;
2648
2649 va_list args;
2650 va_start(args, line);
2651
2652 // logging function needs to be const in order to be called from const member functions
2653 // without problems. But at this point we face the problem with virtual members which
2654 // are not necessarily const.
2655 AliHLTComponent* nonconst=const_cast<AliHLTComponent*>(this);
7efb6418 2656 AliHLTLogging::SetLogString(this, ", %p", "%s (%s_pfmt_): ",
97d2b87a 2657 fChainId[0]!=0?fChainId.c_str():nonconst->GetComponentID(),
7efb6418 2658 nonconst->GetComponentID());
97d2b87a 2659 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
2660 va_end(args);
2661
2662 return iResult;
2663}
cf9cf07e 2664
cc095616 2665TUUID AliHLTComponent::GenerateGUID()
2666{
2667 // Generates a globally unique identifier.
2668
2669 // Start by creating a new UUID. We cannot use the one automatically generated
2670 // by ROOT because the algorithm used will not guarantee unique IDs when generating
2671 // these UUIDs at a high rate in parallel.
2672 TUUID uuid;
2673 // We then use the generated UUID to form part of the random number seeds which
2674 // will be used to generate a proper random UUID. For good measure we use a MD5
2675 // hash also. Note that we want to use the TUUID class because it will combine the
2676 // host address information into the UUID. Using gSystem->GetHostByName() apparently
2677 // can cause problems on Windows machines with a firewall, because it always tries
2678 // to contact a DNS. The TUUID class handles this case appropriately.
2679 union
2680 {
2681 UChar_t buf[16];
2682 UShort_t word[8];
2683 UInt_t dword[4];
2684 };
2685 uuid.GetUUID(buf);
2686 TMD5 md5;
2687 md5.Update(buf, sizeof(buf));
2688 TMD5 md52 = md5;
2689 md5.Final(buf);
2690 dword[0] += gSystem->GetUid();
2691 dword[1] += gSystem->GetGid();
2692 dword[2] += gSystem->GetPid();
2693 for (int i = 0; i < 4; ++i)
2694 {
2695 gRandom->SetSeed(dword[i]);
2696 dword[i] = gRandom->Integer(0xFFFFFFFF);
2697 }
2698 md52.Update(buf, sizeof(buf));
2699 md52.Final(buf);
2700 // To keep to the standard we need to set the version and reserved bits.
2701 word[3] = (word[3] & 0x0FFF) | 0x4000;
2702 buf[8] = (buf[8] & 0x3F) | 0x80;
2703
2704 // Create the name of the new class and file.
2705 char uuidstr[64];
2706 sprintf(uuidstr, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2707 dword[0], word[2], word[3], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]
2708 );
2709
2710 uuid.SetUUID(uuidstr);
2711 return uuid;
2712}
2713
cf9cf07e 2714int AliHLTComponent::ScanECSParam(const char* ecsParam)
2715{
2716 // see header file for function documentation
2717
2718 // format of the parameter string from ECS
2719 // <command>;<parameterkey>=<parametervalue>;<parameterkey>=<parametervalue>;...
2720 // search for a subset of the parameterkeys
c4ffab2c 2721 // RUN_TYPE=
2722 // RUN_NUMBER=
2723 // HLT_IN_DDL_LIST=
2724 // CTP_TRIGGER_CLASS=
2725 // DATA_FORMAT_VERSION=
2726 // BEAM_TYPE=
2727 // HLT_OUT_DDL_LIST=
2728 // HLT_TRIGGER_CODE=
2729 // DETECTOR_LIST=
2730 // HLT_MODE=
2731 // The command apears not to be sent by the online framework
cf9cf07e 2732 int iResult=0;
2733 TString string=ecsParam;
2734 TObjArray* parameter=string.Tokenize(";");
2735 if (parameter) {
77fd699f 2736 for (int i=0; i<parameter->GetEntriesFast(); i++) {
704972af 2737 TString entry=parameter->At(i)->GetName();
cf9cf07e 2738 HLTDebug("scanning ECS entry: %s", entry.Data());
2739 TObjArray* entryParams=entry.Tokenize("=");
2740 if (entryParams) {
77fd699f 2741 if (entryParams->GetEntriesFast()>1) {
cf9cf07e 2742 if ((((TObjString*)entryParams->At(0))->GetString()).CompareTo("CTP_TRIGGER_CLASS")==0) {
704972af 2743 int result=InitCTPTriggerClasses(entryParams->At(1)->GetName());
cf9cf07e 2744 if (iResult>=0 && result<0) iResult=result;
2745 } else {
2746 // TODO: scan the other parameters
2747 // e.g. consistency check of run number
2748 }
2749 }
2750 delete entryParams;
2751 }
2752 }
2753 delete parameter;
2754 }
2755
2756 return iResult;
2757}
2758
adb91bc3 2759int AliHLTComponent::SetupCTPData()
cf9cf07e 2760{
2761 // see header file for function documentation
adb91bc3 2762 if (fpCTPData) delete fpCTPData;
2763 fpCTPData=new AliHLTCTPData;
2764 if (!fpCTPData) return -ENOMEM;
cf9cf07e 2765 return 0;
2766}
2767
adb91bc3 2768int AliHLTComponent::InitCTPTriggerClasses(const char* ctpString)
cf9cf07e 2769{
2770 // see header file for function documentation
adb91bc3 2771 if (!fpCTPData) return 0; // silently accept as the component has to announce that it want's the CTP info
2772 return fpCTPData->InitCTPTriggerClasses(ctpString);
2773}
cf9cf07e 2774
adb91bc3 2775bool AliHLTComponent::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
2776{
2777 // see header file for function documentation
2778 if (!fpCTPData) {
2779 static bool bWarningThrown=false;
2780 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2781 bWarningThrown=true;
cf9cf07e 2782 return false;
2783 }
2784
adb91bc3 2785 return fpCTPData->EvaluateCTPTriggerClass(expression, trigData);
cf9cf07e 2786}
a5e775ec 2787
3fcb48b8 2788int AliHLTComponent::CheckCTPTrigger(const char* name) const
2789{
2790 // see header file for function documentation
2791 if (!fpCTPData) {
2792 static bool bWarningThrown=false;
2793 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2794 bWarningThrown=true;
2795 return false;
2796 }
2797
2798 return fpCTPData->CheckTrigger(name);
2799}
2800
a5e775ec 2801Double_t AliHLTComponent::GetBz()
2802{
2803 // Returns Bz.
2804 return AliHLTMisc::Instance().GetBz();
2805}
2806
2807Double_t AliHLTComponent::GetBz(const Double_t *r)
2808{
2809 // Returns Bz (kG) at the point "r" .
2810 return AliHLTMisc::Instance().GetBz(r);
2811}
2812
2813void AliHLTComponent::GetBxByBz(const Double_t r[3], Double_t b[3])
2814{
2815 // Returns Bx, By and Bz (kG) at the point "r" .
2816 AliHLTMisc::Instance().GetBxByBz(r, b);
2817}