Improved rounding and alignment of output text files
authormfloris <mfloris@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 17 Oct 2013 06:50:55 +0000 (06:50 +0000)
committermfloris <mfloris@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 17 Oct 2013 06:50:55 +0000 (06:50 +0000)
ANALYSIS/AliHEPDataParser.cxx
ANALYSIS/AliHEPDataParser.h

index 4d41a83..4f9e1d6 100644 (file)
 #include "TH1.h"
 #include "TObjArray.h"
 #include "TObjString.h"
+#include "TMath.h"
 #include <fstream>
 #include <iostream>
 using namespace std;
 
 ClassImp(AliHEPDataParser)
 
-AliHEPDataParser::AliHEPDataParser() : TObject(), fHistStat(0),  fHistSyst(0),  fGraphStat(0),  fGraphSyst(0),  fHEPDataFileLines(0), fValueName("")
+AliHEPDataParser::AliHEPDataParser() : TObject(), fHistStat(0),  fHistSyst(0),  fGraphStat(0),  fGraphSyst(0),  fHEPDataFileLines(0), fValueName(""), fXaxisName(""), fTitle(""), fReaction(""), fEnergy(""), fRapidityRange(""), fPrecision(5)
 {
   // default ctor
 
 }
 
-AliHEPDataParser::AliHEPDataParser(TH1 * hStat, TH1 * hSyst): TObject(), fHistStat(0),  fHistSyst(0),  fGraphStat(0),  fGraphSyst(0),  fHEPDataFileLines(0), fValueName("y")
+AliHEPDataParser::AliHEPDataParser(TH1 * hStat, TH1 * hSyst): TObject(), fHistStat(0),  fHistSyst(0),  fGraphStat(0),  fGraphSyst(0),  fHEPDataFileLines(0), fValueName("y"), fXaxisName(""), fTitle(""), fReaction(""), fEnergy(""), fRapidityRange(""), fPrecision(5)
 {
   //ctor
   fHistStat = hStat;
@@ -42,7 +43,7 @@ AliHEPDataParser::AliHEPDataParser(TH1 * hStat, TH1 * hSyst): TObject(), fHistSt
   fHEPDataFileLines = new TObjArray;
 
 }
