#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include "Riostream.h"
#include "TROOT.h"
#include "TGaxis.h"
#include "TVirtualPad.h"
#include "TVirtualX.h"
#include "TLine.h"
#include "TLatex.h"
#include "TStyle.h"
#include "TF1.h"
#include "TAxis.h"
#include "THashList.h"
#include "TObjString.h"
#include "TMath.h"
#include "THLimitsFinder.h"
#include "TColor.h"
#include "TClass.h"
#include "TTimeStamp.h"
Int_t TGaxis::fgMaxDigits = 5;
const Int_t kHori = BIT(9); 
ClassImp(TGaxis)
/*
<img src="gif/gaxis.gif">
*/
//End_Html
TGaxis::TGaxis(): TLine(), TAttText(11,0,1,62,0.040)
{
   fGridLength  = 0.;
   fLabelOffset = 0.005;
   fLabelSize   = 0.040;
   fLabelFont   = 62;
   fLabelColor  = 1;
   fTickSize    = 0.030;
   fTitleOffset = 1;
   fTitleSize   = fLabelSize;
   fChopt       = "";
   fName        = "";
   fTitle       = "";
   fTimeFormat  = "";
   fFunctionName= "";
   fFunction    = 0;
   fAxis        = 0;
}
TGaxis::TGaxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax,
               Double_t wmin, Double_t wmax, Int_t ndiv,   Option_t *chopt,
               Double_t gridlength)
       : TLine(xmin,ymin,xmax,ymax), TAttText(11,0,1,62,0.040)
{
   fWmin        = wmin;
   fWmax        = wmax;
   fNdiv        = ndiv;
   fGridLength  = gridlength;
   fLabelOffset = 0.005;
   fLabelSize   = 0.040;
   fLabelFont   = 62;
   fLabelColor  = 1;
   fTickSize    = 0.030;
   fTitleOffset = 1;
   fTitleSize   = fLabelSize;
   fChopt       = chopt;
   fName        = "";
   fTitle       = "";
   fTimeFormat  = "";
   fFunctionName= "";
   fFunction    = 0;
   fAxis        = 0;
}
TGaxis::TGaxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax,
               const char *funcname, Int_t ndiv,   Option_t *chopt,
               Double_t gridlength)
       : TLine(xmin,ymin,xmax,ymax), TAttText(11,0,1,62,0.040)
{
/*
<img src="gif/gaxisf1.gif">
*/
//End_Html
   fFunction = (TF1*)gROOT->GetFunction(funcname);
   if (!fFunction) {
      Error("TGaxis, calling constructor with an unknown function:%s",funcname);
      fWmin = 0;
      fWmax = 1;
   } else {
      fWmin = fFunction->GetXmin();
      fWmax = fFunction->GetXmax();
   }
   fFunctionName= funcname;
   fNdiv        = ndiv;
   fGridLength  = gridlength;
   fLabelOffset = 0.005;
   fLabelSize   = 0.040;
   fLabelFont   = 62;
   fLabelColor  = 1;
   fTickSize    = 0.030;
   fTitleOffset = 1;
   fTitleSize   = fLabelSize;
   fChopt       = chopt;
   fName        = "";
   fTitle       = "";
   fTimeFormat  = "";
   fAxis        = 0;
}
TGaxis::TGaxis(const TGaxis& ax) :
  TLine(ax),
  TAttText(ax),
  fWmin(ax.fWmin),
  fWmax(ax.fWmax),
  fGridLength(ax.fGridLength),
  fTickSize(ax.fTickSize),
  fLabelOffset(ax.fLabelOffset),
  fLabelSize(ax.fLabelSize),
  fTitleOffset(ax.fTitleOffset),
  fTitleSize(ax.fTitleSize),
  fNdiv(ax.fNdiv),
  fLabelColor(ax.fLabelColor),
  fLabelFont(ax.fLabelFont),
  fChopt(ax.fChopt),
  fName(ax.fName),
  fTitle(ax.fTitle),
  fTimeFormat(ax.fTimeFormat),
  fFunctionName(ax.fFunctionName),
  fFunction(ax.fFunction),
  fAxis(ax.fAxis)
{
   
}
TGaxis& TGaxis::operator=(const TGaxis& ax)
{
   
   if(this!=&ax) {
      TLine::operator=(ax);
      TAttText::operator=(ax);
      fWmin=ax.fWmin;
      fWmax=ax.fWmax;
      fGridLength=ax.fGridLength;
      fTickSize=ax.fTickSize;
      fLabelOffset=ax.fLabelOffset;
      fLabelSize=ax.fLabelSize;
      fTitleOffset=ax.fTitleOffset;
      fTitleSize=ax.fTitleSize;
      fNdiv=ax.fNdiv;
      fLabelColor=ax.fLabelColor;
      fLabelFont=ax.fLabelFont;
      fChopt=ax.fChopt;
      fName=ax.fName;
      fTitle=ax.fTitle;
      fTimeFormat=ax.fTimeFormat;
      fFunctionName=ax.fFunctionName;
      fFunction=ax.fFunction;
      fAxis=ax.fAxis;
   }
   return *this;
}
TGaxis::~TGaxis()
{
}
void TGaxis::CenterLabels(Bool_t center)
{
   if (center) SetBit(TAxis::kCenterLabels);
   else        ResetBit(TAxis::kCenterLabels);
}
void TGaxis::CenterTitle(Bool_t center)
{
   if (center) SetBit(TAxis::kCenterTitle);
   else        ResetBit(TAxis::kCenterTitle);
}
void TGaxis::DrawAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax,
                      Double_t wmin, Double_t wmax, Int_t ndiv,   Option_t *chopt,
                      Double_t gridlength)
{
   TGaxis *newaxis = new TGaxis(xmin,ymin,xmax,ymax,wmin,wmax,ndiv,chopt,gridlength);
   newaxis->SetLineColor(fLineColor);
   newaxis->SetLineWidth(fLineWidth);
   newaxis->SetLineStyle(fLineStyle);
   newaxis->SetTextAlign(fTextAlign);
   newaxis->SetTextAngle(fTextAngle);
   newaxis->SetTextColor(fTextColor);
   newaxis->SetTextFont(fTextFont);
   newaxis->SetTextSize(fTextSize);
   newaxis->SetTitleSize(fTitleSize);
   newaxis->SetTitleOffset(fTitleOffset);
   newaxis->SetLabelFont(fLabelFont);
   newaxis->SetLabelColor(fLabelColor);
   newaxis->SetLabelSize(fLabelSize);
   newaxis->SetLabelOffset(fLabelOffset);
   newaxis->SetTickSize(fTickSize);
   newaxis->SetBit(kCanDelete);
   newaxis->SetTitle(GetTitle());
   newaxis->SetBit(TAxis::kCenterTitle,TestBit(TAxis::kCenterTitle));
   newaxis->AppendPad();
}
Int_t TGaxis::GetMaxDigits()
{
   
   return fgMaxDigits;
}
void TGaxis::ImportAxisAttributes(TAxis *axis)
{
   fAxis = axis;
   SetLineColor(axis->GetAxisColor());
   SetTextColor(axis->GetTitleColor());
   SetTextFont(axis->GetTitleFont());
   SetLabelColor(axis->GetLabelColor());
   SetLabelFont(axis->GetLabelFont());
   SetLabelSize(axis->GetLabelSize());
   SetLabelOffset(axis->GetLabelOffset());
   SetTickSize(axis->GetTickLength());
   SetTitle(axis->GetTitle());
   SetTitleOffset(axis->GetTitleOffset());
   SetTitleSize(axis->GetTitleSize());
   SetBit(TAxis::kCenterTitle,   axis->TestBit(TAxis::kCenterTitle));
   SetBit(TAxis::kCenterLabels,  axis->TestBit(TAxis::kCenterLabels));
   SetBit(TAxis::kRotateTitle,   axis->TestBit(TAxis::kRotateTitle));
   SetBit(TAxis::kNoExponent,    axis->TestBit(TAxis::kNoExponent));
   SetBit(TAxis::kTickPlus,      axis->TestBit(TAxis::kTickPlus));
   SetBit(TAxis::kTickMinus,     axis->TestBit(TAxis::kTickMinus));
   SetBit(TAxis::kMoreLogLabels, axis->TestBit(TAxis::kMoreLogLabels));
   if (axis->GetDecimals())      SetBit(TAxis::kDecimals); 
   SetTimeFormat(axis->GetTimeFormat());
}
void TGaxis::Paint(Option_t *)
{
   Double_t wmin = fWmin;
   Double_t wmax = fWmax;
   Int_t    ndiv = fNdiv;
   
   Double_t x1 = gPad->XtoPad(fX1);
   Double_t y1 = gPad->YtoPad(fY1);
   Double_t x2 = gPad->XtoPad(fX2);
   Double_t y2 = gPad->YtoPad(fY2);
   PaintAxis(x1,y1,x2,y2,wmin,wmax,ndiv,fChopt.Data(),fGridLength);
}
void TGaxis::PaintAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax,
                       Double_t &wmin, Double_t &wmax, Int_t &ndiv,   Option_t *chopt,
                       Double_t gridlength, Bool_t drawGridOnly)
{
   const char *where = "PaintAxis";
   Double_t alfa, beta, ratio1, ratio2, grid_side;
   Double_t axis_lengthN = 0;
   Double_t axis_length0 = 0;
   Double_t axis_length1 = 0;
   Double_t axis_length;
   Double_t atick[3];
   Double_t tick_side;
   Double_t charheight;
   Double_t phil, phi, sinphi, cosphi, asinphi, acosphi;
   Double_t binLow,  binLow2,  binLow3;
   Double_t binHigh, binHigh2, binHigh3;
   Double_t binWidth, binWidth2, binWidth3;
   Double_t xpl1, xpl2, ypl1, ypl2;
   Double_t xtick = 0;
   Double_t xtick0, xtick1, dxtick=0;
   Double_t ytick, ytick0, ytick1;
   Double_t wlabel, dwlabel;
   Double_t xfactor, yfactor;
   Double_t xlabel, ylabel, dxlabel;
   Double_t xone, xtwo;
   Double_t rlab;
   Double_t x0, x1, y0, y1, xx0, xx1, yy0, yy1;
   xx0 = xx1 = yy0 = yy1 = 0;
   Double_t xxmin, xxmax, yymin, yymax;
   xxmin = xxmax = yymin = yymax = 0;
   Double_t xlside, xmside;
   Double_t ww, af, rne;
   Double_t xx, yy;
   Double_t xmnlog, x00, x11, h2, h2sav, axmul, y;
   Float_t chupxvsav, chupyvsav;
   Double_t rtxw, rtyw;
   Int_t nlabels, nticks, nticks0, nticks1;
   Int_t i, j, k, l, decade, ltick;
   Int_t mside, lside;
   Int_t nexe  = 0;
   Int_t lnlen = 0;
   Int_t iexe, if1, if2, na, nf, ih1, ih2, nbinin, nch, kmod;
   Int_t optionLog,optionBlank,optionVert,optionPlus,optionMinus,optionUnlab,optionPara;
   Int_t optionDown,optionRight,optionLeft,optionCent,optionEqual,optionDecimals=0,optionDot;
   Int_t optionY,optionText,optionGrid,optionSize,optionNoopt,optionInt,optionM,optionUp,optionX;
   Int_t optionTime;
   Int_t first,last,labelnumber;
   Int_t xalign, yalign;
   Int_t nn1, nn2, nn3, n1a, n2a, n3a, nb2, nb3;
   Int_t nbins=10, n1aold, nn1old;
   n1aold = nn1old = 0;
   Int_t ndyn;
   Int_t nhilab = 0;
   Int_t idn;
   Bool_t flexe = 0;
   Bool_t flexpo,flexne;
   char *label;
   char *chtemp;
   char *coded;
   char chlabel[256];
   char kchtemp[256];
   char chcoded[8];
   TLine *linegrid;
   TString timeformat;
   time_t timelabel;
   Double_t timed, wTimeIni;
   struct tm* utctis;
   Double_t rangeOffset = 0;
   Double_t epsilon   = 1e-5;
   const Double_t kPI = TMath::Pi();
   Double_t rwmi = wmin;
   Double_t rwma = wmax;
   chtemp = &kchtemp[0];
   label  = &chlabel[0];
   linegrid  = 0;
   fFunction = (TF1*)gROOT->GetFunction(fFunctionName.Data());
   Bool_t noExponent = TestBit(TAxis::kNoExponent);
   Bool_t moreLogLabels = TestBit(TAxis::kMoreLogLabels);
   Double_t padh   = gPad->GetWh()*gPad->GetAbsHNDC();
   Double_t rwxmin = gPad->GetX1();
   Double_t rwxmax = gPad->GetX2();
   Double_t rwymin = gPad->GetY1();
   Double_t rwymax = gPad->GetY2();
   if(strchr(chopt,'G')) optionLog  = 1;  else optionLog  = 0;
   if(strchr(chopt,'B')) optionBlank= 1;  else optionBlank= 0;
   if(strchr(chopt,'V')) optionVert = 1;  else optionVert = 0;
   if(strchr(chopt,'+')) optionPlus = 1;  else optionPlus = 0;
   if(strchr(chopt,'-')) optionMinus= 1;  else optionMinus= 0;
   if(strchr(chopt,'U')) optionUnlab= 1;  else optionUnlab= 0;
   if(strchr(chopt,'P')) optionPara = 1;  else optionPara = 0;
   if(strchr(chopt,'O')) optionDown = 1;  else optionDown = 0;
   if(strchr(chopt,'R')) optionRight= 1;  else optionRight= 0;
   if(strchr(chopt,'L')) optionLeft = 1;  else optionLeft = 0;
   if(strchr(chopt,'C')) optionCent = 1;  else optionCent = 0;
   if(strchr(chopt,'=')) optionEqual= 1;  else optionEqual= 0;
   if(strchr(chopt,'Y')) optionY    = 1;  else optionY    = 0;
   if(strchr(chopt,'T')) optionText = 1;  else optionText = 0;
   if(strchr(chopt,'W')) optionGrid = 1;  else optionGrid = 0;
   if(strchr(chopt,'S')) optionSize = 1;  else optionSize = 0;
   if(strchr(chopt,'N')) optionNoopt= 1;  else optionNoopt= 0;
   if(strchr(chopt,'I')) optionInt  = 1;  else optionInt  = 0;
   if(strchr(chopt,'M')) optionM    = 1;  else optionM    = 0;
   if(strchr(chopt,'0')) optionUp   = 1;  else optionUp   = 0;
   if(strchr(chopt,'X')) optionX    = 1;  else optionX    = 0;
   if(strchr(chopt,'t')) optionTime = 1;  else optionTime = 0;
   if(strchr(chopt,'.')) optionDot  = 1;  else optionDot  = 0;
   if (TestBit(TAxis::kTickPlus))     optionPlus  = 2;
   if (TestBit(TAxis::kTickMinus))    optionMinus = 2;
   if (TestBit(TAxis::kCenterLabels)) optionM     = 1;
   if (TestBit(TAxis::kDecimals))     optionDecimals = 1;
   if (!gStyle->GetStripDecimals())   optionDecimals = 1;
   if (fAxis) {
      if (fAxis->GetLabels()) {
         optionM    = 1;
         optionText = 1;
         ndiv = fAxis->GetLast()-fAxis->GetFirst()+1;
      }
   }
   if (ndiv < 0) {
      Error(where, "Invalid number of divisions: %d",ndiv);
      return;
   }
   if (optionGrid) {
      if (gridlength == 0) gridlength = 0.8;
      linegrid = new TLine();
      linegrid->SetLineColor(gStyle->GetGridColor());
      if (linegrid->GetLineColor() == 0) linegrid->SetLineColor(GetLineColor());
      linegrid->SetLineStyle(gStyle->GetGridStyle());
      linegrid->SetLineWidth(gStyle->GetGridWidth());
   }
   if (GetLabelOffset() > 1.1 ) optionUnlab = 1;
   Int_t idF = fTimeFormat.Index("%F");
   if (idF>=0) {
      timeformat = fTimeFormat(0,idF);
   } else {
      timeformat = fTimeFormat;
   }
   Double_t timeoffset =0;
   if (optionTime) {
      if (idF>=0) {
         Int_t lnF = fTimeFormat.Length();
         TString stringtimeoffset = fTimeFormat(idF+2,lnF);
         Int_t yy, mm, dd, hh, mi, ss;
         if (sscanf(stringtimeoffset.Data(), "%d-%d-%d %d:%d:%d", &yy, &mm, &dd, &hh, &mi, &ss) == 6) {
            struct tm tp;
            struct tm* tptest;
            time_t timeoffsettest;
            
            Int_t zoneoffset = TTimeStamp::GetZoneOffset();
            
            zoneoffset /= 3600;
            tp.tm_year  = yy-1900;
            tp.tm_mon   = mm-1;
            tp.tm_mday  = dd;
            tp.tm_hour  = hh - zoneoffset;
            tp.tm_min   = mi;
            tp.tm_sec   = ss;
            tp.tm_isdst =  1; 
            timeoffset  = mktime(&tp);
            if (timeoffset<0.) timeoffset=0.;
            
            timeoffsettest = (time_t)((Long_t)timeoffset);
            tptest = gmtime(&timeoffsettest);
            timeoffset += timeoffsettest - mktime(tptest);
            
            Int_t ids   = stringtimeoffset.Index("s");
            if (ids >= 0) {
               Float_t dp;
               Int_t lns   = stringtimeoffset.Length();
               TString sdp = stringtimeoffset(ids+1,lns);
               sscanf(sdp.Data(),"%g",&dp);
               timeoffset += dp;
            }
            
            if (stringtimeoffset.Index("GMT")>=0) optionTime =2;
         } else {
            Error(where, "Time offset has not the right format");
         }
      } else {
         timeoffset = gStyle->GetTimeOffset();
      }
      wmin += timeoffset - (int)(timeoffset);
      wmax += timeoffset - (int)(timeoffset);
    
      struct tm* tp0;
      time_t timetp = (time_t)((Long_t)(timeoffset));
      Double_t range = wmax - wmin;
      Long_t rangeBase = 60;
      if (range>60)       rangeBase = 60*20;       
      if (range>3600)     rangeBase = 3600*20;     
      if (range>86400)    rangeBase = 86400*20;    
      if (range>2419200)  rangeBase = 31556736;    
      rangeOffset = (Double_t) ((Long_t)(timeoffset)%rangeBase);
      if (range>31536000) {
         tp0 = gmtime(&timetp);
         tp0->tm_mon   = 0;
         tp0->tm_mday  = 1;
         tp0->tm_hour  = 0;
         tp0->tm_min   = 0;
         tp0->tm_sec   = 0;
         tp0->tm_isdst = 1; 
         rangeBase = (timetp-mktime(tp0)); 
         rangeOffset = (Double_t) (rangeBase);
      }
      wmax += rangeOffset;
      wmin += rangeOffset;
   }
   n1a   = ndiv%100;
   n2a   = (ndiv%10000 - n1a)/100;
   n3a   = ndiv/10000;
   nn3   = TMath::Max(n3a,1);
   nn2   = TMath::Max(n2a,1)*nn3;
   nn1   = TMath::Max(n1a,1)*nn2+1;
   nticks= nn1;
   if (wmin == wmax || ndiv == 0 || n1a <= 1 || optionLog) {
      optionNoopt = 1;
      optionInt   = 0;
   }
   if ( (wmax-wmin) < 1 && optionInt) {
      Error(where, "option I not available");
      optionInt = 0;
   }
   if (!optionNoopt || optionInt ) {
      THLimitsFinder::Optimize(wmin,wmax,n1a,binLow,binHigh,nbins,binWidth,fChopt.Data());
      if (optionInt) {
         if (binLow != Double_t(int(binLow)) || binWidth != Double_t(int(binWidth))) {
            AdjustBinSize(wmin,wmax,n1a,binLow,binHigh,nbins,binWidth);
         }
      }
      if ((wmin-binLow)  > epsilon) { binLow  += binWidth; nbins--; }
      if ((binHigh-wmax) > epsilon) { binHigh -= binWidth; nbins--; }
      if (xmax == xmin) {
         rtyw  = (ymax-ymin)/(wmax-wmin);
         xxmin = xmin;
         xxmax = xmax;
         yymin = rtyw*(binLow-wmin)  + ymin;
         yymax = rtyw*(binHigh-wmin) + ymin;
      }
      else {
         rtxw  = (xmax-xmin)/(wmax-wmin);
         xxmin = rtxw*(binLow-wmin)  + xmin;
         xxmax = rtxw*(binHigh-wmin) + xmin;
         if (ymax == ymin) {
            yymin = ymin;
            yymax = ymax;
         }
         else {
            alfa  = (ymax-ymin)/(xmax-xmin);
            beta  = (ymin*xmax-ymax*xmin)/(xmax-xmin);
            yymin = alfa*xxmin + beta;
            yymax = alfa*xxmax + beta;
         }
      }
      if (fFunction) {
         yymin = ymin;
         yymax = ymax;
         xxmin = xmin;
         xxmax = xmax;
      } else {
         wmin = binLow;
         wmax = binHigh;
      }
      nb2 = n2a;
      if (!optionNoopt && n2a > 1 && binWidth > 0) {
         THLimitsFinder::Optimize(wmin,wmin+binWidth,n2a,binLow2,binHigh2,nb2,binWidth2,fChopt.Data());
      }
      nb3 = n3a;
      if (!optionNoopt && n3a > 1 && binWidth2 > 0) {
         THLimitsFinder::Optimize(binLow2,binLow2+binWidth2,n3a,binLow3,binHigh3,nb3,binWidth3,fChopt.Data());
      }
      n1aold = n1a;
      nn1old = nn1;
      n1a    = nbins;
      nn3    = TMath::Max(nb3,1);
      nn2    = TMath::Max(nb2,1)*nn3;
      nn1    = TMath::Max(n1a,1)*nn2+1;
      nticks = nn1;
   }
   ratio1 = 1/(rwxmax-rwxmin);
   ratio2 = 1/(rwymax-rwymin);
   x0     = ratio1*(xmin-rwxmin);
   x1     = ratio1*(xmax-rwxmin);
   y0     = ratio2*(ymin-rwymin);
   y1     = ratio2*(ymax-rwymin);
   if (!optionNoopt || optionInt ) {
      xx0 = ratio1*(xxmin-rwxmin);
      xx1 = ratio1*(xxmax-rwxmin);
      yy0 = ratio2*(yymin-rwymin);
      yy1 = ratio2*(yymax-rwymin);
   }
   if ((x0 == x1) && (y0 == y1)) {
      Error(where, "length of axis is 0");
      return;
   }
   if (optionX) {
      ndiv = n1a;
      return;
   }
   Int_t maxDigits = 5;
   if (fAxis) maxDigits = fgMaxDigits;
   TLine *lineaxis = new TLine();
   TLatex *textaxis = new TLatex();
   lineaxis->SetLineColor(GetLineColor());
   lineaxis->SetLineStyle(1);
   lineaxis->SetLineWidth(GetLineWidth());
   textaxis->SetTextColor(GetTextColor());
   textaxis->SetTextFont(GetTextFont());
   if (!gPad->IsBatch()) {
      gVirtualX->GetCharacterUp(chupxvsav, chupyvsav);
      gVirtualX->SetClipOFF(gPad->GetCanvasID());
   }
   axis_length = TMath::Sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0));
   if (axis_length == 0) {
      Error(where, "length of axis is 0");
      goto L210;
   }
   if (!optionNoopt || optionInt) {
      axis_lengthN = TMath::Sqrt((xx1-xx0)*(xx1-xx0)+(yy1-yy0)*(yy1-yy0));
      axis_length0 = TMath::Sqrt((xx0-x0)*(xx0-x0)+(yy0-y0)*(yy0-y0));
      axis_length1 = TMath::Sqrt((x1-xx1)*(x1-xx1)+(y1-yy1)*(y1-yy1));
      if (axis_lengthN < epsilon) {
         optionNoopt = 1;
         optionInt   = 0;
         wmin        = rwmi;
         wmax        = rwma;
         n1a         = n1aold;
         nn1         = nn1old;
         nticks      = nn1;
         if (optionTime) {
            wmin        += timeoffset - (int)(timeoffset) + rangeOffset;
            wmax        += timeoffset - (int)(timeoffset) + rangeOffset;
         }
      }
   }
   if (x0 == x1) {
      phi  = 0.5*kPI;
      phil = phi;
   } else {
            phi = TMath::ATan2((y1-y0),(x1-x0));
      Int_t px0 = gPad->UtoPixel(x0);
      Int_t py0 = gPad->VtoPixel(y0);
      Int_t px1 = gPad->UtoPixel(x1);
      Int_t py1 = gPad->VtoPixel(y1);
      if (x0 < x1) phil = TMath::ATan2(Double_t(py0-py1), Double_t(px1-px0));
      else         phil = TMath::ATan2(Double_t(py1-py0), Double_t(px0-px1));
   }
   cosphi  = TMath::Cos(phi);
   sinphi  = TMath::Sin(phi);
   acosphi = TMath::Abs(cosphi);
   asinphi = TMath::Abs(sinphi);
   if (acosphi <= epsilon) { acosphi = 0;  cosphi  = 0; }
   if (asinphi <= epsilon) { asinphi = 0;  sinphi  = 0; }
   mside=1;
   if (x0 == x1 && y1 > y0)       mside = -1;
   if (optionPlus)                mside = 1;
   if (optionMinus)               mside = -1;
   if (optionPlus && optionMinus) mside = 0;
   xmside = mside;
   lside = -mside;
   if (optionEqual) lside = mside;
   if (optionPlus && optionMinus) {
      lside = -1;
      if (optionEqual) lside=1;
   }
   xlside = lside;
   if(xmside >= 0) tick_side = 1;
   else            tick_side = -1;
   if (optionSize) atick[0] = tick_side*axis_length*fTickSize;
   else            atick[0] = tick_side*axis_length*0.03;
   atick[1] = 0.5*atick[0];
   atick[2] = 0.5*atick[1];
   if ((x0 == x1) && (y1 > y0))  grid_side =-1;
   else                          grid_side = 1;
   if(fFunction) {
      rwmi = fFunction->Eval(wmin);
      rwma = fFunction->Eval(wmax);
      if(rwmi > rwma) {
         Double_t t = rwma;
         rwma = rwmi;
         rwmi = t;
      }
   }
   if (!optionBlank) {
      xpl1 = x0;
      xpl2 = x1;
      ypl1 = y0;
      ypl2 = y1;
      lineaxis->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
   }
   if (!drawGridOnly && strlen(GetTitle())) {
      textaxis->SetTextSize (GetTitleSize());
      charheight = GetTitleSize();
      if ((GetTextFont() % 10) > 2) {
         charheight = charheight/gPad->GetWh();
      }
      Double_t toffset = GetTitleOffset();
      if (x1 == x0) ylabel = xlside*1.6*charheight*toffset;
      else          ylabel = xlside*1.3*charheight*toffset;
      if (y1 == y0) ylabel = xlside*1.6*charheight*toffset;
      Double_t axispos;
      if (TestBit(TAxis::kCenterTitle)) axispos = 0.5*axis_length;
      else                       axispos = axis_length;
      if (TestBit(TAxis::kRotateTitle)) {
         if (x1 >= x0) {
            if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22);
            else                              textaxis->SetTextAlign(12);
            Rotate(axispos,ylabel,cosphi,sinphi,x0,y0,xpl1,ypl1);
         } else {
            if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22);
         else                                 textaxis->SetTextAlign(32);
            Rotate(axispos,ylabel,cosphi,sinphi,x0,y0,xpl1,ypl1);
         }
         textaxis->PaintLatex(gPad->GetX1() + xpl1*(gPad->GetX2() - gPad->GetX1()),
                              gPad->GetY1() + ypl1*(gPad->GetY2() - gPad->GetY1()),
                              phil=(kPI+phil)*180/kPI,
                              GetTitleSize(),
                              GetTitle());
      } else {
         if (x1 >= x0) {
            if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22);
            else                              textaxis->SetTextAlign(32);
            Rotate(axispos,ylabel,cosphi,sinphi,x0,y0,xpl1,ypl1);
         } else {
            if (TestBit(TAxis::kCenterTitle)) textaxis->SetTextAlign(22);
         else                                 textaxis->SetTextAlign(12);
            Rotate(axispos,ylabel,cosphi,sinphi,x0,y0,xpl1,ypl1);
         }
         textaxis->PaintLatex(gPad->GetX1() + xpl1*(gPad->GetX2() - gPad->GetX1()),
                              gPad->GetY1() + ypl1*(gPad->GetY2() - gPad->GetY1()),
                              phil*180/kPI,
                              GetTitleSize(),
                              GetTitle());
      }
   }
   if (ndiv == 0)goto L210;
   if (wmin == wmax) {
      Error(where, "wmin (%f) == wmax (%f)", wmin, wmax);
      goto L210;
   }
   charheight = GetLabelSize();
   if (optionText) charheight *= 0.66666;
   textaxis->SetTextFont(GetLabelFont());
   if ((GetLabelFont()%10 < 2) && optionLog) 
      textaxis->SetTextFont((Int_t)(GetLabelFont()/10)*10+2);
   textaxis->SetTextColor(GetLabelColor());
   textaxis->SetTextSize (charheight);
   textaxis->SetTextAngle(GetTextAngle());
   if (GetLabelFont()%10 > 2) {
      charheight /= padh;
   }
   if (!optionUp && !optionDown && !optionY) {
      if (!drawGridOnly && optionText && ((ymin == ymax) || (xmin == xmax))) {
         textaxis->SetTextAlign(32);
         optionText = 2;
         Int_t nl = fAxis->GetLast()-fAxis->GetFirst()+1;
         Double_t angle     = 0;
         for (i=fAxis->GetFirst(); i<=fAxis->GetLast(); i++) {
            textaxis->SetText(0,0,fAxis->GetBinLabel(i));
            if (textaxis->GetXsize() < (xmax-xmin)/nl) continue;
            angle = -20;
            break;
         }
         for (i=fAxis->GetFirst(); i<=fAxis->GetLast(); i++) {
            if ((!strcmp(fAxis->GetName(),"xaxis") && !gPad->TestBit(kHori))
              ||(!strcmp(fAxis->GetName(),"yaxis") &&  gPad->TestBit(kHori))) {
               if (nl > 50) angle = 90;
               if (fAxis->TestBit(TAxis::kLabelsHori)) angle = 0;
               if (fAxis->TestBit(TAxis::kLabelsVert)) angle = 90;
               if (fAxis->TestBit(TAxis::kLabelsUp))   angle = 20;
               if (fAxis->TestBit(TAxis::kLabelsDown)) angle =-20;
               if (angle==   0) textaxis->SetTextAlign(23);
               if (angle== -20) textaxis->SetTextAlign(12);
               textaxis->PaintLatex(fAxis->GetBinCenter(i),
                                    gPad->GetUymin() - 3*fAxis->GetLabelOffset()*(gPad->GetUymax()-gPad->GetUymin()),
                                    angle,
                                    textaxis->GetTextSize(),
                                    fAxis->GetBinLabel(i));
            } else if ((!strcmp(fAxis->GetName(),"yaxis") && !gPad->TestBit(kHori))
                    || (!strcmp(fAxis->GetName(),"xaxis") &&  gPad->TestBit(kHori))) {
               textaxis->PaintLatex(gPad->GetUxmin() - 3*fAxis->GetLabelOffset()*(gPad->GetUxmax()-gPad->GetUxmin()),
                                    fAxis->GetBinCenter(i),
                                    0,
                                    textaxis->GetTextSize(),
                                    fAxis->GetBinLabel(i));
            } else {
               textaxis->PaintLatex(xmin - 3*fAxis->GetLabelOffset()*(gPad->GetUxmax()-gPad->GetUxmin()),
                                    ymin +(i-0.5)*(ymax-ymin)/nl,
                                    0,
                                    textaxis->GetTextSize(),
                                    fAxis->GetBinLabel(i));
            }
         }
      }
   }
   if (!gPad->IsBatch()) {
      if (cosphi > 0) gVirtualX->SetCharacterUp(-sinphi,cosphi);
      else            gVirtualX->SetCharacterUp(sinphi,-cosphi);
      if (x0 == x1)   gVirtualX->SetCharacterUp(0,1);
      if (optionVert) gVirtualX->SetCharacterUp(0,1);
      if (optionPara) gVirtualX->SetCharacterUp(-sinphi,cosphi);
      if (optionDown) gVirtualX->SetCharacterUp(cosphi,sinphi);
   }
   xalign = 2;
   yalign = 1;
   if (x0 == x1)    xalign = 3;
   if (y0 != y1)    yalign = 2;
   if (optionCent)  xalign = 2;
   if (optionRight) xalign = 3;
   if (optionLeft)  xalign = 1;
   if (TMath::Abs(cosphi) > 0.9) {
      xalign = 2;
   } else {
      if (cosphi*sinphi > 0)  xalign = 1;
      if (cosphi*sinphi < 0)  xalign = 3;
   }
   textaxis->SetTextAlign(10*xalign+yalign);
   if (x0 == x1) {
      if (optionPlus && !optionMinus) {
         if (optionEqual) ylabel =  fLabelOffset/2 + atick[0];
         else             ylabel = -fLabelOffset;
      } else {
         ylabel = fLabelOffset;
         if (lside < 0)  ylabel += atick[0];
      }
   } else if (y0 == y1) {
      if (optionMinus && !optionPlus) {
         ylabel = fLabelOffset+0.5*fLabelSize;
         ylabel += TMath::Abs(atick[0]);
      } else {
         ylabel = -fLabelOffset;
         if (mside <= 0) ylabel -= TMath::Abs(atick[0]);
      }
      if (optionLog)  ylabel -= 0.5*charheight;
   } else {
      if (mside+lside >= 0) ylabel =  fLabelOffset;
      else                  ylabel = -fLabelOffset;
   }
   if (optionText) ylabel /= 2;
   if (!optionLog) {
      if (ndiv) {
         if (fFunction) {
            if (optionNoopt && !optionInt) {
               dxtick=(binHigh-binLow)/Double_t(nticks-1);
            } else {
               dxtick=(binHigh-binLow)/Double_t(nticks-1);
            }
         } else {
            if (optionNoopt && !optionInt) dxtick=axis_length/Double_t(nticks-1);
            else                           dxtick=axis_lengthN/Double_t(nticks-1);
         }
         for (k=0;k<nticks; k++) {
            ltick = 2;
            if (k%nn3 == 0) ltick = 1;
            if (k%nn2 == 0) ltick = 0;
            if (fFunction) {
               Double_t xx = binLow+Double_t(k)*dxtick;
               Double_t zz = fFunction->Eval(xx)-rwmi;
               xtick = zz* axis_length / TMath::Abs(rwma-rwmi);
            } else {
               xtick = Double_t(k)*dxtick;
            }
            ytick = 0;
            if (!mside) ytick -= atick[ltick];
            if ( optionNoopt && !optionInt) {
               Rotate(xtick,ytick,cosphi,sinphi,x0,y0,xpl2,ypl2);
               Rotate(xtick,atick[ltick],cosphi,sinphi,x0,y0,xpl1,ypl1);
            }
            else {
               Rotate(xtick,ytick,cosphi,sinphi,xx0,yy0,xpl2,ypl2);
               Rotate(xtick,atick[ltick],cosphi,sinphi,xx0,yy0,xpl1,ypl1);
            }
            if (optionVert) {
               if ((x0 != x1) && (y0 != y1)) {
                  if (mside) {
                     xpl1 = xpl2;
                     if (cosphi > 0) ypl1 = ypl2 + atick[ltick];
                     else            ypl1 = ypl2 - atick[ltick];
                  }
                  else {
                     xpl1 = 0.5*(xpl1 + xpl2);
                     xpl2 = xpl1;
                     ypl1 = 0.5*(ypl1 + ypl2) + atick[ltick];
                     ypl2 = 0.5*(ypl1 + ypl2) - atick[ltick];
                  }
               }
            }
            if (!drawGridOnly) lineaxis->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
            if (optionGrid) {
               if (ltick == 0) {
                  if (optionNoopt && !optionInt) {
                     Rotate(xtick,0,cosphi,sinphi,x0,y0 ,xpl2,ypl2);
                     Rotate(xtick,grid_side*gridlength ,cosphi,sinphi,x0,y0 ,xpl1,ypl1);
                  }
                  else {
                     Rotate(xtick,0,cosphi ,sinphi,xx0,yy0 ,xpl2,ypl2);
                     Rotate(xtick,grid_side*gridlength ,cosphi,sinphi,xx0,yy0 ,xpl1,ypl1);
                  }
                  linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
               }
            }
         }
         xtick0 = 0;
         xtick1 = xtick;
         if ((!optionNoopt || optionInt) && axis_length0) {
            if (fFunction) nticks0 = Int_t((binLow-wmin)/dxtick);
            else           nticks0 = Int_t(axis_length0/dxtick);
            if (nticks0 > 1000) nticks0 = 1000;
            for (k=0; k<=nticks0; k++) {
               ltick = 2;
               if (k%nn3 == 0) ltick = 1;
               if (k%nn2 == 0) ltick = 0;
               ytick0 = 0;
               if (!mside) ytick0 -= atick[ltick];
               if (fFunction) {
                  xtick0 = (fFunction->Eval(binLow - Double_t(k)*dxtick)-rwmi)
                           * axis_length / TMath::Abs(rwma-rwmi);
               }
               Rotate(xtick0,ytick0,cosphi,sinphi,xx0,yy0 ,xpl2,ypl2);
               Rotate(xtick0,atick[ltick],cosphi,sinphi,xx0,yy0 ,xpl1,ypl1);
               if (optionVert) {
                  if ((x0 != x1) && (y0 != y1)) {
                     if (mside) {
                        xpl1 = xpl2;
                        if (cosphi > 0) ypl1 = ypl2 + atick[ltick];
                        else            ypl1 = ypl2 - atick[ltick];
                     }
                     else {
                        xpl1 = 0.5*(xpl1 + xpl2);
                        xpl2 = xpl1;
                        ypl1 = 0.5*(ypl1 + ypl2) + atick[ltick];
                        ypl2 = 0.5*(ypl1 + ypl2) - atick[ltick];
                     }
                  }
               }
               if (!drawGridOnly) lineaxis->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
               if (optionGrid) {
                  if (ltick == 0) {
                     Rotate(xtick0,0,cosphi,sinphi,xx0,yy0,xpl2,ypl2);
                     Rotate(xtick0,grid_side*gridlength ,cosphi,sinphi,xx0,yy0 ,xpl1,ypl1);
                     linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
                  }
               }
               xtick0 -= dxtick;
            }
         }
         if ((!optionNoopt || optionInt) && axis_length1) {
            if (fFunction) nticks1 = int((wmax-binHigh)/dxtick);
            else           nticks1 = int(axis_length1/dxtick);
            if (nticks1 > 1000) nticks1 = 1000;
            for (k=0; k<=nticks1; k++) {
               ltick = 2;
               if (k%nn3 == 0) ltick = 1;
               if (k%nn2 == 0) ltick = 0;
               ytick1 = 0;
               if (!mside) ytick1 -= atick[ltick];
               if (fFunction) {
                  xtick1 = (fFunction->Eval(binHigh + Double_t(k)*dxtick)-rwmi)
                           * axis_length / TMath::Abs(rwma-rwmi);
               }
               Rotate(xtick1,ytick1,cosphi,sinphi,xx0,yy0 ,xpl2,ypl2);
               Rotate(xtick1,atick[ltick],cosphi,sinphi,xx0,yy0 ,xpl1,ypl1);
               if (optionVert) {
                  if ((x0 != x1) && (y0 != y1)) {
                     if (mside) {
                        xpl1 = xpl2;
                        if (cosphi > 0) ypl1 = ypl2 + atick[ltick];
                        else            ypl1 = ypl2 - atick[ltick];
                     }
                     else {
                        xpl1 = 0.5*(xpl1 + xpl2);
                        xpl2 = xpl1;
                        ypl1 = 0.5*(ypl1 + ypl2) + atick[ltick];
                        ypl2 = 0.5*(ypl1 + ypl2) - atick[ltick];
                     }
                  }
               }
               if (!drawGridOnly) lineaxis->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
               if (optionGrid) {
                  if (ltick == 0) {
                     Rotate(xtick1,0,cosphi,sinphi,xx0,yy0 ,xpl2,ypl2);
                     Rotate(xtick1,grid_side*gridlength,cosphi,sinphi,xx0,yy0,xpl1,ypl1);
                     linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
                  }
               }
               xtick1 += dxtick;
            }
         }
      }
   }
   if (!drawGridOnly && !optionUnlab) {
      if (!optionLog) {
         if (n1a) {
            if ((wmin == wmax) || (ndiv == 0)) {
               Error(where, "wmin (%f) == wmax (%f), or ndiv == 0", wmin, wmax);
               goto L210;
            }
            wlabel  = wmin;
            dwlabel = (wmax-wmin)/Double_t(n1a);
            if (optionNoopt && !optionInt) dxlabel = axis_length/Double_t(n1a);
            else                           dxlabel = axis_lengthN/Double_t(n1a);
            if (!optionText && !optionTime) {
               flexe  = kFALSE;
               nexe   = 0;
               flexpo = kFALSE;
               flexne = kFALSE;
               ww     = TMath::Max(TMath::Abs(wmin),TMath::Abs(wmax));
               Double_t xmicros = 0.00099;
               if (maxDigits) xmicros = TMath::Power(10,-maxDigits);
               if (!noExponent && (TMath::Abs(wmax-wmin)/Double_t(n1a)) < xmicros) {
                  af    = TMath::Log10(ww) + epsilon;
                  if (af < 0) {
                     flexe   = kTRUE;
                     nexe    = int(af);
                     iexe    = TMath::Abs(nexe);
                     if (iexe%3 == 1)     iexe += 2;
                     else if(iexe%3 == 2) iexe += 1;
                     if (nexe < 0) nexe = -iexe;
                     else          nexe =  iexe;
                     wlabel  = wlabel*TMath::Power(10,iexe);
                     dwlabel = dwlabel*TMath::Power(10,iexe);
                     if1     = maxDigits;
                     if2     = maxDigits-2;
                     goto L110;
                  }
               }
               if (ww >= 1) af = TMath::Log10(ww);
               else         af = TMath::Log10(ww*0.0001);
               af += epsilon;
               nf  = Int_t(af)+1;
               if (!noExponent && nf > maxDigits)  flexpo = kTRUE;
               if (!noExponent && nf < -maxDigits) flexne = kTRUE;
               if (flexpo) {
                  flexe = kTRUE;
                  while (1) {
                     nexe++;
                     ww      /= 10;
                     wlabel  /= 10;
                     dwlabel /= 10;
                     if (nexe%3 == 0 && ww <= TMath::Power(10,maxDigits-1)) break;
                  }
               }
               if (flexne) {
                  flexe = kTRUE;
                  rne   = 1/TMath::Power(10,maxDigits-2);
                  while (1) {
                     nexe--;
                     ww      *= 10;
                     wlabel  *= 10;
                     dwlabel *= 10;
                     if (nexe%3 == 0 && ww >= rne) break;
                  }
               }
               na = 0;
               for (i=maxDigits-1; i>0; i--) {
                  if (TMath::Abs(ww) < TMath::Power(10,i)) na = maxDigits-i;
               }
               ndyn = n1a;
               while (ndyn) {
                  Double_t wdyn = TMath::Abs((wmax-wmin)/ndyn);
                  if (wdyn <= 0.999 && na < maxDigits-2) {
                     na++;
                     ndyn /= 10;
                  }
                  else break;
               }
               if2 = na;
               if1 = TMath::Max(nf+na,maxDigits)+1;
L110:
               if (TMath::Min(wmin,wmax) < 0)if1 = if1+1;
               if1 = TMath::Min(if1,32);
               while (dwlabel < TMath::Power(10,-if2)) {
                  if1++;
                  if2++;
               }
               coded = &chcoded[0];
               if (if1 > 14) if1=14;
               if (if2 > 14) if2=14;
               if (if2) sprintf(coded,"%%%d.%df",if1,if2);
               else     sprintf(coded,"%%%d.%df",if1+1,1);
            }
            sprintf(chtemp,"%g",dwlabel);
            Int_t ndecimals = 0;
            if (optionDecimals) {
               char *dot = strchr(chtemp,'.');
               if (dot) ndecimals = chtemp + strlen(chtemp) -dot;
            }
            if (optionM) nlabels = n1a-1;
            else         nlabels = n1a;
            wTimeIni = wlabel;
            for ( k=0; k<=nlabels; k++) {
               if (fFunction) {
                  Double_t xx = binLow+Double_t(k*nn2)*dxtick;
                  Double_t zz = fFunction->Eval(xx)-rwmi;
                  wlabel = xx;
                  xlabel = zz* axis_length / TMath::Abs(rwma-rwmi);
               } else {
                  xlabel = dxlabel*k;
               }
               if (optionM)    xlabel += 0.5*dxlabel;
               if (!optionText && !optionTime) {
                  sprintf(label,&chcoded[0],wlabel);
                  label[28] = 0;
                  wlabel += dwlabel;
                  LabelsLimits(label,first,last);  
                  if (label[first] == '.') { 
                     strcpy(chtemp, "0");
                     strcat(chtemp, &label[first]);
                     strcpy(label, chtemp);
                     first = 1; last = strlen(label);
                  }
                  if (label[first] == '-' && label[first+1] == '.') {
                     strcpy(chtemp, "-0");
                     strcat(chtemp, &label[first+1]);
                     strcpy(label, chtemp);
                     first = 1; last = strlen(label);
                  }
                  if (ndecimals) {
                     char *adot = strchr(label,'.');
                     if (adot) adot[ndecimals] = 0;
                  } else {
                     while (label[last] == '0') { label[last] = 0; last--;}
                  }
                  if (label[last] == '.') {
                     if (!optionDot) { label[last] = 0; last--;}
                  }
               }
               if (optionTime) {
                  timed = wlabel + (int)(timeoffset) - rangeOffset;
                  timelabel = (time_t)((Long_t)(timed));
                  if (optionTime == 1) {
                     utctis = localtime(&timelabel);
                  } else {
                     utctis = gmtime(&timelabel);
                  }
                  TString timeformattmp;
                  if (timeformat.Length() < 220) timeformattmp = timeformat;
                  else timeformattmp = "#splitline{Format}{too long}";
                  if (dwlabel<0.9) {
                     double tmpdb;
                     int tmplast;
                     sprintf(label,"%%S%7.5f",modf(timed,&tmpdb));
                     tmplast = strlen(label)-1;
                     while (label[tmplast] == '0') {
                        label[tmplast] = 0; tmplast--;
                     }
                     timeformattmp.ReplaceAll("%S",label);
                     timeformattmp.ReplaceAll("%S0.","%Ss");
                  }
                  strftime(label,256,timeformattmp.Data(),utctis);
                  strcpy(chtemp,&label[0]);
                  first = 0; last=strlen(label)-1;
                  wlabel = wTimeIni + (k+1)*dwlabel;
               }
               if (optionNoopt && !optionInt)
                        Rotate (xlabel,ylabel,cosphi,sinphi,x0,y0,xx,yy);
               else     Rotate (xlabel,ylabel,cosphi,sinphi,xx0,yy0,xx,yy);
               if (y0 == y1 && !optionDown && !optionUp) {
                  yy -= 0.80*charheight;
               }
               if (optionVert) {
                  if (x0 != x1 && y0 != y1) {
                     if (optionNoopt && !optionInt)
                           Rotate (xlabel,0,cosphi,sinphi,x0,y0,xx,yy);
                     else  Rotate (xlabel,0,cosphi,sinphi,xx0,yy0,xx,yy);
                     if (cosphi > 0 ) yy += ylabel;
                     if (cosphi < 0 ) yy -= ylabel;
                  }
               }
               if (!optionY || (x0 == x1)) {
                  if (!optionText) {
                     if (first > last)  strcpy(chtemp, " ");
                     else               strcpy(chtemp, &label[first]);
                     textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()),
                           gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()),
                           0,
                           textaxis->GetTextSize(),
                           chtemp);
                  }
                  else  {
                     if (optionText == 1) textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()),
                                                   gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()),
                                                   0,
                                                   textaxis->GetTextSize(),
                                                   fAxis->GetBinLabel(k+fAxis->GetFirst()));
                  }
               }
               else {
                  if (!optionText)     lnlen = last-first+1;
                  else {
                     if (k+1 > nhilab) lnlen = 0;
                  }
                  for ( l=1; l<=lnlen; l++) {
                     if (!optionText) *chtemp = label[first+l-2];
                     else {
                        if (lnlen == 0) strcpy(chtemp, " ");
                        else            strcpy(chtemp, "1");
                     }
                     textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()),
                           gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()),
                           0,
                           textaxis->GetTextSize(),
                           chtemp);
                     yy -= charheight*1.3;
                  }
               }
            }
            if (flexe && !optionText && nexe)  {
               sprintf(label,"#times10^{%d}", nexe);
               if (x0 != x1) { xfactor = x1-x0+0.1*charheight; yfactor = 0; }
               else          { xfactor = y1-y0+0.1*charheight; yfactor = 0; }
               Rotate (xfactor,yfactor,cosphi,sinphi,x0,y0,xx,yy);
               textaxis->SetTextAlign(11);
               if (GetLabelFont()%10 < 2) 
                  textaxis->SetTextFont((Int_t)(GetLabelFont()/10)*10+2);
               textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()),
                           gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()),
                           0,
                           textaxis->GetTextSize(),
                           label);
            }
         }
      }
   }
   if (optionLog && ndiv) {
      UInt_t xi1=0,xi2,wi,yi1=0,yi2,hi;
      Bool_t firstintlab = kTRUE, overlap = kFALSE;
      if ((wmin == wmax) || (ndiv == 0))  {
         Error(where, "wmin (%f) == wmax (%f), or ndiv == 0", wmin, wmax);
         goto L210;
      }
      if (wmin <= 0)   {
         Error(where, "negative logarithmic axis");
         goto L210;
      }
      if (wmax <= 0)     {
         Error(where, "negative logarithmic axis");
         goto L210;
      }
      xmnlog = TMath::Log10(wmin);
      if (xmnlog > 0) xmnlog += 1.E-6;
      else            xmnlog -= 1.E-6;
      x00    = 0;
      x11    = axis_length;
      h2     = TMath::Log10(wmax);
      h2sav  = h2;
      if (h2 > 0) h2 += 1.E-6;
      else        h2 -= 1.E-6;
      ih1    = int(xmnlog);
      ih2    = 1+int(h2);
      nbinin = ih2-ih1+1;
      axmul  = (x11-x00)/(h2sav-xmnlog);
      decade      = ih1-2;
      labelnumber = ih1;
      if ( xmnlog > 0 && (xmnlog-Double_t(ih1) > 0) ) labelnumber++;
      for (j=1; j<=nbinin; j++) {
         firstintlab = kTRUE, overlap = kFALSE;
         decade++;
         if (x0 == x1 && j == 1) ylabel += charheight*0.33;
         if (y0 == y1 && j == 1) ylabel -= charheight*0.65;
         xone = x00+axmul*(Double_t(decade)-xmnlog);
         
         if (j < 0) printf("j=%d\n",j);
         if (x00 > xone) goto L160;
         if (xone > x11) break;
         xtwo = xone;
         y    = 0;
         if (!mside) y -= atick[0];
         Rotate(xone,y,cosphi,sinphi,x0,y0,xpl2,ypl2);
         Rotate(xtwo,atick[0],cosphi,sinphi,x0,y0,xpl1,ypl1);
         if (optionVert) {
            if ((x0 != x1) && (y0 != y1)) {
               if (mside) {
                  xpl1=xpl2;
                  if (cosphi > 0) ypl1 = ypl2 + atick[0];
                  else            ypl1 = ypl2 - atick[0];
               }
               else {
                  xpl1 = 0.5*(xpl1 + xpl2);
                  xpl2 = xpl1;
                  ypl1 = 0.5*(ypl1 + ypl2) + atick[0];
                  ypl2 = 0.5*(ypl1 + ypl2) - atick[0];
               }
            }
         }
         if (!drawGridOnly) lineaxis->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
         if (optionGrid) {
            Rotate(xone,0,cosphi,sinphi,x0,y0,xpl2,ypl2);
            Rotate(xone,grid_side*gridlength,cosphi,sinphi,x0,y0,xpl1,ypl1);
            linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
         }
         if (!drawGridOnly && !optionUnlab)  {
            if (noExponent) {
               rlab = TMath::Power(10,labelnumber);
               sprintf(label, "%f", rlab);
               LabelsLimits(label,first,last);
               while (last > first) {
                  if (label[last] != '0') break;
                  label[last] = 0;
                  last--;
               }
               if (label[last] == '.') {label[last] = 0; last--;}
            } else {
               sprintf(label, "%d", labelnumber);
               LabelsLimits(label,first,last);
            }
            Rotate (xone,ylabel,cosphi,sinphi,x0,y0,xx,yy);
            if ((x0 == x1) && !optionPara) {
               if (lside < 0) {
                  if (mside < 0) {
                     if (labelnumber == 0) nch=1;
                     else                  nch=2;
                     xx    += nch*charheight;
                  } else {
                     if (labelnumber >= 0) xx    += 0.25*charheight;
                     else                  xx    += 0.50*charheight;
                  }
               }
               xx += 0.25*charheight;
            }
            if ((y0 == y1) && !optionDown && !optionUp) {
               if (noExponent) yy += 0.33*charheight;
            }
            if (n1a == 0)goto L210;
            kmod = nbinin/n1a;
            if (kmod == 0) kmod=1000000;
            if ((nbinin <= n1a) || (j == 1) || (j == nbinin) || ((nbinin > n1a)
            && (j%kmod == 0))) {
               if (labelnumber == 0) {
                  textaxis->PaintTextNDC(xx,yy,"1");
               } else if (labelnumber == 1) {
                  textaxis->PaintTextNDC(xx,yy,"10");
               } else {
                  if (noExponent) {
                     textaxis->PaintTextNDC(xx,yy,&label[first]);
                  } else {
                        sprintf(chtemp, "10^{%d}", labelnumber);
                        textaxis->PaintLatex(gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1()),
                                             gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1()),
                                             0, textaxis->GetTextSize(), chtemp);
                  }
               }
            }
            labelnumber++;
         }
