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);
71 //_____________________________________________________________________________
72 void SetRunAxisRange ( TAxis* axis )
75 for ( Int_t ibin=1; ibin<=axis->GetNbins(); ibin++ ) {
76 TString binLabel = axis->GetBinLabel(ibin);
77 if ( ! binLabel.IsNull()) continue;
78 axis->SetRange(1, ibin-1);
83 //_____________________________________________________________________________
84 Int_t GetRunNumber(TString filePath)
86 /// Get run number from file path
87 TObjArray* array = filePath.Tokenize("/");
89 TString auxString = "";
91 for ( Int_t ientry=0; ientry<array->GetEntries(); ientry++ ) {
92 auxString = array->At(ientry)->GetName();
93 if ( auxString.IsDigit() && auxString.Length()>=6 && auxString.Length()<=9 ) {
94 runNum = auxString.Atoi();
101 array = auxString.Tokenize("_");
103 auxString = array->Last()->GetName();
104 auxString.ReplaceAll(".root","");
105 runNum = auxString.Atoi();
112 //_____________________________________________________________________________
113 Bool_t ChangeFilenames ( TObjArray &fileNameArray )
115 /// Use custom output
116 /// We used to perform the QA on the MTR chamber efficiency
117 /// but since it is obtained form tracks matching with the tracker
118 /// it is not that good for QA since we are dependent on the tracker status.
119 /// In recent versions, the task also calculates the efficiency from all trigger tracks
120 /// (including ghosts). Analyse this output instead.
121 for ( Int_t ifile=0; ifile<fileNameArray.GetEntries(); ifile++ ) {
122 TObjString* currObjString = static_cast<TObjString*>(fileNameArray.At(ifile));
123 TString currFile = currObjString->GetString();
124 TString dirName = gSystem->DirName(currFile.Data());
125 TString fileName = gSystem->BaseName(currFile.Data());
126 Int_t runNum = GetRunNumber(fileName);
127 TString newFilename = Form("%s/terminateRuns/%i/trigChEff_ANY_Apt_allTrig.root",dirName.Data(),runNum);
128 if ( ! gSystem->AccessPathName(newFilename.Data()) ) {
129 printf("New output not found. Use the standard efficiency instead\n");
132 currObjString->SetString(newFilename);
137 //_____________________________________________________________________________
138 Double_t* GetProdErr(Double_t* effErr, Int_t exclude, Int_t nFactors = kNch)
142 Double_t relErr = 0., relProdErrSquare = 0.;
143 for ( Int_t iprod=0; iprod<nFactors; iprod++ ) {
144 if ( iprod == exclude ) continue;
145 prod *= effErr[iprod];
146 relErr = ( effErr[iprod] > kZero ) ? effErr[iprod+nFactors]/effErr[iprod] : 0.;
147 relProdErrSquare += relErr*relErr;
148 //printf("%f +- %f ", effErr[iprod], effErr[iprod+nFactors]); // alBER TO CUT
150 Double_t* prodErr = new Double_t[2];
152 prodErr[1] = prod*TMath::Sqrt(relProdErrSquare);
153 //printf("-> %f %f\n", prodErr[0], prodErr[1]); // REMEMBER TO CUT
158 //_____________________________________________________________________________
159 Double_t* GetConditionalEffErr(Double_t* effErr1, Double_t* effErr2, Double_t* effErrBoth, Int_t exclude = -1)
161 /// Error on conditional efficiency
162 Double_t* effErr = new Double_t[2*kNch];
163 for ( Int_t ich=0; ich<kNch; ich++ ) {
164 if ( ich == exclude ) {
165 effErr[ich] = ( effErr1[ich] < 1. ) ? ( effErr2[ich] - effErrBoth[ich] ) / ( 1. - effErr1[ich] ) : 0.;
166 effErr[ich+kNch] = 0;
167 if ( effErr1[ich] < 1. ) {
168 Double_t err2 = effErr2[ich+kNch] / ( 1. - effErr1[ich] );
169 Double_t errBoth = effErrBoth[ich+kNch] / ( 1. - effErr1[ich] );
170 Double_t err1 = effErr1[ich+kNch] * effErr[ich] / ( 1. - effErr1[ich] );
171 effErr[ich+kNch] = TMath::Sqrt(err2*err2 + errBoth*errBoth + err1*err1);
175 effErr[ich] = ( effErr1[ich] > kZero ) ? effErrBoth[ich]/effErr1[ich] : 0.;
176 Double_t relErr1 = ( effErr1[ich] > kZero ) ? effErr1[ich+kNch]/effErr1[ich] : 0.;
177 Double_t relErrBoth = ( effErrBoth[ich] > kZero ) ? effErrBoth[ich+kNch]/effErrBoth[ich] : 0.;
178 effErr[ich+kNch] = effErr[ich] * TMath::Sqrt(relErr1*relErr1 + relErrBoth*relErrBoth);
180 //printf("%f %f %f -> %f\n", effErr1[ich], effErr2[ich], effErrBoth[ich], effErr[ich]); // REMEMBER TO CUT
181 } // loop on chambers
186 //_____________________________________________________________________________
187 Double_t* GetBinomial(Double_t* effErr1, Double_t* effErr2 = 0x0, Double_t* effErrBoth = 0x0)
191 Double_t defaultEffErr[2] = {1.,0.};
192 Double_t* auxBinomial = 0x0;
193 Double_t* currEffErr44 = 0x0;
194 Double_t* effErrBinomial = new Double_t[2];
195 effErrBinomial[0] = 0.;
196 effErrBinomial[1] = 0.;
198 for ( Int_t ich = -1; ich<kNch; ich++ ) {
199 Double_t* currEffErr = GetProdErr(effErr1, ich);
201 currEffErr[0] = currEffErr[0] - currEffErr44[0];
202 currEffErr[1] = TMath::Sqrt(currEffErr[1]*currEffErr[1] + currEffErr44[1]*currEffErr44[1]);
205 Double_t* auxEffErr = GetConditionalEffErr(effErr1, effErr2, effErrBoth, ich);
206 auxBinomial = GetBinomial(auxEffErr);
209 for ( Int_t ival=0; ival<2; ival++ ) {
210 effProd[2*ival] = currEffErr[ival];
211 effProd[2*ival+1] = ( effErr2 ) ? auxBinomial[ival] : defaultEffErr[ival];
213 if ( ich < 0 ) currEffErr44 = currEffErr;
214 else delete currEffErr;
217 Double_t* effErr = GetProdErr(effProd, -1, 2);
218 //printf("%f * %f = %f\n", effProd[0], effProd[1], effErr[0]); // REMEMBER TO CUT
219 effErrBinomial[0] += effErr[0];
220 effErrBinomial[1] += effErr[1]*effErr[1];
222 } // loop on chambers
226 effErrBinomial[1] = TMath::Sqrt(effErrBinomial[1]);
228 return effErrBinomial;
232 //_____________________________________________________________________________
233 TH1* GetHisto(TString histoName, TFile* file, TList* histoList)
238 histo = (TH1*)histoList->FindObject(histoName.Data());
240 histo = (TH1*)file->FindObjectAny(histoName.Data());
245 //_____________________________________________________________________________
246 Int_t GetEffIndex ( Int_t iel, Int_t icount, Int_t ich = -1 )
248 /// Get efficienct histogram index
249 if ( iel == 0 ) return icount;
250 return 3 + 4*3*(iel-1) + 3*ich + icount;
253 //_____________________________________________________________________________
254 TList* GetOCDBList ( )
256 /// Get list of CDB objetcs
257 TString storageType = AliCDBManager::Instance()->GetDefaultStorage()->GetType();
258 Bool_t isGrid = storageType.Contains("alien");
259 TString baseFolder = AliCDBManager::Instance()->GetDefaultStorage()->GetBaseFolder();
261 TList* outList = new TList();
263 TString dirName[3] = {"GlobalTriggerCrateConfig", "RegionalTriggerConfig", "LocalTriggerBoardMasks"};
264 for ( Int_t idir=0; idir<3; idir++ ) {
266 TGridResult *res = gGrid->Ls(Form("%s/MUON/Calib/%s", baseFolder.Data(), dirName[idir].Data()));
267 if (!res) return 0x0;
268 for ( Int_t ires=0; ires<res->GetEntries(); ires++ ) {
269 TString currFile = static_cast<TMap*>(res->At(ires))->GetValue("name")->GetName();
270 outList->Add(new TObjString(currFile));
274 TString fileListStr = gSystem->GetFromPipe(Form("ls %s/MUON/Calib/%s", baseFolder.Data(), dirName[idir].Data()));
275 TObjArray* fileList = fileListStr.Tokenize("\n");
276 for ( Int_t ires=0; ires<fileList->GetEntries(); ires++ ) {
277 TString currFile = fileList->At(ires)->GetName();
278 outList->Add(new TObjString(currFile));
286 //_____________________________________________________________________________
287 Bool_t IsOCDBChanged ( Int_t currRun, Int_t previousRun, TList* fileList )
289 /// Check if the OCDB object is changed w.r.t. the previous run
290 if ( ! fileList ) return kTRUE;
291 for ( Int_t ifile=0; ifile<fileList->GetEntries(); ifile++ ) {
292 TString filename = static_cast<TObjString*>(fileList->At(ifile))->GetString();
293 filename.ReplaceAll("Run","");
294 TObjArray* array = filename.Tokenize("_");
295 Int_t firstRun = static_cast<TObjString*>(array->At(0))->GetString().Atoi();
296 Int_t lastRun = static_cast<TObjString*>(array->At(1))->GetString().Atoi();
298 Bool_t isCurrRunInside = ( currRun >= firstRun && currRun <= lastRun );
299 Bool_t isPreviousRunInside = ( previousRun >= firstRun && previousRun <= lastRun );
300 if ( isCurrRunInside != isPreviousRunInside ) return kTRUE;
305 //_____________________________________________________________________________
306 void TrigEffTrending(TObjArray runNumArray, TObjArray fileNameArray, TList& outCanList, TList& outList)
308 /// Get the efficiency vs. run number
309 TString elementName[3] = { "Chamber", "RPC", "Board" };
310 TString countTypeName[4] = { "allTracks", "bendPlane", "nonBendPlane", "bothPlanes" };
312 TString filename = "", effName = "", effTitle = "";
315 Double_t effValues[3][2*kNch];
316 const Int_t kNgraphs = kNch*3*2+3;
317 TObjArray effList(kNgraphs);
318 const Int_t kNeffVsRun = kNgraphs+1;
319 TObjArray effVsRunList(kNeffVsRun);
321 effName = "totalEffEvolution";
322 effTitle = "Multinomial probability of firing at least 3/4 chambers";
323 TH1D* totalEff = new TH1D(effName.Data(), effTitle.Data(), 0, 0., 1.);
324 effVsRunList.AddAt(totalEff, kNeffVsRun-1);
326 TString runNumString = "";
327 for ( Int_t irun=0; irun<runNumArray.GetEntries(); irun++ ) {
328 runNumString = runNumArray.At(irun)->GetName();
330 // Search corresponding file (for sorting)
331 for ( Int_t ifile=0; ifile<fileNameArray.GetEntries(); ifile++ ) {
332 filename = fileNameArray.At(ifile)->GetName();
333 if ( filename.Contains(runNumString.Data()) ) break;
336 if ( filename.Contains("alien://") && ! gGrid ) gGrid->Connect("alien://");
339 // First get the list of efficiency graphs
342 // Chamber efficiency
343 TFile* file = TFile::Open(filename.Data());
345 printf("Warning: cannot find %s\n", filename.Data());
349 TList* trigEffList = (TList*)file->FindObjectAny("triggerChamberEff");
350 if ( ! trigEffList ) printf("Warning: histo list not found in %s. Check directly in file\n", filename.Data());
353 for ( Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts; icount++ ) {
354 effName = countTypeName[icount] + "Count" + elementName[0];
356 histoDen = GetHisto(effName, file, trigEffList);
360 TH1* histoNum = GetHisto(effName, file, trigEffList);
361 TGraphAsymmErrors* graph = new TGraphAsymmErrors(histoNum, histoDen);
362 effName.ReplaceAll("Count","Eff");
363 graph->SetName(effName.Data());
364 effList.AddAt(graph, GetEffIndex(0, icount-1));
369 printf("Error: cannot find histograms in file %s. Skip to next\n", filename.Data());
373 // RPC/board efficiency
374 AliMUONTriggerChamberEfficiency trigChEff(filename);
375 for ( Int_t iel=1; iel<3; iel++ ) {
376 for ( Int_t ich=0; ich<kNch; ich++ ) {
377 for ( Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts-1; icount++ ) {
378 TObject* obj = trigChEff.GetEffObject(2-iel, icount, ich);
379 effList.AddAt(obj, GetEffIndex(iel, icount, ich));
384 // Fill efficiency vs run
385 for ( Int_t iel=0; iel<3; iel++ ) {
386 for ( Int_t ich=0; ich<kNch; ich++ ) {
387 for ( Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts-1; icount++ ) {
388 TGraphAsymmErrors* graph = static_cast<TGraphAsymmErrors*>(effList.At(GetEffIndex(iel, icount, ich)));
389 Int_t nPoints = ( iel == 0 ) ? 1 : graph->GetN();
390 for ( Int_t ipoint=0; ipoint<nPoints; ipoint++ ) {
391 Int_t currPoint = ( iel == 0 ) ? ich : ipoint;
393 graph->GetPoint(currPoint, xpt, ypt);
394 effValues[icount][ich] = ypt;
395 Int_t ihisto = GetEffIndex(iel,icount,ich);
396 TH2* effHisto = static_cast<TH2*>(effVsRunList.At(ihisto));
398 effName = Form("effEvolution%s%s", countTypeName[icount+1].Data(), elementName[iel].Data());
399 effTitle = Form("Trigger chamber efficiency vs run");
401 effName += Form("Ch%i", 11+ich);
402 effTitle += Form(" for chamber %i", 11+ich);
404 effHisto = new TH2D(effName.Data(), effTitle.Data(), 0, 0., 1., graph->GetN(), xpt-0.5, xpt-0.5+(Double_t)graph->GetN());
405 effVsRunList.AddAt(effHisto, ihisto);
407 Int_t currBin = effHisto->Fill(runNumString.Data(), xpt, ypt);
408 Double_t err = 0.5*(graph->GetErrorYlow(ipoint) + graph->GetErrorYhigh(ipoint));
409 Int_t binx, biny, binz;
410 effHisto->GetBinXYZ(currBin, binx, biny, binz);
411 effHisto->SetBinError(binx, biny, err);
412 effValues[icount][ich+kNch] = err;
415 } // loop on chambers
416 if ( iel > 0 ) continue;
417 Double_t* binomialEff = GetBinomial(effValues[0], effValues[1], effValues[2]);
418 Int_t currBin = totalEff->Fill(runNumString, binomialEff[0]);
420 // Well, error calculation of the binomial efficiency is a mess...
421 // Sometimes it happens that efficiency + error > 1.
422 // In that case reduce the error.
423 totalEff->SetBinError(currBin, TMath::Min(binomialEff[1], 1.-binomialEff[0]));
425 } // loop on detection elements
428 // Set correct range (do not show last empty bins)
429 for ( Int_t ihisto=0; ihisto<effVsRunList.GetEntries(); ihisto++ ) {
430 TH1* histo = static_cast<TH1*>(effVsRunList.At(ihisto));
431 SetRunAxisRange(histo->GetXaxis());
433 //histo->GetXaxis()->SetLabelSize(0.03);
436 TString canName = "totalEff";
437 TCanvas* can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
438 TH1* totEff = (TH1*)effVsRunList.At(kNeffVsRun-1);
439 totEff->GetYaxis()->SetRangeUser(0.9,1.05);
440 totEff->GetYaxis()->SetTitle("Probability to satisfy trigger conditions (3/4)");
441 totEff->SetStats(kFALSE);
445 Int_t color[3] = {kBlack, kRed, kBlue};
446 Int_t markStyle[3] = {20, 24, 26};
449 for ( Int_t ich=0; ich<kNch; ich++ ) {
450 canName = Form("trigEffCh%i", 11+ich);
451 can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
453 leg = new TLegend(0.6, 0.2, 0.9, 0.4);
454 leg->SetBorderSize(1);
456 TString drawOpt = "e";
457 for(Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts-1; icount++) {
459 TH2* histo = static_cast<TH2*>(effVsRunList.At(GetEffIndex(0, icount)));
460 TH1* chEff = histo->ProjectionX(Form("effEvolutionCh%i",11+ich), ich+1, ich+1);
461 chEff->SetTitle(Form("%s for chamber %i", histo->GetTitle(), 11+ich));
462 chEff->GetYaxis()->SetRangeUser(0.9,1.);
463 chEff->SetStats(kFALSE);
464 chEff->GetYaxis()->SetTitle("Trigger chamber efficiency");
465 TH1* copyEff = chEff->DrawCopy(drawOpt.Data());
466 copyEff->SetLineColor(color[icount]);
467 copyEff->SetMarkerColor(color[icount]);
468 copyEff->SetMarkerStyle(markStyle[icount]);
469 leg->AddEntry(copyEff, countTypeName[icount+1].Data(), "lp");
474 } // loop on chambers
476 for ( Int_t iel=1; iel<3; iel++ ) {
477 for ( Int_t ich=0; ich<kNch; ich++ ) {
478 Int_t icount = AliMUONTriggerEfficiencyCells::kBothPlanesEff; // Just plot the efficiency for both
479 // for ( Int_t icount=0; icount<AliMUONTriggerEfficiencyCells::kNcounts-1; icount++ ) {
480 canName = Form("trigEff%sCh%i", elementName[iel].Data(), 11+ich);
481 can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
482 can->SetRightMargin(0.14);
483 TH2* histo = static_cast<TH2*>(effVsRunList.At(GetEffIndex(iel, icount,ich)));
484 histo->SetStats(kFALSE);
485 histo->GetYaxis()->SetTitle(elementName[iel].Data());
486 histo->DrawCopy("COLZ");
487 // } // loop on counts
489 } // loop on chambers
490 } // loop on detection element type
493 //_____________________________________________________________________________
494 void MaskTrending ( TObjArray runNumArray, TString defaultStorage, TList& outCanList, TList& outList )
496 /// Get the masks vs. run number
497 if ( defaultStorage.Contains("alien://") || defaultStorage.Contains("raw://") ) {
498 if ( ! gGrid ) TGrid::Connect("alien://");
500 printf("Error: Problem connetting to grid: nothing done");
506 TObjArray maskedList(8);
507 TObjArray auxList(8);
509 TString histoName = "", histoTitle = "";
510 for(Int_t icath=0; icath<2; icath++){
511 TString cathName = ( icath==0 ) ? "bendPlane" : "nonBendPlane";
512 for(Int_t ich=0; ich<kNch; ich++){
513 histoName = Form("%sMaskCh%i", cathName.Data(), 11+ich);
514 histoTitle = Form("Chamber %i - %s: fraction of masked channels", 11+ich, cathName.Data());
515 TH2* histo = new TH2D(histoName.Data(), histoTitle.Data(),0,0.,1., 234, 0.5, 234. + 0.5);
516 histo->GetYaxis()->SetTitle("Board Id");
517 histo->SetOption("COLZ");
518 Int_t imask = 2*ich + icath;
519 maskedList.AddAt(histo, imask);
520 auxList.AddAt(histo->Clone(Form("%s_aux",histoName.Data())), imask);
521 } // loop on chambers
522 } // loop on cathodes
524 TArrayS xyPatternAll[2];
525 for(Int_t icath=0; icath<2; icath++){
526 xyPatternAll[icath].Set(kNch);
527 xyPatternAll[icath].Reset(0xFFFF);
530 if ( ! AliCDBManager::Instance()->IsDefaultStorageSet() ) AliCDBManager::Instance()->SetDefaultStorage(defaultStorage.Data());
531 TList* ocdbFileList = 0x0;
532 Int_t previousRun = -1;
533 AliMUONDigitMaker* digitMaker = 0x0;
534 AliMUONDigitStoreV2R digitStore;
536 AliMUONCalibrationData* calibData = 0x0;
537 AliMUONTriggerUtilities* trigUtilities = 0x0;
538 for ( Int_t irun=0; irun<runNumArray.GetEntries(); irun++ ) {
539 TString runNumString = runNumArray.At(irun)->GetName();
540 Int_t runNumber = runNumString.Atoi();
542 if ( IsOCDBChanged(runNumber, previousRun, ocdbFileList) ) {
543 AliCDBManager::Instance()->SetRun(runNumber);
545 if ( ! digitMaker ) {
546 digitMaker = new AliMUONDigitMaker(kFALSE);
547 // Create a store with all digits in trigger
548 for ( Int_t iboard=1; iboard<=234; iboard++ ) {
549 digitMaker->TriggerDigits(iboard, xyPatternAll, digitStore, kFALSE);
553 if ( ! ocdbFileList ) ocdbFileList = GetOCDBList();
556 calibData = new AliMUONCalibrationData (runNumber);
557 delete trigUtilities;
558 trigUtilities = new AliMUONTriggerUtilities (calibData);
561 previousRun = runNumber;
563 TIter next(digitStore.CreateIterator());
564 AliMUONVDigit* dig = 0x0;
565 while ( ( dig = static_cast<AliMUONVDigit*>(next()) ) ) {
566 Int_t icath = dig->Cathode();
567 Int_t detElemId = dig->DetElemId();
568 Int_t ich = detElemId/100-11;
569 Int_t iboard = dig->ManuId();
570 Int_t imask = 2*ich + icath;
571 static_cast<TH2*>(auxList.At(imask))->Fill(runNumString.Data(),iboard,1.);
572 static_cast<TH2*>(maskedList.At(imask))->Fill(runNumString.Data(),iboard,(Double_t)trigUtilities->IsMasked(*dig));
576 delete trigUtilities;
579 TString canName = "";
580 for ( Int_t imask=0; imask<maskedList.GetEntries(); imask++ ) {
581 TH2* histo = static_cast<TH2*>(maskedList.At(imask));
582 histo->Divide(static_cast<TH2*>(auxList.At(imask)));
583 SetRunAxisRange(histo->GetXaxis());
586 canName = Form("%sCan", histo->GetName());
587 TCanvas* can = new TCanvas(canName.Data(), canName.Data(), 200, 10, 600, 600);
588 can->SetRightMargin(0.14);
589 histo->SetStats(kFALSE);
590 histo->DrawCopy("COLZ");
595 //_____________________________________________________________________________
596 Bool_t CheckPattern ( TString trigName, TObjArray* keepArray, TObjArray* rejectArray )
599 for ( Int_t ipat=0; ipat<rejectArray->GetEntries(); ++ipat ) {
600 if ( trigName.Contains(rejectArray->At(ipat)->GetName() ) ) return kFALSE;
601 } // loop on reject pattern
603 for ( Int_t ipat=0; ipat<keepArray->GetEntries(); ++ipat ) {
604 if ( trigName.Contains(keepArray->At(ipat)->GetName() ) ) return kTRUE;
605 } // loop on keep pattern
607 return ( keepArray->GetEntries() == 0 ) ? kTRUE : kFALSE;
610 //_____________________________________________________________________________
611 TObjArray* BuildListOfTrigger ( const TObjArray* triggerArray, TString keepPattern = "", TString rejectPattern="OTHER,TRUE,PHI,ANY,EMC,-ACE-,-ABCE-,WU,MUP,SPI,SHM" )
613 /// Build list of trigger classes
614 TObjArray* selectedList = new TObjArray();
615 selectedList->SetOwner();
616 TObjArray* rejectArray = rejectPattern.Tokenize(",");
617 TObjArray* keepArray = keepPattern.Tokenize(",");
619 for ( Int_t iTrig = 0; iTrig < triggerArray->GetEntries(); iTrig++ ){
620 TString currTrigName = ((TObjString*)triggerArray->At(iTrig))->GetName();
621 if ( CheckPattern(currTrigName, keepArray, rejectArray) ) selectedList->AddLast(new TObjString(currTrigName.Data()));
631 //_____________________________________________________________________________
632 TString FindCorrespondingTrigger ( TString checkTrigger, TObjArray* triggerArray )
634 /// Find trigger from pattern
635 TString foundName = "";
636 for ( Int_t iTrig = 0; iTrig < triggerArray->GetEntries(); iTrig++ ){
637 TString currTrigName = ((TObjString*)triggerArray->At(iTrig))->GetName();
638 TObjArray* array = currTrigName.Tokenize("-");
639 TString collisionType = array->At(1)->GetName();
641 collisionType.Append("-");
642 collisionType.Prepend("-");
643 if ( checkTrigger.Contains(collisionType.Data()) ) {
644 foundName = currTrigName;
652 //_____________________________________________________________________________
653 void ScalerTrending ( TObjArray runNumArray, TString mergedFileName, TString defaultStorage, TList& outCanList, TList& outList )
655 /// Get the scalers vs. run number
656 if ( defaultStorage.Contains("alien://") || defaultStorage.Contains("raw://") ) {
657 if ( ! gGrid ) TGrid::Connect("alien://");
659 printf("Error: Problem connetting to grid: nothing done");
664 if ( ! AliCDBManager::Instance()->IsDefaultStorageSet() ) AliCDBManager::Instance()->SetDefaultStorage(defaultStorage.Data());
666 //trigger count from ESDs
667 TFile *file = TFile::Open(mergedFileName.Data());
668 AliCounterCollection* ccol = (AliCounterCollection*)((TDirectoryFile*)file->FindObjectAny("MUON_QA"))->FindObjectAny("eventCounters");
670 //Build the trigger list for trigger with muon only in readout and min. bias triggers
671 TString triggerListName = ccol->GetKeyWords("trigger");
673 TObjArray selectedTriggerArray, selectedL0TriggerArray;
674 selectedTriggerArray.SetOwner();
675 selectedL0TriggerArray.SetOwner();
677 const Int_t nScaler = 3;
678 TString sScaler[nScaler] = {"L0B","L2A","L0BRATE"};
679 enum eScaler {kL0B = 0, kL2A=1, kL0BRATE=2};
680 Float_t maxScaler[nScaler] = {1e8,1e7,1e6};
682 TObjArray hFromScalers;
686 TString sHistName, sHistNameFull, sTitleName;
687 Int_t nRuns = runNumArray.GetEntries();
690 //Fill histos for Scalers and QA
693 for ( Int_t iRun = 0; iRun < runNumArray.GetEntries(); iRun++ ) {
695 TString sRunNr = ((TObjString*)runNumArray.At(iRun))->GetString();
696 Int_t runNr = sRunNr.Atoi();
697 AliAnalysisTriggerScalers triggerScaler(runNr);
698 AliTriggerConfiguration* tc = static_cast<AliTriggerConfiguration*>(triggerScaler.GetOCDBObject("GRP/CTP/Config",runNr));
699 const TObjArray& trClasses = tc->GetClasses();
703 for ( Int_t itype=0; itype<2; itype++ ) {
704 TObjArray* currSelectedList = ( itype == 0 ) ? &selectedTriggerArray : &selectedL0TriggerArray;
705 TString matchTrig = ( itype == 0 ) ? "" : "C0TVX";
706 TObjArray* selectedTrigArrayForRun = BuildListOfTrigger(&trClasses, matchTrig);
708 //loop on trigger list
709 for ( Int_t iTrig = 0; iTrig < selectedTrigArrayForRun->GetEntries(); iTrig++ ) {
711 TString currTrigName = selectedTrigArrayForRun->At(iTrig)->GetName();
712 if ( itype == 0 && ! triggerListName.Contains(currTrigName.Data()) ) continue;
713 if ( ! currSelectedList->FindObject(currTrigName.Data()) ) currSelectedList->Add(new TObjString(currTrigName));
715 //loop on scaler list
716 for ( Int_t iScaler = 0; iScaler < nScaler; iScaler++ ) {
718 if ( itype == 1 && iScaler != kL0B ) continue;
721 TGraph* graph = triggerScaler.PlotTrigger(currTrigName.Data(),sScaler[iScaler].Data());
723 sHistName = Form("%s_%s",currTrigName.Data(),sScaler[iScaler].Data());
724 sHistNameFull = Form("Scalers_%s",sHistName.Data());
726 TH1* hist = (TH1*) hFromScalers.FindObject(sHistNameFull);
728 hist = new TH1D(sHistNameFull,sHistName,nRuns,1.,1.+(Double_t)nRuns);
729 hist->SetDirectory(0);
731 hist->SetMaximum(maxScaler[0]);
732 hFromScalers.AddLast(hist);
733 hOutput.AddLast(hist);
734 if ( iScaler == kL2A ) {
735 sHistNameFull = "QA_" + sHistName;
736 hFromQA.AddLast(hist->Clone(sHistNameFull.Data()));
739 Double_t *tab = (Double_t*) graph->GetY();
740 if ( tab ) hist->SetBinContent(ibin,tab[0]);
741 hist->GetXaxis()->SetBinLabel(ibin,sRunNr.Data());
745 if ( iScaler != kL2A ) continue;
746 TH1* histCounters = static_cast<TH1*>(ccol->Get("run",Form("run:%s/trigger:%s",sRunNr.Data(),currTrigName.Data())));
747 sHistNameFull = sHistNameFull = "QA_" + sHistName;
748 hist = (TH1*) hFromQA.FindObject(sHistNameFull);
749 if ( histCounters ) hist->SetBinContent(ibin,histCounters->GetSumOfWeights());
750 hist->GetXaxis()->SetBinLabel(ibin,sRunNr.Data());
752 }//end loop on scaler list
753 }//end loop on trigger list
754 } // end loop on type
755 }//end loop on run list
758 if ( selectedTriggerArray.GetEntries() == 0 ) {
759 printf("No trigger selected from trigger list %s\n",triggerListName.Data());
762 printf("Nr of triggers selected %i\n",selectedTriggerArray.GetEntries());
764 printf("Nr of T0 triggers selected %i\n",selectedL0TriggerArray.GetEntries());
766 //Set options for QA and Scalers histos
768 for ( Int_t itype=0; itype<2; itype++ ) {
769 TObjArray* currList = ( itype == 0 ) ? &hFromScalers : &hFromQA;
770 for ( Int_t ihisto=0; ihisto<currList->GetEntriesFast(); ihisto++ ) {
771 TH1* histo = static_cast<TH1*> ( currList->At(ihisto) );
772 if (!histo) continue;
773 // Write run number to each bin
774 for ( Int_t iRun = 0; iRun < runNumArray.GetEntries(); iRun++ ) {
775 TString sRunNr = ((TObjString*)runNumArray.At(iRun))->GetString();
777 TString binLabel = histo->GetXaxis()->GetBinLabel(ibin);
778 if ( ! binLabel.IsNull() ) continue;
779 histo->GetXaxis()->SetBinLabel(ibin,sRunNr.Data());
781 histo->SetStats(kFALSE);
786 //Loop on histos from scalers and QA and create resulting histos from scalers
787 const Int_t nHisto = 3;
788 TString sHisto[nHisto] = {"L0BoverL0BC0TVX","L2AoverL0B","L2AQAoverSCALERS"};
789 TString sTitleHisto[nHisto] = {"L0B trigger / L0BC0TVX","L2A / L0B","L2A from QA / L2A from SCALERS"};
790 // TString sHisto[nHisto] = {"L2AoverL0B","L2AQAoverSCALERS"};
792 //loop on trigger list
793 for ( Int_t iTrig = 0; iTrig < selectedTriggerArray.GetEntries(); iTrig++ ) {
795 sHistNameFull = Form("Scalers_%s_L0B",((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
796 TH1* histo1 = static_cast<TH1*> ( hFromScalers.FindObject(sHistNameFull) );
797 if (!histo1) continue;
801 TString sTrig = ( (TObjString*) selectedTriggerArray.At(iTrig) )->GetName();
802 TString sL0Trig = FindCorrespondingTrigger(sTrig, &selectedL0TriggerArray);
804 sHistNameFull = Form("Scalers_%s_L0B",sL0Trig.Data());
806 TH1* histo0 = static_cast<TH1*> ( hFromScalers.FindObject(sHistNameFull) );
808 sHistNameFull = Form("%s_%s",sHisto[0].Data(),((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
809 TH1* histo10 = (TH1*) histo1->Clone(sHistNameFull);
810 histo10->SetTitle(sTitleHisto[0].Data());
812 histo10->Divide(histo0);
813 histo10->SetMaximum(10);
814 histo10->SetMinimum(1e-5);
815 //outList.Add(histo10);
816 hOutput.AddLast(histo10);
817 //outList.Add(histo0);
818 //outList.Add(histo1);
822 sHistNameFull = Form("Scalers_%s_L2A",((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
823 TH1* histo2 = static_cast<TH1*> ( hFromScalers.FindObject(sHistNameFull) );
824 if (!histo2) continue;
826 sHistNameFull = Form("%s_%s",sHisto[1].Data(),((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
827 TH1* histo3 = (TH1*) histo2->Clone(sHistNameFull);
828 histo3->SetTitle(sTitleHisto[1]);
830 histo3->Divide(histo1);
831 histo3->SetMaximum(1.2);
832 histo3->SetMinimum(1e-5);
833 //outList.Add(histo3);
834 hOutput.AddLast(histo3);
837 sHistNameFull = Form("QA_%s_L2A",((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
838 TH1* histo4 = static_cast<TH1*> ( hFromQA.FindObject(sHistNameFull) );
839 if (!histo4) continue;
841 sHistNameFull = Form("%s_%s",sHisto[2].Data(),((TObjString*) selectedTriggerArray.At(iTrig))->GetName());
842 TH1* histo5 = (TH1*) histo4->Clone(sHistNameFull);
843 histo5->SetTitle(sTitleHisto[2]);
845 histo5->Divide(histo2);
846 histo5->SetMaximum(1.2);
847 histo5->SetMinimum(5e-1);
848 //outList.Add(histo5);
849 hOutput.AddLast(histo5);
852 // Plot all on canvases (only canvases will be saved)
853 const Int_t nCanvases = nScaler + nHisto;
854 TString sCanvases[nCanvases];
855 for (Int_t iScaler = 0; iScaler < nScaler; iScaler++) sCanvases[iScaler] = sScaler[iScaler];
856 for (Int_t iHisto = 0; iHisto < nHisto; iHisto++) sCanvases[nScaler+iHisto] = sHisto[iHisto];
859 for ( Int_t iCan = 0; iCan < nCanvases; iCan++) {
860 TCanvas* canvas = new TCanvas(sCanvases[iCan],sCanvases[iCan],200,10,600,600);
861 TLegend* leg = new TLegend(0.72,0.7,0.9,0.85);
862 leg->SetBorderSize(1);
863 if ( iCan != 4 ) canvas->SetLogy();
864 TString optDraw = "e";
866 //loop on trigger list
868 for ( Int_t iTrig = 0; iTrig < selectedTriggerArray.GetEntries(); iTrig++ ) {
870 if ( iCan < nScaler ) sHistNameFull = Form("Scalers_%s_%s",selectedTriggerArray.At(iTrig)->GetName(),sCanvases[iCan].Data());
871 else sHistNameFull = Form("%s_%s",sCanvases[iCan].Data(),selectedTriggerArray.At(iTrig)->GetName());
872 TH1* histo1 = static_cast<TH1*> ( hOutput.FindObject(sHistNameFull) );
873 if (!histo1) continue;
875 if ( icolor == 10 ) icolor++;
876 histo1->SetLineColor(icolor++);
877 histo1->Draw(optDraw);
880 leg->AddEntry(histo1,selectedTriggerArray.At(iTrig)->GetName(),"l");
885 outCanList.Add(canvas);
891 //_____________________________________________________________________________
892 void trigEffQA(TString fileListName, TString outFilename = "", TString defaultStorage = "raw://", Bool_t doScalers = kFALSE)
895 ifstream inFile(fileListName.Data());
896 TObjArray fileNameArray, runNumArray;
897 fileNameArray.SetOwner();
898 runNumArray.SetOwner();
899 TString currString = "";
900 if (inFile.is_open()) {
901 while (! inFile.eof() ) {
902 currString.ReadLine(inFile,kTRUE); // Read line
903 if ( currString.IsNull() || ! currString.Contains(".root") ||
904 currString.BeginsWith("#") ) continue;
905 fileNameArray.AddLast(new TObjString(currString.Data()));
906 Int_t runNum = GetRunNumber(currString);
907 runNumArray.AddLast(new TObjString(Form("%i",runNum)));
912 printf("Fatal: cannot open input file %s\n",fileListName.Data());
918 // Instead of using the efficiency stored in the QA output
919 // search for the new efficiency produced with trigger tracks only
920 TObjArray tmpArray = fileNameArray;
921 TObjArray* finalFileNameArray = ChangeFilenames(tmpArray) ? &tmpArray : &fileNameArray;
923 TList outCanList, outList;
924 TrigEffTrending(runNumArray, *finalFileNameArray, outCanList, outList);
925 if ( ! defaultStorage.IsNull() ) MaskTrending(runNumArray, defaultStorage, outCanList, outList);
926 if ( ! defaultStorage.IsNull() && doScalers ) ScalerTrending(runNumArray, "QAresults_Merged.root", defaultStorage, outCanList, outList);
928 if ( outFilename.IsNull() ) return;
930 TString outCanName = outFilename;
931 outCanName.ReplaceAll(".root",".pdf");
932 for ( Int_t ican=0; ican<outCanList.GetEntries(); ican++ ) {
933 TString canName = outCanName;
934 if ( ican == 0 ) canName.Append("("); // open pdf file
935 else if ( ican == outCanList.GetEntries()-1 ) canName.Append(")"); // close pdf file
936 static_cast<TCanvas*>(outCanList.At(ican))->Print(canName.Data());
938 // There is a bug when creating a pdf
939 // So create a ps and then convert via epstopdf
940 if ( outCanName.Contains(".ps") || outCanName.Contains(".eps") ) {
941 gSystem->Exec(Form("epstopdf %s", outCanName.Data()));
942 gSystem->Exec(Form("rm %s", outCanName.Data()));
945 TFile* outFile = new TFile(outFilename.Data(), "recreate");