Bug fix for missing DCS update data block.
[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 }
262 if (iResult>=0) {
5ef2a37b 263 iResult=CheckOCDBEntries();
264 }
265 if (iResult>=0) {
8451168b 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;
499 }
58f0fd47 500 }
501 }
58f0fd47 502 }
503 delete pTokensQuote;
504 }
02bc7a5f 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 );
bd2a51b0 699 strncat( output, ":", 1 );
9ce4bf4a 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
ebdd604d 1396int AliHLTComponent::PushBack(const TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
79c114b5 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
ebdd604d 1448int AliHLTComponent::PushBack(const TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
79c114b5 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
ebdd604d 1533int AliHLTComponent::EstimateObjectSize(const TObject* pObject) const
8451168b 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 }
bd2a51b0 1705 else if (fEventDoneData) {
eafbc306 1706 memcpy( reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize, edd.fData, edd.fDataSize );
1707 fEventDoneData->fDataSize += edd.fDataSize;
1708 }
bd2a51b0 1709 else {
1710 HLTError("internal mismatch, fEventDoneData=%d but buffer is NULL", fEventDoneDataSize);
1711 iResult=-EFAULT;
1712 }
a655eae3 1713 return iResult;
1714}
1715
0622a0f3 1716namespace
1717{
1718 // helper function for std:sort, implements an operator<
1719 bool SortComponentStatisticsById(const AliHLTComponentStatistics& a, const AliHLTComponentStatistics& b)
1720 {
1721 return a.fId<b.fId;
1722 }
1723
1724 // helper function for std:sort
1725 bool SortComponentStatisticsDescendingByLevel(const AliHLTComponentStatistics& a, const AliHLTComponentStatistics& b)
1726 {
1727 return a.fId>b.fId;
1728 }
1729
1730 // helper class to define operator== between AliHLTComponentStatistics and AliHLTComponentStatistics.fId
1731 class AliHLTComponentStatisticsId {
1732 public:
1733 AliHLTComponentStatisticsId(AliHLTUInt32_t id) : fId(id) {}
f308715b 1734 AliHLTComponentStatisticsId(const AliHLTComponentStatisticsId& src) : fId(src.fId) {}
0622a0f3 1735 bool operator==(const AliHLTComponentStatistics& a) const {return a.fId==fId;}
1736 private:
1737 AliHLTComponentStatisticsId();
0622a0f3 1738 AliHLTUInt32_t fId;
1739 };
1740
1741 // operator for std::find of AliHLTComponentStatistics by id
1742 bool operator==(const AliHLTComponentStatistics& a, const AliHLTComponentStatisticsId& b)
1743 {
1744 return b==a;
1745 }
1746
1747 bool AliHLTComponentStatisticsCompareIds(const AliHLTComponentStatistics& a, const AliHLTComponentStatistics& b)
1748 {
1749 return a.fId==b.fId;
1750 }
1751
1752 // helper class to define operator== between AliHLTComponentBlockData and AliHLTComponentBlockData.fSpecification
1753 class AliHLTComponentBlockDataSpecification {
1754 public:
1755 AliHLTComponentBlockDataSpecification(AliHLTUInt32_t specification) : fSpecification(specification) {}
f308715b 1756 AliHLTComponentBlockDataSpecification(const AliHLTComponentBlockDataSpecification& src) : fSpecification(src.fSpecification) {}
0622a0f3 1757 bool operator==(const AliHLTComponentBlockData& bd) const {return bd.fSpecification==fSpecification;}
1758 private:
1759 AliHLTComponentBlockDataSpecification();
0622a0f3 1760 AliHLTUInt32_t fSpecification;
1761 };
1762
1763 // operator for std::find of AliHLTComponentBlockData by specification
1764 bool operator==(const AliHLTComponentBlockData& bd, const AliHLTComponentBlockDataSpecification& spec)
1765 {
1766 return spec==bd;
1767 }
1768
1769 // operator for std::find
1770 bool operator==(const AliHLTComponentBlockData& a, const AliHLTComponentBlockData& b)
1771 {
1772 if (!MatchExactly(a.fDataType,b.fDataType)) return false;
1773 return a.fSpecification==b.fSpecification;
1774 }
1775
1776} // end of namespace
1777
3cde846d 1778int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1779 const AliHLTComponentBlockData* blocks,
1780 AliHLTComponentTriggerData& trigData,
1781 AliHLTUInt8_t* outputPtr,
1782 AliHLTUInt32_t& size,
1783 AliHLTUInt32_t& outputBlockCnt,
1784 AliHLTComponentBlockData*& outputBlocks,
1785 AliHLTComponentEventDoneData*& edd )
1786{
70ed7d01 1787 // see header file for function documentation
66108417 1788 HLTLogKeyword(fChainId.c_str());
90ebac25 1789 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1790 int iResult=0;
1791 fCurrentEvent=evtData.fEventID;
a655eae3 1792 fCurrentEventData=evtData;
1793 fpInputBlocks=blocks;
1794 fCurrentInputBlock=-1;
1795 fSearchDataType=kAliHLTAnyDataType;
1796 fpOutputBuffer=outputPtr;
1797 fOutputBufferSize=size;
1798 fOutputBufferFilled=0;
1799 fOutputBlocks.clear();
96f9673a 1800 outputBlockCnt=0;
1801 outputBlocks=NULL;
438635e3 1802
1803 AliHLTComponentBlockDataList forwardedBlocks;
1804
1805 // optional component statistics
a0aeb701 1806 AliHLTComponentStatisticsList compStats;
438635e3 1807 bool bAddComponentTableEntry=false;
abb52c8f 1808 vector<AliHLTUInt32_t> parentComponentTables;
0622a0f3 1809 int processingLevel=-1;
78d29060 1810#if defined(HLT_COMPONENT_STATISTICS)
1811 if ((fFlags&kDisableComponentStat)==0) {
1812 AliHLTComponentStatistics outputStat;
1813 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
1814 outputStat.fStructSize=sizeof(AliHLTComponentStatistics);
1815 outputStat.fId=fChainIdCrc;
1816 if (fpBenchmark) {
1817 fpBenchmark->Stop();
1818 outputStat.fComponentCycleTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1819 fpBenchmark->Reset();
1820 fpBenchmark->Start();
1821 }
1822 compStats.push_back(outputStat);
a0aeb701 1823 }
78d29060 1824#endif // HLT_COMPONENT_STATISTICS
559631d5 1825
48abe484 1826 // data processing is skipped
1827 // - if there are only steering events in the block list.
1828 // For the sake of data source components data processing
1829 // is not skipped if there is no block list at all or if it
1830 // just contains the eventType block
1831 // - always skipped if the event is of type
1832 // - gkAliEventTypeConfiguration
1833 // - gkAliEventTypeReadPreprocessor
45c0a780 1834 const unsigned int skipModeDefault=0x1;
1835 const unsigned int skipModeForce=0x2;
1836 unsigned int bSkipDataProcessing=skipModeDefault;
1837
559631d5 1838 // find special events
45c0a780 1839 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1840 // first look for all special events and execute in the appropriate
1841 // sequence afterwords
1842 int indexComConfEvent=-1;
b543e186 1843 int indexUpdtDCSEvent=-1;
579d9eb7 1844 int indexSOREvent=-1;
1845 int indexEOREvent=-1;
cf9cf07e 1846 int indexECSParamBlock=-1;
83fec083 1847 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1848 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1849 indexSOREvent=i;
45c0a780 1850 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1851 bSkipDataProcessing&=~skipModeDefault;
1852 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1853 // run type string
1854 // handling is not clear yet
1855 if (fpInputBlocks[i].fPtr) {
1856 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1857 }
579d9eb7 1858 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1859 indexEOREvent=i;
45c0a780 1860 // the calibration processor relies on the SOR and EOR events
1861 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1862 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1863 // DDL list
1864 // this event is most likely deprecated
1865 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1866 indexComConfEvent=i;
b543e186 1867 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1868 indexUpdtDCSEvent=i;
1869 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1870 fEventType=fpInputBlocks[i].fSpecification;
9e14734f 1871 if (fEventType != gkAliEventTypeConfiguration and
1872 fEventType != gkAliEventTypeReadPreprocessor
1873 )
1874 {
1875 // We can actually get the event type from the CDH if it is valid.
1876 // Otherwise just use the specification of the input block.
1877 const AliRawDataHeader* cdh;
1878 if (ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL) == 0)
1879 {
1880 fEventType = ExtractEventTypeFromCDH(cdh);
1881 }
1882 }
48abe484 1883
1884 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1885 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1886
1887 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1888 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1889
1890 // never skip if the event type block is the only block
1891 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1892
a0aeb701 1893 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1894 if (compStats.size()>0) {
1895 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1896 for (AliHLTUInt32_t offset=0;
1897 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1898 offset+=sizeof(AliHLTComponentStatistics)) {
1899 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1900 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1901 compStats[0].fLevel=pStat->fLevel+1;
1902 }
0622a0f3 1903 if (find(compStats.begin(), compStats.end(), AliHLTComponentStatisticsId(pStat->fId))==compStats.end()) {
1904 compStats.push_back(*pStat);
1905 }
a0aeb701 1906 }
1907 }
438635e3 1908 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
0622a0f3 1909 AliHLTComponentBlockDataList::iterator element=forwardedBlocks.begin();
1910 while ((element=find(element, forwardedBlocks.end(), AliHLTComponentBlockDataSpecification(fpInputBlocks[i].fSpecification)))!=forwardedBlocks.end()) {
1911 if (element->fDataType==fpInputBlocks[i].fDataType) break;
1912 // TODO: think about some more checks inclusing also the actual data buffers
1913 // this has to handle multiplicity>1 in the online system, where all components
1914 // send the information on SOR, because this event is broadcasted
1915 }
1916 if (element==forwardedBlocks.end()) {
1917 forwardedBlocks.push_back(fpInputBlocks[i]);
1918 }
abb52c8f 1919 parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
0622a0f3 1920 if (fpInputBlocks[i].fSize>=sizeof(AliHLTComponentTableEntry)) {
1921 const AliHLTComponentTableEntry* entry=reinterpret_cast<AliHLTComponentTableEntry*>(fpInputBlocks[i].fPtr);
1922 if (entry->fStructSize==sizeof(AliHLTComponentTableEntry)) {
1923 if (processingLevel<0 || processingLevel<=(int)entry->fLevel)
1924 processingLevel=entry->fLevel+1;
1925 }
1926 }
cf9cf07e 1927 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeECSParam) {
1928 indexECSParamBlock=i;
45c0a780 1929 } else {
1930 // the processing function is called if there is at least one
1931 // non-steering data block. Steering blocks are not filtered out
1932 // for sake of performance
1933 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1934 if (compStats.size()>0) {
1935 compStats[0].fInputBlockCount++;
1936 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1937 }
579d9eb7 1938 }
1939 }
45c0a780 1940
579d9eb7 1941 if (indexSOREvent>=0) {
1942 // start of run
438635e3 1943 bAddComponentTableEntry=true;
0622a0f3 1944 compStats.clear(); // no component statistics for SOR
579d9eb7 1945 if (fpRunDesc==NULL) {
1946 fpRunDesc=new AliHLTRunDesc;
48abe484 1947 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1948 }
1949 if (fpRunDesc) {
1950 AliHLTRunDesc rundesc;
1951 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1952 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1953 *fpRunDesc=rundesc;
579d9eb7 1954 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1955 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1956 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1957 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1958 }
559631d5 1959 }
579d9eb7 1960 } else {
45c0a780 1961 iResult=-ENOMEM;
579d9eb7 1962 }
cf9cf07e 1963
1964 if (indexECSParamBlock>=0) {
1965 if (fpInputBlocks[indexECSParamBlock].fSize>0) {
1966 const char* param=reinterpret_cast<const char*>(fpInputBlocks[indexECSParamBlock].fPtr);
1967 TString paramString;
1968 if (param[fpInputBlocks[indexECSParamBlock].fSize-1]!=0) {
1969 HLTWarning("ECS parameter string not terminated");
1970 paramString.Insert(0, param, fpInputBlocks[indexECSParamBlock].fSize);
1971 paramString+="";
1972 } else {
1973 paramString=param;
1974 }
1975 ScanECSParam(paramString.Data());
1976 } else {
1977 HLTWarning("empty ECS parameter received");
1978 }
1979 } else {
1980 // TODO: later on we might throw a warning here since the CTP trigger classes
1981 // should be mandatory
1982 }
579d9eb7 1983 }
1984 if (indexEOREvent>=0) {
9d4d4b02 1985 fLastPushBackTime=0; // always send at EOR
438635e3 1986 bAddComponentTableEntry=true;
0622a0f3 1987 compStats.clear(); // no component statistics for EOR
579d9eb7 1988 if (fpRunDesc!=NULL) {
1989 if (fpRunDesc) {
1990 AliHLTRunDesc rundesc;
1991 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1992 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 1993 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 1994 } else {
1995 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 1996 }
559631d5 1997 }
bee8f777 1998 // we do not unload the fpRunDesc struct here in order to have the run information
1999 // available during the event processing
2000 // https://savannah.cern.ch/bugs/?39711
2001 // the info will be cleared in DeInit
559631d5 2002 }
579d9eb7 2003 } else {
2004 HLTWarning("did not receive SOR, ignoring EOR");
2005 }
2006 }
48abe484 2007 if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
579d9eb7 2008 TString cdbEntry;
b543e186 2009 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 2010 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
2011 }
2012 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
2013 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
2014 if (tmpResult<0) {
2015 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 2016 }
2017 }
48abe484 2018 if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
b543e186 2019 TString modules;
fd778a50 2020 if (indexUpdtDCSEvent>=0 && fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
b543e186 2021 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
2022 }
d6b69874 2023 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
2024 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 2025 if (tmpResult<0) {
2026 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
2027 }
2028 }
45c0a780 2029 } else {
2030 // processing function needs to be called if there are no input data
2031 // blocks in order to make data source components working.
2032 bSkipDataProcessing&=~skipModeDefault;
559631d5 2033 }
a0aeb701 2034
2035 // data processing is not skipped if the component explicitly asks
2036 // for the private blocks
78d29060 2037 if ((fFlags&kRequireSteeringBlocks)!=0) bSkipDataProcessing=0;
a0aeb701 2038
0622a0f3 2039 // data processing is not skipped for data sources
2040 if (GetComponentType()==AliHLTComponent::kSource) bSkipDataProcessing=0;
2041
edd72347 2042 if (fpCTPData) {
2043 // set the active triggers for this event
2044 fpCTPData->SetTriggers(trigData);
2045 // increment CTP trigger counters if available
2046 if (IsDataEvent()) fpCTPData->Increment(trigData);
2047 }
adb91bc3 2048
2be3f004 2049 AliHLTComponentBlockDataList blockData;
45c0a780 2050 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 2051 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 2052 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
2053 // in order to avoid 'shadowed variable' warning
2054 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
90ebac25 2055 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
2056 } // end of the scope of the stopwatch guard
b543e186 2057 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 2058 if (fOutputBlocks.size()>0) {
df61f928 2059 // High Level interface
2060
2061 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 2062 // sync memory files and descriptors
2be3f004 2063 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 2064 int i=0;
2065 while (element!=fMemFiles.end() && iResult>=0) {
2066 if (*element) {
2067 if ((*element)->IsClosed()==0) {
2068 HLTWarning("memory file has not been closed, force flush");
2069 iResult=CloseMemoryFile(*element);
2070 }
2071 }
2072 element++; i++;
2073 }
2074
2075 if (iResult>=0) {
2076 // create the descriptor list
2077 if (blockData.size()>0) {
2078 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
2079 iResult=-EFAULT;
2080 } else {
abb52c8f 2081 if (compStats.size()>0 && IsDataEvent()) {
a0aeb701 2082 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
2083 if (offset>0) fOutputBufferFilled+=offset;
2084 }
438635e3 2085 if (bAddComponentTableEntry) {
0622a0f3 2086 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables, processingLevel);
438635e3 2087 if (offset>0) size+=offset;
2088 }
2089 if (forwardedBlocks.size()>0) {
2090 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
2091 }
79c114b5 2092 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
2093 size=fOutputBufferFilled;
2094 }
a655eae3 2095 }
2096 } else {
df61f928 2097 // Low Level interface
0622a0f3 2098 if (blockData.empty() && size!=0) {
2099 // set the size to zero because there is no announced data
2100 //HLTWarning("no output blocks added by component but output buffer filled %d of %d", size, fOutputBufferSize);
2101 size=0;
2102 }
2103
a0aeb701 2104 if (compStats.size()>0) {
2105 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
2106 if (offset>0) size+=offset;
2107 }
438635e3 2108 if (bAddComponentTableEntry) {
0622a0f3 2109 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables, processingLevel);
438635e3 2110 if (offset>0) size+=offset;
2111 }
2112 if (forwardedBlocks.size()>0) {
2113 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
2114 }
a655eae3 2115 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
2116 }
2117 if (iResult<0) {
2118 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
2119 }
2120 }
b543e186 2121 if (iResult<0 || bSkipDataProcessing) {
a655eae3 2122 outputBlockCnt=0;
2123 outputBlocks=NULL;
2124 }
8451168b 2125 CleanupInputObjects();
48abe484 2126 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 2127 IncrementEventCounter();
2128 }
96f9673a 2129 if (outputBlockCnt==0) {
2130 // no output blocks, set size to 0
2131 size=0;
2132 }
6f4231a1 2133
2134 // reset the internal EventData struct
4646c6e3 2135 FillEventData(fCurrentEventData);
edd72347 2136
2137 // reset the active triggers
2138 if (fpCTPData) fpCTPData->SetTriggers(0);
9d4d4b02 2139
2140 // set the time for the pushback period
2141 if (fPushbackPeriod>0) {
2142 // suppress the output
2143 TDatime time;
ebdd604d 2144 if (fLastPushBackTime<0) {
2145 // choose a random offset at beginning to equalize traffic for multiple instances
2146 // of the component
2147 gRandom->SetSeed(fChainIdCrc);
2148 fLastPushBackTime=time.Get();
2149 fLastPushBackTime-=gRandom->Integer(fPushbackPeriod);
2150 } else if ((int)time.Get()-fLastPushBackTime>=fPushbackPeriod) {
9d4d4b02 2151 fLastPushBackTime=time.Get();
2152 }
2153 }
2154
3cde846d 2155 return iResult;
2156}
a655eae3 2157
a0aeb701 2158int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
2159 AliHLTUInt8_t* buffer,
2160 AliHLTUInt32_t bufferSize,
2161 AliHLTUInt32_t offset,
2162 AliHLTComponentStatisticsList& stats) const
2163{
2164 // see header file for function documentation
2165 int iResult=0;
78d29060 2166 if ((fFlags&kDisableComponentStat)!=0) return 0;
2167#if defined(HLT_COMPONENT_STATISTICS)
a0aeb701 2168 if (stats.size()==0) return -ENOENT;
ae962989 2169 // check if there is space for at least one entry
2170 if (offset+sizeof(AliHLTComponentStatistics)>bufferSize) return 0;
a0aeb701 2171 stats[0].fTotalOutputSize=offset;
2172 stats[0].fOutputBlockCount=blocks.size();
2173 if (fpBenchmark) {
2e3fd14f 2174 fpBenchmark->Stop();
2175 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
2176 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
2177 fpBenchmark->Continue();
a0aeb701 2178 }
0622a0f3 2179
2180 sort(stats.begin(), stats.end(), SortComponentStatisticsDescendingByLevel);
2181
2182 // shrink the number of entries if the buffer is too small
ae962989 2183 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize) {
0622a0f3 2184 unsigned originalSize=stats.size();
ae962989 2185 AliHLTUInt32_t removedLevel=0;
2186 do {
2187 // remove all entries of the level of the last entry
2188 removedLevel=stats.back().fLevel;
2189 AliHLTComponentStatisticsList::iterator element=stats.begin();
2190 element++;
2191 while (element!=stats.end()) {
2192 if (element->fLevel<=removedLevel) {
2193 element=stats.erase(element);
2194 } else {
2195 element++;
2196 }
2197 }
2198 } while (stats.size()>1 &&
2199 (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize));
0622a0f3 2200 HLTWarning("too little space in output buffer to add block of %d statistics entries (size %d), available %d, removed %d entries",
2201 originalSize, sizeof(AliHLTComponentStatistics), bufferSize-offset, originalSize-stats.size());
2202 } else {
2203 HLTDebug("adding block of %d statistics entries", stats.size());
ae962989 2204 }
2205 assert(stats.size()>0);
2206 if (stats.size()==0) return 0;
2207
a0aeb701 2208 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
2209 AliHLTComponentBlockData bd;
2210 FillBlockData( bd );
2211 bd.fOffset = offset;
2212 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
2213 bd.fDataType = kAliHLTDataTypeComponentStatistics;
0622a0f3 2214 bd.fSpecification = fChainIdCrc;
a0aeb701 2215 memcpy(buffer+offset, &(stats[0]), bd.fSize);
2216 blocks.push_back(bd);
2217 iResult=bd.fSize;
2218 }
bd6cac58 2219#else
2220 if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
2221 // get rid of warning
2222 }
78d29060 2223#endif // HLT_COMPONENT_STATISTICS
438635e3 2224 return iResult;
2225}
2226
2227int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
2228 AliHLTUInt8_t* buffer,
2229 AliHLTUInt32_t bufferSize,
abb52c8f 2230 AliHLTUInt32_t offset,
0622a0f3 2231 const vector<AliHLTUInt32_t>& parents,
2232 int processingLevel) const
438635e3 2233{
2234 // see header file for function documentation
2235 int iResult=0;
78d29060 2236 if ((fFlags&kDisableComponentStat)!=0) return 0;
2237#if defined(HLT_COMPONENT_STATISTICS)
abb52c8f 2238 // the payload consists of the AliHLTComponentTableEntry struct,
2239 // followed by a an array of 32bit crc chain ids and the component
2240 // description string
2241 unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
2242 payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
2243
2244 // the component description has the following format:
2245 // chain-id{component-id:arguments}
2246 const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
2247 unsigned int descriptionSize=fChainId.size()+1;
2248 descriptionSize+=2; // the '{}' around the component id
2249 descriptionSize+=strlen(componentId);
2250 descriptionSize+=1; // the ':' between component id and arguments
2251 descriptionSize+=fComponentArgs.size();
2252
2253 payloadSize+=descriptionSize;
2254 if (buffer && (offset+payloadSize<=bufferSize)) {
2255 AliHLTUInt8_t* pTgt=buffer+offset;
2256 memset(pTgt, 0, payloadSize);
2257
2258 // write entry
2259 AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
2260 pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
0622a0f3 2261 pEntry->fLevel=processingLevel>=0?processingLevel:0;
abb52c8f 2262 pEntry->fNofParents=parents.size();
2263 pEntry->fSizeDescription=descriptionSize;
2264 pTgt=pEntry->fBuffer;
2265
2266 // write array of parents
2267 if (parents.size()>0) {
2268 unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
2269 memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
2270 pTgt+=copy;
2271 }
2272
2273 // write component description
2274 memcpy(pTgt, fChainId.c_str(), fChainId.size());
2275 pTgt+=fChainId.size();
2276 *pTgt++='{';
2277 memcpy(pTgt, componentId, strlen(componentId));
2278 pTgt+=strlen(componentId);
2279 *pTgt++=':';
2280 memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
2281 pTgt+=fComponentArgs.size();
2282 *pTgt++='}';
2283 *pTgt++=0;
2284
438635e3 2285 AliHLTComponentBlockData bd;
2286 FillBlockData( bd );
2287 bd.fOffset = offset;
abb52c8f 2288 bd.fSize = payloadSize;
438635e3 2289 bd.fDataType = kAliHLTDataTypeComponentTable;
2290 bd.fSpecification = fChainIdCrc;
438635e3 2291 blocks.push_back(bd);
2292 iResult=bd.fSize;
2293 }
bd6cac58 2294#else
0622a0f3 2295 if (blocks.size() && buffer && bufferSize && offset && parents.size() && processingLevel) {
bd6cac58 2296 // get rid of warning
2297 }
78d29060 2298#endif // HLT_COMPONENT_STATISTICS
a0aeb701 2299 return iResult;
2300}
2301
90ebac25 2302AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
2303 :
2304 fpStopwatch(NULL),
2305 fpPrec(NULL)
2306{
2307 // standard constructor (not for use)
2308}
2309
2310AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
2311 :
2312 fpStopwatch(pStopwatch),
2313 fpPrec(NULL)
2314{
2315 // constructor
2316
2317 // check for already existing guard
2318 if (fgpCurrent) fpPrec=fgpCurrent;
2319 fgpCurrent=this;
2320
2321 // stop the preceeding guard if it controls a different stopwatch
2322 int bStart=1;
2323 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
2324
2325 // start the stopwatch if the current guard controls a different one
2326 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
2327}
2328
e419b223 2329AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 2330 :
2331 fpStopwatch(NULL),
2332 fpPrec(NULL)
2333{
e419b223 2334 //
2335 // copy constructor not for use
2336 //
2337}
2338
2339AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
2340{
2341 //
2342 // assignment operator not for use
2343 //
2344 fpStopwatch=NULL;
2345 fpPrec=NULL;
2346 return *this;
90ebac25 2347}
2348
2349AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
2350
2351AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
2352{
2353 // destructor
2354
2355 // resume the preceeding guard if it controls a different stopwatch
2356 int bStop=1;
2357 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
2358
2359 // stop the stopwatch if the current guard controls a different one
2360 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
2361
2362 // resume to the preceeding guard
2363 fgpCurrent=fpPrec;
2364}
2365
0007ed52 2366int AliHLTComponent::AliHLTStopwatchGuard::Hold(const TStopwatch* pSucc)
90ebac25 2367{
2368 // see header file for function documentation
2369 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
2370 return fpStopwatch!=pSucc?1:0;
2371}
2372
0007ed52 2373int AliHLTComponent::AliHLTStopwatchGuard::Resume(const TStopwatch* pSucc)
90ebac25 2374{
2375 // see header file for function documentation
2376 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
2377 return fpStopwatch!=pSucc?1:0;
2378}
2379
2380int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
2381{
2382 // see header file for function documentation
2383 int iResult=0;
2384 if (pSW!=NULL && type<kSWTypeCount) {
2385 if (fpStopwatches) {
2386 TObject* pObj=fpStopwatches->At((int)type);
2387 if (pSW==NULL // explicit reset
2388 || pObj==NULL) { // explicit set
2389 fpStopwatches->AddAt(pSW, (int)type);
2390 } else if (pObj!=pSW) {
2391 HLTWarning("stopwatch %d already set, reset first", (int)type);
2392 iResult=-EBUSY;
2393 }
2394 }
2395 } else {
2396 iResult=-EINVAL;
2397 }
2398 return iResult;
2399}
2400
2401int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
2402{
2403 // see header file for function documentation
2404 if (pStopwatches==NULL) return -EINVAL;
2405
2406 int iResult=0;
77fd699f 2407 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntriesFast(); i++)
90ebac25 2408 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
2409 return iResult;
2410}
559631d5 2411
2412AliHLTUInt32_t AliHLTComponent::GetRunNo() const
2413{
29312178 2414 // see header file for function documentation
6e289790 2415
2416 // 2010-02-11 OCDB is now the reliable source for the run number, it is
2417 // initialized either by aliroot or the external interface depending
2418 // on the environment. It turned out that the rundescriptor is not set
2419 // in the aliroot mode, resulting in an invalid run number. However this
2420 // did not cause problems until now. OCDB initialization has been revised
2421 // already in 10/2009. This was a remnant.
2422 // Have to check whether we get rid of the rundescriptor at some point.
2423 if (fpRunDesc==NULL) return AliHLTMisc::Instance().GetCDBRunNo();
2424 if (fpRunDesc->fRunNo!=(unsigned)AliHLTMisc::Instance().GetCDBRunNo()) {
2425 HLTWarning("run number mismatch: ocdb %d run descriptor %d", AliHLTMisc::Instance().GetCDBRunNo(), fpRunDesc->fRunNo);
2426 }
559631d5 2427 return fpRunDesc->fRunNo;
2428}
2429
2430AliHLTUInt32_t AliHLTComponent::GetRunType() const
2431{
29312178 2432 // see header file for function documentation
45c0a780 2433 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 2434 return fpRunDesc->fRunType;
2435}
2436
6700298e 2437AliHLTUInt32_t AliHLTComponent::GetTimeStamp() const
2438{
2439 // see header file for function documentation
bee8f777 2440 if (fCurrentEventData.fEventCreation_s) {
2441 return fCurrentEventData.fEventCreation_s;
2442 }
2443 // using the actual UTC if the time stamp was not set by the framework
2444 return static_cast<AliHLTUInt32_t>(time(NULL));
6700298e 2445}
2446
2447AliHLTUInt32_t AliHLTComponent::GetPeriodNumber() const
2448{
2449 // see header file for function documentation
2450 return (GetEventId()>>36)&0xfffffff;
2451}
2452
2453AliHLTUInt32_t AliHLTComponent::GetOrbitNumber() const
2454{
2455 // see header file for function documentation
2456 return (GetEventId()>>12)&0xffffff;
2457}
2458
2459AliHLTUInt16_t AliHLTComponent::GetBunchCrossNumber() const
2460{
2461 // see header file for function documentation
2462 return GetEventId()&0xfff;
2463}
2464
0007ed52 2465bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt) const
48abe484 2466{
2467 // see header file for function documentation
2468 if (pTgt) *pTgt=fEventType;
2469 return (fEventType==gkAliEventTypeData ||
9e14734f 2470 fEventType==gkAliEventTypeDataReplay);
48abe484 2471}
2472
83fec083 2473int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 2474 const char* structname, const char* eventname)
2475{
29312178 2476 // see header file for function documentation
559631d5 2477 int iResult=0;
2478 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
2479 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
2480 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
2481 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 2482 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 2483 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 2484 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 2485 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
2486 }
2487 if (copy!=iStructSize) {
c5123824 2488 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 2489 if (copy>iStructSize) {
2490 copy=iStructSize;
2491 } else {
2492 memset(pTgt, 0, iStructSize);
2493 }
2494 }
3294f81a 2495 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 2496 *pTgt=iStructSize;
2497 iResult=copy;
2498 } else {
2499 HLTWarning("%s event: missing data block", eventname);
2500 }
2501 } else {
2502 iResult=-ENODATA;
2503 }
2504 } else {
2505 HLTError("invalid struct");
2506 iResult=-EINVAL;
2507 }
2508 return iResult;
2509}
ed504011 2510
48abe484 2511AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
2512{
2513 // see header file for function documentation
2514 AliHLTUInt32_t remainder = 0;
2515 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
2516 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
2517 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
2518
2519 // code from
2520 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
2521
2522 /*
2523 * Perform modulo-2 division, a byte at a time.
2524 */
2525 for (int byte = 0; byte < size; ++byte)
2526 {
2527 /*
2528 * Bring the next byte into the remainder.
2529 */
2530 remainder ^= (buffer[byte] << (crcwidth - 8));
2531
2532 /*
2533 * Perform modulo-2 division, a bit at a time.
2534 */
2535 for (uint8_t bit = 8; bit > 0; --bit)
2536 {
2537 /*
2538 * Try to divide the current data bit.
2539 */
2540 if (remainder & topbit)
2541 {
2542 remainder = (remainder << 1) ^ polynomial;
2543 }
2544 else
2545 {
2546 remainder = (remainder << 1);
2547 }
2548 }
2549 }
2550
2551 /*
2552 * The final remainder is the CRC result.
2553 */
2554 return (remainder);
2555}
abb52c8f 2556
2557int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
2558 string& retChainId, string& retCompId, string& retCompArgs,
0622a0f3 2559 vector<AliHLTUInt32_t>& parents, int& level)
abb52c8f 2560{
2561 // see header file for function documentation
2562 retChainId.clear();
2563 retCompId.clear();
2564 retCompArgs.clear();
2565 parents.clear();
0622a0f3 2566 level=-1;
abb52c8f 2567 if (!pBuffer || size==0) return 0;
2568
2569 const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
2570 if (size<8/* the initial size of the structure*/ ||
2571 pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
0622a0f3 2572
2573 if (pEntry->fStructSize!=sizeof(AliHLTComponentTableEntry)) return -EBADF;
2574 level=pEntry->fLevel;
abb52c8f 2575 const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
2576 const AliHLTUInt8_t* pEnd=pBuffer+size;
2577
2578 if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
2579 for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
2580 parents.push_back(*pParents);
2581 }
2582
2583 const char* pDescription=reinterpret_cast<const char*>(pParents);
2584 if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
2585 *(pDescription+pEntry->fSizeDescription)!=0) {
2586 return -EBADF;
2587 }
2588
2589 TString descriptor=reinterpret_cast<const char*>(pDescription);
2590 TString chainId;
2591 TString compId;
2592 TString compArgs;
2593 TObjArray* pTokens=descriptor.Tokenize("{");
2594 if (pTokens) {
2595 int n=0;
77fd699f 2596 if (pTokens->GetEntriesFast()>n) {
704972af 2597 retChainId=pTokens->At(n++)->GetName();
abb52c8f 2598 }
77fd699f 2599 if (pTokens->GetEntriesFast()>n) {
704972af 2600 compId=pTokens->At(n++)->GetName();
abb52c8f 2601 }
2602 delete pTokens;
2603 }
2604 if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
2605 int n=0;
77fd699f 2606 if (pTokens->GetEntriesFast()>n) {
704972af 2607 compId=pTokens->At(n++)->GetName();
abb52c8f 2608 }
77fd699f 2609 if (pTokens->GetEntriesFast()>n) {
704972af 2610 compArgs=pTokens->At(n++)->GetName();
abb52c8f 2611 }
2612 delete pTokens;
2613 }
2614 compId.ReplaceAll("}", "");
2615 compArgs.ReplaceAll("}", "");
2616
2617 retCompId=compId;
2618 retCompArgs=compArgs;
2619
2620 if (retChainId.size()==0) return -ENODATA;
2621
2622 return 1;
2623}
97d2b87a 2624
89413559 2625int AliHLTComponent::ExtractTriggerData(
2626 const AliHLTComponentTriggerData& trigData,
2627 const AliHLTUInt8_t (**attributes)[gkAliHLTBlockDAttributeCount],
2628 AliHLTUInt64_t* status,
2629 const AliRawDataHeader** cdh,
2630 AliHLTReadoutList* readoutlist,
2631 bool printErrors
2632 )
2633{
2634 // see header file for function documentation
2635
2636 // Check that the trigger data structure is the correct size.
2637 if (trigData.fStructSize != sizeof(AliHLTComponentTriggerData))
2638 {
2639 if (printErrors)
2640 {
2641 AliHLTLogging log;
2642 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2643 "Invalid trigger structure size: %d but expected %d.", trigData.fStructSize, sizeof(AliHLTComponentTriggerData)
2644 );
2645 }
2646 return -ENOENT;
2647 }
2648
e4d966f5 2649 // Get the size of the AliHLTEventTriggerData structure without the readout list part.
2650 // The way we do this here should also handle memory alignment correctly.
2651 AliHLTEventTriggerData* dummy = NULL;
2652 size_t sizeWithoutReadout = (char*)(&dummy->fReadoutList) - (char*)(dummy);
2653
89413559 2654 // Check that the trigger data pointer points to data of a size we can handle.
e4d966f5 2655 // Either it is the size of AliHLTEventTriggerData or the size of the old
2656 // version of AliHLTEventTriggerData using AliHLTEventDDLV0.
89413559 2657 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData) and
e4d966f5 2658 trigData.fDataSize != sizeWithoutReadout + sizeof(AliHLTEventDDLV0)
89413559 2659 )
2660 {
2661 if (printErrors)
2662 {
2663 AliHLTLogging log;
2664 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2665 "Invalid trigger data size: %d but expected %d.", trigData.fDataSize, sizeof(AliHLTEventTriggerData)
2666 );
2667 }
2668 return -EBADF;
2669 }
2670
2671 AliHLTEventTriggerData* evtData = reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
2672 assert(evtData != NULL);
2673
2674 // Check that the CDH has 8 words.
2675 if (cdh != NULL and evtData->fCommonHeaderWordCnt != 8)
2676 {
2677 if (printErrors)
2678 {
2679 AliHLTLogging log;
2680 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2681 "Common Data Header (CDH) has wrong number of data words: %d but expected %d",
2682 evtData->fCommonHeaderWordCnt, sizeof(AliRawDataHeader)/sizeof(AliHLTUInt32_t)
2683 );
2684 }
2685 return -EBADMSG;
2686 }
2687
2688 // Check that the readout list has the correct count of words. i.e. something we can handle,
2689 if (readoutlist != NULL and
2690 evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV0 and
2691 evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV1
2692 )
2693 {
2694 if (printErrors)
2695 {
2696 AliHLTLogging log;
2697 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2698 "Readout list structure has wrong number of data words: %d but expected %d",
2699 evtData->fReadoutList.fCount, gkAliHLTDDLListSize
2700 );
2701 }
2702 return -EPROTO;
2703 }
2704
2705 if (attributes != NULL)
2706 {
2707 *attributes = &evtData->fAttributes;
2708 }
2709 if (status != NULL)
2710 {
2711 *status = evtData->fHLTStatus;
2712 }
2713 if (cdh != NULL)
2714 {
24451d1f 2715 const AliRawDataHeader* cdhptr = reinterpret_cast<const AliRawDataHeader*>(&evtData->fCommonHeader[0]);
89413559 2716 *cdh = cdhptr;
2717 }
2718 if (readoutlist != NULL)
2719 {
2720 *readoutlist = AliHLTReadoutList(evtData->fReadoutList);
2721 }
2722 return 0;
2723}
2724
9e14734f 2725AliHLTUInt32_t AliHLTComponent::ExtractEventTypeFromCDH(const AliRawDataHeader* cdh)
2726{
2727 // see header file for function documentation
2728
2729 UChar_t l1msg = cdh->GetL1TriggerMessage();
2730 if ((l1msg & 0x1) == 0x0) return gkAliEventTypeData;
2731 // The L2SwC bit must be one if we got here, i.e. l1msg & 0x1 == 0x1.
2732 if (((l1msg >> 2) & 0xF) == 0xE) return gkAliEventTypeStartOfRun;
2733 if (((l1msg >> 2) & 0xF) == 0xF) return gkAliEventTypeEndOfRun;
2734 // Check the C1T bit to see if this is a calibration event,
2735 // if not then it must be some other software trigger event.
2736 if (((l1msg >> 6) & 0x1) == 0x1) return gkAliEventTypeCalibration;
2737 return gkAliEventTypeSoftware;
2738}
2739
97d2b87a 2740int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity,
2741 const char* originClass, const char* originFunc,
2742 const char* file, int line, ... ) const
2743{
2744 // see header file for function documentation
2745 int iResult=0;
2746
2747 va_list args;
2748 va_start(args, line);
2749
2750 // logging function needs to be const in order to be called from const member functions
2751 // without problems. But at this point we face the problem with virtual members which
2752 // are not necessarily const.
2753 AliHLTComponent* nonconst=const_cast<AliHLTComponent*>(this);
7efb6418 2754 AliHLTLogging::SetLogString(this, ", %p", "%s (%s_pfmt_): ",
97d2b87a 2755 fChainId[0]!=0?fChainId.c_str():nonconst->GetComponentID(),
7efb6418 2756 nonconst->GetComponentID());
97d2b87a 2757 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
2758 va_end(args);
2759
2760 return iResult;
2761}
cf9cf07e 2762
cc095616 2763TUUID AliHLTComponent::GenerateGUID()
2764{
2765 // Generates a globally unique identifier.
2766
2767 // Start by creating a new UUID. We cannot use the one automatically generated
2768 // by ROOT because the algorithm used will not guarantee unique IDs when generating
2769 // these UUIDs at a high rate in parallel.
2770 TUUID uuid;
2771 // We then use the generated UUID to form part of the random number seeds which
2772 // will be used to generate a proper random UUID. For good measure we use a MD5
2773 // hash also. Note that we want to use the TUUID class because it will combine the
2774 // host address information into the UUID. Using gSystem->GetHostByName() apparently
2775 // can cause problems on Windows machines with a firewall, because it always tries
2776 // to contact a DNS. The TUUID class handles this case appropriately.
2777 union
2778 {
2779 UChar_t buf[16];
2780 UShort_t word[8];
2781 UInt_t dword[4];
2782 };
2783 uuid.GetUUID(buf);
2784 TMD5 md5;
2785 md5.Update(buf, sizeof(buf));
2786 TMD5 md52 = md5;
2787 md5.Final(buf);
2788 dword[0] += gSystem->GetUid();
2789 dword[1] += gSystem->GetGid();
2790 dword[2] += gSystem->GetPid();
2791 for (int i = 0; i < 4; ++i)
2792 {
2793 gRandom->SetSeed(dword[i]);
2794 dword[i] = gRandom->Integer(0xFFFFFFFF);
2795 }
2796 md52.Update(buf, sizeof(buf));
2797 md52.Final(buf);
2798 // To keep to the standard we need to set the version and reserved bits.
2799 word[3] = (word[3] & 0x0FFF) | 0x4000;
2800 buf[8] = (buf[8] & 0x3F) | 0x80;
2801
2802 // Create the name of the new class and file.
2803 char uuidstr[64];
2804 sprintf(uuidstr, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2805 dword[0], word[2], word[3], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]
2806 );
2807
2808 uuid.SetUUID(uuidstr);
2809 return uuid;
2810}
2811
cf9cf07e 2812int AliHLTComponent::ScanECSParam(const char* ecsParam)
2813{
2814 // see header file for function documentation
2815
2816 // format of the parameter string from ECS
2817 // <command>;<parameterkey>=<parametervalue>;<parameterkey>=<parametervalue>;...
2818 // search for a subset of the parameterkeys
c4ffab2c 2819 // RUN_TYPE=
2820 // RUN_NUMBER=
2821 // HLT_IN_DDL_LIST=
2822 // CTP_TRIGGER_CLASS=
2823 // DATA_FORMAT_VERSION=
2824 // BEAM_TYPE=
2825 // HLT_OUT_DDL_LIST=
2826 // HLT_TRIGGER_CODE=
2827 // DETECTOR_LIST=
2828 // HLT_MODE=
2829 // The command apears not to be sent by the online framework
cf9cf07e 2830 int iResult=0;
2831 TString string=ecsParam;
2832 TObjArray* parameter=string.Tokenize(";");
2833 if (parameter) {
77fd699f 2834 for (int i=0; i<parameter->GetEntriesFast(); i++) {
704972af 2835 TString entry=parameter->At(i)->GetName();
cf9cf07e 2836 HLTDebug("scanning ECS entry: %s", entry.Data());
2837 TObjArray* entryParams=entry.Tokenize("=");
2838 if (entryParams) {
77fd699f 2839 if (entryParams->GetEntriesFast()>1) {
cf9cf07e 2840 if ((((TObjString*)entryParams->At(0))->GetString()).CompareTo("CTP_TRIGGER_CLASS")==0) {
704972af 2841 int result=InitCTPTriggerClasses(entryParams->At(1)->GetName());
cf9cf07e 2842 if (iResult>=0 && result<0) iResult=result;
2843 } else {
2844 // TODO: scan the other parameters
2845 // e.g. consistency check of run number
2846 }
2847 }
2848 delete entryParams;
2849 }
2850 }
2851 delete parameter;
2852 }
2853
2854 return iResult;
2855}
2856
adb91bc3 2857int AliHLTComponent::SetupCTPData()
cf9cf07e 2858{
2859 // see header file for function documentation
adb91bc3 2860 if (fpCTPData) delete fpCTPData;
2861 fpCTPData=new AliHLTCTPData;
2862 if (!fpCTPData) return -ENOMEM;
cf9cf07e 2863 return 0;
2864}
2865
adb91bc3 2866int AliHLTComponent::InitCTPTriggerClasses(const char* ctpString)
cf9cf07e 2867{
2868 // see header file for function documentation
adb91bc3 2869 if (!fpCTPData) return 0; // silently accept as the component has to announce that it want's the CTP info
2870 return fpCTPData->InitCTPTriggerClasses(ctpString);
2871}
cf9cf07e 2872
adb91bc3 2873bool AliHLTComponent::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
2874{
2875 // see header file for function documentation
2876 if (!fpCTPData) {
2877 static bool bWarningThrown=false;
2878 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2879 bWarningThrown=true;
cf9cf07e 2880 return false;
2881 }
2882
adb91bc3 2883 return fpCTPData->EvaluateCTPTriggerClass(expression, trigData);
cf9cf07e 2884}
a5e775ec 2885
3fcb48b8 2886int AliHLTComponent::CheckCTPTrigger(const char* name) const
2887{
2888 // see header file for function documentation
2889 if (!fpCTPData) {
2890 static bool bWarningThrown=false;
2891 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2892 bWarningThrown=true;
2893 return false;
2894 }
2895
2896 return fpCTPData->CheckTrigger(name);
2897}
2898
a5e775ec 2899Double_t AliHLTComponent::GetBz()
2900{
2901 // Returns Bz.
2902 return AliHLTMisc::Instance().GetBz();
2903}
2904
2905Double_t AliHLTComponent::GetBz(const Double_t *r)
2906{
2907 // Returns Bz (kG) at the point "r" .
2908 return AliHLTMisc::Instance().GetBz(r);
2909}
2910
2911void AliHLTComponent::GetBxByBz(const Double_t r[3], Double_t b[3])
2912{
2913 // Returns Bx, By and Bz (kG) at the point "r" .
2914 AliHLTMisc::Instance().GetBxByBz(r, b);
2915}