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