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