1 #if !defined(__CINT__) || defined(__MAKECINT__)
3 #include "AliEMCALGeometry.h"
7 #include <TDirectory.h>
12 #include <TGraphErrors.h>
17 #include <TObjString.h>
23 // This macro produces runLevelQA for EMCAL from a QAresults.root file
24 // Authors: Y. Mao, A. Mas, M. Germain & A.Shabetai SUBATECH
25 // re-factored for automatic QA processing A.SHABETAI
27 Int_t DrawOccupancy(Long_t run, TString period, TString pass, TString fTrigger, TString system, TFile* f, TFile* fout, AliEMCALGeometry* geom, Int_t SavePlots);
28 Int_t DrawRun(Long_t run, TString period, TString pass, TString fTrigger, TFile *f, TFile* fout, Int_t SavePlots, Int_t nSM , Bool_t kFilter);
29 Int_t TrendingEMCALTree(Long_t RunId,TString fCalorimeter,TString system,TString period , TString pass,const int n ,TList* TriggersList,TFile* f,TFile *fout, Int_t SavePlots);
31 TH2F* FormatRunHisto(TH2F* aHisto,const char* title,const char* YTitle="");
32 TH2F* HistoPerMod(TH2F* name,const char* title);
33 TH2F* AutoZoom(TH2F* H,Option_t* aType="all", Int_t EntryMin=0);
34 int FindNumberOfSM(TFile* f, TString fTrigger,TString period);
37 TString QAPATHF = "./";
38 //-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
41 const Int_t NRGBs = 5;
42 const Int_t NCont = 255;
44 Double_t stops[NRGBs] = { 0.00, 0.34, 0.61, 0.84, 1.00 };
45 Double_t red[NRGBs] = { 0.00, 0.00, 0.87, 1.00, 0.51 };
46 Double_t green[NRGBs] = { 0.00, 0.81, 1.00, 0.20, 0.00 };
47 Double_t blue[NRGBs] = { 0.51, 1.00, 0.12, 0.00, 0.00 };
48 TColor::CreateGradientColorTable(NRGBs, stops, red, green, blue, NCont);
49 gStyle->SetNumberContours(NCont);
53 //-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
54 Double_t pi0massP2(Double_t *x, Double_t *par)
58 if (par[2] != 0.) gaus = par[0] * TMath::Exp( -(x[0]-par[1])*(x[0]-par[1]) / (2*par[2]*par[2]) );
60 else gaus = 99999999.;
62 Double_t back = par[3] + par[4]*x[0] + par[5]*x[0]*x[0];
68 //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
69 Double_t pi0massP1(Double_t *x, Double_t *par)
71 Double_t gaus = par[0] * TMath::Exp( -(x[0]-par[1])*(x[0]-par[1]) / (2*par[2]*par[2]) );
73 Double_t back = par[3] + par[4]*x[0];
79 //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
80 Double_t fitE(Double_t *x, Double_t *par)
85 levy = par[0] * TMath::Exp( -par[1]/x[0]) * TMath::Power(x[0], -par[2]) ;
90 //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
91 int CreateEMCALRunQA(const char* filename, TString RunId, TString period, TString pass, Int_t SavePlots = 0, Bool_t filter=0 , TString fTrigger = "", TString system = "", TString fCalorimeter = "EMCAL")
94 QAPATH = TString(gSystem->Getenv("QAPATH"));
95 if(QAPATH.IsNull()) QAPATH = QAPATHF;
96 if(! QAPATH.BeginsWith("./")) { QAPATH = QAPATH + RunId + "/";}
98 AliLog::SetGlobalLogLevel(AliLog::kError);
99 TFile *f = new TFile(filename);
100 AliLog::SetGlobalLogLevel(AliLog::kInfo);
102 if (f->IsZombie()) {Error(__FUNCTION__,Form("Error openning the input file %s",filename)); return -1;}
104 TList* TriggersList = new TList();
108 TPMERegexp name_re("CaloQA_\\w+");
109 TObjLink* link = f->GetListOfKeys()->FirstLink();
113 TString name = link->GetObject()->GetName();
114 if (name_re.Match(name))
116 TriggersList->Add(link->GetObject());
117 if(TString(filename).Contains("barrel") && ! name.Contains("default")) TriggersList->Remove(link->GetObject());
118 if(TString(filename).Contains("outer") && ! name.Contains("EMC")) TriggersList->Remove(link->GetObject());
122 } else {TriggersList->Add(new TObjString(fTrigger.Data()));}
124 if(!TriggersList->GetEntries()) {Error(__FUNCTION__,"No trigger found!"); return -2;}
126 int nSM = FindNumberOfSM(f,((TObjString*)TriggersList->Last())->GetString(),period);
127 if (nSM<0) {Error(__FUNCTION__,"Could not find the number of super modules!"); return -3;}
128 Info(__FUNCTION__,Form("%i super modules were discuvered",nSM));
130 if (nSM <= 6) { nSM=6; GeomName = "EMCAL_FIRSTYEARv1";}
131 else if (nSM <= 10) { nSM=10; GeomName = "EMCAL_COMPLETEv1";}
132 else if (nSM <= 12) { nSM=12; GeomName = "EMCAL_COMPLETE12SMv1";}
133 else {nSM = 20; GeomName = "EMCAL_COMPLETE12SMv1_DCAL_8SM";}
135 AliEMCALGeometry *geom = new AliEMCALGeometry(GeomName.Data(),"EMCAL");
136 Info(__FUNCTION__,Form("Using %i super modules and the Geometry %s",nSM,GeomName.Data()));
138 TFile *fout = new TFile(TString( QAPATH + period+"_"+pass + fTrigger+"_"+ (Long_t)RunId.Atoi() +"_QAplots.root").Data(),"RECREATE");
140 if((system.IsNull()) && (period.EndsWith("h"))) {system = "PbPb";}
143 TIter next(TriggersList);
144 while (TObject *obj = next())
146 fTrigger= TString(obj->GetName());
147 ret -= DrawOccupancy(RunId.Atoi(),period,pass,fTrigger,system,f,fout,geom,SavePlots);
148 ret -= DrawRun(RunId.Atoi(),period,pass,fTrigger,f,fout,SavePlots,nSM,filter);
150 ret-= TrendingEMCALTree(RunId.Atoi(),fCalorimeter,system,period,pass,nSM,TriggersList,f,fout,SavePlots);
160 //----------------------------------------------------------------------------------------------------------------------------------------------------------
161 Int_t DrawOccupancy(Long_t run , TString period, TString pass, TString fTrigger,TString system, TFile* f,TFile* fout, AliEMCALGeometry* geom, Int_t SavePlots)
165 gStyle->SetOptStat(0);
166 TH1::AddDirectory(kFALSE);
167 TH2D *hEnergyMapReal = new TH2D("hEnergyMapReal","",96,-48,48,120,-0,120);
168 TH2D *hOccupancyMapReal = new TH2D("hOccupancyMapReal","",96,-48,48,120,-0,120);
169 hEnergyMapReal->SetXTitle("eta (bin)");
170 hEnergyMapReal->SetYTitle("phi (bin)");
171 hEnergyMapReal->SetZTitle("E(GeV)/event");
172 hEnergyMapReal->GetYaxis()->SetTitleOffset(1.2);
173 hEnergyMapReal->GetZaxis()->SetLabelSize(0.02);
174 hEnergyMapReal->GetZaxis()->SetTitleOffset(1.36);
176 hOccupancyMapReal->SetXTitle("eta (bin)");
177 hOccupancyMapReal->SetYTitle("phi (bin)");
178 hOccupancyMapReal->GetYaxis()->SetTitleOffset(1.2);
179 hOccupancyMapReal->GetZaxis()->SetLabelSize(0.02);
181 Int_t nSupMod, nModule, nIphi, nIeta;
187 Int_t mask[1] = {2222222};
189 TH2F *hCellAmplitude;
195 if(!fTrigger.Contains("QA")) {
199 Bool_t dirok = f->cd(direct);
200 if (!dirok) { Error(__FUNCTION__,Form("No input drectory %s",direct.Data())); return -1;}
201 TList *outputList = (TList*)gDirectory->Get(direct);
202 if(!outputList){ Error(__FUNCTION__,"No input list! "); return -1;}
203 outputList->SetOwner();
205 fout->mkdir(Form("%s/%s/%ld/%s/%s",period.Data(),pass.Data(),run,"RunLevelQA",fTrigger.Data()));
207 fout->Cd(Form("%s/%s/%ld/%s/%s",period.Data(),pass.Data(),run,"RunLevelQA",fTrigger.Data()));
209 hNEvents =(TH1F *)outputList->FindObject("hNEvents");
210 if(!hNEvents){ Error(__FUNCTION__,Form("hNEvent histogram not found for trigger %s ",fTrigger.Data())); return -2;}
211 Events = (Int_t)hNEvents->GetEntries();
212 if(Events==0){ Error(__FUNCTION__,Form("No event in trigger %s",fTrigger.Data())); return -3;}
217 if (fTrigger.Contains("EMC")) Eth=20.;
221 if (fTrigger.Contains("EMC")) Eth=5.;
224 hCellAmplitude =(TH2F *)outputList->FindObject("EMCAL_hAmpId");
226 for(Int_t i = 0; i < geom->GetNCells() ; i++){
230 for (Int_t j = 1; j <= hCellAmplitude->GetNbinsX(); j++)
232 Double_t E = hCellAmplitude->GetXaxis()->GetBinCenter(j);
233 Double_t N = hCellAmplitude->GetBinContent(j, i+1);
235 if (E < 0.3) continue;
244 if(n!=0) {if(mask[n]<=mask[n-1]) Warning(__FUNCTION__,"The list of bad cells is not sorted !!");}
245 if(i==mask[n]){n++ ; continue; } // skip bad cells
247 geom->GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
248 geom->GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi,ieta);
250 realbinphi = 120-(nSupMod/2)*24 -iphi -1; //
251 if (nSupMod%2==0) realbineta= 48-ieta -1;
252 if (nSupMod%2==1) realbineta= -ieta -1;
254 hEnergyMapReal->Fill(realbineta,realbinphi,Esum/(Double_t)Events);
255 hOccupancyMapReal->Fill(realbineta,realbinphi,Nsum/(Double_t)Events);
258 cout <<" Run: " << run << " trigger: " << fTrigger << " N_events: "<<Events<<endl;
260 TPMERegexp r("_\\w+");
261 TString Energy; Energy = QAPATH + "MapEnergy" + fTrigger(r) + ".pdf";
262 TString Energy2; Energy2 = QAPATH + "MapEnergy" + fTrigger(r) + ".png";
263 TString Entries; Entries = QAPATH + "MapEntries" + fTrigger(r) + ".pdf";
264 TString Entries2; Entries2 = QAPATH + "MapEntries" + fTrigger(r) + ".png";
266 TCanvas *c1 = new TCanvas("Energymap","Energy Map",600,600);
269 c1->SetRightMargin(0.14);
270 TString title = "run ";
272 if(fTrigger.Contains("EMC")) { title += " EMC ";} else {title += " MB ";}
273 title += " Summed energy map";
274 hEnergyMapReal->SetTitle(title);
275 hEnergyMapReal->DrawCopy("colz");
276 if(SavePlots==2) c1->SaveAs(Energy);
277 if(SavePlots) c1->SaveAs(Energy2);
282 TCanvas *c2 = new TCanvas("Occupancy","Occupancy Map",600,600);
285 c2->SetRightMargin(0.14);
286 TString title2 = "run ";
288 if(fTrigger.Contains("EMC")) { title2 += " EMC ";} else { title2 += " MB ";}
289 title2 += " Occupancy map";
290 hOccupancyMapReal->SetTitle(title2);
291 hOccupancyMapReal->DrawCopy("colz");
292 if(SavePlots==2) c2->SaveAs(Entries);
293 if(SavePlots) c2->SaveAs(Entries2);
297 if (outputList) {outputList->Delete();}
299 delete hEnergyMapReal;
300 delete hOccupancyMapReal;
305 //-----------------------------------------------------------------------------------------------------------------------
306 Int_t DrawRun(const Long_t run, TString period, TString pass, TString fTrigger, TFile *f,TFile *fout, Int_t SavePlots, Int_t nSM, Bool_t kFilter)
310 if(!fTrigger.Contains("QA")) {
316 if(!direct) { Error(__FUNCTION__,Form("No input directory %s",direct.Data())); return -1;}
317 TList *outputList = (TList*)gDirectory->Get(direct);
318 if(!outputList){ Error(__FUNCTION__,Form("No input list! %s",direct.Data())); return -2;}
319 outputList->SetOwner();
322 fout->mkdir(Form("%s/%s/%ld/%s",period.Data(),pass.Data(),run,fTrigger.Data()));
324 fout->Cd(Form("%s/%s/%ld/%s",period.Data(),pass.Data(),run,fTrigger.Data()));
328 fout->Cd(Form("%s/%s/%ld/%s/%s",period.Data(),pass.Data(),run,"RunLevelQA",fTrigger.Data()));
332 gStyle->SetPalette(1);
333 TH1::AddDirectory(kFALSE);
335 TString outfilename2;
336 const char* legend="";
337 TPMERegexp r("_\\w+");
339 if (fTrigger.Contains("EMC")){ legend = Form(" Run %d EMC ",(int)run);}
340 else legend = Form(" Run %d MB ",(int)run);
342 TH1F* hNEvents =(TH1F *)outputList->FindObject("hNEvents");
343 if(!hNEvents){ Error(__FUNCTION__,Form("hNEvent histogram not found for trigger %s ",fTrigger.Data())); return -3;}
344 Int_t Events = (Int_t)hNEvents->GetEntries();
345 if(Events==0){ Error(__FUNCTION__,Form("No event in trigger %s",fTrigger.Data())); return -4 ;}
347 TCanvas* c1 = new TCanvas("TimeVsE", "Cluster Time Vs Energy", 600, 600);
350 c1->SetBorderSize(0);
351 c1->SetFrameBorderMode(0);
353 TH2F* hClusterTimeEnergy =(TH2F *)outputList->FindObject("EMCAL_hClusterTimeEnergy");
354 if(!hClusterTimeEnergy) { Error(__FUNCTION__,Form("EMCAL_hClusterTimeEnergy: Histogram for trigger %s not found!",fTrigger.Data())); return -5;}
355 FormatRunHisto(hClusterTimeEnergy,Form("Time Vs Energy%s",legend),"EMCAL ToF(ns)");
357 AutoZoom(hClusterTimeEnergy,"maxx")->DrawCopy("colz");
358 outfilename = QAPATH + "TimeRun" + fTrigger(r) + ".pdf" ;
359 outfilename2 = QAPATH + "TimeRun" + fTrigger(r) + ".png" ;
361 if(SavePlots==2) c1->SaveAs(outfilename);
362 if(SavePlots) c1->SaveAs(outfilename2);
366 TCanvas * c2 = new TCanvas("ClusterVsTrack ","Correlation calo Mult Vs Track Multiplicity", 600, 600);
369 c2->SetBorderSize(0);
370 c2->SetFrameBorderMode(0);
372 TH2F* hClusterVsTrack =(TH2F *)outputList->FindObject("EMCAL_hCaloTrackMNClusters");
373 FormatRunHisto(hClusterVsTrack,Form("N cluster Vs N track%s",legend));
375 AutoZoom(hClusterVsTrack,"maxx,maxy",1)->DrawCopy("colz");
376 outfilename = QAPATH + "CaloTrackMult" + fTrigger(r) + ".pdf";
377 outfilename2 = QAPATH + "CaloTrackMult" + fTrigger(r) + ".png";
378 if(SavePlots==2) c2->SaveAs(outfilename);
379 if(SavePlots) c2->SaveAs(outfilename2);
383 TCanvas* c3 = new TCanvas("ClusterEVsTrack ","Correlation E calo Vs Track Multiplicity", 600, 600);
386 c3->SetBorderSize(0);
387 c3->SetFrameBorderMode(0);
389 TH2F* hClusterEVsTrack =(TH2F*)outputList->FindObject("EMCAL_hCaloTrackMEClusters");
390 FormatRunHisto(hClusterEVsTrack,Form("Sum E cluster Vs N track%s",legend));
392 AutoZoom(hClusterEVsTrack,"maxx,maxy",1)->DrawCopy("colz");
393 outfilename = QAPATH + "ETrackMult" + fTrigger(r) + ".pdf";
394 outfilename2 = QAPATH + "ETrackMult" + fTrigger(r) + ".png";
395 if(SavePlots==2) c3->SaveAs(outfilename);
396 if(SavePlots) c3->SaveAs(outfilename2);
400 TCanvas* c4 = new TCanvas("ClusterEVsV0 ","Correlation E calo Vs V0 signal", 600, 600);
403 c4->SetBorderSize(0);
404 c4->SetFrameBorderMode(0);
406 TH2F* hClusterEVsV0S =(TH2F*)outputList->FindObject("EMCAL_hCaloV0SEClusters");
407 FormatRunHisto(hClusterEVsV0S,Form("Sum E cluster Vs V0 signal%s",legend));
409 AutoZoom(hClusterEVsV0S,"maxx,maxy",1)->DrawCopy("colz");
410 outfilename = QAPATH +"EVsV0s" + fTrigger(r) + ".pdf";
411 outfilename2 = QAPATH +"EVsV0s" + fTrigger(r) + ".png";
412 if(SavePlots==2) c4->SaveAs(outfilename);
413 if(SavePlots) c4->SaveAs(outfilename2);
417 TCanvas* c5 = new TCanvas("CellsperCluster","Nb of cells per cluster for each SM", 600, 600);
420 c5->SetBorderSize(0);
421 c5->SetFrameBorderMode(0);
422 Bool_t mod3=0; if (nSM%3) mod3=1;
423 c5->Divide(3,(nSM/3)+mod3);
425 for (int ism = 0; ism < nSM; ism++)
429 if(TString(Form("Nb of cells per cluster%s Mod %d",legend,ism)).Length() > 60) { Error(__FUNCTION__,"Title too long!"); return -6;}
430 AutoZoom(HistoPerMod((TH2F*)outputList->FindObject(Form("EMCAL_hNCellsPerCluster_Mod%i",ism)),Form("Nb of cells per cluster%s Mod %d",legend,ism)),"all",1)->DrawCopy("colz");
433 outfilename = QAPATH + "CellsperClusterSM" + fTrigger(r) + ".pdf";
434 outfilename2 = QAPATH + "CellsperClusterSM" + fTrigger(r) + ".png";
435 if(SavePlots==2) c5->SaveAs(outfilename);
436 if(SavePlots) c5->SaveAs(outfilename2);
440 if (outputList) outputList->Delete();
445 //----------------------------------------------------------------------------------------------------------------------------------
446 Int_t TrendingEMCALTree(Long_t RunId,TString fCalorimeter,TString system,TString period , TString pass,int n ,TList* TriggersList,TFile* f,TFile *fout, Int_t SavePlots)
450 TString aCalorimeter;
451 if (n<=12) {aCalorimeter = fCalorimeter;} else {aCalorimeter = TString("EMCAL_and_DCAL");}
459 Double_t ClusterMean=0;
460 Double_t ClusterRMS=0;
461 Double_t EtotalMean=0;
462 Double_t EtotalRMS=0;
464 Double_t CellPerClusterMean=0; //
465 Double_t CellPerClusterRMS=0; //
467 Double_t mPDG = 134.9766;
471 Double_t MeanPosErr=0;
474 Double_t Chi2NdfPi0=0;
477 Double_t Signif=0; // !S/(S+B)
478 Double_t SignifErr=0; // !S/(S+B)
480 TFile* ftree = new TFile(Form("%s/trending.root",QAPATH.Data()),"RECREATE");
482 TTree *tree = new TTree("trending","Trending QA Tree");
483 tree->Branch("fDate",&now);
484 tree->Branch("fCalorimeter",&aCalorimeter);
485 tree->Branch("system",&system);
486 tree->Branch("period",&period);
487 tree->Branch("pass",&pass);
488 tree->Branch("fTrigger",&fTrigger);
489 tree->Branch("run",&RunId,"run/I");
490 tree->Branch("xe",&xe,"xe/D");
492 tree->Branch("Nevent",&Nevent,"Nevent/D");
493 tree->Branch("CellMean",&CellMean,"CellMean/D");
494 tree->Branch("CellRMS",&CellRMS,"CellRMS/D");
495 tree->Branch("ClusterMean",&ClusterMean,"ClusterMean/D");
496 tree->Branch("ClusterRMS",&ClusterRMS,"ClusterRMS/D");
497 tree->Branch("EtotalMean",&EtotalMean,"EtotalMean/D");
498 tree->Branch("EtotalRMS",&EtotalRMS,"EtotalRMS/D");
500 tree->Branch("CellPerClusterMean",&CellPerClusterMean,"CellPerClusterMean/D"); //
501 tree->Branch("CellPerClusterRMS",&CellPerClusterRMS,"CellPerClusterRMS/D"); //
503 tree->Branch("Npi0",&Npi0,"Npi0/D");
504 tree->Branch("Npi0Err",&Npi0Err,"Npi0Err/D");
505 tree->Branch("MeanPos",&MeanPos,"MeanPos/D");
506 tree->Branch("MeanPosErr",&MeanPosErr,"MeanPosErr/D");
507 tree->Branch("Width",&Width,"Width/D");
508 tree->Branch("WidthErr",&WidthErr,"WidthErr/D");
509 tree->Branch("Chi2NdfPi0",&Chi2NdfPi0,"Chi2NdfPi0/D");
510 tree->Branch("Ngg",&Ngg,"Ngg/D");
511 tree->Branch("NggErr",&NggErr,"NggErr/D");
512 tree->Branch("Signif",&Signif,"Signif/D");
513 tree->Branch("SignifErr",&SignifErr,"SignifErr/D");
515 tree->Branch("nSM",&n,"nSM/I");
518 Double_t CellMeanSM[nMax];
519 Double_t CellRMSSM[nMax];
520 Double_t ClusterMeanSM[nMax];
521 Double_t ClusterRMSSM[nMax];
522 Double_t EtotalMeanSM[nMax]; //mean total energy deposited per event
523 Double_t EtotalRMSSM[nMax];
524 Double_t CellPerClusterMeanSM[nMax];
525 Double_t CellPerClusterRMSSM[nMax];
526 Double_t ECell1MeanSM[nMax]; //total energy deposited per event without 1 cell clusters
527 Double_t ECell1RMSSM[nMax];
529 Double_t MeanPosSM[nMax];
530 Double_t MeanPosErrSM[nMax];
531 Double_t WidthSM[nMax];
532 Double_t WidthErrSM[nMax];
533 Double_t Npi0SM[nMax];
534 Double_t Npi0ErrSM[nMax];
536 tree->Branch("CellMeanSM",CellMeanSM,TString::Format("CellMeanSM[%i]/D",nMax));
537 tree->Branch("CellRMSSM",CellRMSSM,TString::Format("CellRMSSM[%i]/D",nMax));
538 tree->Branch("ClusterMeanSM",ClusterMeanSM,TString::Format("ClusterMeanSM[%i]/D",nMax));
539 tree->Branch("ClusterRMSSM",ClusterRMSSM,TString::Format("ClusterRMSSM[%i]/D",nMax));
540 tree->Branch("EtotalMeanSM",EtotalMeanSM,TString::Format("EtotalMeanSM[%i]/D",nMax));
541 tree->Branch("EtotalRMSSM",EtotalRMSSM,TString::Format("EtotalRMSSM[%i]/D",nMax));
542 tree->Branch("CellPerClusterMeanSM",CellPerClusterMeanSM,TString::Format("CellPerClusterMeanSM[%i]/D",nMax));
543 tree->Branch("CellPerClusterRMSSM",CellPerClusterRMSSM,TString::Format("CellPerClusterRMSSM[%i]/D",nMax));
544 tree->Branch("ECell1MeanSM",ECell1MeanSM,TString::Format("ECell1MeanSM[%i]/D",nMax));
545 tree->Branch("ECell1RMSSM",ECell1RMSSM,TString::Format("ECell1RMSSM[%i]/D",nMax));
547 tree->Branch("MeanPosSM",MeanPosSM,TString::Format("MeanPosSM[%i]/D",nMax));
548 tree->Branch("MeanPosErrSM",MeanPosErrSM,TString::Format("MeanPosErrSM[%i]/D",nMax));
549 tree->Branch("WidthSM",WidthSM,TString::Format("WidthSM[%i]/D",nMax));
550 tree->Branch("WidthErrSM",WidthErrSM,TString::Format("WidthErrSM[%i]/D",nMax));
551 tree->Branch("Npi0SM",Npi0SM,TString::Format("Npi0SM[%i]/D",nMax));
552 tree->Branch("Npi0ErrSM",Npi0ErrSM,TString::Format("Npi0ErrSM[%i]/D",nMax));
554 TF1* fitMass = new TF1("fitMass",pi0massP2,100,250,6);
555 fitMass->SetParName(0,"A");
556 fitMass->SetParName(1,"m_{0}");
557 fitMass->SetParName(2,"sigma");
558 fitMass->SetParName(3,"a_{0}");
559 fitMass->SetParName(4,"a_{1}");
560 fitMass->SetParName(5,"a_{2}");
561 fitMass->SetParLimits(0, 1.e-5,1.e5);
562 fitMass->SetParLimits(1, 0.11, 0.16); //
563 fitMass->SetParLimits(2, 0.001,0.06);
569 TH1F* fhNClusters = 0x0;
570 TH1F* fhNCells = 0x0;
574 TH2F* NCellsPerCluster[n];
582 TPMERegexp r("_\\w+");
583 TIter next(TriggersList);
585 while (TObject *obj = next())
587 fTrigger= TString(obj->GetName());
588 TString namefile = QAPATH + period + "_" + pass + fTrigger(r).Data() + "_" + RunId + "_data.txt";
589 ofstream QAData(namefile, ios::app); // write checks at the end
603 memset (CellMeanSM, 0, sizeof (Double_t) * nMax);
604 memset (CellRMSSM, 0, sizeof (Double_t) * nMax);
605 memset (ClusterMeanSM, 0, sizeof (Double_t) * nMax);
606 memset (ClusterRMSSM, 0, sizeof (Double_t) * nMax);
607 memset (EtotalMeanSM, 0, sizeof (Double_t) * nMax);
608 memset (EtotalRMSSM, 0, sizeof (Double_t) * nMax);
609 memset (CellPerClusterMeanSM, 0, sizeof (Double_t) * nMax);
610 memset (CellPerClusterRMSSM, 0, sizeof (Double_t) * nMax);
611 memset (ECell1MeanSM, 0, sizeof (Double_t) * nMax);
612 memset (ECell1RMSSM, 0, sizeof (Double_t) * nMax);
614 memset (MeanPosSM, 0, sizeof (Double_t) * nMax);
615 memset (MeanPosErrSM, 0, sizeof (Double_t) * nMax);
616 memset (WidthSM, 0, sizeof (Double_t) * nMax);
617 memset (WidthErrSM, 0, sizeof (Double_t) * nMax);
618 memset (Npi0SM, 0, sizeof (Double_t) * nMax);
619 memset (Npi0ErrSM, 0, sizeof (Double_t) * nMax);
622 if(!fTrigger.Contains("QA")) {
627 Bool_t dirok = f->cd(dirname);
628 if(!dirok) { Error(__FUNCTION__,Form("No input directory %s",dirname.Data())); tree->Fill(); ftree->cd(); tree->Write(); ret= -1; continue;}
629 outputList = (TList*)gDirectory->Get(dirname);
630 if(!outputList){ Error(__FUNCTION__,Form("No input list! %s",dirname.Data())); tree->Fill(); ftree->cd(); tree->Write(); ret=-2; continue;;}
631 outputList->SetOwner();
634 fhNEvents =(TH1F *)outputList->FindObject("hNEvents");
635 if(!fhNEvents){ Error(__FUNCTION__,Form("NEvent histogram not found for trigger %s",fTrigger.Data())); tree->Fill(); ftree->cd(); tree->Write(); ret=-3; continue;}
636 Nevent=fhNEvents->GetEntries();
637 if(Nevent==0) {Error(__FUNCTION__,Form("No event in trigger %s",fTrigger.Data())); tree->Fill(); ftree->cd(); tree->Write(); ret=-4; continue;}
638 if(Nevent<20) {Error(__FUNCTION__,Form("Less than 20 events in trigger %s",fTrigger.Data())); tree->Fill(); ftree->cd(); tree->Write(); ret=-5; continue;}
640 // first do clusters trending
641 fhE = (TH1F *)outputList->FindObject(fCalorimeter+"_hE");
642 Double_t energy = 0. ;
644 for(Int_t ibin = fhE->FindBin(0.6) ; ibin <fhE->FindBin(50.) ; ibin++){
645 energy+=fhE->GetBinCenter(ibin)*fhE->GetBinContent(ibin);
647 if(fhE->Integral(fhE->FindBin(0.6), fhE->FindBin(50.))==0){Error(__FUNCTION__,Form("Not enough events")); tree->Fill(); ftree->cd(); tree->Write(); ret=-6; continue;}
648 EtotalMean=energy/fhE->Integral(fhE->FindBin(0.6), fhE->FindBin(50.)) ;
649 EtotalRMS=fhE->GetMeanError();
651 TString nameNCell = Form("%s_hNCells_Mod",fCalorimeter.Data());
652 TString nameNCluster = Form("%s_hNClusters_Mod",fCalorimeter.Data());
653 TString nameE = Form("%s_hE_Mod",fCalorimeter.Data());
654 TH2F* hNCellsMod= (TH2F*)outputList->FindObject(nameNCell.Data());
655 TH2F* hNClusterMod=(TH2F*)outputList->FindObject(nameNCluster.Data());
656 TH2F* hEMod=(TH2F*)outputList->FindObject(nameE.Data());
658 if (!hNCellsMod || !hNClusterMod || !hEMod) {Error(__FUNCTION__,"A requiered histogram was not found (the imput QAresult.root might be too old)!"); tree->Fill(); ftree->cd(); tree->Write(); ret=-7; continue;}
660 TCanvas* c1 = new TCanvas("Pi0InvMassSM","Pi0 Invariant Mass for each SM", 600, 600);
662 c1->SetBorderSize(0);
663 c1->SetFrameBorderMode(0);
664 Bool_t mod3=0; if (n%3) mod3=1;
665 c1->Divide(3,n/3+mod3);
668 TString nameNCellPerCluster;
669 for(Int_t ism = 0 ; ism < n ; ism++){
670 cout << "#########################"<< endl;
671 cout << " Super Module " << ism << " Run " << RunId << endl;
672 // first do clusters trending
673 nameNCellPerCluster = Form("%s_hNCellsPerCluster_Mod%d",fCalorimeter.Data(),ism);
674 NCellsPerCluster[ism] = (TH2F*)outputList->FindObject(nameNCellPerCluster.Data());
675 if(! (TH2F*)outputList->FindObject(nameNCellPerCluster.Data()) ) { Error(__FUNCTION__,Form("NCellsPerCluster histogram not found for super module %i",ism));ret=-8; continue;}
676 NCellsPerCluster[ism] = (TH2F*)outputList->FindObject(nameNCellPerCluster.Data());
678 NCells[ism] = (TH1F*)hNCellsMod->ProjectionX(Form("NCells%d",ism),ism+1,ism+2,"");
679 NClusters[ism] = (TH1F*)hNClusterMod->ProjectionX(Form("NClusters%d",ism),ism+1,ism+2,"");
680 E[ism] = (TH1F*)hEMod->ProjectionX(Form("E%d",ism),ism+1,ism+2,"");
681 CellMeanSM[ism]=NCells[ism]->GetMean();
682 CellRMSSM[ism]=NCells[ism]->GetMeanError();
683 ClusterMeanSM[ism]=NClusters[ism]->GetMean();
684 ClusterRMSSM[ism]=NClusters[ism]->GetMeanError();
685 CellPerClusterMeanSM[ism]=NCellsPerCluster[ism]->GetMean(2);
686 CellPerClusterRMSSM[ism]=NCellsPerCluster[ism]->GetMeanError(2);
688 ECell1MeanSM[ism] =NCellsPerCluster[ism]->ProjectionX("",2,50,"")->Integral(5,50)/(Nevent);
689 ECell1RMSSM[ism] =NCellsPerCluster[ism]->ProjectionX("",2,50,"")->GetMeanError();
690 Double_t energySM = 0. ;
691 for(Int_t ibin = E[ism]->FindBin(0.6) ; ibin <E[ism]->FindBin(50.) ; ibin++){
692 energySM+=E[ism]->GetBinCenter(ibin)*(E[ism]->GetBinContent(ibin));
694 if(E[ism]->Integral(E[ism]->FindBin(0.6),E[ism]->FindBin(50.))==0){Error(__FUNCTION__,Form("Energy: Not enough events/SM")); continue;}
695 EtotalMeanSM[ism]=energySM/(E[ism]->Integral(E[ism]->FindBin(0.6),E[ism]->FindBin(50.)));
697 EtotalRMSSM[ism]=E[ism]->GetMeanError();
700 fhNCells = (TH1F*)NCells[ism]->Clone("NCells");
701 fhNClusters = (TH1F*)NClusters[ism]->Clone("NClusters");
704 fhNCells->Add(NCells[ism],1);
705 fhNClusters->Add(NClusters[ism],1);
710 TString namePair = Form("%s_hIM_Mod%d",fCalorimeter.Data(),ism);
711 IM[ism] = (TH2F*)outputList->FindObject(namePair.Data());
714 TString projname = Form("SM_%d",ism);
715 MggSM[ism] = (TH1F *)IM[ism]->ProjectionY(projname.Data(), 2, 150, "") ;
718 if(MggSM[ism]->GetEntries()>100) {
719 fitMass->SetParameter(0, MggSM[ism]->GetBinContent(MggSM[ism]->GetMaximumBin()));
720 fitMass->SetParameter(1, mPDG); //
721 fitMass->SetParameter(2, 15.); //
722 fitMass->SetParameter(3,0.);
723 fitMass->SetParameter(4,MggSM[ism]->GetBinContent(MggSM[ism]->FindBin(0.11)));
724 fitMass->SetParameter(5,MggSM[ism]->GetBinContent(MggSM[ism]->FindBin(0.20)));
726 if(MggSM[ism]->GetEntries()<1000){ MggSM[ism]->Rebin(4);} else {MggSM[ism]->Rebin();}
727 MggSM[ism]->Fit("fitMass", "WL R +","",0.05, 0.30);
728 MggSM[ism]->SetTitle(Form("Pi0 Mass for super module %i",ism));
729 MggSM[ism]->SetTitleSize(0.1);
730 MggSM[ism]->SetXTitle("Pi0 Mass");
731 MggSM[ism]->SetYTitle("Nb of entries");
732 MggSM[ism]->GetXaxis()->SetLabelSize(0.05);
733 MggSM[ism]->GetXaxis()->SetTitleSize(0.07);
734 MggSM[ism]->GetXaxis()->SetTitleOffset(0.68);
735 MggSM[ism]->GetYaxis()->SetLabelSize(0.05);
736 MggSM[ism]->GetYaxis()->SetTitleSize(0.06);
737 MggSM[ism]->GetYaxis()->SetTitleOffset(0.78);
739 MeanPosSM[ism] = MggSM[ism]->GetFunction("fitMass")->GetParameter(1)*1000;
740 MeanPosErrSM[ism] = MggSM[ism]->GetFunction("fitMass")->GetParError(1)*1000;
741 WidthSM[ism] = MggSM[ism]->GetFunction("fitMass")->GetParameter(2)*1000;
742 WidthErrSM[ism] = MggSM[ism]->GetFunction("fitMass")->GetParError(2)*1000;
743 Npi0SM[ism] = MggSM[ism]->GetFunction("fitMass")->GetParameter(0)*(MggSM[ism]->GetFunction("fitMass")->GetParameter(2))*TMath::Sqrt(2*TMath::Pi())/(Nevent*MggSM[ism]->GetBinWidth(1));
744 Npi0ErrSM[ism] = TMath::Sqrt((MggSM[ism]->GetFunction("fitMass")->GetParError(0)/MggSM[ism]->GetFunction("fitMass")->GetParameter(0))*(MggSM[ism]->GetFunction("fitMass")->GetParError(0)/MggSM[ism]->GetFunction("fitMass")->GetParameter(0))
745 +(MggSM[ism]->GetFunction("fitMass")->GetParError(2)/MggSM[ism]->GetFunction("fitMass")->GetParameter(2))*(MggSM[ism]->GetFunction("fitMass")->GetParError(2)/MggSM[ism]->GetFunction("fitMass")->GetParameter(2)));
746 Npi0ErrSM[ism] = 0.; //
748 }// end if enough events for Pi0 fit and trending
749 else { Info(__FUNCTION__,Form("Not enough events for Pi0 fit and trending for super module %i",ism));} ;
752 // Now Pi0 global trending
753 TCanvas* c2 = new TCanvas("Pi0InvMass","Pi0 Invariant Mass", 600, 600);
755 c2->SetBorderSize(0);
756 c2->SetFrameBorderMode(0);
758 fhIM = (TH2F *)outputList->FindObject(fCalorimeter+"_hIM");
760 fhMgg = (TH1F *)fhIM->ProjectionY("Mgg", 2, 150, "") ;
761 if(fhMgg->GetEntries()==0) {Error(__FUNCTION__,"The Pi0 histogram is empty !"); tree->Fill(); ret=-8; continue;}
762 fitMass->SetParameter(0, 4500);
763 fitMass->SetParameter(1, mPDG);
764 fitMass->SetParameter(2, 0.01);
765 fitMass->SetParameter(3,0.);
766 fitMass->SetParameter(4,fhMgg->GetBinContent(fhMgg->FindBin(0.11)));
767 fitMass->SetParameter(5,fhMgg->GetBinContent(fhMgg->FindBin(0.20)));
769 if(fhMgg->GetEntries()<5000){
773 fhMgg->Fit("fitMass", "L R +", "", 0.05, 0.20);
775 fhMgg->SetTitle("Pi0 Mass");
776 fhMgg->SetTitleSize(0.1);
777 fhMgg->SetXTitle("Pi0 Mass");
778 fhMgg->SetYTitle("Nb of entries");
779 fhMgg->GetXaxis()->SetLabelSize(0.03);
780 fhMgg->GetXaxis()->SetTitleSize(0.03);
781 fhMgg->GetXaxis()->SetTitleOffset(1.3);
782 fhMgg->GetYaxis()->SetLabelSize(0.03);
783 fhMgg->GetYaxis()->SetTitleSize(0.03);
784 fhMgg->GetYaxis()->SetTitleOffset(1.3);
786 MeanPos = fhMgg->GetFunction("fitMass")->GetParameter(1)*1000;
787 MeanPosErr = fhMgg->GetFunction("fitMass")->GetParError(1)*1000;
788 Width = fhMgg->GetFunction("fitMass")->GetParameter(2)*1000;
789 WidthErr = fhMgg->GetFunction("fitMass")->GetParError(2)*1000;
790 Chi2NdfPi0 = fhMgg->GetFunction("fitMass")->GetChisquare()/fhMgg->GetFunction("fitMass")->GetNDF();
791 Npi0 = fhMgg->GetFunction("fitMass")->GetParameter(0)*fhMgg->GetFunction("fitMass")->GetParameter(2)*TMath::Sqrt(2*TMath::Pi())/(Nevent*fhMgg->GetBinWidth(10));
792 Npi0Err = TMath::Sqrt((fhMgg->GetFunction("fitMass")->GetParError(0)/fhMgg->GetFunction("fitMass")->GetParameter(0))*(fhMgg->GetFunction("fitMass")->GetParError(0)/fhMgg->GetFunction("fitMass")->GetParameter(0))+(WidthErr/Width)*(WidthErr/Width));
794 Ngg = fhMgg->GetFunction("fitMass")->Integral(0.11, 0.16)/(Nevent*fhMgg->GetBinWidth(10));
795 NggErr = fhMgg->GetFunction("fitMass")->IntegralError(0.11, 0.16)/(fhMgg->Integral()*fhMgg->GetBinWidth(10));
797 SignifErr = TMath::Sqrt((Npi0Err/Npi0*(Npi0Err/Npi0)+(NggErr/Ngg*(NggErr/Ngg))));
798 SignifErr = Signif*SignifErr;
800 cout<<"******************"<<endl;
801 //end of global trending
803 ClusterMean=fhNClusters->GetMean();
804 ClusterRMS=fhNClusters->GetMeanError();
805 CellMean=fhNCells->GetMean();
806 CellRMS=fhNCells->GetMeanError();
809 TString outfilename = QAPATH + "Pi0InvMass" + fTrigger(r) + ".pdf";
810 TString outfilename2 = QAPATH + "Pi0InvMass" + fTrigger(r) + ".png";
811 if(SavePlots==2) c2->SaveAs(outfilename);
812 if(SavePlots) c2->SaveAs(outfilename2);
814 outfilename = QAPATH + "Pi0InvMassSM" + fTrigger(r) + ".pdf";
815 outfilename2 = QAPATH + "Pi0InvMassSM" + fTrigger(r) + ".png";
816 if(SavePlots==2) c1->SaveAs(outfilename);
817 if(SavePlots) c1->SaveAs(outfilename2);
820 fout->Cd(Form("%s/%s/%ld/%s/%s",period.Data(),pass.Data(),RunId,"RunLevelQA",fTrigger.Data()));
825 if (outputList) outputList->Delete() ;
827 QAData << RunId<<" "<< Nevent
842 //-------------------------------------------------------------------------
843 TH2F* FormatRunHisto(TH2F* aHisto,const char* title,const char* YTitle)
846 if(!aHisto) {Error(__FUNCTION__,Form("The histogram with title \"%s\" was not found!",title)); return new TH2F();}
847 aHisto->SetStats(kFALSE);
848 aHisto->SetTitle(title);
849 aHisto->SetStats(kFALSE);
850 aHisto->SetYTitle(YTitle);
851 aHisto->GetYaxis()->SetTitleOffset(1.2);
852 aHisto->GetYaxis()->SetLabelSize(0.03);
853 aHisto->GetZaxis()->SetLabelSize(0.02);
859 //--------------------------------------------------------------------------------------------------------------
860 TH2F* HistoPerMod(TH2F* hTmpPerMod,const char* title)
863 if(!hTmpPerMod) {Error(__FUNCTION__,Form("The histogram with title \"%s\" was not found!",title)); return new TH2F();}
864 hTmpPerMod->SetStats(kFALSE);
865 hTmpPerMod->SetTitle(title);
866 hTmpPerMod->SetTitleSize(0.1);
867 hTmpPerMod->GetXaxis()->SetTitleOffset(1.1);
868 hTmpPerMod->GetXaxis()->SetTitleSize(0.05);
869 hTmpPerMod->GetXaxis()->SetLabelSize(0.06);
870 hTmpPerMod->GetYaxis()->SetTitleOffset(1.1);
871 hTmpPerMod->GetYaxis()->SetTitleSize(0.05);
872 hTmpPerMod->GetYaxis()->SetLabelSize(0.06);
873 hTmpPerMod->GetZaxis()->SetLabelSize(0.04);
879 //---------------------------------------------------------------------------------------------------
880 TH2F* AutoZoom(TH2F* H,Option_t* aType, Int_t EntryMin)
883 Int_t shiftX = (Int_t)(H->GetNbinsX()/30.);
884 Int_t shiftY = (Int_t)(H->GetNbinsY()/30.);
890 int maxX = H->GetNbinsX();
895 int maxY = H->GetNbinsY();
899 if (opt.Contains("all")) opt = TString("minx,maxx,miny,maxy");
901 if (opt.Contains("maxx"))
904 for (New_maxX = maxX;New_maxX >=minX; New_maxX--)
906 for (int i_y = maxY; i_y >= minY;i_y--)
907 { c = H->GetBinContent(New_maxX,i_y); if (c>EntryMin) break;}
908 if (c>EntryMin) break;
912 if (opt.Contains("maxy"))
915 for (New_maxY = maxY;New_maxY >=minY;New_maxY--)
917 for (int i_x=maxX; i_x>=minX;i_x--)
918 { c = H->GetBinContent(i_x, New_maxY ); if (c>EntryMin) break;}
919 if (c>EntryMin) break;
924 if (opt.Contains("minx"))
927 for (New_minX = minX;New_minX <=maxX; New_minX++)
929 for (int i_y = minY; i_y <= maxY;i_y++)
930 { c = H->GetBinContent(New_minX,i_y); if (c>EntryMin) break;}
931 if (c>EntryMin) break;
935 if (opt.Contains("miny"))
937 for (New_minY = minY;New_minY <=maxY;New_minY++)
939 for (int i_x=minX; i_x<=maxX;i_x++)
940 { c = H->GetBinContent(i_x, New_minY ); if (c>EntryMin) break;}
941 if (c>EntryMin) break;
945 if (New_maxX!=-1 && New_maxY!=-1) H->GetXaxis()->SetRange(New_minX - shiftX , New_maxX + shiftX);
946 if (New_maxX!=-1 && New_maxY!=-1) H->GetYaxis()->SetRange(New_minY - shiftY , New_maxY + shiftY);
952 //----------------------------------------------------------------------------------------------------
953 int FindNumberOfSM(TFile* f, TString fTrigger, TString period)
957 if(!fTrigger.Contains("QA")) {
963 Int_t year = 2000 + TString(period(3,2)).Atoi();
964 if ( year == 2010 ) { nSMt=6; }
965 else if ( year == 2011 || year == 2012 ) { nSMt=10; }
966 else if ( year == 2013 || year == 2014 ) { nSMt=12; }
970 Bool_t dirok = f->cd(direct);
971 if (!dirok) { Error(__FUNCTION__,Form("No input directory %s, the number SMs will be returned based on the year!",direct.Data()));}
972 else { outputList = (TList*)gDirectory->Get(direct);}
973 if(!outputList) { Error(__FUNCTION__,"No input list, the number SMs will be returned based on the year! ");}
975 outputList->SetOwner();
976 TH2F* hNSM =(TH2F *)outputList->FindObject("EMCAL_hE_Mod");
977 if (!hNSM || (!hNSM->GetEntries())) { Error(__FUNCTION__,"hNSM Histogram not found or it is empty, the number SMs will be returned based on the year!");}
979 nSMt = hNSM->GetYaxis()->GetBinUpEdge(hNSM->FindLastBinAbove(0,2));
982 if (outputList) {outputList->Delete();}