-AliHEPDataParser::AliHEPDataParser(TGraph * grStat, TGraph * grSyst): TObject(), fHistStat(0),  fHistSyst(0),  fGraphStat(0),  fGraphSyst(0),  fHEPDataFileLines(0), fValueName("")
+AliHEPDataParser::AliHEPDataParser(TGraph * grStat, TGraph * grSyst): TObject(), fHistStat(0),  fHistSyst(0),  fGraphStat(0),  fGraphSyst(0),  fHEPDataFileLines(0), fValueName(""), fXaxisName(""), fTitle(""), fReaction(""), fEnergy(""), fRapidityRange(""), fPrecision(5)
 {
   // ctor
   fGraphStat = grStat;
@@ -61,25 +62,37 @@ AliHEPDataParser::AliHEPDataParser(const char * hepfileName): TObject(), fHistSt
   TString line;
   Int_t ipoints = 0;
   while (line.ReadLine(infile)) {
-    TObjArray * tokens = line.Tokenize(" ");
-    if(tokens->GetEntries() < 1) {
+    TObjArray * tokens = line.Tokenize(" \t");
+    if(! ((TObjString*) tokens->At(0))->String().Atof()) {
+      //The first column is not a number: those are the headers: skip!
       delete tokens;
-      AliError("not enough columns");
+      continue;
+    }
+    if(tokens->GetEntries() != 8) {
+      // this should never happen!
+      delete tokens;
+      AliError(Form("Wrong number of columns %d! Assuming [x xlow xhigh y dystat+ dystat- dysyst+ dysyst-]", tokens->GetEntries()));
+      cout << line.Data() << endl;
       return;      
+      //continue;
     }
-    // TODO: Assumes the format
-    // binmin binmax y +-stat +-syst. Try to make it smarter...
-    TObjString * binMin = (TObjString*) tokens->At(0);
-    TObjString * binMax = (TObjString*) tokens->At(1);
-    TObjString * value  = (TObjString*) tokens->At(2);
-    TObjString * stat   = (TObjString*) tokens->At(3);
-    TObjString * syst   = (TObjString*) tokens->At(4);
-    stat->String().ReplaceAll("+-","");
-    if(syst) syst->String().ReplaceAll("+-","");
-    if (!binMin->String().Atof()) {delete tokens; continue;} // skip headers
-    Float_t binCenter = (binMax->String().Atof() + binMin->String().Atof())/2;
-    Float_t binWidth  =  (binMax->String().Atof() - binMin->String().Atof())/2;
-    cout << line.Data() << endl;//<< " " << binMin->String().Atof() <<" " <<  binCenter << " " << binWidth << endl;
+    // FIXME: Assumes the format
+    // x xlow xhigh y dystat+ dystat- dysyst+ dysyst-
+    TObjString * xbin   = (TObjString*) tokens->At(0);
+    TObjString * xlow   = (TObjString*) tokens->At(1);
+    TObjString * xhigh  = (TObjString*) tokens->At(2);
+    TObjString * value  = (TObjString*) tokens->At(3);
+    TObjString * statp  = (TObjString*) tokens->At(4);
+    TObjString * statm  = (TObjString*) tokens->At(5);
+    TObjString * systp  = (TObjString*) tokens->At(6);
+    TObjString * systm  = (TObjString*) tokens->At(7);
+    statm->String().ReplaceAll("+-","");
+    statp->String().ReplaceAll("+-","");
+    if(systp) systp->String().ReplaceAll("+-","");
+    if(systm) systm->String().ReplaceAll("+-","");
+    //    if (!binMin->String().Atof()) {delete tokens; continue;} // skip headers
+    Float_t binCenter = xbin->String().Atof();
+    Float_t binWidth  =  (xlow->String().Atof() - xhigh->String().Atof())/2;
 
 
     fGraphStat->SetPoint(ipoints, binCenter, value->String().Atof());
@@ -87,13 +100,13 @@ AliHEPDataParser::AliHEPDataParser(const char * hepfileName): TObject(), fHistSt
     ((TGraphAsymmErrors*)fGraphStat)->SetPointError(ipoints, 
                                                    binWidth,
                                                    binWidth,
-                                                   stat->String().Atof(),
-                                                   stat->String().Atof());
-    if(syst) ((TGraphAsymmErrors*)fGraphSyst)->SetPointError(ipoints, 
-                                                            binWidth,
-                                                            binWidth,
-                                                            syst->String().Atof(),
-                                                            syst->String().Atof());
+                                                   statp->String().Atof(),
+                                                   statm->String().Atof());
+    if(systp && systm) ((TGraphAsymmErrors*)fGraphSyst)->SetPointError(ipoints, 
+                                                             binWidth,
+                                                             binWidth,
+                                                             systp->String().Atof(),
+                                                             systm->String().Atof());
     ipoints++;
     delete tokens;
   }
@@ -112,9 +125,21 @@ AliHEPDataParser::~AliHEPDataParser(){
 }
   
 void AliHEPDataParser::SaveHEPDataFile(const char * hepfileName, Bool_t trueUseGraphFalesUseHisto) {
+
   // Fills fHEPDataFileLines and saves its content to a file
   if(!fHEPDataFileLines)   fHEPDataFileLines = new TObjArray;
+  // Write headers if relevant
+  if(fTitle.Length())         fHEPDataFileLines->Add(new TObjString(fTitle));
+  if(fReaction.Length())      fHEPDataFileLines->Add(new TObjString(fReaction));
+  if(fEnergy.Length())        fHEPDataFileLines->Add(new TObjString(fEnergy));
+  if(fRapidityRange.Length()) fHEPDataFileLines->Add(new TObjString(fRapidityRange));
+  if(!fValueName.Length() || !fXaxisName.Length()) AliFatal("At least x and y titles should be given!");
+  fHEPDataFileLines->Add(new TObjString(Form("x: %s", fXaxisName.Data())));
+  fHEPDataFileLines->Add(new TObjString(Form("y: %s", fValueName.Data())));
+
+
   if(trueUseGraphFalesUseHisto) {
+    AliWarning("Graph saving not thoroughly tested!!");
     if(!fGraphStat) {
       AliError("Graph not set");
       return;
@@ -128,46 +153,65 @@ void AliHEPDataParser::SaveHEPDataFile(const char * hepfileName, Bool_t trueUseG
     for(Int_t ipoint = 0; ipoint < npoint; ipoint++){            
       if(ipoint == 0) {
        if(fGraphSyst) {
-         if (asym)
-           fHEPDataFileLines->Add(new TObjString(Form("BinCenter %s +stat -stat +syst -syst", fValueName.Data()))); 
-         else 
-           fHEPDataFileLines->Add(new TObjString(Form("BinCenter %s +-stat +-syst", fValueName.Data()))); 
+         fHEPDataFileLines->Add(new TObjString("x\txlow\txhigh\t+stat\t-stat\t+syst\t-syst"));
        }
        else {
-         if(asym)
-           fHEPDataFileLines->Add(new TObjString(Form("BinCenter %s +stat -stat", fValueName.Data()))); 
-         else 
-           fHEPDataFileLines->Add(new TObjString(Form("BinCenter %s +-stat", fValueName.Data()))); 
+         fHEPDataFileLines->Add(new TObjString("x\txlow\txhigh\t+stat\t-stat"));
        }
       }
       // Skip empty bins
       if(!fGraphStat->GetY()[ipoint]) continue;
-      TObjString * line = new TObjString;      
+      TObjString * line = new TObjString;    
+      fGraphStat->Print();
+      fGraphSyst->Print();
       if(fGraphSyst) {
        if (asym)
-         line->String().Form("%f %f +%f -%f +%f -%f", 
-                             fGraphStat->GetX()[ipoint], fGraphStat->GetY()[ipoint],
-                             ((TGraphAsymmErrors*)fGraphStat)->GetEYhigh()[ipoint], 
-                             ((TGraphAsymmErrors*)fGraphStat)->GetEYlow()[ipoint], 
-                             ((TGraphAsymmErrors*)fGraphSyst)->GetEYhigh()[ipoint], 
-                             ((TGraphAsymmErrors*)fGraphSyst)->GetEYlow()[ipoint]);
+         line->String().Form("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
+                             //        line->String().Form("%10s %10s %10s %10s %10s %10s %10s %10s", 
+                             GetFixWidthCol(fGraphStat->GetX()[ipoint],                                                                   10).Data(),                      
+                             GetFixWidthCol(RoundToSignificantFigures(fGraphStat->GetX()[ipoint]-((TGraphAsymmErrors*)fGraphStat)->GetEXlow()[ipoint],  fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(fGraphStat->GetX()[ipoint]+((TGraphAsymmErrors*)fGraphStat)->GetEXhigh()[ipoint], fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(fGraphStat->GetY()[ipoint],                            fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphAsymmErrors*)fGraphStat)->GetEYhigh()[ipoint], fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphAsymmErrors*)fGraphStat)->GetEYlow()[ipoint] , fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphAsymmErrors*)fGraphSyst)->GetEYhigh()[ipoint], fPrecision), 10).Data(),
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphAsymmErrors*)fGraphSyst)->GetEYlow()[ipoint] , fPrecision), 10).Data());
        else 
