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