21 #include <Riostream.h> 22 #include "TObjString.h" 23 #include "TObjArray.h" 29 #include "TDirectory.h" 35 #include "TGridResult.h" 36 #include "TGraphAsymmErrors.h" 46 #include "TFileMerger.h" 47 #include "TFitResultPtr.h" 48 #include "THashList.h" 51 #include "AliMergeableCollection.h" 52 #include "AliCounterCollection.h" 54 #include "AliAnalysisMuonUtility.h" 57 #include "AliCDBManager.h" 58 #include "AliCDBStorage.h" 60 #include "AliCDBEntry.h" 61 #include "AliMUONCDB.h" 62 #include "AliMUONTriggerEfficiencyCells.h" 110 return SetCondition(physSel, trigClassName, centrality, itrackSel, imatch, imethod, kFALSE);
118 if ( ! trigOut->GetMergeableCollection() ) {
119 AliError(Form(
"Cannot find %s in %s",outputName,filename));
135 if ( idxFromRun >= 0 ) obj =
fRunMap[idxFromRun];
138 obj->SetUniqueID(
fRunMap.size());
157 if ( irpc == 0 || irpc == 9 ) {
158 Int_t arr[] = {26,27,28,29,48,49,50,51,68,69,84,85,100,101,113};
159 Int_t nBoards =
sizeof(arr)/
sizeof(arr[0]);
160 boards.Set(nBoards,arr);
162 for (
Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
164 else if ( irpc == 1 || irpc == 8 ) {
165 Int_t arr[] = {9,10,11,30,31,32,33,52,53,54,55,70,71,86,87,102,103,114};
166 Int_t nBoards =
sizeof(arr)/
sizeof(arr[0]);
167 boards.Set(nBoards,arr);
169 for (
Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
171 else if ( irpc == 2 || irpc == 7 ) {
172 Int_t arr[] = {12,13,34,35,56,57,72,73,88,89,104,105,115};
173 Int_t nBoards =
sizeof(arr)/
sizeof(arr[0]);
174 boards.Set(nBoards,arr);
176 for (
Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
178 else if ( irpc == 3 || irpc == 6 ) {
179 Int_t arr[] = {14,15,36,37,58,59,74,75,90,91,106,107,116};
180 Int_t nBoards =
sizeof(arr)/
sizeof(arr[0]);
181 boards.Set(nBoards,arr);
183 for (
Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
185 else if ( irpc == 4 || irpc == 5 ) {
186 Int_t arr[] = {16,38,60,76,92,108,117};
187 Int_t nBoards =
sizeof(arr)/
sizeof(arr[0]);
188 boards.Set(nBoards,arr);
190 for (
Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
192 else if ( irpc == 17 || irpc == 10 ) {
193 Int_t arr[] = {6,7,8,22,23,24,25,44,45,46,47,66,67,82,83,98,99,112};
194 Int_t nBoards =
sizeof(arr)/
sizeof(arr[0]);
195 boards.Set(nBoards,arr);
197 for (
Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
199 else if ( irpc == 16 || irpc == 11 ) {
200 Int_t arr[] = {4,5,20,21,42,43,64,65,80,81,96,97,111};
201 Int_t nBoards =
sizeof(arr)/
sizeof(arr[0]);
202 boards.Set(nBoards,arr);
204 for (
Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
206 else if ( irpc == 15 || irpc == 12 ) {
207 Int_t arr[] = {2,3,18,19,40,41,62,63,78,79,94,95,110};
208 Int_t nBoards =
sizeof(arr)/
sizeof(arr[0]);
209 boards.Set(nBoards,arr);
211 for (
Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
213 else if ( irpc == 14 || irpc == 13 ) {
214 Int_t arr[] = {1,17,39,61,77,93,109};
215 Int_t nBoards =
sizeof(arr)/
sizeof(arr[0]);
216 boards.Set(nBoards,arr);
218 for (
Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
230 clonedEffHistos->SetOwner();
231 TIter next(effHistos);
233 while ( (obj = next()) ) {
234 clonedEffHistos->Add(obj->Clone());
236 return clonedEffHistos;
245 AliInfo(
"Building efficiency map for systematic uncertainties");
248 Double_t xref=0., yref=0., xpt=0., ypt=0.;
253 std::vector<std::string> systKeys = obj->GetSortKeys();
254 Int_t nSysts = systKeys.size();
257 TList* effHistos = obj->GetEffHistoList(
fConditions->UncheckedAt(0)->GetName());
260 for (
Int_t ich=0; ich<4; ich++ ) {
264 TH1* histoList[nSysts*4];
265 TH1* systHistoList[4];
266 for (
Int_t isyst=0; isyst<nSysts; isyst++ ) {
267 effHistos = obj->GetEffHistoList(systKeys[isyst].c_str());
268 for (
Int_t icount=0; icount<4; icount++ ) {
270 histoList[4*isyst+icount] =
static_cast<TH1*
>(effHistos->FindObject(currName.Data()));
272 systHistoList[icount] =
static_cast<TH1*
>(systematicList->FindObject(currName.Data()));
278 checkEffList[isyst] =
new TGraphAsymmErrors(histoList[inum],histoList[iden],
"e0");
281 for (
Int_t icount=0; icount<3; icount++ ) {
291 for (
Int_t ipt=0; ipt<refGraph->GetN(); ipt++ ) {
292 refGraph->GetPoint(ipt,xref,yref);
293 Int_t chosenSyst = -1;
295 for (
Int_t isyst=1; isyst<nSysts; isyst++ ) {
297 graph->GetPoint(ipt,xpt,ypt);
299 Double_t err = (diff > 0.) ? graph->GetErrorYlow(ipt) : graph->GetErrorYhigh(ipt);
300 Double_t absDiff = TMath::Abs(diff);
301 if ( absDiff < nSigmas*err )
continue;
302 if ( foundAbsDiff < absDiff ) {
303 foundAbsDiff = absDiff;
309 AliDebug(2,Form(
"Chamber %i board %i systematicCondition %i",11+ich,ibin,chosenSyst));
310 if ( chosenSyst >= 0 ) {
311 for (
Int_t icount=0; icount<4; icount++ ) {
312 systHistoList[icount]->SetBinContent(ibin,histoList[4*chosenSyst+icount]->GetBinContent(ibin));
318 for (
Int_t icount=0; icount<3; icount++ ) {
320 graph->GetPoint(ipt,xpt,ypt);
321 Double_t errHigh = graph->GetErrorYhigh(ipt);
322 Double_t errLow = graph->GetErrorYlow(ipt);
323 Double_t newEff = ( errLow > errHigh ) ? ypt - errLow : ypt + errHigh;
324 Double_t newCount = TMath::Nint(newEff * countAll);
325 if ( newCount < 0 || newCount > countAll ) {
326 TString warning = Form(
"WARNING: ch %i board %i cath %i systDiff %g newEff %g / %g",11+ich,ibin,icount,newEff-yref,newCount,countAll);
327 if ( newCount < 0 ) newCount = 0;
328 else newCount = countAll;
329 warning += Form(
" => setting numerator to %g",newCount);
330 AliWarning(warning.Data());
332 systHistoList[icount]->SetBinContent(ibin,newCount);
336 for (
Int_t it=0; it<nSysts; it++ )
delete checkEffList[it];
337 for (
Int_t it=0; it<3; it++ )
delete refEffList[it];
339 obj->AddEffHistoList(
"Systematics",systematicList);
350 AliError(
"The list of trigger efficiency object is not initialized. Please use either InitFromLocal, InitFromGrid or InitFromWeb");
361 if ( srcs.Contains(
"raw://") ) {
362 AliError(
"The method assumes that the specified storage is a SpecificStorage. Hence, please replace raw:// with the actual path in alien, e.g.: alien://folder=/alice/data/<year>/OCDB");
365 TObjArray* sourceList = srcs.Tokenize(
",");
367 effHistoLists.SetOwner();
369 TIter next(sourceList);
370 TObjString* src = 0x0;
371 while ( (src = static_cast<TObjString*>(next())) ) {
373 if ( ! readList )
continue;
374 effHistoLists.Add(readList);
386 TObjArray* titleList = sTitles.Tokenize(
",");
390 Int_t nLists = effHistoLists->GetEntriesFast();
392 TString sCanvasNameSuffix(canvasNameSuffix);
393 if ( ! sCanvasNameSuffix.IsNull() && ! sCanvasNameSuffix.BeginsWith(
"_") ) sCanvasNameSuffix.Prepend(
"_");
396 enum {kEff, kDiff, kPull};
401 if ( sOpt.Contains(
"diff") ) {
403 yTitle =
"Eff. - (ref.Eff)";
405 else if ( sOpt.Contains(
"pull") ) {
407 yTitle =
"(Eff - (ref.Eff)) / err";
411 if ( iopt != kEff && nLists <2 ) {
412 AliError(Form(
"You ask for %s but you only provided one set of histograms: nothing done",opt));
416 Bool_t needsLegend = ( nLists > 1 );
419 Int_t colors[] = {kBlack, kRed, kSpring, kTeal, kBlue, kViolet, kMagenta, kOrange, kGray};
426 for (
Int_t itype=0; itype<2; itype++ ) {
428 for (
Int_t icount=0; icount<3; icount++ ) {
430 for (
Int_t ich=0; ich<4; ich++ ) {
435 for (
Int_t ilist=0; ilist<nLists; ilist++ ) {
436 TString currTitle = titleList->At(ilist)->GetName();
437 TList* effHistos =
static_cast<TList*
>(effHistoLists->UncheckedAt(ilist));
439 TH1* histoDen =
static_cast<TH1*
>(effHistos->FindObject(currName.Data()));
441 TH1* histoNum =
static_cast<TH1*
>(effHistos->FindObject(currName.Data()));
443 currName = histoNum->GetName();
444 currName.ReplaceAll(
"Count",
"Eff");
445 currName.Append(Form(
"_%s",currTitle.Data()));
446 graph->SetName(currName.Data());
448 if ( iopt != kEff ) {
450 for (
Int_t ipt=0; ipt<graph->GetN(); ipt++ ) {
451 refGraph->GetPoint(ipt,xref,yref);
452 graph->GetPoint(ipt,xpt,ypt);
454 if ( TMath::Abs(diff) > 1.e-4 ) nDiffs++;
455 if ( iopt == kDiff ) graph->SetPoint(ipt,xpt,diff);
456 else if ( iopt == kPull ) {
457 Double_t err =
GetError(graph->GetErrorYlow(ipt),graph->GetErrorYhigh(ipt));
458 Double_t pull = ( err > 0. ) ? diff/err : 0.;
459 graph->SetPoint(ipt,xpt,pull);
470 currName = graph->GetName();
471 currName.Remove(currName.Length()-currTitle.Length()-5);
472 currName += sCanvasNameSuffix;
473 can =
new TCanvas(currName.Data(),currName.Data(),20*ican,20*ican,600,600);
477 if ( needsLegend && ! leg ) {
478 leg =
new TLegend(0.35, 0.15, 0.65, 0.45);
479 if ( refGraph ) leg->SetHeader(Form(
"Ref.: %s",titleList->At(0)->GetName()));
483 Int_t icolor = ( ilist < ncolors ) ? colors[ilist] : 20+ilist;
484 graph->SetLineColor(icolor);
485 graph->SetMarkerColor(icolor);
486 graph->SetMarkerStyle(20+ilist);
487 graph->SetMarkerSize(0.5);
488 graph->GetXaxis()->SetTitle(xTitle.Data());
489 graph->GetYaxis()->SetTitle(yTitle.Data());
490 graph->Draw((gPad->GetListOfPrimitives()->GetEntries()==0)?
"ap":
"p");
491 if ( leg ) leg->AddEntry(graph,titleList->At(ilist)->GetName(),
"lp");
493 if (leg ) leg->Draw();
509 AliWarning(
"No condition found! Please specify the default efficiency condition with SetEffConditions and then add additional tests with AddSystematicCondition");
519 effHistoLists.SetOwner();
521 for (
Int_t icond=0; icond<nConditions; icond++ ) {
526 effHistoLists.Add(effHistos);
527 titles += Form(
"%s,",condTitle.Data());
530 titles.Remove(TString::kTrailing,
',');
541 AliWarning(
"There is only one merged object: nothing to compare to");
545 AliInfo(
"Comparing the merged efficiencies");
552 TList* effHistos = obj->GetEffHistoList(condition->GetName());
553 effHistoList.Add(effHistos);
554 titles += Form(
"%i_%i,",obj->GetMinRun(),obj->GetMaxRun());
556 titles.Remove(TString::kTrailing,
',');
566 TObjArray* sourceList = srcs.Tokenize(
",");
568 effHistoLists.SetOwner();
572 AliError(
"The method requires to set an efficiency confition with SetEffConditions");
576 TIter next(sourceList);
577 TObjString* src = 0x0;
578 while ( (src = static_cast<TObjString*>(next())) ) {
579 if ( ! src->String().EndsWith(
".root") ) {
580 AliError(
"The method reads files with the output of AliAnalysisTaskTrigChEff and re-compute the efficiency");
585 if ( ! readList )
continue;
586 effHistoLists.Add(readList);
634 TDirectory *savdir = gDirectory;
635 TDirectory *adir = savdir->mkdir(source->GetName());
639 TIter nextkey(source->GetListOfKeys());
640 while ((key = (TKey*)nextkey())) {
641 const char *classname = key->GetClassName();
642 TClass *cl = gROOT->GetClass(classname);
644 if (cl->InheritsFrom(TDirectory::Class())) {
645 source->cd(key->GetName());
646 TDirectory *subdir = gDirectory;
650 }
else if (cl->InheritsFrom(TTree::Class())) {
653 TTree *newT = T->CloneTree(-1,
"fast");
659 obj->Write(obj->GetName(),TObject::kSingleKey);
663 adir->SaveSelf(kTRUE);
675 Bool_t isGrid = (! sPattern.IsNull());
677 if ( sOutDir.IsNull() ) {
679 TString data = sPath(TRegexp(
"/data/"));
680 TString year = sPath(TRegexp(
"/20[0-9][0-9]/"));
681 TString period = sPath(TRegexp(
"/LHC[0-9][0-9][a-z]"));
683 TString pass = AliAnalysisMuonUtility::GetPassName(path);
684 if ( pass.IsNull() ) pass = AliAnalysisMuonUtility::GetPassName(pattern);
685 sOutDir = data+year+period+pass;
686 sOutDir.ReplaceAll(
"//",
"/");
687 sOutDir.Remove(TString::kTrailing,
'/');
688 sOutDir.Remove(TString::kLeading,
'/');
690 else sOutDir = sPath;
691 sOutDir.Remove(TString::kTrailing,
'/');
692 sOutDir.Remove(TString::kLeading,
'/');
695 TGridResult* res = 0x0;
698 if ( ! gGrid ) TGrid::Connect(
"alien://");
699 res = gGrid->Query(path,pattern);
702 if (
gSystem->Exec(
"which curl &> /dev/null") == 0 ) hasCurl = kTRUE;
707 ofstream outFile(localFileList);
710 Bool_t overwrite = kFALSE;
711 for (
Int_t irun=0; irun<rl->GetEntries(); irun++ ) {
712 TString run =
static_cast<TObjString*
>(rl->At(irun))->String();
713 TString dest = Form(
"%s/%09i/QAresults.root",sOutDir.Data(),run.Atoi());
715 if (
gSystem->AccessPathName(destDir.Data()) )
ExecCommand(Form(
"mkdir -p %s",destDir.Data()),kFALSE);
718 if (
gSystem->AccessPathName(dest) == 0 ) {
721 cout <<
"Local file " << dest.Data() <<
" already exist: overwrite? [y/n/ya/na (a=use decision for all)]" << endl;
723 if ( decision.EndsWith(
"a") ) prompt = kFALSE;
724 if ( decision.BeginsWith(
"y") ) overwrite = kTRUE;
725 else overwrite = kFALSE;
727 copyFile = overwrite;
732 for (
Int_t ifile=0; ifile<res->GetEntries(); ifile++ ) {
733 TString inFilename = res->GetKey(ifile,
"turl");
734 if ( inFilename.Contains(run.Data()) ) {
739 if ( src.IsNull() ) {
740 AliWarning(Form(
"Cannot find output for run %s",run.Data()));
744 TFile* outFile = TFile::Open(dest,
"RECREATE");
745 TFile* inFile = TFile::Open(src);
747 TDirectory*
dir =
static_cast<TDirectory*
>(inFile->Get(directory));
752 else isFileOk = kFALSE;
758 src = Form(
"http://aliqamu.web.cern.ch/aliqamu/%s",dest.Data());
762 Int_t cmdOut =
gSystem->Exec(Form(
"curl -f -# -o %s %s",dest.Data(),src.Data()));
763 isFileOk = ( cmdOut == 0 );
765 else isFileOk = TFile::Cp(src.Data(),dest.Data());
769 if ( isFileOk ) outFile <<
gSystem->pwd() <<
"/" << dest.Data() << endl;
771 AliWarning(Form(
"Problem getting run %s",run.Data()));
784 if (
Check() )
return;
786 TString baseNames[3] = {
"Chamber",
"RPC",
"Board"};
787 TString base = baseNames[itype] +
"Eff";
790 AliWarning(
"Please specify RPC");
793 base += Form(
"InRPC%i",irpc);
817 for (
Int_t ich=0; ich<nCh; ich++ ) {
820 TCanvas* can =
new TCanvas(canName.Data(),canName.Data(),25*ich,25*ich,width,height);
821 can->Divide(nColumns,nRows,0,0);
822 can->SetTopMargin(0.);
823 can->SetBottomMargin(0.);
824 for (
Int_t idetelem=0; idetelem<nDetEl; idetelem++ ) {
826 if ( idetelem/nColumns == nRows - 1 ) gPad->SetBottomMargin(0.15);
827 if ( gPad->GetListOfExecs()->GetEntries() == 0 ) gPad->AddExec(
"ZoomPad",
"AliMTRChEffAnalysis::ZoomPad()");
830 Int_t detElemId = idetelem;
835 TLegend* leg =
new TLegend(0.2,legYmin,0.8,legYmax);
836 leg->SetHeader(title.Data());
837 for (
Int_t icount=0; icount<2; icount++ ) {
839 gr->SetLineColor(icount+1);
840 gr->SetMarkerColor(icount+1);
841 gr->SetMarkerStyle(24+2*icount);
842 gr->GetYaxis()->SetRangeUser(minEff,maxEff);
843 gr->GetXaxis()->SetLabelSize(0.07);
844 gr->GetXaxis()->SetTitle(
"");
848 gr->Draw(icount==0?
"ap":
"p");
849 TString legTitle = ( icount==0 ) ?
"bending plane" :
"non-bending plane";
850 leg->AddEntry(gr,legTitle.Data(),
"lp");
851 if ( maxNsigmaOutliers > 0. ) {
853 outliers->SetLineColor(6+icount);
854 outliers->SetMarkerColor(6+icount);
855 outliers->SetMarkerStyle(20+2*icount);
856 outliers->SetLineWidth(2);
858 legTitle.ReplaceAll(
"plane",
"outliers");
859 leg->AddEntry(outliers,legTitle.Data(),
"lp");
873 AliWarning(
"This function is valid only for itype 1 and 2");
877 TString baseNames[3] = {
"Chamber",
"RPC",
"Board"};
878 TString base = baseNames[itype] +
"Stat";
881 AliWarning(
"Please specify RPC");
884 base += Form(
"InRPC%i",irpc);
897 for (
Int_t ich=0; ich<nCh; ich++ ) {
899 TH1* sumHistos = 0x0;
900 for (
Int_t idetelem=0; idetelem<nDetEl; idetelem++ ) {
901 Int_t detElemId = idetelem;
904 histos[idetelem]->SetName(Form(
"%s_stat",histos[idetelem]->GetName()));
905 histos[idetelem]->SetStats(0);
906 if ( sumHistos ) sumHistos->Add(histos[idetelem]);
907 else sumHistos =
static_cast<TH1*
>(histos[idetelem]->Clone(
"sumHistos"));
911 TCanvas* can =
new TCanvas(canName.Data(),canName.Data(),25*ich,25*ich,width,height);
912 can->Divide(nColumns,nRows,0,0);
913 for (
Int_t idetelem=0; idetelem<nDetEl; idetelem++ ) {
915 if ( gPad->GetListOfExecs()->GetEntries() == 0 ) gPad->AddExec(
"ZoomPad",
"AliMTRChEffAnalysis::ZoomPad()");
918 Int_t detElemId = idetelem;
921 TLegend* leg =
new TLegend(0.2,0.65,0.8,0.9);
922 leg->SetHeader(title.Data());
924 gr->SetHistogram(static_cast<TH1F*>(histos[idetelem]));
926 gr->SetMarkerStyle(24);
927 gr->SetMarkerSize(0.5);
928 gr->GetYaxis()->SetRangeUser(minY,maxY);
929 gr->GetYaxis()->SetTitle(Form(
"Tracks in %s / Sum of tracks of %ss in %s",baseNames[itype].
Data(),baseNames[itype].
Data(),baseNames[itype-1].
Data()));
934 if ( maxNsigmaOutliers > 0. ) {
936 outliers->SetLineColor(6);
937 outliers->SetMarkerColor(6);
938 outliers->SetMarkerStyle(20);
939 outliers->SetLineWidth(2);
941 legTitle =
"outliers";
942 leg->AddEntry(outliers,legTitle.Data(),
"lp");
957 AliInfo(
"Drawing the systematic variations");
959 Int_t colors[] = {kBlack, kRed, kSpring, kTeal, kBlue, kViolet, kMagenta, kOrange, kGray};
971 std::vector<std::string> systKeys = obj->GetSortKeys();
972 std::vector<std::string> shortSystName;
973 for ( std::string str : systKeys ) {
976 Int_t nSysts = systKeys.size();
978 TString baseName = Form(
"mergedTrigEff_%i_%i",obj->GetMinRun(),obj->GetMaxRun());
985 for (
Int_t iplane=0; iplane<8; iplane++ ) {
986 effGraphs[iplane].SetOwner();
991 for (
Int_t isyst=0; isyst<nSysts; isyst++ ) {
992 TList* effHistos = obj->GetEffHistoList(systKeys[isyst].c_str());
993 effHistoLists.Add(effHistos);
994 titles += Form(
"%s,",shortSystName[isyst].c_str());
996 for (
Int_t ich=0; ich<4; ich++ ) {
998 TH1* histoDen =
static_cast<TH1*
>(effHistos->FindObject(currName.Data()));
999 for (
Int_t icount=0; icount<2; icount++ ) {
1000 Int_t iplane = 4*icount+ich;
1002 if ( histoDen->GetEntries() > 0 ) {
1004 TH1* histoNum =
static_cast<TH1*
>(effHistos->FindObject(currName.Data()));
1007 effGraphs[iplane].AddAtAndExpand(gr,isyst);
1011 AliWarning(Form(
"No entries in count %i and ch %i for %s",countTypes[icount],ich,shortSystName[isyst].c_str()));
1017 titles.Remove(TString::kTrailing,
',');
1021 TString canName = Form(
"EffSyst_%s",baseName.Data());
1022 Int_t pos = 25*(imerged+1);
1023 TCanvas* can =
new TCanvas(canName.Data(),canName.Data(),pos,pos,1200,800);
1024 can->Divide(4,2,0,0);
1026 for (
Int_t icount=0; icount<2; icount++ ) {
1027 for (
Int_t ich=0; ich<4; ich++ ) {
1028 Int_t iplane = 4*icount+ich;
1030 if ( gPad->GetListOfExecs()->GetEntries() == 0 ) gPad->AddExec(
"ZoomPad",
"AliMTRChEffAnalysis::ZoomPad()");
1031 gPad->SetTicks(1,1);
1033 TLegend* leg =
new TLegend(0.15,0.7,0.9,0.9);
1034 leg->SetHeader(
Namer()->GetHistoName(-1,icount,ich,-1,-1,-1));
1035 TH1* sumHisto = 0x0;
1036 for (
Int_t isyst=1; isyst<nSysts; isyst++ ) {
1037 if ( isEmpty[isyst] == 1 )
continue;
1038 TH1* histo =
new TH1D(Form(
"syst_%s_%s_plane%i_ch%i",baseName.Data(),shortSystName[isyst].c_str(),icount,11+ich),
"",200,-0.1,0.1);
1039 histo->GetXaxis()->SetTitle(
"Eff.-(ref.Eff.)");
1040 histo->GetYaxis()->SetTitle(
"1/#sigma^{2}");
1044 for (
Int_t ipt=0; ipt<gr->GetN(); ipt++ ) {
1045 gr->GetPoint(ipt,xpt,ypt);
1047 Double_t invErr2 = ( err > 0. ) ? 1./(err*err) : 0.;
1048 grRef->GetPoint(ipt,xref,yref);
1051 histo->Fill(diff,invErr2);
1055 sumHisto =
static_cast<TH1*
>(histo->Clone(Form(
"syst_%s_plane%i_ch%i",baseName.Data(),icount,11+ich)));
1056 sumHisto->SetLineColor(1);
1058 leg->AddEntry(sumHisto,
"All systematics",
"l");
1060 else sumHisto->Add(histo);
1061 Int_t icolor = ( isyst < ncolors ) ? colors[isyst] : 20+isyst;
1062 histo->SetLineColor(icolor);
1063 histo->Draw(
"same");
1064 leg->AddEntry(histo,shortSystName[isyst].c_str(),
"l");
1071 canName = Form(
"TriggerEff_3outOf4_syst_%s",baseName.Data());
1073 TCanvas* canSyst =
new TCanvas(canName.Data(),canName.Data(),pos,pos,600,600);
1075 TLegend* leg =
new TLegend(0.15,0.7,0.9,0.4);
1078 for (
Int_t isyst=0; isyst<nSysts; isyst++ ) {
1079 if ( isEmpty[isyst] == 1 )
continue;
1080 histo[isyst] =
new TH1D(Form(
"TriggerEff_syst_%s_%s",shortSystName[isyst].c_str(),baseName.Data()),
"Dispersion of trigger probability (3/4)",200,-0.1,0.1);
1081 histo[isyst]->GetXaxis()->SetTitle(
"Trig. prob. - (ref. trig. prob)");
1082 histo[isyst]->GetYaxis()->SetTitle(
"1/#sigma^{2}");
1085 for (
Int_t ipt=0; ipt<
nDE; ipt++ ) {
1087 for (
Int_t isyst=0; isyst<nSysts; isyst++ ) {
1088 if ( isEmpty[isyst] == 1 )
continue;
1089 Double_t trigProb = 1., trigProbErr2 = 0.;
1090 for (
Int_t icount=0; icount<2; icount++ ) {
1091 for (
Int_t ich=0; ich<4; ich++ ) {
1092 Int_t iplane = 4*icount+ich;
1094 gr->GetPoint(ipt,xpt,ypt);
1096 effErr[ich] =
GetError(gr->GetErrorYlow(ipt),gr->GetErrorYhigh(ipt));
1101 trigProbErr2 += effErr34*effErr34;
1105 refTrigProb = trigProb;
1109 Double_t invErr2 = ( trigProbErr2>0. ) ? 1./trigProbErr2 : 0.;
1110 histo[isyst]->Fill(trigProb-refTrigProb,invErr2);
1115 for (
Int_t isyst=0; isyst<nSysts; isyst++ ) {
1116 if ( isEmpty[isyst] == 1 )
continue;
1117 TString title = ( isyst == 0 ) ?
"All systematics" : shortSystName[isyst].c_str();
1118 Int_t icolor = ( isyst < ncolors ) ? colors[isyst] : 20+isyst;
1119 histo[isyst]->SetLineColor(icolor);
1120 histo[isyst]->Draw((isyst == 0)?
"":
"same");
1121 leg->AddEntry(histo[isyst],title.Data(),
"l");
1122 if ( isyst>0 ) histo[0]->Add(histo[isyst]);
1135 if ( gROOT->IsBatch() ) prompt = kFALSE;
1138 cout << command.Data() <<
" ? [y/n]" << endl;
1143 if ( decision ==
"y" ) {
1144 cout <<
"Executing: " << command.Data() << endl;
1145 gSystem->Exec(command.Data());
1164 Int_t nChanges = par[0];
1166 Int_t matchChange = -1;
1167 for (
Int_t iknot=0; iknot<nChanges; iknot++ ) {
1168 Int_t iparChange = 2*(iknot+1);
1169 Double_t diff = xx - par[iparChange];
1170 if ( diff >= 0. && diff < matchDiff ) {
1172 matchChange = iparChange;
1175 if ( matchChange >= 0 ) val = par[matchChange+1];
1185 TH1* statHisto = 0x0;
1188 TList* effHistoList = obj->GetEffHistoList(
fConditions->UncheckedAt(0)->GetName());
1189 Int_t run = obj->GetMinRun();
1190 if ( run < firstRun || run > lastRun )
continue;
1193 if ( statHisto ) statHisto->Add(histo);
1194 else statHisto =
static_cast<TH1*
>(histo->Clone(
"tmpStatHisto"));
1197 if ( ! statHisto )
return 0.;
1202 Int_t excludeBoardsHalf[] = {1, 17, 39, 61, 77, 93,109,
1203 16, 38, 60, 76, 92, 108, 117,
1204 110, 111, 112, 113, 114, 115, 116};
1205 Int_t nExcludedHalf =
sizeof(excludeBoardsHalf)/
sizeof(excludeBoardsHalf[0]);
1206 for (
Int_t ibin=1; ibin<=statHisto->GetNbinsX(); ibin++ ) {
1208 for (
Int_t iexcl=0; iexcl<nExcludedHalf; iexcl++ ) {
1209 if ( ibin == excludeBoardsHalf[iexcl] || ibin == excludeBoardsHalf[iexcl]+117 ) {
1214 if ( skip )
continue;
1215 statPerDE += statHisto->GetBinContent(ibin);
1220 statPerDE = statHisto->Integral();
1221 nDe = (
Double_t)statHisto->GetNbinsX();
1223 statPerDE = nDe > 0. ? statPerDE/nDe : -1.;
1233 Int_t itrackSel = condition->UncheckedAt(3)->GetUniqueID();
1234 Int_t imatch = condition->UncheckedAt(4)->GetUniqueID();
1235 Int_t imethod = condition->UncheckedAt(5)->GetUniqueID();
1237 return trigOut->
GetEffHistoList(condition->At(0)->GetName(),condition->At(1)->GetName(),condition->At(2)->GetName(),itrackSel,imatch,imethod);
1244 return TMath::Max(errLow,errHigh);
1252 return static_cast<TH1*
>(effHistoList->At(ihisto));
1260 AliInfo(
"Selecting ranges with homogeneous efficiency");
1264 TH1F* hRunChangeCount =
new TH1F(
"runChangeCount",
"Number of RPCs changing efficiency per run",nRuns,-0.5,-0.5+(
Double_t)nRuns);
1265 hRunChangeCount->SetXTitle(
"Run num.");
1266 hRunChangeCount->SetYTitle(
"Num. of RPCs with change in eff.");
1267 for (
Int_t irun=0; irun<nRuns; irun++ ) {
1268 hRunChangeCount->GetXaxis()->SetBinLabel(irun+1,Form(
"%i",
GetRunNumber(irun)));
1273 Int_t nCanvas = perRPC ? 4 : 18;
1277 for (
Int_t irpc=0; irpc<18; irpc++ ) {
1280 Int_t firstDetEl = perRPC ? irpc : 0;
1281 Int_t lastDetEl = perRPC ? irpc : boards.GetSize()-1;
1283 for (
Int_t ich=0; ich<4; ich++ ) {
1284 Int_t ican = perRPC ? ich : irpc;
1285 TCanvas* can =
static_cast<TCanvas*
>(canList.At(ican));
1287 TString canName = perRPC ? Form(
"testRanges_ch%i",11+ich) : Form(
"testRanges_RPC%i",irpc);
1288 can =
new TCanvas(canName.Data(),canName.Data(),10*ich,10*ich,1200,800);
1289 can->Divide(6,3,0,0);
1290 can->SetMargin(0.,0.,0.,0.);
1291 canList.AddAt(can,ican);
1294 for (
Int_t idetel=firstDetEl; idetel<=lastDetEl; idetel++ ) {
1295 Int_t currDE = ( perRPC ) ? idetel : boards[idetel];
1299 trendGraph->GetYaxis()->SetRangeUser(minEff,maxEff);
1302 if ( gPad->GetListOfExecs()->GetEntries() == 0 ) gPad->AddExec(
"ZoomPad",
"AliMTRChEffAnalysis::ZoomPad()");
1303 gPad->SetTicks(1,1);
1304 gPad->SetMargin(0.08,0.,0.08,0.);
1305 TString drawOpt = ( gPad->GetListOfPrimitives()->GetEntries() == 0 ) ?
"ap" :
"p";
1307 TString legendName = Form(
"%s_%i",can->GetName(),currDE);
1308 TLegend* leg =
static_cast<TLegend*
>(legList.FindObject(legendName.Data()));
1310 leg =
new TLegend(0.2,0.15,0.8,0.4);
1311 leg->SetHeader(Form(
"%s %i",perRPC?
"RPC":
"Board",currDE));
1312 leg->SetName(legendName.Data());
1317 Int_t icolor = ich+1;
1318 trendGraph->SetLineColor(icolor);
1319 trendGraph->SetMarkerColor(icolor);
1320 trendGraph->SetMarkerStyle(24+ich);
1321 TF1* func =
static_cast<TF1*
>(trendGraph->GetListOfFunctions()->At(0));
1323 func->SetLineWidth(2);
1324 func->SetLineColor(icolor);
1327 trendGraph->GetXaxis()->SetLabelSize(0.07);
1328 trendGraph->SetTitle(
"");
1330 trendGraph->Draw(drawOpt.Data());
1331 leg->AddEntry(trendGraph,Form(
"Chamber %i",11+ich),
"lp");
1332 if ( perRPC || ich == 3 ) leg->Draw();
1333 for (
Int_t ichange=2; ichange<range.GetSize(); ichange++ ) {
1335 if ( ichange%2 == 1 )
continue;
1336 Int_t runIdx = range[ichange];
1338 TLine* line =
new TLine(runIdx,minEff,runIdx,maxEff);
1339 line->SetLineStyle(2);
1344 hRunChangeCount->Fill(runIdx);
1345 if ( hRunChangeCount->GetBinContent(runIdx+1) == 1 ) {
1346 TString infoMsg = Form(
"Efficiency change in %i triggered by ch %i RPC %i",
GetRunNumber(runIdx),11+ich,irpc);
1347 if ( ! perRPC ) infoMsg += Form(
" Board %i",currDE);
1348 AliInfo(infoMsg.Data());
1357 TArrayI runChangeClust(nRuns);
1360 for (
Int_t irun=0; irun<=nRuns; irun++ ) {
1361 if ( irun == nRuns || hRunChangeCount->GetBinContent(irun+1) == 0 ) {
1362 if ( sumWgt > 0. ) {
1363 Int_t averageRun = TMath::Nint(sumWgtRun / sumWgt);
1364 AliDebug(2,Form(
"Average run: %i => %i",averageRun,
GetRunNumber(averageRun)));
1365 runChangeClust[averageRun]++;
1370 if ( irun == nRuns )
break;
1372 AliDebug(2,Form(
"irun %i => %i: wgt %g",irun,
GetRunNumber(irun),hRunChangeCount->GetBinContent(irun+1)));
1375 Double_t wgt = hRunChangeCount->GetBinContent(irun+1);
1376 if ( forcedChanges ) {
1377 for (
Int_t ichange=0; ichange<forcedChanges->GetSize(); ichange++ ) {
1378 if (
GetRunNumber(irun) == forcedChanges->At(ichange) ) wgt *= 10.;
1385 TCanvas* summaryCan =
new TCanvas(
"effChangeSummary",
"effChangeSummary",50,50,600,600);
1386 summaryCan->SetLogy();
1387 hRunChangeCount->GetXaxis()->LabelsOption(
"v");
1388 hRunChangeCount->Draw();
1393 for (
Int_t irun=1; irun<nRuns; irun++ ) {
1394 if ( runChangeClust[irun] > 0 ) {
1400 runRanges.Set(ientry);
1413 if ( forcedChanges ) {
1414 forcedChangesBin.Set(forcedChanges->GetSize());
1415 for (
Int_t ichange=0; ichange<forcedChanges->GetSize(); ichange++ ) {
1417 if ( idx >= 0 ) forcedChangesBin[nForced++] = (
Double_t)idx;
1418 else AliWarning(Form(
"Cannot find run %i",forcedChanges->At(ichange)));
1423 Int_t minNormChi2Step = -1;
1429 for (
Int_t istep=0; istep<maxNRanges; istep++ ) {
1430 Int_t nPars = 2*(istep+1);
1431 Double_t xMin = trendGraph->GetXaxis()->GetXmin();
1432 Double_t xMax = trendGraph->GetXaxis()->GetXmax();
1434 func->FixParameter(0,istep);
1435 for (
Int_t ipar=1; ipar<nPars; ipar++ ) {
1443 func->SetParameter(ipar,val);
1444 if ( ipar%2 == 0 ) func->SetParLimits(ipar,xMin,xMax);
1447 TFitResultPtr fitResult = trendGraph->Fit(func,fitOpt.Data());
1450 if ( forcedChanges ) {
1451 Bool_t hasFixedPars = kFALSE;
1452 for (
Int_t iforced=0; iforced<nForced; iforced++ ) {
1453 for (
Int_t jstep=0; jstep<istep; jstep++ ) {
1454 Int_t ipar = 2*(jstep+1);
1455 if ( TMath::Abs(forcedChangesBin[iforced]-func->GetParameter(ipar)) > 2. )
continue;
1456 func->FixParameter(ipar,forcedChangesBin[iforced]);
1457 hasFixedPars = kTRUE;
1460 if ( hasFixedPars ) fitResult = trendGraph->Fit(func,fitOpt.Data());
1468 if ( normChi2 < minNormChi2 ) {
1469 minNormChi2 = normChi2;
1470 minNormChi2Step = istep;
1473 if ( normChi2 < chi2Cut )
break;
1479 trendGraph->GetListOfFunctions()->Add(func->Clone());
1485 Int_t nPoints = nSteps+1;
1488 for (
Int_t ipar=0; ipar<func->GetNpar(); ipar++ ) {
1489 Int_t istep = ipar/2;
1490 if ( ipar%2 == 0 ) parRunIdx[istep] = func->GetParameter(ipar);
1491 else parEff[istep] = func->GetParameter(ipar);
1495 TMath::Sort(nPoints,parRunIdx.GetArray(),sortIdx.GetArray(),kFALSE);
1497 runRanges.Set(2*nPoints);
1500 for (
Int_t ipoint=1; ipoint<nPoints; ipoint++ ) {
1501 Double_t deltaEff = TMath::Abs(parEff[sortIdx[ipoint]]-parEff[sortIdx[ipoint-1]]);
1503 if ( deltaEff < minEffVariation ) {
1504 AliWarning(Form(
"Efficiency variation for %s is %g => consider uniform",trendGraph->GetName(),deltaEff));
1507 Int_t runChangeIdx = TMath::Nint(parRunIdx[sortIdx[ipoint]]);
1508 AliDebug(1,Form(
"Change run: %s => %g => %i %i",trendGraph->GetName(),parRunIdx[sortIdx[ipoint]],runChangeIdx,
GetRunNumber(runChangeIdx)));
1509 runRanges[irun++] = returnIndex ? runChangeIdx-1 :
GetRunNumber(runChangeIdx-1);
1510 runRanges[irun++] = returnIndex ? runChangeIdx :
GetRunNumber(runChangeIdx);
1512 Int_t lastPt = trendGraph->GetN()-1;
1513 runRanges[irun++] = returnIndex ? lastPt :
GetRunNumber(lastPt);
1514 runRanges.Set(irun);
1517 AliWarning(Form(
"Fit did not converge for %s (minimum chi2 %g for step %i)",trendGraph->GetName(),minNormChi2,minNormChi2Step));
1526 if ( maxRun < minRun ) maxRun = minRun;
1527 return Form(
"%s_%i_%i",condition,minRun,maxRun);
1535 if ( obj->GetMinRun() == runNumber ) {
1536 return obj->GetUniqueID();
1549 outliers->SetHistogram(static_cast<TH1F*>(graph->GetHistogram()->Clone(Form(
"%s_outliers",graph->GetHistogram()->GetName()))));
1551 if ( graph->GetListOfFunctions()->GetEntries() == 0 ) graph->Fit(
"pol0",
"Q0");
1552 TF1* func =
static_cast<TF1*
>(graph->GetListOfFunctions()->At(0));
1556 for (
Int_t ipt=0; ipt<graph->GetN(); ipt++ ) {
1557 graph->GetPoint(ipt,xpt,ypt);
1558 Double_t diff = ypt - func->Eval(xpt);
1559 Double_t err = ( diff > 0. ) ? graph->GetErrorYlow(ipt) : graph->GetErrorYhigh(ipt);
1560 if ( err <= 0. || TMath::Abs(diff)/err > maxNsigmas )
continue;
1561 outliers->RemovePoint(ipt-nremoved);
1572 if ( ipt < 0 || ipt >=
fRunMap.size() )
return -1;
1573 return fRunMap[ipt]->GetMinRun();
1583 if (
gSystem->AccessPathName(sRunList) || sRunList.EndsWith(
".root") ) {
1584 sRunList.ReplaceAll(
",",
" ");
1585 if ( sRunList.IsDigit() ) {
1586 TObjArray* arr = sRunList.Tokenize(
" ");
1587 for (
Int_t iarr=0; iarr<arr->GetEntries(); iarr++ ) {
1588 rl->Add(
new TObjString(arr->At(iarr)->GetName()));
1594 ifstream inFile(sRunList.Data());
1596 while ( ! inFile.eof() ) {
1597 currLine.ReadLine(inFile);
1598 TString currRun = AliAnalysisMuonUtility::GetRunNumberAsString(currLine);
1599 if ( ! currRun.IsNull() ) rl->Add(
new TObjString(currRun));
1614 TString sRef(refCondition->GetName());
1618 if ( ! condition || sCond == sRef ) {
1622 for (
Int_t ic=0; ic<condition->GetEntriesFast(); ic++ ) {
1623 TString currCond =
static_cast<TObjString*
>(condition->UncheckedAt(ic))->String();
1624 TString refCond =
static_cast<TObjString*
>(refCondition->UncheckedAt(ic))->String();
1625 if ( currCond == refCond )
continue;
1626 title +=
";" + currCond;
1628 title.Remove(TString::kLeading,
';');
1630 title.ReplaceAll(
",",
"+");
1640 for (
Int_t ic=3; ic<6; ic++ ) {
1641 objName += condition->UncheckedAt(ic)->GetName();
1643 return static_cast<TH1*
>(trigOut->GetSum(condition->At(0)->GetName(),condition->At(1)->GetName(),condition->At(2)->GetName(),objName));
1651 if ( idetelem < 0 && ichamber >=0 ) idetelem = 11+ichamber;
1653 TH1* outHisto = 0x0;
1660 TList* effHistoList = obj->GetEffHistoList(
fConditions->UncheckedAt(0)->GetName());
1663 TString outName = Form(
"histo_type%i_count%i_ch%i_",itype,icount,11+ichamber);
1665 outName += Form(
"%i_trend",idetelem);
1666 outHisto =
new TH1D(outName.Data(),outName.Data(),nRuns,0.,(
Double_t)nRuns);
1667 outHisto->SetDirectory(0);
1668 outHisto->GetXaxis()->SetTitle(
"Run num.");
1670 Int_t run = obj->GetMinRun();
1671 outHisto->GetXaxis()->SetBinLabel(ibin,Form(
"%i",run));
1672 TH1* histo =
GetHisto(effHistoList,itype,icount,ichamber);
1673 Int_t currBin = histo->GetXaxis()->FindBin(idetelem);
1674 outHisto->SetBinContent(ibin,histo->GetBinContent(currBin));
1675 outHisto->SetBinError(ibin,histo->GetBinError(currBin));
1678 if ( outHisto ) outHisto->GetXaxis()->LabelsOption(
"v");
1686 if (
Check() )
return NULL;
1688 AliWarning(
"Chose either bending plane, non-bending plane or both planes");
1691 TH1* histoNum =
GetTrend(itype,icount,ichamber,idetelem);
1695 histoNum->SetStats(kFALSE);
1697 graph->SetHistogram(
new TH1F(*static_cast<TH1F*>(histoNum)));
1698 graph->GetHistogram()->SetDirectory(0);
1699 graph->GetYaxis()->SetTitle(
"Efficiency");
1700 graph->SetMarkerSize(0.5);
1715 for (
Int_t jch=-1; jch<4; jch++ ) {
1718 for (
Int_t ich=0; ich<4; ich++ ) {
1719 Double_t currEff = ( ich == jch ) ? 1.-eff[ich] : eff[ich];
1721 Double_t relErr = ( currEff>0. ) ? effErr[ich]/currEff : 0.;
1722 prodErr2 += relErr*relErr;
1724 binomialEff += prodEff;
1725 sumErr2 += prodEff*prodEff*prodErr2;
1727 probErr = TMath::Sqrt(sumErr2);
1736 AliError(
"You first need to merge efficiency objects with MergeOutput");
1747 AliInfo(
"Reading efficiency objects");
1752 gSystem->ExpandPathName(filename);
1753 if (
gSystem->AccessPathName(filename.Data()) ) {
1754 AliWarning(Form(
"Cannot find %s",filename.Data()));
1757 if ( filename.EndsWith(
".root") )
return AddToList(filename.Data(),outputName);
1761 std::map<int,std::string> tmpMap;
1762 ifstream inFile(filename.Data());
1764 while ( ! inFile.eof() ) {
1765 currLine.ReadLine(inFile);
1766 if ( currLine.IsNull() )
continue;
1767 if (
gSystem->AccessPathName(currLine.Data()) )
continue;
1769 tmpMap[currRun] = std::string(currLine.Data());
1774 for (
auto it = tmpMap.begin(); it != tmpMap.end(); ++it ) {
1775 if ( !
AddToList(it->second.c_str(), outputName) ) isOk = kFALSE;
1785 CopyLocally(runList,path,pattern,localFileList,outDir,directory);
1793 CopyLocally(runList,path,
"",localFileList,outDir,directory);
1802 if ( runRanges.GetSize()%2 == 1 ) {
1803 AliError(
"Run ranges expected in the form: start_period1,end_period1,start_period2,end_period2... => even number expected");
1809 AliInfo(
"Merging efficiencies");
1811 Int_t nRanges = mergedRanges.GetSize()/2;
1819 for (
Int_t irange=0; irange<nRanges; irange++ ) {
1820 Int_t firstRun = mergedRanges[2*irange];
1821 Int_t lastRun = mergedRanges[2*irange+1];
1829 TFileMerger fileMerger;
1831 Int_t run = obj->GetMinRun();
1832 if ( run < firstRun || run > lastRun )
continue;
1833 filename = obj->GetFilename();
1834 outputname = obj->GetOutputname();
1835 if ( firstRun == lastRun )
continue;
1836 fileMerger.AddFile(filename.Data(),kFALSE);
1839 TString sRange = Form(
"%i_%i",firstRun,lastRun);
1840 TString mergedFilename = Form(
"mergedTrigEff_runs_%s.root",sRange.Data());
1842 if ( firstRun == lastRun ) TFile::Cp(filename.Data(),mergedFilename.Data(),kFALSE);
1844 fileMerger.OutputFile(mergedFilename.Data());
1867 std::vector<bool> rangeOk;
1868 for (
Int_t irun=0; irun<runRanges.GetSize(); ++irun ) {
1869 rangeOk.push_back(
false);
1872 Int_t nRanges = runRanges.GetSize()/2;
1875 Int_t run = obj->GetMinRun();
1876 bool isInside =
false;
1877 for (
Int_t irange=0; irange<nRanges; ++irange ) {
1878 Int_t istart = 2*irange;
1879 Int_t iend = istart+1;
1880 Int_t firstRun = runRanges[istart];
1881 Int_t lastRun = runRanges[iend];
1882 if ( run == firstRun ) rangeOk[istart] =
true;
1883 else if ( run == lastRun ) rangeOk[iend] =
true;
1884 if ( run >= firstRun && run <= lastRun ) {
1890 AliWarning(Form(
"Warning: run %i is not inside range!",run));
1895 for (
int irun=0; irun<rangeOk.size(); ++irun ) {
1896 if ( ! rangeOk[irun] ) {
1897 AliWarning(Form(
"Warning: range limit %i not taken from the list of runs",runRanges[irun]));
1908 if ( averageStatError <= 0. || averageStatError >= 1. )
return runRanges;
1916 Double_t averageStatNeeded = effForStatCalc*(1.-effForStatCalc)/(averageStatError*averageStatError);
1918 AliInfo(Form(
"Average statistics needed to reach precision of %g : %g",averageStatError,averageStatNeeded));
1920 Int_t nRanges = runRanges.GetSize()/2;
1924 for (
Int_t irange=0; irange<nRanges; irange++ ) {
1926 fullStat += averageStat[irange];
1929 TArrayI mergedRanges(runRanges.GetSize());
1931 mergedRanges[imerged++] = runRanges[0];
1932 Double_t mergedAverageStat = 0., remainingStat = fullStat;
1933 for (
Int_t irange=0; irange<nRanges; irange++ ) {
1934 Int_t istart = 2*irange;
1935 Int_t iend = istart+1;
1936 mergedAverageStat += averageStat[irange];
1937 remainingStat -= averageStat[irange];
1939 AliInfo(Form(
"%i - %i => stat %g",runRanges[2*irange],runRanges[2*irange+1],averageStat[irange]));
1941 if ( ( mergedAverageStat >= averageStatNeeded && remainingStat >= averageStatNeeded ) || iend == runRanges.GetSize()-1 ) {
1942 mergedRanges[imerged++] = runRanges[iend];
1943 AliInfo(Form(
" merged range %i - %i => stat %g",mergedRanges[imerged-2],mergedRanges[imerged-1],mergedAverageStat));
1944 mergedAverageStat = 0.;
1945 Int_t nextRun = iend+1;
1946 if ( nextRun < runRanges.GetSize() ) mergedRanges[imerged++] = runRanges[nextRun];
1949 mergedRanges.Set(imerged);
1950 return mergedRanges;
1975 if ( ! listToModify || ! fromList )
return kFALSE;
1976 ifstream inFile(
gSystem->ExpandPathName(boardsToPatch));
1977 if ( ! inFile.is_open() ) {
1978 AliError(Form(
"Cannot open %s",boardsToPatch));
1982 while ( ! inFile.eof() ) {
1983 line.ReadLine(inFile);
1984 if ( line.IsNull() )
continue;
1986 Int_t iboard =
static_cast<TObjString*
>(arr->UncheckedAt(0))->String().Atoi();
1987 if ( iboard <= 0 )
continue;
1988 Int_t firstCh = 11, lastCh = 14;
1989 if ( arr->GetEntries() == 2 ) {
1990 Int_t currCh =
static_cast<TObjString*
>(arr->UncheckedAt(1))->String().Atoi();
1991 if ( currCh >= firstCh && currCh <= lastCh ) {
1998 for (
Int_t ich=firstCh; ich<=lastCh; ich++ ) {
1999 AliInfo(Form(
"Patching efficiency of board %i in ch %i",iboard,11+ich));
2000 for (
Int_t icount=0; icount<4; icount++ ) {
2002 TH1* histoToPatch =
static_cast<TH1*
>(listToModify->FindObject(currName.Data()));
2003 TH1* fromHisto =
static_cast<TH1*
>(fromList->FindObject(currName.Data()));
2004 histoToPatch->SetBinContent(iboard,fromHisto->GetBinContent(iboard));
2019 AliInfo(Form(
"Additional systematic uncertainties from %s",additionalSystematics));
2023 systName.Remove(0,systName.Index(
"?")+1);
2024 systName.Prepend(
"added_syst_from_");
2027 TList* effList = obj->GetEffHistoList(
fConditions->UncheckedAt(0)->GetName());
2029 newSyst->SetName(systName.Data());
2030 if (
PatchEffLists(newSyst,additionalSystList,affectedBoards) ) {
2031 obj->AddEffHistoList(systName.Data(),newSyst);
2033 else delete newSyst;
2052 TFile* outFile = TFile::Open(
gSystem->ExpandPathName(outFilename),
"create");
2053 listToModify->Write(
"triggerChamberEff",TObject::kSingleKey);
2065 TString trigEffCDBdir =
"MUON/Calib/TriggerEfficiency";
2067 if ( currSrc.BeginsWith(
"alien") && ! gGrid ) TGrid::Connect(
"alien://");
2069 AliMUONTriggerEfficiencyCells* effMap = 0x0;
2070 Bool_t deleteMap = kTRUE;
2071 if ( currSrc.EndsWith(
".root") ) effMap =
new AliMUONTriggerEfficiencyCells(currSrc.Data());
2073 TObjArray* dirRun = currSrc.Tokenize(
"?");
2075 TString runNum = ( dirRun->GetEntriesFast() > 1 ) ? dirRun->UncheckedAt(1)->GetName() :
"";
2076 AliCDBManager* mgr = AliCDBManager::Instance();
2077 if ( ! mgr->GetDefaultStorage() ) mgr->SetDefaultStorage(
"local://$ALICE_ROOT/OCDB");
2078 if ( mgr->GetEntryCache()->Contains(trigEffCDBdir.Data()) ) mgr->UnloadFromCache(trigEffCDBdir.Data());
2079 mgr->SetSpecificStorage(trigEffCDBdir.Data(),cdbPath.Data());
2080 Int_t runNumber = 0;
2081 if ( runNum.IsNull() ) {
2082 cout <<
"Please enter run number: " << endl;
2085 else runNumber = runNum.Atoi();
2086 mgr->SetRun(runNumber);
2087 AliCDBEntry* cdbEntry = mgr->Get(trigEffCDBdir.Data());
2092 effMap =
static_cast<AliMUONTriggerEfficiencyCells*
>(cdbEntry->GetObject());
2096 AliError(Form(
"Cannot find effieciency map in %s",src));
2101 if ( deleteMap )
delete effMap;
2103 return effHistoList;
2119 AliInfo(
"Check for local boards where the efficiency could not be computed and recover it from other maps");
2122 std::vector<TList*> readEffLists;
2123 std::vector<TList*> systLists;
2126 if ( referenceRun >= 0 ) refRun = Form(
"%i",referenceRun);
2127 TList *refRead = 0x0, *refSyst = 0x0;
2132 TList* effList = obj->GetEffHistoList(
fConditions->UncheckedAt(0)->GetName());
2133 std::array<TH1*,16> histoList;
2134 for (
Int_t ich=0; ich<4; ich++ ) {
2135 for (
Int_t icount=0; icount<4; icount++ ) {
2137 histoList[4*ich+icount] =
static_cast<TH1*
>(effList->FindObject(currName.Data()));
2140 for (
Int_t ibin=1; ibin<=histoList[0]->GetXaxis()->GetNbins(); ibin++ ) {
2141 Bool_t isUnknown[4] = {0,0,0,0};
2142 Int_t nDead = 0, nUnknown = 0;
2143 for (
Int_t ich=0; ich<4; ich++ ) {
2145 if ( countAll > 10 ) {
2147 if ( eff<0.1 ) nDead++;
2155 if ( nUnknown == 3 ) {
2156 for (
Int_t ich=0; ich<4; ich++ ) {
2157 if ( ! isUnknown[ich] )
continue;
2158 AliInfo(Form(
"Recovering board %i in ch %i",ibin,11+ich));
2159 if ( readEffLists.size() == 0 ) {
2162 if ( rList->GetEntries() == 0 ) {
2163 AliError(
"A recovery is needed, but no run list is specified: please specify it");
2166 if ( refRun.IsNull() ) refRun = rList->Last()->GetName();
2167 else if ( ! rList->FindObject(refRun.Data()) ) rList->Add(
new TObjString(refRun));
2168 AliInfo(Form(
"Using efficiency of run %s",refRun.Data()));
2169 for (
Int_t itype=0; itype<2; itype++ ) {
2171 TString currOcdb = ( itype == 0 ) ? ocdb : systOcdb;
2172 TString baseName = ( itype == 0 ) ?
"RecoveredFrom" :
"RecoveredSystFrom";
2174 TObjString* runObj = 0x0;
2175 while ( (runObj = static_cast<TObjString*>(next())) ) {
2176 Bool_t isRefRun = ( runObj->String() == refRun );
2178 if ( itype == 1 && ! isRefRun )
continue;
2180 readList->SetName(Form(
"%s_%s",baseName.Data(),runObj->GetName()));
2181 readEffLists.push_back(readList);
2183 if ( isRefRun && itype == 0 ) {
2190 if ( systLists.size() == 0 ) {
2191 for (
UInt_t imap=0; imap<readEffLists.size(); imap++ ) {
2199 systEffList->SetName(readEffLists[imap]->GetName());
2200 systLists.push_back(systEffList);
2203 if ( readEffLists[imap] == refRead ) refSyst = systEffList;
2207 for (
UInt_t imap=0; imap<readEffLists.size(); imap++ ) {
2208 TList* readList = readEffLists[imap];
2209 for (
Int_t icount=0; icount<4; icount++ ) {
2211 TH1* histoFrom =
static_cast<TH1*
>(readList->FindObject(currName.Data()));
2212 TH1* histoTo = ( readList == refRead ) ? histoList[4*ich+icount] : static_cast<TH1*>(systLists[imap]->
FindObject(currName.Data()));
2213 histoTo->SetBinContent(ibin,histoFrom->GetBinContent(ibin));
2218 else AliWarning(Form(
"Local board %i: unknown efficiency: %i %i %i %i",ibin,isUnknown[0],isUnknown[1],isUnknown[2],isUnknown[3]));
2221 for (
TList* systEffHistoList : systLists ) {
2222 if ( systEffHistoList == refSyst ) {
2223 delete systEffHistoList;
2228 obj->AddEffHistoList(systEffHistoList->GetName(),systEffHistoList);
2238 readEffLists.clear();
2254 TString sCondition = Form(
"%s;%s;%s",physSel,trigClassName,centrality);
2264 if ( foundCondition ) {
2266 if ( foundCondition == basicCondition )
return kFALSE;
2269 addCondition = foundCondition;
2273 AliInfo(
"Systematic condition already added");
2278 addCondition = sCondition.Tokenize(
";");
2279 addCondition->SetName(sCondition.Data());
2280 addCondition->UncheckedAt(3)->SetUniqueID(itrackSel);
2281 addCondition->UncheckedAt(4)->SetUniqueID(imatch);
2282 addCondition->UncheckedAt(5)->SetUniqueID(imethod);
2287 if ( basicCondition ) {
2288 AliInfo(Form(
"Changing current eff. condition: %s",basicCondition->GetName()));
2290 delete basicCondition;
2297 obj->RemoveEffHistoList(sCondition.Data());
2298 AddToList(obj->GetFilename(), obj->GetOutputname());
2318 return SetCondition(physSel, trigClassName, centrality, itrackSel, imatch, imethod, kTRUE);
2327 AliInfo(
"Writing merged efficiencies to OCDB");
2330 if ( ! outCDB.Contains(
"://") || outCDB ==
"raw://" ) {
2331 AliError(
"Invalid CDB output dir");
2336 if ( outCDB.BeginsWith(
"alien://") && ! gGrid ) {
2337 TGrid::Connect(
"alien://");
2338 rmCommand =
"alien_rm";
2340 AliError(
"Cannot open grid connection");
2345 AliCDBManager* mgr = AliCDBManager::Instance();
2346 if ( ! mgr->GetDefaultStorage() ) mgr->SetDefaultStorage(
"local://$ALICE_ROOT/OCDB");
2348 TString trigEffCDBdir =
"MUON/Calib/TriggerEfficiency";
2350 mgr->SetSpecificStorage(trigEffCDBdir.Data(),outCDB.Data());
2352 AliCDBStorage* specificStorage = mgr->GetSpecificStorage(trigEffCDBdir.Data());
2353 TString baseOutDir = specificStorage->GetBaseFolder();
2355 TString condName = ( writeSystematics ) ?
"Systematics" :
fConditions->UncheckedAt(0)->GetName();
2358 TList* effHistos = obj->GetEffHistoList(condName.Data());
2359 if ( ! effHistos ) {
2360 AliWarning(
"No systematic condition found: you should first run BuildSystematicMap");
2364 WriteToOCDB(effHistos,outputCDB,obj->GetMinRun(),obj->GetMaxRun());
2374 if ( ! effHistos )
return kFALSE;
2375 return WriteToOCDB(effHistos,outputCDB,firstRun,lastRun,defaultOCDB);
2382 AliInfo(
"Writing merged efficiencies to OCDB");
2385 if ( ! outCDB.Contains(
"://") || outCDB ==
"raw://" ) {
2386 AliError(
"Invalid CDB output dir");
2391 if ( outCDB.BeginsWith(
"alien://") ) {
2392 rmCommand =
"alien_rm";
2394 if ( ! TGrid::Connect(
"alien://") ) {
2395 AliError(
"Cannot open grid connection");
2401 AliCDBManager* mgr = AliCDBManager::Instance();
2402 if ( ! mgr->GetDefaultStorage() ) mgr->SetDefaultStorage(defaultOCDB);
2404 TString trigEffCDBdir =
"MUON/Calib/TriggerEfficiency";
2405 mgr->SetSpecificStorage(trigEffCDBdir.Data(),outCDB.Data());
2407 AliCDBStorage* specificStorage = mgr->GetSpecificStorage(trigEffCDBdir.Data());
2408 TString baseOutDir = specificStorage->GetBaseFolder();
2411 for (
Int_t irun=0; irun<2; irun++ ) {
2412 Int_t runnr = ( irun == 0 ) ? firstRun : lastRun;
2413 specificStorage->QueryCDB(runnr);
2414 TObjArray* allIdsForRun = specificStorage->GetQueryCDBList();
2415 TIter nextId(allIdsForRun);
2417 while ((
id = static_cast<AliCDBId*>(nextId()))) {
2419 Int_t foundFirst =
id->GetFirstRun();
2420 Int_t foundLast =
id->GetLastRun();
2421 Int_t version =
id->GetVersion();
2422 Int_t subversion = TMath::Max(id->GetSubVersion(),0);
2423 TString fullPath = Form(
"%s/%s/Run%d_%d_v%d_s%d.root",baseOutDir.Data(),path.Data(),foundFirst,foundLast,version,subversion);
2424 ExecCommand(Form(
"%s %s",rmCommand.Data(),fullPath.Data()), kTRUE);
2429 AliMUONTriggerEfficiencyCells* effMap =
new AliMUONTriggerEfficiencyCells(
CloneEffHistoList(effHistos));
2430 AliMUONCDB::WriteToCDB(effMap,
"MUON/Calib/TriggerEfficiency", firstRun, lastRun,
"Measured efficiencies");
2439 if ( gPad->GetEvent() != kButton1Double )
return;
2440 TVirtualPad* pad = gPad;
2441 Int_t px = pad->GetEventX();
2442 Int_t py = pad->GetEventY();
2443 TCanvas* can =
new TCanvas(
"zoom",
"zoom",px,py,600,600);
2444 for (
Int_t iobj=0; iobj<pad->GetListOfPrimitives()->GetEntries(); iobj++ ) {
2445 TObject* obj = pad->GetListOfPrimitives()->At(iobj);
2446 obj = obj->Clone(Form(
"%s_zoom",obj->GetName()));
2447 TString drawOpt = obj->GetOption();
2448 if ( drawOpt.IsNull() ) {
2449 if ( obj->InheritsFrom(TGraph::Class()) ) {
2451 if ( iobj == 1 ) drawOpt.Append(
"a");
2452 static_cast<TGraph*
>(obj)->GetXaxis()->SetLabelSize();
2454 else if ( obj->InheritsFrom(TH1::Class()) ) {
2456 if ( iobj == 1 ) drawOpt.Append(
"same");
2457 static_cast<TH1*
>(obj)->GetXaxis()->SetLabelSize();
2460 obj->Draw(drawOpt.Data());
2469 fFilename(filename),
2470 fOutputname(outputname),
2483 delete mapEntry.second;
2492 auto const& mapEntry =
fEffLists.find(condition);
2493 if ( mapEntry ==
fEffLists.end() )
return 0x0;
2494 return mapEntry->second;
2502 AliWarning(Form(
"Condition %s already present: nothing done",condition));
2505 fEffLists.insert({condition,effHistoList});
2514 auto const& mapEntry =
fEffLists.find(condition);
2515 if ( mapEntry ==
fEffLists.end() )
return kFALSE;
2516 delete mapEntry->second;
Hit pattern from tracker track extrapolation.
TList * GetEffHistoList(TString physSel, TString trigClassNames, TString centrality, Int_t itrackSel, Int_t imatch, Int_t imethod)
void CompareMergedEfficiencies(const char *opt) const
std::vector< std::string > fSortKeys
void CopyDir(TDirectory *source) const
Double_t GetError(Double_t errLow, Double_t errHigh) const
Bool_t AdditionalSystematics(const char *additionalSystematics, const char *affectedBoards) const
std::map< std::string, TList * > fEffLists
Bool_t CopyLocally(const char *runList, const char *path, const char *pattern, const char *localFileList, const char *outDir, const char *directory) const
Double_t GetThreeOfFour(TArrayD eff, TArrayD effErr, Double_t &probErr) const
TGraphAsymmErrors * GetTrendEff(Int_t itype, Int_t icount, Int_t ichamber, Int_t idetelem) const
Bool_t RemoveEffHistoList(const char *condition)
AliMTRChEffInnerObj(const char *filename, const char *outputname, Int_t minRun, Int_t maxRun=-1)
TArrayI MergeRangesForStat(TArrayI runRanges, Double_t averageStatError, Bool_t excludePeriphericBoards=kTRUE) const
Int_t ComputeAndCompareEfficiencies(const char *sources, const char *titles, const char *opt, const char *canvasNameSuffix="") const
Counts per board histogram index.
Bool_t CheckRanges(TArrayI runRanges) const
Bool_t InitFromWeb(const char *runList, const char *path, const char *localFileList="localFileList.txt", const char *outDir="", const char *directory="MTR_ChamberEffMap", const char *outputName="testMTRChamberEff")
Int_t CompareEfficiencies(const char *sources, const char *titles, const char *opt, const char *canvasNameSuffix="") const
TList * GetEffHistoList(const char *condition) const
TLatex * text[5]
option to what and if export to output file
tracks used for calculation
Bool_t PatchEfficiency(const char *effToModify, const char *fromEff, const char *boardsToPatch, const char *outFilename) const
UShort_t T(UShort_t m, UShort_t t)
TList * GetEffHistoList(AliTrigChEffOutput *trigOut, TObjArray *condition) const
Bool_t WriteMergedToOCDB(const char *outputCDB="CDB", Bool_t writeSystematics=kFALSE) const
Bool_t AddToList(const char *filename, const char *outputName)
virtual ~AliMTRChEffAnalysis()
Int_t CompareEfficiencyMethods(const char *source, const char *opt, const char *canvasNameSuffix="") const
Output for Trig chamber effieincy.
virtual ~AliMTRChEffInnerObj()
Bool_t InitFromLocal(const char *localFileList, const char *outputName="testMTRChamberEff")
Bool_t AddEffHistoList(const char *condition, TList *effHistoList)
TArrayI GetHomogeneousRanges(Double_t chi2Cut=3, Int_t maxNRanges=4, Double_t minEffVariation=0.005, Bool_t perRPC=kTRUE, TArrayI *forcedChanges=0x0, Double_t minEff=0.85, Double_t maxEff=1.01)
Bool_t SetEffConditions(const char *physSel, const char *trigClassName, const char *centrality, Int_t itrackSel, Int_t imatch, Int_t imethod)
Output for Trig chamber effieincy.
AliTrigChEffOutput * fNamer
! Namer for histograms
void DrawStatContribution(Int_t itype, Int_t irpc, Double_t maxNsigmaOutliers=-1., Double_t minY=0., Double_t maxY=0.15) const
Bool_t PatchEffLists(TList *listToModify, TList *fromList, const char *boardsToPatch) const
Double_t GetAverageStat(Int_t firstRun, Int_t lastRun, Int_t itype=AliTrigChEffOutput::kHboardEff, Bool_t excludePeriphericBoards=kTRUE) const
Bool_t Data(TH1F *h, Double_t *rangefit, Bool_t writefit, Double_t &sgn, Double_t &errsgn, Double_t &bkg, Double_t &errbkg, Double_t &sgnf, Double_t &errsgnf, Double_t &sigmafit, Int_t &status)
TString GetId(const char *condition, Int_t minRun, Int_t maxRun=-1) const
TObject * FindObject(int bin, const char *nameH, const TList *lst, Bool_t normPerEvent=kTRUE)
AliTrigChEffOutput * Namer() const
std::vector< AliMTRChEffAnalysis::AliMTRChEffInnerObj * > fRunMap
! Map of internal objects per run
std::vector< AliMTRChEffAnalysis::AliMTRChEffInnerObj * > fMergedMap
! Map of merged internal objects
TH1 * GetHisto(TList *effHistoList, Int_t itype, Int_t icount, Int_t ichamber) const
Bool_t SetCondition(const char *physSel, const char *trigClassName, const char *centrality, Int_t itrackSel, Int_t imatch, Int_t imethod, Bool_t isBasic)
Bool_t WriteToOCDB(const char *inFilename, const char *outputCDB, Int_t firstRun, Int_t lastRun, const char *defaultOCDB="local://$ALIROOT_OCDB_ROOT/OCDB") const
Counts per cathode histogram index.
TList * GetRunList(const char *runList) const
Int_t GetRunNumber(Int_t ipt) const
Bool_t HasMergedResults() const
Bool_t ExecCommand(TString command, Bool_t prompt) const
TArrayI BoardsInRPC(Int_t irpc) const
Bool_t RecoverEfficiency(const char *runList, const char *ocdb, const char *systOcdb, Int_t referenceRun=-1)
Int_t GetIndexFromRun(Int_t runNumber) const
Double_t FitRangesFunc(Double_t *x, Double_t *par)
Int_t GetRunNumber(TString)
void DrawEffTrend(Int_t itype, Int_t irpc, Double_t maxNsigmasOutliers=-1., Double_t minEff=0.8, Double_t maxEff=1.01) const
TObjArray * fConditions
! List of conditions for trigger efficiency
Bool_t InitFromGrid(const char *runList, const char *path, const char *pattern, const char *localFileList="localFileList.txt", const char *outDir="", const char *directory="MTR_ChamberEffMap", const char *outputName="testMTRChamberEff")
TList * CloneEffHistoList(TList *effHistos) const
TGraphAsymmErrors * GetOutliers(TGraphAsymmErrors *graph, Double_t maxNsigmas=3.) const
Bool_t AddSystematicCondition(const char *physSel, const char *trigClassName, const char *centrality, Int_t itrackSel, Int_t imatch, Int_t imethod)
TString GetShortConditionTitle(const char *conditionName) const
Bool_t DrawSystematicEnvelope(Bool_t perRPC=kFALSE) const
Bool_t MergeOutput(TArrayI runRanges, Double_t averageStatError=0.01, Bool_t isIndex=kFALSE)
TString GetHistoName(Int_t itype, Int_t icount, Int_t ichamber, Int_t itrackSel, Int_t imatch, Int_t imethod)
Bool_t SetDefaultEffConditions()
Bool_t BuildSystematicMap()
TH1 * GetSum(AliTrigChEffOutput *trigOut, TObjArray *condition, Int_t itype, Int_t icount, Int_t ichamber) const
TList * ReadEffHistoList(const char *src) const
Counts per slat histogram index.
TH1 * GetTrend(Int_t itype, Int_t icount, Int_t ichamber, Int_t idetelem) const