21 std::cout <<
" This application is currently only available in the analysis releases \n \
22 Please setup an AthAnalysisBase release to use this application." << std::endl;
33 #include "TApplication.h"
35 #include "TDirectory.h"
37 #include "TObjString.h"
51 lbx() : nExpected(0),nSeen(0) {}
54 bool fromSuspect =
false;
58 const char* optstring =
"m";
59 bool showMissing =
false;
63 {
"showMissing", no_argument , NULL,
'm'}
71 while ((option = getopt_long(
argc,
argv,
75 showMissing =
true;nOptions++;
78 printf(
"Please supply a valid option to the program. Exiting\n");
88 std::cout <<
"Usage: <lumicalcfile.root> <list of xAOD or D3PD>" << std::endl;
89 std::cout <<
"Option: -m lists run numbers with any missing lumi" << std::endl;
90 std::cout <<
"" << std::endl;
91 std::cout <<
"Further Documentation: see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/AthAnalysisBase#How_to_check_the_luminosity_cove " <<std::endl;
94 gSystem->Load(
"libTree.so");
98 std::map<uint, std::map<uint, lbx> > lbxs;
104 for(
int i=2+nOptions;
i<
argc;
i++) {
106 if(
s.find(
".xml")==std::string::npos)
continue;
115 std::vector<std::string> lumiFiles;
118 for(
int i=1+nOptions;
i<
argc;
i++) {
121 if(
s.find(
".root")==std::string::npos)
continue;
123 if(
file==0)
continue;
127 TTree *
tmp = (TTree*)
file->Get(
"LumiMetaData" );
129 std::cout <<
"is lumicalc [ok]" << std::endl;
131 lumiFiles.push_back(
s);
138 if(
file->Get(
"MetaData")!=0) {
139 TTree* metaTree =
static_cast<TTree*
>(
file->Get(
"MetaData"));
142 bool useTEvent(
false);
146 metaTree->SetMakeClass(1);
148 std::vector<unsigned int> startRunNumber;
149 std::vector<unsigned int> stopRunNumber;
152 std::vector<unsigned int> eventsExpected;
166 if(metaTree->FindBranch(
"LumiBlocksAux.")) {
167 if(metaTree->FindBranch(
"LumiBlocksAux.")->GetSplitLevel()==0) {
168 std::cout <<
" Unable to read unsplit LumiBlocksAux" << std::endl;
173 metaTree->SetBranchAddress(
"LumiBlocksAux.startRunNumber",&startRunNumber);
174 metaTree->SetBranchAddress(
"LumiBlocksAux.stopRunNumber",&stopRunNumber);
177 metaTree->SetBranchAddress(
"LumiBlocksAux.eventsExpected",&eventsExpected);
178 metaTree->SetBranchAddress(
"LumiBlocksAux.eventsSeen",&
eventsSeen);
183 std::cout <<
"...xAOD LumiBlocks";
184 for(
int ii=0;ii<metaTree->GetEntries();ii++) {
187 metaTree->GetEntry(ii);
188 for(
unsigned int j=0;j<startRunNumber.size();j++) {
190 r->setStartRunNumber(startRunNumber.at(j));
r->setStopRunNumber(stopRunNumber.at(j));
192 r->setEventsExpected(eventsExpected.at(j));
r->setEventsSeen(
eventsSeen.at(j));
197 for(
auto lbr : *lbrs) {
199 if(lbr->startLumiBlockNumber()!=lbr->stopLumiBlockNumber()) {std::cout <<
" Unexpected behaviour. Please report! " << std::endl;
exit(1);}
201 lbxs[
runNum][
lb].nSeen += lbr->eventsSeen();
202 if(lbxs[
runNum][
lb].nExpected!=0 && lbxs[
runNum][
lb].nExpected != lbr->eventsExpected()) {
203 std::cout <<
"...mismatch on expected events in [run,lb]=[" <<
runNum <<
"," <<
lb <<
"] got " << lbr->eventsExpected() <<
" but had " << lbxs[
runNum][
lb].nExpected << std::endl;
204 std::cout <<
"...PLEASE REPORT THIS to hn-atlas-PATHelp@cern.ch ... for now I will assume the larger number is correct" << std::endl;
205 if(lbxs[
runNum][
lb].nExpected < lbr->eventsExpected()) lbxs[
runNum][
lb].nExpected = lbr->eventsExpected();
207 else if(lbxs[
runNum][
lb].nExpected==0) lbxs[
runNum][
lb].nExpected=lbr->eventsExpected();
213 std::cout <<
"...ok" << std::endl;
214 if(!useTEvent) {
delete lbrs;
delete lbrs_aux; }
224 if(metaTree->FindBranch(
"IncompleteLumiBlocksAux.")) {
225 if(metaTree->FindBranch(
"IncompleteLumiBlocksAux.")->GetSplitLevel()==0) {
226 std::cout <<
" Unable to read unsplit IncompleteLumiBlocksAux" << std::endl;
231 metaTree->ResetBranchAddresses();
232 metaTree->SetBranchAddress(
"IncompleteLumiBlocksAux.startRunNumber",&startRunNumber);
233 metaTree->SetBranchAddress(
"IncompleteLumiBlocksAux.stopRunNumber",&stopRunNumber);
234 metaTree->SetBranchAddress(
"IncompleteLumiBlocksAux.startLumiBlockNumber",&
startLumiBlockNumber);
235 metaTree->SetBranchAddress(
"IncompleteLumiBlocksAux.stopLumiBlockNumber",&
stopLumiBlockNumber);
236 metaTree->SetBranchAddress(
"IncompleteLumiBlocksAux.eventsExpected",&eventsExpected);
237 metaTree->SetBranchAddress(
"IncompleteLumiBlocksAux.eventsSeen",&
eventsSeen);
242 std::cout <<
"...xAOD IncompleteLumiBlocks";
243 for(
int ii=0;ii<metaTree->GetEntries();ii++) {
246 metaTree->GetEntry(ii);
247 for(
unsigned int j=0;j<startRunNumber.size();j++) {
249 r->setStartRunNumber(startRunNumber.at(j));
r->setStopRunNumber(stopRunNumber.at(j));
251 r->setEventsExpected(eventsExpected.at(j));
r->setEventsSeen(
eventsSeen.at(j));
256 for(
auto lbr : *lbrs) {
258 if(lbr->startLumiBlockNumber()!=lbr->stopLumiBlockNumber()) {std::cout <<
" Unexpected behaviour. Please report! " << std::endl;
exit(1);}
260 lbxs[
runNum][
lb].nSeen += lbr->eventsSeen();
261 if(lbxs[
runNum][
lb].nExpected!=0 && lbxs[
runNum][
lb].nExpected != lbr->eventsExpected()) {
262 std::cout <<
"...mismatch on expected events in [run,lb]=[" <<
runNum <<
"," <<
lb <<
"] got " << lbr->eventsExpected() <<
" but had " << lbxs[
runNum][
lb].nExpected << std::endl;
263 std::cout <<
"...PLEASE REPORT THIS to hn-atlas-PATHelp@cern.ch ... for now I will assume the larger number is correct" << std::endl;
264 if(lbxs[
runNum][
lb].nExpected < lbr->eventsExpected()) lbxs[
runNum][
lb].nExpected = lbr->eventsExpected();
266 else if(lbxs[
runNum][
lb].nExpected==0) lbxs[
runNum][
lb].nExpected=lbr->eventsExpected();
272 std::cout <<
"...ok" << std::endl;
273 if(!useTEvent) {
delete lbrs; lbrs = 0;
delete lbrs_aux; lbrs_aux=0; }
285 if(metaTree->FindBranch(
"SuspectLumiBlocksAux.")) {
286 if(metaTree->FindBranch(
"SuspectLumiBlocksAux.")->GetSplitLevel()==0) {
287 std::cout <<
" Unable to read unsplit SuspectLumiBlocks" << std::endl;
292 metaTree->ResetBranchAddresses();
293 metaTree->SetBranchAddress(
"SuspectLumiBlocksAux.startRunNumber",&startRunNumber);
294 metaTree->SetBranchAddress(
"SuspectLumiBlocksAux.stopRunNumber",&stopRunNumber);
296 metaTree->SetBranchAddress(
"SuspectLumiBlocksAux.stopLumiBlockNumber",&
stopLumiBlockNumber);
297 metaTree->SetBranchAddress(
"SuspectLumiBlocksAux.eventsExpected",&eventsExpected);
298 metaTree->SetBranchAddress(
"SuspectLumiBlocksAux.eventsSeen",&
eventsSeen);
303 std::cout <<
"...xAOD SuspectLumiBlocksAux";
304 for(
int ii=0;ii<metaTree->GetEntries();ii++) {
307 metaTree->GetEntry(ii);
308 for(
unsigned int j=0;j<startRunNumber.size();j++) {
310 r->setStartRunNumber(startRunNumber.at(j));
r->setStopRunNumber(stopRunNumber.at(j));
312 r->setEventsExpected(eventsExpected.at(j));
r->setEventsSeen(
eventsSeen.at(j));
316 for(
auto lbr : *lbrs) {
318 if(lbr->startLumiBlockNumber()!=lbr->stopLumiBlockNumber()) {std::cout <<
" Unexpected behaviour. Please report! " << std::endl;
exit(1);}
320 lbxs[
runNum][
lb].nSeen += lbr->eventsSeen();
321 lbxs[
runNum][
lb].fromSuspect =
true;
322 if(lbxs[
runNum][
lb].nExpected!=0 && lbxs[
runNum][
lb].nExpected != lbr->eventsExpected()) {
323 std::cout <<
"...mismatch on expected events in [run,lb]=[" <<
runNum <<
"," <<
lb <<
"] got " << lbr->eventsExpected() <<
" but had " << lbxs[
runNum][
lb].nExpected << std::endl;
324 std::cout <<
"...PLEASE REPORT THIS to hn-atlas-PATHelp@cern.ch ... for now I will assume the larger number is correct" << std::endl;
325 if(lbxs[
runNum][
lb].nExpected < lbr->eventsExpected()) lbxs[
runNum][
lb].nExpected = lbr->eventsExpected();
327 else if(lbxs[
runNum][
lb].nExpected==0) lbxs[
runNum][
lb].nExpected=lbr->eventsExpected();
334 std::cout <<
"...ok" << std::endl;
335 if(!useTEvent) {
delete lbrs; lbrs = 0;
delete lbrs_aux; lbrs_aux=0; }
338 if(ok) {
file->Close();
delete file;
continue; }
342 if(
file->GetDirectory(
"Lumi")==0) { std::cout <<
"...no Lumi folder. Skipping" << std::endl; }
346 TTree* lumiTree =
dynamic_cast<TTree*
>(
gDirectory->Get(
"lumiTree"));
348 std::cout <<
"...lumiTree";
351 lumiTree->SetBranchAddress(
"lumi",&in);
352 for(
int j=0;j<lumiTree->GetEntries();j++) {
353 lumiTree->GetEntry(j);
356 std::cout <<
"...ok" << std::endl;
360 for( Int_t j = 0; j <
keys->GetEntries(); ++j ) {
361 TKey *
key =
dynamic_cast<TKey*
>(
keys->At( j ) );
362 TObjString* ostring = (TObjString*)
key->ReadObjectAny( TObjString::Class() );
363 if( ! ostring ) { std::cout <<
"...skipping object: " <<
key->GetName() << std::endl;
continue;}
365 if( ostring->GetString().BeginsWith(
"<?xml version=" ) && ostring->GetString().Contains(
"DOCTYPE LumiRangeCollection" ) ) {
367 std::cout <<
"...ok" << std::endl;
378 std::stringstream definitelySuspect;
379 std::stringstream possiblySuspect;
380 for(
auto&
it : lbxs) {
382 for(
auto& it2 :
it.second) {
383 uint lbn = it2.first;
384 if(it2.second.nSeen > it2.second.nExpected) { fromXAODSuspect.
AddRunLumiBlock(
runNum,lbn);
continue; }
394 l.AddGRL(fromXAOD); lIncomplete.
AddGRL(fromXAODIncomplete); lSuspect.
AddGRL(fromXAODSuspect);lPossiblySuspect.
AddGRL(fromXAODPossiblySuspect);
400 double totalLumi = 0;
double totalLumiIncomplete = 0;
double totalLumiSuspect=0;
double allMissing=0;
double totalLumiPossiblySuspect=0;
401 std::map<UInt_t, float> missingRuns;std::map<UInt_t,bool> allRuns;std::set<UInt_t> incompleteRuns;std::set<UInt_t> suspectRuns;
402 std::map<UInt_t, std::string> missingRunLB;
411 if(lumiFiles.size()==0) {
412 std::cout <<
"FATAL: No lumicalc file provided, please include at least one lumicalc file in your input list" << std::endl;
416 std::cout <<
"Reading LumiMetaData...";
418 for(
auto lfile : lumiFiles) {
419 TFile *lumicalcFile = TFile::Open(
lfile.c_str());
420 if(lumicalcFile==0) {
421 std::cout <<
"Could not open lumicalc file: " <<
argv[1+nOptions] << std::endl;
425 TTree *
tmp = (TTree*)lumicalcFile->Get(
"LumiMetaData" );
427 std::cout <<
"Could not find LumiMetaData tree in lumicalc file: " <<
argv[1+nOptions] << std::endl;
433 UInt_t runNbr=0;Float_t intLumi=0;TBranch *b_runNbr;TBranch *b_intLumi;
434 UInt_t
lb=0.; TBranch *b_lb;
435 if(
tmp->SetBranchAddress(
"RunNbr",&runNbr,&b_runNbr)!=0) {
436 std::cout <<
"Could not find RunNbr branch in LumiMetaData TTree" << std::endl;
return 0;
438 if(
tmp->SetBranchAddress(
"LBStart",&
lb,&b_lb)!=0) {
439 std::cout <<
"Could not find LBStart branch in Data TTree" << std::endl;
return 0;
441 if(
tmp->SetBranchAddress(
"IntLumi",&intLumi,&b_intLumi)!=0) {
442 std::cout <<
"Could not find IntLumi branch in Data TTree" << std::endl;
return 0;
446 int startMissingBlock = -1;UInt_t lastRunNumber=0;
int lastLb=0;
double missingLumi=0;
449 b_runNbr->GetEntry(
i);b_intLumi->GetEntry(
i);b_lb->GetEntry(
i);
452 bool hasLumi =
l.HasRunLumiBlock(runNbr,
lb);
453 if(hasLumi) totalLumi += intLumi;
454 else if(lIncomplete.
HasRunLumiBlock(runNbr,
lb)) {hasLumi=
true; totalLumiIncomplete += intLumi; incompleteRuns.insert(runNbr);}
455 else if(lSuspect.
HasRunLumiBlock(runNbr,
lb)) {hasLumi=
true;totalLumiSuspect += intLumi; suspectRuns.insert(runNbr); definitelySuspect <<
"(" << runNbr <<
"," <<
lb <<
"),";}
457 if(lPossiblySuspect.
HasRunLumiBlock(runNbr,
lb)) {totalLumiPossiblySuspect += intLumi; possiblySuspect <<
"(" << runNbr <<
"," <<
lb <<
"),"; }
459 if(!hasLumi && intLumi==0.) hasLumi=
true;
460 if((lastRunNumber!=runNbr&&startMissingBlock>=0) || (hasLumi && startMissingBlock>=0)) {
462 missingRunLB[lastRunNumber] += ((startMissingBlock==lastLb) ?
TString::Format(
"%d",startMissingBlock) :
TString::Format(
"%d-%d",startMissingBlock,lastLb));
463 missingRunLB[lastRunNumber] +=
",";
464 if(showMissing) std::cout <<
"[" << lastRunNumber <<
"," << startMissingBlock <<
"-" << lastLb <<
"," << missingLumi <<
"]";
465 missingRuns[lastRunNumber]+=missingLumi;
466 allMissing+=missingLumi; missingLumi=0;
467 startMissingBlock=-1;
469 if(!hasLumi && startMissingBlock==-1) {startMissingBlock=
lb;missingLumi=intLumi/1E6;}
470 else if(!hasLumi) { missingLumi+=(intLumi/1E6); }
471 lastRunNumber=runNbr;lastLb=
lb;
472 allRuns[runNbr] =
true;
474 lumicalcFile->Close();
475 allMissing += missingLumi;
477 missingRuns[lastRunNumber] += missingLumi;
478 missingRunLB[lastRunNumber] += ((startMissingBlock==lastLb) ?
TString::Format(
"%d",startMissingBlock) :
TString::Format(
"%d-%d",startMissingBlock,lastLb));
479 missingRunLB[lastRunNumber] +=
",";
482 std::cout <<
"Done" << std::endl;
483 std::cout <<
"--------------------------------------------" << std::endl;
484 std::cout <<
"***************LUMI REPORT******************" << std::endl << std::endl;
488 if(possiblySuspect.str().size()) {
489 std::cout <<
"Possibly suspect lumiblocks: " << possiblySuspect.str() << std::endl;
491 if(definitelySuspect.str().size()) {
492 std::cout <<
"WARNING ... Definitely suspect lumiblocks (please report this!): " << definitelySuspect.str() << std::endl;
494 std::cout << std::endl <<
"No definitely suspect lumiblocks, that's good!";
499 std::cout << std::endl <<
"Runs with incomplete blocks: ";
500 for(
auto r : incompleteRuns) {
501 std::cout <<
r <<
",";
503 std::cout << std::endl <<
"Runs with missing blocks (missing blocks in brackets): " << std::endl << std::endl;
504 for(
auto it=missingRuns.begin();
it!=missingRuns.end();++
it) {
505 std::cout <<
" " <<
it->first <<
": " <<
it->second <<
" pb-1 (" << missingRunLB[
it->first] <<
")" << std::endl;
507 std::cout << std::endl <<
"Complete runs: ";
509 if(missingRuns.find(
it->first) == missingRuns.end() && incompleteRuns.find(
it->first)==incompleteRuns.end() && suspectRuns.find(
it->first) == suspectRuns.end()) std::cout <<
it->first <<
",";
511 std::cout << std::endl;
513 std::cout << std::endl;
514 std::cout <<
"Complete Luminosity = " << totalLumi/1E6 <<
" pb-1" << std::endl;
515 if(totalLumiIncomplete) std::cout <<
"Incomplete Luminosity = " << totalLumiIncomplete/1E6 <<
" pb-1 (this is partially processed lumi blocks)" << std::endl;
516 if(totalLumiSuspect) std::cout <<
"Definitely Suspect Luminosity = " << totalLumiSuspect/1E6 <<
" pb-1 (this is problematic luminosity... please report!)" << std::endl;
517 std::cout <<
"Complete+Incomplete";
518 if(totalLumiSuspect) std::cout <<
"+Suspect";
519 std::cout <<
" Luminosity = " << (totalLumi+totalLumiIncomplete+totalLumiSuspect)/1E6 <<
" pb-1" << std::endl;
520 if(totalLumiPossiblySuspect) {
521 std::cout <<
" (of which is possibly suspect = " << totalLumiPossiblySuspect/1E6 <<
" pb-1 (caused by jobs that did not finish correctly))" << std::endl;
524 std::cout <<
"(Missing Lumonisity = " << allMissing <<
" pb-1) (this is luminosity in your lumicalc files that you appear not to have run over)";
526 std::cout << std::endl;