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 if ( ! histo ) continue;
456 SetRunAxisRange(histo->GetXaxis());
458 //histo->GetXaxis()->SetLabelSize(0.03);
461 TString canName = "totalEff";
462 TCanvas* can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
463 TH1* totEff = (TH1*)effVsRunList.At(kNeffVsRun-1);
464 totEff->GetYaxis()->SetRangeUser(0.9,1.05);
465 totEff->GetYaxis()->SetTitle("Probability to satisfy trigger conditions (3/4)");
466 totEff->SetStats(kFALSE);
470 Int_t color[3] = {kBlack, kRed, kBlue};
471 Int_t markStyle[3] = {20, 24, 26};
474 for ( Int_t ich=0; ich<kNch; ich++ ) {
475 canName = Form("trigEffCh%i", 11+ich);
476 can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
478 leg = new TLegend(0.6, 0.2, 0.9, 0.4);
479 leg->SetBorderSize(1);
481 TString drawOpt = "e";
482 for(Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts-1; icount++) {
484 TH2* histo = static_cast<TH2*>(effVsRunList.At(GetEffIndex(0, icount)));
485 if ( ! histo ) continue;
486 TH1* chEff = histo->ProjectionX(Form("effEvolutionCh%i",11+ich), ich+1, ich+1);
487 chEff->SetTitle(Form("%s for chamber %i", histo->GetTitle(), 11+ich));
488 chEff->GetYaxis()->SetRangeUser(0.9,1.);
489 chEff->SetStats(kFALSE);
490 chEff->GetYaxis()->SetTitle("Trigger chamber efficiency");
491 TH1* copyEff = chEff->DrawCopy(drawOpt.Data());
492 copyEff->SetLineColor(color[icount]);
493 copyEff->SetMarkerColor(color[icount]);
494 copyEff->SetMarkerStyle(markStyle[icount]);
495 leg->AddEntry(copyEff, countTypeName[icount+1].Data(), "lp");
500 } // loop on chambers
502 for ( Int_t iel=1; iel<3; iel++ ) {
503 for ( Int_t ich=0; ich<kNch; ich++ ) {
504 Int_t icount = AliMUONTriggerEfficiencyCells::kBothPlanesEff; // Just plot the efficiency for both
505 // for ( Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts-1; icount++ ) {
506 canName = Form("trigEff%sCh%i", elementName[iel].Data(), 11+ich);
507 can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
508 can->SetRightMargin(0.14);
509 TH2* histo = static_cast<TH2*>(effVsRunList.At(GetEffIndex(iel, icount,ich)));
510 if ( ! histo ) continue;
511 histo->SetStats(kFALSE);
512 histo->GetYaxis()->SetTitle(elementName[iel].Data());
513 histo->DrawCopy("COLZ");
514 // } // loop on counts
516 } // loop on chambers
517 } // loop on detection element type
520 //_____________________________________________________________________________
521 void MaskTrending ( TObjArray runNumArray, TString defaultStorage, TList& outCanList, TList& outList )
523 /// Get the masks vs. run number
524 if ( defaultStorage.Contains("alien://") || defaultStorage.Contains("raw://") ) {
525 if ( ! gGrid ) TGrid::Connect("alien://");
527 printf("Error: Problem connetting to grid: nothing done");
533 TObjArray maskedList(8);
534 TObjArray auxList(8);
536 TString histoName = "", histoTitle = "";
537 for(Int_t icath=0; icath<2; icath++){
538 TString cathName = ( icath==0 ) ? "bendPlane" : "nonBendPlane";
539 for(Int_t ich=0; ich<kNch; ich++){
540 histoName = Form("%sMaskCh%i", cathName.Data(), 11+ich);
541 histoTitle = Form("Chamber %i - %s: fraction of masked channels", 11+ich, cathName.Data());
542 TH2* histo = new TH2D(histoName.Data(), histoTitle.Data(),1,0.,1., 234, 0.5, 234. + 0.5);
543 histo->GetYaxis()->SetTitle("Board Id");
544 histo->SetOption("COLZ");
545 Int_t imask = 2*ich + icath;
546 maskedList.AddAt(histo, imask);
547 auxList.AddAt(histo->Clone(Form("%s_aux",histoName.Data())), imask);
548 } // loop on chambers
549 } // loop on cathodes
551 TArrayS xyPatternAll[2];
552 for(Int_t icath=0; icath<2; icath++){
553 xyPatternAll[icath].Set(kNch);
554 xyPatternAll[icath].Reset(0xFFFF);
557 if ( ! AliCDBManager::Instance()->IsDefaultStorageSet() ) AliCDBManager::Instance()->SetDefaultStorage(defaultStorage.Data());
558 TList* ocdbFileList = 0x0;
559 Int_t previousRun = -1;
560 AliMUONDigitMaker* digitMaker = 0x0;
561 AliMUONDigitStoreV2R digitStore;
563 AliMUONCalibrationData* calibData = 0x0;
564 AliMUONTriggerUtilities* trigUtilities = 0x0;
565 for ( Int_t irun=0; irun<runNumArray.GetEntries(); irun++ ) {
566 TString runNumString = runNumArray.At(irun)->GetName();
567 Int_t runNumber = runNumString.Atoi();
569 if ( IsOCDBChanged(runNumber, previousRun, ocdbFileList) ) {
570 AliCDBManager::Instance()->SetRun(runNumber);
572 if ( ! digitMaker ) {
573 digitMaker = new AliMUONDigitMaker(kFALSE);
574 // Create a store with all digits in trigger
575 for ( Int_t iboard=1; iboard<=234; iboard++ ) {
576 digitMaker->TriggerDigits(iboard, xyPatternAll, digitStore, kFALSE);
580 if ( ! ocdbFileList ) ocdbFileList = GetOCDBList();
583 calibData = new AliMUONCalibrationData (runNumber);
584 delete trigUtilities;
585 trigUtilities = new AliMUONTriggerUtilities (calibData);
588 previousRun = runNumber;
590 TIter next(digitStore.CreateIterator());
591 AliMUONVDigit* dig = 0x0;
592 while ( ( dig = static_cast<AliMUONVDigit*>(next()) ) ) {
593 Int_t icath = dig->Cathode();
594 Int_t detElemId = dig->DetElemId();
595 Int_t ich = detElemId/100-11;
596 Int_t iboard = dig->ManuId();
597 Int_t imask = 2*ich + icath;
598 static_cast<TH2*>(auxList.At(imask))->Fill(runNumString.Data(),iboard,1.);
599 static_cast<TH2*>(maskedList.At(imask))->Fill(runNumString.Data(),iboard,(Double_t)trigUtilities->IsMasked(*dig));
603 delete trigUtilities;
606 TString canName = "";
607 for ( Int_t imask=0; imask<maskedList.GetEntries(); imask++ ) {
608 TH2* histo = static_cast<TH2*>(maskedList.At(imask));
609 histo->Divide(static_cast<TH2*>(auxList.At(imask)));
610 SetRunAxisRange(histo->GetXaxis());
613 canName = Form("%sCan", histo->GetName());
614 TCanvas* can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
615 can->SetRightMargin(0.14);
616 histo->SetStats(kFALSE);
617 histo->DrawCopy("COLZ");
622 //_____________________________________________________________________________
623 Bool_t CheckPattern ( TString trigName, TObjArray* keepArray, TObjArray* rejectArray )
626 for ( Int_t ipat=0; ipat<rejectArray->GetEntries(); ++ipat ) {
627 if ( trigName.Contains(rejectArray->At(ipat)->GetName() ) ) return kFALSE;
628 } // loop on reject pattern
630 for ( Int_t ipat=0; ipat<keepArray->GetEntries(); ++ipat ) {
631 if ( trigName.Contains(keepArray->At(ipat)->GetName() ) ) return kTRUE;
632 } // loop on keep pattern
634 return ( keepArray->GetEntries() == 0 ) ? kTRUE : kFALSE;
637 //_____________________________________________________________________________
638 TObjArray* BuildListOfTrigger ( const TObjArray* triggerArray, TString keepPattern = "", TString rejectPattern="OTHER,TRUE,PHI,ANY,EMC,-ACE-,-ABCE-,WU,MUP,SPI,SHM" )
640 /// Build list of trigger classes
641 TObjArray* selectedList = new TObjArray();
642 selectedList->SetOwner();
643 TObjArray* rejectArray = rejectPattern.Tokenize(",");
644 TObjArray* keepArray = keepPattern.Tokenize(",");
646 for ( Int_t iTrig = 0; iTrig < triggerArray->GetEntries(); iTrig++ ){
647 TString currTrigName = ((TObjString*)triggerArray->At(iTrig))->GetName();
648 if ( CheckPattern(currTrigName, keepArray, rejectArray) ) selectedList->AddLast(new TObjString(currTrigName.Data()));
658 //_____________________________________________________________________________
659 TString FindCorrespondingTrigger ( TString checkTrigger, TObjArray* triggerArray )
661 /// Find trigger from pattern
662 TString foundName = "";
663 for ( Int_t iTrig = 0; iTrig < triggerArray->GetEntries(); iTrig++ ){
664 TString currTrigName = ((TObjString*)triggerArray->At(iTrig))->GetName();
665 TObjArray* array = currTrigName.Tokenize("-");
666 TString collisionType = array->At(1)->GetName();
668 collisionType.Append("-");
669 collisionType.Prepend("-");
670 if ( checkTrigger.Contains(collisionType.Data()) ) {
671 foundName = currTrigName;
679 //_____________________________________________________________________________
680 void ScalerTrending ( TObjArray runNumArray, TString mergedFileName, TString defaultStorage, TList& outCanList, TList& outList )
682 /// Get the scalers vs. run number
683 if ( defaultStorage.Contains("alien://") || defaultStorage.Contains("raw://") ) {
684 if ( ! gGrid ) TGrid::Connect("alien://");
686 printf("Error: Problem connetting to grid: nothing done");
691 if ( ! AliCDBManager::Instance()->IsDefaultStorageSet() ) AliCDBManager::Instance()->SetDefaultStorage(defaultStorage.Data());
693 //trigger count from ESDs
694 TFile *file = TFile::Open(mergedFileName.Data());
695 AliCounterCollection* ccol = (AliCounterCollection*)((TDirectoryFile*)file->FindObjectAny("MUON_QA"))->FindObjectAny("eventCounters");
697 //Build the trigger list for trigger with muon only in readout and min. bias triggers
698 TString triggerListName = ccol->GetKeyWords("trigger");
700 TObjArray selectedTriggerArray, selectedL0TriggerArray;
701 selectedTriggerArray.SetOwner();
702 selectedL0TriggerArray.SetOwner();
704 const Int_t nScaler = 3;
705 TString sScaler[nScaler] = {"L0B","L2A","L0BRATE"};
706 enum eScaler {kL0B = 0, kL2A=1, kL0BRATE=2};
707 Float_t maxScaler[nScaler] = {1e8,1e7,1e6};
709 TObjArray hFromScalers;
713 TString sHistName, sHistNameFull, sTitleName;
714 Int_t nRuns = runNumArray.GetEntries();
717 //Fill histos for Scalers and QA
720 for ( Int_t iRun = 0; iRun < runNumArray.GetEntries(); iRun++ ) {
722 TString sRunNr = ((TObjString*)runNumArray.At(iRun))->GetString();
723 Int_t runNr = sRunNr.Atoi();
724 AliAnalysisTriggerScalers triggerScaler(runNr);
725 AliTriggerConfiguration* tc = static_cast<AliTriggerConfiguration*>(triggerScaler.GetOCDBObject("GRP/CTP/Config",runNr));
726 const TObjArray& trClasses = tc->GetClasses();
730 for ( Int_t itype=0; itype<2; itype++ ) {
731 TObjArray* currSelectedList = ( itype == 0 ) ? &selectedTriggerArray : &selectedL0TriggerArray;
732 TString matchTrig = ( itype == 0 ) ? "" : "C0TVX";
733 TObjArray* selectedTrigArrayForRun = BuildListOfTrigger(&trClasses, matchTrig);
735 //loop on trigger list
736 for ( Int_t iTrig = 0; iTrig < selectedTrigArrayForRun->GetEntries(); iTrig++ ) {
738 TString currTrigName = selectedTrigArrayForRun->At(iTrig)->GetName();
739 if ( itype == 0 && ! triggerListName.Contains(currTrigName.Data()) ) continue;
740 if ( ! currSelectedList->FindObject(currTrigName.Data()) ) currSelectedList->Add(new TObjString(currTrigName));
742 //loop on scaler list
743 for ( Int_t iScaler = 0; iScaler < nScaler; iScaler++ ) {
745 if ( itype == 1 && iScaler != kL0B ) continue;
748 TGraph* graph = triggerScaler.PlotTrigger(currTrigName.Data(),sScaler[iScaler].Data());
750 sHistName = Form("%s_%s",currTrigName.Data(),sScaler[iScaler].Data());
751 sHistNameFull = Form("Scalers_%s",sHistName.Data());
753 TH1* hist = (TH1*) hFromScalers.FindObject(sHistNameFull);
755 hist = new TH1D(sHistNameFull,sHistName,nRuns,1.,1.+(Double_t)nRuns);
756 hist->SetDirectory(0);
758 hist->SetMaximum(maxScaler[0]);
759 hFromScalers.AddLast(hist);
760 hOutput.AddLast(hist);
761 if ( iScaler == kL2A ) {
762 sHistNameFull = "QA_" + sHistName;
763 hFromQA.AddLast(hist->Clone(sHistNameFull.Data()));
766 Double_t *tab = (Double_t*) graph->GetY();
767 if ( tab ) hist->SetBinContent(ibin,tab[0]);
768 hist->GetXaxis()->SetBinLabel(ibin,sRunNr.Data());
772 if ( iScaler != kL2A ) continue;
773 TH1* histCounters = static_cast<TH1*>(ccol->Get("run",Form("run:%s/trigger:%s",sRunNr.Data(),currTrigName.Data())));
774 sHistNameFull = sHistNameFull = "QA_" + sHistName;
775 hist = (TH1*) hFromQA.FindObject(sHistNameFull);
776 if ( histCounters ) hist->SetBinContent(ibin,histCounters->GetSumOfWeights());
777 hist->GetXaxis()->SetBinLabel(ibin,sRunNr.Data());
779 }//end loop on scaler list
780 }//end loop on trigger list
781 } // end loop on type
782 }//end loop on run list
785 if ( selectedTriggerArray.GetEntries() == 0 ) {
786 printf("No trigger selected from trigger list %s\n",triggerListName.Data());
789 printf("Nr of triggers selected %i\n",selectedTriggerArray.GetEntries());
791 printf("Nr of T0 triggers selected %i\n",selectedL0TriggerArray.GetEntries());
793 //Set options for QA and Scalers histos
795 for ( Int_t itype=0; itype<2; itype++ ) {
796 TObjArray* currList = ( itype == 0 ) ? &hFromScalers : &hFromQA;
797 for ( Int_t ihisto=0; ihisto<currList->GetEntriesFast(); ihisto++ ) {
798 TH1* histo = static_cast<TH1*> ( currList->At(ihisto) );
799 if (!histo) continue;
800 // Write run number to each bin
801 for ( Int_t iRun = 0; iRun < runNumArray.GetEntries(); iRun++ ) {
802 TString sRunNr = ((TObjString*)runNumArray.At(iRun))->GetString();
804 TString binLabel = histo->GetXaxis()->GetBinLabel(ibin);
805 if ( ! binLabel.IsNull() ) continue;
806 histo->GetXaxis()->SetBinLabel(ibin,sRunNr.Data());
808 histo->SetStats(kFALSE);
813 //Loop on histos from scalers and QA and create resulting histos from scalers
814 const Int_t nHisto = 3;
815 TString sHisto[nHisto] = {"L0BoverL0BC0TVX","L2AoverL0B","L2AQAoverSCALERS"};
816 TString sTitleHisto[nHisto] = {"L0B trigger / L0BC0TVX","L2A / L0B","L2A from QA / L2A from SCALERS"};
817 // TString sHisto[nHisto] = {"L2AoverL0B","L2AQAoverSCALERS"};
819 //loop on trigger list
820 for ( Int_t iTrig = 0; iTrig < selectedTriggerArray.GetEntries(); iTrig++ ) {
822 sHistNameFull = Form("Scalers_%s_L0B",((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
823 TH1* histo1 = static_cast<TH1*> ( hFromScalers.FindObject(sHistNameFull) );
824 if (!histo1) continue;
828 TString sTrig = ( (TObjString*) selectedTriggerArray.At(iTrig) )->GetName();
829 TString sL0Trig = FindCorrespondingTrigger(sTrig, &selectedL0TriggerArray);
831 sHistNameFull = Form("Scalers_%s_L0B",sL0Trig.Data());
833 TH1* histo0 = static_cast<TH1*> ( hFromScalers.FindObject(sHistNameFull) );
835 sHistNameFull = Form("%s_%s",sHisto[0].Data(),((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
836 TH1* histo10 = (TH1*) histo1->Clone(sHistNameFull);
837 histo10->SetTitle(sTitleHisto[0].Data());
839 histo10->Divide(histo0);
840 histo10->SetMaximum(10);
841 histo10->SetMinimum(1e-5);
842 //outList.Add(histo10);
843 hOutput.AddLast(histo10);
844 //outList.Add(histo0);
845 //outList.Add(histo1);
849 sHistNameFull = Form("Scalers_%s_L2A",((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
850 TH1* histo2 = static_cast<TH1*> ( hFromScalers.FindObject(sHistNameFull) );
851 if (!histo2) continue;
853 sHistNameFull = Form("%s_%s",sHisto[1].Data(),((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
854 TH1* histo3 = (TH1*) histo2->Clone(sHistNameFull);
855 histo3->SetTitle(sTitleHisto[1]);
857 histo3->Divide(histo1);
858 histo3->SetMaximum(1.2);
859 histo3->SetMinimum(1e-5);
860 //outList.Add(histo3);
861 hOutput.AddLast(histo3);
864 sHistNameFull = Form("QA_%s_L2A",((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
865 TH1* histo4 = static_cast<TH1*> ( hFromQA.FindObject(sHistNameFull) );
866 if (!histo4) continue;
868 sHistNameFull = Form("%s_%s",sHisto[2].Data(),((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
869 TH1* histo5 = (TH1*) histo4->Clone(sHistNameFull);
870 histo5->SetTitle(sTitleHisto[2]);
872 histo5->Divide(histo2);
873 histo5->SetMaximum(1.2);
874 histo5->SetMinimum(5e-1);
875 //outList.Add(histo5);
876 hOutput.AddLast(histo5);
879 // Plot all on canvases (only canvases will be saved)
880 const Int_t nCanvases = nScaler + nHisto;
881 TString sCanvases[nCanvases];
882 for (Int_t iScaler = 0; iScaler < nScaler; iScaler++) sCanvases[iScaler] = sScaler[iScaler];
883 for (Int_t iHisto = 0; iHisto < nHisto; iHisto++) sCanvases[nScaler+iHisto] = sHisto[iHisto];
886 for ( Int_t iCan = 0; iCan < nCanvases; iCan++) {
887 TCanvas* canvas = new TCanvas(sCanvases[iCan],sCanvases[iCan],200,10,600,600);
888 TLegend* leg = new TLegend(0.72,0.7,0.9,0.85);
889 leg->SetBorderSize(1);
890 if ( iCan != 4 ) canvas->SetLogy();
891 TString optDraw = "e";
893 //loop on trigger list
895 for ( Int_t iTrig = 0; iTrig < selectedTriggerArray.GetEntries(); iTrig++ ) {
897 if ( iCan < nScaler ) sHistNameFull = Form("Scalers_%s_%s",selectedTriggerArray.At(iTrig)->GetName(),sCanvases[iCan].Data());
898 else sHistNameFull = Form("%s_%s",sCanvases[iCan].Data(),selectedTriggerArray.At(iTrig)->GetName());
899 TH1* histo1 = static_cast<TH1*> ( hOutput.FindObject(sHistNameFull) );
900 if (!histo1) continue;
902 if ( icolor == 10 ) icolor++;
903 histo1->SetLineColor(icolor++);
904 histo1->Draw(optDraw);
907 leg->AddEntry(histo1,selectedTriggerArray.At(iTrig)->GetName(),"l");
912 outCanList.Add(canvas);
918 //_____________________________________________________________________________
919 void trigEffQA(TString fileListName, TString outFilename = "", TString defaultStorage = "raw://", Bool_t doScalers = kFALSE, TString trackerQAmergedOut="QAresults_merged.root")
922 ifstream inFile(fileListName.Data());
923 TObjArray fileNameArray, runNumArray;
924 fileNameArray.SetOwner();
925 runNumArray.SetOwner();
926 TString currString = "";
927 if (inFile.is_open()) {
928 while (! inFile.eof() ) {
929 currString.ReadLine(inFile); // Read line
930 if ( ! currString.Contains(".root") ||
931 currString.BeginsWith("#") ) continue;
932 fileNameArray.AddLast(new TObjString(currString.Data()));
933 Int_t runNum = GetRunNumber(currString);
934 runNumArray.AddLast(new TObjString(Form("%i",runNum)));
939 printf("Fatal: cannot open input file %s\n",fileListName.Data());
945 // Instead of using the efficiency stored in the QA output
946 // search for the new efficiency produced with trigger tracks only
947 TObjArray tmpArray = fileNameArray;
948 TObjArray* finalFileNameArray = ChangeFilenames(tmpArray) ? &tmpArray : &fileNameArray;
950 TList outCanList, outList;
951 TrigEffTrending(runNumArray, *finalFileNameArray, outCanList, outList);
952 if ( ! defaultStorage.IsNull() ) MaskTrending(runNumArray, defaultStorage, outCanList, outList);
953 if ( ! defaultStorage.IsNull() && doScalers ) {
954 if ( gSystem->AccessPathName(trackerQAmergedOut.Data()) ) {
955 printf("Warning: cannot perform scaler trending:\n merged QA from tracker\n %s\n does not exist\n",trackerQAmergedOut.Data());
958 ScalerTrending(runNumArray, trackerQAmergedOut, defaultStorage, outCanList, outList);
962 if ( outFilename.IsNull() ) return;
964 TString outCanName = outFilename;
965 outCanName.ReplaceAll(".root",".pdf");
966 for ( Int_t ican=0; ican<outCanList.GetEntries(); ican++ ) {
967 TString canName = outCanName;
968 if ( ican == 0 ) canName.Append("("); // open pdf file
969 else if ( ican == outCanList.GetEntries()-1 ) canName.Append(")"); // close pdf file
970 static_cast<TCanvas*>(outCanList.At(ican))->Print(canName.Data());
972 // There is a bug when creating a pdf
973 // So create a ps and then convert via epstopdf
974 if ( outCanName.Contains(".ps") || outCanName.Contains(".eps") ) {
975 gSystem->Exec(Form("epstopdf %s", outCanName.Data()));
976 gSystem->Exec(Form("rm %s", outCanName.Data()));
979 TFile* outFile = new TFile(outFilename.Data(), "recreate");