-         line->String().Form("%f %f +-%f +-%f", 
-                             fGraphStat->GetX()[ipoint], fGraphStat->GetY()[ipoint],
-                             ((TGraphErrors*)fGraphStat)->GetEY()[ipoint], 
-                             ((TGraphErrors*)fGraphSyst)->GetEY()[ipoint]);
+         line->String().Form("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
+                             //        line->String().Form("%10s %10s %10s %10s %10s %10s %10s %10s", 
+                             GetFixWidthCol(fGraphStat->GetX()[ipoint],                                                                   10).Data(),                      
+                             GetFixWidthCol(fGraphStat->GetX()[ipoint]-fGraphStat->GetEX()[ipoint],                                    10).Data(), 
+                             GetFixWidthCol(fGraphStat->GetX()[ipoint]+fGraphStat->GetEX()[ipoint],                                10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(fGraphStat->GetY()[ipoint],                            fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphErrors*)fGraphStat)->GetEY()[ipoint], fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphErrors*)fGraphStat)->GetEY()[ipoint], fPrecision), 10).Data(),
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphErrors*)fGraphSyst)->GetEY()[ipoint], fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphErrors*)fGraphSyst)->GetEY()[ipoint], fPrecision), 10).Data());
+         // line->String().Form("%f %f +-%f +-%f", 
+         //                  fGraphStat->GetX()[ipoint], RoundToSignificantFigures(fGraphStat->GetY()[ipoint],fPrecision),
+         //                  RoundToSignificantFigures(((TGraphErrors*)fGraphStat)->GetEY()[ipoint],fPrecision), 
+         //                  RoundToSignificantFigures(((TGraphErrors*)fGraphSyst)->GetEY()[ipoint],fPrecision));
 
        fHEPDataFileLines->Add(line);
       } else {
        if (asym)
-         line->String().Form("%f %f +%f -%f", 
-                             fGraphStat->GetX()[ipoint], fGraphStat->GetY()[ipoint],
-                             ((TGraphAsymmErrors*)fGraphStat)->GetEYhigh()[ipoint], ((TGraphAsymmErrors*)fGraphStat)->GetEYlow()[ipoint]);
-       else { 
-         line->String().Form("%f %f +-%f", 
-                             fGraphStat->GetX()[ipoint], fGraphStat->GetY()[ipoint],
-                             ((TGraphErrors*)fGraphStat)->GetEY()[ipoint]);
-       }
+         line->String().Form("%s\t%s\t%s\t%s\t%s\t%s",
+                             //        line->String().Form("%10s %10s %10s %10s %10s %10s %10s %10s", 
+                             GetFixWidthCol(fGraphStat->GetX()[ipoint],                                                                   10).Data(),                      
+                             GetFixWidthCol(fGraphStat->GetX()[ipoint]-fGraphStat->GetEXlow()[ipoint],                                    10).Data(), 
+                             GetFixWidthCol(fGraphStat->GetX()[ipoint]+fGraphStat->GetEXhigh()[ipoint],                                   10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(fGraphStat->GetY()[ipoint],                            fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphAsymmErrors*)fGraphStat)->GetEYhigh()[ipoint], fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphAsymmErrors*)fGraphStat)->GetEYlow()[ipoint] , fPrecision), 10).Data()); 
+       else 
+         line->String().Form("%s\t%s\t%s\t%s\t%s\t%s",
+                             //        line->String().Form("%10s %10s %10s %10s %10s %10s %10s %10s", 
+                             GetFixWidthCol(fGraphStat->GetX()[ipoint],                                                                   10).Data(),                      
+                             GetFixWidthCol(fGraphStat->GetX()[ipoint]-fGraphStat->GetEX()[ipoint],                                    10).Data(), 
+                             GetFixWidthCol(fGraphStat->GetX()[ipoint]+fGraphStat->GetEX()[ipoint],                                10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(fGraphStat->GetY()[ipoint],                            fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphErrors*)fGraphStat)->GetEY()[ipoint], fPrecision), 10).Data(), 
+                             GetFixWidthCol(RoundToSignificantFigures(((TGraphErrors*)fGraphStat)->GetEY()[ipoint], fPrecision), 10).Data());
 
        fHEPDataFileLines->Add(line);
       }
