    // @(#)root/graf:$Name:  $:$Id: TGaxis.cxx,v 1.72 2004/06/16 08:51:25 brun Exp $
    // Author: Rene Brun, Olivier Couet   12/12/94

    /*************************************************************************
     * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
     * All rights reserved.                                                  *
     *                                                                       *
     * For the licensing terms see $ROOTSYS/LICENSE.                         *
     * For the list of contributors see $ROOTSYS/README/CREDITS.             *
     *************************************************************************/

    #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"

    Int_t TGaxis::fgMaxDigits = 5;
    const Int_t kHori = BIT(9); //defined in TPad

    ClassImp(TGaxis)

    //______________________________________________________________________________
    //
    // Service class for the graphical representation of axis.
    // Instances of this class are generated by the histogram classes and TGraph.
    //
    // The picture below has been generated by the following macro.
    //{
    //
    //  gROOT.Reset();
    //
    //  c1 = new TCanvas("c1","Examples of Gaxis",10,10,700,500);
    //
    //  c1->Range(-10,-1,10,1);
    //
    //  TGaxis *axis1 = new TGaxis(-4.5,-0.2,5.5,-0.2,-6,8,510,"");
    //  axis1->SetName("axis1");
    //  axis1->Draw();
    //
    //  TGaxis *axis2 = new TGaxis(-4.5,0.2,5.5,0.2,0.001,10000,510,"G");
    //  axis2->SetName("axis2");
    //  axis2->Draw();
    //
    //  TGaxis *axis3 = new TGaxis(-9,-0.8,-9,0.8,-8,8,50510,"");
    //  axis3->SetName("axis3");
    //  axis3->Draw();
    //
    //  TGaxis *axis4 = new TGaxis(-7,-0.8,-7,0.8,1,10000,50510,"G");
    //  axis4->SetName("axis4");
    //  axis4->Draw();
    //
    //  TGaxis *axis5 = new TGaxis(-4.5,-0.6,5.5,-0.6,1.2,1.32,80506,"-+");
    //  axis5->SetName("axis5");
    //  axis5->SetLabelSize(0.03);
    //  axis5->SetTextFont(72);
    //  axis5->SetLabelOffset(0.025);
    //
    //  axis5->Draw();
    //
    //  TGaxis *axis6 = new TGaxis(-4.5,0.6,5.5,0.6,100,900,50510,"-");
    //  axis6->SetName("axis6");
    //  axis6->Draw();
    //
    //  TGaxis *axis7 = new TGaxis(8,-0.8,8,0.8,0,9000,50510,"+L");
    //  axis7->SetName("axis7");
    //  axis7->SetLabelOffset(0.01);
    //  axis7->Draw();
    //
    //  //one can make axis going top->bottom. However because of a long standing
    //  //problem, the two x values should not be equal
    //  TGaxis *axis8 = new TGaxis(6.5,0.8,6.499,-0.8,0,90,50510,"-");
    //  axis8->SetName("axis8");
    //  axis8->Draw();
    //}
    //

/* */ //

