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