diff --git a/Software/Monitoring/Makefile b/Software/Monitoring/Makefile index 5921a0a..2d08751 100755 --- a/Software/Monitoring/Makefile +++ b/Software/Monitoring/Makefile @@ -22,13 +22,16 @@ CXXFLAGS += -D OSX endif -all: PlotTrends +all: PlotTrends PlotCooling PlotTrends: PlotTrends.C c++ -I$(OPT) $(CXXFLAGS) $(ROOTC) -o $@ $^ $(LDLIBS) $(ROOTL) $(gliblibs) +PlotCooling: PlotCooling.C + c++ -I$(OPT) $(CXXFLAGS) $(ROOTC) -o $@ $^ $(LDLIBS) $(ROOTL) $(gliblibs) clean: rm -f *.o PlotTrends + rm -f *.o PlotCooling rm -rf *.dSYM diff --git a/Software/Monitoring/PlotCooling.C b/Software/Monitoring/PlotCooling.C new file mode 100644 index 0000000..333d1cc --- /dev/null +++ b/Software/Monitoring/PlotCooling.C @@ -0,0 +1,529 @@ +//************************************************ +// Author: Federica Lionetto +// Created on: 07/12/2015 +//************************************************ + +/* + + PlotCooling creates a ROOT file with the trends of the temperature measured by the theromostat sensor and the temperature measured by the Sensirion sensor (close to the silicon sensor). + + Compile with: + + make + + Run with: + + ./PlotCooling [sensor] [from] [to] [additional folder] + + where + + - [sensor] is the type of sensor (Hans410, ...); + - [from] is the optional starting time from which one wants to display the trends, according to the "ddd mmm d hh:mm:ss yyyy" format; + - [to] is the optional stopping time to which one wants to display the trends, according to the "ddd mmm d hh:mm:ss yyyy" format; + - [additional folder] is the optional additional folder where the output will be saved. + + For example: + + ./PlotCooling Hans320 + + or + + ./PlotCooling Hans320 "Thu Apr 9 16:55:00 2015" "Thu Apr 9 16:55:52 2015" + + A folder named AnalysisResults will be created in a fixed location and a ROOT file will be saved in there. A folder named Figures will be created inside the folder named AnalysisResults, with some monitoring plots. + + If needed, an additional folder can be specified, that will be created inside the folder named AnalysisResults. + */ + +#include "../Tools/Lib.C" +#include "../Tools/UsefulFunctions.C" +#include "../Tools/lhcbStyle.C" +#include "../Tools/Style.C" + +#include "../Tools/Par.C" + +void PlotCooling(char *sensor, char *from=0, char *to=0, char *externalPath=0); + +vector SelectFiles(string inputDirectory, vector list_of_files, time_t t_from, time_t t_to); + + + +int main(int argc, char *argv[]) +{ + getLHCbStyle(); + PersonalStyle(); + + if ((argc ==2) && (string(argv[1]) == "--info")) + { + cout << "**************************************************" << endl; + + cout << "PlotCooling creates a ROOT file with the trends of the temperature measured by the theromostat sensor and the temperature meas ured by the Sensirion sensor (close to the silicon sensor)." << endl; + + cout << "Compile with:" << endl; + + cout << "make" << endl; + + cout << "Run with:" << endl; + + cout << "./PlotCooling [sensor] [from] [to] [additional folder]" << endl; + + cout << "where" << endl; + + cout << "- [sensor] is the type of sensor (Hans410, ...);" << endl; + cout << "- [from] is the optional starting time from which one wants to display the trends, according to the 'ddd mmm d hh:mm:ss yyyy' format;" << endl; + cout << "- [to] is the optional stopping time to which one wants to display the trends, according to the 'ddd mmm d hh:mm:ss yyyy' format;" << endl; + cout << "- [additional folder] is the optional additional folder where the output will be saved." << endl; + + cout << "For example:" << endl; + + cout << "./PlotCooling Hans320" << endl; + + cout << "or" << endl; + + cout << "./PlotCooling Hans320 'Thu Apr 9 16:55:00 2015' 'Thu Apr 9 16:55:52 2015'" << endl; + + cout << "A folder named AnalysisResults will be created in a fixed location and a ROOT file will be saved in there. A folder named Figures will be created inside the folder named AnalysisResults, with some monitoring plots." << endl; + + cout << "If needed, an additional folder can be specified, that will be created inside the folder named AnalysisResults." << endl; + + cout << "**************************************************" << endl; + + return 0; + } + else if (argc < 2) + { + cout << "**************************************************" << endl; + + cout << "Error! Input information missing..." << endl; + cout << "Please use the following format:" << endl; + cout << "./PlotCooling [1] [2] [3] [4]" << endl; + cout << "with:" << endl; + cout << "[1] = Type of sensor (Hans410, ...);" << endl; + cout << "[2] = Starting time, optional;" << endl; + cout << "[3] = Stopping time, optional;" << endl; + cout << "[4] = Additional folder, optional." << endl; + cout << "Type ./PlotCooling --info for more information." << endl; + + cout << "**************************************************" << endl; + + return 0; + } + else + { + cout << "Type of sensor: " << argv[1] << endl; + if (argc == 2) + PlotCooling(argv[1]); + else if (argc == 3) + { + cout << "**************************************************" << endl; + + cout << "Error! Stopping time not specified..." << endl; + + cout << "**************************************************" << endl; + + return 0; + } + else if (argc == 4) + { + cout << "Starting time: " << argv[2] << endl; + cout << "Stopping time: " << argv[3] << endl; + PlotCooling(argv[1],argv[2],argv[3]); + } + else if (argc == 5) + { + cout << "Staring time: " << argv[2] << endl; + cout << "Stopping time: " << argv[3] << endl; + cout << "Additional folder: " << argv[4] << endl; + PlotCooling(argv[1],argv[2],argv[3],argv[4]); + } + else + { + cout << "Error! Too many arguments given..." << endl; + + return 0; + } + + return 0; + } +} + +void PlotCooling(char *sensor, char *from, char *to, char *externalPath) +{ + cout << "**************************************************" << endl; + cout << "Plotting trends..." << endl; + cout << "**************************************************" << endl; + + // Do not comment this line. + gROOT->ProcessLine("#include "); + + string funName = "PlotCooling"; + + // Adjust time format for output ROOT file and figures. + string s_from = ""; + string s_to = ""; + + struct tm tm_from; + time_t t_from; + + struct tm tm_to; + time_t t_to; + + if ((from != 0) && (to != 0)) + { + s_from = string(from); + s_to = string(to); + + // Remove white spaces from s_from and s_to. + s_from.erase(remove(s_from.begin(), s_from.end(), ' '), s_from.end()); + s_to.erase(remove(s_to.begin(), s_to.end(), ' '), s_to.end()); + + // Convert the string with date and time to something that is interpreted as date and time. tm_from is a tm object, t_from is a time_t object and corresponds to the number of seconds since epoch. The format specifier %c stands for date and time representation. + + memset(&tm_from, 0, sizeof(struct tm)); + strptime(from,"%c",&tm_from); + t_from = mktime(&tm_from); + + /* + cout << tm_from.tm_year << endl; + cout << t_from << endl; + */ + + memset(&tm_to, 0, sizeof(struct tm)); + strptime(to,"%c",&tm_to); + t_to = mktime(&tm_to); + + /* + cout << tm_to.tm_year << endl; + cout << t_to << endl; + */ + + // Check that the starting time is earlier than the stopping time. + if (t_from >= t_to) + { + cout << "Error! Starting time earlier than stopping time..." << endl; + return; + } + } + + // Do some fanciness to get the directory right. + string inputDirectory = "/disk/groups/hep/flionett/TestStand/Data/"+string(sensor)+"/Cooling"; + string outputDirectory = "/disk/groups/hep/flionett/TestStand/AnalysisResults/"+string(sensor)+"/Cooling"; + if (externalPath!=0) + outputDirectory = string(outputDirectory+"/"+externalPath); + cout << "The input directory is: " << inputDirectory << endl; + cout << "The output directory is: " << outputDirectory << endl; + + // Create the outputDirectory directory if it does not exist. + string path_to_make = "mkdir -p "+outputDirectory; + system(path_to_make.c_str()); + + cout << "Figures stored in: " << outputDirectory+"/Figures" << endl; + + // Create a directory named Figures inside the directory named outputDirectory if it does not exist. + string path_to_make_figures = "mkdir -p "+outputDirectory+"/Figures"; + if ((from != 0) && (to != 0)) + path_to_make_figures = path_to_make_figures+"/"+funName+"-from"+s_from+"to"+s_to; + else + path_to_make_figures = path_to_make_figures+"/"+funName+"-all"; + system(path_to_make_figures.c_str()); + + TString path_to_figures = (string(path_to_make_figures)).substr((string(path_to_make_figures)).find_last_of(' ')+1); + + + + TDatime *time; + vector vtime; + + double TSi; + vector vTSi; + + double TTh; + vector vTTh; + + string trash1; + string trash2; + string trash3; + string trash4; + string trash5; + + // Given starting and stopping time, find the corresponding input text files. + vector list_of_files; + vector list_of_selected_files; + + list_of_files = open(inputDirectory); + if ((from != 0) && (to != 0)) + list_of_selected_files = SelectFiles(inputDirectory, list_of_files, t_from, t_to); + else + list_of_selected_files = list_of_files; + + if (list_of_selected_files.size() == 0) { + cout << "Error! No input text file selected..." << endl; + return; + } + + ifstream file; + string header; + string line; + struct tm tm_time_in_line; + time_t t_time_in_line; + + // Read data from selected input text files. + for (vector::const_iterator i = list_of_selected_files.begin(); i != list_of_selected_files.end(); ++i) + { + // Open file. + cout << "Selected input text file #" << i-list_of_selected_files.begin() << ": " << *i << endl; + file.open((inputDirectory+"/"+*i).c_str()); + if (file.is_open()) + { + // cout << "Great! File opened..." << endl; + + // Skip header. + if (getline(file,header)) + { + // Read time in each line. + while (getline(file,line)) + { + memset(&tm_time_in_line, 0, sizeof(struct tm)); + strptime(line.c_str(),"%c",&tm_time_in_line); + t_time_in_line = mktime(&tm_time_in_line); + + if ((from != 0) && (to != 0)) + { + if ((t_time_in_line <= t_to) && (t_time_in_line >= t_from)) + { + // cout << "Time in line: " << t_time_in_line << " from epoch time" << endl; + time = new TDatime(tm_time_in_line.tm_year,tm_time_in_line.tm_mon+1,tm_time_in_line.tm_mday,tm_time_in_line.tm_hour+1,tm_time_in_line.tm_min,tm_time_in_line.tm_sec); + // cout << "Time going in the ROOT file: " << time->Convert() << endl; + // Get time, temperature, humidity, and dew point. + istringstream iss(line); + iss >> trash1 >> trash2 >> trash3 >> trash4 >> trash5 >> TSi >> TTh; + vtime.push_back(time->Convert()); + vTSi.push_back(TSi); + vTTh.push_back(TTh); + } + } + else + { + // cout << "Time in line: " << t_time_in_line << " from epoch time" << endl; + time = new TDatime(tm_time_in_line.tm_year,tm_time_in_line.tm_mon+1,tm_time_in_line.tm_mday,tm_time_in_line.tm_hour+1,tm_time_in_line.tm_min,tm_time_in_line.tm_sec); + // cout << "Time going in the ROOT file: " << time->Convert() << endl; + // Get time, temperature, humidity, and dew point. + istringstream iss(line); + iss >> trash1 >> trash2 >> trash3 >> trash4 >> trash5 >> TSi >> TTh; + vtime.push_back(time->Convert()); + vTSi.push_back(TSi); + vTTh.push_back(TTh); + } + } + } + else + { + cout << "Error! Unable to read header..." << endl; + // return; + } + + // Close file. + file.close(); + } + else { + cout << "Error! Unable to open file." << endl; // To be modified to stop everything if there is a problem. + // return; + } + } + + double *aTSi = &vTSi[0]; + double *aTTh = &vTTh[0]; + double *atime = &vtime[0]; + + /* + cout << vT.size() << endl; + cout << vtime.size() << endl; + + cout << vT[0] << endl; + cout << vtime[0] << endl; + + cout << vT[10] << endl; + cout << vtime[10] << endl; + */ + + // Open output ROOT file. + string output_ROOT; + if ((from != 0) && (to !=0)) + output_ROOT = outputDirectory+"/"+funName+"-from"+s_from+"to"+s_to+".root"; + else + output_ROOT = outputDirectory+"/"+funName+"-all.root"; + TFile *output = TFile::Open(TString(output_ROOT),"RECREATE"); + + // Temperature trends. + TCanvas *cTSi = new TCanvas(TString(funName)+"-TSi","",400,300); + + cTSi->SetLeftMargin(0.1363636); + cTSi->SetRightMargin(0.08808081); + cTSi->SetBottomMargin(0.2095588); + + TGraph *gTSi = new TGraph(vTSi.size(),atime,aTSi); + InitGraph(gTSi,"Temperature trends","Time","Temperature (#circC)"); + gTSi->GetXaxis()->SetTimeDisplay(1); + gTSi->GetXaxis()->SetLabelOffset(0.04); + gTSi->GetXaxis()->SetTitleOffset(1.50); + gTSi->GetYaxis()->SetTitleOffset(0.95); + gTSi->GetXaxis()->SetTimeFormat("#splitline{%Y-%m-%d}{%H:%M:%S}"); + gTSi->GetXaxis()->SetNdivisions(-503); + gTSi->GetXaxis()->SetTimeOffset(0,"gmt"); + DrawGraph(cTSi,gTSi,"AP",path_to_figures); + + TCanvas *cTTh = new TCanvas(TString(funName)+"-TTh","",400,300); + + cTTh->SetLeftMargin(0.1363636); + cTTh->SetRightMargin(0.08808081); + cTTh->SetBottomMargin(0.2095588); + + TGraph *gTTh = new TGraph(vTTh.size(),atime,aTTh); + InitGraph(gTTh,"Temperature trends","Time","Temperature (#circC)"); + gTTh->GetXaxis()->SetTimeDisplay(1); + gTTh->GetXaxis()->SetLabelOffset(0.04); + gTTh->GetXaxis()->SetTitleOffset(1.50); + gTTh->GetYaxis()->SetTitleOffset(0.95); + gTTh->GetXaxis()->SetTimeFormat("#splitline{%Y-%m-%d}{%H:%M:%S}"); + gTTh->GetXaxis()->SetNdivisions(-503); + gTTh->GetXaxis()->SetTimeOffset(0,"gmt"); + DrawGraph(cTTh,gTTh,"AP",path_to_figures); + + // Combined trends. + TCanvas *cTSiAndTTh = new TCanvas(TString(funName)+"-TSiAndTTh","",400,300); + + cTSiAndTTh->SetLeftMargin(0.1363636); + cTSiAndTTh->SetRightMargin(0.08808081); + cTSiAndTTh->SetBottomMargin(0.2095588); + + TMultiGraph *mgTSiAndTTh = new TMultiGraph(); + + gTSi->SetMarkerColor(kGreen); + gTSi->SetLineColor(kGreen); + gTTh->SetMarkerColor(kRed); + gTTh->SetLineColor(kRed); + + TLegend *legTSiAndTTh = CreateLegend2(gTSi,"Si",gTTh,"thermostat","lpw",0.17,0.24,0.42,0.49); + + mgTSiAndTTh->Add(gTSi); + mgTSiAndTTh->Add(gTTh); + + cTSiAndTTh->cd(); + mgTSiAndTTh->Draw("AP"); + + mgTSiAndTTh->GetXaxis()->SetTimeDisplay(1); + mgTSiAndTTh->GetXaxis()->SetLabelOffset(0.04); + mgTSiAndTTh->GetXaxis()->SetTitleOffset(1.50); + mgTSiAndTTh->GetYaxis()->SetTitleOffset(0.95); + mgTSiAndTTh->GetXaxis()->SetTimeFormat("#splitline{%Y-%m-%d}{%H:%M:%S}"); + mgTSiAndTTh->GetXaxis()->SetNdivisions(-503); + mgTSiAndTTh->GetXaxis()->SetTimeOffset(0,"gmt"); + + DrawGraphCompare(cTSiAndTTh,mgTSiAndTTh,legTSiAndTTh,"Temperature trends","Time","Temperature (#circC)","AP",path_to_figures); + + TCanvas *cTSiVSTTh = new TCanvas(TString(funName)+"-TSiVSTTh","",400,300); + + cTSiVSTTh->SetLeftMargin(0.1363636); + cTSiVSTTh->SetRightMargin(0.08808081); + cTSiVSTTh->SetBottomMargin(0.2095588); + + TGraph *gTSiVSTTh = new TGraph(vTSi.size(),aTSi,aTTh); + InitGraph(gTSiVSTTh,"Temperature trends","Temperature (#circC)","Temperature (#circC)"); + gTSiVSTTh->GetXaxis()->SetLabelOffset(0.04); + gTSiVSTTh->GetXaxis()->SetTitleOffset(1.50); + gTSiVSTTh->GetYaxis()->SetTitleOffset(0.95); + gTSiVSTTh->GetXaxis()->SetNdivisions(-503); + DrawGraph(cTSiVSTTh,gTSiVSTTh,"AP",path_to_figures); + + // Write output ROOT file. + output->Write(); + + // Close output ROOT file. + output->Close(); + + return; +} + + + +vector SelectFiles(string inputDirectory, vector list_of_files, time_t t_from, time_t t_to) { + ifstream file; + + string header; + string first_line; + string last_line; + + struct tm tm_time_in_first_line; + struct tm tm_time_in_last_line; + + time_t t_time_in_first_line; + time_t t_time_in_last_line; + + vector list_of_selected_files; + + for (vector::const_iterator i = list_of_files.begin(); i != list_of_files.end(); ++i) + { + cout << "Input text file #" << i-list_of_files.begin() << ": " << *i << endl; + + // Check whether this input text file must be selected. + file.open((inputDirectory+"/"+*i).c_str()); + if (file.is_open()) + { + // cout << "Great! File opened..." << endl; + + // Skip header. + if (getline(file,header)) + { + // Read time in first line. + if (getline(file,first_line)) + { + memset(&tm_time_in_first_line, 0, sizeof(struct tm)); + strptime(first_line.c_str(),"%c",&tm_time_in_first_line); + t_time_in_first_line = mktime(&tm_time_in_first_line); + + // cout << "Time in first line: " << t_time_in_first_line << " from epoch time" << endl; + } + else + { + cout << "Error! Cannot read time in first line..." << endl; + return vector(); + } + // Read time in last line. + last_line = getLastLine(file); + memset(&tm_time_in_last_line, 0, sizeof(struct tm)); + strptime(last_line.c_str(),"%c",&tm_time_in_last_line); + t_time_in_last_line = mktime(&tm_time_in_last_line); + + // cout << "Time in last line: " << t_time_in_last_line << " from epoch time" << endl; + + // Decide if this input text file must be selected. + + if ((t_time_in_first_line <= t_to) && (t_time_in_last_line >= t_from)) + { + // Select the input text file. + list_of_selected_files.push_back(*i); + } + + } + else + { + cout << "Error! Unable to read header..." << endl; + return vector(); + } + + file.close(); + } + else { + cout << "Error! Unable to open file." << endl; // To be modified to stop everything if there is a problem. + return vector(); + } + } + + // cout << "Selected input text files" << endl; + for (vector::const_iterator i = list_of_selected_files.begin(); i != list_of_selected_files.end(); ++i) + { + // cout << "Selected input text file #" << i-list_of_selected_files.begin() << ": " << *i << endl; + } + + return list_of_selected_files; +} diff --git a/Software/Tools/Style.py b/Software/Tools/Style.py new file mode 100644 index 0000000..c9f61d7 --- /dev/null +++ b/Software/Tools/Style.py @@ -0,0 +1,445 @@ +""" +Author: Federica Lionetto +Date: November 16th, 2015 + +Description: +Define some useful functions to be used to accomplish common tasks with ROOT objects. +- LHCbStyle() +- InitHist(hist,title,x,y) +- InitHist2(hist,title,x,y,z) +- InitGraph(graph,title,x,y) +- SetStyleObj(obj,markerColor,lineColor,fillColor,markerSize,markerStyle,lineWidth,lineStyle) +- AdjustOffsets(hist,axis,labelOffset,titleOffset) +- DrawObj(canvas,obj,leg,option,folder) +- DrawOjbCompare(canvas,objList,colorDict,optionDict,leg,folder) +- CreateLegend(objList,labelDict,optionDict,x1,y1,x2,y2) +- CreateStats(hist,option,x1,y1,x2,y2) +- TestStyle() + +How to run it: +Include it in the other python scripts. +""" + +from array import array + +import numpy as np + +import ROOT + +def LHCbStyle() : + lhcbFont = 132 + lhcbWidth = 2 + lhcbTSize = 0.06 + + ROOT.gROOT.SetStyle('Plain') + lhcbStyle = ROOT.TStyle('lhcbStyle','LHCb plots style') + + lhcbStyle.SetFillColor(0) + lhcbStyle.SetFillStyle(1001) + lhcbStyle.SetFrameFillColor(0) + lhcbStyle.SetFrameBorderMode(0) + lhcbStyle.SetPadBorderMode(0) + lhcbStyle.SetPadColor(0) + lhcbStyle.SetCanvasBorderMode(0) + lhcbStyle.SetCanvasColor(0) + lhcbStyle.SetStatColor(0) + lhcbStyle.SetLegendBorderSize(0) + lhcbStyle.SetLegendFont(132) + + lhcbStyle.SetPalette(1) + colors=array('i',[0,5,7,3,6,2,4,1]) + # colors=np.array([0,5,7,3,6,2,4,1],dtype=np.int_) + print colors + print len(colors) + lhcbStyle.SetPalette(len(colors),colors) + + lhcbStyle.SetPaperSize(20,26) + lhcbStyle.SetPadTopMargin(0.05) + lhcbStyle.SetPadRightMargin(0.05) + lhcbStyle.SetPadBottomMargin(0.16) + lhcbStyle.SetPadLeftMargin(0.14) + + lhcbStyle.SetTextFont(lhcbFont) + lhcbStyle.SetTextSize(lhcbTSize) + lhcbStyle.SetLabelFont(lhcbFont,"x") + lhcbStyle.SetLabelFont(lhcbFont,"y") + lhcbStyle.SetLabelFont(lhcbFont,"z") + lhcbStyle.SetLabelSize(lhcbTSize,"x") + lhcbStyle.SetLabelSize(lhcbTSize,"y") + lhcbStyle.SetLabelSize(lhcbTSize,"z") + lhcbStyle.SetTitleFont(lhcbFont) + lhcbStyle.SetTitleFont(lhcbFont,"x") + lhcbStyle.SetTitleFont(lhcbFont,"y") + lhcbStyle.SetTitleFont(lhcbFont,"z") + lhcbStyle.SetTitleSize(1.2*lhcbTSize,"x") + lhcbStyle.SetTitleSize(1.2*lhcbTSize,"y") + lhcbStyle.SetTitleSize(1.2*lhcbTSize,"z") + + lhcbStyle.SetLineWidth(lhcbWidth) + lhcbStyle.SetFrameLineWidth(lhcbWidth) + lhcbStyle.SetHistLineWidth(lhcbWidth) + lhcbStyle.SetFuncWidth(lhcbWidth) + lhcbStyle.SetGridWidth(lhcbWidth) + lhcbStyle.SetLineStyleString(2,"[12 12]") + lhcbStyle.SetMarkerStyle(20) + lhcbStyle.SetMarkerSize(1.0) + + lhcbStyle.SetLabelOffset(0.010,"X") + lhcbStyle.SetLabelOffset(0.010,"Y") + + lhcbStyle.SetOptStat(0) + lhcbStyle.SetStatFormat("6.3g") + lhcbStyle.SetOptTitle(0) + lhcbStyle.SetOptFit(0) + lhcbStyle.SetTitleOffset(0.95,"X") + lhcbStyle.SetTitleOffset(0.95,"Y") + lhcbStyle.SetTitleOffset(1.2,"Z") + lhcbStyle.SetTitleFillColor(0) + lhcbStyle.SetTitleStyle(0) + lhcbStyle.SetTitleBorderSize(0) + lhcbStyle.SetTitleFont(lhcbFont,"title") + lhcbStyle.SetTitleX(0.0) + lhcbStyle.SetTitleY(1.0) + lhcbStyle.SetTitleW(1.0) + lhcbStyle.SetTitleH(0.05) + + lhcbStyle.SetStatBorderSize(0) + lhcbStyle.SetStatFont(lhcbFont) + lhcbStyle.SetStatFontSize(0.05) + lhcbStyle.SetStatX(0.9) + lhcbStyle.SetStatY(0.9) + lhcbStyle.SetStatW(0.25) + lhcbStyle.SetStatH(0.15) + + lhcbStyle.SetPadTickX(1) + lhcbStyle.SetPadTickY(1) + + lhcbStyle.SetNdivisions(505,"x") + lhcbStyle.SetNdivisions(510,"y") + + ROOT.gROOT.SetStyle("lhcbStyle") + ROOT.gROOT.ForceStyle() + + lhcbName = ROOT.TPaveText(ROOT.gStyle.GetPadLeftMargin() + 0.05,0.87 - ROOT.gStyle.GetPadTopMargin(),ROOT.gStyle.GetPadLeftMargin() + 0.20,0.95 - ROOT.gStyle.GetPadTopMargin(),'BRNDC') + lhcbName.AddText("LHCb") + lhcbName.SetFillColor(0) + lhcbName.SetTextAlign(12) + lhcbName.SetBorderSize(0) + + lhcbLabel = ROOT.TText() + lhcbLabel.SetTextFont(lhcbFont) + lhcbLabel.SetTextColor(1) + lhcbLabel.SetTextSize(lhcbTSize) + lhcbLabel.SetTextAlign(12) + + lhcbLatex = ROOT.TLatex() + lhcbLatex.SetTextFont(lhcbFont) + lhcbLatex.SetTextColor(1) + lhcbLatex.SetTextSize(lhcbTSize) + lhcbLatex.SetTextAlign(12) + + print '-------------------------' + print 'Set LHCb Style - Feb 2012' + print '-------------------------' + + return lhcbStyle + +def InitCanvas(canvas,top=0.15,bottom=None,left=None,right=None) : + if top is not None : + canvas.SetTopMargin(top) + if bottom is not None : + canvas.SetBottomMargin(bottom) + if left is not None : + canvas.SetLeftMargin(left) + # Set the right margin to 0.19 for COLZ plots. + if right is not None : + canvas.SetRightMargin(right) + return + +def InitHist(hist,title='',x='',y='') : + """ + Initialise 1D histogram with title , x axis title <x>, and y axis title <y>. + If <y> is not given, a y axis title based on the number of entries per bin is set. + """ + hist.SetTitle(title) + hist.GetXaxis().SetTitle(x) + if (y=='') : + hist.GetYaxis().SetTitle('Entries / {0}'.format(hist.GetBinWidth(1))) + else : + hist.GetYaxis().SetTitle(y) + return + +def InitHist2(hist,title='',x='',y='',z='') : + """ + Initialise 2D histogram <hist> with title <title>, x axis title <x>, y axis title <y>, and z axis title <z>. + If <z> is not given, a z axis title based on the number of entries per bin is set. + """ + hist.SetTitle(title) + hist.GetXaxis().SetTitle(x) + hist.GetYaxis().SetTitle(y) + if (z=='') : + hist.GetZaxis().SetTitle('Entries / ({0}*{1})'.format(hist.GetXaxis().GetBinWidth(1),hist.GetYaxis().GetBinWidth(1))) + else : + hist.GetZaxis().SetTitle(z) + return + +def InitGraph(graph,title='',x='',y='') : + """ + Initialise graph <graph> with title <title>, x axis title <x>, and y axis title <y>. + """ + graph.SetTitle(title) + graph.GetXaxis().SetTitle(x) + graph.GetYaxis().SetTitle(y) + return + +def SetStyleObj(obj,markerColor=ROOT.kBlack,lineColor=ROOT.kMagenta,fillColor=None,markerSize=1,markerStyle=20,lineWidth=2,lineStyle=1) : + """ + Set the style of object <obj>: + - marker color + - line color + - fill color + - marker size + - marker style + - line width + - line style + A default value exists for the last four. + """ + obj.SetMarkerColor(markerColor) + obj.SetLineColor(lineColor) + obj.SetFillStyle(1001) + if fillColor is not None : + obj.SetFillColor(fillColor) + obj.SetMarkerSize(markerSize) + obj.SetMarkerStyle(markerStyle) + obj.SetLineWidth(lineWidth) + obj.SetLineStyle(lineStyle) + return + +def AdjustOffsets(hist,axis,labelOffset=0.005,titleOffset=0.85) : + """ + Adjust the offsets of histogram <hist> along the axis <axis>, by setting the label offset <labelOffset> and the title offset <titleOffset>. + The argument <axis> can be 'X', 'Y', or 'Z'. + The default values are those used for a TH2 object one wants to draw with the COLZ option. + """ + hist.SetLabelOffset(labelOffset,axis) + hist.SetTitleOffset(titleOffset,axis) + return + +def DrawObj(canvas,obj,leg=None,option='',folder='.') : + """ + Draw object <obj> in canvas <canvas>, together with legend <leg> (if provided), with option <option> and save the result in a pdf file having the same name as the canvas, located in the folder <folder>. + """ + name=canvas.GetName() + canvas.cd() + obj.Draw(option) + if ('A' in option) : + canvas.SetTickx(1) + canvas.SetTicky(1) + if (leg is not None) : + leg.Draw() + canvas.Update() + canvas.Write() + canvas.SaveAs(folder+'/'+name+'.pdf') + canvas.Close() + return + +def DrawObjCompare(canvas,objList,colorDict,optionDict,leg,folder='.') : + """ + Draw list of objects <objList> in canvas <canvas>, together with legend <leg>, with color <colorDict> and option <optionDict> and save the result in a pdf file having the same name as the canvas, located in the folder <folder>. + This allows to draw histograms, graphs, and functions in the same canvas. + However, since graphs do not have a 'GetMaximum()' method, the object to be drawn first is searched for among histograms and functions only (whose names start with 'h' and 'f', respectively). The remaining objects are drawn after. + """ + name=canvas.GetName() + canvas.cd() + maxList = [] + for obj in objList : + obj.SetMarkerColor(colorDict[obj.GetName()]) + obj.SetLineColor(colorDict[obj.GetName()]) + obj.SetFillColor(colorDict[obj.GetName()]) + if (obj.GetName().startswith('h') or obj.GetName().startswith('f')) : + maxList.append(obj.GetMaximum()) + + print maxList + + firstDraw = maxList.index(max(maxList)) + print firstDraw + + objList[firstDraw].Draw(optionDict[objList[firstDraw].GetName()]) + for obj in objList : + if (obj != objList[firstDraw]) : + obj.Draw(optionDict[obj.GetName()]+'SAME') + leg.Draw() + canvas.Update() + canvas.Write() + canvas.SaveAs(folder+'/'+name+'.pdf') + canvas.Close() + return + +def CreateLegend(objList,labelDict,optionDict,x1=0.64,y1=0.59,x2=0.94,y2=0.89) : + """ + Create legend <leg> starting from list of objects <objList>, dictionary of labels <labelDict>, and dictionary of options <optionDict>. + The legend is displayed in the position identified by <x1>, <y1>, <x2>, and <y2>. + If the option 'w' is specified, the fill color is set to white. + The text size is set to '0.05'. + """ + leg = ROOT.TLegend(x1,y1,x2,y2) + leg.SetFillColor(ROOT.kWhite) + for obj in objList : + label = labelDict[obj.GetName()] + option = optionDict[obj.GetName()] + leg.AddEntry(obj,label,option) + leg.SetTextSize(0.05) + return leg + +def CreateStats(hist,option,x1=0.64,y1=0.59,x2=0.94,y2=0.89) : + """ + Create stats <stats> of histogram <hist> depending on option <option>. + The stats are displayed in the position identified by <x1>, <y1>, <x2>, and <y2>. + """ + stats = ROOT.TPaveStats(x1,y1,x2,y2,'brNDC') + stats.SetName('stats') + stats.SetBorderSize(1) + stats.SetFillColor(0) + stats.SetTextAlign(12) + text = stats.AddText('Entries = {0}'.format(hist.GetEntries())) + if ('I' in option) : + text = stats.AddText('Integral = {0}'.format(hist.Integral())) + N = hist.GetDimension() + if (N == 1) : + text = stats.AddText('Mean = {0}'.format(hist.GetMean())); + text = stats.AddText('RMS = {0}'.format(hist.GetRMS())); + if ('S' in option) : + text = stats.AddText('Skewness = {0}'.format(hist.GetSkewness())) + if ('K' in option) : + text = stats.AddText('Kurtosis = {0}'.format(hist.GetKurtosis())) + if ('U' in option) : + text = stats.AddText('Underflow = {0}'.format(hist.GetBinContent(0))) + if ('O' in option) : + over = hist.GetNbinsX()+1 + text = stats.AddText('Overflow = {0}'.format(hist.GetBinContent(over))) + else : + text = stats.AddText('Mean x = {0}'.format(hist.GetMean(1))) + text = stats.AddText('Mean y = {0}'.format(hist.GetMean(2))) + text = stats.AddText('RMS x = {0}'.format(hist.GetRMS(1))) + text = stats.AddText('RMS y = {0}'.format(hist.GetRMS(2))) + if ('S' in option) : + text = stats.AddText('Skewness x = {0}'.format(hist.GetSkewness(1))) + text = stats.AddText('Skewness y = {0}'.format(hist.GetSkewness(2))) + if ('K' in option) : + text = stats.AddText('Kurtosis x = {0}'.format(hist.GetKurtosis(1))) + text = stats.AddText('Kurtosis y = {0}'.format(hist.GetKurtosis(2))) + if ('U' in option or 'O' in option) : + nbinsX = hist.GetNbinsX() + nbinsY = hist.GetNbinsY() + bl = hist.GetBinContent(0,0) + bc = 0 + for i in range(1,nbinsX+1) : + bc += hist.GetBinContent(i,0) + br = hist.GetBinContent(nbinsX+1,0) + cl = 0 + for i in range(1,nbinsY+1) : + cl += hist.GetBinContent(0,i) + cc = hist.GetEffectiveEntries() + cr = 0 + for i in range(1,nbinsX+1) : + cr += hist.GetBinContent(nbinsX+1,i) + tl = hist.GetBinContent(0,nbinsY+1) + tc = 0 + for i in range(1,nbinsX+1) : + tc += hist.GetBinContent(i,nbinsY+1) + tr = hist.GetBinContent(nbinsX+1,nbinsY+1) + text = stats.AddText('{0}| {1}| {2}'.format(tl,tc,tr)) + text = stats.AddText('{0}| {1}| {2}'.format(cl,cc,cr)) + text = stats.AddText('{0}| {1}| {2}'.format(bl,bc,br)) + return stats + +def TestStyle() : + """ + Test the functions defined above in a quick and automatic way. + """ + lhcbStyle = LHCbStyle() + + canvasDrawObj = ROOT.TCanvas('canvasDrawObj','canvasDrawObj',400,300) + canvasDrawObjCompare = ROOT.TCanvas('canvasDrawObjCompare','canvasDrawObjCompare',400,300) + canvasDrawObjCompare2 = ROOT.TCanvas('canvasDrawObjCompare2','canvasDrawObjCompare2',400,300) + + hist1 = ROOT.TH1F('hist1','hist1',100,0,10) + hist2 = ROOT.TH1F('hist2','hist2',100,0,10) + hist3 = ROOT.TH1F('hist3','hist3',100,0,10) + + hist2D = ROOT.TH2F('hist2D','hist2D',100,0,10,10,0,2) + + hist1.Fill(2,10) + hist2.Fill(3,2) + hist3.Fill(5,1) + + hist2D.Fill(2,1) + hist2D.Fill(4,0) + hist2D.Fill(5,2,10) + + ax = np.arange(0.,10.,2.) + ay = ax*5. + asize = len(ax) + print ax + print ay + print asize + graph = ROOT.TGraph(asize,ax,ay) + graph.SetName('graph') + + # Test InitHist. + InitHist(hist1,title='title for hist 1',x='x axis',y='y axis') + InitHist(hist2,title='title for hist 2',x='x axis') + InitHist(hist3,title='') + + # Test InitHist2. + InitHist2(hist2D) + + # Test InitGraph. + InitGraph(graph) + + markerColor=ROOT.kMagenta + lineColor=ROOT.kMagenta + fillColor=ROOT.kMagenta + # Test SetStyleObj. + SetStyleObj(hist1,markerColor,lineColor,fillColor) + SetStyleObj(graph,markerColor,lineColor,fillColor) + + # Test AdjustOffsets. + AdjustOffsets(hist2D,'Z') + + objList=[hist1,hist2,hist3] + colorDict={hist1.GetName():ROOT.kRed,hist2.GetName():ROOT.kBlue,hist3.GetName():ROOT.kGreen} + optionDrawDict={hist1.GetName():'E',hist2.GetName():'',hist3.GetName():'E'} + labelDict={hist1.GetName():'first',hist2.GetName():'second',hist3.GetName():'third'} + optionLegDict={hist1.GetName():'l',hist2.GetName():'p',hist3.GetName():'fw'} + + objList2=[hist1,graph] + colorDict2={hist1.GetName():ROOT.kRed,graph.GetName():ROOT.kBlue} + optionDrawDict2={hist1.GetName():'E',graph.GetName():'APC'} + labelDict2={hist1.GetName():'first',graph.GetName():'second'} + optionLegDict2={hist1.GetName():'l',graph.GetName():'pw'} + + print objList2 + print colorDict2 + print optionDrawDict2 + print labelDict2 + print optionLegDict2 + + # Test DrawObj. + DrawObj(canvasDrawObj,hist1) + + # Test CreateLegend. + leg = CreateLegend(objList,labelDict,optionLegDict,0.5,0.5,0.8,0.7) + leg2 = CreateLegend(objList2,labelDict2,optionLegDict2,0.6,0.2,0.9,0.5) + + # Test DrawObjCompare. + DrawObjCompare(canvasDrawObjCompare,objList,colorDict,optionDrawDict,leg) + DrawObjCompare(canvasDrawObjCompare2,objList2,colorDict2,optionDrawDict2,leg2) + + option = 'IUO' + # Test CreateStats. + CreateStats(hist1,option) + + return + +LHCbStyle()