2 #if !defined(__CINT__) || defined(__MAKECINT__)
7 #include "TGraphAsymmErrors.h"
15 #include "TObjArray.h"
17 #include "TObjString.h"
23 #include "TGridResult.h"
25 #include "AliCDBManager.h"
26 #include "AliCDBEntry.h"
27 #include "AliCDBPath.h"
28 #include "AliCDBStorage.h"
29 #include "AliMUONTriggerEfficiencyCells.h"
30 #include "AliMUONTriggerChamberEfficiency.h"
31 #include "AliMUONTriggerUtilities.h"
32 #include "AliMUONDigitMaker.h"
33 #include "AliMUONVDigit.h"
34 #include "AliMUONDigitStoreV2R.h"
35 #include "AliMUONCalibrationData.h"
36 #include "AliAnalysisTriggerScalers.h"
37 #include "AliCounterCollection.h"
38 #include "AliTriggerConfiguration.h"
42 const Double_t kZero = 1.e-7; // Avoid problems when comparing to 0.
44 //_____________________________________________________________________________
48 gStyle->SetCanvasColor(10);
49 gStyle->SetFrameFillColor(10);
50 gStyle->SetStatColor(10);
51 gStyle->SetFillColor(10);
52 gStyle->SetTitleFillColor(10);
54 gStyle->SetTitleXSize(0.03);
55 gStyle->SetTitleXOffset(1.1);
56 gStyle->SetTitleYSize(0.03);
57 gStyle->SetTitleYOffset(1.9);
59 gStyle->SetMarkerSize(0.7);
60 gStyle->SetHistLineWidth(2);
62 gStyle->SetPadLeftMargin(0.12);
63 gStyle->SetPadRightMargin(0.04);
64 gStyle->SetPadBottomMargin(0.08);
65 gStyle->SetPadTopMargin(0.08);
70 //_____________________________________________________________________________
71 Bool_t IsRunNum ( TString stringToken )
73 return ( stringToken.IsDigit() && stringToken.Length()>=6 && stringToken.Length()<=9 );
77 //_____________________________________________________________________________
78 void SetRunAxisRange ( TAxis* axis )
81 for ( Int_t ibin=1; ibin<=axis->GetNbins(); ibin++ ) {
82 TString binLabel = axis->GetBinLabel(ibin);
83 if ( ! binLabel.IsNull()) continue;
84 axis->SetRange(1, ibin-1);
89 //_____________________________________________________________________________
90 Int_t GetRunNumber(TString filePath)
92 /// Get run number from file path
93 TObjArray* array = filePath.Tokenize("/");
95 TString auxString = "";
97 for ( Int_t ientry=0; ientry<array->GetEntries(); ientry++ ) {
98 auxString = array->At(ientry)->GetName();
99 if ( IsRunNum(auxString) ) {
100 runNum = auxString.Atoi();
107 array = auxString.Tokenize("_");
109 auxString = array->Last()->GetName();
110 auxString.ReplaceAll(".root","");
111 if ( IsRunNum(auxString) ) runNum = auxString.Atoi();
118 //_____________________________________________________________________________
119 Bool_t ChangeFilenames ( TObjArray &fileNameArray )
121 /// Use custom output
122 /// We used to perform the QA on the MTR chamber efficiency
123 /// but since it is obtained form tracks matching with the tracker
124 /// it is not that good for QA since we are dependent on the tracker status.
125 /// In recent versions, the task also calculates the efficiency from all trigger tracks
126 /// (including ghosts). Analyse this output instead.
127 TString newBaseName = "trigChEff_ANY_Apt_allTrig.root";
128 for ( Int_t ifile=0; ifile<fileNameArray.GetEntries(); ifile++ ) {
129 TObjString* currObjString = static_cast<TObjString*>(fileNameArray.At(ifile));
130 TString currFile = currObjString->GetString();
131 TString baseName = gSystem->BaseName(currFile.Data());
132 // In the old scripts, the run number is in the QA filename
133 Int_t runNum = GetRunNumber(baseName);
134 TString newFilename = "";
136 // New central script: the re-created trigger output is in the same directory
137 newFilename = currFile;
138 newFilename.ReplaceAll(baseName.Data(),newBaseName.Data());
141 // Old script. The re-creaated trigger output is in terminateRuns
142 TString dirName = gSystem->DirName(currFile.Data());
143 newFilename = Form("%s/terminateRuns/%i/%s",dirName.Data(),runNum,newBaseName.Data());
145 if ( gSystem->AccessPathName(newFilename.Data()) ) {
146 printf("New output not found. Use the standard efficiency instead\n");
149 else printf("Using re-built output in %s\n",newBaseName.Data());
150 currObjString->SetString(newFilename);
155 //_____________________________________________________________________________
156 Double_t* GetProdErr(Double_t* effErr, Int_t exclude, Int_t nFactors = kNch)
160 Double_t relErr = 0., relProdErrSquare = 0.;
161 for ( Int_t iprod=0; iprod<nFactors; iprod++ ) {
162 if ( iprod == exclude ) continue;
163 prod *= effErr[iprod];
164 relErr = ( effErr[iprod] > kZero ) ? effErr[iprod+nFactors]/effErr[iprod] : 0.;
165 relProdErrSquare += relErr*relErr;
166 //printf("%f +- %f ", effErr[iprod], effErr[iprod+nFactors]); // alBER TO CUT
168 Double_t* prodErr = new Double_t[2];
170 prodErr[1] = prod*TMath::Sqrt(relProdErrSquare);
171 //printf("-> %f %f\n", prodErr[0], prodErr[1]); // REMEMBER TO CUT
176 //_____________________________________________________________________________
177 Double_t* GetConditionalEffErr(Double_t* effErr1, Double_t* effErr2, Double_t* effErrBoth, Int_t exclude = -1)
179 /// Error on conditional efficiency
180 Double_t* effErr = new Double_t[2*kNch];
181 for ( Int_t ich=0; ich<kNch; ich++ ) {
182 if ( ich == exclude ) {
183 effErr[ich] = ( effErr1[ich] < 1. ) ? ( effErr2[ich] - effErrBoth[ich] ) / ( 1. - effErr1[ich] ) : 0.;
184 effErr[ich+kNch] = 0;
185 if ( effErr1[ich] < 1. ) {
186 Double_t err2 = effErr2[ich+kNch] / ( 1. - effErr1[ich] );
187 Double_t errBoth = effErrBoth[ich+kNch] / ( 1. - effErr1[ich] );
188 Double_t err1 = effErr1[ich+kNch] * effErr[ich] / ( 1. - effErr1[ich] );
189 effErr[ich+kNch] = TMath::Sqrt(err2*err2 + errBoth*errBoth + err1*err1);
193 effErr[ich] = ( effErr1[ich] > kZero ) ? effErrBoth[ich]/effErr1[ich] : 0.;
194 Double_t relErr1 = ( effErr1[ich] > kZero ) ? effErr1[ich+kNch]/effErr1[ich] : 0.;
195 Double_t relErrBoth = ( effErrBoth[ich] > kZero ) ? effErrBoth[ich+kNch]/effErrBoth[ich] : 0.;
196 effErr[ich+kNch] = effErr[ich] * TMath::Sqrt(relErr1*relErr1 + relErrBoth*relErrBoth);
198 //printf("%f %f %f -> %f\n", effErr1[ich], effErr2[ich], effErrBoth[ich], effErr[ich]); // REMEMBER TO CUT
199 } // loop on chambers
204 //_____________________________________________________________________________
205 Double_t* GetBinomial(Double_t* effErr1, Double_t* effErr2 = 0x0, Double_t* effErrBoth = 0x0)
209 Double_t defaultEffErr[2] = {1.,0.};
210 Double_t* auxBinomial = 0x0;
211 Double_t* currEffErr44 = 0x0;
212 Double_t* effErrBinomial = new Double_t[2];
213 effErrBinomial[0] = 0.;
214 effErrBinomial[1] = 0.;
216 for ( Int_t ich = -1; ich<kNch; ich++ ) {
217 Double_t* currEffErr = GetProdErr(effErr1, ich);
219 currEffErr[0] = currEffErr[0] - currEffErr44[0];
220 currEffErr[1] = TMath::Sqrt(currEffErr[1]*currEffErr[1] + currEffErr44[1]*currEffErr44[1]);
223 Double_t* auxEffErr = GetConditionalEffErr(effErr1, effErr2, effErrBoth, ich);
224 auxBinomial = GetBinomial(auxEffErr);
227 for ( Int_t ival=0; ival<2; ival++ ) {
228 effProd[2*ival] = currEffErr[ival];
229 effProd[2*ival+1] = ( effErr2 ) ? auxBinomial[ival] : defaultEffErr[ival];
231 if ( ich < 0 ) currEffErr44 = currEffErr;
232 else delete currEffErr;
235 Double_t* effErr = GetProdErr(effProd, -1, 2);
236 //printf("%f * %f = %f\n", effProd[0], effProd[1], effErr[0]); // REMEMBER TO CUT
237 effErrBinomial[0] += effErr[0];
238 effErrBinomial[1] += effErr[1]*effErr[1];
240 } // loop on chambers
244 effErrBinomial[1] = TMath::Sqrt(effErrBinomial[1]);
246 return effErrBinomial;
250 //_____________________________________________________________________________
251 TH1* GetHisto(TString histoName, TFile* file, TList* histoList)
256 histo = (TH1*)histoList->FindObject(histoName.Data());
258 histo = (TH1*)file->FindObjectAny(histoName.Data());
263 //_____________________________________________________________________________
264 Int_t GetEffIndex ( Int_t iel, Int_t icount, Int_t ich = -1 )
266 /// Get efficienct histogram index
267 if ( iel == 0 ) return icount;
268 return 3 + 4*3*(iel-1) + 3*ich + icount;
271 //_____________________________________________________________________________
272 TList* GetOCDBList ( )
274 /// Get list of CDB objetcs
275 TString storageType = AliCDBManager::Instance()->GetDefaultStorage()->GetType();
276 Bool_t isGrid = storageType.Contains("alien");
277 TString baseFolder = AliCDBManager::Instance()->GetDefaultStorage()->GetBaseFolder();
279 TList* outList = new TList();
281 TString dirName[3] = {"GlobalTriggerCrateConfig", "RegionalTriggerConfig", "LocalTriggerBoardMasks"};
282 for ( Int_t idir=0; idir<3; idir++ ) {
284 TGridResult *res = gGrid->Ls(Form("%s/MUON/Calib/%s", baseFolder.Data(), dirName[idir].Data()));
285 if (!res) return 0x0;
286 for ( Int_t ires=0; ires<res->GetEntries(); ires++ ) {
287 TString currFile = static_cast<TMap*>(res->At(ires))->GetValue("name")->GetName();
288 outList->Add(new TObjString(currFile));
292 TString fileListStr = gSystem->GetFromPipe(Form("ls %s/MUON/Calib/%s", baseFolder.Data(), dirName[idir].Data()));
293 TObjArray* fileList = fileListStr.Tokenize("\n");
294 for ( Int_t ires=0; ires<fileList->GetEntries(); ires++ ) {
295 TString currFile = fileList->At(ires)->GetName();
296 outList->Add(new TObjString(currFile));
304 //_____________________________________________________________________________
305 Bool_t IsOCDBChanged ( Int_t currRun, Int_t previousRun, TList* fileList )
307 /// Check if the OCDB object is changed w.r.t. the previous run
308 if ( ! fileList ) return kTRUE;
309 for ( Int_t ifile=0; ifile<fileList->GetEntries(); ifile++ ) {
310 TString filename = static_cast<TObjString*>(fileList->At(ifile))->GetString();
311 filename.ReplaceAll("Run","");
312 TObjArray* array = filename.Tokenize("_");
313 Int_t firstRun = static_cast<TObjString*>(array->At(0))->GetString().Atoi();
314 Int_t lastRun = static_cast<TObjString*>(array->At(1))->GetString().Atoi();
316 Bool_t isCurrRunInside = ( currRun >= firstRun && currRun <= lastRun );
317 Bool_t isPreviousRunInside = ( previousRun >= firstRun && previousRun <= lastRun );
318 if ( isCurrRunInside != isPreviousRunInside ) return kTRUE;
323 //_____________________________________________________________________________
324 void TrigEffTrending(TObjArray runNumArray, TObjArray fileNameArray, TList& outCanList, TList& outList)
326 /// Get the efficiency vs. run number
327 TString elementName[3] = { "Chamber", "RPC", "Board" };
328 TString countTypeName[4] = { "allTracks", "bendPlane", "nonBendPlane", "bothPlanes" };
330 TString filename = "", effName = "", effTitle = "";
333 Double_t effValues[3][2*kNch];
334 const Int_t kNgraphs = kNch*3*2+3;
335 TObjArray effList(kNgraphs);
337 const Int_t kNeffVsRun = kNgraphs+1;
338 TObjArray effVsRunList(kNeffVsRun);
340 effName = "totalEffEvolution";
341 effTitle = "Multinomial probability of firing at least 3/4 chambers";
342 TH1D* totalEff = new TH1D(effName.Data(), effTitle.Data(), 1, 0., 1.);
343 effVsRunList.AddAt(totalEff, kNeffVsRun-1);
345 TString runNumString = "";
346 for ( Int_t irun=0; irun<runNumArray.GetEntries(); irun++ ) {
348 runNumString = runNumArray.At(irun)->GetName();
350 // Search corresponding file (for sorting)
351 for ( Int_t ifile=0; ifile<fileNameArray.GetEntries(); ifile++ ) {
352 filename = fileNameArray.At(ifile)->GetName();
353 if ( filename.Contains(runNumString.Data()) ) break;
356 if ( filename.Contains("alien://") && ! gGrid ) gGrid->Connect("alien://");
359 // First get the list of efficiency graphs
362 // Chamber efficiency
363 TFile* file = TFile::Open(filename.Data());
365 printf("Warning: cannot find %s\n", filename.Data());
369 TList* trigEffList = (TList*)file->FindObjectAny("triggerChamberEff");
370 if ( ! trigEffList ) printf("Warning: histo list not found in %s. Check directly in file\n", filename.Data());
371 if ( trigEffList->GetEntries() == 0 ) {
372 printf("Warning: empty trigger list in file %s. Probably no MUON info there. Skip.\n", filename.Data());
377 for ( Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts; icount++ ) {
378 effName = countTypeName[icount] + "Count" + elementName[0];
380 histoDen = GetHisto(effName, file, trigEffList);
384 TH1* histoNum = GetHisto(effName, file, trigEffList);
385 TGraphAsymmErrors* graph = new TGraphAsymmErrors(histoNum, histoDen,"e0");
386 effName.ReplaceAll("Count","Eff");
387 graph->SetName(effName.Data());
388 effList.AddAt(graph, GetEffIndex(0, icount-1));
393 printf("Error: cannot find histograms in file %s. Skip to next\n", filename.Data());
397 // RPC/board efficiency
398 AliMUONTriggerChamberEfficiency trigChEff(filename);
399 for ( Int_t iel=1; iel<3; iel++ ) {
400 for ( Int_t ich=0; ich<kNch; ich++ ) {
401 for ( Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts-1; icount++ ) {
402 TObject* obj = trigChEff.GetEffObject(2-iel, icount, ich);
403 effList.AddAt(obj->Clone(Form("%s_cloned",obj->GetName())), GetEffIndex(iel, icount, ich));
408 // Fill efficiency vs run
409 for ( Int_t iel=0; iel<3; iel++ ) {
410 for ( Int_t ich=0; ich<kNch; ich++ ) {
411 for ( Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts-1; icount++ ) {
412 TGraphAsymmErrors* graph = static_cast<TGraphAsymmErrors*>(effList.At(GetEffIndex(iel, icount, ich)));
413 Int_t nPoints = ( iel == 0 ) ? 1 : graph->GetN();
414 for ( Int_t ipoint=0; ipoint<nPoints; ipoint++ ) {
415 Int_t currPoint = ( iel == 0 ) ? ich : ipoint;
417 graph->GetPoint(currPoint, xpt, ypt);
418 effValues[icount][ich] = ypt;
419 Int_t ihisto = GetEffIndex(iel,icount,ich);
420 TH2* effHisto = static_cast<TH2*>(effVsRunList.At(ihisto));
422 effName = Form("effEvolution%s%s", countTypeName[icount+1].Data(), elementName[iel].Data());
423 effTitle = Form("Trigger chamber efficiency vs run");
425 effName += Form("Ch%i", 11+ich);
426 effTitle += Form(" for chamber %i", 11+ich);
428 effHisto = new TH2D(effName.Data(), effTitle.Data(), 1, 0., 1., graph->GetN(), xpt-0.5, xpt-0.5+(Double_t)graph->GetN());
429 effVsRunList.AddAt(effHisto, ihisto);
431 Int_t currBin = effHisto->Fill(runNumString.Data(), xpt, ypt);
432 Double_t err = 0.5*(graph->GetErrorYlow(ipoint) + graph->GetErrorYhigh(ipoint));
433 Int_t binx, biny, binz;
434 effHisto->GetBinXYZ(currBin, binx, biny, binz);
435 effHisto->SetBinError(binx, biny, err);
436 effValues[icount][ich+kNch] = err;
439 } // loop on chambers
440 if ( iel > 0 ) continue;
441 Double_t* binomialEff = GetBinomial(effValues[0], effValues[1], effValues[2]);
442 Int_t currBin = totalEff->Fill(runNumString, binomialEff[0]);
444 // Well, error calculation of the binomial efficiency is a mess...
445 // Sometimes it happens that efficiency + error > 1.
446 // In that case reduce the error.
447 totalEff->SetBinError(currBin, TMath::Min(binomialEff[1], 1.-binomialEff[0]));
449 } // loop on detection elements
452 // Set correct range (do not show last empty bins)
453 for ( Int_t ihisto=0; ihisto<effVsRunList.GetEntries(); ihisto++ ) {
454 TH1* histo = static_cast<TH1*>(effVsRunList.At(ihisto));
455 SetRunAxisRange(histo->GetXaxis());
457 //histo->GetXaxis()->SetLabelSize(0.03);
460 TString canName = "totalEff";
461 TCanvas* can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
462 TH1* totEff = (TH1*)effVsRunList.At(kNeffVsRun-1);
463 totEff->GetYaxis()->SetRangeUser(0.9,1.05);
464 totEff->GetYaxis()->SetTitle("Probability to satisfy trigger conditions (3/4)");
465 totEff->SetStats(kFALSE);
469 Int_t color[3] = {kBlack, kRed, kBlue};
470 Int_t markStyle[3] = {20, 24, 26};
473 for ( Int_t ich=0; ich<kNch; ich++ ) {
474 canName = Form("trigEffCh%i", 11+ich);
475 can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
477 leg = new TLegend(0.6, 0.2, 0.9, 0.4);
478 leg->SetBorderSize(1);
480 TString drawOpt = "e";
481 for(Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts-1; icount++) {
483 TH2* histo = static_cast<TH2*>(effVsRunList.At(GetEffIndex(0, icount)));
484 TH1* chEff = histo->ProjectionX(Form("effEvolutionCh%i",11+ich), ich+1, ich+1);
485 chEff->SetTitle(Form("%s for chamber %i", histo->GetTitle(), 11+ich));
486 chEff->GetYaxis()->SetRangeUser(0.9,1.);
487 chEff->SetStats(kFALSE);
488 chEff->GetYaxis()->SetTitle("Trigger chamber efficiency");
489 TH1* copyEff = chEff->DrawCopy(drawOpt.Data());
490 copyEff->SetLineColor(color[icount]);
491 copyEff->SetMarkerColor(color[icount]);
492 copyEff->SetMarkerStyle(markStyle[icount]);
493 leg->AddEntry(copyEff, countTypeName[icount+1].Data(), "lp");
498 } // loop on chambers
500 for ( Int_t iel=1; iel<3; iel++ ) {
501 for ( Int_t ich=0; ich<kNch; ich++ ) {
502 Int_t icount = AliMUONTriggerEfficiencyCells::kBothPlanesEff; // Just plot the efficiency for both
503 // for ( Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts-1; icount++ ) {
504 canName = Form("trigEff%sCh%i", elementName[iel].Data(), 11+ich);
505 can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
506 can->SetRightMargin(0.14);
507 TH2* histo = static_cast<TH2*>(effVsRunList.At(GetEffIndex(iel, icount,ich)));
508 histo->SetStats(kFALSE);
509 histo->GetYaxis()->SetTitle(elementName[iel].Data());
510 histo->DrawCopy("COLZ");
511 // } // loop on counts
513 } // loop on chambers
514 } // loop on detection element type
517 //_____________________________________________________________________________
518 void MaskTrending ( TObjArray runNumArray, TString defaultStorage, TList& outCanList, TList& outList )
520 /// Get the masks vs. run number
521 if ( defaultStorage.Contains("alien://") || defaultStorage.Contains("raw://") ) {
522 if ( ! gGrid ) TGrid::Connect("alien://");
524 printf("Error: Problem connetting to grid: nothing done");
530 TObjArray maskedList(8);
531 TObjArray auxList(8);
533 TString histoName = "", histoTitle = "";
534 for(Int_t icath=0; icath<2; icath++){
535 TString cathName = ( icath==0 ) ? "bendPlane" : "nonBendPlane";
536 for(Int_t ich=0; ich<kNch; ich++){
537 histoName = Form("%sMaskCh%i", cathName.Data(), 11+ich);
538 histoTitle = Form("Chamber %i - %s: fraction of masked channels", 11+ich, cathName.Data());
539 TH2* histo = new TH2D(histoName.Data(), histoTitle.Data(),1,0.,1., 234, 0.5, 234. + 0.5);
540 histo->GetYaxis()->SetTitle("Board Id");
541 histo->SetOption("COLZ");
542 Int_t imask = 2*ich + icath;
543 maskedList.AddAt(histo, imask);
544 auxList.AddAt(histo->Clone(Form("%s_aux",histoName.Data())), imask);
545 } // loop on chambers
546 } // loop on cathodes
548 TArrayS xyPatternAll[2];
549 for(Int_t icath=0; icath<2; icath++){
550 xyPatternAll[icath].Set(kNch);
551 xyPatternAll[icath].Reset(0xFFFF);
554 if ( ! AliCDBManager::Instance()->IsDefaultStorageSet() ) AliCDBManager::Instance()->SetDefaultStorage(defaultStorage.Data());
555 TList* ocdbFileList = 0x0;
556 Int_t previousRun = -1;
557 AliMUONDigitMaker* digitMaker = 0x0;
558 AliMUONDigitStoreV2R digitStore;
560 AliMUONCalibrationData* calibData = 0x0;
561 AliMUONTriggerUtilities* trigUtilities = 0x0;
562 for ( Int_t irun=0; irun<runNumArray.GetEntries(); irun++ ) {
563 TString runNumString = runNumArray.At(irun)->GetName();
564 Int_t runNumber = runNumString.Atoi();
566 if ( IsOCDBChanged(runNumber, previousRun, ocdbFileList) ) {
567 AliCDBManager::Instance()->SetRun(runNumber);
569 if ( ! digitMaker ) {
570 digitMaker = new AliMUONDigitMaker(kFALSE);
571 // Create a store with all digits in trigger
572 for ( Int_t iboard=1; iboard<=234; iboard++ ) {
573 digitMaker->TriggerDigits(iboard, xyPatternAll, digitStore, kFALSE);
577 if ( ! ocdbFileList ) ocdbFileList = GetOCDBList();
580 calibData = new AliMUONCalibrationData (runNumber);
581 delete trigUtilities;
582 trigUtilities = new AliMUONTriggerUtilities (calibData);
585 previousRun = runNumber;
587 TIter next(digitStore.CreateIterator());
588 AliMUONVDigit* dig = 0x0;
589 while ( ( dig = static_cast<AliMUONVDigit*>(next()) ) ) {
590 Int_t icath = dig->Cathode();
591 Int_t detElemId = dig->DetElemId();
592 Int_t ich = detElemId/100-11;
593 Int_t iboard = dig->ManuId();
594 Int_t imask = 2*ich + icath;
595 static_cast<TH2*>(auxList.At(imask))->Fill(runNumString.Data(),iboard,1.);
596 static_cast<TH2*>(maskedList.At(imask))->Fill(runNumString.Data(),iboard,(Double_t)trigUtilities->IsMasked(*dig));
600 delete trigUtilities;
603 TString canName = "";
604 for ( Int_t imask=0; imask<maskedList.GetEntries(); imask++ ) {
605 TH2* histo = static_cast<TH2*>(maskedList.At(imask));
606 histo->Divide(static_cast<TH2*>(auxList.At(imask)));
607 SetRunAxisRange(histo->GetXaxis());
610 canName = Form("%sCan", histo->GetName());
611 TCanvas* can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
612 can->SetRightMargin(0.14);
613 histo->SetStats(kFALSE);
614 histo->DrawCopy("COLZ");
619 //_____________________________________________________________________________
620 Bool_t CheckPattern ( TString trigName, TObjArray* keepArray, TObjArray* rejectArray )
623 for ( Int_t ipat=0; ipat<rejectArray->GetEntries(); ++ipat ) {
624 if ( trigName.Contains(rejectArray->At(ipat)->GetName() ) ) return kFALSE;
625 } // loop on reject pattern
627 for ( Int_t ipat=0; ipat<keepArray->GetEntries(); ++ipat ) {
628 if ( trigName.Contains(keepArray->At(ipat)->GetName() ) ) return kTRUE;
629 } // loop on keep pattern
631 return ( keepArray->GetEntries() == 0 ) ? kTRUE : kFALSE;
634 //_____________________________________________________________________________
635 TObjArray* BuildListOfTrigger ( const TObjArray* triggerArray, TString keepPattern = "", TString rejectPattern="OTHER,TRUE,PHI,ANY,EMC,-ACE-,-ABCE-,WU,MUP,SPI,SHM" )
637 /// Build list of trigger classes
638 TObjArray* selectedList = new TObjArray();
639 selectedList->SetOwner();
640 TObjArray* rejectArray = rejectPattern.Tokenize(",");
641 TObjArray* keepArray = keepPattern.Tokenize(",");
643 for ( Int_t iTrig = 0; iTrig < triggerArray->GetEntries(); iTrig++ ){
644 TString currTrigName = ((TObjString*)triggerArray->At(iTrig))->GetName();
645 if ( CheckPattern(currTrigName, keepArray, rejectArray) ) selectedList->AddLast(new TObjString(currTrigName.Data()));
655 //_____________________________________________________________________________
656 TString FindCorrespondingTrigger ( TString checkTrigger, TObjArray* triggerArray )
658 /// Find trigger from pattern
659 TString foundName = "";
660 for ( Int_t iTrig = 0; iTrig < triggerArray->GetEntries(); iTrig++ ){
661 TString currTrigName = ((TObjString*)triggerArray->At(iTrig))->GetName();
662 TObjArray* array = currTrigName.Tokenize("-");
663 TString collisionType = array->At(1)->GetName();
665 collisionType.Append("-");
666 collisionType.Prepend("-");
667 if ( checkTrigger.Contains(collisionType.Data()) ) {
668 foundName = currTrigName;
676 //_____________________________________________________________________________
677 void ScalerTrending ( TObjArray runNumArray, TString mergedFileName, TString defaultStorage, TList& outCanList, TList& outList )
679 /// Get the scalers vs. run number
680 if ( defaultStorage.Contains("alien://") || defaultStorage.Contains("raw://") ) {
681 if ( ! gGrid ) TGrid::Connect("alien://");
683 printf("Error: Problem connetting to grid: nothing done");
688 if ( ! AliCDBManager::Instance()->IsDefaultStorageSet() ) AliCDBManager::Instance()->SetDefaultStorage(defaultStorage.Data());
690 //trigger count from ESDs
691 TFile *file = TFile::Open(mergedFileName.Data());
692 AliCounterCollection* ccol = (AliCounterCollection*)((TDirectoryFile*)file->FindObjectAny("MUON_QA"))->FindObjectAny("eventCounters");
694 //Build the trigger list for trigger with muon only in readout and min. bias triggers
695 TString triggerListName = ccol->GetKeyWords("trigger");
697 TObjArray selectedTriggerArray, selectedL0TriggerArray;
698 selectedTriggerArray.SetOwner();
699 selectedL0TriggerArray.SetOwner();
701 const Int_t nScaler = 3;
702 TString sScaler[nScaler] = {"L0B","L2A","L0BRATE"};
703 enum eScaler {kL0B = 0, kL2A=1, kL0BRATE=2};
704 Float_t maxScaler[nScaler] = {1e8,1e7,1e6};
706 TObjArray hFromScalers;
710 TString sHistName, sHistNameFull, sTitleName;
711 Int_t nRuns = runNumArray.GetEntries();
714 //Fill histos for Scalers and QA
717 for ( Int_t iRun = 0; iRun < runNumArray.GetEntries(); iRun++ ) {
719 TString sRunNr = ((TObjString*)runNumArray.At(iRun))->GetString();
720 Int_t runNr = sRunNr.Atoi();
721 AliAnalysisTriggerScalers triggerScaler(runNr);
722 AliTriggerConfiguration* tc = static_cast<AliTriggerConfiguration*>(triggerScaler.GetOCDBObject("GRP/CTP/Config",runNr));
723 const TObjArray& trClasses = tc->GetClasses();
727 for ( Int_t itype=0; itype<2; itype++ ) {
728 TObjArray* currSelectedList = ( itype == 0 ) ? &selectedTriggerArray : &selectedL0TriggerArray;
729 TString matchTrig = ( itype == 0 ) ? "" : "C0TVX";
730 TObjArray* selectedTrigArrayForRun = BuildListOfTrigger(&trClasses, matchTrig);
732 //loop on trigger list
733 for ( Int_t iTrig = 0; iTrig < selectedTrigArrayForRun->GetEntries(); iTrig++ ) {
735 TString currTrigName = selectedTrigArrayForRun->At(iTrig)->GetName();
736 if ( itype == 0 && ! triggerListName.Contains(currTrigName.Data()) ) continue;
737 if ( ! currSelectedList->FindObject(currTrigName.Data()) ) currSelectedList->Add(new TObjString(currTrigName));
739 //loop on scaler list
740 for ( Int_t iScaler = 0; iScaler < nScaler; iScaler++ ) {
742 if ( itype == 1 && iScaler != kL0B ) continue;
745 TGraph* graph = triggerScaler.PlotTrigger(currTrigName.Data(),sScaler[iScaler].Data());
747 sHistName = Form("%s_%s",currTrigName.Data(),sScaler[iScaler].Data());
748 sHistNameFull = Form("Scalers_%s",sHistName.Data());
750 TH1* hist = (TH1*) hFromScalers.FindObject(sHistNameFull);
752 hist = new TH1D(sHistNameFull,sHistName,nRuns,1.,1.+(Double_t)nRuns);
753 hist->SetDirectory(0);
755 hist->SetMaximum(maxScaler[0]);
756 hFromScalers.AddLast(hist);
757 hOutput.AddLast(hist);
758 if ( iScaler == kL2A ) {
759 sHistNameFull = "QA_" + sHistName;
760 hFromQA.AddLast(hist->Clone(sHistNameFull.Data()));
763 Double_t *tab = (Double_t*) graph->GetY();
764 if ( tab ) hist->SetBinContent(ibin,tab[0]);
765 hist->GetXaxis()->SetBinLabel(ibin,sRunNr.Data());
769 if ( iScaler != kL2A ) continue;
770 TH1* histCounters = static_cast<TH1*>(ccol->Get("run",Form("run:%s/trigger:%s",sRunNr.Data(),currTrigName.Data())));
771 sHistNameFull = sHistNameFull = "QA_" + sHistName;
772 hist = (TH1*) hFromQA.FindObject(sHistNameFull);
773 if ( histCounters ) hist->SetBinContent(ibin,histCounters->GetSumOfWeights());
774 hist->GetXaxis()->SetBinLabel(ibin,sRunNr.Data());
776 }//end loop on scaler list
777 }//end loop on trigger list
778 } // end loop on type
779 }//end loop on run list
782 if ( selectedTriggerArray.GetEntries() == 0 ) {
783 printf("No trigger selected from trigger list %s\n",triggerListName.Data());
786 printf("Nr of triggers selected %i\n",selectedTriggerArray.GetEntries());
788 printf("Nr of T0 triggers selected %i\n",selectedL0TriggerArray.GetEntries());
790 //Set options for QA and Scalers histos
792 for ( Int_t itype=0; itype<2; itype++ ) {
793 TObjArray* currList = ( itype == 0 ) ? &hFromScalers : &hFromQA;
794 for ( Int_t ihisto=0; ihisto<currList->GetEntriesFast(); ihisto++ ) {
795 TH1* histo = static_cast<TH1*> ( currList->At(ihisto) );
796 if (!histo) continue;
797 // Write run number to each bin
798 for ( Int_t iRun = 0; iRun < runNumArray.GetEntries(); iRun++ ) {
799 TString sRunNr = ((TObjString*)runNumArray.At(iRun))->GetString();
801 TString binLabel = histo->GetXaxis()->GetBinLabel(ibin);
802 if ( ! binLabel.IsNull() ) continue;
803 histo->GetXaxis()->SetBinLabel(ibin,sRunNr.Data());
805 histo->SetStats(kFALSE);
810 //Loop on histos from scalers and QA and create resulting histos from scalers
811 const Int_t nHisto = 3;
812 TString sHisto[nHisto] = {"L0BoverL0BC0TVX","L2AoverL0B","L2AQAoverSCALERS"};
813 TString sTitleHisto[nHisto] = {"L0B trigger / L0BC0TVX","L2A / L0B","L2A from QA / L2A from SCALERS"};
814 // TString sHisto[nHisto] = {"L2AoverL0B","L2AQAoverSCALERS"};
816 //loop on trigger list
817 for ( Int_t iTrig = 0; iTrig < selectedTriggerArray.GetEntries(); iTrig++ ) {
819 sHistNameFull = Form("Scalers_%s_L0B",((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
820 TH1* histo1 = static_cast<TH1*> ( hFromScalers.FindObject(sHistNameFull) );
821 if (!histo1) continue;
825 TString sTrig = ( (TObjString*) selectedTriggerArray.At(iTrig) )->GetName();
826 TString sL0Trig = FindCorrespondingTrigger(sTrig, &selectedL0TriggerArray);
828 sHistNameFull = Form("Scalers_%s_L0B",sL0Trig.Data());
830 TH1* histo0 = static_cast<TH1*> ( hFromScalers.FindObject(sHistNameFull) );
832 sHistNameFull = Form("%s_%s",sHisto[0].Data(),((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
833 TH1* histo10 = (TH1*) histo1->Clone(sHistNameFull);
834 histo10->SetTitle(sTitleHisto[0].Data());
836 histo10->Divide(histo0);
837 histo10->SetMaximum(10);
838 histo10->SetMinimum(1e-5);
839 //outList.Add(histo10);
840 hOutput.AddLast(histo10);
841 //outList.Add(histo0);
842 //outList.Add(histo1);
846 sHistNameFull = Form("Scalers_%s_L2A",((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
847 TH1* histo2 = static_cast<TH1*> ( hFromScalers.FindObject(sHistNameFull) );
848 if (!histo2) continue;
850 sHistNameFull = Form("%s_%s",sHisto[1].Data(),((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
851 TH1* histo3 = (TH1*) histo2->Clone(sHistNameFull);
852 histo3->SetTitle(sTitleHisto[1]);
854 histo3->Divide(histo1);
855 histo3->SetMaximum(1.2);
856 histo3->SetMinimum(1e-5);
857 //outList.Add(histo3);
858 hOutput.AddLast(histo3);
861 sHistNameFull = Form("QA_%s_L2A",((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
862 TH1* histo4 = static_cast<TH1*> ( hFromQA.FindObject(sHistNameFull) );
863 if (!histo4) continue;
865 sHistNameFull = Form("%s_%s",sHisto[2].Data(),((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
866 TH1* histo5 = (TH1*) histo4->Clone(sHistNameFull);
867 histo5->SetTitle(sTitleHisto[2]);
869 histo5->Divide(histo2);
870 histo5->SetMaximum(1.2);
871 histo5->SetMinimum(5e-1);
872 //outList.Add(histo5);
873 hOutput.AddLast(histo5);
876 // Plot all on canvases (only canvases will be saved)
877 const Int_t nCanvases = nScaler + nHisto;
878 TString sCanvases[nCanvases];
879 for (Int_t iScaler = 0; iScaler < nScaler; iScaler++) sCanvases[iScaler] = sScaler[iScaler];
880 for (Int_t iHisto = 0; iHisto < nHisto; iHisto++) sCanvases[nScaler+iHisto] = sHisto[iHisto];
883 for ( Int_t iCan = 0; iCan < nCanvases; iCan++) {
884 TCanvas* canvas = new TCanvas(sCanvases[iCan],sCanvases[iCan],200,10,600,600);
885 TLegend* leg = new TLegend(0.72,0.7,0.9,0.85);
886 leg->SetBorderSize(1);
887 if ( iCan != 4 ) canvas->SetLogy();
888 TString optDraw = "e";
890 //loop on trigger list
892 for ( Int_t iTrig = 0; iTrig < selectedTriggerArray.GetEntries(); iTrig++ ) {
894 if ( iCan < nScaler ) sHistNameFull = Form("Scalers_%s_%s",selectedTriggerArray.At(iTrig)->GetName(),sCanvases[iCan].Data());
895 else sHistNameFull = Form("%s_%s",sCanvases[iCan].Data(),selectedTriggerArray.At(iTrig)->GetName());
896 TH1* histo1 = static_cast<TH1*> ( hOutput.FindObject(sHistNameFull) );
897 if (!histo1) continue;
899 if ( icolor == 10 ) icolor++;
900 histo1->SetLineColor(icolor++);
901 histo1->Draw(optDraw);
904 leg->AddEntry(histo1,selectedTriggerArray.At(iTrig)->GetName(),"l");
909 outCanList.Add(canvas);
915 //_____________________________________________________________________________
916 void trigEffQA(TString fileListName, TString outFilename = "", TString defaultStorage = "raw://", Bool_t doScalers = kFALSE, TString trackerQAmergedOut="QAresults_merged.root")
919 ifstream inFile(fileListName.Data());
920 TObjArray fileNameArray, runNumArray;
921 fileNameArray.SetOwner();
922 runNumArray.SetOwner();
923 TString currString = "";
924 if (inFile.is_open()) {
925 while (! inFile.eof() ) {
926 currString.ReadLine(inFile); // Read line
927 if ( ! currString.Contains(".root") ||
928 currString.BeginsWith("#") ) continue;
929 fileNameArray.AddLast(new TObjString(currString.Data()));
930 Int_t runNum = GetRunNumber(currString);
931 runNumArray.AddLast(new TObjString(Form("%i",runNum)));
936 printf("Fatal: cannot open input file %s\n",fileListName.Data());
942 // Instead of using the efficiency stored in the QA output
943 // search for the new efficiency produced with trigger tracks only
944 TObjArray tmpArray = fileNameArray;
945 TObjArray* finalFileNameArray = ChangeFilenames(tmpArray) ? &tmpArray : &fileNameArray;
947 TList outCanList, outList;
948 TrigEffTrending(runNumArray, *finalFileNameArray, outCanList, outList);
949 if ( ! defaultStorage.IsNull() ) MaskTrending(runNumArray, defaultStorage, outCanList, outList);
950 if ( ! defaultStorage.IsNull() && doScalers ) {
951 if ( gSystem->AccessPathName(trackerQAmergedOut.Data()) ) {
952 printf("Warning: cannot perform scaler trending:\n merged QA from tracker\n %s\n does not exist\n",trackerQAmergedOut.Data());
955 ScalerTrending(runNumArray, trackerQAmergedOut, defaultStorage, outCanList, outList);
959 if ( outFilename.IsNull() ) return;
961 TString outCanName = outFilename;
962 outCanName.ReplaceAll(".root",".pdf");
963 for ( Int_t ican=0; ican<outCanList.GetEntries(); ican++ ) {
964 TString canName = outCanName;
965 if ( ican == 0 ) canName.Append("("); // open pdf file
966 else if ( ican == outCanList.GetEntries()-1 ) canName.Append(")"); // close pdf file
967 static_cast<TCanvas*>(outCanList.At(ican))->Print(canName.Data());
969 // There is a bug when creating a pdf
970 // So create a ps and then convert via epstopdf
971 if ( outCanName.Contains(".ps") || outCanName.Contains(".eps") ) {
972 gSystem->Exec(Form("epstopdf %s", outCanName.Data()));
973 gSystem->Exec(Form("rm %s", outCanName.Data()));
976 TFile* outFile = new TFile(outFilename.Data(), "recreate");