AliPhysics  58f3d52 (58f3d52)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliMTRChEffAnalysis.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3  * *
4  * Author: The ALICE Off-line Project. *
5  * Contributors are mentioned in the code where appropriate. *
6  * *
7  * Permission to use, copy, modify and distribute this software and its *
8  * documentation strictly for non-commercial purposes is hereby granted *
9  * without fee, provided that the above copyright notice appears in all *
10  * copies and that both the copyright notice and this permission notice *
11  * appear in the supporting documentation. The authors make no claims *
12  * about the suitability of this software for any purpose. It is *
13  * provided "as is" without express or implied warranty. *
14  **************************************************************************/
15 
16 #include "AliMTRChEffAnalysis.h"
17 
18 // ROOT includes
19 #include <Riostream.h>
20 #include "TObjString.h"
21 #include "TObjArray.h"
22 #include "TList.h"
23 #include "TSystem.h"
24 #include "TROOT.h"
25 #include "TRegexp.h"
26 #include "TFile.h"
27 #include "TDirectory.h"
28 #include "TTree.h"
29 #include "TKey.h"
30 #include "TArrayI.h"
31 #include "TArrayD.h"
32 #include "TGrid.h"
33 #include "TGridResult.h"
34 #include "TGraphAsymmErrors.h"
35 #include "TH1.h"
36 #include "TH2.h"
37 #include "TAxis.h"
38 #include "TF1.h"
39 #include "TMath.h"
40 #include "TCanvas.h"
41 #include "TLegend.h"
42 #include "TLine.h"
43 #include "TLatex.h"
44 #include "TFileMerger.h"
45 #include "TFitResultPtr.h"
46 
47 #include "AliLog.h"
48 #include "AliMergeableCollection.h"
49 #include "AliCounterCollection.h"
50 
51 #include "AliAnalysisMuonUtility.h"
52 #include "AliTrigChEffOutput.h"
53 
54 #include "AliCDBManager.h"
55 #include "AliCDBStorage.h"
56 #include "AliCDBId.h"
57 #include "AliCDBEntry.h"
58 #include "AliMUONCDB.h"
59 #include "AliMUONTriggerEfficiencyCells.h"
60 
62 ClassImp(AliMTRChEffAnalysis) // Class implementation in ROOT context
64 
65 using std::cout;
66 using std::endl;
67 using std::cin;
68 using std::ofstream;
69 using std::ifstream;
70 
71 //________________________________________________________________________
73  TObject(),
74  fConditions(0x0),
75  fNamer(0x0)
76 {
78 
79 }
80 
81 //________________________________________________________________________
82 AliMTRChEffAnalysis::AliMTRChEffAnalysis ( const char *localFileList, const char* outputName ) :
83  TObject(),
84  fConditions(0x0),
85  fNamer(0x0)
86 {
88  InitFromLocal(localFileList,outputName);
89 }
90 
91 //________________________________________________________________________
93 {
94  //
96  //
97  delete fConditions;
98  delete fNamer;
99  for ( AliMTRChEffAnalysis::AliMTRChEffInnerObj* obj : fRunMap ) delete obj;
100  for ( AliMTRChEffAnalysis::AliMTRChEffInnerObj* obj : fMergedMap ) delete obj;
101 }
102 
103 //________________________________________________________________________
104 Bool_t AliMTRChEffAnalysis::AddSystematicCondition ( const char* physSel, const char* trigClassName, const char* centrality, Int_t itrackSel, Int_t imatch, Int_t imethod )
105 {
107  return SetCondition(physSel, trigClassName, centrality, itrackSel, imatch, imethod, kFALSE);
108 }
109 
110 //________________________________________________________________________
111 Bool_t AliMTRChEffAnalysis::AddToList ( const char *filename, const char *outputName )
112 {
114  AliTrigChEffOutput* trigOut = new AliTrigChEffOutput(filename,outputName);
115  if ( ! trigOut->GetMergeableCollection() ) {
116  AliError(Form("Cannot find %s in %s",outputName,filename));
117  return kFALSE;
118  }
119 
120  TObjArray* condition = static_cast<TObjArray*>(fConditions->At(0));
121 
122 // // Delete counter collection to save memory
123 // trigOut->RemoveFromList(trigOut->GetCounterCollection());
124  // Just keep counter and mergeable collections
125  TList* effHistoList = GetEffHistoList(trigOut,condition);
126 // effHistoList->SetName(filename);
127  Int_t runNum = AliAnalysisMuonUtility::GetRunNumber(filename);
128 // effHistoList->SetUniqueID(currRun.Atoi());
129 
131  Int_t idxFromRun = GetIndexFromRun(runNum);
132  if ( idxFromRun >= 0 ) obj = fRunMap[idxFromRun];
133  else {
134  obj = new AliMTRChEffAnalysis::AliMTRChEffInnerObj(filename,outputName,runNum);
135  obj->SetUniqueID(fRunMap.size());
136  fRunMap.push_back(obj);
137  }
138 
139  obj->AddEffHistoList(condition->GetName(), effHistoList);
140 
141 
142  delete trigOut;
143  return kTRUE;
144 }
145 
146 //________________________________________________________________________
148 {
150 
151  // FIXME: ugly and hardcoded, but avoid loading the mapping
152 
153  TArrayI boards;
154  if ( irpc == 0 || irpc == 9 ) {
155  Int_t arr[] = {26,27,28,29,48,49,50,51,68,69,84,85,100,101,113};
156  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
157  boards.Set(nBoards,arr);
158  if ( irpc == 9 )
159  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
160  }
161  else if ( irpc == 1 || irpc == 8 ) {
162  Int_t arr[] = {9,10,11,30,31,32,33,52,53,54,55,70,71,86,87,102,103,114};
163  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
164  boards.Set(nBoards,arr);
165  if ( irpc == 8 )
166  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
167  }
168  else if ( irpc == 2 || irpc == 7 ) {
169  Int_t arr[] = {12,13,34,35,56,57,72,73,88,89,104,105,115};
170  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
171  boards.Set(nBoards,arr);
172  if ( irpc == 7 )
173  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
174  }
175  else if ( irpc == 3 || irpc == 6 ) {
176  Int_t arr[] = {14,15,36,37,58,59,74,75,90,91,106,107,116};
177  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
178  boards.Set(nBoards,arr);
179  if ( irpc == 6 )
180  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
181  }
182  else if ( irpc == 4 || irpc == 5 ) {
183  Int_t arr[] = {16,38,60,76,92,108,117};
184  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
185  boards.Set(nBoards,arr);
186  if ( irpc == 5 )
187  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
188  }
189  else if ( irpc == 17 || irpc == 10 ) {
190  Int_t arr[] = {6,7,8,22,23,24,25,44,45,46,47,66,67,82,83,98,99,112};
191  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
192  boards.Set(nBoards,arr);
193  if ( irpc == 10 )
194  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
195  }
196  else if ( irpc == 16 || irpc == 11 ) {
197  Int_t arr[] = {4,5,20,21,42,43,64,65,80,81,96,97,111};
198  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
199  boards.Set(nBoards,arr);
200  if ( irpc == 11 )
201  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
202  }
203  else if ( irpc == 15 || irpc == 12 ) {
204  Int_t arr[] = {2,3,18,19,40,41,62,63,78,79,94,95,110};
205  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
206  boards.Set(nBoards,arr);
207  if ( irpc == 12 )
208  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
209  }
210  else if ( irpc == 14 || irpc == 13 ) {
211  Int_t arr[] = {1,17,39,61,77,93,109};
212  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
213  boards.Set(nBoards,arr);
214  if ( irpc == 13 )
215  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
216  }
217 
218  return boards;
219 }
220 
221 
222 //________________________________________________________________________
224 {
226  TList* clonedEffHistos = new TList();
227  clonedEffHistos->SetOwner();
228  TIter next(effHistos);
229  TObject* obj = 0x0;
230  while ( (obj = next()) ) {
231  clonedEffHistos->Add(obj->Clone());
232  }
233  return clonedEffHistos;
234 }
235 
236 //________________________________________________________________________
238 {
240  if ( ! HasMergedResults() ) return kFALSE;
241 
242  AliInfo("Building efficiency map for systematic uncertainties");
243 
244  TString currName = "";
245  Double_t xref=0., yref=0., xpt=0., ypt=0.;
246  Double_t nSigmas = 1.;
247 
249 
250  std::vector<std::string> systKeys = obj->GetSortKeys();
251  Int_t nSysts = systKeys.size();
252 
253  // Clone the histogram list that will contain the systematic uncertainties
254  TList* effHistos = obj->GetEffHistoList(fConditions->UncheckedAt(0)->GetName());
255  TList* systematicList = CloneEffHistoList(effHistos);
256 
257  for ( Int_t ich=0; ich<4; ich++ ) {
258  // Get the efficiency graph for the different conditions
259  // as well as the list of histograms to build the efficiency
260  TGraphAsymmErrors* checkEffList[nSysts];
261  TH1* histoList[nSysts*4];
262  TH1* systHistoList[4];
263  for ( Int_t isyst=0; isyst<nSysts; isyst++ ) {
264  effHistos = obj->GetEffHistoList(systKeys[isyst].c_str());
265  for ( Int_t icount=0; icount<4; icount++ ) {
266  currName = Namer()->GetHistoName(AliTrigChEffOutput::kHboardEff, icount, ich, -1, -1, -1);
267  histoList[4*isyst+icount] = static_cast<TH1*>(effHistos->FindObject(currName.Data()));
268  if ( isyst == 0 ) {
269  systHistoList[icount] = static_cast<TH1*>(systematicList->FindObject(currName.Data()));
270  }
271  }
272 
274  Int_t iden = 4*isyst+AliTrigChEffOutput::kAllTracks;
275  checkEffList[isyst] = new TGraphAsymmErrors(histoList[inum],histoList[iden],"e0");
276  } // loop on systematics
277  TGraphAsymmErrors* refEffList[3];
278  for ( Int_t icount=0; icount<3; icount++ ) {
279  refEffList[icount] = new TGraphAsymmErrors(histoList[icount],histoList[AliTrigChEffOutput::kAllTracks],"e0");
280  }
281 
282  // First check what condition to use for the systematic uncertainty
283  // We're searching for the one giving the maximum discrepancy from the reference
284  // not compatible with statistical uncertainty
285  // If this is not found, we'll just use the statistical uncertanty of the reference
286 
287  TGraphAsymmErrors* refGraph = checkEffList[0];
288  for ( Int_t ipt=0; ipt<refGraph->GetN(); ipt++ ) {
289  refGraph->GetPoint(ipt,xref,yref);
290  Int_t chosenSyst = -1;
291  Double_t foundAbsDiff = -1.;
292  for ( Int_t isyst=1; isyst<nSysts; isyst++ ) {
293  TGraphAsymmErrors* graph = checkEffList[isyst];
294  graph->GetPoint(ipt,xpt,ypt);
295  Double_t diff = ypt - yref;
296  Double_t err = (diff > 0.) ? graph->GetErrorYlow(ipt) : graph->GetErrorYhigh(ipt);
297  Double_t absDiff = TMath::Abs(diff);
298  if ( absDiff < nSigmas*err ) continue;
299  if ( foundAbsDiff < absDiff ) {
300  foundAbsDiff = absDiff;
301  chosenSyst = isyst;
302  }
303  } // loop on Systs
304 
305  Int_t ibin = ipt+1;
306  AliDebug(2,Form("Chamber %i board %i systematicCondition %i",11+ich,ibin,chosenSyst));
307  if ( chosenSyst >= 0 ) {
308  for ( Int_t icount=0; icount<4; icount++ ) {
309  systHistoList[icount]->SetBinContent(ibin,histoList[4*chosenSyst+icount]->GetBinContent(ibin));
310  }
311  }
312  else {
313  Double_t countAll = histoList[AliTrigChEffOutput::kAllTracks]->GetBinContent(ibin);
314  systHistoList[AliTrigChEffOutput::kAllTracks]->SetBinContent(ibin,countAll);
315  for ( Int_t icount=0; icount<3; icount++ ) {
316  TGraphAsymmErrors* graph = refEffList[icount];
317  graph->GetPoint(ipt,xpt,ypt);
318  Double_t errHigh = graph->GetErrorYhigh(ipt);
319  Double_t errLow = graph->GetErrorYlow(ipt);
320  Double_t newEff = ( errLow > errHigh ) ? ypt - errLow : ypt + errHigh;
321  Double_t newCount = TMath::Nint(newEff * countAll);
322  if ( newCount < 0 || newCount > countAll ) {
323  TString warning = Form("WARNING: ch %i board %i cath %i systDiff %g newEff %g / %g",11+ich,ibin,icount,newEff-yref,newCount,countAll);
324  if ( newCount < 0 ) newCount = 0;
325  else newCount = countAll;
326  warning += Form(" => setting numerator to %g",newCount);
327  AliWarning(warning.Data());
328  }
329  systHistoList[icount]->SetBinContent(ibin,newCount);
330  }
331  }
332  } // loop on points
333  for ( Int_t it=0; it<nSysts; it++ ) delete checkEffList[it];
334  for ( Int_t it=0; it<3; it++ ) delete refEffList[it];
335  } // loop on chambers
336  obj->AddEffHistoList("Systematics",systematicList);
337  } // loop on merged efficiencies
338 
339  return kTRUE;
340 }
341 
342 //________________________________________________________________________
344 {
346  if ( fRunMap.empty() ) {
347  AliError("The list of trigger efficiency object is not initialized. Please use either InitFromLocal, InitFromGrid or InitFromWeb");
348  return 1;
349  }
350  return 0;
351 }
352 
353 //________________________________________________________________________
354 Int_t AliMTRChEffAnalysis::CompareEfficiencies ( const char* sources, const char* titles, const char* opt, const char* canvasNameSuffix ) const
355 {
357  TString srcs(sources);
358  if ( srcs.Contains("raw://") ) {
359  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");
360  return -2;
361  }
362  TObjArray* sourceList = srcs.Tokenize(",");
363  TObjArray effHistoLists;
364  effHistoLists.SetOwner();
365 
366  TIter next(sourceList);
367  TObjString* src = 0x0;
368  while ( (src = static_cast<TObjString*>(next())) ) {
369  TList* readList = ReadEffHistoList(src->String().Data());
370  if ( ! readList ) continue;
371  effHistoLists.Add(readList);
372  }
373 
374  return CompareEfficiencies(&effHistoLists, titles, opt, canvasNameSuffix);
375 }
376 
377 //________________________________________________________________________
378 Int_t AliMTRChEffAnalysis::CompareEfficiencies ( TObjArray* effHistoLists, const char* titles, const char* opt, const char* canvasNameSuffix ) const
379 {
381 
382  TString sTitles(titles);
383  TObjArray* titleList = sTitles.Tokenize(",");
384 
385  Int_t nDiffs = 0;
386 
387  Int_t nLists = effHistoLists->GetEntriesFast();
388 
389  TString sCanvasNameSuffix(canvasNameSuffix);
390  if ( ! sCanvasNameSuffix.IsNull() && ! sCanvasNameSuffix.BeginsWith("_") ) sCanvasNameSuffix.Prepend("_");
391 
392  Double_t xpt, ypt, xref, yref;
393  enum {kEff, kDiff, kPull};
394  TString sOpt(opt);
395  sOpt.ToLower();
396  Int_t iopt = kEff;
397  TString yTitle = "Eff.";
398  if ( sOpt.Contains("diff") ) {
399  iopt = kDiff;
400  yTitle = "Eff. - (ref.Eff)";
401  }
402  else if ( sOpt.Contains("pull") ) {
403  iopt = kPull;
404  yTitle = "(Eff - (ref.Eff)) / err";
405  }
406  else nDiffs = -1;
407 
408  if ( iopt != kEff && nLists <2 ) {
409  AliError(Form("You ask for %s but you only provided one set of histograms: nothing done",opt));
410  return -1;
411  }
412 
413  Bool_t needsLegend = ( nLists > 1 );
414 // if ( iopt != kEff ) needsLegend = nLists > 2;
415 
416  Int_t colors[] = {kBlack, kRed, kSpring, kTeal, kBlue, kViolet, kMagenta, kOrange, kGray};
417  Int_t ncolors = sizeof(colors)/sizeof(colors[0]);
418 
420 
421  TString currName = "";
422  Int_t ican = 0;
423  for ( Int_t itype=0; itype<2; itype++ ) {
424  TString xTitle = ( hTypes[itype] == AliTrigChEffOutput::kHslatEff ) ? "RPC" : "Board";
425  for ( Int_t icount=0; icount<3; icount++ ) {
426  TCanvas* can = 0x0;
427  for ( Int_t ich=0; ich<4; ich++ ) {
428  TLegend* leg = 0x0;
429 // Int_t hrefIdx = AliTrigChEffOutput::kNcounts + AliTrigChEffOutput::kNcounts*4*(itype-1) + 4*AliTrigChEffOutput::kAllTracks + ich;
430 // Int_t hIdx = AliTrigChEffOutput::kNcounts + AliTrigChEffOutput::kNcounts*4*(itype-1) + 4*icount + ich;
431  TGraphAsymmErrors* refGraph = 0x0;
432  for ( Int_t ilist=0; ilist<nLists; ilist++ ) {
433  TString currTitle = titleList->At(ilist)->GetName();
434  TList* effHistos = static_cast<TList*>(effHistoLists->UncheckedAt(ilist));
435  currName = Namer()->GetHistoName(hTypes[itype], AliTrigChEffOutput::kAllTracks, ich, -1, -1, -1);
436  TH1* histoDen = static_cast<TH1*>(effHistos->FindObject(currName.Data()));
437  currName = Namer()->GetHistoName(hTypes[itype], icount, ich, -1, -1, -1);
438  TH1* histoNum = static_cast<TH1*>(effHistos->FindObject(currName.Data()));
439  TGraphAsymmErrors* graph = new TGraphAsymmErrors(histoNum,histoDen,"e0");
440  currName = histoNum->GetName();
441  currName.ReplaceAll("Count","Eff");
442  currName.Append(Form("_%s",currTitle.Data()));
443  graph->SetName(currName.Data());
444 
445  if ( iopt != kEff ) {
446  if ( refGraph ) {
447  for ( Int_t ipt=0; ipt<graph->GetN(); ipt++ ) {
448  refGraph->GetPoint(ipt,xref,yref);
449  graph->GetPoint(ipt,xpt,ypt);
450  Double_t diff = ypt - yref;
451  if ( TMath::Abs(diff) > 1.e-4 ) nDiffs++;
452  if ( iopt == kDiff ) graph->SetPoint(ipt,xpt,diff);
453  else if ( iopt == kPull ) {
454  Double_t err = GetError(graph->GetErrorYlow(ipt),graph->GetErrorYhigh(ipt));
455  Double_t pull = ( err > 0. ) ? diff/err : 0.;
456  graph->SetPoint(ipt,xpt,pull);
457  }
458  } // loop on points
459  }
460  else {
461  refGraph = graph;
462  continue;
463  }
464  }
465 
466  if ( ! can ) {
467  currName = graph->GetName();
468  currName.Remove(currName.Length()-currTitle.Length()-5);
469  currName += sCanvasNameSuffix;
470  can = new TCanvas(currName.Data(),currName.Data(),20*ican,20*ican,600,600);
471  can->Divide(2,2);
472  ican++;
473  }
474  if ( needsLegend && ! leg ) {
475  leg = new TLegend(0.35, 0.15, 0.65, 0.45);
476  if ( refGraph ) leg->SetHeader(Form("Ref.: %s",titleList->At(0)->GetName()));
477  }
478  can->cd(ich+1);
479  gPad->SetGridy();
480  Int_t icolor = ( ilist < ncolors ) ? colors[ilist] : 20+ilist;
481  graph->SetLineColor(icolor);
482  graph->SetMarkerColor(icolor);
483  graph->SetMarkerStyle(20+ilist);
484  graph->SetMarkerSize(0.5);
485  graph->GetXaxis()->SetTitle(xTitle.Data());
486  graph->GetYaxis()->SetTitle(yTitle.Data());
487  graph->Draw((gPad->GetListOfPrimitives()->GetEntries()==0)?"ap":"p");
488  if ( leg ) leg->AddEntry(graph,titleList->At(ilist)->GetName(),"lp");
489  } // loop on lists
490  if (leg ) leg->Draw();
491  delete refGraph;
492  } // loop on chambers
493  } // loop on counts
494  } // loop on types
495 
496  delete titleList;
497 
498  return nDiffs;
499 }
500 
501 //________________________________________________________________________
502 Int_t AliMTRChEffAnalysis::CompareEfficiencyMethods ( const char* source, const char* opt, const char* canvasNameSuffix ) const
503 {
505  if ( ! fConditions ) {
506  AliWarning("No condition found! Please specify the default efficiency condition with SetEffConditions and then add additional tests with AddSystematicCondition");
507  return -1;
508  }
509 
510  AliTrigChEffOutput trigOut(source);
511 
512  Int_t nConditions = fConditions->GetEntriesFast();
513 
514  TString titles = "";
515  TObjArray effHistoLists;
516  effHistoLists.SetOwner();
517 
518  for ( Int_t icond=0; icond<nConditions; icond++ ) {
519  TObjArray* condition = static_cast<TObjArray*>(fConditions->UncheckedAt(icond));
520  TString condTitle = GetShortConditionTitle(condition->GetName());
521 
522  TList* effHistos = GetEffHistoList(&trigOut, condition);
523  effHistoLists.Add(effHistos);
524  titles += Form("%s,",condTitle.Data());
525  }
526 
527  titles.Remove(TString::kTrailing,',');
528  return CompareEfficiencies(&effHistoLists, titles, opt, canvasNameSuffix);
529 }
530 
531 
532 //________________________________________________________________________
534 {
535  if ( ! HasMergedResults() ) return;
536 
537  if ( fMergedMap.size() < 2 ) {
538  AliWarning("There is only one merged object: nothing to compare to");
539  return;
540  }
541 
542  AliInfo("Comparing the merged efficiencies");
543 
544  TObjArray* condition = static_cast<TObjArray*>(fConditions->At(0));
545  TString titles = "";
546 
547  TObjArray effHistoList;
549  TList* effHistos = obj->GetEffHistoList(condition->GetName());
550  effHistoList.Add(effHistos);
551  titles += Form("%i_%i,",obj->GetMinRun(),obj->GetMaxRun());
552  }
553  titles.Remove(TString::kTrailing,',');
554 
555  CompareEfficiencies(&effHistoList, titles.Data(), opt, "MergedComp");
556 }
557 
558 //________________________________________________________________________
559 Int_t AliMTRChEffAnalysis::ComputeAndCompareEfficiencies ( const char* sources, const char* titles, const char* opt, const char* canvasNameSuffix ) const
560 {
562  TString srcs(sources);
563  TObjArray* sourceList = srcs.Tokenize(",");
564  TObjArray effHistoLists;
565  effHistoLists.SetOwner();
566 
567  TObjArray* condition = static_cast<TObjArray*>(fConditions->At(0));
568  if ( ! condition ) {
569  AliError("The method requires to set an efficiency confition with SetEffConditions");
570  return -1;
571  }
572 
573  TIter next(sourceList);
574  TObjString* src = 0x0;
575  while ( (src = static_cast<TObjString*>(next())) ) {
576  if ( ! src->String().EndsWith(".root") ) {
577  AliError("The method reads files with the output of AliAnalysisTaskTrigChEff and re-compute the efficiency");
578  return -1;
579  }
580  AliTrigChEffOutput trigOut(src->GetName());
581  TList* readList = GetEffHistoList(&trigOut,condition);
582  if ( ! readList ) continue;
583  effHistoLists.Add(readList);
584  }
585 
586  return CompareEfficiencies(&effHistoLists, titles, opt, canvasNameSuffix);
587 }
588 
589 
590 //________________________________________________________________________
591 //TArrayI AliMTRChEffAnalysis::CheckHomogeneity ( const TGraphAsymmErrors* trendGraph, Double_t nSigmas, Bool_t revert ) const
592 //{
593 // /// Check efficiency homogeneity
594 // TArrayI ranges(trendGraph->GetN());
595 // Double_t xpt=0., ypt=0.;
596 //
597 // Double_t sumEffOverSigma2 = -10.;
598 // Double_t sumInvSimga2 = 0.001;
599 // Int_t irange = 0;
600 // Int_t npt = trendGraph->GetN();
601 // for ( Int_t ipt=0; ipt<npt; ipt++ ) {
602 // Int_t currPt = ( revert ) ? npt-1-ipt : ipt;
603 // trendGraph->GetPoint(currPt,xpt,ypt);
604 // Double_t err = GetError(trendGraph->GetErrorYlow(currPt),trendGraph->GetErrorYhigh(currPt));
605 // Double_t invSigma2 = 1./(err*err);
606 // Double_t effOverSigma2 = ypt*invSigma2;
607 //
608 // Double_t meanEff = sumEffOverSigma2 / sumInvSimga2;
609 // Double_t diff = ypt - meanEff;
610 // Double_t diffErr = TMath::Sqrt(err*err+1./sumInvSimga2);
612 // if ( TMath::Abs(diff)/diffErr > nSigmas ) {
613 // TString run = trendGraph->GetXaxis()->GetBinLabel(currPt+1);
614 // ranges[irange++] = run.Atoi();
615 // sumEffOverSigma2 = 0.;
616 // sumInvSimga2 = 0.;
617 // }
618 // sumEffOverSigma2 += effOverSigma2;
619 // sumInvSimga2 += invSigma2;
620 // }
621 // TString run = trendGraph->GetXaxis()->GetBinLabel(trendGraph->GetN());
622 // ranges[irange++] = run.Atoi();
623 // ranges.Set(irange);
624 // return ranges;
625 //}
626 
627 //________________________________________________________________________
628 void AliMTRChEffAnalysis::CopyDir(TDirectory *source) const
629 {
631  TDirectory *savdir = gDirectory;
632  TDirectory *adir = savdir->mkdir(source->GetName());
633  adir->cd();
634  //loop on all entries of this directory
635  TKey *key;
636  TIter nextkey(source->GetListOfKeys());
637  while ((key = (TKey*)nextkey())) {
638  const char *classname = key->GetClassName();
639  TClass *cl = gROOT->GetClass(classname);
640  if (!cl) continue;
641  if (cl->InheritsFrom(TDirectory::Class())) {
642  source->cd(key->GetName());
643  TDirectory *subdir = gDirectory;
644  adir->cd();
645  CopyDir(subdir);
646  adir->cd();
647  } else if (cl->InheritsFrom(TTree::Class())) {
648  TTree *T = (TTree*)source->Get(key->GetName());
649  adir->cd();
650  TTree *newT = T->CloneTree(-1,"fast");
651  newT->Write();
652  } else {
653  source->cd();
654  TObject *obj = key->ReadObj();
655  adir->cd();
656  obj->Write(obj->GetName(),TObject::kSingleKey);
657  delete obj;
658  }
659  }
660  adir->SaveSelf(kTRUE);
661  savdir->cd();
662 }
663 
664 
665 //________________________________________________________________________
666 Bool_t AliMTRChEffAnalysis::CopyLocally ( const char* runList, const char* path, const char* pattern, const char* localFileList, const char* outDir, const char* directory ) const
667 {
669  TString sPattern(pattern);
670  TString sOutDir(outDir);
671  TString sPath(path);
672  Bool_t isGrid = (! sPattern.IsNull());
673 
674  if ( sOutDir.IsNull() ) {
675  if ( isGrid ) {
676  TString data = sPath(TRegexp("/data/"));
677  TString year = sPath(TRegexp("/20[0-9][0-9]/"));
678  TString period = sPath(TRegexp("/LHC[0-9][0-9][a-z]"));
679  period.Append("/");
680  TString pass = AliAnalysisMuonUtility::GetPassName(path);
681  if ( pass.IsNull() ) pass = AliAnalysisMuonUtility::GetPassName(pattern);
682  sOutDir = data+year+period+pass;
683  sOutDir.ReplaceAll("//","/");
684  sOutDir.Remove(TString::kTrailing,'/');
685  sOutDir.Remove(TString::kLeading,'/');
686  }
687  else sOutDir = sPath;
688  sOutDir.Remove(TString::kTrailing,'/');
689  sOutDir.Remove(TString::kLeading,'/');
690  }
691 
692  TGridResult* res = 0x0;
693  Bool_t hasCurl = kFALSE;
694  if ( isGrid ) {
695  if ( ! gGrid ) TGrid::Connect("alien://");
696  res = gGrid->Query(path,pattern);
697  }
698  else {
699  if ( gSystem->Exec("which curl &> /dev/null") == 0 ) hasCurl = kTRUE;
700  }
701 
702  TList* rl = GetRunList(runList);
703 
704  ofstream outFile(localFileList);
705  Bool_t allOk = kTRUE;
706  Bool_t prompt = kTRUE;
707  Bool_t overwrite = kFALSE;
708  for ( Int_t irun=0; irun<rl->GetEntries(); irun++ ) {
709  TString run = static_cast<TObjString*>(rl->At(irun))->String();
710  TString dest = Form("%s/%09i/QAresults.root",sOutDir.Data(),run.Atoi());
711  TString destDir = gSystem->DirName(dest.Data());
712  if ( gSystem->AccessPathName(destDir.Data()) ) ExecCommand(Form("mkdir -p %s",destDir.Data()),kFALSE);
713  Bool_t copyFile = kTRUE;
714  Bool_t isFileOk = kTRUE;
715  if ( gSystem->AccessPathName(dest) == 0 ) {
716  if ( prompt ) {
717  TString decision = "";
718  cout << "Local file " << dest.Data() << " already exist: overwrite? [y/n/ya/na (a=use decision for all)]" << endl;
719  cin >> decision;
720  if ( decision.EndsWith("a") ) prompt = kFALSE;
721  if ( decision.BeginsWith("y") ) overwrite = kTRUE;
722  else overwrite = kFALSE;
723  }
724  copyFile = overwrite;
725  }
726  if ( copyFile ) {
727  TString src = "";
728  if ( isGrid ) {
729  for ( Int_t ifile=0; ifile<res->GetEntries(); ifile++ ) {
730  TString inFilename = res->GetKey(ifile,"turl");
731  if ( inFilename.Contains(run.Data()) ) {
732  src = inFilename;
733  break;
734  }
735  }
736  if ( src.IsNull() ) {
737  AliWarning(Form("Cannot find output for run %s",run.Data()));
738  isFileOk = kFALSE;
739  }
740  else {
741  TFile* outFile = TFile::Open(dest,"RECREATE");
742  TFile* inFile = TFile::Open(src);
743  inFile->cd();
744  TDirectory* dir = static_cast<TDirectory*>(inFile->Get(directory));
745  if ( dir ) {
746  outFile->cd();
747  CopyDir(dir);
748  }
749  else isFileOk = kFALSE;
750  delete inFile;
751  delete outFile;
752  }
753  }
754  else {
755  src = Form("http://aliqamu.web.cern.ch/aliqamu/%s",dest.Data());
756  // TFile::Cp was having some issue lately.
757  // If curl is found on the system, let's use it instead...
758  if ( hasCurl ) {
759  Int_t cmdOut = gSystem->Exec(Form("curl -f -# -o %s %s",dest.Data(),src.Data()));
760  isFileOk = ( cmdOut == 0 );
761  }
762  else isFileOk = TFile::Cp(src.Data(),dest.Data());
763  }
764  }
765 
766  if ( isFileOk ) outFile << gSystem->pwd() << "/" << dest.Data() << endl;
767  else {
768  AliWarning(Form("Problem getting run %s",run.Data()));
769  allOk = kFALSE;
770  }
771  }
772  delete rl;
773  outFile.close();
774  return allOk;
775 }
776 
777 //________________________________________________________________________
778 void AliMTRChEffAnalysis::DrawEffTrend ( Int_t itype, Int_t irpc, Double_t maxNsigmaOutliers, Double_t minEff, Double_t maxEff ) const
779 {
781  if ( Check() ) return;
782 
783  TString baseNames[3] = {"Chamber","RPC","Board"};
784  TString base = baseNames[itype] + "Eff";
785  if ( itype == AliTrigChEffOutput::kHboardEff ) {
786  if ( irpc < 0 ) {
787  AliWarning("Please specify RPC");
788  return;
789  }
790  base += Form("InRPC%i",irpc);
791  }
792 
793  Int_t nColumns = 2;
794  Int_t nRows = 2;
795  Int_t width = 600;
796  Int_t height = 600;
797  Int_t nDetEl = 4;
798  Int_t nCh = 1;
799  Double_t legYmin = 0.65;
800  Double_t legYmax = 0.9;
801  if ( itype != AliTrigChEffOutput::kHchamberEff ) {
802  nColumns = 6;
803  nRows = 3;
804  width = 1200;
805  height = 800;
806  nDetEl = 18;
807  nCh = 4;
808  legYmin = 0.15;
809  legYmax = 0.4;
810  }
811  TArrayI boards = BoardsInRPC(irpc);
812  if ( itype == AliTrigChEffOutput::kHboardEff ) nDetEl = boards.GetSize();
813 
814  for ( Int_t ich=0; ich<nCh; ich++ ) {
815  TString canName = base;
816  if ( itype != AliTrigChEffOutput::kHchamberEff ) canName += Form("Ch%i",11+ich);
817  TCanvas* can = new TCanvas(canName.Data(),canName.Data(),25*ich,25*ich,width,height);
818  can->Divide(nColumns,nRows,0,0);
819  can->SetTopMargin(0.);
820  can->SetBottomMargin(0.);
821  for ( Int_t idetelem=0; idetelem<nDetEl; idetelem++ ) {
822  can->cd(idetelem+1);
823  if ( idetelem/nColumns == nRows - 1 ) gPad->SetBottomMargin(0.15);
824  if ( gPad->GetListOfExecs()->GetEntries() == 0 ) gPad->AddExec("ZoomPad","AliMTRChEffAnalysis::ZoomPad()");
825  gPad->SetTicks(1,1);
826  gPad->SetGridy();
827  Int_t detElemId = idetelem;
828  if ( itype == AliTrigChEffOutput::kHchamberEff ) detElemId = 11+idetelem;
829  else if ( itype == AliTrigChEffOutput::kHboardEff ) detElemId = boards[idetelem];
830 
831  TString title = Form("%s %i",baseNames[itype].Data(),detElemId);
832  TLegend* leg = new TLegend(0.2,legYmin,0.8,legYmax);
833  leg->SetHeader(title.Data());
834  for ( Int_t icount=0; icount<2; icount++ ) {
835  TGraphAsymmErrors* gr = GetTrendEff(itype, icount, ich, detElemId);
836  gr->SetLineColor(icount+1);
837  gr->SetMarkerColor(icount+1);
838  gr->SetMarkerStyle(24+2*icount);
839  gr->GetYaxis()->SetRangeUser(minEff,maxEff);
840  gr->GetXaxis()->SetLabelSize(0.07);
841  gr->GetXaxis()->SetTitle("");
842  // gr->GetYaxis()->SetLabelSize(0.025*nRows);
843  // gr->GetXaxis()->SetLabelSize(0.025*nColumns);
844  gr->SetTitle("");
845  gr->Draw(icount==0?"ap":"p");
846  TString legTitle = ( icount==0 ) ? "bending plane" : "non-bending plane";
847  leg->AddEntry(gr,legTitle.Data(),"lp");
848  if ( maxNsigmaOutliers > 0. ) {
849  TGraphAsymmErrors* outliers = GetOutliers(gr,maxNsigmaOutliers);
850  outliers->SetLineColor(6+icount);
851  outliers->SetMarkerColor(6+icount);
852  outliers->SetMarkerStyle(20+2*icount);
853  outliers->SetLineWidth(2);
854  outliers->Draw("p");
855  legTitle.ReplaceAll("plane","outliers");
856  leg->AddEntry(outliers,legTitle.Data(),"lp");
857  }
858  }
859  leg->Draw();
860  }
861  if ( itype == AliTrigChEffOutput::kHchamberEff ) break;
862  }
863 }
864 
865 //________________________________________________________________________
866 void AliMTRChEffAnalysis::DrawStatContribution ( Int_t itype, Int_t irpc, Double_t maxNsigmaOutliers, Double_t minY, Double_t maxY ) const
867 {
869  if ( itype == AliTrigChEffOutput::kHchamberEff ) {
870  AliWarning("This function is valid only for itype 1 and 2");
871  return;
872  }
873 
874  TString baseNames[3] = {"Chamber","RPC","Board"};
875  TString base = baseNames[itype] + "Stat";
876  if ( itype == AliTrigChEffOutput::kHboardEff ) {
877  if ( irpc < 0 ) {
878  AliWarning("Please specify RPC");
879  return;
880  }
881  base += Form("InRPC%i",irpc);
882  }
883 
884  Int_t nColumns = 6;
885  Int_t nRows = 3;
886  Int_t width = 1200;
887  Int_t height = 800;
888  Int_t nDetEl = 18;
889  Int_t nCh = 1;
890 
891  TArrayI boards = BoardsInRPC(irpc);
892  if ( itype == AliTrigChEffOutput::kHboardEff ) nDetEl = boards.GetSize();
893 
894  for ( Int_t ich=0; ich<nCh; ich++ ) {
895  TH1* histos[nDetEl];
896  TH1* sumHistos = 0x0;
897  for ( Int_t idetelem=0; idetelem<nDetEl; idetelem++ ) {
898  Int_t detElemId = idetelem;
899  if ( itype == AliTrigChEffOutput::kHboardEff ) detElemId = boards[idetelem];
900  histos[idetelem] = GetTrend(itype, AliTrigChEffOutput::kAllTracks, ich, detElemId);
901  histos[idetelem]->SetName(Form("%s_stat",histos[idetelem]->GetName()));
902  histos[idetelem]->SetStats(0);
903  if ( sumHistos ) sumHistos->Add(histos[idetelem]);
904  else sumHistos = static_cast<TH1*>(histos[idetelem]->Clone("sumHistos"));
905  }
906 
907  TString canName = base; //Form("%sCh%i",base.Data(),11+ich);
908  TCanvas* can = new TCanvas(canName.Data(),canName.Data(),25*ich,25*ich,width,height);
909  can->Divide(nColumns,nRows,0,0);
910  for ( Int_t idetelem=0; idetelem<nDetEl; idetelem++ ) {
911  can->cd(idetelem+1);
912  if ( gPad->GetListOfExecs()->GetEntries() == 0 ) gPad->AddExec("ZoomPad","AliMTRChEffAnalysis::ZoomPad()");
913  gPad->SetTicks(1,1);
914  gPad->SetGridy();
915  Int_t detElemId = idetelem;
916  if ( itype == AliTrigChEffOutput::kHboardEff ) detElemId = boards[idetelem];
917  TString title = Form("%s %i",baseNames[itype].Data(),detElemId);
918  TLegend* leg = new TLegend(0.2,0.65,0.8,0.9);
919  leg->SetHeader(title.Data());
920  TGraphAsymmErrors* gr = new TGraphAsymmErrors(histos[idetelem],sumHistos,"e0");
921  gr->SetHistogram(static_cast<TH1F*>(histos[idetelem]));
922 
923  gr->SetMarkerStyle(24);
924  gr->SetMarkerSize(0.5);
925  gr->GetYaxis()->SetRangeUser(minY,maxY);
926  gr->GetYaxis()->SetTitle(Form("Tracks in %s / Sum of tracks of %ss in %s",baseNames[itype].Data(),baseNames[itype].Data(),baseNames[itype-1].Data()));
927  gr->SetTitle("");
928  gr->Draw("ap");
929  TString legTitle = "stat";
930 // leg->AddEntry(gr,legTitle.Data(),"lp");
931  if ( maxNsigmaOutliers > 0. ) {
932  TGraphAsymmErrors* outliers = GetOutliers(gr,maxNsigmaOutliers);
933  outliers->SetLineColor(6);
934  outliers->SetMarkerColor(6);
935  outliers->SetMarkerStyle(20);
936  outliers->SetLineWidth(2);
937  outliers->Draw("p");
938  legTitle = "outliers";
939  leg->AddEntry(outliers,legTitle.Data(),"lp");
940  }
941 // }
942  leg->Draw();
943  }
944  delete sumHistos;
945  }
946 }
947 
948 //________________________________________________________________________
950 {
952  if ( ! HasMergedResults() ) return kFALSE;
953 
954  AliInfo("Drawing the systematic variations");
955 
956  Int_t colors[] = {kBlack, kRed, kSpring, kTeal, kBlue, kViolet, kMagenta, kOrange, kGray};
957  Int_t ncolors = sizeof(colors)/sizeof(colors[0]);
958 
961 
962  Double_t xpt, ypt, xref, yref;
963  TArrayD eff(4), effErr(4);
964 
965  Int_t imerged = -1;
967  imerged++;
968  std::vector<std::string> systKeys = obj->GetSortKeys();
969  std::vector<std::string> shortSystName;
970  for ( std::string str : systKeys ) {
971  shortSystName.push_back(GetShortConditionTitle(str.c_str()).Data());
972  }
973  Int_t nSysts = systKeys.size();
974 
975  TString baseName = Form("mergedTrigEff_%i_%i",obj->GetMinRun(),obj->GetMaxRun());
976 
977  TArrayI isEmpty(nSysts);
978 
979  // First get the needed graphs
980  Int_t nDE = 0;
981  TObjArray effGraphs[8];
982  for ( Int_t iplane=0; iplane<8; iplane++ ) {
983  effGraphs[iplane].SetOwner();
984  }
985  TString titles = "";
986  TObjArray effHistoLists;
987 // effHistoLists.SetOwner();
988  for ( Int_t isyst=0; isyst<nSysts; isyst++ ) {
989  TList* effHistos = obj->GetEffHistoList(systKeys[isyst].c_str());
990  effHistoLists.Add(effHistos);
991  titles += Form("%s,",shortSystName[isyst].c_str());
992 
993  for ( Int_t ich=0; ich<4; ich++ ) {
994  TString currName = Namer()->GetHistoName(itype, AliTrigChEffOutput::kAllTracks, ich, -1, -1, -1);
995  TH1* histoDen = static_cast<TH1*>(effHistos->FindObject(currName.Data()));
996  for ( Int_t icount=0; icount<2; icount++ ) {
997  Int_t iplane = 4*icount+ich;
998 
999  if ( histoDen->GetEntries() > 0 ) {
1000  currName = Namer()->GetHistoName(itype, countTypes[icount], ich, -1, -1, -1);
1001  TH1* histoNum = static_cast<TH1*>(effHistos->FindObject(currName.Data()));
1002  TGraphAsymmErrors* gr = new TGraphAsymmErrors(histoNum,histoDen,"e0");
1003  nDE = gr->GetN();
1004  effGraphs[iplane].AddAtAndExpand(gr,isyst);
1005  }
1006  else {
1007  isEmpty[isyst] = 1;
1008  AliWarning(Form("No entries in count %i and ch %i for %s",countTypes[icount],ich,shortSystName[isyst].c_str()));
1009  }
1010  }
1011  }
1012  }
1013 
1014  titles.Remove(TString::kTrailing,',');
1015  CompareEfficiencies(&effHistoLists, titles, "diff", baseName.Data());
1016 
1017  // Draw average dispersion per plane
1018  TString canName = Form("EffSyst_%s",baseName.Data());
1019  Int_t pos = 25*(imerged+1);
1020  TCanvas* can = new TCanvas(canName.Data(),canName.Data(),pos,pos,1200,800);
1021  can->Divide(4,2,0,0);
1022 
1023  for ( Int_t icount=0; icount<2; icount++ ) {
1024  for ( Int_t ich=0; ich<4; ich++ ) {
1025  Int_t iplane = 4*icount+ich;
1026  can->cd(iplane+1);
1027  if ( gPad->GetListOfExecs()->GetEntries() == 0 ) gPad->AddExec("ZoomPad","AliMTRChEffAnalysis::ZoomPad()");
1028  gPad->SetTicks(1,1);
1029  gPad->SetLogy();
1030  TLegend* leg = new TLegend(0.15,0.7,0.9,0.9);
1031  leg->SetHeader(Namer()->GetHistoName(-1,icount,ich,-1,-1,-1));
1032  TH1* sumHisto = 0x0;
1033  for ( Int_t isyst=1; isyst<nSysts; isyst++ ) {
1034  if ( isEmpty[isyst] == 1 ) continue;
1035  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);
1036  histo->GetXaxis()->SetTitle("Eff.-(ref.Eff.)");
1037  histo->GetYaxis()->SetTitle("1/#sigma^{2}");
1038 
1039  TGraphAsymmErrors* gr = static_cast<TGraphAsymmErrors*>(effGraphs[iplane].UncheckedAt(isyst));
1040  TGraphAsymmErrors* grRef = static_cast<TGraphAsymmErrors*>(effGraphs[iplane].UncheckedAt(0));
1041  for ( Int_t ipt=0; ipt<gr->GetN(); ipt++ ) {
1042  gr->GetPoint(ipt,xpt,ypt);
1043  Double_t err = GetError(gr->GetErrorYlow(ipt),gr->GetErrorYhigh(ipt));
1044  Double_t invErr2 = ( err > 0. ) ? 1./(err*err) : 0.;
1045  grRef->GetPoint(ipt,xref,yref);
1046 
1047  Double_t diff = ypt-yref;
1048  histo->Fill(diff,invErr2);
1049  }
1050 
1051  if ( ! sumHisto ) {
1052  sumHisto = static_cast<TH1*>(histo->Clone(Form("syst_%s_plane%i_ch%i",baseName.Data(),icount,11+ich)));
1053  sumHisto->SetLineColor(1);
1054  sumHisto->Draw();
1055  leg->AddEntry(sumHisto,"All systematics","l");
1056  }
1057  else sumHisto->Add(histo);
1058  Int_t icolor = ( isyst < ncolors ) ? colors[isyst] : 20+isyst;
1059  histo->SetLineColor(icolor);
1060  histo->Draw("same");
1061  leg->AddEntry(histo,shortSystName[isyst].c_str(),"l");
1062  } // loop on conditions
1063  leg->Draw();
1064  } // loop on chambers
1065  } // loop on counts
1066 
1067 
1068  canName = Form("TriggerEff_3outOf4_syst_%s",baseName.Data());
1069  pos += 50;
1070  TCanvas* canSyst = new TCanvas(canName.Data(),canName.Data(),pos,pos,600,600);
1071  canSyst->SetLogy();
1072  TLegend* leg = new TLegend(0.15,0.7,0.9,0.4);
1073 // leg->SetHeader(trigOut->GetHistoName(-1,icount,ich,-1,-1,-1));
1074  TH1* histo[nSysts];
1075  for ( Int_t isyst=0; isyst<nSysts; isyst++ ) {
1076  if ( isEmpty[isyst] == 1 ) continue;
1077  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);
1078  histo[isyst]->GetXaxis()->SetTitle("Trig. prob. - (ref. trig. prob)");
1079  histo[isyst]->GetYaxis()->SetTitle("1/#sigma^{2}");
1080  }
1081 
1082  for ( Int_t ipt=0; ipt<nDE; ipt++ ) {
1083  Double_t refTrigProb = 0.; // refTrigProbErr = 0.;
1084  for ( Int_t isyst=0; isyst<nSysts; isyst++ ) {
1085  if ( isEmpty[isyst] == 1 ) continue;
1086  Double_t trigProb = 1., trigProbErr2 = 0.;
1087  for ( Int_t icount=0; icount<2; icount++ ) {
1088  for ( Int_t ich=0; ich<4; ich++ ) {
1089  Int_t iplane = 4*icount+ich;
1090  TGraphAsymmErrors* gr = static_cast<TGraphAsymmErrors*>(effGraphs[iplane].UncheckedAt(isyst));
1091  gr->GetPoint(ipt,xpt,ypt);
1092  eff[ich] = ypt;
1093  effErr[ich] = GetError(gr->GetErrorYlow(ipt),gr->GetErrorYhigh(ipt));
1094  } // loop on chambers
1095  Double_t effErr34 = 0.;
1096  Double_t eff34 = GetThreeOfFour(eff,effErr,effErr34);
1097  trigProb *= eff34;
1098  trigProbErr2 += effErr34*effErr34;
1099  } // loop on counts
1100 
1101  if ( isyst == 0 ) {
1102  refTrigProb = trigProb;
1103 // refTrigProbErr = trigProbErr;
1104  }
1105  else {
1106  Double_t invErr2 = ( trigProbErr2>0. ) ? 1./trigProbErr2 : 0.;
1107  histo[isyst]->Fill(trigProb-refTrigProb,invErr2);
1108  }
1109  } // loop on conditions
1110  } // loop on points
1111 
1112  for ( Int_t isyst=0; isyst<nSysts; isyst++ ) {
1113  if ( isEmpty[isyst] == 1 ) continue;
1114  TString title = ( isyst == 0 ) ? "All systematics" : shortSystName[isyst].c_str();
1115  Int_t icolor = ( isyst < ncolors ) ? colors[isyst] : 20+isyst;
1116  histo[isyst]->SetLineColor(icolor);
1117  histo[isyst]->Draw((isyst == 0)?"":"same");
1118  leg->AddEntry(histo[isyst],title.Data(),"l");
1119  if ( isyst>0 ) histo[0]->Add(histo[isyst]);
1120  }
1121  leg->Draw();
1122  } // loop on merged output
1123  return kTRUE;
1124 }
1125 
1126 //________________________________________________________________________
1128 {
1130  TString decision = "y";
1131 
1132  if ( gROOT->IsBatch() ) prompt = kFALSE; // To run with crontab
1133 
1134  if ( prompt ) {
1135  cout << command.Data() << " ? [y/n]" << endl;
1136  cin >> decision;
1137  }
1138 
1139  decision.ToLower();
1140  if ( decision == "y" ) {
1141  cout << "Executing: " << command.Data() << endl;
1142  gSystem->Exec(command.Data());
1143  return kTRUE;
1144  }
1145 
1146  return kFALSE;
1147 }
1148 
1149 //________________________________________________________________________
1151 {
1158 
1159  Double_t xx = x[0];
1160  Double_t val = par[1];
1161  Int_t nChanges = par[0];
1162  Double_t matchDiff = 123456789.;
1163  Int_t matchChange = -1;
1164  for ( Int_t iknot=0; iknot<nChanges; iknot++ ) {
1165  Int_t iparChange = 2*(iknot+1);
1166  Double_t diff = xx - par[iparChange];
1167  if ( diff >= 0. && diff < matchDiff ) {
1168  matchDiff = diff;
1169  matchChange = iparChange;
1170  }
1171  }
1172  if ( matchChange >= 0 ) val = par[matchChange+1];
1173 
1174  return val;
1175 }
1176 
1177 //________________________________________________________________________
1178 Double_t AliMTRChEffAnalysis::GetAverageStat ( Int_t firstRun, Int_t lastRun, Int_t itype,Bool_t excludePeriphericBoard ) const
1179 {
1181 
1182  TH1* statHisto = 0x0;
1183 
1185  TList* effHistoList = obj->GetEffHistoList(fConditions->UncheckedAt(0)->GetName());
1186  Int_t run = obj->GetMinRun();
1187  if ( run < firstRun || run > lastRun ) continue;
1188  TH1* histo = GetHisto(effHistoList,itype,AliTrigChEffOutput::kAllTracks,0);
1189 // if ( ! histo ) continue;
1190  if ( statHisto ) statHisto->Add(histo);
1191  else statHisto = static_cast<TH1*>(histo->Clone("tmpStatHisto"));
1192 // delete histo;
1193  }
1194  if ( ! statHisto ) return 0.;
1195 
1196  Double_t statPerDE = 0.;
1197  Double_t nDe = 0.;
1198  if ( itype == AliTrigChEffOutput::kHboardEff && excludePeriphericBoard ) {
1199  Int_t excludeBoardsHalf[] = {1, 17, 39, 61, 77, 93,109,
1200  16, 38, 60, 76, 92, 108, 117,
1201  110, 111, 112, 113, 114, 115, 116};
1202  Int_t nExcludedHalf = sizeof(excludeBoardsHalf)/sizeof(excludeBoardsHalf[0]);
1203  for ( Int_t ibin=1; ibin<=statHisto->GetNbinsX(); ibin++ ) {
1204  Bool_t skip = kFALSE;
1205  for ( Int_t iexcl=0; iexcl<nExcludedHalf; iexcl++ ) {
1206  if ( ibin == excludeBoardsHalf[iexcl] || ibin == excludeBoardsHalf[iexcl]+117 ) {
1207  skip = kTRUE;
1208  break;
1209  }
1210  }
1211  if ( skip ) continue;
1212  statPerDE += statHisto->GetBinContent(ibin);
1213  nDe += 1.;
1214  }
1215  }
1216  else {
1217  statPerDE = statHisto->Integral();
1218  nDe = (Double_t)statHisto->GetNbinsX();
1219  }
1220  statPerDE = nDe > 0. ? statPerDE/nDe : -1.;
1221 
1222  delete statHisto;
1223  return statPerDE;
1224 }
1225 
1226 //________________________________________________________________________
1228 {
1230  Int_t itrackSel = condition->UncheckedAt(3)->GetUniqueID();
1231  Int_t imatch = condition->UncheckedAt(4)->GetUniqueID();
1232  Int_t imethod = condition->UncheckedAt(5)->GetUniqueID();
1233 
1234  return trigOut->GetEffHistoList(condition->At(0)->GetName(),condition->At(1)->GetName(),condition->At(2)->GetName(),itrackSel,imatch,imethod);
1235 }
1236 
1237 //________________________________________________________________________
1239 {
1241  return TMath::Max(errLow,errHigh);
1242 }
1243 
1244 //________________________________________________________________________
1245 TH1* AliMTRChEffAnalysis::GetHisto ( TList* effHistoList, Int_t itype, Int_t icount, Int_t ichamber ) const
1246 {
1248  Int_t ihisto = ( itype == AliTrigChEffOutput::kHchamberEff ) ? icount : AliTrigChEffOutput::kNcounts + 4*AliTrigChEffOutput::kNcounts*(itype-1) + 4*icount + ichamber;
1249  return static_cast<TH1*>(effHistoList->At(ihisto));
1250 }
1251 
1252 //________________________________________________________________________
1253 TArrayI AliMTRChEffAnalysis::GetHomogeneousRanges ( Double_t chi2Cut, Int_t maxNRanges, Double_t minEffVariation, Bool_t perRPC, TArrayI* forcedChanges, Double_t minEff, Double_t maxEff )
1254 {
1256 
1257  AliInfo("Selecting ranges with homogeneous efficiency");
1258 
1259  Int_t nRuns = fRunMap.size();
1260 
1261  TH1F* hRunChangeCount = new TH1F("runChangeCount","Number of RPCs changing efficiency per run",nRuns,-0.5,-0.5+(Double_t)nRuns);
1262  hRunChangeCount->SetXTitle("Run num.");
1263  hRunChangeCount->SetYTitle("Num. of RPCs with change in eff.");
1264  for ( Int_t irun=0; irun<nRuns; irun++ ) {
1265  hRunChangeCount->GetXaxis()->SetBinLabel(irun+1,Form("%i",GetRunNumber(irun)));
1266  }
1267 
1269 
1270  Int_t nCanvas = perRPC ? 4 : 18;
1271  TObjArray canList(nCanvas);
1272 
1273  for ( Int_t irpc=0; irpc<18; irpc++ ) {
1275  TArrayI boards = BoardsInRPC(irpc);
1276  Int_t firstDetEl = perRPC ? irpc : 0;
1277  Int_t lastDetEl = perRPC ? irpc : boards.GetSize()-1;
1278 
1279  for ( Int_t ich=0; ich<4; ich++ ) {
1280  Int_t ican = perRPC ? ich : irpc;
1281  TCanvas* can = static_cast<TCanvas*>(canList.At(ican));
1282  if ( ! can ) {
1283  TString canName = perRPC ? Form("testRanges_ch%i",11+ich) : Form("testRanges_RPC%i",irpc);
1284  can = new TCanvas(canName.Data(),canName.Data(),10*ich,10*ich,1200,800);
1285  can->Divide(6,3,0,0);
1286  can->SetMargin(0.,0.,0.,0.);
1287  canList.AddAt(can,ican);
1288  }
1289 
1290  for ( Int_t idetel=firstDetEl; idetel<=lastDetEl; idetel++ ) {
1291  Int_t currDE = ( perRPC ) ? idetel : boards[idetel];
1292 // for ( Int_t icount=0; icount<2; icount++ ) {
1293  TGraphAsymmErrors* trendGraph = GetTrendEff(itype,icount,ich,currDE);
1294  TArrayI range = GetHomogeneousRanges(trendGraph,chi2Cut,maxNRanges,minEffVariation,forcedChanges, kTRUE);
1295  trendGraph->GetYaxis()->SetRangeUser(minEff,maxEff);
1296 
1297  can->cd(idetel+1);
1298  if ( gPad->GetListOfExecs()->GetEntries() == 0 ) gPad->AddExec("ZoomPad","AliMTRChEffAnalysis::ZoomPad()");
1299  gPad->SetTicks(1,1);
1300  gPad->SetMargin(0.08,0.,0.08,0.);
1301  TString drawOpt = ( gPad->GetListOfPrimitives()->GetEntries() == 0 ) ? "ap" : "p";
1302 
1303  TString legendName = Form("%s_%i",can->GetName(),currDE);
1304  TLegend* leg = static_cast<TLegend*>(gPad->GetListOfPrimitives()->FindObject(legendName.Data()));
1305  if ( ! leg ) {
1306  leg = new TLegend(0.2,0.15,0.8,0.4);
1307  leg->SetHeader(Form("%s %i",perRPC?"RPC":"Board",currDE));
1308  leg->SetName(legendName.Data());
1309  }
1310 
1311  if ( ! perRPC ) {
1312  Int_t icolor = ich+1;
1313  trendGraph->SetLineColor(icolor);
1314  trendGraph->SetMarkerColor(icolor);
1315  trendGraph->SetMarkerStyle(24+ich);
1316  TF1* func = static_cast<TF1*>(trendGraph->GetListOfFunctions()->At(0));
1317  if ( func ) {
1318  func->SetLineWidth(2);
1319  func->SetLineColor(icolor);
1320  }
1321  }
1322  trendGraph->GetXaxis()->SetLabelSize(0.07);
1323  trendGraph->SetTitle("");
1324 
1325  trendGraph->Draw(drawOpt.Data());
1326  leg->AddEntry(trendGraph,Form("Chamber %i",11+ich),"lp");
1327  leg->Draw();
1328  for ( Int_t ichange=2; ichange<range.GetSize(); ichange++ ) {
1329  // Store only the run when the change applies
1330  if ( ichange%2 == 1 ) continue;
1331  Int_t runIdx = range[ichange];
1332 // if ( ichange != 0 ) {
1333  TLine* line = new TLine(runIdx,minEff,runIdx,maxEff);
1334  line->SetLineStyle(2);
1335  line->Draw("same");
1336  TLatex text;
1337  text.DrawLatex((Double_t)(runIdx-3),maxEff-0.1*(maxEff-minEff)*(Double_t)(ichange/2),Form("%i",GetRunNumber(runIdx)));
1338 // }
1339  hRunChangeCount->Fill(runIdx);
1340  if ( hRunChangeCount->GetBinContent(runIdx+1) == 1 ) {
1341  TString infoMsg = Form("Efficiency change in %i triggered by ch %i RPC %i",GetRunNumber(runIdx),11+ich,irpc);
1342  if ( ! perRPC ) infoMsg += Form(" Board %i",currDE);
1343  AliInfo(infoMsg.Data());
1344  }
1345  } // loop on change
1346  } // loop on detection element
1347 // }
1348  } // loop on chambers
1349  } // loop on RPC
1350 
1351  // Clusterize contiguous runs
1352  TArrayI runChangeClust(nRuns);
1353  Double_t sumWgtRun = 0.;
1354  Double_t sumWgt = 0;
1355  for ( Int_t irun=0; irun<=nRuns; irun++ ) {
1356  if ( irun == nRuns || hRunChangeCount->GetBinContent(irun+1) == 0 ) {
1357  if ( sumWgt > 0. ) {
1358  Int_t averageRun = TMath::Nint(sumWgtRun / sumWgt);
1359  AliDebug(2,Form("Average run: %i => %i",averageRun,GetRunNumber(averageRun)));
1360  runChangeClust[averageRun]++;
1361  sumWgtRun = 0.;
1362  sumWgt = 0.;
1363  }
1364  }
1365  if ( irun == nRuns ) break;
1366 
1367  AliDebug(2,Form("irun %i => %i: wgt %g",irun,GetRunNumber(irun),hRunChangeCount->GetBinContent(irun+1)));
1368 
1369 // Double_t wgt = (Double_t)runChangeCount[irun];
1370  Double_t wgt = hRunChangeCount->GetBinContent(irun+1);
1371  if ( forcedChanges ) {
1372  for ( Int_t ichange=0; ichange<forcedChanges->GetSize(); ichange++ ) {
1373  if ( GetRunNumber(irun) == forcedChanges->At(ichange) ) wgt *= 10.;
1374  }
1375  }
1376  sumWgtRun += wgt*(Double_t)irun;
1377  sumWgt += wgt;
1378  }
1379 
1380  TCanvas* summaryCan = new TCanvas("effChangeSummary","effChangeSummary",50,50,600,600);
1381  summaryCan->SetLogy();
1382  hRunChangeCount->GetXaxis()->LabelsOption("v");
1383  hRunChangeCount->Draw();
1384 
1385  Int_t ientry = 0;
1386  TArrayI runRanges(nRuns);
1387  runRanges[ientry++] = GetRunNumber(0);
1388  for ( Int_t irun=1; irun<nRuns; irun++ ) {
1389  if ( runChangeClust[irun] > 0 ) {
1390  runRanges[ientry++] = GetRunNumber(irun-1);
1391  runRanges[ientry++] = GetRunNumber(irun);
1392  }
1393  }
1394  runRanges[ientry++] = GetRunNumber(nRuns-1);
1395  runRanges.Set(ientry);
1396  return runRanges;
1397 }
1398 
1399 //________________________________________________________________________
1400 TArrayI AliMTRChEffAnalysis::GetHomogeneousRanges ( TGraphAsymmErrors* trendGraph, Double_t chi2Cut, Int_t maxNRanges, Double_t minEffVariation, TArrayI* forcedChanges, Bool_t returnIndex )
1401 {
1403 
1404  TArrayI runRanges;
1405  TF1* func = 0x0;
1406  TArrayD forcedChangesBin;
1407  Int_t nForced = 0;
1408  if ( forcedChanges ) {
1409  forcedChangesBin.Set(forcedChanges->GetSize());
1410  for ( Int_t ichange=0; ichange<forcedChanges->GetSize(); ichange++ ) {
1411  Int_t idx = GetIndexFromRun(forcedChanges->At(ichange));
1412  if ( idx >= 0 ) forcedChangesBin[nForced++] = (Double_t)idx;
1413  else AliWarning(Form("Cannot find run %i",forcedChanges->At(ichange)));
1414  }
1415  }
1416 
1417  Double_t minNormChi2 = 123456789.;
1418  Int_t minNormChi2Step = -1;
1419  TString fitOpt = "NQ0";
1420 // Double_t fakeVal = -999.;
1421 // TArrayD params(2*maxNRanges);
1422 // params.Reset(fakeVal);
1423 
1424  for ( Int_t istep=0; istep<maxNRanges; istep++ ) {
1425  Int_t nPars = 2*(istep+1);
1426  Double_t xMin = trendGraph->GetXaxis()->GetXmin();
1427  Double_t xMax = trendGraph->GetXaxis()->GetXmax();
1428  func = new TF1("rangeFunc",this,&AliMTRChEffAnalysis::FitRangesFunc,xMin,xMax,nPars,"AliMTRChEffAnalysis","FitRanges");
1429  func->FixParameter(0,istep);
1430  for ( Int_t ipar=1; ipar<nPars; ipar++ ) {
1431 // if ( ipar >= 2*istep ) {
1432 // if ( TMath::Abs(params[ipar]-fakeVal) < 0.01 ) {
1433 // if ( ipar%2 == 1 ) params[ipar] = 0.95;
1434 // else params[ipar] = (xMax-xMin) * (Double_t)(ipar/2)/((Double_t)(istep+1));
1435 // }
1436 // func->SetParameter(ipar,params[ipar]);
1437  Double_t val = ( ipar%2 == 1 ) ? 0.95 : (xMax-xMin) * (Double_t)(ipar/2)/((Double_t)(istep+1));
1438  func->SetParameter(ipar,val);
1439  if ( ipar%2 == 0 ) func->SetParLimits(ipar,xMin,xMax);
1440  }
1441 
1442  TFitResultPtr fitResult = trendGraph->Fit(func,fitOpt.Data());
1443  // If fit converges close to a point where a break is forced
1444  // fix parameters and redo the fit
1445  if ( forcedChanges ) {
1446  Bool_t hasFixedPars = kFALSE;
1447  for ( Int_t iforced=0; iforced<nForced; iforced++ ) {
1448  for ( Int_t jstep=0; jstep<istep; jstep++ ) {
1449  Int_t ipar = 2*(jstep+1);
1450  if ( TMath::Abs(forcedChangesBin[iforced]-func->GetParameter(ipar)) > 2. ) continue;
1451  func->FixParameter(ipar,forcedChangesBin[iforced]);
1452  hasFixedPars = kTRUE;
1453  }
1454  }
1455  if ( hasFixedPars ) fitResult = trendGraph->Fit(func,fitOpt.Data());
1456  }
1457 
1458 // for ( Int_t ipar=1; ipar<nPars; ipar++ ) {
1459 // params[ipar] = func->GetParameter(ipar);
1460 // }
1461 
1462  Double_t normChi2 = func->GetChisquare() / ((Double_t)func->GetNDF());
1463  if ( normChi2 < minNormChi2 ) {
1464  minNormChi2 = normChi2;
1465  minNormChi2Step = istep;
1466  }
1467 // if ( static_cast<int>(fitResult) == 0 && normChi2 < chi2Cut ) break;
1468  if ( normChi2 < chi2Cut ) break; // REMEMBER TO CHECK
1469  delete func;
1470  func = 0x0;
1471  }
1472 
1473  if ( func ) {
1474  trendGraph->GetListOfFunctions()->Add(func->Clone());
1475  Int_t nSteps = (Int_t)func->GetParameter(0);
1476 
1477  // The runs for which the efficiency changes could be unsorted
1478  // (when forced values are requires)
1479  // Copy the parameters in arrays to sort them
1480  Int_t nPoints = nSteps+1;
1481  TArrayD parRunIdx(nPoints);
1482  TArrayD parEff(nPoints);
1483  for ( Int_t ipar=0; ipar<func->GetNpar(); ipar++ ) {
1484  Int_t istep = ipar/2;
1485  if ( ipar%2 == 0 ) parRunIdx[istep] = func->GetParameter(ipar);
1486  else parEff[istep] = func->GetParameter(ipar);
1487  }
1488  parRunIdx[0] = 0.;
1489  TArrayI sortIdx(nPoints);
1490  TMath::Sort(nPoints,parRunIdx.GetArray(),sortIdx.GetArray(),kFALSE);
1491 
1492  runRanges.Set(2*nPoints);
1493  Int_t irun = 0;
1494  runRanges[irun++] = returnIndex ? 0 : GetRunNumber(0);
1495  for ( Int_t ipoint=1; ipoint<nPoints; ipoint++ ) {
1496  Double_t deltaEff = TMath::Abs(parEff[sortIdx[ipoint]]-parEff[sortIdx[ipoint-1]]);
1497 // if ( ipoint>=2 ) deltaEff = TMath::Max(deltaEff,TMath::Abs(parEff[sortIdx[ipoint]]-parEff[sortIdx[ipoint-2]]));
1498  if ( deltaEff < minEffVariation ) {
1499  AliWarning(Form("Efficiency variation for %s is %g => consider uniform",trendGraph->GetName(),deltaEff));
1500  continue;
1501  }
1502  Int_t runChangeIdx = TMath::Nint(parRunIdx[sortIdx[ipoint]]);
1503  AliDebug(1,Form("Change run: %s => %g => %i %i",trendGraph->GetName(),parRunIdx[sortIdx[ipoint]],runChangeIdx,GetRunNumber(runChangeIdx)));
1504  runRanges[irun++] = returnIndex ? runChangeIdx-1 : GetRunNumber(runChangeIdx-1);
1505  runRanges[irun++] = returnIndex ? runChangeIdx : GetRunNumber(runChangeIdx);
1506  }
1507  Int_t lastPt = trendGraph->GetN()-1;
1508  runRanges[irun++] = returnIndex ? lastPt : GetRunNumber(lastPt);
1509  runRanges.Set(irun);
1510  }
1511  else {
1512  AliWarning(Form("Fit did not converge for %s (minimum chi2 %g for step %i)",trendGraph->GetName(),minNormChi2,minNormChi2Step));
1513  }
1514  return runRanges;
1515 }
1516 
1517 //________________________________________________________________________
1518 TString AliMTRChEffAnalysis::GetId ( const char* condition, Int_t minRun, Int_t maxRun ) const
1519 {
1521  if ( maxRun < minRun ) maxRun = minRun;
1522  return Form("%s_%i_%i",condition,minRun,maxRun);
1523 }
1524 
1525 //________________________________________________________________________
1527 {
1530  if ( obj->GetMinRun() == runNumber ) {
1531  return obj->GetUniqueID();
1532  break;
1533  }
1534  }
1535  return -1;
1536 }
1537 
1538 //________________________________________________________________________
1540 {
1542 // TGraphAsymmErrors* outliers = new TGraphAsymmErrors();
1543  TGraphAsymmErrors* outliers = new TGraphAsymmErrors(*graph);
1544  outliers->SetHistogram(static_cast<TH1F*>(graph->GetHistogram()->Clone(Form("%s_outliers",graph->GetHistogram()->GetName()))));
1545 // outliers->SetLineColor(graph->GetLineColor()+1);
1546  if ( graph->GetListOfFunctions()->GetEntries() == 0 ) graph->Fit("pol0","Q0");
1547  TF1* func = static_cast<TF1*>(graph->GetListOfFunctions()->At(0));
1548 
1549  Double_t xpt, ypt;
1550  Int_t nremoved = 0;
1551  for ( Int_t ipt=0; ipt<graph->GetN(); ipt++ ) {
1552  graph->GetPoint(ipt,xpt,ypt);
1553  Double_t diff = ypt - func->Eval(xpt);
1554  Double_t err = ( diff > 0. ) ? graph->GetErrorYlow(ipt) : graph->GetErrorYhigh(ipt);
1555  if ( err <= 0. || TMath::Abs(diff)/err > maxNsigmas ) continue;
1556  outliers->RemovePoint(ipt-nremoved);
1557  nremoved++;
1558 // outliers->SetPoint(iopt,xpt,ypt);
1559  }
1560  return outliers;
1561 }
1562 
1563 //________________________________________________________________________
1565 {
1567  if ( ipt < 0 || ipt >= fRunMap.size() ) return -1;
1568  return fRunMap[ipt]->GetMinRun();
1569 }
1570 
1571 //________________________________________________________________________
1572 TList* AliMTRChEffAnalysis::GetRunList ( const char* runList ) const
1573 {
1575  TList* rl = new TList;
1576  rl->SetOwner();
1577  TString sRunList = gSystem->ExpandPathName(runList);
1578  if ( gSystem->AccessPathName(sRunList) || sRunList.EndsWith(".root") ) {
1579  sRunList.ReplaceAll(","," ");
1580  if ( sRunList.IsDigit() ) {
1581  TObjArray* arr = sRunList.Tokenize(" ");
1582  for ( Int_t iarr=0; iarr<arr->GetEntries(); iarr++ ) {
1583  rl->Add(new TObjString(arr->At(iarr)->GetName()));
1584  }
1585  delete arr;
1586  }
1587  }
1588  else {
1589  ifstream inFile(sRunList.Data());
1590  TString currLine = "";
1591  while ( ! inFile.eof() ) {
1592  currLine.ReadLine(inFile);
1593  TString currRun = AliAnalysisMuonUtility::GetRunNumberAsString(currLine);
1594  if ( ! currRun.IsNull() ) rl->Add(new TObjString(currRun));
1595  }
1596  inFile.close();
1597  }
1598  rl->Sort();
1599  return rl;
1600 }
1601 
1602 //________________________________________________________________________
1603 TString AliMTRChEffAnalysis::GetShortConditionTitle ( const char* conditionName ) const
1604 {
1606 
1607  TString sCond(conditionName);
1608  TObjArray* refCondition = static_cast<TObjArray*>(fConditions->UncheckedAt(0));
1609  TString sRef(refCondition->GetName());
1610 
1611  TObjArray* condition = static_cast<TObjArray*>(fConditions->FindObject(conditionName));
1612  TString title = "";
1613  if ( ! condition || sCond == sRef ) {
1614  title = sCond;
1615  }
1616  else {
1617  for ( Int_t ic=0; ic<condition->GetEntriesFast(); ic++ ) {
1618  TString currCond = static_cast<TObjString*>(condition->UncheckedAt(ic))->String();
1619  TString refCond = static_cast<TObjString*>(refCondition->UncheckedAt(ic))->String();
1620  if ( currCond == refCond ) continue;
1621  title += ";" + currCond;
1622  }
1623  title.Remove(TString::kLeading,';');
1624  }
1625  title.ReplaceAll(",","+");
1626 
1627  return title;
1628 }
1629 
1630 //________________________________________________________________________
1631 TH1* AliMTRChEffAnalysis::GetSum ( AliTrigChEffOutput* trigOut, TObjArray* condition, Int_t itype, Int_t icount, Int_t ichamber ) const
1632 {
1634  TString objName = "";
1635  for ( Int_t ic=3; ic<6; ic++ ) {
1636  objName += condition->UncheckedAt(ic)->GetName();
1637  }
1638  return static_cast<TH1*>(trigOut->GetSum(condition->At(0)->GetName(),condition->At(1)->GetName(),condition->At(2)->GetName(),objName));
1639 }
1640 
1641 //________________________________________________________________________
1642 TH1* AliMTRChEffAnalysis::GetTrend ( Int_t itype, Int_t icount, Int_t ichamber, Int_t idetelem ) const
1643 {
1645  if ( itype == AliTrigChEffOutput::kHchamberEff ) {
1646  if ( idetelem < 0 && ichamber >=0 ) idetelem = 11+ichamber;
1647  }
1648  TH1* outHisto = 0x0;
1649 
1650  Int_t nRuns = fRunMap.size();
1651 
1652  Int_t ibin = 0;
1654  ibin++;
1655  TList* effHistoList = obj->GetEffHistoList(fConditions->UncheckedAt(0)->GetName());
1656  if ( ! outHisto ) {
1657 // TString outName = identifier;
1658  TString outName = Form("histo_type%i_count%i_ch%i_",itype,icount,11+ichamber);
1659 // outName.ReplaceAll("/","_");
1660  outName += Form("%i_trend",idetelem);
1661  outHisto = new TH1D(outName.Data(),outName.Data(),nRuns,0.,(Double_t)nRuns);
1662  outHisto->SetDirectory(0);
1663  outHisto->GetXaxis()->SetTitle("Run num.");
1664  }
1665  Int_t run = obj->GetMinRun();
1666  outHisto->GetXaxis()->SetBinLabel(ibin,Form("%i",run));
1667  TH1* histo = GetHisto(effHistoList,itype,icount,ichamber);
1668  Int_t currBin = histo->GetXaxis()->FindBin(idetelem);
1669  outHisto->SetBinContent(ibin,histo->GetBinContent(currBin));
1670  outHisto->SetBinError(ibin,histo->GetBinError(currBin));
1671  }
1672  if ( outHisto ) outHisto->GetXaxis()->LabelsOption("v");
1673  return outHisto;
1674 }
1675 
1676 //________________________________________________________________________
1677 TGraphAsymmErrors* AliMTRChEffAnalysis::GetTrendEff ( Int_t itype, Int_t icount, Int_t ichamber, Int_t idetelem ) const
1678 {
1680  if ( Check() ) return NULL;
1681  if ( icount == AliTrigChEffOutput::kAllTracks ) {
1682  AliWarning("Chose either bending plane, non-bending plane or both planes");
1683  return NULL;
1684  }
1685  TH1* histoNum = GetTrend(itype,icount,ichamber,idetelem);
1686  TH1* histoDen = GetTrend(itype,AliTrigChEffOutput::kAllTracks,ichamber,idetelem);
1687  TGraphAsymmErrors* graph = new TGraphAsymmErrors(histoNum,histoDen,"e0");
1688  histoNum->Reset();
1689  histoNum->SetStats(kFALSE);
1690  // Solves crash when saving the canvas as a root file
1691  graph->SetHistogram(new TH1F(*static_cast<TH1F*>(histoNum)));
1692  graph->GetHistogram()->SetDirectory(0);
1693  graph->GetYaxis()->SetTitle("Efficiency");
1694  graph->SetMarkerSize(0.5);
1695 // for ( Int_t ibin=1; ibin<=histoNum->GetXaxis()->GetNbins(); ibin++ ) {
1696 // graph->GetXaxis()->SetBinLabel(ibin,histoNum->GetXaxis()->GetBinLabel(ibin));
1697 // }
1698  delete histoNum;
1699  delete histoDen;
1700  return graph;
1701 }
1702 
1703 //________________________________________________________________________
1705 {
1707  Double_t binomialEff = 0.;
1708  Double_t sumErr2 = 0.;
1709  for ( Int_t jch=-1; jch<4; jch++ ) {
1710  Double_t prodEff = 1.;
1711  Double_t prodErr2 = 0.;
1712  for ( Int_t ich=0; ich<4; ich++ ) {
1713  Double_t currEff = ( ich == jch ) ? 1.-eff[ich] : eff[ich];
1714  prodEff *= currEff;
1715  Double_t relErr = ( currEff>0. ) ? effErr[ich]/currEff : 0.;
1716  prodErr2 += relErr*relErr;
1717  }
1718  binomialEff += prodEff;
1719  sumErr2 += prodEff*prodEff*prodErr2;
1720  }
1721  probErr = TMath::Sqrt(sumErr2);
1722  return binomialEff;
1723 }
1724 
1725 //________________________________________________________________________
1727 {
1729  if ( fMergedMap.empty() ) {
1730  AliError("You first need to merge efficiency objects with MergeOutput");
1731  return kFALSE;
1732  }
1733  return kTRUE;
1734 }
1735 
1736 //________________________________________________________________________
1737 Bool_t AliMTRChEffAnalysis::InitFromLocal ( const char *localFileList, const char *outputName )
1738 {
1740 
1741  AliInfo("Reading efficiency objects");
1742 
1744 
1745  TString filename(localFileList);
1746  gSystem->ExpandPathName(filename);
1747  if ( gSystem->AccessPathName(filename.Data()) ) {
1748  AliWarning(Form("Cannot find %s",filename.Data()));
1749  return kFALSE;
1750  }
1751  if ( filename.EndsWith(".root") ) return AddToList(filename.Data(),outputName);
1752 
1753  Bool_t isOk = kTRUE;
1754  // std::vector<Int_t> orderedRuns;
1755  std::map<int,std::string> tmpMap;
1756  ifstream inFile(filename.Data());
1757  TString currLine = "";
1758  while ( ! inFile.eof() ) {
1759  currLine.ReadLine(inFile);
1760  if ( currLine.IsNull() ) continue;
1761  if ( gSystem->AccessPathName(currLine.Data()) ) continue;
1762  int currRun = AliAnalysisMuonUtility::GetRunNumber ( currLine );
1763  tmpMap[currRun] = std::string(currLine.Data());
1764  // orderedRuns.push_back(currRun);
1765  }
1766  inFile.close();
1767 
1768  for ( auto it = tmpMap.begin(); it != tmpMap.end(); ++it ) {
1769  if ( ! AddToList(it->second.c_str(), outputName) ) isOk = kFALSE;
1770  }
1771 
1772  return isOk;
1773 }
1774 
1775 //________________________________________________________________________
1776 Bool_t AliMTRChEffAnalysis::InitFromGrid ( const char *runList, const char *path, const char *pattern, const char* localFileList, const char* outDir, const char *directory, const char* outputName )
1777 {
1779  CopyLocally(runList,path,pattern,localFileList,outDir,directory);
1780  return InitFromLocal(localFileList,outputName);
1781 }
1782 
1783 //________________________________________________________________________
1784 Bool_t AliMTRChEffAnalysis::InitFromWeb ( const char *runList, const char *path, const char* localFileList, const char* outDir, const char *directory, const char* outputName )
1785 {
1787  CopyLocally(runList,path,"",localFileList,outDir,directory);
1788  return InitFromLocal(localFileList,outputName);
1789 }
1790 
1791 //________________________________________________________________________
1792 Bool_t AliMTRChEffAnalysis::MergeOutput ( TArrayI runRanges, Double_t averageStatError, Bool_t isIndex )
1793 {
1795 
1796  if ( runRanges.GetSize()%2 == 1 ) {
1797  AliError("Run ranges expected in the form: start_period1,end_period1,start_period2,end_period2... => even number expected");
1798  return kFALSE;
1799  }
1800 
1801  TArrayI mergedRanges = MergeRangesForStat(runRanges, averageStatError);
1802 
1803  AliInfo("Merging efficiencies");
1804 
1805  Int_t nRanges = mergedRanges.GetSize()/2;
1806 
1807 
1808  if ( fMergedMap.size() > 0 ) {
1809  for ( AliMTRChEffAnalysis::AliMTRChEffInnerObj* obj : fMergedMap ) delete obj;
1810  fMergedMap.clear();
1811  }
1812 
1813  for ( Int_t irange=0; irange<nRanges; irange++ ) {
1814  Int_t firstRun = mergedRanges[2*irange];
1815  Int_t lastRun = mergedRanges[2*irange+1];
1816  if ( isIndex ) {
1817  firstRun = GetRunNumber(firstRun);
1818  lastRun = GetRunNumber(lastRun);
1819  }
1820 
1821  TString filename = "", outputname = "";
1822 
1823  TFileMerger fileMerger;
1825  Int_t run = obj->GetMinRun();
1826  if ( run < firstRun || run > lastRun ) continue;
1827  filename = obj->GetFilename();
1828  outputname = obj->GetOutputname();
1829  if ( firstRun == lastRun ) continue;
1830  fileMerger.AddFile(filename.Data(),kFALSE);
1831  }
1832 
1833  TString sRange = Form("%i_%i",firstRun,lastRun);
1834  TString mergedFilename = Form("mergedTrigEff_runs_%s.root",sRange.Data());
1835 
1836  if ( firstRun == lastRun ) TFile::Cp(filename.Data(),mergedFilename.Data(),kFALSE);
1837  else {
1838  fileMerger.OutputFile(mergedFilename.Data());
1839  fileMerger.Merge();
1840  }
1841  AliTrigChEffOutput* trigOut = new AliTrigChEffOutput(mergedFilename,outputname);
1842  AliMTRChEffInnerObj* mergedObj = new AliMTRChEffInnerObj(mergedFilename.Data(),outputname.Data(),firstRun,lastRun);
1843  for ( Int_t icond=0; icond<fConditions->GetEntriesFast(); icond++ ) {
1844  TObjArray* condition = static_cast<TObjArray*>(fConditions->UncheckedAt(icond));
1845  TList* effHistoList = GetEffHistoList(trigOut,condition);
1846  mergedObj->AddEffHistoList(condition->GetName(), effHistoList);
1847  }
1848  fMergedMap.push_back(mergedObj);
1849  delete trigOut;
1850  }
1851  return kTRUE;
1852 }
1853 
1854 //________________________________________________________________________
1855 TArrayI AliMTRChEffAnalysis::MergeRangesForStat ( TArrayI runRanges, Double_t averageStatError, Bool_t excludePeriphericBoards ) const
1856 {
1857  if ( averageStatError <= 0. || averageStatError >= 1. ) return runRanges;
1858 
1859  // FIXME: statstical error for binomial depends on the value of epsilon
1860  // for the moment let's assume an average efficiency of 0.9 (underestimated)
1861  // in the future one could maybe actually calculate it
1862  // (still we're working with average values...so the precision is limited)
1863  Double_t effForStatCalc = 0.9;
1864 
1865  Double_t averageStatNeeded = effForStatCalc*(1.-effForStatCalc)/(averageStatError*averageStatError);
1866 
1867  AliInfo(Form("Average statistics needed to reach precision of %g : %g",averageStatError,averageStatNeeded));
1868 
1869  Int_t nRanges = runRanges.GetSize()/2;
1870 
1871  TArrayD averageStat(nRanges);
1872  Double_t fullStat = 0.;
1873  for ( Int_t irange=0; irange<nRanges; irange++ ) {
1874  averageStat[irange] = GetAverageStat(runRanges[2*irange],runRanges[2*irange+1],AliTrigChEffOutput::kHboardEff,excludePeriphericBoards);
1875  fullStat += averageStat[irange];
1876  }
1877 
1878  TArrayI mergedRanges(runRanges.GetSize());
1879  Int_t imerged = 0;
1880  mergedRanges[imerged++] = runRanges[0];
1881  Double_t mergedAverageStat = 0., remainingStat = fullStat;
1882  for ( Int_t irange=0; irange<nRanges; irange++ ) {
1883  Int_t istart = 2*irange;
1884  Int_t iend = istart+1;
1885  mergedAverageStat += averageStat[irange];
1886  remainingStat -= averageStat[irange];
1887 
1888  AliInfo(Form("%i - %i => stat %g",runRanges[2*irange],runRanges[2*irange+1],averageStat[irange]));
1889 
1890  if ( ( mergedAverageStat >= averageStatNeeded && remainingStat >= averageStatNeeded ) || iend == runRanges.GetSize()-1 ) {
1891  mergedRanges[imerged++] = runRanges[iend];
1892  AliInfo(Form(" merged range %i - %i => stat %g",mergedRanges[imerged-2],mergedRanges[imerged-1],mergedAverageStat));
1893  mergedAverageStat = 0.;
1894  Int_t nextRun = iend+1;
1895  if ( nextRun < runRanges.GetSize() ) mergedRanges[imerged++] = runRanges[nextRun];
1896  }
1897  }
1898  mergedRanges.Set(imerged);
1899  return mergedRanges;
1900 }
1901 
1902 //________________________________________________________________________
1904 {
1906  if ( fNamer ) return fNamer;
1907 
1908  TObjArray arr;
1909  fNamer = new AliTrigChEffOutput(&arr,"dummy");
1910 
1911  return fNamer;
1912 }
1913 
1914 
1915 //________________________________________________________________________
1917 {
1919  TString currSrc(src);
1920  TString trigEffCDBdir = "MUON/Calib/TriggerEfficiency";
1921 
1922  if ( currSrc.BeginsWith("alien") && ! gGrid ) TGrid::Connect("alien://");
1923 
1924  AliMUONTriggerEfficiencyCells* effMap = 0x0;
1925  Bool_t deleteMap = kTRUE;
1926  if ( currSrc.EndsWith(".root") ) effMap = new AliMUONTriggerEfficiencyCells(currSrc.Data());
1927  else {
1928  TObjArray* dirRun = currSrc.Tokenize("?");
1929  TString cdbPath = dirRun->UncheckedAt(0)->GetName();
1930  TString runNum = ( dirRun->GetEntriesFast() > 1 ) ? dirRun->UncheckedAt(1)->GetName() : "";
1931  AliCDBManager* mgr = AliCDBManager::Instance();
1932  if ( ! mgr->GetDefaultStorage() ) mgr->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
1933  if ( mgr->GetEntryCache()->Contains(trigEffCDBdir.Data()) ) mgr->UnloadFromCache(trigEffCDBdir.Data());
1934  mgr->SetSpecificStorage(trigEffCDBdir.Data(),cdbPath.Data());
1935  Int_t runNumber = 0;
1936  if ( runNum.IsNull() ) {
1937  cout << "Please enter run number: " << endl;
1938  cin >> runNumber;
1939  }
1940  else runNumber = runNum.Atoi();
1941  mgr->SetRun(runNumber);
1942  AliCDBEntry* cdbEntry = mgr->Get(trigEffCDBdir.Data());
1943 
1944  // The CDB manager replace the current effMap with another in case two specific storage are provided
1945  // To avoid double deletion, do not delete the object
1946  deleteMap = kFALSE;
1947  effMap = static_cast<AliMUONTriggerEfficiencyCells*>(cdbEntry->GetObject());
1948  }
1949 
1950  if ( ! effMap ) {
1951  AliError(Form("Cannot find effieciency map in %s",src));
1952  return 0x0;
1953  }
1954 
1955  TList* effHistoList = CloneEffHistoList(effMap->GetHistoList());
1956  if ( deleteMap ) delete effMap;
1957 
1958  return effHistoList;
1959 }
1960 
1961 //________________________________________________________________________
1962 Bool_t AliMTRChEffAnalysis::RecoverEfficiency ( const char* runList, const char* ocdb, const char* systOcdb, Int_t referenceRun )
1963 {
1971 
1972  if ( ! HasMergedResults() ) return kFALSE;
1973 
1974  AliInfo("Check for local boards where the efficiency could not be computed and recover it from other maps");
1975 
1976  TList* rList = 0x0;
1977  std::vector<TList*> readEffLists;
1978  std::vector<TList*> systLists;
1979 
1980  TString refRun = "";
1981  if ( referenceRun >= 0 ) refRun = Form("%i",referenceRun);
1982  TList *refRead = 0x0, *refSyst = 0x0;
1983 
1984  // Search for chambers with missing efficiencies
1985  TString currName = "";
1987  TList* effList = obj->GetEffHistoList(fConditions->UncheckedAt(0)->GetName());
1988  std::vector<TH1*> histoList;
1989  histoList.reserve(16);
1990  for ( Int_t ich=0; ich<4; ich++ ) {
1991  for ( Int_t icount=0; icount<4; icount++ ) {
1992  currName = Namer()->GetHistoName(AliTrigChEffOutput::kHboardEff, icount, ich, -1, -1, -1);
1993  histoList[4*ich+icount] = static_cast<TH1*>(effList->FindObject(currName.Data()));
1994  }
1995  }
1996  for ( Int_t ibin=1; ibin<=histoList[0]->GetXaxis()->GetNbins(); ibin++ ) {
1997  Bool_t isUnknown[4] = {0,0,0,0};
1998  Int_t nDead = 0, nUnknown = 0;
1999  for ( Int_t ich=0; ich<4; ich++ ) {
2000  Double_t countAll = histoList[4*ich+AliTrigChEffOutput::kAllTracks]->GetBinContent(ibin);
2001  if ( countAll > 10 ) {
2002  Double_t eff = histoList[4*ich+AliTrigChEffOutput::kBothPlanesEff]->GetBinContent(ibin) / countAll;
2003  if ( eff<0.1 ) nDead++;
2004  }
2005  else {
2006  isUnknown[ich] = 1;
2007  nUnknown++;
2008  }
2009  }
2010  if ( nDead > 0 ) {
2011  if ( nUnknown == 3 ) {
2012  for ( Int_t ich=0; ich<4; ich++ ) {
2013  AliInfo(Form("Recovering board %i in ch %i",ibin,11+ich));
2014  if ( ! isUnknown[ich] ) continue;
2015  if ( readEffLists.size() == 0 ) {
2016  // Initialize once all needed objects for recovery
2017  rList = GetRunList(runList);
2018  if ( rList->GetEntries() == 0 ) {
2019  AliError("A recovery is needed, but no run list is specified: please specify it");
2020  return kFALSE;
2021  }
2022  if ( refRun.IsNull() ) refRun = rList->Last()->GetName();
2023  else if ( ! rList->FindObject(refRun.Data()) ) rList->Add(new TObjString(refRun));
2024  AliInfo(Form("Using efficiency of run %s",refRun.Data()));
2025  for ( Int_t itype=0; itype<2; itype++ ) {
2026  // Loop once on standard efficiency and another time for systematic efficiency
2027  TString currOcdb = ( itype == 0 ) ? ocdb : systOcdb;
2028  TString baseName = ( itype == 0 ) ? "RecoveredFrom" : "RecoveredSystFrom";
2029  TIter next(rList);
2030  TObjString* runObj = 0x0;
2031  while ( (runObj = static_cast<TObjString*>(next())) ) {
2032  Bool_t isRefRun = ( runObj->String() == refRun );
2033  // We only need the systematics for the chosen run
2034  if ( itype == 1 && ! isRefRun ) continue;
2035  TList* readList = ReadEffHistoList(Form("%s?%s",currOcdb.Data(),runObj->GetName()));
2036  readEffLists.push_back(readList);
2037 
2038  // The systematic efficiency list is a clone of the merged efficiency object
2039  // We will copy later on the recovered efficiency ONLY for the missing boards
2040  TList* systEffList = CloneEffHistoList(effList);
2041  systEffList->SetName(Form("%s_%s",baseName.Data(),runObj->GetName()));
2042  systLists.push_back(systEffList);
2043 
2044  if ( isRefRun && itype == 0 ) {
2045  refRead = readList;
2046  refSyst = systEffList;
2047  }
2048  } // loop on runs
2049  } // loop on standard or systematic OCDB
2050  }
2051  for ( UInt_t imap=0; imap<readEffLists.size(); imap++ ) {
2052  TList* readList = readEffLists[imap];
2053  for ( Int_t icount=0; icount<4; icount++ ) {
2054  currName = Namer()->GetHistoName(AliTrigChEffOutput::kHboardEff, icount, ich, -1, -1, -1);
2055  TH1* histoFrom = static_cast<TH1*>(readList->FindObject(currName.Data()));
2056  TH1* histoTo = ( readList == refRead ) ? histoList[4*ich+icount] : static_cast<TH1*>(systLists[imap]->FindObject(currName.Data()));
2057  histoTo->SetBinContent(ibin,histoFrom->GetBinContent(ibin));
2058  } // loop on counts
2059  } // loop on maps
2060  } // loop on chambers
2061  } // needs recovery
2062  else AliWarning(Form("Local board %i: unknown efficiency: %i %i %i %i",ibin,isUnknown[0],isUnknown[1],isUnknown[2],isUnknown[3]));
2063  }
2064  } // loop on local boards
2065  for ( TList* systEffHistoList : systLists ) {
2066  if ( systEffHistoList == refSyst ) continue;
2067  obj->AddEffHistoList(systEffHistoList->GetName(),systEffHistoList);
2068  }
2069  } // loop on merged objects
2070 
2071  // Delete objects
2072  for ( TList* obj : systLists ) delete obj;
2073  readEffLists.clear();
2074  delete rList;
2075 
2076  return kTRUE;
2077 }
2078 
2079 //________________________________________________________________________
2080 Bool_t AliMTRChEffAnalysis::SetCondition ( const char* physSel, const char* trigClassName, const char* centrality, Int_t itrackSel, Int_t imatch, Int_t imethod, Bool_t isBasic )
2081 {
2083  if ( ! fConditions ) {
2084  fConditions = new TObjArray();
2085  fConditions->SetOwner();
2086  }
2087 
2088 
2089  TString sCondition = Form("%s;%s;%s",physSel,trigClassName,centrality);
2090  sCondition += ";" + Namer()->GetHistoName(-1,-1,-1,itrackSel,-1,-1);
2091  sCondition += ";" + Namer()->GetHistoName(-1,-1,-1,-1,imatch,-1);
2092  sCondition += ";" + Namer()->GetHistoName(-1,-1,-1,-1,-1,imethod);
2093 
2094  TObjArray* foundCondition = static_cast<TObjArray*>(fConditions->FindObject(sCondition.Data()));
2095  TObjArray* basicCondition = static_cast<TObjArray*>(fConditions->At(0));
2096 
2097  TObjArray* addCondition = 0x0;
2098 
2099  if ( foundCondition ) {
2100  if ( isBasic ) {
2101  if ( foundCondition == basicCondition ) return kFALSE;
2102  else {
2103  fConditions->Remove(foundCondition);
2104  addCondition = foundCondition;
2105  }
2106  }
2107  else {
2108  AliInfo("Systematic condition already added");
2109  return kFALSE;
2110  }
2111  }
2112  else {
2113  addCondition = sCondition.Tokenize(";");
2114  addCondition->SetName(sCondition.Data());
2115  addCondition->UncheckedAt(3)->SetUniqueID(itrackSel);
2116  addCondition->UncheckedAt(4)->SetUniqueID(imatch);
2117  addCondition->UncheckedAt(5)->SetUniqueID(imethod);
2118  }
2119 
2120 
2121  if ( isBasic ) {
2122  if ( basicCondition ) {
2123  AliInfo(Form("Changing current eff. condition: %s",basicCondition->GetName()));
2124  fConditions->Remove(basicCondition);
2125  delete basicCondition;
2126  }
2127  fConditions->AddAt(addCondition,0);
2128  fConditions->Compress();
2129 
2130  // Update outputs
2132  obj->RemoveEffHistoList(sCondition.Data());
2133  AddToList(obj->GetFilename(), obj->GetOutputname());
2134  }
2135  }
2136  else fConditions->Add(addCondition);
2137 
2138  return kTRUE;
2139 }
2140 
2141 //________________________________________________________________________
2143 {
2146 }
2147 
2148 
2149 //________________________________________________________________________
2150 Bool_t AliMTRChEffAnalysis::SetEffConditions ( const char* physSel, const char* trigClassName, const char* centrality, Int_t itrackSel, Int_t imatch, Int_t imethod )
2151 {
2153  return SetCondition(physSel, trigClassName, centrality, itrackSel, imatch, imethod, kTRUE);
2154 }
2155 
2156 //________________________________________________________________________
2157 Bool_t AliMTRChEffAnalysis::WriteMergedToOCDB ( const char* outputCDB, Bool_t writeSystematics ) const
2158 {
2160  if ( ! HasMergedResults() ) return kFALSE;
2161 
2162  AliInfo("Writing merged efficiencies to OCDB");
2163 
2164  TString outCDB(outputCDB);
2165  if ( ! outCDB.Contains("://") || outCDB == "raw://" ) {
2166  AliError("Invalid CDB output dir");
2167  return kFALSE;
2168  }
2169 
2170  TString rmCommand = "rm";
2171  if ( outCDB.BeginsWith("alien://") && ! gGrid ) {
2172  TGrid::Connect("alien://");
2173  rmCommand = "alien_rm";
2174  if ( ! gGrid ) {
2175  AliError("Cannot open grid connection");
2176  return kFALSE;
2177  }
2178  }
2179 
2180  AliCDBManager* mgr = AliCDBManager::Instance();
2181  if ( ! mgr->GetDefaultStorage() ) mgr->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
2182 
2183  TString trigEffCDBdir = "MUON/Calib/TriggerEfficiency";
2184 
2185  mgr->SetSpecificStorage(trigEffCDBdir.Data(),outCDB.Data());
2186 
2187  AliCDBStorage* specificStorage = mgr->GetSpecificStorage(trigEffCDBdir.Data());
2188  TString baseOutDir = specificStorage->GetBaseFolder();
2189 
2190  TString condName = ( writeSystematics ) ? "Systematics" : fConditions->UncheckedAt(0)->GetName();
2191 
2193  TList* effHistos = obj->GetEffHistoList(condName.Data());
2194  if ( ! effHistos ) {
2195  AliWarning("No systematic condition found: you should first run BuildSystematicMap");
2196  continue;
2197  }
2198 
2199  // Write OCDB object
2200  Int_t firstRun = obj->GetMinRun();
2201  Int_t lastRun = obj->GetMaxRun();
2202 
2203  // If an object is already there, ask to remove it or keep it
2204  for ( Int_t irun=0; irun<2; irun++ ) {
2205  Int_t runnr = ( irun == 0 ) ? firstRun : lastRun;
2206  specificStorage->QueryCDB(runnr);
2207  TObjArray* allIdsForRun = specificStorage->GetQueryCDBList();
2208  TIter nextId(allIdsForRun);
2209  AliCDBId* id = 0x0;
2210  while ((id = static_cast<AliCDBId*>(nextId()))) {
2211  TString path(id->GetPath());
2212  Int_t foundFirst = id->GetFirstRun();
2213  Int_t foundLast = id->GetLastRun();
2214  Int_t version = id->GetVersion();
2215  Int_t subversion = TMath::Max(id->GetSubVersion(),0);
2216  TString fullPath = Form("%s/%s/Run%d_%d_v%d_s%d.root",baseOutDir.Data(),path.Data(),foundFirst,foundLast,version,subversion);
2217  ExecCommand(Form("%s %s",rmCommand.Data(),fullPath.Data()), kTRUE);
2218  }
2219  }
2220 
2221  // Save the CDB object in the specific storage
2222  AliMUONTriggerEfficiencyCells* effMap = new AliMUONTriggerEfficiencyCells(CloneEffHistoList(effHistos));
2223  AliMUONCDB::WriteToCDB(effMap, "MUON/Calib/TriggerEfficiency", firstRun, lastRun, "Measured efficiencies");
2224  delete effMap; // CAVEAT: effMap is owner of effHistos
2225  }
2226  return kTRUE;
2227 }
2228 
2229 //________________________________________________________________________
2231 {
2232  if ( gPad->GetEvent() != kButton1Double ) return;
2233  TVirtualPad* pad = gPad;
2234  Int_t px = pad->GetEventX();
2235  Int_t py = pad->GetEventY();
2236  TCanvas* can = new TCanvas("zoom","zoom",px,py,600,600);
2237  for ( Int_t iobj=0; iobj<pad->GetListOfPrimitives()->GetEntries(); iobj++ ) {
2238  TObject* obj = pad->GetListOfPrimitives()->At(iobj);
2239  obj = obj->Clone(Form("%s_zoom",obj->GetName()));
2240  TString drawOpt = obj->GetOption();
2241  if ( drawOpt.IsNull() ) {
2242  if ( obj->InheritsFrom(TGraph::Class()) ) {
2243  drawOpt = "p";
2244  if ( iobj == 1 ) drawOpt.Append("a");
2245  static_cast<TGraph*>(obj)->GetXaxis()->SetLabelSize();
2246  }
2247  else if ( obj->InheritsFrom(TH1::Class()) ) {
2248  drawOpt = "e";
2249  if ( iobj == 1 ) drawOpt.Append("same");
2250  static_cast<TH1*>(obj)->GetXaxis()->SetLabelSize();
2251  }
2252  }
2253  obj->Draw(drawOpt.Data());
2254  }
2255  can->Modified();
2256  can->Update();
2257 }
2258 
2259 //___________________________________________________________________________
2260 AliMTRChEffAnalysis::AliMTRChEffInnerObj::AliMTRChEffInnerObj ( const char* filename, const char* outputname, Int_t minRun, Int_t maxRun ) :
2261  TObject(),
2262  fFilename(filename),
2263  fOutputname(outputname),
2264  fMinRun(minRun),
2265  fMaxRun(maxRun)
2266 {
2268  if ( fMaxRun < fMinRun ) fMaxRun = fMinRun;
2269 }
2270 
2271 //___________________________________________________________________________
2273 {
2275  for ( auto& mapEntry : fEffLists ) delete mapEntry.second;
2276  fEffLists.clear();
2277 }
2278 
2279 //___________________________________________________________________________
2281 {
2283  auto const& mapEntry = fEffLists.find(condition);
2284  if ( mapEntry == fEffLists.end() ) return 0x0;
2285  return mapEntry->second;
2286 }
2287 
2288 //___________________________________________________________________________
2290 {
2292  if ( fEffLists.find(condition) != fEffLists.end() ) {
2293  AliWarning(Form("Condition %s already present: nothing done",condition));
2294  return kFALSE;
2295  }
2296  fEffLists.insert({condition,effHistoList});
2297  fSortKeys.push_back(condition);
2298  return kTRUE;
2299 }
2300 
2301 //___________________________________________________________________________
2303 {
2305  auto const& mapEntry = fEffLists.find(condition);
2306  if ( mapEntry == fEffLists.end() ) return kFALSE;
2307  delete mapEntry->second;
2308  return fEffLists.erase(condition);
2309 }
const char * filename
Definition: TestFCM.C:1
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
double Double_t
Definition: External.C:58
void CopyDir(TDirectory *source) const
Double_t GetError(Double_t errLow, Double_t errHigh) const
const char * title
Definition: MakeQAPdf.C:27
const char * cdbPath
Definition: AOD.C:26
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
AliRunLoader * rl
TSystem * gSystem
TGraphAsymmErrors * GetTrendEff(Int_t itype, Int_t icount, Int_t ichamber, Int_t idetelem) const
centrality
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 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
Int_t nDE
UShort_t T(UShort_t m, UShort_t t)
Definition: RingBits.C:60
TList * GetEffHistoList(AliTrigChEffOutput *trigOut, TObjArray *condition) const
int Int_t
Definition: External.C:63
Bool_t WriteMergedToOCDB(const char *outputCDB="CDB", Bool_t writeSystematics=kFALSE) const
unsigned int UInt_t
Definition: External.C:33
Bool_t AddToList(const char *filename, const char *outputName)
Number of count type.
Int_t CompareEfficiencyMethods(const char *source, const char *opt, const char *canvasNameSuffix="") const
Output for Trig chamber effieincy.
Bool_t InitFromLocal(const char *localFileList, const char *outputName="testMTRChamberEff")
Definition: External.C:212
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
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
Int_t colors[nPtBins]
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)
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)
Definition: PlotMuonQA.C:2235
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)
bool Bool_t
Definition: External.C:53
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)
Definition: External.C:196
TH1 * GetSum(AliTrigChEffOutput *trigOut, TObjArray *condition, Int_t itype, Int_t icount, Int_t ichamber) const
TDirectoryFile * dir
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