1 |
|
// $Id$ |
2 |
|
|
3 |
|
#include "MitAna/TreeMod/interface/OutputMod.h" |
4 |
+ |
#include "MitAna/TreeMod/interface/HLTFwkMod.h" |
5 |
|
#include "MitAna/DataUtil/interface/Debug.h" |
6 |
|
#include "MitAna/DataTree/interface/Names.h" |
7 |
|
#include "MitAna/DataUtil/interface/TreeWriter.h" |
23 |
|
fSplitLevel(99), |
24 |
|
fBranchSize(32*1024), |
25 |
|
fDoReset(kFALSE), |
26 |
< |
fCheckDep(kTRUE), |
26 |
> |
fCheckTamBr(kTRUE), |
27 |
> |
fKeepTamBr(kTRUE), |
28 |
|
fTreeWriter(0), |
29 |
< |
fNBranchesMax(1024) |
29 |
> |
fEventHeader(0), |
30 |
> |
fAllEventHeader(0), |
31 |
> |
fRunInfo(0), |
32 |
> |
fLaHeader(0), |
33 |
> |
fNBranchesMax(1024), |
34 |
> |
fRunTree(0), |
35 |
> |
fLATree(0), |
36 |
> |
fAllTree(0), |
37 |
> |
fL1Tree(0), |
38 |
> |
fHltTree(0), |
39 |
> |
fRunEntries(0), |
40 |
> |
fOrigL1Entry(-1), |
41 |
> |
fL1Entries(0), |
42 |
> |
fOrigHltEntry(-1), |
43 |
> |
fHltEntries(0), |
44 |
> |
fFileNum(0), |
45 |
> |
fLastWrittenEvt(-1), |
46 |
> |
fLastSeenEvt(-1), |
47 |
> |
fCounter(0) |
48 |
|
{ |
49 |
< |
|
49 |
> |
// Constructor. |
50 |
|
} |
51 |
|
|
52 |
|
//-------------------------------------------------------------------------------------------------- |
53 |
|
void OutputMod::BeginRun() |
54 |
|
{ |
55 |
< |
// Todo. |
55 |
> |
// Create HLT tree if HLTFwkMod is being run. |
56 |
> |
|
57 |
> |
if (!HasHLTInfo()) |
58 |
> |
return; |
59 |
|
|
60 |
+ |
if (!fHltTree) { |
61 |
+ |
HLTFwkMod *hm = const_cast<HLTFwkMod*>(GetHltFwkMod()); |
62 |
+ |
fTreeWriter->AddBranchToTree(hm->HLTTreeName(), hm->HLTTabName(), &(hm->fHLTTab), 32000, 0); |
63 |
+ |
fTreeWriter->AddBranchToTree(hm->HLTTreeName(), hm->HLTLabName(), &(hm->fHLTLab), 32000, 0); |
64 |
+ |
fTreeWriter->SetAutoFill(hm->HLTTreeName(), 0); |
65 |
+ |
fHltTree = fTreeWriter->GetTree(hm->HLTTreeName()); |
66 |
+ |
} |
67 |
|
} |
68 |
|
|
69 |
|
//-------------------------------------------------------------------------------------------------- |
70 |
|
void OutputMod::CheckAndAddBranch(const char *bname, const char *cname) |
71 |
|
{ |
72 |
< |
// Todo. |
73 |
< |
|
72 |
> |
// Check if the given branch should be kept or dropped. |
73 |
> |
|
74 |
|
if (IsAcceptedBranch(bname)) |
75 |
|
return; |
76 |
|
|
77 |
|
// populate regular expression list if this was not yet done |
78 |
< |
if (fCmdReList.size() != fCmdList.Entries()) { |
79 |
< |
for (UInt_t i=0; i<fCmdList.Entries(); ++i) { |
80 |
< |
const char *ptr = fCmdList.At(i)->c_str(); |
78 |
> |
if (fCmdReList.size() != fCmdList.size()) { |
79 |
> |
for (UInt_t i=0; i<fCmdList.size(); ++i) { |
80 |
> |
const char *ptr = fCmdList.at(i).c_str(); |
81 |
|
fCmdReList.push_back(TRegexp(ptr+5,kTRUE)); |
82 |
|
if (ptr[0]=='k') |
83 |
|
fCmdDeList.push_back(kTRUE); |
91 |
|
Bool_t decision = kFALSE; |
92 |
|
Bool_t decision_found = kFALSE; |
93 |
|
|
94 |
< |
for (UInt_t i=0; i<fCmdList.Entries(); ++i) { |
94 |
> |
for (UInt_t i=0; i<fCmdList.size(); ++i) { |
95 |
|
TRegexp &re(fCmdReList.at(i)); |
96 |
|
if (brname.Index(re) == kNPOS) |
97 |
|
continue; |
114 |
|
// add branch to accepted branch list |
115 |
|
Info("CheckAndAddBranch", "Kept branch with name %s and class %s.", bname, cname); |
116 |
|
|
117 |
< |
fBrNameList.AddCopy(string(bname)); |
118 |
< |
fBrClassList.AddCopy(string(cname)); |
117 |
> |
fBrNameList.push_back(string(bname)); |
118 |
> |
fBrClassList.push_back(string(cname)); |
119 |
|
|
120 |
|
// request branch |
121 |
|
RequestBranch(bname); |
122 |
|
} |
123 |
|
|
124 |
|
//-------------------------------------------------------------------------------------------------- |
125 |
< |
void OutputMod::RequestBranch(const char *bname) |
125 |
> |
void OutputMod::CheckAndResolveDep(Bool_t solve) |
126 |
|
{ |
127 |
< |
// Request given branch from TAM. |
127 |
> |
// Check if TAM has loaded additional branches. If requested try to solve the the dependency |
128 |
> |
// by adding the branch to the list of branches. |
129 |
|
|
130 |
< |
if (GetNBranches()>=fNBranchesMax) { |
131 |
< |
Error("RequestBranch", "Can not request branch for %bname" |
132 |
< |
"since maximum number of branches [%d] is reached", bname, fNBranchesMax); |
133 |
< |
return; |
130 |
> |
const THashTable &ht = GetSel()->GetBranchTable(); |
131 |
> |
|
132 |
> |
TIter iter(ht.MakeIterator()); |
133 |
> |
const TAMBranchInfo *next = dynamic_cast<const TAMBranchInfo*>(iter.Next()); |
134 |
> |
|
135 |
> |
while (next) { |
136 |
> |
const TAMBranchInfo *cur = next; |
137 |
> |
next = dynamic_cast<const TAMBranchInfo*>(iter.Next()); |
138 |
> |
Bool_t isloaded = cur->IsLoaded(); |
139 |
> |
if (!isloaded) |
140 |
> |
continue; |
141 |
> |
|
142 |
> |
const char *bname = cur->GetName(); |
143 |
> |
if (IsAcceptedBranch(bname)) |
144 |
> |
continue; |
145 |
> |
|
146 |
> |
TreeBranchLoader *loader = dynamic_cast<TreeBranchLoader*>(cur->GetLoader()); |
147 |
> |
if (!loader) |
148 |
> |
continue; |
149 |
> |
|
150 |
> |
TBranch *br = loader->GetBranch(); |
151 |
> |
if (!br) |
152 |
> |
continue; |
153 |
> |
|
154 |
> |
const char *cname = br->GetClassName(); |
155 |
> |
|
156 |
> |
if (solve) { |
157 |
> |
Info("CheckAndResolveDep", "Resolving dependency for loaded branch %s and class %s", |
158 |
> |
bname,cname); |
159 |
> |
|
160 |
> |
fBrNameList.push_back(string(bname)); |
161 |
> |
fBrClassList.push_back(string(cname)); |
162 |
> |
fBranches[GetNBranches()-1] = reinterpret_cast<TObject*>(loader->GetAddress()); |
163 |
> |
|
164 |
> |
} else { |
165 |
> |
Warning("CheckAndResolveDep", "Unresolved dependency for loaded branch %s and class %s", |
166 |
> |
bname,cname); |
167 |
> |
} |
168 |
|
} |
104 |
– |
|
105 |
– |
fBranches[GetNBranches()-1] = 0; |
106 |
– |
ReqBranch(bname, fBranches[GetNBranches()-1]); |
169 |
|
} |
170 |
|
|
171 |
|
//-------------------------------------------------------------------------------------------------- |
172 |
|
void OutputMod::EndRun() |
173 |
|
{ |
174 |
< |
// Todo. |
174 |
> |
// Todo |
175 |
> |
} |
176 |
|
|
177 |
+ |
//-------------------------------------------------------------------------------------------------- |
178 |
+ |
void OutputMod::FillAllEventHeader(Bool_t isremoved) |
179 |
+ |
{ |
180 |
+ |
// Fill event header into the all-event-header tree. |
181 |
+ |
|
182 |
+ |
const EventHeader *eh = GetEventHeader(); |
183 |
+ |
fAllEventHeader->SetEvtNum(eh->EvtNum()); |
184 |
+ |
fAllEventHeader->SetLumiSec(eh->LumiSec()); |
185 |
+ |
fAllEventHeader->SetRunNum(eh->RunNum()); |
186 |
+ |
if (isremoved) |
187 |
+ |
fAllEventHeader->SetRunEntry(-1); |
188 |
+ |
else |
189 |
+ |
fAllEventHeader->SetRunEntry(eh->RunEntry()); |
190 |
+ |
fAllEventHeader->SetIsRemoved(isremoved); |
191 |
+ |
|
192 |
+ |
fAllTree->Fill(); |
193 |
+ |
} |
194 |
+ |
|
195 |
+ |
//-------------------------------------------------------------------------------------------------- |
196 |
+ |
void OutputMod::FillL1Info() |
197 |
+ |
{ |
198 |
+ |
// Not doing anything here until the production writes out L1 information. |
199 |
+ |
|
200 |
+ |
if (!fL1Tree) |
201 |
+ |
return; |
202 |
+ |
} |
203 |
+ |
|
204 |
+ |
//-------------------------------------------------------------------------------------------------- |
205 |
+ |
void OutputMod::FillHltInfo() |
206 |
+ |
{ |
207 |
+ |
// Write HLT trigger table if needed. |
208 |
+ |
|
209 |
+ |
if (!fHltTree) |
210 |
+ |
return; |
211 |
+ |
|
212 |
+ |
if (fOrigHltEntry == GetHltFwkMod()->fCurEnt) |
213 |
+ |
return; |
214 |
+ |
|
215 |
+ |
fHltTree->Fill(); |
216 |
+ |
fOrigHltEntry = GetHltFwkMod()->fCurEnt; |
217 |
+ |
++fHltEntries; |
218 |
|
} |
219 |
|
|
220 |
|
//-------------------------------------------------------------------------------------------------- |
225 |
|
|
226 |
|
// search in branch list |
227 |
|
for (UInt_t i=0; i<GetNBranches(); ++i) { |
228 |
< |
if (fBrNameList.At(i)->compare(bname) == 0) |
228 |
> |
if (fBrNameList.at(i).compare(bname) == 0) |
229 |
|
return kTRUE; |
230 |
|
} |
231 |
|
|
241 |
|
//-------------------------------------------------------------------------------------------------- |
242 |
|
Bool_t OutputMod::Notify() |
243 |
|
{ |
244 |
< |
// Todo |
244 |
> |
// On first notify, loop over list of branches to determine the list of kept branches. |
245 |
> |
|
246 |
> |
if (GetNEventsProcessed() != 0) |
247 |
> |
return kTRUE; |
248 |
|
|
249 |
|
TTree *tree=const_cast<TTree*>(GetSel()->GetTree()); |
250 |
|
if (!tree) |
281 |
|
// Loop over requested branches and load them. |
282 |
|
|
283 |
|
for (UInt_t i=0; i<GetNBranches(); ++i) { |
284 |
< |
LoadBranch(fBrNameList.At(i)->c_str()); |
284 |
> |
LoadBranch(fBrNameList.at(i).c_str()); |
285 |
|
} |
286 |
|
} |
287 |
|
|
288 |
|
//-------------------------------------------------------------------------------------------------- |
289 |
|
void OutputMod::Process() |
290 |
|
{ |
291 |
< |
// Pre and post event processing at once?! |
291 |
> |
// Write out the kept branches of the current event. Make sure the meta information is |
292 |
> |
// correctly updated. |
293 |
> |
|
294 |
> |
if (GetSel()->GetCurEvt() == fLastSeenEvt) { |
295 |
> |
Warning("Process", "Event with %ul already seen", fLastSeenEvt); |
296 |
> |
return; |
297 |
> |
} |
298 |
> |
fLastSeenEvt = GetSel()->GetCurEvt(); |
299 |
|
|
300 |
+ |
if (GetSel()->GetCurEvt() == fLastWrittenEvt) { |
301 |
+ |
Warning("Process", "Event with %ul already written", fLastWrittenEvt); |
302 |
+ |
return; |
303 |
+ |
} |
304 |
+ |
fLastWrittenEvt = GetSel()->GetCurEvt(); |
305 |
+ |
++fCounter; |
306 |
+ |
|
307 |
+ |
// prepare for tree filling |
308 |
|
fTreeWriter->BeginEvent(fDoReset); |
309 |
|
|
310 |
< |
if (GetNEventsProcessed() == 0 && fCheckDep) { |
311 |
< |
ResolveDep(kTRUE); |
310 |
> |
if (GetNEventsProcessed() == 0 && fCheckTamBr) { |
311 |
> |
CheckAndResolveDep(fKeepTamBr); |
312 |
|
} |
313 |
|
|
314 |
+ |
// load all our branches |
315 |
|
LoadBranches(); |
193 |
– |
// load additional branches |
194 |
– |
//LoadBranch("EventHeader"); |
316 |
|
|
317 |
+ |
// pass our branches to tree writer if on first event |
318 |
|
if (GetNEventsProcessed() == 0) { |
319 |
< |
SetupBranches(); |
319 |
> |
SetupBranches(); |
320 |
> |
} |
321 |
> |
|
322 |
> |
// reset per file quantities if a new file was opened |
323 |
> |
if (fTreeWriter->GetFileNumber()!=fFileNum) { |
324 |
> |
fRunmap.clear(); |
325 |
> |
fRunEntries = 0; |
326 |
> |
fL1Entries = -1; |
327 |
> |
fHltEntries = -1; |
328 |
> |
fFileNum = fTreeWriter->GetFileNumber(); |
329 |
> |
} |
330 |
> |
|
331 |
> |
UInt_t runnum = GetEventHeader()->RunNum(); |
332 |
> |
|
333 |
> |
// store look ahead information |
334 |
> |
if (fRunEntries>0) { |
335 |
> |
fLaHeader->SetRunNum(runnum); |
336 |
> |
fLATree->Fill(); |
337 |
> |
} |
338 |
> |
|
339 |
> |
// fill event header |
340 |
> |
fEventHeader->SetEvtNum(GetEventHeader()->EvtNum()); |
341 |
> |
fEventHeader->SetLumiSec(GetEventHeader()->LumiSec()); |
342 |
> |
fEventHeader->SetRunNum(runnum); |
343 |
> |
|
344 |
> |
// fill all event header |
345 |
> |
// *** note that we need to read an existing tree in |
346 |
> |
// the future to make sure we can do skims of skims *** |
347 |
> |
FillAllEventHeader(kFALSE); |
348 |
> |
|
349 |
> |
// look-up if entry is in map |
350 |
> |
map<UInt_t,Int_t>::iterator riter = fRunmap.find(runnum); |
351 |
> |
if (riter != fRunmap.end()) { // found existing run info |
352 |
> |
Int_t runentry = riter->second; |
353 |
> |
fEventHeader->SetRunEntry(runentry); |
354 |
> |
|
355 |
> |
IncNEventsProcessed(); |
356 |
> |
fTreeWriter->EndEvent(fDoReset); |
357 |
> |
return; |
358 |
|
} |
359 |
|
|
360 |
+ |
// fill new run info |
361 |
+ |
Int_t runentry = fRunEntries; |
362 |
+ |
++fRunEntries; |
363 |
+ |
fEventHeader->SetRunEntry(runentry); |
364 |
+ |
fRunmap.insert(pair<UInt_t,Int_t>(runnum,runentry)); |
365 |
+ |
fRunInfo->SetRunNum(runnum); |
366 |
+ |
|
367 |
+ |
Int_t l1entry = fL1Entries; |
368 |
+ |
FillL1Info(); |
369 |
+ |
fRunInfo->SetL1Entry(l1entry); |
370 |
+ |
|
371 |
+ |
Int_t hltentry = fHltEntries; |
372 |
+ |
FillHltInfo(); |
373 |
+ |
fRunInfo->SetHltEntry(hltentry); |
374 |
+ |
|
375 |
+ |
fRunTree->Fill(); |
376 |
+ |
|
377 |
|
IncNEventsProcessed(); |
378 |
|
fTreeWriter->EndEvent(fDoReset); |
379 |
|
} |
380 |
|
|
381 |
|
//-------------------------------------------------------------------------------------------------- |
382 |
+ |
void OutputMod::ProcessAll() |
383 |
+ |
{ |
384 |
+ |
// Called by the Selector class for events that were skipped. |
385 |
+ |
|
386 |
+ |
if (GetSel()->GetCurEvt() == fLastSeenEvt) |
387 |
+ |
return; |
388 |
+ |
fLastSeenEvt = GetSel()->GetCurEvt(); |
389 |
+ |
++fCounter; |
390 |
+ |
|
391 |
+ |
FillAllEventHeader(kTRUE); |
392 |
+ |
} |
393 |
+ |
|
394 |
+ |
//-------------------------------------------------------------------------------------------------- |
395 |
+ |
void OutputMod::RequestBranch(const char *bname) |
396 |
+ |
{ |
397 |
+ |
// Request given branch from TAM. |
398 |
+ |
|
399 |
+ |
if (GetNBranches()>=fNBranchesMax) { |
400 |
+ |
Error("RequestBranch", "Can not request branch for %bname" |
401 |
+ |
"since maximum number of branches [%d] is reached", bname, fNBranchesMax); |
402 |
+ |
return; |
403 |
+ |
} |
404 |
+ |
|
405 |
+ |
fBranches[GetNBranches()-1] = 0; |
406 |
+ |
TAModule::ReqBranch(bname, fBranches[GetNBranches()-1]); |
407 |
+ |
} |
408 |
+ |
|
409 |
+ |
//-------------------------------------------------------------------------------------------------- |
410 |
|
void OutputMod::SetupBranches() |
411 |
|
{ |
412 |
|
// Setup branches in tree writer. |
413 |
|
|
414 |
|
for (UInt_t i=0; i<GetNBranches(); ++i) { |
415 |
< |
const char *bname = fBrNameList.At(i)->c_str(); |
416 |
< |
const char *cname = fBrClassList.At(i)->c_str(); |
415 |
> |
const char *bname = fBrNameList.at(i).c_str(); |
416 |
> |
const char *cname = fBrClassList.at(i).c_str(); |
417 |
|
if (!fBranches[i]) { |
418 |
|
Error("SetupBranches", "Pointer for branch with name %s and class %s is NULL.", |
419 |
|
bname, cname); |
420 |
|
continue; |
421 |
|
} |
422 |
< |
fTreeWriter->AddBranch(bname,cname,&fBranches[i]); |
422 |
> |
fTreeWriter->AddBranch(bname, cname, &fBranches[i]); |
423 |
|
} |
424 |
|
} |
425 |
|
|
426 |
|
//-------------------------------------------------------------------------------------------------- |
427 |
|
void OutputMod::SlaveBegin() |
428 |
|
{ |
429 |
< |
// Todo |
225 |
< |
|
226 |
< |
// request here branches we want |
227 |
< |
//ReqBranch("EventHeader", fEventHeader); |
429 |
> |
// Setup the tree writer and create branches that can already be created at this point. |
430 |
|
|
431 |
|
// setup tree writer |
432 |
|
fTreeWriter = new TreeWriter(fTreeName, kFALSE); |
439 |
|
fTreeWriter->AddTree(fTreeName); |
440 |
|
fTreeWriter->DoBranchRef(fTreeName); |
441 |
|
|
442 |
+ |
// deal with my own tree objects |
443 |
+ |
fEventHeader = new EventHeader; |
444 |
+ |
fTreeWriter->AddBranch(GetSel()->GetEvtHdrName(), &fEventHeader); |
445 |
+ |
|
446 |
+ |
// deal with other trees |
447 |
+ |
const char *tname = 0; |
448 |
+ |
fRunInfo = new RunInfo; |
449 |
+ |
tname = GetSel()->GetRunTreeName(); |
450 |
+ |
fTreeWriter->AddBranchToTree(tname, GetSel()->GetRunInfoName(), &fRunInfo); |
451 |
+ |
fTreeWriter->SetAutoFill(tname, 0); |
452 |
+ |
fRunTree = fTreeWriter->GetTree(tname); |
453 |
+ |
fLaHeader = new LAHeader; |
454 |
+ |
tname = GetSel()->GetLATreeName(); |
455 |
+ |
fTreeWriter->AddBranchToTree(tname, GetSel()->GetLAHdrName(), &fLaHeader); |
456 |
+ |
fTreeWriter->SetAutoFill(tname,0); |
457 |
+ |
fLATree = fTreeWriter->GetTree(tname); |
458 |
+ |
fAllEventHeader = new EventHeader; |
459 |
+ |
tname = GetSel()->GetAllEvtTreeName(); |
460 |
+ |
fTreeWriter->AddBranchToTree(tname, GetSel()->GetAllEvtHdrBrn(), &fAllEventHeader); |
461 |
+ |
fAllTree = fTreeWriter->GetTree(tname); |
462 |
+ |
|
463 |
+ |
// get pointer to fAllTreeIn todo |
464 |
+ |
// todo |
465 |
|
// deal here with published objects |
466 |
+ |
// todo |
467 |
|
|
468 |
|
// create TObject space for TAM |
469 |
|
fBranches = new TObject*[fNBranchesMax]; |
470 |
+ |
|
471 |
+ |
// adjust checks for TAM branches |
472 |
+ |
if (fKeepTamBr) |
473 |
+ |
fCheckTamBr = kTRUE; |
474 |
|
} |
475 |
|
|
476 |
|
//-------------------------------------------------------------------------------------------------- |
477 |
|
void OutputMod::SlaveTerminate() |
478 |
|
{ |
479 |
< |
// Todo |
479 |
> |
// Terminate tree writing and do cleanup. |
480 |
|
|
481 |
|
delete fTreeWriter; |
482 |
|
fTreeWriter = 0; |
483 |
|
|
484 |
< |
delete[] fBranches; |
485 |
< |
} |
486 |
< |
|
487 |
< |
//-------------------------------------------------------------------------------------------------- |
258 |
< |
|
259 |
< |
void OutputMod::ResolveDep(Bool_t solve) |
260 |
< |
{ |
261 |
< |
// Todo |
262 |
< |
|
263 |
< |
const THashTable &ht = GetSel()->GetBranchTable(); |
484 |
> |
delete fEventHeader; |
485 |
> |
delete fRunInfo; |
486 |
> |
delete fLaHeader; |
487 |
> |
delete fAllEventHeader; |
488 |
|
|
489 |
< |
TIterator *iter = ht.MakeIterator(); |
266 |
< |
const TAMBranchInfo *next = dynamic_cast<const TAMBranchInfo*>(iter->Next()); |
267 |
< |
|
268 |
< |
while (next) { |
269 |
< |
const TAMBranchInfo *cur = next; |
270 |
< |
next = dynamic_cast<const TAMBranchInfo*>(iter->Next()); |
271 |
< |
Bool_t isloaded = cur->IsLoaded(); |
272 |
< |
if (!isloaded) |
273 |
< |
continue; |
274 |
< |
|
275 |
< |
const char *bname = cur->GetName(); |
276 |
< |
if (IsAcceptedBranch(bname)) |
277 |
< |
continue; |
278 |
< |
|
279 |
< |
TreeBranchLoader *loader = dynamic_cast<TreeBranchLoader*>(cur->GetLoader()); |
280 |
< |
if (!loader) |
281 |
< |
continue; |
282 |
< |
|
283 |
< |
TBranch *br = loader->GetBranch(); |
284 |
< |
if (!br) |
285 |
< |
continue; |
286 |
< |
|
287 |
< |
const char *cname = br->GetClassName(); |
489 |
> |
delete[] fBranches; |
490 |
|
|
491 |
< |
if (solve) { |
492 |
< |
Info("ResolveDep", "Resolving dependency for auto-loaded branch %s and class %s", |
493 |
< |
bname,cname); |
292 |
< |
CheckAndAddBranch(bname, cname); |
293 |
< |
} else { |
294 |
< |
Warning("ResolveDep", "Unresolved dependency for auto-loaded branch %s and class %s", |
295 |
< |
bname,cname); |
296 |
< |
} |
297 |
< |
} |
491 |
> |
Double_t frac = 100.*GetNEventsProcessed()/fCounter; |
492 |
> |
Info("SlaveTerminate", "Stored %.2g%% events (%ld out of %ld)", |
493 |
> |
frac, GetNEventsProcessed(), fCounter); |
494 |
|
} |