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