L160:
         for (k=2;k<10;k++) {
            xone = x00+axmul*(TMath::Log10(Double_t(k))+Double_t(decade)-xmnlog);
            if (x00 > xone) continue;
            if (xone > x11) goto L200;
            y = 0;
            if (!mside)  y -= atick[1];
            xtwo = xone;
            Rotate(xone,y,cosphi,sinphi,x0,y0,xpl2,ypl2);
            Rotate(xtwo,atick[1],cosphi,sinphi,x0,y0,xpl1,ypl1);
            if (optionVert) {
               if ((x0 != x1) && (y0 != y1)) {
                  if (mside) {
                     xpl1 = xpl2;
                     if (cosphi > 0) ypl1 = ypl2 + atick[1];
                     else            ypl1 = ypl2 - atick[1];
                  }
                  else {
                     xpl1 = 0.5*(xpl1+xpl2);
                     xpl2 = xpl1;
                     ypl1 = 0.5*(ypl1+ypl2) + atick[1];
                     ypl2 = 0.5*(ypl1+ypl2) - atick[1];
                  }
               }
            }
            idn = n1a*2;
            if ((nbinin <= idn) || ((nbinin > idn) && (k == 5))) {
               if (!drawGridOnly) lineaxis->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
               if (moreLogLabels && !optionUnlab && !drawGridOnly && !overlap) {
                  if (noExponent) {
                     rlab = Double_t(k)*TMath::Power(10,labelnumber-1);
                     sprintf(chtemp, "%g", rlab);
                  } else {
                     if (labelnumber-1 == 0) {
                        sprintf(chtemp, "%d", k);
                     } else if (labelnumber-1 == 1) {
                        sprintf(chtemp, "%d", 10*k);
                     } else {
                        sprintf(chtemp, "%d#times10^{%d}", k, labelnumber-1);
                     }
                  }
                  Rotate (xone,ylabel,cosphi,sinphi,x0,y0,xx,yy);
                  if ((x0 == x1) && !optionPara) {
                     if (lside < 0) {
                        if (mside < 0) {
                           if (labelnumber == 0) nch=1;
                           else                  nch=2;
                           xx    += nch*charheight;
                        } else {
                           if (labelnumber >= 0) xx    += 0.25*charheight;
                           else                  xx    += 0.50*charheight;
                        }
                     }
                     xx += 0.25*charheight;
                  }
                  if ((y0 == y1) && !optionDown && !optionUp) {
                     if (noExponent) yy += 0.33*charheight;
                  }
                  if (optionVert) {
                     if ((x0 != x1) && (y0 != y1)) {
                        Rotate(xone,ylabel,cosphi,sinphi,x0,y0,xx,yy);
                        if (cosphi > 0) yy += ylabel;
                        else            yy -= ylabel;
                     }
                  }
                  textaxis->SetTitle(chtemp);
                  Double_t u = gPad->GetX1() + xx*(gPad->GetX2() - gPad->GetX1());
                  Double_t v = gPad->GetY1() + yy*(gPad->GetY2() - gPad->GetY1());
                  if (firstintlab) {
                     textaxis->GetBoundingBox(wi, hi); wi=(UInt_t)(wi*1.3); hi*=(UInt_t)(hi*1.3);
                     xi1 = gPad->XtoAbsPixel(u);
                     yi1 = gPad->YtoAbsPixel(v);
                     firstintlab = kFALSE;
                     textaxis->PaintLatex(u,v,0,textaxis->GetTextSize(),chtemp);
                  } else {
                     xi2 = gPad->XtoAbsPixel(u);
                     yi2 = gPad->YtoAbsPixel(v);
                     if ((x0 == x1 && yi1-hi <= yi2) || (y0 == y1 && xi1+wi >= xi2)){
                        overlap = kTRUE;
                     } else {
                        xi1 = xi2;
                        yi1 = yi2;
                        textaxis->GetBoundingBox(wi, hi); wi=(UInt_t)(wi*1.3); hi*=(UInt_t)(hi*1.3);
                        textaxis->PaintLatex(u,v,0,textaxis->GetTextSize(),chtemp);
                     }
                  }
               }
               if (optionGrid && nbinin <= 5 && ndiv > 100) {
                  Rotate(xone,0,cosphi,sinphi,x0,y0,xpl2, ypl2);
                  Rotate(xone,grid_side*gridlength,cosphi,sinphi,x0,y0, xpl1,ypl1);
                  linegrid->PaintLineNDC(xpl1, ypl1, xpl2, ypl2);
               }
            }  
         }  
      } 
