AliPhysics  a0db429 (a0db429)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 "TPRegexp.h"
26 #include "TRegexp.h"
27 #include "TFile.h"
28 #include "TDirectory.h"
29 #include "TTree.h"
30 #include "TKey.h"
31 #include "TArrayI.h"
32 #include "TArrayD.h"
33 #include "TGrid.h"
34 #include "TGridResult.h"
35 #include "TGraphAsymmErrors.h"
36 #include "TH1.h"
37 #include "TH2.h"
38 #include "TAxis.h"
39 #include "TF1.h"
40 #include "TMath.h"
41 #include "TCanvas.h"
42 #include "TLegend.h"
43 #include "TLine.h"
44 #include "TLatex.h"
45 #include "TFileMerger.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  fOutputs(0x0),
75  fConditions(0x0),
76  fMergedOutputs(0x0)
77 {
79 
80 }
81 
82 //________________________________________________________________________
83 AliMTRChEffAnalysis::AliMTRChEffAnalysis ( const char *localFileList, const char* outputName ) :
84  TObject(),
85  fOutputs(0x0),
86  fConditions(0x0),
87  fMergedOutputs(0x0)
88 {
90  SetOutList(localFileList,outputName);
91 }
92 
93 //________________________________________________________________________
95 {
96  //
98  //
99  delete fOutputs;
100  delete fConditions;
101  delete fMergedOutputs;
102 }
103 
104 //________________________________________________________________________
105 Bool_t AliMTRChEffAnalysis::AddSystematicCondition ( const char* physSel, const char* trigClassName, const char* centrality, Int_t itrackSel, Int_t imatch, Int_t imethod )
106 {
108  return SetCondition(physSel, trigClassName, centrality, itrackSel, imatch, imethod, kFALSE);
109 }
110 
111 //________________________________________________________________________
112 Bool_t AliMTRChEffAnalysis::AddToList ( const char *filename, const char *outputName )
113 {
115  AliTrigChEffOutput* trigOut = new AliTrigChEffOutput(filename,outputName);
116  if ( ! trigOut->GetMergeableCollection() ) {
117  AliError(Form("Cannot find %s in %s\n",outputName,filename));
118  return kFALSE;
119  }
120 
121  TObjArray* condition = static_cast<TObjArray*>(fConditions->At(0));
122 
123 // // Delete counter collection to save memory
124 // trigOut->RemoveFromList(trigOut->GetCounterCollection());
125  // Just keep counter and mergeable collections
126  TList* effHistoList = GetEffHistoList(trigOut,condition);
127  effHistoList->SetName(filename);
128  TString currRun = AliAnalysisMuonUtility::GetRunNumberAsString(filename);
129  effHistoList->SetUniqueID(currRun.Atoi());
130 
131  if ( ! fOutputs ) {
132  fOutputs = new TObjArray();
133  fOutputs->SetOwner();
134  fOutputs->SetName(outputName);
135  }
136  fOutputs->Add(effHistoList);
137  delete trigOut;
138  return kTRUE;
139 }
140 
141 //________________________________________________________________________
142 TArrayI AliMTRChEffAnalysis::BoardsInRPC ( Int_t irpc ) const
143 {
145 
146  // FIXME: ugly and hardcoded, but avoid loading the mapping
147 
148  TArrayI boards;
149  if ( irpc == 0 || irpc == 9 ) {
150  Int_t arr[] = {26,27,28,29,48,49,50,51,68,69,84,85,100,101,113};
151  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
152  boards.Set(nBoards,arr);
153  if ( irpc == 9 )
154  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
155  }
156  else if ( irpc == 1 || irpc == 8 ) {
157  Int_t arr[] = {9,10,11,30,31,32,33,52,53,54,55,70,71,86,87,102,103,114};
158  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
159  boards.Set(nBoards,arr);
160  if ( irpc == 8 )
161  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
162  }
163  else if ( irpc == 2 || irpc == 7 ) {
164  Int_t arr[] = {12,13,34,35,56,57,72,73,88,89,104,105,115};
165  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
166  boards.Set(nBoards,arr);
167  if ( irpc == 7 )
168  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
169  }
170  else if ( irpc == 3 || irpc == 6 ) {
171  Int_t arr[] = {14,15,36,37,58,59,74,75,90,91,106,107,116};
172  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
173  boards.Set(nBoards,arr);
174  if ( irpc == 6 )
175  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
176  }
177  else if ( irpc == 4 || irpc == 5 ) {
178  Int_t arr[] = {16,38,60,76,92,108,117};
179  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
180  boards.Set(nBoards,arr);
181  if ( irpc == 5 )
182  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
183  }
184  else if ( irpc == 17 || irpc == 10 ) {
185  Int_t arr[] = {6,7,8,22,23,24,25,44,45,46,47,66,67,82,83,98,99,112};
186  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
187  boards.Set(nBoards,arr);
188  if ( irpc == 10 )
189  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
190  }
191  else if ( irpc == 16 || irpc == 11 ) {
192  Int_t arr[] = {4,5,20,21,42,43,64,65,80,81,96,97,111};
193  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
194  boards.Set(nBoards,arr);
195  if ( irpc == 11 )
196  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
197  }
198  else if ( irpc == 15 || irpc == 12 ) {
199  Int_t arr[] = {2,3,18,19,40,41,62,63,78,79,94,95,110};
200  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
201  boards.Set(nBoards,arr);
202  if ( irpc == 12 )
203  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
204  }
205  else if ( irpc == 14 || irpc == 13 ) {
206  Int_t arr[] = {1,17,39,61,77,93,109};
207  Int_t nBoards = sizeof(arr)/sizeof(arr[0]);
208  boards.Set(nBoards,arr);
209  if ( irpc == 13 )
210  for ( Int_t iboard=0; iboard<nBoards; iboard++ ) boards[iboard] += 117;
211  }
212 
213  return boards;
214 }
215 
216 //________________________________________________________________________
217 void AliMTRChEffAnalysis::CompareEfficiencies ( const char* sources, const char* titles, const char* opt ) const
218 {
220  TString srcs(sources);
221  if ( srcs.Contains("raw://") ) {
222  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");
223  return;
224  }
225  TObjArray* sourceList = srcs.Tokenize(",");
226  TObjArray effMapList;
227  effMapList.SetOwner();
228 
229  TString trigEffCDBdir = "MUON/Calib/TriggerEfficiency";
230 
231  TIter next(sourceList);
232  TObjString* src = 0x0;
233  while ( (src = static_cast<TObjString*>(next())) ) {
234  TString currSrc = src->String();
235  if ( currSrc.BeginsWith("alien") && ! gGrid ) TGrid::Connect("alien://");
236 
237  AliMUONTriggerEfficiencyCells* effMap = 0x0;
238  if ( currSrc.EndsWith(".root") ) effMap = new AliMUONTriggerEfficiencyCells(currSrc.Data());
239  else {
240  TObjArray* dirRun = currSrc.Tokenize("?");
241  TString cdbPath = dirRun->UncheckedAt(0)->GetName();
242  TString runNum = ( dirRun->GetEntriesFast() > 1 ) ? dirRun->UncheckedAt(1)->GetName() : "";
243  AliCDBManager* mgr = AliCDBManager::Instance();
244  if ( ! mgr->GetDefaultStorage() ) mgr->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
245  mgr->SetSpecificStorage(trigEffCDBdir.Data(),cdbPath.Data());
246  Int_t runNumber = 0;
247  if ( runNum.IsNull() ) {
248  cout << "Please enter run number: " << endl;
249  cin >> runNumber;
250  }
251  else runNumber = runNum.Atoi();
252  mgr->SetRun(runNumber);
253  AliCDBEntry* cdbEntry = mgr->Get(trigEffCDBdir.Data());
254 
255  // The CDB manager replace the current effMap with another in case two specific storage are provided
256  // To avoid double deletion, the object must be cloned
257  effMap = static_cast<AliMUONTriggerEfficiencyCells*>(cdbEntry->GetObject()->Clone());
258  }
259  if ( ! effMap ) continue;
260  effMapList.Add(effMap);
261  }
262 
263  CompareEfficiencies(&effMapList, titles, opt);
264 }
265 
266 //________________________________________________________________________
267 void AliMTRChEffAnalysis::CompareEfficiencies ( TObjArray* effMapList, const char* titles, const char* opt ) const
268 {
270 
271  TString sTitles(titles);
272  TObjArray* titleList = sTitles.Tokenize(",");
273 
274  Int_t nLists = effMapList->GetEntriesFast();
275 
276  Double_t xpt, ypt, xref, yref;
277  enum {kEff, kDiff, kPull};
278  TString sOpt(opt);
279  sOpt.ToLower();
280  Int_t iopt = kEff;
281  TString yTitle = "Eff.";
282  if ( sOpt.Contains("diff") ) {
283  iopt = kDiff;
284  yTitle = "Eff. - (ref.Eff)";
285  }
286  else if ( sOpt.Contains("pull") ) {
287  iopt = kPull;
288  yTitle = "(Eff - (ref.Eff)) / err";
289  }
290 
291  Bool_t needsLegend = ( nLists > 1 );
292 // if ( iopt != kEff ) needsLegend = nLists > 2;
293 
294  Int_t colors[] = {kBlack, kRed, kSpring, kTeal, kBlue, kViolet, kMagenta, kOrange, kGray};
295  Int_t ncolors = sizeof(colors)/sizeof(colors[0]);
296 
297  Int_t hTypes[2] = {AliMUONTriggerEfficiencyCells::kHboardCount,AliMUONTriggerEfficiencyCells::kHslatCount};
298  Int_t countTypes[3] = {AliMUONTriggerEfficiencyCells::kBendingEff,AliMUONTriggerEfficiencyCells::kNonBendingEff,AliMUONTriggerEfficiencyCells::kBothPlanesEff};
299 
300  TString currName = "";
301  Int_t ican = 0;
302  for ( Int_t itype=0; itype<2; itype++ ) {
303  TString xTitle = ( hTypes[itype] == AliMUONTriggerEfficiencyCells::kHslatCount ) ? "RPC" : "Board";
304  for ( Int_t icount=0; icount<3; icount++ ) {
305  TCanvas* can = 0x0;
306  for ( Int_t ich=0; ich<4; ich++ ) {
307  TLegend* leg = 0x0;
308 // Int_t hrefIdx = AliTrigChEffOutput::kNcounts + AliTrigChEffOutput::kNcounts*4*(itype-1) + 4*AliTrigChEffOutput::kAllTracks + ich;
309 // Int_t hIdx = AliTrigChEffOutput::kNcounts + AliTrigChEffOutput::kNcounts*4*(itype-1) + 4*icount + ich;
310  TGraphAsymmErrors* refGraph = 0x0;
311  for ( Int_t ilist=0; ilist<nLists; ilist++ ) {
312  TString currTitle = titleList->At(ilist)->GetName();
313  AliMUONTriggerEfficiencyCells* effMap = static_cast<AliMUONTriggerEfficiencyCells*>(effMapList->UncheckedAt(ilist));
314  currName = effMap->GetHistoName(hTypes[itype],AliMUONTriggerEfficiencyCells::kAllTracks,ich);
315  TH1* histoDen = static_cast<TH1*>(effMap->GetHistoList()->FindObject(currName.Data()));
316  currName = effMap->GetHistoName(hTypes[itype],countTypes[icount],ich);
317  TH1* histoNum = static_cast<TH1*>(effMap->GetHistoList()->FindObject(currName.Data()));
318  TGraphAsymmErrors* graph = new TGraphAsymmErrors(histoNum,histoDen,"e0");
319  currName = histoNum->GetName();
320  currName.ReplaceAll("Count","Eff");
321  currName.Append(Form("_%s",currTitle.Data()));
322  graph->SetName(currName.Data());
323 
324  if ( iopt != kEff ) {
325  if ( refGraph ) {
326  for ( Int_t ipt=0; ipt<graph->GetN(); ipt++ ) {
327  refGraph->GetPoint(ipt,xref,yref);
328  graph->GetPoint(ipt,xpt,ypt);
329  if ( iopt == kDiff ) graph->SetPoint(ipt,xpt,ypt-yref);
330  else if ( iopt == kPull ) {
331  Double_t err = GetError(graph->GetErrorYlow(ipt),graph->GetErrorYhigh(ipt));
332  Double_t pull = ( err > 0. ) ? (ypt-yref)/err : 0.;
333  graph->SetPoint(ipt,xpt,pull);
334  }
335  } // loop on points
336  }
337  else {
338  refGraph = graph;
339  continue;
340  }
341  }
342 
343  if ( ! can ) {
344  currName = graph->GetName();
345  currName.Remove(currName.Length()-currTitle.Length()-5);
346  can = new TCanvas(currName.Data(),currName.Data(),20*ican,20*ican,600,600);
347  can->Divide(2,2);
348  ican++;
349  }
350  if ( needsLegend && ! leg ) {
351  leg = new TLegend(0.35, 0.15, 0.65, 0.45);
352  if ( refGraph ) leg->SetHeader(Form("Ref.: %s",titleList->At(0)->GetName()));
353  }
354  can->cd(ich+1);
355  gPad->SetGridy();
356  Int_t icolor = ( ilist < ncolors ) ? colors[ilist] : 20+ilist;
357  graph->SetLineColor(icolor);
358  graph->SetMarkerColor(icolor);
359  graph->SetMarkerStyle(20+ilist);
360  graph->SetMarkerSize(0.5);
361  graph->GetXaxis()->SetTitle(xTitle.Data());
362  graph->GetYaxis()->SetTitle(yTitle.Data());
363  graph->Draw((gPad->GetListOfPrimitives()->GetEntries()==0)?"ap":"p");
364  if ( leg ) leg->AddEntry(graph,titleList->At(ilist)->GetName(),"lp");
365  } // loop on lists
366  if (leg ) leg->Draw();
367  delete refGraph;
368  } // loop on chambers
369  } // loop on counts
370  } // loop on types
371 
372  delete titleList;
373 }
374 
375 //________________________________________________________________________
377 {
378  if ( ! HasMergedResults() ) return;
379 
380  TObjArray* condition = static_cast<TObjArray*>(fConditions->At(0));
381  TString titles = "";
382 
383  TObjArray effMapList;
384  effMapList.SetOwner();
385 
386  AliTrigChEffOutput* trigOut = 0x0;
387  TIter next(fMergedOutputs);
388  while ( (trigOut = static_cast<AliTrigChEffOutput*>(next())) ) {
389  TList* effList = GetEffHistoList(trigOut, condition);
390  AliMUONTriggerEfficiencyCells* effMap = new AliMUONTriggerEfficiencyCells(effList);
391  effMapList.Add(effMap);
392  titles += Form("%s,",trigOut->GetName());
393  }
394  titles.Remove(TString::kTrailing,',');
395 
396  CompareEfficiencies(&effMapList, titles.Data(), opt);
397 }
398 
399 
400 //________________________________________________________________________
401 //TArrayI AliMTRChEffAnalysis::CheckHomogeneity ( const TGraphAsymmErrors* trendGraph, Double_t nSigmas, Bool_t revert ) const
402 //{
403 // /// Check efficiency homogeneity
404 // TArrayI ranges(trendGraph->GetN());
405 // Double_t xpt=0., ypt=0.;
406 //
407 // Double_t sumEffOverSigma2 = -10.;
408 // Double_t sumInvSimga2 = 0.001;
409 // Int_t irange = 0;
410 // Int_t npt = trendGraph->GetN();
411 // for ( Int_t ipt=0; ipt<npt; ipt++ ) {
412 // Int_t currPt = ( revert ) ? npt-1-ipt : ipt;
413 // trendGraph->GetPoint(currPt,xpt,ypt);
414 // Double_t err = GetError(trendGraph->GetErrorYlow(currPt),trendGraph->GetErrorYhigh(currPt));
415 // Double_t invSigma2 = 1./(err*err);
416 // Double_t effOverSigma2 = ypt*invSigma2;
417 //
418 // Double_t meanEff = sumEffOverSigma2 / sumInvSimga2;
419 // Double_t diff = ypt - meanEff;
420 // Double_t diffErr = TMath::Sqrt(err*err+1./sumInvSimga2);
422 // if ( TMath::Abs(diff)/diffErr > nSigmas ) {
423 // TString run = trendGraph->GetXaxis()->GetBinLabel(currPt+1);
424 // ranges[irange++] = run.Atoi();
425 // sumEffOverSigma2 = 0.;
426 // sumInvSimga2 = 0.;
427 // }
428 // sumEffOverSigma2 += effOverSigma2;
429 // sumInvSimga2 += invSigma2;
430 // }
431 // TString run = trendGraph->GetXaxis()->GetBinLabel(trendGraph->GetN());
432 // ranges[irange++] = run.Atoi();
433 // ranges.Set(irange);
434 // return ranges;
435 //}
436 
437 //________________________________________________________________________
438 void AliMTRChEffAnalysis::CopyDir(TDirectory *source) const
439 {
441  TDirectory *savdir = gDirectory;
442  TDirectory *adir = savdir->mkdir(source->GetName());
443  adir->cd();
444  //loop on all entries of this directory
445  TKey *key;
446  TIter nextkey(source->GetListOfKeys());
447  while ((key = (TKey*)nextkey())) {
448  const char *classname = key->GetClassName();
449  TClass *cl = gROOT->GetClass(classname);
450  if (!cl) continue;
451  if (cl->InheritsFrom(TDirectory::Class())) {
452  source->cd(key->GetName());
453  TDirectory *subdir = gDirectory;
454  adir->cd();
455  CopyDir(subdir);
456  adir->cd();
457  } else if (cl->InheritsFrom(TTree::Class())) {
458  TTree *T = (TTree*)source->Get(key->GetName());
459  adir->cd();
460  TTree *newT = T->CloneTree(-1,"fast");
461  newT->Write();
462  } else {
463  source->cd();
464  TObject *obj = key->ReadObj();
465  adir->cd();
466  obj->Write(obj->GetName(),TObject::kSingleKey);
467  delete obj;
468  }
469  }
470  adir->SaveSelf(kTRUE);
471  savdir->cd();
472 }
473 
474 
475 //________________________________________________________________________
476 Bool_t AliMTRChEffAnalysis::CopyLocally ( const char* runList, const char* path, const char* pattern, const char* localFileList, const char* outDir, const char* directory ) const
477 {
479  TString sPattern(pattern);
480  TString sOutDir(outDir);
481  TString sPath(path);
482  Bool_t isGrid = (! sPattern.IsNull());
483 
484  if ( sOutDir.IsNull() ) {
485  if ( isGrid ) {
486  TString data = sPath(TRegexp("/data/"));
487  TString year = sPath(TRegexp("/20[0-9][0-9]/"));
488  TString period = sPath(TRegexp("/LHC[0-9][0-9][a-z]"));
489  period.Append("/");
490  // TPRegexp re("/(muon|pass).*?/");
491  TString pass = AliAnalysisMuonUtility::GetPassName(path);
492  if ( pass.IsNull() ) pass = AliAnalysisMuonUtility::GetPassName(pattern);
493  sOutDir = data+year+period+pass;
494  sOutDir.ReplaceAll("//","/");
495  sOutDir.Remove(TString::kTrailing,'/');
496  sOutDir.Remove(TString::kLeading,'/');
497  }
498  else sOutDir = sPath;
499  sOutDir.Remove(TString::kTrailing,'/');
500  sOutDir.Remove(TString::kLeading,'/');
501  }
502 
503  TGridResult* res = 0x0;
504  if ( isGrid ) {
505  if ( ! gGrid ) TGrid::Connect("alien://");
506  res = gGrid->Query(path,pattern);
507  }
508 
509  TList* rl = GetRunList(runList);
510 
511  ofstream outFile(localFileList);
512  Bool_t allOk = kTRUE;
513  Bool_t prompt = kTRUE;
514  Bool_t overwrite = kFALSE;
515  for ( Int_t irun=0; irun<rl->GetEntries(); irun++ ) {
516  TString run = static_cast<TObjString*>(rl->At(irun))->String();
517  TString dest = Form("%s/%09i/QAresults.root",sOutDir.Data(),run.Atoi());
518  TString destDir = gSystem->DirName(dest.Data());
519  if ( gSystem->AccessPathName(destDir.Data()) ) ExecCommand(Form("mkdir -p %s",destDir.Data()),kFALSE);
520  Bool_t copyFile = kTRUE;
521  Bool_t isFileOk = kTRUE;
522  if ( gSystem->AccessPathName(dest) == 0 ) {
523  if ( prompt ) {
524  TString decision = "";
525  cout << "Local file " << dest.Data() << " already exist: overwrite? [y/n/ya/na (a=use decision for all)]" << endl;
526  cin >> decision;
527  if ( decision.EndsWith("a") ) prompt = kFALSE;
528  if ( decision.BeginsWith("y") ) overwrite = kTRUE;
529  else overwrite = kFALSE;
530  }
531  copyFile = overwrite;
532  }
533  if ( copyFile ) {
534  TString src = "";
535  if ( isGrid ) {
536  for ( Int_t ifile=0; ifile<res->GetEntries(); ifile++ ) {
537  TString inFilename = res->GetKey(ifile,"turl");
538  if ( inFilename.Contains(run.Data()) ) {
539  src = inFilename;
540  break;
541  }
542  }
543  if ( src.IsNull() ) {
544  AliWarning(Form("Cannot find output for run %s",run.Data()));
545  isFileOk = kFALSE;
546  }
547  else {
548  TFile* outFile = TFile::Open(dest,"RECREATE");
549  TFile* inFile = TFile::Open(src);
550  inFile->cd();
551  TDirectory* dir = static_cast<TDirectory*>(inFile->Get(directory));
552  if ( dir ) {
553  outFile->cd();
554  CopyDir(dir);
555  }
556  else isFileOk = kFALSE;
557  delete inFile;
558  delete outFile;
559  }
560  }
561  else {
562  src = Form("http://aliqamu.web.cern.ch/aliqamu/%s",dest.Data());
563  isFileOk = TFile::Cp(src.Data(),dest.Data());
564  }
565  }
566 
567  if ( isFileOk ) outFile << gSystem->pwd() << "/" << dest.Data() << endl;
568  else allOk = kFALSE;
569  }
570  delete rl;
571  outFile.close();
572  return allOk;
573 }
574 
575 //________________________________________________________________________
576 void AliMTRChEffAnalysis::DrawEffTrend ( Int_t itype, Int_t irpc, Double_t maxNsigmaOutliers, Double_t minEff, Double_t maxEff ) const
577 {
579  TString baseNames[3] = {"Chamber","RPC","Board"};
580  TString base = baseNames[itype] + "Eff";
581  if ( itype == AliTrigChEffOutput::kHboardEff ) {
582  if ( irpc < 0 ) {
583  AliWarning("Please specify RPC");
584  return;
585  }
586  base += Form("InRPC%i",irpc);
587  }
588 
589  Int_t nColumns = 2;
590  Int_t nRows = 2;
591  Int_t width = 600;
592  Int_t height = 600;
593  Int_t nDetEl = 4;
594  Int_t nCh = 1;
595  if ( itype != AliTrigChEffOutput::kHchamberEff ) {
596  nColumns = 6;
597  nRows = 3;
598  width = 1200;
599  height = 800;
600  nDetEl = 18;
601  nCh = 4;
602  }
603  TArrayI boards = BoardsInRPC(irpc);
604  if ( itype == AliTrigChEffOutput::kHboardEff ) nDetEl = boards.GetSize();
605 
606  for ( Int_t ich=0; ich<nCh; ich++ ) {
607  TString canName = base;
608  if ( itype != AliTrigChEffOutput::kHchamberEff ) canName += Form("Ch%i",11+ich);
609  TCanvas* can = new TCanvas(canName.Data(),canName.Data(),25*ich,25*ich,width,height);
610  can->Divide(nColumns,nRows,0,0);
611  // can->SetTopMargin(0.03);
612  // can->SetBottomMargin(0.1);
613  for ( Int_t idetelem=0; idetelem<nDetEl; idetelem++ ) {
614  can->cd(idetelem+1);
615  gPad->SetTicks(1,1);
616  gPad->SetGridy();
617  Int_t detElemId = idetelem;
618  if ( itype == AliTrigChEffOutput::kHchamberEff ) detElemId = 11+idetelem;
619  else if ( itype == AliTrigChEffOutput::kHboardEff ) detElemId = boards[idetelem];
620 
621  TString title = Form("%s %i",baseNames[itype].Data(),detElemId);
622  TLegend* leg = new TLegend(0.2,0.15,0.8,0.4);
623  leg->SetHeader(title.Data());
624  for ( Int_t icount=0; icount<2; icount++ ) {
625  TGraphAsymmErrors* gr = GetTrendEff(itype, icount, ich, detElemId);
626  gr->SetLineColor(icount+1);
627  gr->SetMarkerColor(icount+1);
628  gr->SetMarkerStyle(24+2*icount);
629  gr->GetYaxis()->SetRangeUser(minEff,maxEff);
630  // gr->GetYaxis()->SetLabelSize(0.025*nRows);
631  // gr->GetXaxis()->SetLabelSize(0.025*nColumns);
632  gr->SetTitle("");
633  gr->Draw(icount==0?"ap":"p");
634  TString legTitle = ( icount==0 ) ? "bending plane" : "non-bending plane";
635  leg->AddEntry(gr,legTitle.Data(),"lp");
636  if ( maxNsigmaOutliers > 0. ) {
637  TGraphAsymmErrors* outliers = GetOutliers(gr,maxNsigmaOutliers);
638  outliers->SetLineColor(6+icount);
639  outliers->SetMarkerColor(6+icount);
640  outliers->SetMarkerStyle(20+2*icount);
641  outliers->SetLineWidth(2);
642  outliers->Draw("p");
643  legTitle.ReplaceAll("plane","outliers");
644  leg->AddEntry(outliers,legTitle.Data(),"lp");
645  }
646  }
647  leg->Draw();
648  }
649  if ( itype == AliTrigChEffOutput::kHchamberEff ) break;
650  }
651 }
652 
653 //________________________________________________________________________
654 void AliMTRChEffAnalysis::DrawStatContribution ( Int_t itype, Int_t irpc, Double_t maxNsigmaOutliers, Double_t minY, Double_t maxY ) const
655 {
657  if ( itype == AliTrigChEffOutput::kHchamberEff ) {
658  AliWarning("This function is valid only for itype 1 and 2");
659  return;
660  }
661 
662  TString baseNames[3] = {"Chamber","RPC","Board"};
663  TString base = baseNames[itype] + "Stat";
664  if ( itype == AliTrigChEffOutput::kHboardEff ) {
665  if ( irpc < 0 ) {
666  AliWarning("Please specify RPC");
667  return;
668  }
669  base += Form("InRPC%i",irpc);
670  }
671 
672  Int_t nColumns = 6;
673  Int_t nRows = 3;
674  Int_t width = 1200;
675  Int_t height = 800;
676  Int_t nDetEl = 18;
677  Int_t nCh = 1;
678 
679  TArrayI boards = BoardsInRPC(irpc);
680  if ( itype == AliTrigChEffOutput::kHboardEff ) nDetEl = boards.GetSize();
681 
682  for ( Int_t ich=0; ich<nCh; ich++ ) {
683  TH1* histos[nDetEl];
684  TH1* sumHistos = 0x0;
685  for ( Int_t idetelem=0; idetelem<nDetEl; idetelem++ ) {
686  Int_t detElemId = idetelem;
687  if ( itype == AliTrigChEffOutput::kHboardEff ) detElemId = boards[idetelem];
688  histos[idetelem] = GetTrend(itype, AliTrigChEffOutput::kAllTracks, ich, detElemId);
689  histos[idetelem]->SetName(Form("%s_stat",histos[idetelem]->GetName()));
690  histos[idetelem]->SetStats(0);
691  if ( sumHistos ) sumHistos->Add(histos[idetelem]);
692  else sumHistos = static_cast<TH1*>(histos[idetelem]->Clone("sumHistos"));
693  }
694 
695  TString canName = base; //Form("%sCh%i",base.Data(),11+ich);
696  TCanvas* can = new TCanvas(canName.Data(),canName.Data(),25*ich,25*ich,width,height);
697  can->Divide(nColumns,nRows,0,0);
698  for ( Int_t idetelem=0; idetelem<nDetEl; idetelem++ ) {
699  can->cd(idetelem+1);
700  gPad->SetTicks(1,1);
701  gPad->SetGridy();
702  Int_t detElemId = idetelem;
703  if ( itype == AliTrigChEffOutput::kHboardEff ) detElemId = boards[idetelem];
704  TString title = Form("%s %i",baseNames[itype].Data(),detElemId);
705  TLegend* leg = new TLegend(0.2,0.65,0.8,0.9);
706  leg->SetHeader(title.Data());
707  TGraphAsymmErrors* gr = new TGraphAsymmErrors(histos[idetelem],sumHistos,"e0");
708  gr->SetHistogram(static_cast<TH1F*>(histos[idetelem]));
709 
710  gr->SetMarkerStyle(24);
711  gr->SetMarkerSize(0.5);
712  gr->GetYaxis()->SetRangeUser(minY,maxY);
713  gr->GetYaxis()->SetTitle(Form("Tracks in %s / Sum of tracks of %ss in %s",baseNames[itype].Data(),baseNames[itype].Data(),baseNames[itype-1].Data()));
714  gr->SetTitle("");
715  gr->Draw("ap");
716  TString legTitle = "stat";
717 // leg->AddEntry(gr,legTitle.Data(),"lp");
718  if ( maxNsigmaOutliers > 0. ) {
719  TGraphAsymmErrors* outliers = GetOutliers(gr,maxNsigmaOutliers);
720  outliers->SetLineColor(6);
721  outliers->SetMarkerColor(6);
722  outliers->SetMarkerStyle(20);
723  outliers->SetLineWidth(2);
724  outliers->Draw("p");
725  legTitle = "outliers";
726  leg->AddEntry(outliers,legTitle.Data(),"lp");
727  }
728 // }
729  leg->Draw();
730  }
731  delete sumHistos;
732  }
733 }
734 
735 //________________________________________________________________________
736 Bool_t AliMTRChEffAnalysis::DrawSystematicEnvelope ( Bool_t perRPC, Double_t miny, Double_t maxy ) const
737 {
739  if ( ! HasMergedResults() ) return kFALSE;
740 
742 
743  Int_t colors[] = {kBlack, kRed, kSpring, kTeal, kBlue, kViolet, kMagenta, kOrange, kGray};
744  Int_t ncolors = sizeof(colors)/sizeof(colors[0]);
745 
746  Int_t nConditions = fConditions->GetEntriesFast();
747 
748 
749  TObjArray* refCondition = 0x0;
750  TObjArray condTitle(nConditions);
751  condTitle.SetOwner();
752 
753  Double_t xpt, ypt, xref, yref;
754  TArrayD eff(4), effErr(4);
755 
756  AliTrigChEffOutput* trigOut = 0x0;
757  TIter next(fMergedOutputs);
758  Int_t imerged = -1;
759  while ( (trigOut = static_cast<AliTrigChEffOutput*>(next())) ) {
760  imerged++;
761 
762  // Get meaningful short titles for each systematic
763  if ( imerged == 0 ) {
764  for ( Int_t icond=0; icond<nConditions; icond++ ) {
765  TObjArray* condition = static_cast<TObjArray*>(fConditions->UncheckedAt(icond));
766  if ( icond == 0 ) refCondition = condition;
767  TString title = "";
768  for ( Int_t ic=0; ic<condition->GetEntriesFast(); ic++ ) {
769  TString currCond = static_cast<TObjString*>(condition->UncheckedAt(ic))->String();
770  TString refCond = static_cast<TObjString*>(refCondition->UncheckedAt(ic))->String();
771  if ( currCond == refCond ) continue;
772  TString add = currCond;
773  if ( ic == 3 ) add = trigOut->GetHistoName(-1,-1,-1,currCond.Atoi(),-1,-1);
774  else if ( ic == 4 ) add = trigOut->GetHistoName(-1,-1,-1,-1,currCond.Atoi(),-1);
775  else if ( ic == 5 ) add = trigOut->GetHistoName(-1,-1,-1,-1,-1,currCond.Atoi());
776  title += Form("_%s",add.Data());
777  }
778  title.Remove(TString::kLeading,'_');
779  condTitle.AddAt(new TObjString(title),icond);
780  }
781  }
782 
783  // First get the needed graphs
784  Int_t nDE = 0;
785  TObjArray effGraphs[8];
786  for ( Int_t iplane=0; iplane<8; iplane++ ) {
787  effGraphs[iplane].SetOwner();
788  }
789  for ( Int_t icond=0; icond<nConditions; icond++ ) {
790  TObjArray* condition = static_cast<TObjArray*>(fConditions->UncheckedAt(icond));
791  for ( Int_t icount=0; icount<2; icount++ ) {
792  for ( Int_t ich=0; ich<4; ich++ ) {
793  Int_t iplane = 4*icount+ich;
794  TH1* histoNum = GetSum(trigOut,condition,itype,icount,ich);
795  TH1* histoDen = GetSum(trigOut,condition,itype,AliTrigChEffOutput::kAllTracks,ich);
796  TGraphAsymmErrors* gr = new TGraphAsymmErrors(histoNum,histoDen,"e0");
797  nDE = gr->GetN();
798  effGraphs[iplane].Add(gr);
799  delete histoNum;
800  delete histoDen;
801  }
802  }
803  }
804 
805  // Draw average dispersion per plane
806  TString canName = Form("EffSyst_%s",trigOut->GetName());
807  Int_t pos = 25*(imerged+1);
808  TCanvas* can = new TCanvas(canName.Data(),canName.Data(),pos,pos,1200,800);
809  can->Divide(4,2,0,0);
810 
811  TObjArray* refCond = static_cast<TObjArray*>(fConditions->UncheckedAt(0));
812  for ( Int_t icount=0; icount<2; icount++ ) {
813  for ( Int_t ich=0; ich<4; ich++ ) {
814  Int_t iplane = 4*icount+ich;
815  can->cd(iplane+1);
816  gPad->SetTicks(1,1);
817  gPad->SetLogy();
818  TLegend* leg = new TLegend(0.15,0.7,0.9,0.9);
819  leg->SetHeader(trigOut->GetHistoName(-1,icount,ich,-1,-1,-1));
820  TH1* sumHisto = 0x0;
821  for ( Int_t icond=1; icond<nConditions; icond++ ) {
822  TH1* histo = new TH1D(Form("syst_%s_%s_plane%i_ch%i",trigOut->GetName(),condTitle[icond]->GetName(),icount,11+ich),"",200,-0.1,0.1);
823  histo->GetXaxis()->SetTitle("Eff.-(ref.Eff.)");
824 // histo->GetXaxis()->SetTitle("1/#sigma^{2}");
825 
826  TGraphAsymmErrors* gr = static_cast<TGraphAsymmErrors*>(effGraphs[iplane].UncheckedAt(icond));
827  TGraphAsymmErrors* grRef = static_cast<TGraphAsymmErrors*>(effGraphs[iplane].UncheckedAt(0));
828  for ( Int_t ipt=0; ipt<gr->GetN(); ipt++ ) {
829  gr->GetPoint(ipt,xpt,ypt);
830  Double_t err = GetError(gr->GetErrorYlow(ipt),gr->GetErrorYhigh(ipt));
831  Double_t invErr2 = ( err > 0. ) ? 1./(err*err) : 0.;
832  grRef->GetPoint(ipt,xref,yref);
833 
834  Double_t diff = ypt-yref;
835  histo->Fill(diff,invErr2);
836  }
837 
838  if ( ! sumHisto ) {
839  sumHisto = static_cast<TH1*>(histo->Clone(Form("syst_%s_plane%i_ch%i",trigOut->GetName(),icount,11+ich)));
840  sumHisto->SetLineColor(1);
841  sumHisto->Draw();
842  leg->AddEntry(sumHisto,"All systematics","l");
843  }
844  else sumHisto->Add(histo);
845  Int_t icolor = ( icond < ncolors ) ? colors[icond] : 20+icond;
846  histo->SetLineColor(icolor);
847  histo->Draw("same");
848  leg->AddEntry(histo,condTitle[icond]->GetName(),"l");
849  } // loop on conditions
850  leg->Draw();
851  } // loop on chambers
852  } // loop on counts
853 
854 
855  canName = Form("TriggerEff_3outOf4_syst_%s",trigOut->GetName());
856  pos += 50;
857  TCanvas* canSyst = new TCanvas(canName.Data(),canName.Data(),pos,pos,600,600);
858  canSyst->SetLogy();
859  TLegend* leg = new TLegend(0.15,0.7,0.9,0.4);
860 // leg->SetHeader(trigOut->GetHistoName(-1,icount,ich,-1,-1,-1));
861  TH1* sumHisto = 0x0;
862  TH1* histo[nConditions];
863  for ( Int_t icond=0; icond<nConditions; icond++ ) {
864  histo[icond] = new TH1D(Form("TriggerEff_syst_%s_%s",condTitle[icond]->GetName(),trigOut->GetName()),"Dispersion of trigger probability (3/4)",200,-0.1,0.1);
865  histo[icond]->GetXaxis()->SetTitle("Trig. prob. - (ref. trig. prob)");
866  }
867 
868  for ( Int_t ipt=0; ipt<nDE; ipt++ ) {
869  Double_t refTrigProb = 0.; // refTrigProbErr = 0.;
870  for ( Int_t icond=0; icond<nConditions; icond++ ) {
871  Double_t trigProb = 1., trigProbErr2 = 0.;
872  for ( Int_t icount=0; icount<2; icount++ ) {
873  for ( Int_t ich=0; ich<4; ich++ ) {
874  Int_t iplane = 4*icount+ich;
875  TGraphAsymmErrors* gr = static_cast<TGraphAsymmErrors*>(effGraphs[iplane].UncheckedAt(icond));
876  gr->GetPoint(ipt,xpt,ypt);
877  eff[ich] = ypt;
878  effErr[ich] = GetError(gr->GetErrorYlow(ipt),gr->GetErrorYhigh(ipt));
879  } // loop on chambers
880  Double_t effErr34 = 0.;
881  Double_t eff34 = GetThreeOfFour(eff,effErr,effErr34);
882  trigProb *= eff34;
883  trigProbErr2 += effErr34*effErr34;
884  } // loop on counts
885 
886  if ( icond == 0 ) {
887  refTrigProb = trigProb;
888 // refTrigProbErr = trigProbErr;
889  }
890  else {
891  Double_t invErr2 = ( trigProbErr2>0. ) ? 1./trigProbErr2 : 0.;
892  histo[icond]->Fill(trigProb-refTrigProb,invErr2);
893  }
894  } // loop on conditions
895  } // loop on points
896 
897  for ( Int_t icond=0; icond<nConditions; icond++ ) {
898  TString title = ( icond == 0 ) ? "All systematics" : condTitle[icond]->GetName();
899  Int_t icolor = ( icond < ncolors ) ? colors[icond] : 20+icond;
900  histo[icond]->SetLineColor(icolor);
901  histo[icond]->Draw((icond == 0)?"":"same");
902  leg->AddEntry(histo[icond],title.Data(),"l");
903  if ( icond>0 ) histo[0]->Add(histo[icond]);
904  }
905  leg->Draw();
906  } // loop on merged output
907  return kTRUE;
908 }
909 
910 //________________________________________________________________________
911 Bool_t AliMTRChEffAnalysis::ExecCommand ( TString command, Bool_t prompt ) const
912 {
914  TString decision = "y";
915 
916  if ( gROOT->IsBatch() ) prompt = kFALSE; // To run with crontab
917 
918  if ( prompt ) {
919  cout << command.Data() << " ? [y/n]" << endl;
920  cin >> decision;
921  }
922 
923  decision.ToLower();
924  if ( decision == "y" ) {
925  cout << "Executing: " << command.Data() << endl;
926  gSystem->Exec(command.Data());
927  return kTRUE;
928  }
929 
930  return kFALSE;
931 }
932 
933 //________________________________________________________________________
934 Double_t AliMTRChEffAnalysis::FitRangesFunc ( Double_t* x, Double_t* par )
935 {
942 
943  Double_t xx = x[0];
944  Double_t val = par[1];
945  Int_t nChanges = par[0];
946  for ( Int_t iknot=0; iknot<nChanges; iknot++ ) {
947  if ( xx > par[2*(iknot+1)] ) val = par[2*(iknot+1)+1];
948  }
949  return val;
950 }
951 
952 //________________________________________________________________________
953 Double_t AliMTRChEffAnalysis::GetAverageStat ( Int_t firstRun, Int_t lastRun, Int_t itype,Bool_t excludePeriphericBoard ) const
954 {
955  TH1* statHisto = 0x0;
956  TObjArray* condition = static_cast<TObjArray*>(fConditions->At(0));
957 
958  TIter next(fOutputs);
959  TList* effHistoList = 0x0;
960  while ( (effHistoList = static_cast<TList*>(next()) ) ) {
961  UInt_t run = effHistoList->GetUniqueID();
962  if ( run < firstRun || run > lastRun ) continue;
963  TH1* histo = GetHisto(effHistoList,itype,AliTrigChEffOutput::kAllTracks,0);
964 // if ( ! histo ) continue;
965  if ( statHisto ) statHisto->Add(histo);
966  else statHisto = static_cast<TH1*>(histo->Clone("tmpStatHisto"));
967 // delete histo;
968  }
969  if ( ! statHisto ) return 0.;
970 
971  Double_t statPerDE = 0.;
972  Double_t nDe = 0.;
973  if ( itype == AliTrigChEffOutput::kHboardEff && excludePeriphericBoard ) {
974  Int_t excludeBoardsHalf[] = {1, 17, 39, 61, 77, 93,109,
975  16, 38, 60, 76, 92, 108, 117,
976  110, 111, 112, 113, 114, 115, 116};
977  Int_t nExcludedHalf = sizeof(excludeBoardsHalf)/sizeof(excludeBoardsHalf[0]);
978  for ( Int_t ibin=1; ibin<=statHisto->GetNbinsX(); ibin++ ) {
979  Bool_t skip = kFALSE;
980  for ( Int_t iexcl=0; iexcl<nExcludedHalf; iexcl++ ) {
981  if ( ibin == excludeBoardsHalf[iexcl] || ibin == excludeBoardsHalf[iexcl]+117 ) {
982  skip = kTRUE;
983  break;
984  }
985  }
986  if ( skip ) continue;
987  statPerDE += statHisto->GetBinContent(ibin);
988  nDe += 1.;
989  }
990  }
991  else {
992  statPerDE = statHisto->Integral();
993  nDe = (Double_t)statHisto->GetNbinsX();
994  }
995  statPerDE = nDe > 0. ? statPerDE/nDe : -1.;
996 
997  delete statHisto;
998  return statPerDE;
999 }
1000 
1001 //________________________________________________________________________
1002 TList* AliMTRChEffAnalysis::GetEffHistoList ( AliTrigChEffOutput* trigOut, TObjArray* condition ) const
1003 {
1005  Int_t itrackSel = static_cast<TObjString*>(condition->At(3))->String().Atoi();
1006  Int_t imatch = static_cast<TObjString*>(condition->At(4))->String().Atoi();
1007  Int_t imethod = static_cast<TObjString*>(condition->At(5))->String().Atoi();
1008 
1009  return trigOut->GetEffHistoList(condition->At(0)->GetName(),condition->At(1)->GetName(),condition->At(2)->GetName(),itrackSel,imatch,imethod);
1010 }
1011 
1012 //________________________________________________________________________
1013 Double_t AliMTRChEffAnalysis::GetError ( Double_t errLow, Double_t errHigh ) const
1014 {
1016  return TMath::Max(errLow,errHigh);
1017 }
1018 
1019 //________________________________________________________________________
1020 TH1* AliMTRChEffAnalysis::GetHisto ( TList* effHistoList, Int_t itype, Int_t icount, Int_t ichamber ) const
1021 {
1023  Int_t ihisto = ( itype == AliTrigChEffOutput::kHchamberEff ) ? icount : AliTrigChEffOutput::kNcounts + 4*AliTrigChEffOutput::kNcounts*(itype-1) + 4*icount + ichamber;
1024  return static_cast<TH1*>(effHistoList->At(ihisto));
1025 }
1026 
1027 //________________________________________________________________________
1028 TArrayI AliMTRChEffAnalysis::GetHomogeneusRanges ( Double_t chi2Cut, Int_t maxNRanges, Double_t minEffVariation, TArrayI* forcedChanges, Double_t minEff, Double_t maxEff )
1029 {
1031 
1032  Int_t nRuns = fOutputs->GetEntriesFast();
1033 
1034  TH1F* hRunChangeCount = new TH1F("runChangeCount","Number of RPCs changing efficiency per run",nRuns,-0.5,-0.5+(Double_t)nRuns);
1035  hRunChangeCount->SetXTitle("Run num.");
1036  hRunChangeCount->SetYTitle("Num. of RPCs with change in eff.");
1037  for ( Int_t irun=0; irun<nRuns; irun++ ) {
1038  hRunChangeCount->GetXaxis()->SetBinLabel(irun+1,Form("%i",GetRunNumber(irun)));
1039  }
1040 
1041  for ( Int_t ich=0; ich<4; ich++ ) {
1042  TString canName = Form("testRanges_ch%i",11+ich);
1043  TCanvas* can = new TCanvas(canName.Data(),canName.Data(),10*ich,10*ich,1200,800);
1044  can->Divide(6,3,0,0);
1045  for ( Int_t irpc=0; irpc<18; irpc++ ) {
1046  Int_t icount = AliTrigChEffOutput::kBothPlanesEff;
1047  can->cd(irpc+1);
1048  gPad->SetTicks(1,1);
1049 // for ( Int_t icount=0; icount<2; icount++ ) {
1050  TGraphAsymmErrors* trendGraph = GetTrendEff(AliTrigChEffOutput::kHslatEff,icount,ich,irpc);
1051  TArrayI range = GetHomogeneusRanges(trendGraph,chi2Cut,maxNRanges,minEffVariation,forcedChanges, kTRUE);
1052  trendGraph->GetYaxis()->SetRangeUser(minEff,maxEff);
1053  trendGraph->Draw("ap");
1054  for ( Int_t ichange=0; ichange<range.GetSize(); ichange++ ) {
1055  // Store only the run when the change applies
1056  if ( ichange%2 == 1 ) continue;
1057  Int_t runIdx = range[ichange];
1058  if ( ichange != 0 ) {
1059  TLine* line = new TLine(runIdx,minEff,runIdx,maxEff);
1060  line->SetLineStyle(2);
1061  line->Draw("same");
1062  TLatex text;
1063  text.DrawLatex((Double_t)(runIdx-3),maxEff-0.1*(maxEff-minEff)*(Double_t)(ichange/2),Form("%i",GetRunNumber(runIdx)));
1064  }
1065  hRunChangeCount->Fill(runIdx);
1066  if ( hRunChangeCount->GetBinContent(runIdx+1) == 1 ) {
1067  AliInfo(Form("Efficiency change in %i triggered by ch %i RPC %i",GetRunNumber(runIdx),11+ich,irpc));
1068  }
1069  }
1070 // }
1071  }
1072  }
1073 
1074  // Clusterize contiguous runs
1075  TArrayI runChangeClust(nRuns);
1076  Double_t sumWgtRun = 0.;
1077  Double_t sumWgt = 0;
1078  for ( Int_t irun=0; irun<=nRuns; irun++ ) {
1079  if ( irun == nRuns || hRunChangeCount->GetBinContent(irun+1) == 0 ) {
1080  if ( sumWgt > 0. ) {
1081  Int_t averageRun = TMath::Nint(sumWgtRun / sumWgt);
1082  AliDebug(2,Form("Average run: %i => %i\n",averageRun,GetRunNumber(averageRun)));
1083  runChangeClust[averageRun]++;
1084  sumWgtRun = 0.;
1085  sumWgt = 0.;
1086  }
1087  }
1088  if ( irun == nRuns ) break;
1089 
1090  AliDebug(2,Form("irun %i => %i: wgt %g",irun,GetRunNumber(irun),hRunChangeCount->GetBinContent(irun+1)));
1091 
1092 // Double_t wgt = (Double_t)runChangeCount[irun];
1093  Double_t wgt = hRunChangeCount->GetBinContent(irun+1);
1094  if ( forcedChanges ) {
1095  for ( Int_t ichange=0; ichange<forcedChanges->GetSize(); ichange++ ) {
1096  if ( GetRunNumber(irun) == forcedChanges->At(ichange) ) wgt *= 10.;
1097  }
1098  }
1099  sumWgtRun += wgt*(Double_t)irun;
1100  sumWgt += wgt;
1101  }
1102 
1103  TCanvas* summaryCan = new TCanvas("effChangeSummary","effChangeSummary",50,50,600,600);
1104  summaryCan->SetLogy();
1105  hRunChangeCount->GetXaxis()->LabelsOption("v");
1106  hRunChangeCount->Draw();
1107 
1108  Int_t ientry = 0;
1109  TArrayI runRanges(nRuns);
1110  for ( Int_t irun=0; irun<nRuns; irun++ ) {
1111  if ( runChangeClust[irun] > 0 ) {
1112  if ( irun > 0 ) runRanges[ientry++] = GetRunNumber(irun-1);
1113  runRanges[ientry++] = GetRunNumber(irun);
1114  }
1115  }
1116  runRanges[ientry++] = GetRunNumber(nRuns-1);
1117  runRanges.Set(ientry);
1118  return runRanges;
1119 }
1120 
1121 //________________________________________________________________________
1122 TArrayI AliMTRChEffAnalysis::GetHomogeneusRanges ( TGraphAsymmErrors* trendGraph, Double_t chi2Cut, Int_t maxNRanges, Double_t minEffVariation, TArrayI* forcedChanges, Bool_t returnIndex )
1123 {
1125 
1126  TArrayI runRanges;
1127  TF1* func = 0x0;
1128 // TString canName = "fitTestCan";
1129  TArrayD forcedChangesBin;
1130  Int_t nForced = 0;
1131  if ( forcedChanges ) {
1132  forcedChangesBin.Set(forcedChanges->GetSize());
1133  for ( Int_t ichange=0; ichange<forcedChanges->GetSize(); ichange++ ) {
1134  Int_t idx = GetIndexFromRun(forcedChanges->At(ichange));
1135  if ( idx >= 0 ) forcedChangesBin[nForced++] = (Double_t)idx;
1136  else AliWarning(Form("Cannot find run %i\n",forcedChanges->At(ichange)));
1137  }
1138  }
1139 
1140  for ( Int_t istep=0; istep<maxNRanges; istep++ ) {
1141  Int_t nPars = 2*(istep+1);
1142  Double_t xMin = trendGraph->GetXaxis()->GetXmin();
1143  Double_t xMax = trendGraph->GetXaxis()->GetXmax();
1144  func = new TF1("rangeFunc",this,&AliMTRChEffAnalysis::FitRangesFunc,xMin,xMax,nPars,"AliMTRChEffAnalysis","FitRanges");
1145  func->FixParameter(0,istep);
1146  for ( Int_t ipar=1; ipar<nPars; ipar++ ) {
1147  Double_t val = ( ipar%2 == 1 ) ? 0.95 : (xMax-xMin) * (Double_t)(ipar/2)/((Double_t)(istep+1));
1148  func->SetParameter(ipar,val);
1149  if ( forcedChanges ) {
1150  Int_t currChange = ipar/2 - 1;
1151  if ( ipar%2==0 && currChange < nForced ) func->FixParameter(ipar,forcedChangesBin[currChange]);
1152  }
1153  }
1154 // trendGraph->Draw("ap");
1155  trendGraph->Fit(func,"NQ0");
1156 // func->DrawCopy("same");
1157  Double_t normChi2 = func->GetChisquare() / ((Double_t)func->GetNDF());
1158 // printf("normChi2 %g\n",normChi2);
1159  if ( normChi2 < chi2Cut ) break;
1160  delete func;
1161  func = 0x0;
1162  }
1163 
1164  if ( func ) {
1165  trendGraph->GetListOfFunctions()->Add(func->Clone());
1166  Int_t nSteps = func->GetParameter(0);
1167  runRanges.Set(2*(nSteps+1));
1168  Int_t irun = 0;
1169  runRanges[irun++] = returnIndex ? 0 : GetRunNumber(0);
1170  for ( Int_t istep=0; istep<nSteps; istep++ ) {
1171  Int_t ipar = 2*(istep+1);
1172  Double_t deltaEff = TMath::Abs(func->GetParameter(ipar-1)-func->GetParameter(ipar+1));
1173  if ( deltaEff < minEffVariation ) {
1174  AliWarning(Form("Efficiency variation for %s is %g => consider uniform",trendGraph->GetName(),deltaEff));
1175  continue;
1176  }
1177  Int_t runChangeIdx = TMath::Nint(func->GetParameter(ipar));
1178  AliDebug(1,Form("Change run: %s => %g => %i %i",trendGraph->GetName(),func->GetParameter(ipar),runChangeIdx,GetRunNumber(runChangeIdx)));
1179  runRanges[irun++] = returnIndex ? runChangeIdx-1 : GetRunNumber(runChangeIdx-1);
1180  runRanges[irun++] = returnIndex ? runChangeIdx : GetRunNumber(runChangeIdx);
1181  }
1182  Int_t lastPt = trendGraph->GetN()-1;
1183  runRanges[irun++] = returnIndex ? lastPt : GetRunNumber(trendGraph->GetN()-1);
1184  runRanges.Set(irun);
1185 // for ( Int_t irange=0; irange<runRanges.GetSize()/2; irange++ ) {
1186 // printf("%i - %i\n",runRanges[2*irange],runRanges[2*irange+1]);
1187 // }
1188  }
1189  return runRanges;
1190 }
1191 
1192 //________________________________________________________________________
1193 TString AliMTRChEffAnalysis::GetIdentifier ( AliTrigChEffOutput* trigOut, TObjArray* condition, Int_t itype, Int_t icount, Int_t ichamber ) const
1194 {
1196 // AliTrigChEffOutput* trigOut = static_cast<AliTrigChEffOutput*>(fOutputs->At(0));
1197 // if ( ! trigOut ) {
1198 // AliWarning("No output object found!");
1199 // delete arr;
1200 // return "";
1201 // }
1202  TString identifier = Form("/%s/%s/%s/",condition->At(0)->GetName(),condition->At(1)->GetName(),condition->At(2)->GetName());
1203  Int_t itrackSel = static_cast<TObjString*>(condition->At(3))->String().Atoi();
1204  Int_t imatch = static_cast<TObjString*>(condition->At(4))->String().Atoi();
1205  Int_t imethod = static_cast<TObjString*>(condition->At(5))->String().Atoi();
1206  TString objName = trigOut->GetHistoName(itype, icount, ichamber, itrackSel, imatch, imethod);
1207  identifier += objName;
1208  return identifier;
1209 }
1210 
1211 //________________________________________________________________________
1212 Int_t AliMTRChEffAnalysis::GetIndexFromRun ( UInt_t runNumber ) const
1213 {
1215  for ( Int_t ipt=0; ipt<fOutputs->GetEntriesFast(); ipt++ ) {
1216  UInt_t run = fOutputs->UncheckedAt(ipt)->GetUniqueID();
1217  if ( run == runNumber ) return ipt;
1218  }
1219  return -1;
1220 }
1221 
1222 //________________________________________________________________________
1223 TGraphAsymmErrors* AliMTRChEffAnalysis::GetOutliers ( TGraphAsymmErrors* graph, Double_t maxNsigmas ) const
1224 {
1226 // TGraphAsymmErrors* outliers = new TGraphAsymmErrors();
1227  TGraphAsymmErrors* outliers = new TGraphAsymmErrors(*graph);
1228  outliers->SetHistogram(static_cast<TH1F*>(graph->GetHistogram()->Clone(Form("%s_outliers",graph->GetHistogram()->GetName()))));
1229 // outliers->SetLineColor(graph->GetLineColor()+1);
1230  if ( graph->GetListOfFunctions()->GetEntries() == 0 ) graph->Fit("pol0","Q0");
1231  TF1* func = static_cast<TF1*>(graph->GetListOfFunctions()->At(0));
1232 
1233  Double_t xpt, ypt;
1234  Int_t nremoved = 0;
1235  for ( Int_t ipt=0; ipt<graph->GetN(); ipt++ ) {
1236  graph->GetPoint(ipt,xpt,ypt);
1237  Double_t diff = ypt - func->Eval(xpt);
1238  Double_t err = ( diff > 0. ) ? graph->GetErrorYlow(ipt) : graph->GetErrorYhigh(ipt);
1239  if ( err < 0. || TMath::Abs(diff)/err > maxNsigmas ) continue;
1240  outliers->RemovePoint(ipt-nremoved);
1241  nremoved++;
1242 // outliers->SetPoint(iopt,xpt,ypt);
1243  }
1244  return outliers;
1245 }
1246 
1247 //________________________________________________________________________
1248 Int_t AliMTRChEffAnalysis::GetRunNumber ( Int_t ipt ) const
1249 {
1251  if ( ipt < 0 && ipt >= fOutputs->GetEntriesFast() ) return -1;
1252  return fOutputs->UncheckedAt(ipt)->GetUniqueID();
1253 }
1254 
1255 //________________________________________________________________________
1256 TList* AliMTRChEffAnalysis::GetRunList ( const char* runList ) const
1257 {
1259  TList* rl = new TList;
1260  rl->SetOwner();
1261  TString sRunList = gSystem->ExpandPathName(runList);
1262  if ( gSystem->AccessPathName(sRunList) || sRunList.EndsWith(".root") ) {
1263  sRunList.ReplaceAll(","," ");
1264  if ( sRunList.IsDigit() ) {
1265  TObjArray* arr = sRunList.Tokenize(" ");
1266  for ( Int_t iarr=0; iarr<arr->GetEntries(); iarr++ ) {
1267  rl->Add(new TObjString(arr->At(iarr)->GetName()));
1268  }
1269  delete arr;
1270  }
1271  }
1272  else {
1273  ifstream inFile(sRunList.Data());
1274  TString currLine = "";
1275  while ( ! inFile.eof() ) {
1276  currLine.ReadLine(inFile);
1277  TString currRun = AliAnalysisMuonUtility::GetRunNumberAsString(currLine);
1278  if ( ! currRun.IsNull() ) rl->Add(new TObjString(currRun));
1279  }
1280  inFile.close();
1281  }
1282  rl->Sort();
1283  return rl;
1284 }
1285 
1286 //________________________________________________________________________
1287 TH1* AliMTRChEffAnalysis::GetSum ( AliTrigChEffOutput* trigOut, TObjArray* condition, Int_t itype, Int_t icount, Int_t ichamber ) const
1288 {
1290  Int_t itrackSel = static_cast<TObjString*>(condition->At(3))->String().Atoi();
1291  Int_t imatch = static_cast<TObjString*>(condition->At(4))->String().Atoi();
1292  Int_t imethod = static_cast<TObjString*>(condition->At(5))->String().Atoi();
1293  TString objName = trigOut->GetHistoName(itype, icount, ichamber, itrackSel, imatch, imethod);
1294  return static_cast<TH1*>(trigOut->GetSum(condition->At(0)->GetName(),condition->At(1)->GetName(),condition->At(2)->GetName(),objName));
1295 }
1296 
1297 //________________________________________________________________________
1298 TH1* AliMTRChEffAnalysis::GetTrend ( Int_t itype, Int_t icount, Int_t ichamber, Int_t idetelem ) const
1299 {
1301  if ( itype == AliTrigChEffOutput::kHchamberEff ) {
1302  if ( idetelem < 0 && ichamber >=0 ) idetelem = 11+ichamber;
1303  }
1304  TH1* outHisto = 0x0;
1305  TObjArray* condition = static_cast<TObjArray*>(fConditions->At(0));
1306 
1307  TIter next(fOutputs);
1308  TList* effHistoList = 0x0;
1309  Int_t ibin = 0;
1310  while ( (effHistoList = static_cast<TList*>(next()) ) ) {
1311  ibin++;
1312 // TString identifier = GetIdentifier(trigOut,condition,itype,icount,ichamber);
1313  if ( ! outHisto ) {
1314 // TString outName = identifier;
1315  TString outName = Form("histo_type%i_count%i_ch%i_",itype,icount,11+ichamber);
1316 // outName.ReplaceAll("/","_");
1317  outName += Form("%i_trend",idetelem);
1318  outHisto = new TH1D(outName.Data(),outName.Data(),fOutputs->GetEntriesFast(),0.,(Double_t)fOutputs->GetEntriesFast());
1319  outHisto->SetDirectory(0);
1320  outHisto->GetXaxis()->SetTitle("Run num.");
1321  }
1322  UInt_t run = effHistoList->GetUniqueID();
1323  outHisto->GetXaxis()->SetBinLabel(ibin,Form("%u",run));
1324  TH1* histo = GetHisto(effHistoList,itype,icount,ichamber);
1325  Int_t currBin = histo->GetXaxis()->FindBin(idetelem);
1326  outHisto->SetBinContent(ibin,histo->GetBinContent(currBin));
1327  outHisto->SetBinError(ibin,histo->GetBinError(currBin));
1328  }
1329  if ( outHisto ) outHisto->GetXaxis()->LabelsOption("v");
1330  return outHisto;
1331 }
1332 
1333 //________________________________________________________________________
1334 TGraphAsymmErrors* AliMTRChEffAnalysis::GetTrendEff ( Int_t itype, Int_t icount, Int_t ichamber, Int_t idetelem ) const
1335 {
1337  if ( icount == AliTrigChEffOutput::kAllTracks ) {
1338  AliWarning("Chose either bending plane, non-bending plane or both planes");
1339  return NULL;
1340  }
1341  TH1* histoNum = GetTrend(itype,icount,ichamber,idetelem);
1342  TH1* histoDen = GetTrend(itype,AliTrigChEffOutput::kAllTracks,ichamber,idetelem);
1343  TGraphAsymmErrors* graph = new TGraphAsymmErrors(histoNum,histoDen,"e0");
1344  histoNum->Reset();
1345  histoNum->SetStats(kFALSE);
1346  graph->SetHistogram(static_cast<TH1F*>(histoNum));
1347  graph->GetYaxis()->SetTitle("Efficiency");
1348  graph->SetMarkerSize(0.5);
1349 // for ( Int_t ibin=1; ibin<=histoNum->GetXaxis()->GetNbins(); ibin++ ) {
1350 // graph->GetXaxis()->SetBinLabel(ibin,histoNum->GetXaxis()->GetBinLabel(ibin));
1351 // }
1352 // delete histoNum;
1353  delete histoDen;
1354  return graph;
1355 }
1356 
1357 //________________________________________________________________________
1358 Double_t AliMTRChEffAnalysis::GetThreeOfFour ( TArrayD eff, TArrayD effErr, Double_t &probErr ) const
1359 {
1361  Double_t binomialEff = 0.;
1362  Double_t sumErr2 = 0.;
1363  for ( Int_t jch=-1; jch<4; jch++ ) {
1364  Double_t prodEff = 1.;
1365  Double_t prodErr2 = 0.;
1366  for ( Int_t ich=0; ich<4; ich++ ) {
1367  Double_t currEff = ( ich == jch ) ? 1.-eff[ich] : eff[ich];
1368  prodEff *= currEff;
1369  Double_t relErr = ( currEff>0. ) ? effErr[ich]/currEff : 0.;
1370  prodErr2 += relErr*relErr;
1371  }
1372  binomialEff += prodEff;
1373  sumErr2 += prodEff*prodEff*prodErr2;
1374  }
1375  probErr = TMath::Sqrt(sumErr2);
1376  return binomialEff;
1377 }
1378 
1379 //________________________________________________________________________
1381 {
1383  if ( ! fMergedOutputs || fMergedOutputs->IsEmpty() ) {
1384  AliError("You first need to merge efficiency objects with MergeOutput");
1385  return kFALSE;
1386  }
1387  return kTRUE;
1388 }
1389 
1390 //________________________________________________________________________
1391 Bool_t AliMTRChEffAnalysis::MergeOutput ( TArrayI runRanges, Double_t averageStatError, Bool_t isIndex )
1392 {
1394 
1395  if ( runRanges.GetSize()%2 == 1 ) {
1396  AliError("Run ranges expected in the form: start_period1,end_period1,start_period2,end_period2... => even number expected");
1397  return kFALSE;
1398  }
1399 
1400  TArrayI mergedRanges = MergeRangesForStat(runRanges, averageStatError);
1401 
1402  Int_t nRanges = mergedRanges.GetSize()/2;
1403 
1404 
1405  if ( fMergedOutputs ) fMergedOutputs->Delete();
1406  else {
1407  fMergedOutputs = new TObjArray(nRanges);
1408  fMergedOutputs->SetOwner();
1409  }
1410 
1411  TList* effHistoList = 0x0;
1412  for ( Int_t irange=0; irange<nRanges; irange++ ) {
1413  Int_t firstRun = mergedRanges[2*irange];
1414  Int_t lastRun = mergedRanges[2*irange+1];
1415  if ( isIndex ) {
1416  firstRun = GetRunNumber(firstRun);
1417  lastRun = GetRunNumber(lastRun);
1418  }
1419 
1420  TObjArray* mergedOut = 0x0;
1421  TIter next(fOutputs);
1422  TFileMerger fileMerger;
1423  while ( (effHistoList = static_cast<TList*>(next()) ) ) {
1424  UInt_t run = effHistoList->GetUniqueID();
1425  if ( run < firstRun || run > lastRun ) continue;
1426  fileMerger.AddFile(effHistoList->GetName(),kFALSE);
1427  }
1428 
1429  TString sRange = Form("%i_%i",firstRun,lastRun);
1430  TString mergedFilename = Form("mergedTrigEff_runs_%s.root",sRange.Data());
1431  fileMerger.OutputFile(mergedFilename.Data());
1432  fileMerger.Merge();
1433  AliTrigChEffOutput* trigOut = new AliTrigChEffOutput(mergedFilename);
1434  trigOut->SetName(sRange.Data());
1435  fMergedOutputs->Add(trigOut);
1436  }
1437  return kTRUE;
1438 }
1439 
1440 //________________________________________________________________________
1441 TArrayI AliMTRChEffAnalysis::MergeRangesForStat ( TArrayI runRanges, Double_t averageStatError, Bool_t excludePeriphericBoards ) const
1442 {
1443  if ( averageStatError <= 0. || averageStatError >= 1. ) return runRanges;
1444 
1445  // FIXME: statstical error for binomial depends on the value of epsilon
1446  // for the moment let's assume an average efficiency of 0.9 (underestimated)
1447  // in the future one could maybe actually calculate it
1448  // (still we're working with average values...so the precision is limited)
1449  Double_t effForStatCalc = 0.9;
1450 
1451  Double_t averageStatNeeded = effForStatCalc*(1.-effForStatCalc)/(averageStatError*averageStatError);
1452 
1453  AliInfo(Form("Average statistics needed to reach precision of %g : %g",averageStatError,averageStatNeeded));
1454 
1455  Int_t nRanges = runRanges.GetSize()/2;
1456 
1457  TArrayD averageStat(nRanges);
1458  Double_t fullStat = 0.;
1459  for ( Int_t irange=0; irange<nRanges; irange++ ) {
1460  averageStat[irange] = GetAverageStat(runRanges[2*irange],runRanges[2*irange+1],AliTrigChEffOutput::kHboardEff,excludePeriphericBoards);
1461  fullStat += averageStat[irange];
1462  }
1463 
1464  TArrayI mergedRanges(runRanges.GetSize());
1465  Int_t imerged = 0;
1466  mergedRanges[imerged++] = runRanges[0];
1467  Double_t mergedAverageStat = 0., remainingStat = fullStat;
1468  for ( Int_t irange=0; irange<nRanges; irange++ ) {
1469  Int_t istart = 2*irange;
1470  Int_t iend = istart+1;
1471  mergedAverageStat += averageStat[irange];
1472  remainingStat -= averageStat[irange];
1473 
1474  AliInfo(Form("%i - %i => stat %g",runRanges[2*irange],runRanges[2*irange+1],averageStat[irange]));
1475 
1476  if ( ( mergedAverageStat >= averageStatNeeded && remainingStat >= averageStatNeeded ) || iend == runRanges.GetSize()-1 ) {
1477  mergedRanges[imerged++] = runRanges[iend];
1478  AliInfo(Form(" merged range %i - %i => stat %g",mergedRanges[imerged-2],mergedRanges[imerged-1],mergedAverageStat));
1479  mergedAverageStat = 0.;
1480  Int_t nextRun = iend+1;
1481  if ( nextRun < runRanges.GetSize() ) mergedRanges[imerged++] = runRanges[nextRun];
1482  }
1483  }
1484  mergedRanges.Set(imerged);
1485  return mergedRanges;
1486 }
1487 
1488 //________________________________________________________________________
1489 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 )
1490 {
1492  if ( ! fConditions ) {
1493  fConditions = new TObjArray();
1494  fConditions->SetOwner();
1495  }
1496 
1497  TString sCondition = Form("%s;%s;%s;%i;%i;%i",physSel,trigClassName,centrality,itrackSel,imatch,imethod);
1498  TObjArray* foundCondition = static_cast<TObjArray*>(fConditions->FindObject(sCondition.Data()));
1499  TObjArray* basicCondition = static_cast<TObjArray*>(fConditions->At(0));
1500 
1501  TObjArray* addCondition = 0x0;
1502 
1503  if ( foundCondition ) {
1504  if ( isBasic ) {
1505  if ( foundCondition == basicCondition ) return kFALSE;
1506  else {
1507  fConditions->Remove(foundCondition);
1508  addCondition = foundCondition;
1509  }
1510  }
1511  else {
1512  AliInfo("Systematic condition already added");
1513  return kFALSE;
1514  }
1515  }
1516  else {
1517  addCondition = sCondition.Tokenize(";");
1518  addCondition->SetName(sCondition.Data());
1519  }
1520 
1521 
1522  if ( isBasic ) {
1523  if ( basicCondition ) {
1524  AliInfo(Form("Changing current eff. condition: %s\n",basicCondition->GetName()));
1525  fConditions->Remove(basicCondition);
1526  delete basicCondition;
1527  }
1528  fConditions->AddAt(addCondition,0);
1529  fConditions->Compress();
1530 
1531  // Update outputs
1532  if ( fOutputs ) {
1533  TObjArray* tmpOutputs = static_cast<TObjArray*>(fOutputs->Clone());
1534  fOutputs->Delete();
1535  TIter next(tmpOutputs);
1536  TList* effHistiList = 0x0;
1537  while ( (effHistiList = static_cast<TList*>(next())) ) {
1538  AddToList(effHistiList->GetName(), fOutputs->GetName());
1539  }
1540  delete tmpOutputs;
1541  }
1542  }
1543  else fConditions->Add(addCondition);
1544 
1545  return kTRUE;
1546 }
1547 
1548 //________________________________________________________________________
1550 {
1553 }
1554 
1555 
1556 //________________________________________________________________________
1557 Bool_t AliMTRChEffAnalysis::SetEffConditions ( const char* physSel, const char* trigClassName, const char* centrality, Int_t itrackSel, Int_t imatch, Int_t imethod )
1558 {
1560  return SetCondition(physSel, trigClassName, centrality, itrackSel, imatch, imethod, kTRUE);
1561 }
1562 
1563 //________________________________________________________________________
1564 Bool_t AliMTRChEffAnalysis::SetOutList ( const char *localFileList, const char *outputName )
1565 {
1567 
1569 
1570  TString filename(localFileList);
1571  gSystem->ExpandPathName(filename);
1572  if ( gSystem->AccessPathName(filename.Data()) ) {
1573  AliWarning(Form("Cannot find %s",filename.Data()));
1574  return kFALSE;
1575  }
1576  if ( filename.EndsWith(".root") ) return AddToList(filename.Data(),outputName);
1577 
1578  Bool_t isOk = kTRUE;
1579  ifstream inFile(filename.Data());
1580  TString currLine = "";
1581  while ( ! inFile.eof() ) {
1582  currLine.ReadLine(inFile);
1583  if ( currLine.IsNull() ) continue;
1584  if ( gSystem->AccessPathName(currLine.Data()) ) continue;
1585  if ( ! AddToList(currLine.Data(), outputName) ) isOk = kFALSE;
1586  }
1587  inFile.close();
1588 
1589  return isOk;
1590 }
1591 
1592 //________________________________________________________________________
1593 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 )
1594 {
1596  CopyLocally(runList,path,pattern,localFileList,outDir,directory);
1597  return SetOutList(localFileList,outputName);
1598 }
1599 
1600 //________________________________________________________________________
1601 Bool_t AliMTRChEffAnalysis::SetResultsFromWeb ( const char *runList, const char *path, const char* localFileList, const char* outDir, const char *directory, const char* outputName )
1602 {
1604  CopyLocally(runList,path,"",localFileList,outDir,directory);
1605  return SetOutList(localFileList,outputName);
1606 }
1607 
1608 //________________________________________________________________________
1609 Bool_t AliMTRChEffAnalysis::WriteMergedToOCDB ( const char* outputCDB ) const
1610 {
1612  if ( ! HasMergedResults() ) return kFALSE;
1613  TString outCDBdir(outputCDB);
1614  if ( outCDBdir.Contains("://") && ! outCDBdir.BeginsWith("local") ) {
1615  AliError("A local directory is required to store the information");
1616  return kFALSE;
1617  }
1618  outCDBdir.ReplaceAll("local://","");
1619  if ( gSystem->AccessPathName(outCDBdir.Data()) ) {
1620  if ( ! ExecCommand(Form("mkdir -p %s",outCDBdir.Data()), kTRUE) ) {
1621  AliError(Form("Failed to create directory %s",outCDBdir.Data()));
1622  return kFALSE;
1623  }
1624  }
1625  TString outCDB = outCDBdir;
1626  outCDB.Prepend("local://");
1627 
1628  AliCDBManager* mgr = AliCDBManager::Instance();
1629  if ( ! mgr->GetDefaultStorage() ) mgr->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
1630 
1631  TString trigEffCDBdir = "MUON/Calib/TriggerEfficiency";
1632 
1633  mgr->SetSpecificStorage(trigEffCDBdir.Data(),outCDB.Data());
1634 
1635  AliCDBStorage* specificStorage = mgr->GetSpecificStorage(trigEffCDBdir.Data());
1636 
1637  TObjArray* condition = static_cast<TObjArray*>(fConditions->At(0));
1638 
1639  AliTrigChEffOutput* trigOut = 0x0;
1640  TIter next(fMergedOutputs);
1641  while ( (trigOut = static_cast<AliTrigChEffOutput*>(next())) ) {
1642  TList* effList = GetEffHistoList(trigOut,condition);
1643  TString runRange = trigOut->GetName();
1644 
1645 // // Write full merged output in file
1646 // TFile* file = TFile::Open(Form("mergedTrigEff_runs_%s.root",runRange.Data()),"RECREATE");
1647 // effList->Write("triggerChamberEff",TObject::kSingleKey);
1648 // trigOut->GetOutput()->Write(trigOut->GetOutput()->GetName(),TObject::kSingleKey);
1649 // file->Close();
1650 // delete file;
1651 
1652 
1653  // Write OCDB object
1654  TObjArray* currRange = runRange.Tokenize("_");
1655  Int_t firstRun = static_cast<TObjString*>(currRange->UncheckedAt(0))->String().Atoi();
1656  Int_t lastRun = static_cast<TObjString*>(currRange->UncheckedAt(1))->String().Atoi();
1657  delete currRange;
1658 
1659  // If an object is already there, ask to remove it or keep it
1660  for ( Int_t irun=0; irun<2; irun++ ) {
1661  Int_t runnr = ( irun == 0 ) ? firstRun : lastRun;
1662  specificStorage->QueryCDB(runnr);
1663  TObjArray* allIdsForRun = specificStorage->GetQueryCDBList();
1664  TIter nextId(allIdsForRun);
1665  AliCDBId* id = 0x0;
1666  while ((id = dynamic_cast<AliCDBId*>(nextId()))) {
1667  TString path(id->GetPath());
1668  Int_t foundFirst = id->GetFirstRun();
1669  Int_t foundLast = id->GetLastRun();
1670  Int_t version = id->GetVersion();
1671  Int_t subversion = id->GetSubVersion();
1672  TString locPath = Form("%s/%s/Run%d_%d_v%d_s%d.root",outCDBdir.Data(),path.Data(),foundFirst,foundLast,version,subversion);
1673  if ( ! gSystem->AccessPathName(locPath.Data()) ) {
1674  ExecCommand(Form("rm %s",locPath.Data()), kTRUE);
1675  }
1676  }
1677  }
1678 
1679  // Save the CDB object in the specific storage
1680  AliMUONTriggerEfficiencyCells* effMap = new AliMUONTriggerEfficiencyCells(effList);
1681  AliMUONCDB::WriteToCDB(effMap, "MUON/Calib/TriggerEfficiency", firstRun, lastRun, "Measured efficiencies");
1682  delete effMap; // CAVEAT: effMap is owner of efflist
1683  }
1684  return kTRUE;
1685 }
1686 
1687 //___________________________________________________________________________
1688 //Bool_t AliMTRChEffAnalysis::WriteMerged() const
1689 //{
1690 // /// Write merged efficiencies on file
1691 // if ( ! HasMergedResults ) return kFALSE;
1692 //
1693 // TObjArray* condition = static_cast<TObjArray*>(fConditions->At(0));
1694 //
1695 // AliTrigChEffOutput* trigOut = 0x0;
1696 // TIter next(fMergedOutputs);
1697 // while ( (trigOut = static_cast<AliTrigChEffOutput*>(next())) ) {
1698 // TFile* file = TFile::Open(Form("mergedTrigEff_runs_%s.root",trigOut->GetName()),"RECREATE");
1699 // TList* effList = GetEffHistoList(trigOut,condition);
1700 // effList->Write("triggerChamberEff",TObject::kSingleKey);
1701 // trigOut->GetOutput()->Write(trigOut->GetOutput()->GetName(),TObject::kSingleKey);
1702 // file->Close();
1703 // delete file;
1704 // delete effList;
1705 // }
1706 // return kTRUE;
1707 //}
void CompareEfficiencies(const char *sources, const char *titles, const char *opt) const
TArrayI GetHomogeneusRanges(Double_t chi2Cut=3, Int_t maxNRanges=4, Double_t minEffVariation=0.005, TArrayI *forcedChanges=0x0, Double_t minEff=0.85, Double_t maxEff=1.01)
Counts per cathode histogram index.
Int_t GetIndexFromRun(UInt_t runNumber) const
ClassImp(AliAnalysisTaskTriggerRates) AliAnalysisTaskTriggerRates
TList * GetEffHistoList(TString physSel, TString trigClassNames, TString centrality, Int_t itrackSel, Int_t imatch, Int_t imethod)
void CompareMergedEfficiencies(const char *opt) const
void CopyDir(TDirectory *source) const
Double_t GetError(Double_t errLow, Double_t errHigh) const
Bool_t DrawSystematicEnvelope(Bool_t perRPC=kFALSE, Double_t miny=-0.03, Double_t maxy=0.03) const
const char * title
Definition: MakeQAPdf.C:26
tracks used for calculation
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
TArrayI MergeRangesForStat(TArrayI runRanges, Double_t averageStatError, Bool_t excludePeriphericBoards=kTRUE) const
Counts per slat histogram index.
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
TList * GetEffHistoList(AliTrigChEffOutput *trigOut, TObjArray *condition) const
Number of count type.
Bool_t AddToList(const char *filename, const char *outputName)
TObjArray * fMergedOutputs
!<! List of conditions for trigger efficiency
Output for Trig chamber effieincy.
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.
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)
TString GetIdentifier(AliTrigChEffOutput *trigOut, TObjArray *condition, Int_t itype, Int_t icount, Int_t ichamber) 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)
TH1 * GetHisto(TList *effHistoList, Int_t itype, Int_t icount, Int_t ichamber) const
Bool_t SetCondition(const char *physSel, const char *trigClassName, const char *centrality, Int_t itrackSel, Int_t imatch, Int_t imethod, Bool_t isBasic)
Bool_t WriteMergedToOCDB(const char *outputCDB="CDB") const
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
Double_t FitRangesFunc(Double_t *x, Double_t *par)
Counts per board histogram index.
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 outputs
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_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 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)
TH1 * GetSum(AliTrigChEffOutput *trigOut, TObjArray *condition, Int_t itype, Int_t icount, Int_t ichamber) const
TH1 * GetTrend(Int_t itype, Int_t icount, Int_t ichamber, Int_t idetelem) const