set centrality from outside
[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
92void AliLatexTable::SetNextCol(Double_t val, Int_t scientificNotation){
93
94 // Set next column in current row - double, specify resolution
95
96 char col[200];
97 if(scientificNotation >= 0) {
98 char format[100];
99
100 // cout << format << endl;
101 Double_t mantissa, exp;
102 GetMantissaAndExpBase10(val, mantissa, exp);
103
104 if (exp == 0) {
105 sprintf(format, " $%%%d.%df $", scientificNotation, scientificNotation);
106 sprintf(col, format, mantissa);
107 }
108 else {
109 sprintf(format, " $%%%d.%df \\cdot 10^{%%0.0f} $", scientificNotation, scientificNotation);
110 sprintf(col, format, mantissa, exp);
111 }
112
113
114
115
116 SetNextCol(col);
117
118 } else if (scientificNotation < -1) {
119 char format[100];
120 sprintf(format, " $%%%d.%df $", -scientificNotation,-scientificNotation);
121 sprintf(col, format , val);
122 SetNextCol(col);
123 } else {
124 sprintf(col, " %f ", val);
125 SetNextCol(col);
126 }
127
128}
129void AliLatexTable::SetNextCol(Double_t val, Double_t err, Int_t scientificNotation){
130
131 // Set next column in current row - double +- double, specify resolution
132
133 // if scientific notation is != -1 is used to determine number of
134 // digits in error
135
136 //if it is > 0 exp notation is used
137
138 //if it is < -1 number is truncated to the number of digits after
139 //point dictated by scientificNotation,
140
141 char col[200];
142 if(scientificNotation >=0 ) {
143
144 Double_t mantissa, exp;
145 GetMantissaAndExpBase10(val, mantissa, exp);
146
147 Double_t mantissa_err, exp_err;
148 GetMantissaAndExpBase10(err, mantissa_err, exp_err);
149
150 Int_t nSigDigits =TMath::Nint(exp - exp_err);
151 if(scientificNotation != 0) nSigDigits = nSigDigits + scientificNotation - 1;
152
153
154 char format[100];
155 if (exp == 0) {
156 sprintf(format, " $%%%d.%df \\pm %%%d.%df $", nSigDigits, nSigDigits, nSigDigits, nSigDigits);
157 sprintf(col, format, mantissa, mantissa_err/TMath::Power(10,exp - exp_err));
158 }
159 else {
160 sprintf(format, " $%%%d.%df \\pm %%%d.%df \\cdot 10^{%%0.0f}$", nSigDigits, nSigDigits, nSigDigits, nSigDigits);
161 sprintf(col, format, mantissa, mantissa_err/TMath::Power(10,exp - exp_err), exp);
162 }
163
164
165 //cout << format << endl;
166
167 SetNextCol(col);
168
169 } else if (scientificNotation < -1) {
170 char format[100];
171 sprintf(format, " $%%%d.%df \\pm %%%d.%df $", -scientificNotation,-scientificNotation,-scientificNotation,-scientificNotation);
172 sprintf(col, format , val, err);
173 SetNextCol(col);
174 }
175 else {
176 sprintf(col, " $%f \\pm %f$ ", val, err);
177 SetNextCol(col);
178 }
179}
180
181void AliLatexTable::SetNextCol(Double_t val, Double_t err, Double_t errSyst, Int_t scientificNotation){
182
183 // Set next column in current row - double +- double +- double, specify resolution
184
185 // if scientific notation is != -1 is used to determine number of
186 // digits in error
187
188 //if it is > 0 exp notation is used
189
190 //if it is < -1 number is truncated to the number of digits after
191 //point dictated by scientificNotation,
192
193 char col[200];
194 if(scientificNotation >=0 ) {
195
196 Double_t mantissa, exp;
197 GetMantissaAndExpBase10(val, mantissa, exp);
198
199 Double_t mantissa_err, exp_err;
200 GetMantissaAndExpBase10(err, mantissa_err, exp_err);
201
202 Double_t mantissa_errsyst, exp_errsyst;
203 GetMantissaAndExpBase10(errSyst, mantissa_errsyst, exp_errsyst);
204
205 Int_t nSigDigits =TMath::Nint(exp - exp_err);
206 if(scientificNotation != 0) nSigDigits = nSigDigits + scientificNotation - 1;
207
208
209 char format[100];
210 if (exp == 0) {
211 sprintf(format, " $%%%d.%df \\pm %%%d.%df \\pm %%%d.%df $",
212 nSigDigits, nSigDigits, nSigDigits, nSigDigits, nSigDigits, nSigDigits);
213 sprintf(col, format, mantissa,
214 mantissa_err/TMath::Power(10,exp - exp_err),
215 mantissa_errsyst/TMath::Power(10,exp - exp_errsyst));
216 }
217 else {
218 sprintf(format, " $%%%d.%df \\pm %%%d.%df \\pm %%%d.%df \\cdot 10^{%%0.0f}$",
219 nSigDigits, nSigDigits, nSigDigits, nSigDigits, nSigDigits, nSigDigits);
220 sprintf(col, format, mantissa,
221 mantissa_err/TMath::Power(10,exp - exp_err),
222 mantissa_errsyst/TMath::Power(10,exp - exp_errsyst),
223 exp);
224 }
225
226
227 //cout << format << endl;
228
229 SetNextCol(col);
230
231 } else if (scientificNotation < -1) {
232 char format[100];
233 sprintf(format, " $%%%d.%df \\pm %%%d.%df \\pm %%%d.%df $", -scientificNotation,-scientificNotation,-scientificNotation,-scientificNotation, -scientificNotation,-scientificNotation);
234 sprintf(col, format , val, err);
235 SetNextCol(col);
236 }
237 else {
238 sprintf(col, " $%f \\pm %f \\pm %f$ ", val, err, errSyst);
239 SetNextCol(col);
240 }
241}
242
243// void AliLatexTable::SetNextColPrintf(const char *va_(fmt), ...){
244
245
246// const Int_t buf_size = 1024; // hope it's long enough
247// char colBuffer[buf_size];
248
249// va_list ap;
250// va_start(ap, va_(fmt));
251// Int_t n = vsnprintf(colBuffer, buf_size, fmt, ap);
252
253// if (n == -1 || n >= buf_size) {
254// Error("SetNextCol", "vsnprintf error!");
255// }
256
257// va_end(ap);
258
259// // for(int iobj=0; iobj<num; iobj++){ //Loop until all objects are added
260// // TH1 * obj = (TH1 *) va_arg(arguments, void *);
261// // returnValue = returnValue && AddObject(obj,(char*)fOptMany.Data(), EColor(iobj+1));
262// // }
263// SetNextCol(colBuffer);
264// }
265
266
267void AliLatexTable::SetNextCol(TString val){
268
269 // Set next column in current row - tstring
270
271 fCols->Add(new TObjString(val));
272 fNcolReady++;
273
274}
275
276void AliLatexTable::InsertCustomRow(TString row){
277 // insert a full row from string. Make sure you have all the columns
278 fRows->Add(new TObjString(row));
279}
280
281
282
283void AliLatexTable::InsertRow(){
284
285 // Insert the row, based on all the individual columns
286
287 if ( fNcolReady != fNcol) {
288 Warning("InsertRow", "Wrong number of cols: %d (!= %d)", fNcolReady, fNcol);
289 }
290
291 TString row = "";
292 for(Int_t icol = 0; icol < fNcol; icol++){
293 row = row + ((TObjString*) fCols->At(icol))->String();
294 if(icol != (fNcol-1)) row = row + " & ";
295 }
296 row+="\\\\";
297
298 fRows->Add(new TObjString(row));
299
300 fNcolReady = 0;
301 fCols->Clear();
302
303}
304
305void AliLatexTable::InsertHline(){
306
307 // insert an horizontal line
308 fRows->Add(new TObjString("\\hline"));
309
310
311}
312
313Int_t * AliLatexTable::GetColWidths() {
314
315 // Compute the width of columns, for nice ascii printing
316
317 Int_t * col_widths= new Int_t[fNcol];
318 Int_t nrow = fRows->GetEntriesFast();
319
320 for(Int_t icol = 0; icol < fNcol; icol++){
321 col_widths[icol] = 0;
322 }
323
324
325 for(Int_t irow = 0; irow < nrow; irow++){
326 TString row(((TObjString*) fRows->At(irow))->String());
327 if(row.Contains("\\hline"))continue;
328
329 StripLatex(row, "ASCII");
330
331 TObjArray * cols = row.Tokenize("&");
332 if(cols->GetEntries() != fNcol) {
333 Error("GetColWidths", "Wrong number of cols in row %s: %d - %d", row.Data(), cols->GetEntries(), fNcol);
334 }
335 for(Int_t icol = 0; icol < fNcol; icol++){
336 Int_t w = ((TObjString *) cols->At(icol))->String().Length();
337 if (w>col_widths[icol]) col_widths[icol] = w;
338 }
339
340 }
341
342 return col_widths;
343}
344
345void AliLatexTable::PrintTable(Option_t * opt){
346
347 // Print the table on screen. You can specify the format with opt.
348 // Currently supported:
349 // "" -> LaTeX
350 // "ASCII" -> plain ASCII
351 // "HTML" -> HTML, to be improved
92da8c93 352 // "CSV" -> skips hline, usefult for importing in excell
4c0d7bc7 353
92da8c93 354 if(TString(opt) == "ASCII" || TString(opt)=="HTML" || TString(opt)=="CSV") {
4c0d7bc7 355
356 Int_t nrow = fRows->GetEntriesFast();
357
358 Int_t * col_widths = GetColWidths();
359
360 Int_t total_lenght = 0;
361 for(Int_t icol = 0; icol < fNcol; icol++) total_lenght = total_lenght + col_widths[icol] + 2 ;
362
363
364 for(Int_t irow = 0; irow < nrow; irow++){
365 TString row = ((TObjString*) fRows->At(irow))->String();
92da8c93 366 if (row.Contains("\\hline")){
367 if (TString(opt)!="CSV") {
368 for(Int_t il = 0; il < total_lenght; il++) printf("-");
369 printf("\n");
370 }
4c0d7bc7 371 continue;
372 }
373 StripLatex(row, opt);
374 TObjArray * cols = row.Tokenize("&");
375 for(Int_t icol = 0; icol < fNcol; icol++){
376 const char * colstr = ((TObjString *) cols->At(icol))->String().Data();
377 char format [200];
92da8c93 378 if (TString(opt)!="CSV") {
379 sprintf(format, "%%%ds", col_widths[icol] + 2);
380 } else {
381 sprintf(format, "%%s");
382 }
4c0d7bc7 383 printf(format, colstr);
92da8c93 384 if (TString(opt)=="CSV") printf(", ");
4c0d7bc7 385
386 }
387 printf ("\n");
388 }
389
390
391 return;
392 }
393
394
395 cout << "\\begin{tabular}{"<<fFormat<<"}"<<endl;
396
397 Int_t nrow = fRows->GetEntriesFast();
398
399 for(Int_t irow = 0; irow < nrow; irow++){
400 cout << ((TObjString*) fRows->At(irow))->String() << endl;
401 }
402
403 cout << "\\end{tabular}" << endl;
404
405
406}
407
408// void AliLatexTable::ParseExponent(TString &expo){
409// // TString parseExponent = col;
410// TRegexp re = "e[+-][0-9][0-9]";
411// // cout << col << endl;
412
413// if(expo.Contains(re)){
414// Int_t index = expo.Index(re);
415// TString replacement = "\\cdot 10^{";
416// replacement = replacement + expo(index+1, 3) +"}";
417// // cout << replacement <<" --- "<< endl;
418// replacement.ReplaceAll("+","");
419// // cout << "B: " << expo << endl;
420// // cout << "RE " << expo(re) << endl;
421
422// expo.ReplaceAll(expo(re), replacement);
423// // cout << "A: " << expo << endl;
424// // recursion to parse all exponents
425// if (expo.Contains(re)) ParseExponent(expo);
426// }
427// else Warning("", "Error parsing exponent");
428// }
429
430void AliLatexTable::GetMantissaAndExpBase10(Double_t num, Double_t &man, Double_t &exp) {
431
432 // Helper used to get mantissa and exponent
433
434 exp = TMath::Floor(TMath::Log10(TMath::Abs(num)));
435 man = num / TMath::Power(10, exp);
436
437// cout << "" << endl;
438// cout << num << " = " << man << " x10^{"<<exp<<"} " << endl;
439
440
441}
442
443void AliLatexTable::StripLatex(TString &text, TString format) {
444
445 // Strip latex away for ascii and html printing. Replaces latex
446 // command with corresponding text/tags
447
448 text.ReplaceAll("\\cdot", "x");
449 text.ReplaceAll("\\pm", "+-");
450 text.ReplaceAll("$", "");
451 if (format == "ASCII") {
452 text.ReplaceAll("\\right>", ">");
453 text.ReplaceAll("\\left<", "<");
454 text.ReplaceAll("\\rangle", ">");
455 text.ReplaceAll("\\langle", "<");
456 } else if (format == "HTML") {
457 text.ReplaceAll("\\right>", "&rang;");
458 text.ReplaceAll("\\left<", "&lang;");
459 text.ReplaceAll("\\rangle", "&rang;");
460 text.ReplaceAll("\\langle", "&lang;");
461 }
462 if(text.Contains("multicolumn")) {
463 // cout << "col " << text.Data() << endl;
464 // in case of multicol span, replace first column with content and
465 // add n empty cols
fff5b67e 466 TObjArray * array = TPRegexp("multicolumn\\{(.*)\\}\\{.*\\}\\{(.*)\\}").MatchS(text); // Added double \\ because gcc 4 triggers hard error on unknown escape sequence. Hope it still works...
4c0d7bc7 467 const TString content = ((TObjString *)array->At(2))->GetString();
468 Int_t nspan = ((TObjString *)array->At(1))->GetString().Atoi();
469 text = content;
470// cout << "ns " << nspan << ((TObjString *)array->At(1))->GetString() << endl;
471// cout << "t " << text << endl;
472
473 for(Int_t ispan = 1; ispan < nspan; ispan++){
474 text+=" & ";
475 }
476 // cout << "t " << text << endl;
477
478
479 }
480
481 text.ReplaceAll("\\mathrm", "");
482
483 text.ReplaceAll("\\", "");
484 text.Strip(TString::EStripType(1), ' ');
485
486}
048a89c1 487
488void AliLatexTable::LoadTeXFromFileAndPrintASCII(const char * filename) {
489
490 // opens a file containing only a latex table and prints it on screen as ASCII
491
492 ifstream file (filename);
493 if (!file.is_open()) {
494 AliError(Form("Cannot open file %s", filename));
495 }
496 TString line;
497 while (line.ReadLine(file)) {
498 if (line.Contains("begin") && line.Contains("tabular")) {
499 // We need to get and parse the format
500 // TPRegexp re("\\begin\\{tabular\\}\\{([^\\}]*)\\}");
501 TPRegexp re(".*begin{tabular}{(.*)}");
502 TObjArray * arr = re.MatchS(line);
503 if (arr->GetLast() > 0){
504 // cout << "Size: " << arr->GetSize() << " " << arr->GetLast() << endl;
505
506 TString subStr = ((TObjString *)arr->At(1))->GetString();
507 subStr.ReplaceAll("|","");
508 subStr.ReplaceAll(" ","");
509 subStr.ReplaceAll("\t","");
510 // subStr.ReplaceAll(" ","");
511 // cout << subStr.Data() << " " << subStr.Length()<< endl;
512 fNcol = subStr.Length();
513 delete arr;
514 }
515 }
516
517 // Skip stuff we don't parse
518 if (line.Contains("begin")) continue;
519 if (line.Contains("end")) continue;
520 if (line.Contains("tabular")) continue;
521 // add line
522 InsertCustomRow(line.Data());
523
524 }
525 PrintTable("ASCII");
526}