L200:
      Int_t kuku=0; if (kuku) { }
   }  
L210:
   delete lineaxis;
   delete linegrid;
   delete textaxis;
}
void TGaxis::AdjustBinSize(Double_t A1,  Double_t A2,  Int_t nold
                          ,Double_t &binLow, Double_t &binHigh, Int_t &nbins, Double_t &binWidth)
{
   binWidth = TMath::Abs(A2-A1)/Double_t(nold);
   if (binWidth <= 1) { binWidth = 1; binLow = int(A1); }
   else {
      Int_t width = int(binWidth/5) + 1;
      binWidth = 5*width;
      binLow   = int(A1/binWidth)*binWidth;
      if (A1 < 0) {
         for (Int_t ic=0; ic<1000; ic++) {
            Double_t rbl = binLow/binWidth;
            Int_t   ibl = int(binLow/binWidth);
            if ( (rbl-ibl) == 0 || ic > width) { binLow -= 5; break;}
         }
      }
   }
   binHigh     = int(A2);
   nbins       = 0;
   Double_t xb  = binLow;
   while (xb <= binHigh) {
      xb += binWidth;
      nbins++;
   }
   binHigh = xb - binWidth;
}
void TGaxis::LabelsLimits(const char *label, Int_t &first, Int_t &last)
{
   last = strlen(label)-1;
   for (Int_t i=0; i<=last; i++) {
      if (strchr("1234567890-+.", label[i]) ) { first = i; return; }
   }
   Error("LabelsLimits", "attempt to draw a blank label");
}
void TGaxis::Rotate(Double_t X,  Double_t Y,  Double_t CFI, Double_t SFI
                   ,Double_t XT, Double_t YT, Double_t &U,   Double_t &V)
{
      U = CFI*X-SFI*Y+XT;
      V = SFI*X+CFI*Y+YT;
}
void TGaxis::SavePrimitive(ostream &out, Option_t * )
{
    
   char quote = '"';
   if (gROOT->ClassSaved(TGaxis::Class())) {
      out<<"   ";
   } else {
      out<<"   TGaxis *";
   }
   out<<"gaxis = new TGaxis("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2
      <<","<<fWmin<<","<<fWmax<<","<<fNdiv<<","<<quote<<fChopt.Data()<<quote<<");"<<endl;
   out<<"   gaxis->SetLabelOffset("<<GetLabelOffset()<<");"<<endl;
   out<<"   gaxis->SetLabelSize("<<GetLabelSize()<<");"<<endl;
   out<<"   gaxis->SetTickSize("<<GetTickSize()<<");"<<endl;
   out<<"   gaxis->SetGridLength("<<GetGridLength()<<");"<<endl;
   out<<"   gaxis->SetTitleOffset("<<GetTitleOffset()<<");"<<endl;
   if (strlen(GetName())) {
      out<<"   gaxis->SetName("<<quote<<GetName()<<quote<<");"<<endl;
   }
   if (strlen(GetTitle())) {
      out<<"   gaxis->SetTitle("<<quote<<GetTitle()<<quote<<");"<<endl;
   }
   if (fLabelColor != 1) {
      if (fLabelColor > 228) {
         TColor::SaveColor(out, fLabelColor);
         out<<"   gaxis->SetLabelColor(ci);" << endl;
      } else
         out<<"   gaxis->SetLabelColor("<<GetLabelColor()<<");"<<endl;
   }
   if (fLineColor != 1) {
      if (fLineColor > 228) {
         TColor::SaveColor(out, fLineColor);
         out<<"   gaxis->SetLineColor(ci);" << endl;
      } else
         out<<"   gaxis->SetLineColor("<<GetLineColor()<<");"<<endl;
   }
   if (fLineStyle != 1) {
      out<<"   gaxis->SetLineStyle("<<GetLineStyle()<<");"<<endl;
   }
   if (fLineWidth != 1) {
      out<<"   gaxis->SetLineWidth("<<GetLineWidth()<<");"<<endl;
   }
   if (fLabelFont != 62) {
      out<<"   gaxis->SetLabelFont("<<GetLabelFont()<<");"<<endl;
   }
   if (TestBit(TAxis::kMoreLogLabels)) {
      out<<"   gaxis->SetMoreLogLabels();"<<endl;
   }
   if (TestBit(TAxis::kNoExponent)) {
      out<<"   gaxis->SetNoExponent();"<<endl;
   }
   out<<"   gaxis->Draw();"<<endl;
}
void TGaxis::SetDecimals(Bool_t dot)
{
   if (dot) SetBit(TAxis::kDecimals);
   else     ResetBit(TAxis::kDecimals);
}
void TGaxis::SetFunction(const char *funcname)
{
   fFunctionName = funcname;
   if (strlen(funcname) == 0) {
      fFunction = 0;
      return;
   }
   fFunction = (TF1*)gROOT->GetFunction(funcname);
   if (!fFunction) {
      Error("SetFunction, Unknown function:%s",funcname);
   } else {
      fWmin = fFunction->GetXmin();
      fWmax = fFunction->GetXmax();
   }
}
void TGaxis::SetMaxDigits(Int_t maxd)
{
   
   
   
   
   
   
   
   fgMaxDigits = maxd;
   if (maxd < 1) fgMaxDigits = 1;
}
void TGaxis::SetName(const char *name)
{
   fName = name;
}
void TGaxis::SetMoreLogLabels(Bool_t more)
{
   if (more) SetBit(TAxis::kMoreLogLabels);
   else      ResetBit(TAxis::kMoreLogLabels);
}
void TGaxis::SetNoExponent(Bool_t noExponent)
{
   if (noExponent) SetBit(TAxis::kNoExponent);
   else            ResetBit(TAxis::kNoExponent);
}
void TGaxis::SetOption(Option_t *option)
{
   fChopt = option;
}
void TGaxis::SetTitle(const char *title)
{
   fTitle = title;
}
void TGaxis::SetTimeFormat(const char *tformat)
{
   TString timeformat = tformat;
   if (timeformat.Index("%F")>=0 || timeformat.IsNull()) {
      fTimeFormat = timeformat;
      return;
   }
   Int_t idF = fTimeFormat.Index("%F");
   if (idF>=0) {
      Int_t lnF = fTimeFormat.Length();
      TString stringtimeoffset = fTimeFormat(idF,lnF);
      fTimeFormat = tformat;
      fTimeFormat.Append(stringtimeoffset);
   } else {
      fTimeFormat = tformat;
      SetTimeOffset(gStyle->GetTimeOffset());
   }
}
void TGaxis::SetTimeOffset(Double_t toffset, Option_t *option)
{
   
   
   TString opt = option;
   opt.ToLower();
   Bool_t gmt = kFALSE;
   if (opt.Contains("gmt")) gmt = kTRUE;
   char tmp[20];
   time_t timeoff;
   struct tm* utctis;
   Int_t idF = fTimeFormat.Index("%F");
   if (idF>=0) fTimeFormat.Remove(idF);
   fTimeFormat.Append("%F");
   timeoff = (time_t)((Long_t)(toffset));
   utctis = gmtime(&timeoff);
   strftime(tmp,256,"%Y-%m-%d %H:%M:%S",utctis);
   fTimeFormat.Append(tmp);
   
   Double_t ds = toffset-(Int_t)toffset;
   if(ds!= 0) {
      sprintf(tmp,"s%g",ds);
      fTimeFormat.Append(tmp);
   }
   
   if (gmt) fTimeFormat.Append(" GMT");
}
void TGaxis::Streamer(TBuffer &R__b)
{
   
   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
      if (R__v > 3) {
         R__b.ReadClassBuffer(TGaxis::Class(), this, R__v, R__s, R__c);
         return;
      }
      
      TLine::Streamer(R__b);
      TAttText::Streamer(R__b);
      R__b >> fNdiv;
      R__b >> fWmin;
      R__b >> fWmax;
      R__b >> fGridLength;
      R__b >> fTickSize;
      R__b >> fLabelOffset;
      R__b >> fLabelSize;
      R__b >> fTitleOffset;
      R__b >> fTitleSize;
      R__b >> fLabelFont;
      if (R__v > 2) {
         R__b >> fLabelColor;
      }
      fChopt.Streamer(R__b);
      fName.Streamer(R__b);
      fTitle.Streamer(R__b);
      fTimeFormat.Streamer(R__b);
      if (R__v > 1) {
         fFunctionName.Streamer(R__b);
         fFunction = (TF1*)gROOT->GetFunction(fFunctionName.Data());
      }
      R__b.CheckByteCount(R__s, R__c, TGaxis::IsA());
      
   } else {
      R__b.WriteClassBuffer(TGaxis::Class(),this);
   }
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.