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