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