@@ -183,24 +227,35 @@ void AliHEPDataParser::SaveHEPDataFile(const char * hepfileName, Bool_t trueUseG
     for(Int_t ibin = 1; ibin <= nbin; ibin++){
       if(ibin == 1) {
        if(fHistSyst)
-         fHEPDataFileLines->Add(new TObjString(Form("BinLow BinHigh %s +-stat +-syst", fValueName.Data()))); 
+         fHEPDataFileLines->Add(new TObjString("x\t\txlow\t\txhigh\t\ty\t\tdystat+\t\tdystat-\t\tdysyst+\t\tdysyst-")); 
        else 
-         fHEPDataFileLines->Add(new TObjString(Form("BinLow BinHigh %s +-stat", fValueName.Data())));          
+         fHEPDataFileLines->Add(new TObjString("x\t\txlow\t\txhigh\t\ty\t\tdystat+\t\tdystat-"));              
       }
       // Skip empty bins
       if(!fHistStat->GetBinContent(ibin)) continue;
       TObjString * line = new TObjString;      
       if(fHistSyst) {
-       line->String().Form("%f %f %f +-%f +-%f", 
-                           fHistStat->GetBinLowEdge(ibin), 
-                           fHistStat->GetBinLowEdge(ibin)+fHistStat->GetBinWidth(ibin), 
-                           fHistStat->GetBinContent(ibin), fHistStat->GetBinError(ibin), fHistSyst->GetBinError(ibin));
+       
+       line->String().Form("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
+                           //  line->String().Form("%10s %10s %10s %10s %10s %10s %10s %10s", 
+                           GetFixWidthCol(fHistStat->GetBinLowEdge(ibin)+fHistStat->GetBinWidth(ibin)/2,         12).Data(),                       
+                           GetFixWidthCol(fHistStat->GetBinLowEdge(ibin),                                        12).Data(), 
+                           GetFixWidthCol(fHistStat->GetBinLowEdge(ibin)+fHistStat->GetBinWidth(ibin),           12).Data(), 
+                           GetFixWidthCol(RoundToSignificantFigures(fHistStat->GetBinContent(ibin),fPrecision),  12).Data(), 
+                           GetFixWidthCol(RoundToSignificantFigures(fHistStat->GetBinError(ibin),  fPrecision),  12).Data(), 
+                           GetFixWidthCol(RoundToSignificantFigures(fHistStat->GetBinError(ibin),  fPrecision),  12).Data(), 
+                           GetFixWidthCol(RoundToSignificantFigures(fHistSyst->GetBinError(ibin),  fPrecision),  12).Data(),
+                           GetFixWidthCol(RoundToSignificantFigures(fHistSyst->GetBinError(ibin),  fPrecision),  12).Data());
+
        fHEPDataFileLines->Add(line);
       } else {
-       line->String().Form("%f %f %f +-%f", 
-                           fHistStat->GetBinLowEdge(ibin), 
-                           fHistStat->GetBinLowEdge(ibin)+fHistStat->GetBinWidth(ibin), 
-                           fHistStat->GetBinContent(ibin), fHistStat->GetBinError(ibin));
+       line->String().Form("%s\t%s\t%s\t%s\t%s\t%s", 
+                           GetFixWidthCol(fHistStat->GetBinLowEdge(ibin)+fHistStat->GetBinWidth(ibin)/2,         10).Data(),                       
+                           GetFixWidthCol(fHistStat->GetBinLowEdge(ibin),                                        10).Data(), 
+                           GetFixWidthCol(fHistStat->GetBinLowEdge(ibin)+fHistStat->GetBinWidth(ibin),           10).Data(), 
+                           GetFixWidthCol(RoundToSignificantFigures(fHistStat->GetBinContent(ibin),fPrecision),  10).Data(), 
+                           GetFixWidthCol(RoundToSignificantFigures(fHistStat->GetBinError(ibin),  fPrecision),  10).Data(), 
+                           GetFixWidthCol(RoundToSignificantFigures(fHistStat->GetBinError(ibin),  fPrecision),  10).Data()); 
        fHEPDataFileLines->Add(line);
       }
       //      delete line;      
@@ -221,3 +276,37 @@ void AliHEPDataParser::SaveHEPDataFile(const char * hepfileName, Bool_t trueUseG
 }
 
 
+Double_t AliHEPDataParser::RoundToSignificantFigures(double num, int n) {
+  // Rounds num to n significant digits.
+  // Recipe from :http://stackoverflow.com/questions/202302/rounding-to-an-arbitrary-number-of-significant-digits
+  // Basically the log is used to determine the number of leading 0s, than convert to an integer by multipliing by the expo, 
+  // round the integer and shift back.
+  if(num == 0) {
+    return 0;
+  }
+
+  Double_t d = TMath::Ceil(TMath::Log10(num < 0 ? -num: num));
+  Int_t power = n - (int) d;
+
+  Double_t magnitude = TMath::Power(10, power);
+  Long_t shifted = TMath::Nint(num*magnitude);
+  return shifted/magnitude;
+
+}
+
+TString AliHEPDataParser::GetFixWidthCol(Double_t number, Int_t width) {
+
+  // Formats a column to fixed width
+  TString col;
+  char format[100];
+  snprintf(format,100,"%%%d#g", fPrecision);
+  col.Form(format, number);
+  if(col.Length()>width) AliError("larger than width, cannot align!");
+
+  if(col.Contains("e"))
+    while (col.Length() < width) col.Append(" ");
+  else
+    while (col.Length() < width) col.Append("0");
+  
+  return col;
+}
index df3be38..ff58e2a 100644 (file)
@@ -37,18 +37,34 @@ public:
   void SaveHEPDataFile(const char * hepfileName, Bool_t trueUseGraphFalesUseHisto = 0);
 
   void SetName(const char * name) { fValueName = name;}
+  void SetXaxisName (TString val) {fXaxisName = val ;}
+  void SetTitle(TString val) {fTitle = val;}
+  void SetReaction(TString val) {fReaction = val;}
+  void SetEnergy(TString val) {fEnergy = val;}
+  void SetRapidityRange(TString val) {fRapidityRange = val;}
+  void SetPrecision(Int_t   val) {fPrecision = val;}
+
 
 protected:
 
+  Double_t RoundToSignificantFigures(double num, int n) ;
+  TString GetFixWidthCol(Double_t number, Int_t width) ;
+
+
   TH1 * fHistStat; // statistical errors (hist)
   TH1 * fHistSyst; // systematic errors (hist) 
   TGraph * fGraphStat; // statistical errors (hist)
   TGraph * fGraphSyst; // systematic errors (hist)  
   TObjArray * fHEPDataFileLines;// TClones array of TObjString
   TString fValueName; // title for the y axis on the ascii file
-
-
-  ClassDef(AliHEPDataParser, 1);
+  TString fXaxisName; // title for the y axis
+  TString fTitle; // title for the HEP DATA file
+  TString fReaction; // Raction ,e.g. RE : Pb + Pb --> pbar + X
+  TString fEnergy; // Raction ,e.g. sqrts : 2760 GeV
+  TString fRapidityRange; // Rapidity ABS(YRAP) : 0.5'
+  Int_t   fPrecision; // number of significant figures for rounding
+
+  ClassDef(AliHEPDataParser, 2);
     
 private: