Excluding lowest pt point for K and p, ratios fit/data are now shown in 3 canvases
[u/mrichter/AliRoot.git] / PWG2 / SPECTRA / Fit / AliLatexTable.cxx
CommitLineData
4c0d7bc7 1// ------------------------------------------------------------------
2//
3// AliLatexTable
4//
5// This class is used to produce tables using latex sintax. It can
6// than print the table as Latex source code (to be pasted on a paper)
7// or ASCII.
8//
9// The basic idea is that you add columns one after the other with the
10// SetNextCol method and than you insert this row. The SetNextCol
11// method comes in different flavours to alow the insertion of
12// different type of values (numbers with or without errors,
13// strings...).
14//
15// TODO:
16// 1. Make the class drawable
17// 2. Implement vertical lines in ascii print
18// 3. Print output in HTML format
19//
20// Author: Michele Floris, CERN
21// ------------------------------------------------------------------
22
23#include "AliLatexTable.h"
24#include "TString.h"
25#include "TRegexp.h"
26#include "TObjString.h"
27#include "TObjArray.h"
28#include <stdarg.h>
29#include "snprintf.h"
30#include "Varargs.h"
31#include "TPRegexp.h"
32#include "TMath.h"
33#include <iostream>
048a89c1 34#include <fstream>
35#include "AliLog.h"
4c0d7bc7 36
37using namespace std;
38
fff5b67e 39ClassImp(AliLatexTable)
4c0d7bc7 40
048a89c1 41AliLatexTable::AliLatexTable() : fNcol(0), fFormat(""), fRows(0), fCols(0), fNcolReady(0){
42 // default constructor
43 fNcol = 1;
44 fFormat = "c";
45 fNcolReady = 0;
46 fRows = new TObjArray;
47 fCols = new TObjArray;
48
49 fRows->SetOwner();
50 fCols->SetOwner();
51
52}
53
4c0d7bc7 54AliLatexTable::AliLatexTable(Int_t ncol, TString format) : fNcol(0), fFormat(""), fRows(0), fCols(0), fNcolReady(0){
55 // constructor, specify number of cols
56 fNcol = ncol;
57 fFormat = format;
58 fNcolReady = 0;
59 fRows = new TObjArray;
60 fCols = new TObjArray;
61
62 fRows->SetOwner();
63 fCols->SetOwner();
64}
65
66
67AliLatexTable::~AliLatexTable() {
68
69 // dtor
70 if (fRows) delete fRows;
71 if (fCols) delete fCols;
72
73}
74
75void AliLatexTable::SetNextCol(Int_t val){
76 // Set next column in current row - integer
77 char col[200];
78 sprintf(col, " %d ", val);
79 SetNextCol(col);
80
81}
82
83void AliLatexTable::SetNextCol(Int_t val, Int_t err){
84
85 // Set next column in current row - int +- int
86 char col[200];
87 sprintf(col, " $%d \\pm %d$ ", val, err);
88 SetNextCol(col);
89
90}
91
24a1ac33 92void AliLatexTable::SetNextCol(Double_t val, Int_t scientificNotation, Bool_t rounding){
4c0d7bc7 93
94 // Set next column in current row - double, specify resolution
95
96 char col[200];
24a1ac33 97 if(rounding) {
98 if(scientificNotation >= 0) {
99 char format[100];
4c0d7bc7 100
24a1ac33 101 // cout << format << endl;
102 Double_t mantissa, exp;
103 GetMantissaAndExpBase10(val, mantissa, exp);
4c0d7bc7 104
24a1ac33 105 if (exp == 0) {
106 sprintf(format, " $%%%d.%df $", scientificNotation, scientificNotation);
107 sprintf(col, format, mantissa);
108 }
109 else {
110 sprintf(format, " $%%%d.%df \\cdot 10^{%%0.0f} $", scientificNotation, scientificNotation);
111 sprintf(col, format, mantissa, exp);
112 }
4c0d7bc7 113
114
115
116
24a1ac33 117 SetNextCol(col);
4c0d7bc7 118
24a1ac33 119 } else {
120 char format[100];
121 sprintf(format, " $%%%d.%df $", -scientificNotation,-scientificNotation);
a2cfdbe4 122 sprintf(col, format , TMath::Nint(val*TMath::Power(10,-scientificNotation))/TMath::Power(10,-scientificNotation));
24a1ac33 123 SetNextCol(col);
124 }
125 }else {
4c0d7bc7 126 sprintf(col, " %f ", val);
127 SetNextCol(col);
128 }
129
130}
24a1ac33 131void AliLatexTable::SetNextCol(Double_t val, Double_t err, Int_t scientificNotation, Bool_t rounding){
4c0d7bc7 132
133 // Set next column in current row - double +- double, specify resolution
134
24a1ac33 135 // scientific notation is used to determine number of
4c0d7bc7 136 // digits in error
137
138 //if it is > 0 exp notation is used
139
4c0d7bc7 140
141 char col[200];
24a1ac33 142 if(rounding) {
143 if(scientificNotation >=0 ) {
144
145 Double_t mantissa, exp;
146 GetMantissaAndExpBase10(val, mantissa, exp);
147
148 Double_t mantissa_err, exp_err;
149 GetMantissaAndExpBase10(err, mantissa_err, exp_err);
150
151 Int_t nSigDigits =TMath::Nint(exp - exp_err);
152 if(scientificNotation != 0) nSigDigits = nSigDigits + scientificNotation - 1;
153
154
155 char format[100];
156 if (exp == 0) {
157 sprintf(format, " $%%%d.%df \\pm %%%d.%df $", nSigDigits, nSigDigits, nSigDigits, nSigDigits);
158 sprintf(col, format, mantissa, mantissa_err/TMath::Power(10,exp - exp_err));
159 }
160 else {
161 sprintf(format, " $%%%d.%df \\pm %%%d.%df \\cdot 10^{%%0.0f}$", nSigDigits, nSigDigits, nSigDigits, nSigDigits);
162 sprintf(col, format, mantissa, mantissa_err/TMath::Power(10,exp - exp_err), exp);
163 }
164
165
166 //cout << format << endl;
4c0d7bc7 167
24a1ac33 168 SetNextCol(col);
4c0d7bc7 169
24a1ac33 170 } else {
171 char format[100];
172 sprintf(format, " $%%%d.%df \\pm %%%d.%df $", -scientificNotation,-scientificNotation,-scientificNotation,-scientificNotation);
a2cfdbe4 173 sprintf(col, format , TMath::Nint(val*TMath::Power(10,-scientificNotation))/TMath::Power(10,-scientificNotation), TMath::Nint(err*TMath::Power(10,-scientificNotation))/TMath::Power(10,-scientificNotation));
24a1ac33 174 SetNextCol(col);
175 }
4c0d7bc7 176 }
177 else {
178 sprintf(col, " $%f \\pm %f$ ", val, err);
179 SetNextCol(col);
180 }
181}
182
24a1ac33 183void AliLatexTable::SetNextCol(Double_t val, Double_t err, Double_t errSyst, Int_t scientificNotation, Bool_t rounding){
4c0d7bc7 184
185 // Set next column in current row - double +- double +- double, specify resolution
186
187 // if scientific notation is != -1 is used to determine number of
188 // digits in error
189
190 //if it is > 0 exp notation is used
191
192 //if it is < -1 number is truncated to the number of digits after
193 //point dictated by scientificNotation,
194
195 char col[200];
24a1ac33 196 if (rounding) {
197 if(scientificNotation >=0 ) {
4c0d7bc7 198
24a1ac33 199 Double_t mantissa, exp;
200 GetMantissaAndExpBase10(val, mantissa, exp);
4c0d7bc7 201
24a1ac33 202 Double_t mantissa_err, exp_err;
203 GetMantissaAndExpBase10(err, mantissa_err, exp_err);
4c0d7bc7 204
24a1ac33 205 Double_t mantissa_errsyst, exp_errsyst;
206 GetMantissaAndExpBase10(errSyst, mantissa_errsyst, exp_errsyst);
4c0d7bc7 207
24a1ac33 208 Int_t nSigDigits =TMath::Nint(exp - exp_err);
209 if(scientificNotation != 0) nSigDigits = nSigDigits + scientificNotation - 1;
4c0d7bc7 210
211
24a1ac33 212 char format[100];
213 if (exp == 0) {
214 sprintf(format, " $%%%d.%df \\pm %%%d.%df \\pm %%%d.%df $",
215 nSigDigits, nSigDigits, nSigDigits, nSigDigits, nSigDigits, nSigDigits);
216 sprintf(col, format, mantissa,
217 mantissa_err/TMath::Power(10,exp - exp_err),
218 mantissa_errsyst/TMath::Power(10,exp - exp_errsyst));
219 }
220 else {
221 sprintf(format, " $%%%d.%df \\pm %%%d.%df \\pm %%%d.%df \\cdot 10^{%%0.0f}$",
222 nSigDigits, nSigDigits, nSigDigits, nSigDigits, nSigDigits, nSigDigits);
223 sprintf(col, format, mantissa,
224 mantissa_err/TMath::Power(10,exp - exp_err),
225 mantissa_errsyst/TMath::Power(10,exp - exp_errsyst),
226 exp);
227 }
4c0d7bc7 228
229
24a1ac33 230 //cout << format << endl;
4c0d7bc7 231
24a1ac33 232 SetNextCol(col);
233
234 } else {
235 char format[100];
236 sprintf(format, " $%%%d.%df \\pm %%%d.%df \\pm %%%d.%df $", -scientificNotation,-scientificNotation,-scientificNotation,-scientificNotation, -scientificNotation,-scientificNotation);
a2cfdbe4 237 sprintf(col, format ,TMath::Nint(val*TMath::Power(10,-scientificNotation))/TMath::Power(10,-scientificNotation), TMath::Nint(err*TMath::Power(10,-scientificNotation))/TMath::Power(10,-scientificNotation), TMath::Nint(errSyst*TMath::Power(10,-scientificNotation))/TMath::Power(10,-scientificNotation));
24a1ac33 238 SetNextCol(col);
239 }
240 }
4c0d7bc7 241 else {
242 sprintf(col, " $%f \\pm %f \\pm %f$ ", val, err, errSyst);
243 SetNextCol(col);
244 }
245}
246
247// void AliLatexTable::SetNextColPrintf(const char *va_(fmt), ...){
248
249
250// const Int_t buf_size = 1024; // hope it's long enough
251// char colBuffer[buf_size];
252
253// va_list ap;
254// va_start(ap, va_(fmt));
255// Int_t n = vsnprintf(colBuffer, buf_size, fmt, ap);
256
257// if (n == -1 || n >= buf_size) {
258// Error("SetNextCol", "vsnprintf error!");
259// }
260
261// va_end(ap);
262
263// // for(int iobj=0; iobj<num; iobj++){ //Loop until all objects are added
264// // TH1 * obj = (TH1 *) va_arg(arguments, void *);
265// // returnValue = returnValue && AddObject(obj,(char*)fOptMany.Data(), EColor(iobj+1));
266// // }
267// SetNextCol(colBuffer);
268// }
269
270
271void AliLatexTable::SetNextCol(TString val){
272
273 // Set next column in current row - tstring
274
275 fCols->Add(new TObjString(val));
276 fNcolReady++;
277
278}
279
280void AliLatexTable::InsertCustomRow(TString row){
281 // insert a full row from string. Make sure you have all the columns
282 fRows->Add(new TObjString(row));
283}
284
285
286
287void AliLatexTable::InsertRow(){
288
289 // Insert the row, based on all the individual columns
290
291 if ( fNcolReady != fNcol) {
292 Warning("InsertRow", "Wrong number of cols: %d (!= %d)", fNcolReady, fNcol);
293 }
294
295 TString row = "";
296 for(Int_t icol = 0; icol < fNcol; icol++){
297 row = row + ((TObjString*) fCols->At(icol))->String();
298 if(icol != (fNcol-1)) row = row + " & ";
299 }
300 row+="\\\\";
301
302 fRows->Add(new TObjString(row));
303
304 fNcolReady = 0;
305 fCols->Clear();
306
307}
308
309void AliLatexTable::InsertHline(){
310
311 // insert an horizontal line
312 fRows->Add(new TObjString("\\hline"));
313
314
315}
316
317Int_t * AliLatexTable::GetColWidths() {
318
319 // Compute the width of columns, for nice ascii printing
320
321 Int_t * col_widths= new Int_t[fNcol];
322 Int_t nrow = fRows->GetEntriesFast();
323
324 for(Int_t icol = 0; icol < fNcol; icol++){
325 col_widths[icol] = 0;
326 }
327
328
329 for(Int_t irow = 0; irow < nrow; irow++){
330 TString row(((TObjString*) fRows->At(irow))->String());
331 if(row.Contains("\\hline"))continue;
332
333 StripLatex(row, "ASCII");
334
335 TObjArray * cols = row.Tokenize("&");
336 if(cols->GetEntries() != fNcol) {
337 Error("GetColWidths", "Wrong number of cols in row %s: %d - %d", row.Data(), cols->GetEntries(), fNcol);
338 }
339 for(Int_t icol = 0; icol < fNcol; icol++){
340 Int_t w = ((TObjString *) cols->At(icol))->String().Length();
341 if (w>col_widths[icol]) col_widths[icol] = w;
342 }
343
344 }
345
346 return col_widths;
347}
348
349void AliLatexTable::PrintTable(Option_t * opt){
350
351 // Print the table on screen. You can specify the format with opt.
352 // Currently supported:
353 // "" -> LaTeX
354 // "ASCII" -> plain ASCII
355 // "HTML" -> HTML, to be improved
92da8c93 356 // "CSV" -> skips hline, usefult for importing in excell
57a944cd 357 // "TWIKI" -> skips hline, usefult for importing in TWIKI
4c0d7bc7 358
57a944cd 359 if(TString(opt) == "ASCII" || TString(opt)=="HTML" || TString(opt)=="CSV" || TString(opt)=="TWIKI") {
4c0d7bc7 360
361 Int_t nrow = fRows->GetEntriesFast();
362
363 Int_t * col_widths = GetColWidths();
364
365 Int_t total_lenght = 0;
366 for(Int_t icol = 0; icol < fNcol; icol++) total_lenght = total_lenght + col_widths[icol] + 2 ;
367
368
369 for(Int_t irow = 0; irow < nrow; irow++){
370 TString row = ((TObjString*) fRows->At(irow))->String();
92da8c93 371 if (row.Contains("\\hline")){
57a944cd 372 if (TString(opt)!="CSV" && TString(opt)!="TWIKI") {
92da8c93 373 for(Int_t il = 0; il < total_lenght; il++) printf("-");
374 printf("\n");
375 }
4c0d7bc7 376 continue;
377 }
378 StripLatex(row, opt);
379 TObjArray * cols = row.Tokenize("&");
57a944cd 380 if (TString(opt)=="TWIKI") printf(" | ");
4c0d7bc7 381 for(Int_t icol = 0; icol < fNcol; icol++){
57a944cd 382 TString strTmp = ((TObjString *) cols->At(icol))->String();
383 if(TString(opt)=="TWIKI" || TString(opt)=="HTML"){
384 strTmp.ReplaceAll("AMPER","&");
385 }
386 const char * colstr = strTmp.Data();
4c0d7bc7 387 char format [200];
92da8c93 388 if (TString(opt)!="CSV") {
389 sprintf(format, "%%%ds", col_widths[icol] + 2);
390 } else {
391 sprintf(format, "%%s");
392 }
4c0d7bc7 393 printf(format, colstr);
92da8c93 394 if (TString(opt)=="CSV") printf(", ");
57a944cd 395 if (TString(opt)=="TWIKI") printf(" | ");
4c0d7bc7 396
397 }
398 printf ("\n");
399 }
400
401
402 return;
403 }
404
405
406 cout << "\\begin{tabular}{"<<fFormat<<"}"<<endl;
407
408 Int_t nrow = fRows->GetEntriesFast();
409
410 for(Int_t irow = 0; irow < nrow; irow++){
411 cout << ((TObjString*) fRows->At(irow))->String() << endl;
412 }
413
414 cout << "\\end{tabular}" << endl;
415
416
417}
418
419// void AliLatexTable::ParseExponent(TString &expo){
420// // TString parseExponent = col;
421// TRegexp re = "e[+-][0-9][0-9]";
422// // cout << col << endl;
423
424// if(expo.Contains(re)){
425// Int_t index = expo.Index(re);
426// TString replacement = "\\cdot 10^{";
427// replacement = replacement + expo(index+1, 3) +"}";
428// // cout << replacement <<" --- "<< endl;
429// replacement.ReplaceAll("+","");
430// // cout << "B: " << expo << endl;
431// // cout << "RE " << expo(re) << endl;
432
433// expo.ReplaceAll(expo(re), replacement);
434// // cout << "A: " << expo << endl;
435// // recursion to parse all exponents
436// if (expo.Contains(re)) ParseExponent(expo);
437// }
438// else Warning("", "Error parsing exponent");
439// }
440
441void AliLatexTable::GetMantissaAndExpBase10(Double_t num, Double_t &man, Double_t &exp) {
442
443 // Helper used to get mantissa and exponent
444
445 exp = TMath::Floor(TMath::Log10(TMath::Abs(num)));
446 man = num / TMath::Power(10, exp);
447
448// cout << "" << endl;
449// cout << num << " = " << man << " x10^{"<<exp<<"} " << endl;
450
451
452}
453
454void AliLatexTable::StripLatex(TString &text, TString format) {
455
456 // Strip latex away for ascii and html printing. Replaces latex
457 // command with corresponding text/tags
458
459 text.ReplaceAll("\\cdot", "x");
4c0d7bc7 460 text.ReplaceAll("$", "");
461 if (format == "ASCII") {
462 text.ReplaceAll("\\right>", ">");
463 text.ReplaceAll("\\left<", "<");
464 text.ReplaceAll("\\rangle", ">");
465 text.ReplaceAll("\\langle", "<");
57a944cd 466 text.ReplaceAll("\\pm", "+-");
467 } else if (format == "HTML" || format == "TWIKI") {
468 // the & is used to tokenize... Have to cheat here
469 text.ReplaceAll("\\right>", "AMPERrang;");
470 text.ReplaceAll("\\left<", "AMPERlang;");
471 text.ReplaceAll("\\rangle", "AMPERrang;");
472 text.ReplaceAll("\\langle", "AMPERlang;");
473 text.ReplaceAll("\\pm", "AMPERplusmn;");
4c0d7bc7 474 }
475 if(text.Contains("multicolumn")) {
476 // cout << "col " << text.Data() << endl;
477 // in case of multicol span, replace first column with content and
478 // add n empty cols
fff5b67e 479 TObjArray * array = TPRegexp("multicolumn\\{(.*)\\}\\{.*\\}\\{(.*)\\}").MatchS(text); // Added double \\ because gcc 4 triggers hard error on unknown escape sequence. Hope it still works...
4c0d7bc7 480 const TString content = ((TObjString *)array->At(2))->GetString();
481 Int_t nspan = ((TObjString *)array->At(1))->GetString().Atoi();
482 text = content;
483// cout << "ns " << nspan << ((TObjString *)array->At(1))->GetString() << endl;
484// cout << "t " << text << endl;
485
486 for(Int_t ispan = 1; ispan < nspan; ispan++){
487 text+=" & ";
488 }
489 // cout << "t " << text << endl;
490
491
492 }
493
494 text.ReplaceAll("\\mathrm", "");
495
496 text.ReplaceAll("\\", "");
497 text.Strip(TString::EStripType(1), ' ');
498
499}
048a89c1 500
501void AliLatexTable::LoadTeXFromFileAndPrintASCII(const char * filename) {
502
503 // opens a file containing only a latex table and prints it on screen as ASCII
504
505 ifstream file (filename);
506 if (!file.is_open()) {
507 AliError(Form("Cannot open file %s", filename));
508 }
509 TString line;
510 while (line.ReadLine(file)) {
511 if (line.Contains("begin") && line.Contains("tabular")) {
512 // We need to get and parse the format
513 // TPRegexp re("\\begin\\{tabular\\}\\{([^\\}]*)\\}");
514 TPRegexp re(".*begin{tabular}{(.*)}");
515 TObjArray * arr = re.MatchS(line);
516 if (arr->GetLast() > 0){
517 // cout << "Size: " << arr->GetSize() << " " << arr->GetLast() << endl;
518
519 TString subStr = ((TObjString *)arr->At(1))->GetString();
520 subStr.ReplaceAll("|","");
521 subStr.ReplaceAll(" ","");
522 subStr.ReplaceAll("\t","");
523 // subStr.ReplaceAll(" ","");
524 // cout << subStr.Data() << " " << subStr.Length()<< endl;
525 fNcol = subStr.Length();
526 delete arr;
527 }
528 }
529
530 // Skip stuff we don't parse
531 if (line.Contains("begin")) continue;
532 if (line.Contains("end")) continue;
533 if (line.Contains("tabular")) continue;
534 // add line
535 InsertCustomRow(line.Data());
536
537 }
538 PrintTable("ASCII");
539}