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