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