Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- plotter.c
- Giulio Candreva (giulio.candreva@cern.ch)
- ------------------------------
- the purpose is to plot the data from the summary files, generated by the script WIP.c
- the script is divided in various functions:
- - split(string s, char delim, vector <string> *elements)
- Takes a string s, splits it in chunks using the 'delim' char as divider.
- The chunks are put in the *elements vector
- - strToTime(string date)
- Takes a string in the format dd/mm/yyyy and returns the UNIX timestamp
- - plot(vector <string> files, string column, string start, float min, float max)
- Reads all the files contained in the vector "file", extract the column "column" and the column "Date"
- it plots all the points in a plot that has the time in the X axis
- the X axis is limited by start and stop (they are two strings containing two dates in the format dd/mm/yyyy) stop is the last analysis date
- the Y axis is limited by min and max
- - plotter()
- The main function of the script. It calls the function plot with various parameteres in orderd to generate
- the desired plots
- - drawLogo()
- helpful function that draws a overlaying logo in the canvas
- !!IF YOU OPENED THIS FILE YOU PROBABLY WANT TO EDIT "plot" AND "plotter" FUNCTIONS SINCE THEY'RE THE CORE OF THE SCRIPT!!
- */
- #include <string>
- #include <stdlib>
- #include <fstream>
- #include <iostream>
- #include <TGaxis.h>
- #include "TCanvas.h"
- #include <TMath.h>
- #include "TColor.h"
- /* User defined function that splits a string s using a delimitator delim and puts the chuncks in the elements vector */
- /* You probably don't need to know how it works */
- void split(string s, char delim, vector <string> * elements) {
- string item = "";
- int i=0;
- while(i<s.size()) {
- if (s.at(i) == delim) {
- (*elements).push_back(item);
- item = "";
- } else {
- item += s.at(i);
- }
- i++;
- }
- (*elements).push_back(item);
- }
- /* user defined function that converts a date in the format dd/mm/yyyy to a UNIX timestamp */
- int strToTime(string datestring) {
- int day, year, month;
- vector <string> elements;
- split(datestring, '/', &elements);
- day = atoi(elements[0].c_str());
- month = atoi(elements[1].c_str());
- year = atoi(elements[2].c_str());
- TDatime * date = new TDatime(year, month, day, 0, 0, 0);
- UInt_t ttt;
- ttt = date->Convert();
- int pTime = (int)ttt;
- return pTime;
- }
- // User defined function that draws lines for acceptable limits
- void drawLimits(string det, string column, float startday, float stopday) {
- float suplim=0, inflim, values[2], times_l[2];
- times_l[0] = startday;
- times_l[1] = stopday;
- if (det == "RICH2") {
- if (column == "CF4") {
- suplim = 93;
- inflim = 91;
- } else if (column == "CO2") {
- suplim = 9;
- inflim = 7;
- } else if (column == "Oxygen") {
- suplim = 3000;
- inflim = -1;
- } else if (column == "Nitrogen") {
- suplim = 12000;
- inflim = -1;
- } else if (column == "Oxygen_2018") {
- suplim = 3000;
- inflim = -1;
- } else if (column == "Nitrogen_2018") {
- suplim = 12000;
- inflim = -1;
- }
- } else if (det == "MWPC") {
- if (column == "CO2") {
- suplim = 58;
- inflim = 56;
- } else if (column == "Ar") {
- suplim = 39;
- inflim = 37;
- } else if (column == "CF4") {
- suplim = 5.5;
- inflim = 4.5;
- }
- } else if (det == "RICH1") {
- if (column == "C4F10") {
- suplim = 100;
- inflim = 100;
- } else if (column == "CO2") {
- suplim = 0.5;
- inflim = -1.0;
- } else if (column == "Air") {
- suplim = 2;
- inflim = -1;
- } else if (column == "Oxygen") {
- suplim = 2000;
- inflim = -1;
- } else if (column == "Nitrogen") {
- suplim = 8000;
- inflim = -1;
- }
- }
- //MARA 30/04 modified for OT plots
- //ANNA change limits for lines on the plot
- else if (det == "OT") {
- if (column == "CO2") {
- suplim = 0.5;
- inflim = -1.0;
- } else if (column == "Argon") {
- suplim = 2;
- inflim = -1;
- } else if (column == "Oxygen") {
- suplim = 2000;
- inflim = -1;
- } else if (column == "Nitrogen") {
- suplim = 8000;
- inflim = -1;
- }
- }
- cout << "limits " << det << " " << column << " " << suplim << " " << inflim << endl;
- if (suplim != 0) {
- // Add line 1 (inferior limit)
- values[0] = inflim;
- values[1] = inflim;
- TGraph *Line = new TGraph(2, times_l, values);
- Line->SetMarkerColor(4); //(kMagenta-2);
- Line->SetMarkerStyle(8);
- Line->SetLineColor(kRed);
- Line->SetLineWidth(2);
- Line->SetMarkerSize(0.2);
- Line->Draw("CP");
- // Add line 2 (superior limit)
- values[0] = suplim;
- values[1] = suplim;
- TGraph *LineS = new TGraph(2, times_l, values);
- LineS->SetMarkerColor(kAzure+1); //(kMagenta-2);
- LineS->SetMarkerStyle(8);
- LineS->SetLineColor(kRed);
- LineS->SetLineWidth(2);
- LineS->SetMarkerSize(0.2);
- LineS->Draw("CP");
- }
- }
- // User defined function that draws a logo based on an image
- void drawLogo() {
- TImage *img = TImage::Open("epdtlogo.jpg");
- if (!img) {
- printf("Could not create an image... exit\n");
- return;
- }
- // TPad *l = new TPad("l", "l",0.1209553,0.7906977,0.220339,0.8901809);
- //gPad->cd(0);
- TPad *l = new TPad("l", "l",0.1209553,0.7906977,0.3466872,0.8901809);
- l->Draw();
- l->cd();
- img->Draw();
- }
- /* function that actually plots */
- void plot(vector <string> names, string column, string start, float min, float max, bool proportional=false){
- //------- GENERAL STYLE INSTRUCTIONS
- gROOT->SetStyle("Plain");
- // background is no longer mouse-dropping white
- gStyle->SetCanvasColor(kWhite);
- // blue to red false color palette. Use 9 for b/w
- gStyle->SetPalette(1,0);
- // turn off canvas borders
- gStyle->SetCanvasBorderMode(0);
- gStyle->SetPadBorderMode(0);
- // What precision to put numbers if plotted with "TEXT"
- gStyle->SetPaintTextFormat("5.2f");
- // For publishing:
- gStyle->SetLineWidth(1.5);
- gStyle->SetTextSize(1.1);
- gStyle->SetLabelSize(0.03,"xy");
- gStyle->SetTitleSize(0.04,"xy");
- gStyle->SetTitleOffset(1.1,"x");
- gStyle->SetTitleOffset(0.9,"y");
- gStyle->SetPadTopMargin(0.1);
- gStyle->SetPadRightMargin(0.05);
- gStyle->SetPadBottomMargin(0.1);
- gStyle->SetPadLeftMargin(0.1);
- //------ END GENERAL STYLE INSTRUCTIONS
- // Initialize the Canvas, graphs and legend
- TCanvas *c;
- char namecanvas[100]; //the TCanvas constructor accepts only char*
- sprintf(namecanvas, "%s_%d_%d", column,min,max);
- c = new TCanvas(namecanvas,"plot",0,0,1300,800); // It doesn't accept string, so I did the conversion
- c->SetFillColor(0);
- c->GetFrame()->SetBorderSize(0);
- c->SetGridy();
- TGraph *Graph[3]; // I will need at most 3 graphs in the same canvas
- //leg = new TLegend(0.6687211,0.7622739,0.9306626,0.872093,NULL,"brNDC");
- leg = new TLegend(0.801877,0.7769784,0.9442127,0.8893885,NULL,"brNDC");
- leg->SetFillColor(0);
- leg->SetBorderSize(1);
- leg->SetTextSize(0.03);
- // end canvas and graphs
- string name; // this will contain the name of the processed file
- int np = 0; // a support variable that counts the plots that I draw
- char *title; // this will be the title of the graph
- string titolo; // I'll use these two variables later
- for (np=0;np < names.size();np++) { // I draw many plots as many as files
- // open file
- name = names[np];
- ifstream thaFile(name.c_str(),ios::in);
- int pos=0; // It will contain the number of the column
- int i=0; // line counter
- string dates[10000]; // this will contain all the dates
- float areas[10000]; // this will contain all the concentrations (although it's called 'areas')
- float errors_y[10000]; // this will contain the errors
- float errors_x[10000]; // this will contain the errors on the x axis (it will be filled with zeros)
- float times[100000]; // this will contain all the unix timestamps (converted from the dates)
- float areas_sum; // this will contain the sum over all areas (possibly used as calib. value, depending on the "proportional" parameter)
- string lineString; // this will contain the current line of the file
- vector <string> elements; // every line will be split into chunks and put in elements
- cout << name << endl; // I print the current file that is being processed
- while(getline(thaFile, lineString)) { // for each line
- elements.clear();
- split(lineString, '\t', &elements); // I split the line as said before
- if (elements[0] == "Date") { // <=> If it's the first line
- for (int j=0;j<elements.size();j++) { // I cycle over all the columns name
- if (column == elements[j]) { // till I find my column, specified in the function arguments
- (proportional==true) ? pos = j : pos = j+2; // And I save its position (+2 cause that's the column that contains the concentration, +0 if I want the raw area)
- }
- }
- continue;
- }
- // Now I want to collect the sum of all the areas for the given row, because it will be used as calibration value if the parameter "proportional" is set to true
- areas_sum = 1;
- for (int j=6;j<elements.size();j++) { // I start from 6 (that becomes 9 due to the mod4 ) because the first 8 values are relative to MS column
- if ((j-1)%4 == 0) {
- areas_sum = areas_sum + atof(elements.at(j).c_str());
- }
- }
- times[i] = (float) strToTime(elements[0]); // I convert the date (elements(0)) into a timestamp
- areas[i] = atof(elements.at(pos).c_str()); // I convert the area (elements(pos)) into a float number
- areas[i] = (areas[i] > 0) ? areas[i] : -1; // If the concentration is zero, then it means that the data is missing: I avoid to plot it, putting it below the x-axis (I assign it a negative value)
- errors_y[i] = atof(elements.at(pos+1).c_str()); // the uncertainty is the next column
- errors_x[i] = 0; // I don't want any error for my x-axis
- if (proportional) { // If proportional is set to true, I divide the area by the sum of all the others
- areas[i] = 100.0 * areas[i] / areas_sum;
- errors_y[i] = 100.0 * errors_y[i] / areas_sum;
- }
- cout << i << " : " << (int) times[i] << " -> " << areas[i] << " +- " << errors_y[i] << "( areas sum = " << areas_sum << ")" << endl; // just for debug
- i++;
- } // end reading the file
- // Now I use the name of the file in order to construct the title of the plot
- vector <string> parts;
- split(name, '_', &parts);
- titolo = parts.at(1) + " " + column;
- title = titolo;
- char *line;
- line = parts.at(2); // the second part of the filename should contain the gas line
- string detector = parts.at(1);
- // End title management
- // I create the Graph and define a lot of graphic things
- Graph[np] = new TGraphErrors(i, times, areas, errors_x, errors_y);
- Graph[np]->SetTitle(title);
- Graph[np]->GetXaxis()->SetTitle("Time");
- Graph[np]->GetYaxis()->SetTitle((column == "Oxygen" || column == "Nitrogen") ? "Concentration (ppm) " : "Concentration (%)");
- Graph[np]->GetXaxis()->SetNdivisions(608,kFALSE); //605
- Graph[np]->GetXaxis()->SetTimeDisplay(1);
- Graph[np]->GetXaxis()->SetTimeFormat("%d\/%m\/%y %F1970-01-01 00:00:00");
- Graph[np]->SetMarkerStyle(8);
- Graph[np]->SetMarkerSize(1);
- // Down here I set the boundaries of the axis
- int startday = strToTime(start);
- //int stopday = strToTime(stop);
- int stopday = (int) times[i-1];
- Graph[np]->GetXaxis()->SetLimits(startday,stopday);
- Graph[np]->SetMinimum(min);
- Graph[np]->SetMaximum(max);
- // I add an entry in the legend, corresponding to this graph (line is the name of the gas line)
- leg->AddEntry(Graph[np],line,"p");
- // Since I'm drawing more graphs on the top of each other, I change the colours of the points
- TColor *colors[3] = {gROOT->GetColor(kAzure), gROOT->GetColor(kGreen+2), gROOT->GetColor(kRed-2)};
- if (np == 0) {
- Graph[np]->SetMarkerColor(colors[0]->GetNumber());
- Graph[np]->Draw("AP");
- } else {
- Graph[np]->SetMarkerColor(colors[np]->GetNumber());
- Graph[np]->Draw("P");
- }
- } // End for each file processed
- drawLimits(detector, column, startday, stopday);
- leg->Draw();
- drawLogo();
- // let's save the canvas in a png file
- char outfile[100];
- sprintf(outfile, "%s_%d.png", titolo, proportional);
- c->Print(outfile);
- } // end plot() function
- void plotter() {
- vector <string> files;
- // MWPC
- files.push_back("Summaries\\150_MWPC_Mixer_Sum.DIF");
- files.push_back("Summaries\\151_MWPC_ExhToDis_Sum.DIF");
- files.push_back("Summaries\\148_MWPC_BefPurif_Sum.DIF");
- plot(files, "CO2", "1/4/2017", 45, 65);
- plot(files, "Ar", "1/4/2017", 30, 44);
- plot(files, "CF4", "1/4/2017", 4, 7);
- plot(files,"Oxygen", "1/4/2017", 0, 200);
- plot(files,"Nitrogen", "1/4/2017", 0, 3000);
- files.clear();
- // OT
- files.push_back("Summaries\\155_OT_Exh_Sum.DIF");
- //files.push_back("Summaries\\154_OT_Mixer_Sum.DIF");
- //plot(nameoffilewithdata, "nameofvariable", "startday", minY, maxY)
- plot(files, "CO2", "1/4/2018", 25, 35);
- plot(files, "Ar", "1/4/2018", 60, 80);
- plot(files,"Oxygen", "1/4/2018", 0, 20000);
- plot(files,"Nitrogen", "1/4/2018", 0, 500);
- files.clear(); //frees the memory of program to go on with other files
- // RICH2
- files.push_back("Summaries\\159_RICH2_BefPurif_Sum.DIF");
- files.push_back("Summaries\\160_RICH2_AftPurif_Sum.DIF");
- plot(files, "CO2", "1/1/2016", 7, 11);
- plot(files, "CF4", "1/1/2016", 85, 95);
- // I want to plot Ratios for CF4 e CO2
- plot(files, "CF4", "1/1/2016", 90, 100, true);
- plot(files, "CO2", "1/1/2016", 7, 11, true);
- //uncomment to get the complete plot from 2016 to 2018
- //plot(files, "Oxygen", "1/1/2016", 0, 6000);
- //plot(files, "Nitrogen", "1/1/2016", 0, 20000);
- plot(files, "Oxygen", "1/3/2018", 4700, 5200); //Anna
- plot(files, "Nitrogen", "1/3/2018", 16600, 18300); //Anna
- files.clear();
- // RICH1
- files.push_back("Summaries\\146_RICH1_AftPump_Sum.DIF");
- plot(files, "C4F10", "1/1/2016", 90, 100, true);
- plot(files, "CO2", "1/1/2016", 0, 10, true);
- plot(files, "Oxygen", "1/1/2016", 0, 12000);
- plot(files, "Nitrogen", "1/1/2016", 0, 25000);
- //plot(files, "Oxygen", "1/3/2018", 0, 12000);
- //plot(files, "Nitrogen", "1/3/2018", 0, 25000);
- plot(files, "Air", "1/1/2016", 0, 1.5, true);
- files.clear();
- }
Add Comment
Please, Sign In to add comment