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