// // // See the second TGaxis constructor for examples of TGaxis // with a mapping function. //______________________________________________________________________________ TGaxis::TGaxis(): TLine(), TAttText(11,0,1,62,0.040) { //*-*-*-*-*-*-*-*-*-*-*Gaxis default constructor-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* //*-* ========================= 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) { //*-*-*-*-*-*-*-*-*-*-*Gaxis normal constructor-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* //*-* ========================= // See explanation of parameters in PaintAxis // 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) { //*-*-*-*-*-*-*-*-*-*-*Gaxis constructor with a TF1 to map axis values-*-*-* //*-* =============================================== // See explanation of parameters in PaintAxis // Instead of the wmin,wmax arguments of the normal constructor, the // name of a TF1 function can be specified. This function will be used // by TGaxis::PaintAxis to map the user coordinates to the axis values // and ticks. // Examples: //void gaxis3a() //{ // gStyle->SetOptStat(0); // // TH2F *h2 = new TH2F("h","Axes",100,0,10,100,-2,2); // h2->Draw(); // // TF1 *f1=new TF1("f1","-x",-10,10); // TGaxis *A1 = new TGaxis(0,2,10,2,"f1",510,"-"); // A1->SetTitle("axis with decreasing values"); // A1->Draw(); // // TF1 *f2=new TF1("f2","exp(x)",0,2); // TGaxis *A2 = new TGaxis(1,1,9,1,"f2"); // A2->SetTitle("exponential axis"); // A2->SetLabelSize(0.03); // A2->SetTitleSize(0.03); // A2->SetTitleOffset(1.2); // A2->Draw(); // // TF1 *f3=new TF1("f3","log10(x)",1,1000); // TGaxis *A3 = new TGaxis(2,-2,2,0,"f3",505,"G"); // A3->SetTitle("logarithmic axis"); // A3->SetLabelSize(0.03); // A3->SetTitleSize(0.03); // A3->SetTitleOffset(1.2); // A3->Draw(); //} // /* */ //

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() { //*-*-*-*-*-*-*-*-*-*-*Gaxis default destructor-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* //*-* ======================= } //______________________________________________________________________________ void TGaxis::CenterLabels(Bool_t center) { // if center = kTRUE axis labels are centered in the center of the bin // default is to center on the primary tick marks // This option does not make sense if there are more bins than tick marks. if (center) SetBit(TAxis::kCenterLabels); else ResetBit(TAxis::kCenterLabels); } //______________________________________________________________________________ void TGaxis::CenterTitle(Bool_t center) { // if center = kTRUE axis title will be centered // default is right adjusted 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) { //*-*-*-*-*-*-*-*-*-*-*Draw this axis with new attributes*-*-*-*-*-*-*-*-*-* //*-* ================================== 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() { // static function returning fgMaxDigits (See SetMaxDigits) return fgMaxDigits; } //______________________________________________________________________________ void TGaxis::ImportAxisAttributes(TAxis *axis) { // Copy TAxis attributes to this TGaxis 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); //the bit is in TAxis::fAxis2 SetTimeFormat(axis->GetTimeFormat()); } //______________________________________________________________________________ void TGaxis::Paint(Option_t *) { //*-*-*-*-*-*-*-*-*-*-*Draw this axis with its current attributes*-*-*-*-*-*-* //*-* ========================================== Double_t wmin = fWmin; Double_t wmax = fWmax; Int_t ndiv = fNdiv; // following code required to support toggle of lin/log scales Double_t x1 = gPad->XtoPad(fX1); Double_t y1 = gPad->YtoPad(fY1); Double_t x2 = gPad->XtoPad(fX2); Double_t y2 = gPad->YtoPad(fY2); TString opt = fChopt; opt.ToUpper(); if (gPad->GetLogx()) { if ((y1 == y2) && !opt.Contains("G")) opt += "G"; } else { if ((y1 == y2) && opt.Contains("G")) opt.ReplaceAll("G",""); } if (gPad->GetLogy()) { if ((x1 == x2) && !opt.Contains("G")) opt += "G"; } else { if ((x1 == x2) && opt.Contains("G")) opt.ReplaceAll("G",""); } PaintAxis(x1,y1,x2,y2,wmin,wmax,ndiv,opt.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) { //*-*-*-*-*-*-*-*-*-*-*-*Control function to draw an axis*-*-*-*-*-*-*-*-*-*-* //*-* ================================ // //============> Original authors (O.Couet C.E.Vandoni N.Cremel-Somon) // largely modified and converted to C++ class by Rene Brun // // _Input parameters: // // xmin : X origin coordinate in WC space. // xmax : X end axis coordinate in WC space. // ymin : Y origin coordinate in WC space. // ymax : Y end axis coordinate in WC space. // wmin : Lowest value for the tick mark // labels written on the axis. // wmax : Highest value for the tick mark labels // written on the axis. // ndiv : Number of divisions. // // ndiv=N1 + 100*N2 + 10000*N3 // N1=number of 1st divisions. // N2=number of 2nd divisions. // N3=number of 3rd divisions. // e.g.: // nndi=0 --> no tick marks. // nndi=2 --> 2 divisions, one tick mark in the middle // of the axis. // // chopt : Options (see below). // // chopt='G': loGarithmic scale, default is linear. // chopt='B': Blank axis. Useful to superpose axis. // // Orientation of tick marks on axis. // ---------------------------------- // // Tick marks are normally drawn on the positive side of the axis, // however, if X0=X1, then negative. // // chopt='+': tick marks are drawn on Positive side. (default) // chopt='-': tick mark are drawn on the negative side. // i.e: '+-' --> tick marks are drawn on both sides of the axis. // chopt='U': Unlabeled axis, default is labeled. // // Size of tick marks // ------------------ // By default, tick marks have a length equal to 3 per cent of the // axis length. // When the option "S" is specified, the length of the tick marks // is equal to fTickSize*axis_length, where fTickSize may be set // via TGaxis::SetTickSize. // // Position of labels on axis. // --------------------------- // // Labels are normally drawn on side opposite to tick marks. // However: // // chopt='=': on Equal side // // Orientation of labels on axis. // ------------------------------ // // Labels are normally drawn parallel to the axis. // However if X0=X1, then Orthogonal // if Y0=Y1, then Parallel // // Position of labels on tick marks. // --------------------------------- // // Labels are centered on tick marks. // However , if X0=X1, then they are right adjusted. // // chopt='R': labels are Right adjusted on tick mark. // (default is centered) // chopt='L': labels are Left adjusted on tick mark. // chopt='C': labels are Centered on tick mark. // chopt='M': In the Middle of the divisions. // // Format of labels. // ----------------- // // Blank characters are stripped, and then the // label is correctly aligned. the dot, if last // character of the string, is also stripped, // unless the option "." (a dot, or period) is specified. // if SetDecimals(kTRUE) has been called (bit TAxis::kDecimals set). // all labels have the same number of decimals after the "." // The same is true if gStyle->SetStripDecimals(kFALSE) has been called. // // In the following, we have some parameters, like // tick marks length and characters height (in percentage // of the length of the axis (WC)) // The default values are as follows: // // Primary tick marks: 3.0 % // Secondary tick marks: 1.5 % // Third order tick marks: .75 % // Characters height for labels: 4% // // Labels offset: 1.0 % // // Optional grid. // -------------- // // chopt='W': cross-Wire // // Axis bining optimization. // ------------------------- // // By default the axis bining is optimized . // // chopt='N': No bining optimization // chopt='I': Integer labelling // // Maximum Number of Digits for the axis labels // -------------------------------------------- // See the static function TGaxis::SetMaxDigits // // Time representation. // -------------------- // // Axis labels may be considered as times, plotted in a defined time format. // The format is set with SetTimeFormat(). // wmin and wmax are considered as two time values in seconds. // The time axis will be spread around the time offset value (set with // SetTimeOffset() ). Actually it will go from TimeOffset+wmin to // TimeOffset+wmax. // see examples in tutorials timeonaxis.C and timeonaxis2.C // // chopt='t': Plot times with a defined format instead of values // 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, 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); //*-*- If MoreLogLabels = kTRUE more Log Intermediate Labels are drawn. Bool_t MoreLogLabels = TestBit(TAxis::kMoreLogLabels); //*-*- the following parameters correspond to the pad range in NDC //*-*- and the WC coordinates in the pad 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; } } //*-*- Set the grid length 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()); } //*-*- Determine time format Int_t IdF = fTimeFormat.Index("%F"); if (IdF>=0) { timeformat = fTimeFormat(0,IdF); } else { timeformat = fTimeFormat; } // determine the time offset and correct for time offset not being integer 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; tp.tm_year = yy-1900; tp.tm_mon = mm-1; tp.tm_mday = dd; tp.tm_hour = hh; tp.tm_min = mi; tp.tm_sec = ss; tp.tm_isdst = -1; timeoffset = mktime(&tp); // have to correct this time to go back to UTC timeoffsettest = (time_t)((Long_t)timeoffset); tptest = gmtime(&timeoffsettest); timeoffset += timeoffsettest - mktime(tptest); // Add the time offset's decimal part if it is there 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 OptionTime = 2 gmtime will be used instead of localtime 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); // correct for time offset at a good limit (min, hour, day, month, year) 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; // minutes if (range>3600) rangeBase = 3600*20; // hours if (range>86400) rangeBase = 86400*20; // days if (range>2419200) rangeBase = 31556736; // months (average # days) 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)); // years rangeOffset = (Double_t) (rangeBase); } wmax += rangeOffset; wmin += rangeOffset; } //*-*- Determine number of divisions 1, 2 and 3 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; //*-*- Axis bining optimization is ignored if: //*-*- - the first and the last label are equal //*-*- - the number of divisions is 0 //*-*- - less than 1 primary division is requested //*-*- - logarithmic scale is requested if (wmin == wmax || ndiv == 0 || N1A <= 1 || OptionLog) { OptionNoopt = 1; OptionInt = 0; } //*-*- Axis bining optimization if ( (wmax-wmin) < 1 && OptionInt) { Error(where, "option I not available"); OptionInt = 0; } if (!OptionNoopt || OptionInt ) { //*-*- Primary divisions optimization //*-*- When integer labelling is required, Optimize is invoked first //*-*- and only if the result is not an integer labelling, AdjustBinSize is invoked. 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; } //*-*- Secondary divisions optimization NB2 = N2A; if (!OptionNoopt && N2A > 1 && BinWidth > 0) { THLimitsFinder::Optimize(wmin,wmin+BinWidth,N2A,BinLow2,BinHigh2,NB2,BinWidth2,fChopt.Data()); } //*-*- Tertiary divisions optimization 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; } //*-*- Coordinates are normalized 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; } //*-*- Return wmin, wmax and the number of primary divisions 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(gStyle->GetLineWidth()); textaxis->SetTextColor(GetTextColor()); textaxis->SetTextFont(GetTextFont()); if (!gPad->IsBatch()) { gVirtualX->GetCharacterUp(chupxvsav, chupyvsav); gVirtualX->SetClipOFF(gPad->GetCanvasID()); } //*-*- Compute length of axis 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 positive, tick marks on positive side //*-*- Mside negative, tick marks on negative side //*-*- Mside zero, tick marks on both sides //*-*- Default is positive except for vertical axis 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; //*-*- Tick marks size 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]; //*-*- Set the side of the grid if ((X0 == X1) && (Y1 > Y0)) grid_side =-1; else grid_side = 1; //*-*- Compute Values if Function is given if(fFunction) { rwmi = fFunction->Eval(wmin); rwma = fFunction->Eval(wmax); if(rwmi > rwma) { Double_t t = rwma; rwma = rwmi; rwmi = t; } } //*-*- Draw the axis if needed... if (!OptionBlank) { xpl1 = X0; xpl2 = X1; ypl1 = Y0; ypl2 = Y1; lineaxis->PaintLineNDC(xpl1, ypl1, xpl2, ypl2); } //*-*- No bining if (ndiv == 0)goto L210; if (wmin == wmax) { Error(where, "wmin (%f) == wmax (%f)", wmin, wmax); goto L210; } //*-*- Draw axis title if it exists if (!drawGridOnly && strlen(GetTitle())) { textaxis->SetTextSize (GetTitleSize()); charheight = GetTitleSize(); if ((GetTextFont() % 10) > 2) { charheight = charheight/gPad->GetWh(); } Double_t toffset = GetTitleOffset(); if (toffset < 0.1) toffset = 1; 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()); } } //*-*- Labels preparation: //*-*- Get character height //*-*- Compute the labels orientation in case of overlaps //*-*- (with alphanumeric labels for horizontal axis). charheight = GetLabelSize(); if (OptionText) charheight *= 0.66666; textaxis->SetTextFont(GetLabelFont()); 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, charheight, 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, charheight, fAxis->GetBinLabel(i)); } else { textaxis->PaintLatex(xmin - 3*fAxis->GetLabelOffset()*(gPad->GetUxmax()-gPad->GetUxmin()), ymin +(i-0.5)*(ymax-ymin)/nl, 0, charheight, fAxis->GetBinLabel(i)); } } } } //*-*- Now determine orientation of labels on axis 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); } //*-*- Now determine text alignment 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); //*-*- Position of labels in Y 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; //*-*- Draw the linear tick marks if needed... 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; } } } } //*-*- Draw the numeric labels if needed... if (!drawGridOnly && !OptionUnlab) { if (!OptionLog) { if (N1A) { //*-*- Spacing of labels 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) { //*-*- We have to decide what format to generate //*-*- (for numeric labels only) //*-*- Test the magnitude, decide format FLEXE = kFALSE; NEXE = 0; FLEXPO = kFALSE; FLEXNE = kFALSE; WW = TMath::Max(TMath::Abs(wmin),TMath::Abs(wmax)); //*-*- First case : (wmax-wmin)/N1A less than 0.001 //*-*- (0.001 fgMaxDigits of 5 (fgMaxDigits) characters). Then we use x 10 n //*-*- format. If AF >=0 x10 n cannot be used 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; //*-*- Use x 10 n format. (only powers of 3 allowed) 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); //*-*- In some cases, IF1 and IF2 are too small.... 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); } //*-*- We draw labels 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); //Eliminate blanks if (LABEL[first] == '.') { //check if '.' is preceeded by a digit 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); } //*-*- We eliminate the non significant 0 after '.' if (ndecimals) { char *adot = strchr(LABEL,'.'); if (adot) adot[ndecimals] = 0; } else { while (LABEL[last] == '0') { LABEL[last] = 0; last--;} } //*-*- We eliminate the dot, unless dot is forced. if (LABEL[last] == '.') { if (!OptionDot) { LABEL[last] = 0; last--;} } } //*-*- Generate the time labels 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}"; //*-*- Appends fractionnal part if seconds displayed if (DWlabel<0.9) { double tmpdb; int tmplast; sprintf(LABEL,"%%S%7.5f",modf(timed,&tmpdb)); tmplast = strlen(LABEL)-1; //*-*- We eliminate the non significiant 0 after '.' while (LABEL[tmplast] == '0') { LABEL[tmplast] = 0; tmplast--; } timeformattmp.ReplaceAll("%S",LABEL); //*-*- replace the "0." at the begining by "s" 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; } //*-*- We generate labels (numeric or alphanumeric). 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 { //*-*- Text alignment is down 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; } } } //*-*- We use the format x 10 ** n 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); textaxis->PaintLatex(gPad->GetX1() + XX*(gPad->GetX2() - gPad->GetX1()), gPad->GetY1() + YY*(gPad->GetY2() - gPad->GetY1()), 0, textaxis->GetTextSize(), LABEL); } } } } //*-*- Log axis 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); //*-*- Plot decade and intermediate tick marks decade = IH1-2; labelnumber = IH1; if ( XMNLOG > 0 && (XMNLOG-Double_t(IH1) > 0) ) labelnumber++; for (j=1; j<=NBININ; j++) { //*-*- Plot decade 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); //the following statement is a trick to circumvent a gcc bug if (j < 0) printf("j=%dn",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) { //*-*- We generate labels (numeric only). 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++) { //*-*- Plot intermediate tick marks 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); //*-*- Draw the intermediate LOG labels if requested 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 ((Y0 == Y1) && !OptionDown && !OptionUp) { if (noExponent) YY += 0.33*charheight; } if ((X0 == X1)) XX += 0.25*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); } } } //*-*- Draw the intermediate LOG grid if only three decades are requested if (OptionGrid && NBININ <= 5) { 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); } } //endif ((NBININ <= IDN) || } //endfor (k=2;k<10;k++) } //endfor (j=1; j<=NBININ; j++) L200: Int_t kuku=0; if (kuku) { } } //endif (OptionLog && ndiv) 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) { //*-*-*-*-*-*-*-*-*-*-*-*Axis labels optimisation*-*-*-*-*-*-*-*-*-*-*-*-*-* //*-* ======================== // // This routine adjusts the bining of the axis // in order to have integer values for the labels // // _Input parameters: // // A1,A2 : Old WMIN,WMAX . // BinLow,BinHigh : New WMIN,WMAX . // nold : Old NDIV (primary divisions) // nbins : New NDIV . // 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; //*-*- We determine BinLow to have one tick mark at 0 //*-*- if there are negative labels. 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) { //*-*-*-*-*-*-*-*-*Find first and last character of a label*-*-*-*-*-*-*-*-*-* //*-* ======================================== 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) { //*-*-*-*-*-*-*-*-*-*-*-*-*-*Rotate axis coordinates*-*-*-*-*-*-*-*-*-*-*-*-* //*-* ======================= U = CFI*X-SFI*Y+XT; V = SFI*X+CFI*Y+YT; } //______________________________________________________________________________ void TGaxis::SavePrimitive(ofstream &out, Option_t *) { // Save primitive as a C++ statement(s) on output stream out 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) { out<<" gaxis->SetLabelColor("<<GetLabelColor()<<");"<<endl; } if (fLineColor != 1) { 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) { // Set the Decimals flag // By default, blank characters are stripped, and then the // label is correctly aligned. The dot, if last character of the string, // is also stripped, unless this option is specified. // One can disable the option by calling axis.SetDecimals(kTRUE). // Note the bit is set in fBits (as opposed to fBits2 in TAxis!) if (dot) SetBit(TAxis::kDecimals); else ResetBit(TAxis::kDecimals); } //______________________________________________________________________________ void TGaxis::SetFunction(const char *funcname) { // specify a function to map the axis values // ========================================= 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) { // static function to set fgMaxDigits for axis with the bin content // (y axis for 1-d histogram, z axis for 2-d histogram) //fgMaxDigits is the maximum number of digits permitted for the axis //labels above which the notation with 10^N is used. //For example, to accept 6 digits number like 900000 on an axis //call TGaxis::SetMaxDigits(6). The default value is 5. //fgMaxDigits must be greater than 0. fgMaxDigits = maxd; if (maxd < 1) fgMaxDigits = 1; } //______________________________________________________________________________ void TGaxis::SetName(const char *name) { //*-*-*-*-*-*-*-*-*-*-*Change the name of the axis*-*-*-*-*-*-*-*-*-*-*-*-*-* //*-* ============================ fName = name; } //______________________________________________________________________________ void TGaxis::SetMoreLogLabels(Bool_t more) { // Set the kMoreLogLabels bit flag // When this option is selected more labels are drawn when in log scale // and there is a small number of decades (<3). // Note that this option is automatically inherited from TAxis if (more) SetBit(TAxis::kMoreLogLabels); else ResetBit(TAxis::kMoreLogLabels); } //______________________________________________________________________________ void TGaxis::SetNoExponent(Bool_t noExponent) { // Set the NoExponent flag // By default, an exponent of the form 10^N is used when the label values // are either all very small or very large. // One can disable the exponent by calling axis.SetNoExponent(kTRUE). if (noExponent) SetBit(TAxis::kNoExponent); else ResetBit(TAxis::kNoExponent); } //______________________________________________________________________________ void TGaxis::SetOption(Option_t *option) { //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*To set axis options*-*-*-*-*-*-*-*-*-*-*-*-*-* //*-* =================== fChopt = option; } //______________________________________________________________________________ void TGaxis::SetTitle(const char *title) { //*-*-*-*-*-*-*-*-*-*-*Change the title of the axis*-*-*-*-*-*-*-*-*-*-*-*-* //*-* ============================ fTitle = title; } //______________________________________________________________________________ void TGaxis::SetTimeFormat(const char *tformat) { //*-*-*-*-*-*-*-*-*-*-*Change the format used for time plotting *-*-*-*-*-*-*-* //*-* ======================================== // The format string for date and time use the same options as the one used // in the standard strftime C function, i.e. : // for date : // %a abbreviated weekday name // %b abbreviated month name // %d day of the month (01-31) // %m month (01-12) // %y year without century // // for time : // %H hour (24-hour clock) // %I hour (12-hour clock) // %p local equivalent of AM or PM // %M minute (00-59) // %S seconds (00-61) // %% % // 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) { // Change the time offset // If option = "gmt" the time offset is treated as a GMT time. 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); // append the decimal part of the time offset Double_t ds = toffset-(Int_t)toffset; if(ds!= 0) { sprintf(tmp,"s%g",ds); fTimeFormat.Append(tmp); } // If the time is GMT, stamp fTimeFormat if (gmt) fTimeFormat.Append(" GMT"); } //______________________________________________________________________________ void TGaxis::Streamer(TBuffer &R__b) { // Stream an object of class TGaxis. 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) { TGaxis::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c); return; } //====process old versions before automatic schema evolution 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()); //====end of old versions } else { TGaxis::Class()->WriteBuffer(R__b,this); } }