bugfix AliHLTCompStatCollector: filling entry 'Level' of the component statistics...
[u/mrichter/AliRoot.git] / HLT / BASE / util / AliHLTCompStatCollector.cxx
CommitLineData
b765ad15 1// $Id$
2
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//* for The ALICE HLT Project. *
9//* *
10//* Permission to use, copy, modify and distribute this software and its *
11//* documentation strictly for non-commercial purposes is hereby granted *
12//* without fee, provided that the above copyright notice appears in all *
13//* copies and that both the copyright notice and this permission notice *
14//* appear in the supporting documentation. The authors make no claims *
15//* about the suitability of this software for any purpose. It is *
16//* provided "as is" without express or implied warranty. *
17//**************************************************************************
18
11010adb 19/// @file AliHLTCompStatCollector.cxx
20/// @author Matthias Richter
21/// @date
22/// @brief Collector component for the component statistics information.
23///
b765ad15 24
25#include "AliHLTCompStatCollector.h"
e3356855 26#include "AliHLTErrorGuard.h"
c7b299f1 27#include "TFile.h"
b765ad15 28#include "TStopwatch.h"
29#include "TH1F.h"
30#include "TH2F.h"
31#include "TH2C.h"
32#include "TTree.h"
abb52c8f 33#include "TFolder.h"
34#include "TNamed.h"
b765ad15 35#include "TString.h"
abb52c8f 36#include <cassert>
11010adb 37#include <algorithm>
38using std::sort;
abb52c8f 39
40#define HLTSTAT_FOLDER_NAME "HLTstat"
41#define HLTSTAT_FOLDER_DESC "ALICE HLT component statistics"
42#define HLTSTAT_ENTRY_PARENT_FOLDER_NAME "parents"
43#define HLTSTAT_ENTRY_PARENT_FOLDER_DESC "parent components"
44#define HLTSTAT_ENTRY_PROPS_FOLDER_NAME "props"
45#define HLTSTAT_ENTRY_PROPS_FOLDER_DESC "component properties"
46#define HLTSTAT_ENTRY_PROPS_IDOBJ_NAME "id"
47#define HLTSTAT_ENTRY_PROPS_IDOBJ_DESC "numerical id calculated from chain id"
b765ad15 48
49/** ROOT macro for the implementation of ROOT specific class methods */
50ClassImp(AliHLTCompStatCollector)
51
52AliHLTCompStatCollector::AliHLTCompStatCollector()
53 :
54 AliHLTProcessor(),
55 fpTimer(NULL),
abb52c8f 56 fpFolder(NULL),
11010adb 57 fInstances(),
b765ad15 58 fpStatTree(NULL),
59 fCycleTime(0),
60 fNofSets(0),
11010adb 61 fArraySize(0),
b765ad15 62 fPosition(0),
63 fpLevelArray(NULL),
64 fpSpecArray(NULL),
65 fpBlockNoArray(NULL),
66 fpIdArray(NULL),
67 fpTimeArray(NULL),
68 fpCTimeArray(NULL),
69 fpInputBlockCountArray(NULL),
70 fpTotalInputSizeArray(NULL),
fce51f62 71 fpNormalizedInputSizeArray(NULL),
b765ad15 72 fpOutputBlockCountArray(NULL),
73 fpTotalOutputSizeArray(NULL)
fce51f62 74 , fpInputOutputRatioArray(NULL)
75 , fpNormalizedInputOutputRatioArray(NULL)
2e3fd14f 76 , fpComponentCycleTimeArray(NULL)
77 , fpEventTypeArray(NULL)
78 , fpEventCountArray(NULL)
63410eb4 79 , fSizeEstimator(1000)
c7b299f1 80 , fMode(kPublishObjects)
81 , fFileName()
82 , fFile(NULL)
83 , fLastTime(time(NULL))
84 , fPeriod(0)
85 , fEventModulo(0)
b765ad15 86{
87 // see header file for class documentation
88 // or
89 // refer to README to build package
90 // or
91 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
92}
93
94AliHLTCompStatCollector::~AliHLTCompStatCollector()
95{
96 // see header file for class documentation
97 ClearAll();
98}
99
100void AliHLTCompStatCollector::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
101{
102 // see header file for class documentation
103 list.push_back(kAliHLTDataTypeComponentStatistics);
104}
105
106AliHLTComponentDataType AliHLTCompStatCollector::GetOutputDataType()
107{
108 // see header file for class documentation
109 return kAliHLTMultipleDataType;
110}
111
112int AliHLTCompStatCollector::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
113{
114 // see header file for class documentation
115 tgtList.clear();
116 tgtList.push_back(kAliHLTDataTypeHistogram);
117 tgtList.push_back(kAliHLTDataTypeTTree);
118 return tgtList.size();
119}
120
121void AliHLTCompStatCollector::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
122{
123 // see header file for class documentation
63410eb4 124 constBase=fSizeEstimator;
b765ad15 125 inputMultiplier=100.0;
126}
127
128int AliHLTCompStatCollector::DoInit( int argc, const char** argv )
129{
130 // see header file for class documentation
131 int iResult=0;
132 TString argument="";
133 int bMissingParam=0;
134 for (int i=0; i<argc && iResult>=0; i++) {
135 argument=argv[i];
136 if (argument.IsNull()) continue;
137
c7b299f1 138 // -file
139 if (argument.CompareTo("-file")==0) {
b765ad15 140 if ((bMissingParam=(++i>=argc))) break;
c7b299f1 141 fFileName=argv[i];
142 fMode|=kSaveObjects;
143
144 // -modulo
145 } else if (argument.CompareTo("-modulo")==0) {
146 if ((bMissingParam=(++i>=argc))) break;
147 TString param=argv[i];
b765ad15 148 if (param.IsDigit()) {
c7b299f1 149 fEventModulo=param.Atoi();
b765ad15 150 } else {
c7b299f1 151 HLTError("expecting number as parameter for option %s", argument.Data());
b765ad15 152 iResult=-EINVAL;
153 }
154
c7b299f1 155 // -period
156 } else if (argument.CompareTo("-period")==0) {
157 if ((bMissingParam=(++i>=argc))) break;
158 TString param=argv[i];
159 if (param.IsDigit()) {
160 fPeriod=param.Atoi();
161 } else {
162 HLTError("expecting number as parameter for option %s", argument.Data());
163 iResult=-EINVAL;
164 }
165
166 // -publish
167 } else if (argument.CompareTo("-publish")==0) {
168 if ((bMissingParam=(++i>=argc))) break;
169 TString param=argv[i];
170 if (param.IsDigit()) {
171 if (param.Atoi()==1) fMode|=kPublishObjects;
172 else if (param.Atoi()==0) fMode&=~kPublishObjects;
173 else {
174 HLTError("expecting 0 or 1 as parameter for option %s", argument.Data());
175 iResult=-EINVAL;
176 }
177 } else {
178 HLTError("expecting number as parameter for option %s", argument.Data());
179 iResult=-EINVAL;
180 }
fce51f62 181
182 // -arraysize
183 } else if (argument.CompareTo("-arraysize")==0) {
184 if ((bMissingParam=(++i>=argc))) break;
185 TString param=argv[i];
186 if (param.IsDigit()) {
11010adb 187 //fArraySize=param.Atoi();
188 HLTWarning("argument -arraysize is deprecated, array size adjusted dynamically");
fce51f62 189 } else {
190 HLTError("expecting number as parameter for option %s", argument.Data());
191 iResult=-EINVAL;
192 }
193
b765ad15 194 } else {
c7b299f1 195 HLTError("unknown argument %s", argument.Data());
b765ad15 196 iResult=-EINVAL;
197 }
198 }
199 if (bMissingParam) {
200 HLTError("missing parameter for argument %s", argument.Data());
201 iResult=-EINVAL;
202 }
203
c7b299f1 204 if (!fFileName.empty()) {
205 fFile=new TFile(fFileName.c_str(), "RECREATE");
206 }
b765ad15 207 return iResult;
208}
209
210int AliHLTCompStatCollector::DoDeinit( )
211{
212 // see header file for class documentation
213 ClearAll();
214
c7b299f1 215 if (fFile) {
216 fFile->Close();
217 delete fFile;
218 fFile=NULL;
219 }
b765ad15 220 return 0;
221}
222
223int AliHLTCompStatCollector::DoEvent( const AliHLTComponentEventData& /*evtData*/, AliHLTComponentTriggerData& /*trigData*/)
224{
225 // see header file for class documentation
226 int iResult=0;
227
abb52c8f 228 AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
229 IsDataEvent(&eventType);
230
b765ad15 231 ResetFillingVariables();
232 if (fpTimer) {
233 fCycleTime=fpTimer->RealTime()*1000000;
234 }
235
11010adb 236 // only if the map of instances is empty it can be initialized from the
237 // component table entries
238 // the logical check fo eventType==gkAliEventTypeStartOfRun does not work
239 // for simulated data where the blocks of the SOR are stored inside the
240 // first event
241 bool bMapInitialization=fInstances.empty();
242 vector<AliHLTCompStatCollector::AliHLTCompStatInstance> sortedInstances;
243
abb52c8f 244 bool bEmbeddedTree=false;
245 bool bFolderCreated=false;
9d5f00ad 246 if ((bFolderCreated=(fpFolder==NULL))) {
abb52c8f 247 fpFolder=new TFolder(HLTSTAT_FOLDER_NAME, HLTSTAT_FOLDER_DESC);
248 if (bEmbeddedTree) fpFolder->Add(fpStatTree);
249 }
250 if (!fpFolder) return -ENOMEM;
251 vector<TFolder*> newFolders;
252
253 for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeComponentTable);
254 pBlock && iResult>=0;
255 pBlock=GetNextInputBlock()) {
256 string chainId, compId, compArgs;
257 vector<AliHLTUInt32_t> parents;
11010adb 258 int level=0;
abb52c8f 259 iResult=ExtractComponentTableEntry((const AliHLTUInt8_t*)pBlock->fPtr, pBlock->fSize,
260 chainId, compId, compArgs,
11010adb 261 parents, level);
abb52c8f 262 if (iResult>0) {
263 HLTDebug("%s(%s) 0x%08x", chainId.c_str(), compId.c_str(), pBlock->fSpecification);
11010adb 264 if (bMapInitialization) {
265 map<AliHLTUInt32_t, AliHLTCompStatInstance>::const_iterator element=fInstances.find(pBlock->fSpecification);
266 AliHLTCompStatInstance newInstance(pBlock->fSpecification, chainId, compId, compArgs, parents, level);
267 if (element==fInstances.end()) {
268 // new instance
269 fInstances[pBlock->fSpecification]=newInstance;
270 sortedInstances.push_back(newInstance);
271 } else {
272 // check existing instance
273 if (element->second!=newInstance) {
274 HLTWarning("component table entries have identical CRC ids but different content\n in list: %s\n skipping: %s",
275 element->second.Description().c_str(), newInstance.Description().c_str());
276 }
277 }
278 }
279
abb52c8f 280 TObject* pObj=NULL;
281 TFolder* pEntry=NULL;
282 if ((pObj=fpFolder->FindObjectAny(chainId.c_str()))!=NULL &&
283 (pEntry=dynamic_cast<TFolder*>(pObj))!=NULL ) {
284
285 } else if (pObj) {
286 HLTError("entry %s exists in folder, but is not a sub-folder", chainId.c_str());
287 } else if (chainId.size()>0) {
288 pEntry=new TFolder(chainId.c_str(), chainId.c_str());
289 if (pEntry) {
290 pEntry->SetOwner();
291 TFolder* pProps=pEntry->AddFolder(HLTSTAT_ENTRY_PROPS_FOLDER_NAME, HLTSTAT_ENTRY_PROPS_FOLDER_DESC);
292 if (pProps) {
293 pProps->Add(new TObjString(compId.c_str()));
294 if (!compArgs.empty())
295 pProps->Add(new TObjString(compArgs.c_str()));
296 TNamed* pCRC=new TNamed(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME, HLTSTAT_ENTRY_PROPS_IDOBJ_DESC);
297 if (pCRC) {
298 pCRC->SetUniqueID(pBlock->fSpecification);
299 pProps->Add(pCRC);
300 }
301 }
302 TFolder* pParents=pEntry->AddFolder(HLTSTAT_ENTRY_PARENT_FOLDER_NAME, HLTSTAT_ENTRY_PARENT_FOLDER_DESC);
303 if (pParents) {
304 for (vector<AliHLTUInt32_t>::iterator parent=parents.begin();
305 parent!=parents.end(); parent++) {
306 TString name; name.Form("0x%08x", *parent);
307 pParents->Add(new TObjString(name));
308 }
309 }
310 if (parents.size()==0) {
311 newFolders.push_back(pEntry);
312 } else {
313 vector<TFolder*>::iterator iter=newFolders.begin();
314 vector<AliHLTUInt32_t>::iterator parent=parents.begin();
315 while (iter!=newFolders.end() && parent!=parents.end()) {
316 TObject* idobj=(*iter)->FindObjectAny(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME);
317 AliHLTUInt32_t crcid=0;
318 if (idobj) crcid=idobj->GetUniqueID();
319 HLTDebug("check: %s 0x%08x", (*iter)->GetName(), crcid);
320 if (idobj && crcid==*parent) break;
321 if ((++parent!=parents.end())) continue;
322 parent=parents.begin();
323 iter++;
324 }
325 newFolders.insert(iter,pEntry);
326 }
327 }
328 } else {
329 HLTError("missing chain id for table entry 0x%08x (%p %d), skipping ...", pBlock->fSpecification, pBlock->fPtr, pBlock->fSize);
330 }
331 } else if (iResult!=0) {
332 HLTError("extraction of table entry 0x%08x (%p %d) failed with %d", pBlock->fSpecification, pBlock->fPtr, pBlock->fSize, iResult);
333 }
334 iResult=0;
335 }
336
11010adb 337 if (bMapInitialization) {
338 // assign tags to all instances in the map
339 int level=-1;
340 int tag=-1;
341 TString componentId;
342 TObjArray* taglist=NULL;
343 sort(sortedInstances.begin(), sortedInstances.end(), AliHLTCompStatInstance::SortByLevelAndComponentId);
344 for (vector< AliHLTCompStatInstance>::const_iterator element=sortedInstances.begin();
345 element!=sortedInstances.end();
346 element++) {
347 if (level!=element->GetLevel() ||
348 componentId.CompareTo(element->GetComponentId().c_str())!=0) {
349 tag++;
350 level=element->GetLevel();
351 componentId=element->GetComponentId().c_str();
352 if (fpFolder) {
353 if (!taglist) {
354 taglist=new TObjArray;
355 taglist->SetName("CompStatMap");
356 fpFolder->Add(taglist);
357 }
358 if (taglist) {
359 TString entry;
360 entry.Form("%02d ", tag); entry+=componentId;
361 taglist->Add(new TObjString(entry));
362 }
363 }
364 }
365 fInstances[element->GetCRCId()].SetTag(tag);
366 }
367
368 if (fpStatTree==NULL && !fInstances.empty()) {
369 iResult=AllocateStatTree(fInstances.size());
e3356855 370 if (!fpStatTree || iResult<0) {
371 ALIHLTERRORGUARD(1, "failed to allocate tree for statistics collection, error %d", iResult);
372 }
11010adb 373 }
374 }
375
abb52c8f 376 if (newFolders.size()>0) {
377 vector<TFolder*> revert;
378 vector<TFolder*>::iterator iter=newFolders.begin();
379 while (iter!=newFolders.end()) {
380 revert.insert(revert.begin(), *iter);
381 HLTDebug("%s", (*iter)->GetName());
382 iter++;
383 }
384 newFolders.empty();
385 newFolders.assign(revert.begin(), revert.end());
386
387 vector<TFolder*>::iterator publisher=newFolders.begin();
388 while (publisher!=newFolders.end()) {
389 bool bRemove=false;
390 HLTDebug("checking %s for parents", (*publisher)->GetName());
391 TFolder* propsFolder=dynamic_cast<TFolder*>((*publisher)->FindObject(HLTSTAT_ENTRY_PROPS_FOLDER_NAME));
392 assert(propsFolder);
393 TObject* idobj=NULL;
394 if (propsFolder) idobj=propsFolder->FindObject(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME);
395 assert(idobj);
abb52c8f 396 if (idobj) {
0b8c418e 397 AliHLTUInt32_t crcid=idobj->GetUniqueID();
398 TString idstr; idstr.Form("0x%08x", crcid);
abb52c8f 399 for (vector<TFolder*>::iterator consumer=publisher+1;
400 consumer!=newFolders.end(); consumer++) {
401 HLTDebug(" checking %s", (*consumer)->GetName());
402 TFolder* parentFolder=dynamic_cast<TFolder*>((*consumer)->FindObject(HLTSTAT_ENTRY_PARENT_FOLDER_NAME));
403 assert(parentFolder);
404 if (parentFolder) {
74dbd6a4 405#ifdef __DEBUG
abb52c8f 406 TIter entries(parentFolder->GetListOfFolders());
407 while (TObject* entry=entries.Next())
460c4045 408 if (entry) {
460c4045 409 HLTDebug(" searching %s in %s: %s", idstr.Data(), (*consumer)->GetName(), entry->GetName());
410 }
e56b78b4 411#endif
abb52c8f 412 TObject* parent=parentFolder->FindObjectAny(idstr);
413 if (parent) {
414 parentFolder->Add(*publisher);
415 parentFolder->Remove(parent);
416 bRemove=true;
417 }
418 }
419 }
420 }
421 if (bRemove) publisher=newFolders.erase(publisher);
422 else publisher++;
423 }
424
425 for (publisher=newFolders.begin();
426 publisher!=newFolders.end(); publisher++) {
427 RemoveRecurrence(*publisher);
428 fpFolder->Add(*publisher);
429 }
430 }
431
b765ad15 432 int blockNo=0;
433 for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeComponentStatistics);
434 pBlock && iResult>=0;
435 pBlock=GetNextInputBlock(), blockNo++) {
436 unsigned int current=fPosition;
2e3fd14f 437 iResult=FillVariablesSorted(pBlock->fPtr, pBlock->fSize, eventType);
b765ad15 438 for (; current<fPosition; current++) {
439 fpSpecArray[current]=pBlock->fSpecification;
440 fpBlockNoArray[current]=blockNo;
441 }
587c9cf9 442 // indicate availability of component statistic block
443 iResult=1;
b765ad15 444 }
445
4e5a2a53 446 int totalOutputSize=0;
2e3fd14f 447 if (iResult>0 && eventType) {
b765ad15 448 fNofSets=fPosition;
e3356855 449 if (fpStatTree) fpStatTree->Fill();
b765ad15 450
587c9cf9 451 // init the timer for the next cycle
452 if (!fpTimer) fpTimer=new TStopwatch;
453 if (fpTimer) {
454 fpTimer->Reset();
455 fpTimer->Start();
456 }
b765ad15 457 }
458
c7b299f1 459 if (eventType==gkAliEventTypeEndOfRun ||
460 (iResult>=0 && CheckPeriod())) {
461
462 // publish objects to component output
463 if ((fMode&kPublishObjects)!=0) {
e3356855 464 if (!bEmbeddedTree && fpStatTree) {
c7b299f1 465 iResult=PushBack(fpStatTree, kAliHLTDataTypeTTree|kAliHLTDataOriginOut);
466 totalOutputSize+=GetLastObjectSize();
467 }
468 iResult=PushBack(fpFolder, kAliHLTDataTypeTObject|kAliHLTDataOriginOut);
469 totalOutputSize+=GetLastObjectSize();
470 }
471
472 // save objects to file
473 if ((fMode&kSaveObjects)!=0 && fFile!=NULL) {
474 HLTDebug("saving objects to file %s", fFileName.c_str());
475 fFile->cd();
e3356855 476 if (!bEmbeddedTree && fpStatTree) {
c7b299f1 477 fpStatTree->Write("", TObject::kOverwrite);
478 }
479 fpFolder->Write("", TObject::kOverwrite);
480 }
4e5a2a53 481 }
c7b299f1 482
4e5a2a53 483 if (iResult==-ENOSPC) {
484 fSizeEstimator+=totalOutputSize;
abb52c8f 485 }
486
487 if (iResult>0) iResult=0;
b765ad15 488 return iResult;
489}
490
491void AliHLTCompStatCollector::ResetFillingVariables()
492{
493 // see header file for class documentation
11010adb 494
495 for (map<AliHLTUInt32_t, AliHLTCompStatInstance>::iterator element=fInstances.begin();
496 element!=fInstances.end();
497 element++) {
498 element->second.ResetProcessed();
499 }
500
b765ad15 501 fCycleTime=0;
502 fNofSets=0;
503 fPosition=0;
11010adb 504 if (fArraySize==0) return;
b765ad15 505 memset(fpLevelArray, 0, sizeof(UInt_t)*fArraySize);
506 memset(fpSpecArray, 0, sizeof(UInt_t)*fArraySize);
507 memset(fpBlockNoArray, 0, sizeof(UInt_t)*fArraySize);
508 memset(fpIdArray, 0, sizeof(UInt_t)*fArraySize);
509 memset(fpTimeArray, 0, sizeof(UInt_t)*fArraySize);
510 memset(fpCTimeArray, 0, sizeof(UInt_t)*fArraySize);
511 memset(fpInputBlockCountArray, 0, sizeof(UInt_t)*fArraySize);
512 memset(fpTotalInputSizeArray, 0, sizeof(UInt_t)*fArraySize);
fce51f62 513 memset(fpNormalizedInputSizeArray, 0, sizeof(UInt_t)*fArraySize);
b765ad15 514 memset(fpOutputBlockCountArray, 0, sizeof(UInt_t)*fArraySize);
515 memset(fpTotalOutputSizeArray, 0, sizeof(UInt_t)*fArraySize);
fce51f62 516 memset(fpInputOutputRatioArray, 0, sizeof(UInt_t)*fArraySize);
517 memset(fpNormalizedInputOutputRatioArray, 0, sizeof(UInt_t)*fArraySize);
2e3fd14f 518 memset(fpComponentCycleTimeArray, 0, sizeof(UInt_t)*fArraySize);
519 memset(fpEventTypeArray, 0, sizeof(UInt_t)*fArraySize);
520 memset(fpEventCountArray, 0, sizeof(UInt_t)*fArraySize);
b765ad15 521}
522
2e3fd14f 523int AliHLTCompStatCollector::FillVariablesSorted(void* ptr, int size, AliHLTUInt32_t eventType)
b765ad15 524{
525 // see header file for class documentation
526 int iResult=0;
527 if (size%sizeof(AliHLTComponentStatistics)) {
2e3fd14f 528 // older or invalid structure
b765ad15 529 HLTError("data block is not aligned to the size of the AliHLTComponentStatistics struct");
530 return -EINVAL;
531 }
2e3fd14f 532
b765ad15 533 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(ptr);
534 UInt_t nofStats=size/sizeof(AliHLTComponentStatistics);
535 vector<int> indexList;
536 UInt_t i=0;
537 for (i=0; i<nofStats; i++) {
538 vector<int>::iterator element=indexList.begin();
539 for (; element!=indexList.end(); element++) {
540 if (pStat[i].fLevel>pStat[*element].fLevel) {
541 break;
542 }
543 }
544 indexList.insert(element, i);
545 }
546
547 i=fPosition;
548 for (vector<int>::iterator element=indexList.begin();
549 element!=indexList.end();
11010adb 550 element++) {
551 map<AliHLTUInt32_t, AliHLTCompStatInstance>::iterator instance=fInstances.find(pStat[*element].fId);
552 if (i<fArraySize && instance!=fInstances.end()) {
553 if (instance->second.IsProcessed()) {
554 //HLTWarning("already processed instance %s, skip", instance->second.Description().c_str());
555 continue;
556 }
557 instance->second.MarkProcessed();
558 if ((int)pStat[*element].fLevel!=instance->second.GetLevel()) {
559 // TODO: there is currently a mismatch of the level set in the statistics entry and
560 // the one in the component table entries. However this does not matter for
561 // archiving because the CRC id is related to a tag/level
562 //HLTWarning("level does not match for instance %s, expected %d", instance->second.Description().c_str(), pStat[*element].fLevel);
563 }
c64ba34e 564 fpLevelArray[i]=pStat[*element].fLevel;
b765ad15 565 fpIdArray[i]=pStat[*element].fId;
566 fpTimeArray[i]=pStat[*element].fTime;
567 fpCTimeArray[i]=pStat[*element].fCTime;
568 fpInputBlockCountArray[i]=pStat[*element].fInputBlockCount;
569 fpTotalInputSizeArray[i]=pStat[*element].fTotalInputSize;
fce51f62 570 fpNormalizedInputSizeArray[i]=pStat[*element].fTotalInputSize;
571 if (pStat[*element].fInputBlockCount>0)
572 fpNormalizedInputSizeArray[i]/=pStat[*element].fInputBlockCount;
b765ad15 573 fpOutputBlockCountArray[i]=pStat[*element].fOutputBlockCount;
574 fpTotalOutputSizeArray[i]=pStat[*element].fTotalOutputSize;
fce51f62 575 if (pStat[*element].fTotalOutputSize>0)
576 fpInputOutputRatioArray[i]=pStat[*element].fTotalInputSize/pStat[*element].fTotalOutputSize;
577 if (pStat[*element].fInputBlockCount>0)
578 fpNormalizedInputOutputRatioArray[i]=fpInputOutputRatioArray[i]*pStat[*element].fOutputBlockCount/pStat[*element].fInputBlockCount;
2e3fd14f 579 fpComponentCycleTimeArray[i]=pStat[*element].fComponentCycleTime;
580 fpEventTypeArray[i]=eventType;
581 fpEventCountArray[i]=GetEventCount();
11010adb 582 i++;
583 } else if (instance==fInstances.end()) {
584 HLTWarning("can not find instance of CRC id 0x%08x", pStat[*element].fId);
b765ad15 585 }
586 }
587
11010adb 588 if (i>fArraySize) {
589 HLTWarning("too little space in branch variables to fill %d statistics blocks, total available %d, current position %d", i, fArraySize, fPosition);
b765ad15 590 fPosition=fArraySize;
591 } else {
592 fPosition=i;
593 }
594
595 return iResult;
596}
597
11010adb 598int AliHLTCompStatCollector::AllocateStatTree(AliHLTUInt32_t size)
599{
600 // allocate the statistics tree and the branch arrays
601 if (fArraySize>0) {
602 ClearStatTree();
603 }
604 fArraySize=size;
605 if (fArraySize==0) return 0;
606
607 fpLevelArray=new UInt_t[fArraySize];
608 fpSpecArray=new UInt_t[fArraySize];
609 fpBlockNoArray=new UInt_t[fArraySize];
610 fpIdArray=new UInt_t[fArraySize];
611 fpTimeArray=new UInt_t[fArraySize];
612 fpCTimeArray=new UInt_t[fArraySize];
613 fpInputBlockCountArray=new UInt_t[fArraySize];
614 fpTotalInputSizeArray=new UInt_t[fArraySize];
615 fpNormalizedInputSizeArray=new UInt_t[fArraySize];
616 fpOutputBlockCountArray=new UInt_t[fArraySize];
617 fpTotalOutputSizeArray=new UInt_t[fArraySize];
618 fpInputOutputRatioArray=new UInt_t[fArraySize];
619 fpNormalizedInputOutputRatioArray=new UInt_t[fArraySize];
620 fpComponentCycleTimeArray=new UInt_t[fArraySize];
621 fpEventTypeArray=new UInt_t[fArraySize];
622 fpEventCountArray=new UInt_t[fArraySize];
623
624 fpStatTree=new TTree("CompStat", "HLT component statistics");
625 if (fpStatTree) {
626 fpStatTree->SetDirectory(0);
627 fpStatTree->Branch("cycleTime", &fCycleTime, "cycleTime/F");
628 fpStatTree->Branch("nofSets", &fNofSets, "nofSets/I");
629 fpStatTree->Branch("Level", fpLevelArray, "Level[nofSets]/i");
630 fpStatTree->Branch("Specification", fpSpecArray, "Specification[nofSets]/i");
631 fpStatTree->Branch("BlockNo", fpBlockNoArray, "BlockNo[nofSets]/i");
632 fpStatTree->Branch("Id", fpIdArray, "Id[nofSets]/i");
633 fpStatTree->Branch("Time", fpTimeArray, "Time[nofSets]/i");
634 fpStatTree->Branch("CTime", fpCTimeArray, "CTime[nofSets]/i");
635 fpStatTree->Branch("InputBlockCount", fpInputBlockCountArray, "InputBlockCount[nofSets]/i");
636 fpStatTree->Branch("TotalInputSize", fpTotalInputSizeArray, "TotalInputSize[nofSets]/i");
637 fpStatTree->Branch("NormalizedInputSize", fpNormalizedInputSizeArray, "NormalizedInputSize[nofSets]/i");
638 fpStatTree->Branch("OutputBlockCount", fpOutputBlockCountArray, "OutputBlockCount[nofSets]/i");
639 fpStatTree->Branch("TotalOutputSize", fpTotalOutputSizeArray, "TotalOutputSize[nofSets]/i");
640 fpStatTree->Branch("InputOutputRatio", fpInputOutputRatioArray, "InputOutputRatio[nofSets]/i");
641 fpStatTree->Branch("NormalizedInputOutputRatio", fpNormalizedInputOutputRatioArray, "NormalizedInputOutputRatio[nofSets]/i");
642 fpStatTree->Branch("ComponentCycleTime",fpComponentCycleTimeArray, "ComponentCycleTime[nofSets]/i");
643 fpStatTree->Branch("EventType",fpEventTypeArray, "EventType[nofSets]/i");
644 fpStatTree->Branch("EventCount",fpEventCountArray, "EventCount[nofSets]/i");
645 }
646
647 return 0;
648}
649
b765ad15 650void AliHLTCompStatCollector::ClearAll()
651{
abb52c8f 652 // see header file for class documentation
b765ad15 653 if (fpTimer) delete fpTimer; fpTimer=NULL;
abb52c8f 654 if (fpFolder) delete fpFolder; fpFolder=NULL;
11010adb 655 ClearStatTree();
656}
657
658void AliHLTCompStatCollector::ClearStatTree()
659{
660 // clear the statistics tree and the branch arrays
b765ad15 661 if (fpStatTree) delete fpStatTree; fpStatTree=NULL;
662 if (fpLevelArray) delete fpLevelArray; fpLevelArray=NULL;
663 if (fpSpecArray) delete fpSpecArray; fpSpecArray=NULL;
664 if (fpBlockNoArray) delete fpBlockNoArray; fpBlockNoArray=NULL;
665 if (fpIdArray) delete fpIdArray; fpIdArray=NULL;
666 if (fpTimeArray) delete fpTimeArray; fpTimeArray=NULL;
667 if (fpCTimeArray) delete fpCTimeArray; fpCTimeArray=NULL;
668 if (fpInputBlockCountArray) delete fpInputBlockCountArray; fpInputBlockCountArray=NULL;
669 if (fpTotalInputSizeArray) delete fpTotalInputSizeArray; fpTotalInputSizeArray=NULL;
fce51f62 670 if (fpNormalizedInputSizeArray) delete fpNormalizedInputSizeArray; fpNormalizedInputSizeArray=NULL;
b765ad15 671 if (fpOutputBlockCountArray) delete fpOutputBlockCountArray; fpOutputBlockCountArray=NULL;
672 if (fpTotalOutputSizeArray) delete fpTotalOutputSizeArray; fpTotalOutputSizeArray=NULL;
fce51f62 673 if (fpInputOutputRatioArray) delete fpInputOutputRatioArray; fpInputOutputRatioArray=NULL;
674 if (fpNormalizedInputOutputRatioArray) delete fpNormalizedInputOutputRatioArray; fpNormalizedInputOutputRatioArray=NULL;
2e3fd14f 675 if (fpComponentCycleTimeArray) delete fpComponentCycleTimeArray; fpComponentCycleTimeArray=NULL;
676 if (fpEventTypeArray) delete fpEventTypeArray; fpEventTypeArray=NULL;
677 if (fpEventCountArray) delete fpEventCountArray; fpEventCountArray=NULL;
11010adb 678 fArraySize=0;
b765ad15 679}
abb52c8f 680
681int AliHLTCompStatCollector::RemoveRecurrence(TFolder* pRoot) const
682{
683 // see header file for class documentation
684 int iResult=0;
685 if (!pRoot) return -EINVAL;
686 TFolder* parentFolder=dynamic_cast<TFolder*>(pRoot->FindObject(HLTSTAT_ENTRY_PARENT_FOLDER_NAME));
687 assert(parentFolder);
688 vector<TFolder*> listRemove;
689 if (parentFolder) {
690 TIter entries(parentFolder->GetListOfFolders());
691 TFolder* entry=NULL;
692 TObject* obj=NULL;
693 while ((obj=entries.Next())!=NULL && (entry=dynamic_cast<TFolder*>(obj))!=NULL) {
694 TString name=entry->GetName();
695 HLTDebug("checking %s for recurrence", name.Data());
696 TIter tokens(parentFolder->GetListOfFolders());
697 TFolder* token=NULL;
698 while ((obj=tokens.Next())!=NULL && (token=dynamic_cast<TFolder*>(obj))!=NULL) {
699 if (name.CompareTo(token->GetName())==0) continue;
0b8c418e 700 if (token->FindObjectAny(name)!=NULL) {
abb52c8f 701 listRemove.push_back(entry);
702 HLTDebug("found recurrence in %s", token->GetName());
703 break;
704 } else {
705 HLTDebug("no recurrence found in %s", token->GetName());
706 }
707 }
708 RemoveRecurrence(entry);
709 }
710 for (vector<TFolder*>::iterator removeElement=listRemove.begin();
711 removeElement!=listRemove.end(); removeElement++) {
712 parentFolder->Remove(*removeElement);
713 }
714 }
715
716 return iResult;
717}
c7b299f1 718
719bool AliHLTCompStatCollector::CheckPeriod(bool bUpdate)
720{
721 // see header file for class documentation
722 bool result=true;
723 if (fEventModulo>0) {
724 if ((result=((GetEventCount()+1)%fEventModulo)==0)) {
725 return true;
726 }
727 }
728 if (fPeriod>0) {
729 if ((result=((difftime(time(NULL), fLastTime)>(double)fPeriod))) &&
730 bUpdate) {
731 fLastTime=time(NULL);
732 }
733 }
734 return result;
735}
11010adb 736
737void AliHLTCompStatCollector::Print(const char* option) const
738{
739 // print information
740 if (strcmp(option, "instances")==0) {
741 vector<AliHLTCompStatInstance> sortedInstances;
742 for (map<AliHLTUInt32_t, AliHLTCompStatInstance>::const_iterator element=fInstances.begin();
743 element!=fInstances.end();
744 element++) {
745 sortedInstances.push_back(element->second);
746 }
747 sort(sortedInstances.begin(), sortedInstances.end(), AliHLTCompStatInstance::SortByLevelAndComponentId);
748 for (vector<AliHLTCompStatInstance>::const_iterator element=sortedInstances.begin();
749 element!=sortedInstances.end();
750 element++) {
751 element->Print("");
752 }
753 }
754}
755
756AliHLTCompStatCollector::AliHLTCompStatInstance::AliHLTCompStatInstance()
757 : fCRCId(0)
758 , fChainId()
759 , fComponentId()
760 , fComponentParam()
761 , fParents()
762 , fLevel(-1)
763 , fTag(-1)
764 , fProcessed(false)
765{
766 /// default constructor
767}
768
769AliHLTCompStatCollector::AliHLTCompStatInstance::AliHLTCompStatInstance(AliHLTUInt32_t CRCId,
770 const char* chainId,
771 const char* componentId,
772 const char* componentParam,
773 const vector<AliHLTUInt32_t>& parents,
774 int level,
775 int tag)
776 : fCRCId(CRCId)
777 , fChainId(chainId)
778 , fComponentId(componentId)
779 , fComponentParam(componentParam)
780 , fParents(parents)
781 , fLevel(level)
782 , fTag(tag)
783 , fProcessed(false)
784{
785}
786
787AliHLTCompStatCollector::AliHLTCompStatInstance::AliHLTCompStatInstance(AliHLTUInt32_t CRCId,
788 const string& chainId,
789 const string& componentId,
790 const string& componentParam,
791 const vector<AliHLTUInt32_t>& parents,
792 int level,
793 int tag)
794 : fCRCId(CRCId)
795 , fChainId(chainId)
796 , fComponentId(componentId)
797 , fComponentParam(componentParam)
798 , fParents(parents)
799 , fLevel(level)
800 , fTag(tag)
801 , fProcessed(false)
802{
803}
804
805AliHLTCompStatCollector::AliHLTCompStatInstance::AliHLTCompStatInstance(const AliHLTCompStatCollector::AliHLTCompStatInstance& src)
806 : fCRCId(src.fCRCId)
807 , fChainId(src.fChainId)
808 , fComponentId(src.fComponentId)
809 , fComponentParam(src.fComponentParam)
810 , fParents(src.fParents)
811 , fLevel(src.fLevel)
812 , fTag(src.fTag)
813 , fProcessed(src.fProcessed)
814{
815 /// copy constructor
816}
817
818AliHLTCompStatCollector::AliHLTCompStatInstance& AliHLTCompStatCollector::AliHLTCompStatInstance::operator=(const AliHLTCompStatCollector::AliHLTCompStatInstance& src)
819{
820 /// assignment operator
821 if (&src==this) return *this;
822
823 fCRCId=src.fCRCId;
824 fChainId=src.fChainId;
825 fComponentId=src.fComponentId;
826 fComponentParam=src.fComponentParam;
827 fParents.assign(src.fParents.begin(), src.fParents.end());
828 fLevel=src.fLevel;
829 fTag=src.fTag;
830
831 return *this;
832}
833
834AliHLTCompStatCollector::AliHLTCompStatInstance::~AliHLTCompStatInstance()
835{
836 /// destructor
837}
838
839string AliHLTCompStatCollector::AliHLTCompStatInstance::Description(const char* /*option*/) const
840{
841 // get a description string
842 TString description;
843 description.Form("0x%08x level %d tag %d: %s (%s) %s",
844 fCRCId, fLevel, fTag, fChainId.c_str(), fComponentId.c_str(), fComponentParam.c_str());
845 string ret=description.Data();
846 return ret;
847}
848
849void AliHLTCompStatCollector::AliHLTCompStatInstance::Print(const char* /*option*/) const
850{
851 // print info to cout
852 cout << Description() << endl;
853}
854
855bool AliHLTCompStatCollector::AliHLTCompStatInstance::operator==(const AliHLTCompStatInstance &b) const
856{
857 // check if two instances are equal
858 if (fChainId !=b.fChainId) return false;
859 if (fComponentId !=b.fComponentId) return false;
860 if (fComponentParam!=b.fComponentParam) return false;
861 if (fCRCId !=b.fCRCId) return false;
862 if (fLevel !=b.fLevel) return false;
863 if (fTag>=0 && fTag!=b.fTag && b.fTag>=0) return false;
864
865 return true;
866}
867
868bool AliHLTCompStatCollector::AliHLTCompStatInstance::SortByLevelAndComponentId(const AliHLTCompStatInstance &a,
869 const AliHLTCompStatInstance &b)
870{
871 // helper function for std::sort
872 if ( a.fLevel != b.fLevel ) return ( a.fLevel < b.fLevel );
873 if ( a.fComponentId != b.fComponentId ) return ( a.fComponentId < b.fComponentId );
874 if ( a.fChainId != b.fChainId ) return ( a.fChainId < b.fChainId );
875 return 0;
876}