TAxis.cxx

Go to the documentation of this file.
00001 // @(#)root/hist:$Id: TAxis.cxx 36506 2010-11-04 20:58:59Z brun $
00002 // Author: Rene Brun   12/12/94
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "Riostream.h"
00013 #include "TAxis.h"
00014 #include "TVirtualPad.h"
00015 #include "TStyle.h"
00016 #include "TError.h"
00017 #include "THashList.h"
00018 #include "TH1.h"
00019 #include "TObjString.h"
00020 #include "TDatime.h"
00021 #include "TROOT.h"
00022 #include "TClass.h"
00023 #include "TMath.h"
00024 #include <time.h>
00025 
00026 ClassImp(TAxis)
00027 
00028 //______________________________________________________________________________
00029 //
00030 // This class manages histogram axis. It is referenced by TH1 and TGraph.
00031 // To make a graphical representation of an histogram axis, this class
00032 // references the TGaxis class.
00033 //
00034 // TAxis supports axis with fixed or variable bin sizes.
00035 // Labels may be associated to individual bins.
00036 //
00037 //    see examples of various axis representations drawn by class TGaxis.
00038 //
00039 
00040 //______________________________________________________________________________
00041 TAxis::TAxis(): TNamed(), TAttAxis()
00042 {
00043    // Default constructor.
00044 
00045    fNbins   = 1;
00046    fXmin    = 0;
00047    fXmax    = 1;
00048    fFirst   = 0;
00049    fLast    = 0;
00050    fParent  = 0;
00051    fLabels  = 0;
00052    fBits2   = 0;
00053    fTimeDisplay = 0;
00054 }
00055 
00056 //______________________________________________________________________________
00057 TAxis::TAxis(Int_t nbins,Double_t xlow,Double_t xup): TNamed(), TAttAxis()
00058 {
00059    // Axis constructor for axis with fix bin size
00060 
00061    fParent  = 0;
00062    fLabels  = 0;
00063    Set(nbins,xlow,xup);
00064 }
00065 
00066 //______________________________________________________________________________
00067 TAxis::TAxis(Int_t nbins,const Double_t *xbins): TNamed(), TAttAxis()
00068 {
00069    // Axis constructor for variable bin size
00070 
00071    fParent  = 0;
00072    fLabels  = 0;
00073    Set(nbins,xbins);
00074 }
00075 
00076 //______________________________________________________________________________
00077 TAxis::~TAxis()
00078 {
00079    // Destructor.
00080 
00081    if (fLabels) {
00082       fLabels->Delete();
00083       delete fLabels;
00084       fLabels = 0;
00085    }
00086 }
00087 
00088 //______________________________________________________________________________
00089 TAxis::TAxis(const TAxis &axis) : TNamed(axis), TAttAxis(axis)
00090 {
00091    // Copy constructor.
00092 
00093    ((TAxis&)axis).Copy(*this);
00094 }
00095 
00096 //______________________________________________________________________________
00097 void TAxis::CenterLabels(Bool_t center)
00098 {
00099    //   if center = kTRUE axis labels will be centered (hori axes only)
00100    //   on the bin center
00101    //   default is to center on the primary tick marks
00102    //   This option does not make sense if there are more bins than tick marks
00103 
00104    if (center) SetBit(kCenterLabels);
00105    else        ResetBit(kCenterLabels);
00106 }
00107 
00108 //______________________________________________________________________________
00109 Bool_t TAxis::GetCenterLabels() const
00110 {
00111    // Return kTRUE if kCenterLabels bit is set, kFALSE otherwise.
00112 
00113    return TestBit(kCenterLabels) ? kTRUE : kFALSE;
00114 }
00115 
00116 //______________________________________________________________________________
00117 void TAxis::CenterTitle(Bool_t center)
00118 {
00119    //   if center = kTRUE axis title will be centered
00120    //   default is right adjusted
00121 
00122    if (center) SetBit(kCenterTitle);
00123    else        ResetBit(kCenterTitle);
00124 }
00125 
00126 //______________________________________________________________________________
00127 Bool_t TAxis::GetCenterTitle() const
00128 {
00129    // Return kTRUE if kCenterTitle bit is set, kFALSE otherwise.
00130 
00131    return TestBit(kCenterTitle) ? kTRUE : kFALSE;
00132 }
00133 
00134 //______________________________________________________________________________
00135 const char *TAxis::ChooseTimeFormat(Double_t axislength)
00136 {
00137    // Choose a reasonable time format from the coordinates in the active pad
00138    // and the number of divisions in this axis
00139    // If orientation = "X", the horizontal axis of the pad will be used for ref.
00140    // If orientation = "Y", the vertical axis of the pad will be used for ref.
00141 
00142    const char *formatstr;
00143    Int_t reasformat = 0;
00144    Int_t ndiv,nx1,nx2,n;
00145    Double_t awidth;
00146    Double_t length;
00147 
00148    if (!axislength) {
00149       length = gPad->GetUxmax() - gPad->GetUxmin();
00150    } else {
00151       length = axislength;
00152    }
00153 
00154    ndiv = GetNdivisions();
00155    if (ndiv > 1000) {
00156       nx2   = ndiv/100;
00157       nx1   = TMath::Max(1, ndiv%100);
00158       ndiv = 100*nx2 + Int_t(Double_t(nx1)*gPad->GetAbsWNDC());
00159    }
00160    ndiv = TMath::Abs(ndiv);
00161    n = ndiv - (ndiv/100)*100;
00162    awidth = length/n;
00163 
00164 //  width in seconds ?
00165    if (awidth>=.5) {
00166       reasformat = 1;
00167 //  width in minutes ?
00168       if (awidth>=30) {
00169          awidth /= 60; reasformat = 2;
00170 //   width in hours ?
00171          if (awidth>=30) {
00172             awidth /=60; reasformat = 3;
00173 //   width in days ?
00174             if (awidth>=12) {
00175                awidth /= 24; reasformat = 4;
00176 //   width in months ?
00177                if (awidth>=15.218425) {
00178                   awidth /= 30.43685; reasformat = 5;
00179 //   width in years ?
00180                   if (awidth>=6) {
00181                      awidth /= 12; reasformat = 6;
00182                      if (awidth>=2) {
00183                         awidth /= 12; reasformat = 7;
00184                      }
00185                   }
00186                }
00187             }
00188          }
00189       }
00190    }
00191 //   set reasonable format
00192    switch (reasformat) {
00193       case 0:
00194         formatstr = "%S";
00195         break;
00196       case 1:
00197         formatstr = "%Mm%S";
00198         break;
00199       case 2:
00200         formatstr = "%Hh%M";
00201         break;
00202       case 3:
00203         formatstr = "%d-%Hh";
00204         break;
00205       case 4:
00206         formatstr = "%d/%m";
00207         break;
00208       case 5:
00209         formatstr = "%d/%m/%y";
00210         break;
00211       case 6:
00212         formatstr = "%d/%m/%y";
00213         break;
00214       case 7:
00215         formatstr = "%m/%y";
00216         break;
00217    }
00218    return formatstr;
00219 }
00220 
00221 //______________________________________________________________________________
00222 void TAxis::Copy(TObject &obj) const
00223 {
00224    // Copy axis structure to another axis
00225 
00226    TNamed::Copy(obj);
00227    TAttAxis::Copy(((TAxis&)obj));
00228    ((TAxis&)obj).fNbins  = fNbins;
00229    ((TAxis&)obj).fXmin   = fXmin;
00230    ((TAxis&)obj).fXmax   = fXmax;
00231    ((TAxis&)obj).fFirst  = fFirst;
00232    ((TAxis&)obj).fLast   = fLast;
00233    ((TAxis&)obj).fBits2  = fBits2;
00234    fXbins.Copy(((TAxis&)obj).fXbins);
00235    ((TAxis&)obj).fTimeFormat   = fTimeFormat;
00236    ((TAxis&)obj).fTimeDisplay  = fTimeDisplay;
00237    ((TAxis&)obj).fParent       = fParent;
00238    ((TAxis&)obj).fLabels       = 0;
00239    if (fLabels) {
00240       for (Int_t i=1;i<=fNbins;i++) ((TAxis&)obj).SetBinLabel(i,this->GetBinLabel(i));
00241    }
00242 }
00243 
00244 //______________________________________________________________________________
00245 Int_t TAxis::DistancetoPrimitive(Int_t, Int_t)
00246 {
00247    // Compute distance from point px,py to an axis
00248 
00249    return 9999;
00250 }
00251 
00252 //______________________________________________________________________________
00253 void TAxis::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00254 {
00255    // Execute action corresponding to one event
00256    //
00257    //  This member function is called when an axis is clicked with the locator
00258    //
00259    //  The axis range is set between the position where the mouse is pressed
00260    //  and the position where it is released.
00261    //  If the mouse position is outside the current axis range when it is released
00262    //  the axis is unzoomed with the corresponding proportions.
00263    //  Note that the mouse does not need to be in the pad or even canvas
00264    //  when it is released.
00265 
00266    if (!gPad) return;
00267    gPad->ExecuteEventAxis(event,px,py,this);
00268 }
00269 
00270 //______________________________________________________________________________
00271 Int_t TAxis::FindBin(Double_t x)
00272 {
00273    // Find bin number corresponding to abscissa x
00274    //
00275    // If x is underflow or overflow, attempt to rebin histogram
00276 
00277    Int_t bin;
00278    if (x < fXmin) {              //*-* underflow
00279       bin = 0;
00280       if (fParent == 0) return bin;
00281       if (!fParent->TestBit(TH1::kCanRebin)) return bin;
00282       ((TH1*)fParent)->RebinAxis(x,this);
00283       return FindFixBin(x);
00284    } else  if ( !(x < fXmax)) {     //*-* overflow  (note the way to catch NaN
00285       bin = fNbins+1;
00286       if (fParent == 0) return bin;
00287       if (!fParent->TestBit(TH1::kCanRebin)) return bin;
00288       ((TH1*)fParent)->RebinAxis(x,this);
00289       return FindFixBin(x);
00290    } else {
00291       if (!fXbins.fN) {        //*-* fix bins
00292          bin = 1 + int (fNbins*(x-fXmin)/(fXmax-fXmin) );
00293       } else {                  //*-* variable bin sizes
00294          //for (bin =1; x >= fXbins.fArray[bin]; bin++);
00295          bin = 1 + TMath::BinarySearch(fXbins.fN,fXbins.fArray,x);
00296       }
00297    }
00298    return bin;
00299 }
00300 
00301 //______________________________________________________________________________
00302 Int_t TAxis::FindBin(const char *label)
00303 {
00304    // Find bin number with label.
00305    // If label is not in the list of labels, add it.
00306    // If the number of labels exceeds the number of bins, double the number
00307    // of bins via TH1::LabelsInflate (if the histogram can be rebinned).
00308 
00309    //create list of labels if it does not exist yet
00310    if (!fLabels) {
00311       if (!fParent) return -1;
00312       fLabels = new THashList(1,1);
00313       fParent->SetBit(TH1::kCanRebin);
00314       if (fXmax <= fXmin) fXmax = fXmin+1;
00315    }
00316 
00317    // search for label in the existing list
00318    TObjString *obj = (TObjString*)fLabels->FindObject(label);
00319    if (obj) return (Int_t)obj->GetUniqueID();
00320 
00321    //Not yet in the list. Can we rebin the histogram ?
00322    if (!fParent->TestBit(TH1::kCanRebin)) return -1;
00323 
00324    // count number of labels in the list
00325    Int_t n = 0;
00326    TIter next(fLabels);
00327    while (next()) {
00328       n++;
00329    }
00330    TH1 *h = (TH1*)fParent;
00331 
00332    //may be we have to resize the histogram (doubling number of channels)
00333    if (n >= fNbins) h->LabelsInflate(GetName());
00334 
00335    //add new label to the list: assign bin number
00336    obj = new TObjString(label);
00337    fLabels->Add(obj);
00338    obj->SetUniqueID(n+1);
00339    return n+1;
00340 }
00341 
00342 //______________________________________________________________________________
00343 Int_t TAxis::FindFixBin(Double_t x) const
00344 {
00345    // Find bin number corresponding to abscissa x
00346 
00347    Int_t bin;
00348    if (x < fXmin) {              //*-* underflow
00349       bin = 0;
00350    } else  if ( !(x < fXmax)) {     //*-* overflow  (note the way to catch NaN
00351       bin = fNbins+1;
00352    } else {
00353       if (!fXbins.fN) {        //*-* fix bins
00354          bin = 1 + int (fNbins*(x-fXmin)/(fXmax-fXmin) );
00355       } else {                  //*-* variable bin sizes
00356 //         for (bin =1; x >= fXbins.fArray[bin]; bin++);
00357          bin = 1 + TMath::BinarySearch(fXbins.fN,fXbins.fArray,x);
00358       }
00359    }
00360    return bin;
00361 }
00362 
00363 //______________________________________________________________________________
00364 const char *TAxis::GetBinLabel(Int_t bin) const
00365 {
00366    // Return label for bin
00367 
00368    if (!fLabels) return "";
00369    if (bin <= 0 || bin > fNbins) return "";
00370    TIter next(fLabels);
00371    TObjString *obj;
00372    while ((obj=(TObjString*)next())) {
00373       Int_t binid = (Int_t)obj->GetUniqueID();
00374       if (binid == bin) return obj->GetName();
00375    }
00376    return "";
00377 }
00378 
00379 //______________________________________________________________________________
00380 Int_t TAxis::GetFirst() const
00381 {
00382    //             return first bin on the axis
00383    //       ie 1 if no range defined
00384    //       NOTE: in some cases a zero is returned (see TAxis::SetRange)
00385 
00386    if (!TestBit(kAxisRange)) return 1;
00387    return fFirst;
00388 }
00389 
00390 //______________________________________________________________________________
00391 Int_t TAxis::GetLast() const
00392 {
00393    //             return last bin on the axis
00394    //       ie fNbins if no range defined
00395    //       NOTE: in some cases a zero is returned (see TAxis::SetRange)
00396 
00397    if (!TestBit(kAxisRange)) return fNbins;
00398    return fLast;
00399 }
00400 
00401 //______________________________________________________________________________
00402 Double_t TAxis::GetBinCenter(Int_t bin) const
00403 {
00404    // Return center of bin
00405 
00406    Double_t binwidth;
00407    if (!fXbins.fN || bin<1 || bin>fNbins) {
00408       binwidth = (fXmax - fXmin) / Double_t(fNbins);
00409       return fXmin + (bin-1) * binwidth + 0.5*binwidth;
00410    } else {
00411       binwidth = fXbins.fArray[bin] - fXbins.fArray[bin-1];
00412       return fXbins.fArray[bin-1] + 0.5*binwidth;
00413    }
00414 }
00415 
00416 //______________________________________________________________________________
00417 Double_t TAxis::GetBinCenterLog(Int_t bin) const
00418 {
00419    // Return center of bin in log
00420    // With a log-equidistant binning for a bin with low and up edges, the mean is : 
00421    // 0.5*(ln low + ln up) i.e. sqrt(low*up) in logx (e.g. sqrt(10^0*10^2) = 10). 
00422    //Imagine a bin with low=1 and up=100 : 
00423    // - the center in lin is (100-1)/2=50.5 
00424    // - the center in log would be sqrt(1*100)=10 (!=log(50.5)) 
00425    // NB: if the low edge of the bin is negative, the function returns the bin center
00426    //     as computed by TAxis::GetBinCenter
00427    
00428    Double_t low,up;
00429    if (!fXbins.fN || bin<1 || bin>fNbins) {
00430       Double_t binwidth = (fXmax - fXmin) / Double_t(fNbins);
00431       low = fXmin + (bin-1) * binwidth;
00432       up  = low+binwidth;
00433    } else {
00434       low = fXbins.fArray[bin-1];
00435       up  = fXbins.fArray[bin];
00436    }
00437    if (low <=0 ) return GetBinCenter(bin);
00438    return TMath::Sqrt(low*up);
00439 }
00440 //______________________________________________________________________________
00441 Double_t TAxis::GetBinLowEdge(Int_t bin) const
00442 {
00443    // Return low edge of bin
00444 
00445    if (fXbins.fN && bin > 0 && bin <=fNbins) return fXbins.fArray[bin-1];
00446    Double_t binwidth = (fXmax - fXmin) / Double_t(fNbins);
00447    return fXmin + (bin-1) * binwidth;
00448 }
00449 
00450 //______________________________________________________________________________
00451 Double_t TAxis::GetBinUpEdge(Int_t bin) const
00452 {
00453    // Return up edge of bin
00454 
00455    Double_t binwidth;
00456    if (!fXbins.fN || bin<1 || bin>fNbins) {
00457       binwidth = (fXmax - fXmin) / Double_t(fNbins);
00458       return fXmin + bin*binwidth;
00459    } else {
00460       binwidth = fXbins.fArray[bin] - fXbins.fArray[bin-1];
00461       return fXbins.fArray[bin-1] + binwidth;
00462    }
00463 }
00464 
00465 //______________________________________________________________________________
00466 Double_t TAxis::GetBinWidth(Int_t bin) const
00467 {
00468    // Return bin width
00469 
00470    if (fNbins <= 0) return 0;
00471    if (fXbins.fN <= 0)  return (fXmax - fXmin) / Double_t(fNbins);
00472    if (bin >fNbins) bin = fNbins;
00473    if (bin <1 ) bin = 1;
00474    return fXbins.fArray[bin] - fXbins.fArray[bin-1];
00475 }
00476 
00477 
00478 //______________________________________________________________________________
00479 void TAxis::GetCenter(Double_t *center) const
00480 {
00481    // Return an array with the center of all bins
00482 
00483    Int_t bin;
00484    for (bin=1; bin<=fNbins; bin++) *(center + bin-1) = GetBinCenter(bin);
00485 }
00486 
00487 //______________________________________________________________________________
00488 void TAxis::GetLowEdge(Double_t *edge) const
00489 {
00490    // Return an array with the lod edge of all bins
00491 
00492    Int_t bin;
00493    for (bin=1; bin<=fNbins; bin++) *(edge + bin-1) = GetBinLowEdge(bin);
00494 }
00495 
00496 //______________________________________________________________________________
00497 const char *TAxis::GetTimeFormatOnly() const
00498 {
00499    // Return *only* the time format from the string fTimeFormat
00500 
00501    static TString timeformat;
00502    Int_t idF = fTimeFormat.Index("%F");
00503    if (idF>=0) {
00504       timeformat = fTimeFormat(0,idF);
00505    } else {
00506       timeformat = fTimeFormat;
00507    }
00508    return timeformat.Data();
00509 }
00510 
00511 //______________________________________________________________________________
00512 const char *TAxis::GetTicks() const
00513 {
00514    // Return the ticks option (see SetTicks)
00515 
00516    if (TestBit(kTickPlus) && TestBit(kTickMinus)) return "+-";
00517    if (TestBit(kTickMinus)) return "-";
00518    return "+";
00519 }
00520 
00521 //______________________________________________________________________________
00522 void TAxis::LabelsOption(Option_t *option)
00523 {
00524    //  Set option(s) to draw axis with labels
00525    //  option = "a" sort by alphabetic order
00526    //         = ">" sort by decreasing values
00527    //         = "<" sort by increasing values
00528    //         = "h" draw labels horizonthal
00529    //         = "v" draw labels vertical
00530    //         = "u" draw labels up (end of label right adjusted)
00531    //         = "d" draw labels down (start of label left adjusted)
00532 
00533    if (!fLabels) {
00534       Warning("Sort","Cannot sort. No labels");
00535       return;
00536    }
00537    TH1 *h = (TH1*)GetParent();
00538    if (!h) {
00539       Error("Sort","Axis has no parent");
00540       return;
00541    }
00542 
00543    h->LabelsOption(option,GetName());
00544 }
00545 
00546 //___________________________________________________________________________
00547 Bool_t TAxis::GetRotateTitle() const
00548 {
00549    // Return kTRUE if kRotateTitle bit is set, kFALSE otherwise.
00550 
00551    return TestBit(kRotateTitle) ? kTRUE : kFALSE;
00552 }
00553 
00554 //______________________________________________________________________________
00555 void TAxis::ImportAttributes(const TAxis *axis)
00556 {
00557    // Copy axis attributes to this 
00558 
00559    SetTitle(axis->GetTitle());
00560    SetNdivisions(axis->GetNdivisions());
00561    SetAxisColor(axis->GetAxisColor());
00562    SetLabelColor(axis->GetLabelColor());
00563    SetLabelFont(axis->GetLabelFont());
00564    SetLabelOffset(axis->GetLabelOffset());
00565    SetLabelSize(axis->GetLabelSize());
00566    SetTickLength(axis->GetTickLength());
00567    SetTitleOffset(axis->GetTitleOffset());
00568    SetTitleSize(axis->GetTitleSize());
00569    SetTitleColor(axis->GetTitleColor());
00570    SetTitleFont(axis->GetTitleFont());
00571    SetBit(TAxis::kCenterTitle,   axis->TestBit(TAxis::kCenterTitle));
00572    SetBit(TAxis::kCenterLabels,  axis->TestBit(TAxis::kCenterLabels));
00573    SetBit(TAxis::kRotateTitle,   axis->TestBit(TAxis::kRotateTitle));
00574    SetBit(TAxis::kNoExponent,    axis->TestBit(TAxis::kNoExponent));
00575    SetBit(TAxis::kTickPlus,      axis->TestBit(TAxis::kTickPlus));
00576    SetBit(TAxis::kTickMinus,     axis->TestBit(TAxis::kTickMinus));
00577    SetBit(TAxis::kMoreLogLabels, axis->TestBit(TAxis::kMoreLogLabels));
00578    if (axis->GetDecimals())      SetBit(TAxis::kDecimals); //the bit is in TAxis::fAxis2   
00579    SetTimeFormat(axis->GetTimeFormat());
00580 }
00581 
00582 //___________________________________________________________________________
00583 void TAxis::RotateTitle(Bool_t rotate)
00584 {
00585    //    rotate title by 180 degrees
00586    //    by default the title is drawn right adjusted.
00587    //    if rotate is TRUE, the title is left adjusted at the end of the axis
00588    //    and rotated by 180 degrees
00589 
00590    if (rotate) SetBit(kRotateTitle);
00591    else        ResetBit(kRotateTitle);
00592 }
00593 
00594 //______________________________________________________________________________
00595 void TAxis::SaveAttributes(ostream &out, const char *name, const char *subname)
00596 {
00597     // Save axis attributes as C++ statement(s) on output stream out
00598 
00599    char quote = '"';
00600    if (strlen(GetTitle())) {
00601       out<<"   "<<name<<subname<<"->SetTitle("<<quote<<GetTitle()<<quote<<");"<<endl;
00602    }
00603    if (fTimeDisplay) {
00604       out<<"   "<<name<<subname<<"->SetTimeDisplay(1);"<<endl;
00605       out<<"   "<<name<<subname<<"->SetTimeFormat("<<quote<<GetTimeFormat()<<quote<<");"<<endl;
00606    }
00607    if (fLabels) {
00608       TIter next(fLabels);
00609       TObjString *obj;
00610       while ((obj=(TObjString*)next())) {
00611          out<<"   "<<name<<subname<<"->SetBinLabel("<<obj->GetUniqueID()<<","<<quote<<obj->GetName()<<quote<<");"<<endl;
00612       }
00613    }
00614 
00615    if (fFirst || fLast) {
00616       out<<"   "<<name<<subname<<"->SetRange("<<fFirst<<","<<fLast<<");"<<endl;
00617    }
00618 
00619    if (TestBit(kLabelsHori)) {
00620       out<<"   "<<name<<subname<<"->SetBit(TAxis::kLabelsHori);"<<endl;
00621    }
00622 
00623    if (TestBit(kLabelsVert)) {
00624       out<<"   "<<name<<subname<<"->SetBit(TAxis::kLabelsVert);"<<endl;
00625    }
00626 
00627    if (TestBit(kLabelsDown)) {
00628       out<<"   "<<name<<subname<<"->SetBit(TAxis::kLabelsDown);"<<endl;
00629    }
00630 
00631    if (TestBit(kLabelsUp)) {
00632       out<<"   "<<name<<subname<<"->SetBit(TAxis::kLabelsUp);"<<endl;
00633    }
00634 
00635    if (TestBit(kCenterTitle)) {
00636       out<<"   "<<name<<subname<<"->CenterTitle(true);"<<endl;
00637    }
00638 
00639    if (TestBit(kRotateTitle)) {
00640       out<<"   "<<name<<subname<<"->RotateTitle(true);"<<endl;
00641    }
00642 
00643    if (TestBit(kMoreLogLabels)) {
00644       out<<"   "<<name<<subname<<"->SetMoreLogLabels();"<<endl;
00645    }
00646 
00647    if (TestBit(kNoExponent)) {
00648       out<<"   "<<name<<subname<<"->SetNoExponent();"<<endl;
00649    }
00650 
00651    TAttAxis::SaveAttributes(out,name,subname);
00652 }
00653 
00654 //______________________________________________________________________________
00655 void TAxis::Set(Int_t nbins, Double_t xlow, Double_t xup)
00656 {
00657    // Initialize axis with fix bins
00658 
00659    fNbins   = nbins;
00660    fXmin    = xlow;
00661    fXmax    = xup;
00662    if (!fParent) SetDefaults();
00663 }
00664 
00665 //______________________________________________________________________________
00666 void TAxis::Set(Int_t nbins, const Float_t *xbins)
00667 {
00668    // Initialize axis with variable bins
00669 
00670    Int_t bin;
00671    fNbins  = nbins;
00672    fXbins.Set(fNbins+1);
00673    for (bin=0; bin<= fNbins; bin++)
00674       fXbins.fArray[bin] = xbins[bin];
00675    for (bin=1; bin<= fNbins; bin++)
00676       if (fXbins.fArray[bin] < fXbins.fArray[bin-1])
00677          Error("TAxis::Set", "bins must be in increasing order");
00678    fXmin      = fXbins.fArray[0];
00679    fXmax      = fXbins.fArray[fNbins];
00680    if (!fParent) SetDefaults();
00681 }
00682 
00683 //______________________________________________________________________________
00684 void TAxis::Set(Int_t nbins, const Double_t *xbins)
00685 {
00686    // Initialize axis with variable bins
00687 
00688    Int_t bin;
00689    fNbins  = nbins;
00690    fXbins.Set(fNbins+1);
00691    for (bin=0; bin<= fNbins; bin++)
00692       fXbins.fArray[bin] = xbins[bin];
00693    for (bin=1; bin<= fNbins; bin++)
00694       if (fXbins.fArray[bin] < fXbins.fArray[bin-1])
00695          Error("TAxis::Set", "bins must be in increasing order");
00696    fXmin      = fXbins.fArray[0];
00697    fXmax      = fXbins.fArray[fNbins];
00698    if (!fParent) SetDefaults();
00699 }
00700 
00701 //______________________________________________________________________________
00702 void TAxis::SetDefaults()
00703 {
00704    // Set axis default values (from TStyle)
00705    
00706    fFirst   = 0;
00707    fLast    = 0;
00708    fBits2   = 0;
00709    char name[2];
00710    strlcpy(name,GetName(),2);
00711    name[1] = 0;
00712    TAttAxis::ResetAttAxis(name);
00713    fTimeDisplay = 0;
00714    SetTimeFormat();
00715 }
00716 
00717 //______________________________________________________________________________
00718 Bool_t TAxis::GetDecimals() const
00719 {
00720    // Returns kTRUE if kDecimals bit is set, kFALSE otherwise.
00721    // see TAxis::SetDecimals
00722    
00723    if ((fBits2 & kDecimals) != 0) return kTRUE;
00724    else                           return kFALSE;
00725 }
00726 
00727 
00728 //______________________________________________________________________________
00729 void TAxis::SetDecimals(Bool_t dot)
00730 {
00731    // Set the Decimals flag
00732    // By default, blank characters are stripped, and then the
00733    // label is correctly aligned. The dot, if last character of the string, 
00734    // is also stripped, unless this option is specified.
00735    // One can disable the option by calling axis.SetDecimals(kTRUE).
00736    // The flag (in fBits2) is passed to the drawing function TGaxis::PaintAxis
00737 
00738    if (dot) fBits2 |=  kDecimals;
00739    else     fBits2 &= ~kDecimals;
00740 }
00741 
00742 //______________________________________________________________________________
00743 void TAxis::SetBinLabel(Int_t bin, const char *label)
00744 {
00745    // Set label for bin
00746 
00747    if (!fLabels) fLabels = new THashList(fNbins,3);
00748    if (bin <= 0 || bin > fNbins) {
00749       Error("SetBinLabel","Illegal bin number: %d",bin);
00750       return;
00751    }
00752 
00753    // Check whether this bin already has a label.
00754    TIter next(fLabels);
00755    TObjString *obj;
00756    while ((obj=(TObjString*)next())) {
00757       if ( obj->GetUniqueID()==(UInt_t)bin ) {
00758          // It does. Overwrite it.
00759          obj->SetString(label);
00760          return;
00761       }
00762    }
00763    // It doesn't. Add this new label.
00764    obj = new TObjString(label);
00765    fLabels->Add(obj);
00766    obj->SetUniqueID((UInt_t)bin);
00767 }
00768 
00769 //______________________________________________________________________________
00770 void TAxis::SetLimits(Double_t xmin, Double_t xmax)
00771 {
00772    //          Set the axis limits
00773 
00774    fXmin = xmin;
00775    fXmax = xmax;
00776 }
00777 
00778 //______________________________________________________________________________
00779 Bool_t TAxis::GetMoreLogLabels() const
00780 {
00781    // Return kTRUE if kMoreLogLabels bit is set, kFALSE otherwise.
00782 
00783    return TestBit(kMoreLogLabels) ? kTRUE : kFALSE;
00784 }
00785 
00786 //______________________________________________________________________________
00787 void TAxis::SetMoreLogLabels(Bool_t more)
00788 {
00789    // Set the kMoreLogLabels bit flag
00790    // When this option is selected more labels are drawn when in log scale
00791    // and there is a small number of decades  (<3).
00792    // The flag (in fBits) is passed to the drawing function TGaxis::PaintAxis
00793 
00794    if (more) SetBit(kMoreLogLabels);
00795    else      ResetBit(kMoreLogLabels);
00796 }
00797 
00798 //______________________________________________________________________________
00799 Bool_t TAxis::GetNoExponent() const
00800 {
00801    // Returns kTRUE if kNoExponent bit is set, kFALSE otherwise.
00802    // see TAxis::SetNoExponent
00803 
00804    return TestBit(kNoExponent) ? kTRUE : kFALSE;
00805 }
00806 
00807 //______________________________________________________________________________
00808 void TAxis::SetNoExponent(Bool_t noExponent)
00809 {
00810    // Set the NoExponent flag
00811    // By default, an exponent of the form 10^N is used when the label values
00812    // are either all very small or very large.
00813    // One can disable the exponent by calling axis.SetNoExponent(kTRUE).
00814    // The flag (in fBits) is passed to the drawing function TGaxis::PaintAxis
00815 
00816    if (noExponent) SetBit(kNoExponent);
00817    else            ResetBit(kNoExponent);
00818 }
00819 
00820 //______________________________________________________________________________
00821 void TAxis::SetRange(Int_t first, Int_t last)
00822 {
00823    //  Set the viewing range for the axis from bin first to last
00824    //  To set a range using the axis coordinates, use TAxis::SetRangeUser.
00825    //  if first<=1 and last>=Nbins or if last < first the range is reset by removing the  
00826    //  bit TAxis::kAxisRange. In this case the functions TAxis::GetFirst() and TAxis::GetLast() 
00827    //  will return 1 and Nbins. 
00828    //  NOTE: If the bit has been set manually by the user in case of no range defined
00829    //         GetFirst() and GetLast() will return 0. 
00830 
00831    if (last <= 0) last = fNbins;
00832    if (last > fNbins) last = fNbins;
00833    if (last  < first) { first = 1; last = fNbins; }
00834    if (first < 1)     first = 1;
00835    if (first == 1 && last == fNbins) {
00836       SetBit(kAxisRange,0);
00837       fFirst = 0;
00838       fLast  = 0;
00839    } else {
00840       SetBit(kAxisRange,1);
00841       fFirst = first;
00842       fLast  = last;
00843    }
00844 }
00845 
00846 
00847 //______________________________________________________________________________
00848 void TAxis::SetRangeUser(Double_t ufirst, Double_t ulast)
00849 {
00850    //  Set the viewing range for the axis from ufirst to ulast (in user coordinates)
00851    //  To set a range using the axis bin numbers, use TAxis::SetRange.
00852 
00853    if (!strstr(GetName(),"xaxis")) {
00854       TH1 *hobj = (TH1*)GetParent();
00855       if (hobj &&
00856           ((hobj->GetDimension() == 2 && strstr(GetName(),"zaxis")) 
00857            || (hobj->GetDimension() == 1 && strstr(GetName(),"yaxis")))) {
00858          hobj->SetMinimum(ufirst);
00859          hobj->SetMaximum(ulast);
00860          return;
00861       }
00862    }
00863    SetRange(FindFixBin(ufirst),FindFixBin(ulast));
00864 }
00865 
00866 //______________________________________________________________________________
00867 void TAxis::SetTicks(Option_t *option)
00868 {
00869    //  set ticks orientation
00870    //  option = "+"  ticks drawn on the "positive side" (default)
00871    //  option = "-"  ticks drawn on the "negative side"
00872    //  option = "+-" ticks drawn on both sides
00873 
00874    ResetBit(kTickPlus);
00875    ResetBit(kTickMinus);
00876    if (strchr(option,'+')) SetBit(kTickPlus);
00877    if (strchr(option,'-')) SetBit(kTickMinus);
00878 }
00879 
00880 //______________________________________________________________________________
00881 void TAxis::SetTimeFormat(const char *tformat)
00882 {
00883    // Change the format used for time plotting
00884    //
00885    //  The format string for date and time use the same options as the one used
00886    //  in the standard strftime C function, i.e. :
00887    //    for date :
00888    //      %a abbreviated weekday name
00889    //      %b abbreviated month name
00890    //      %d day of the month (01-31)
00891    //      %m month (01-12)
00892    //      %y year without century
00893    //
00894    //    for time :
00895    //      %H hour (24-hour clock)
00896    //      %I hour (12-hour clock)
00897    //      %p local equivalent of AM or PM
00898    //      %M minute (00-59)
00899    //      %S seconds (00-61)
00900    //      %% %
00901    //
00902    //    This function allows also to define the time offset. It is done via %F
00903    //    which should be appended at the end of the format string. The time
00904    //    offset has the following format: 'yyyy-mm-dd hh:mm:ss'
00905    //    Example:
00906    //
00907    //          h = new TH1F("Test","h",3000,0.,200000.);
00908    //          h->GetXaxis()->SetTimeDisplay(1);
00909    //          h->GetXaxis()->SetTimeFormat("%d\/%m\/%y%F2000-02-28 13:00:01");
00910    //
00911    //    This defines the time format being "dd/mm/yy" and the time offset as the
00912    //    February 28th 2003 at 13:00:01
00913    //
00914    //    If %F is not specified, the time offset used will be the one defined by:
00915    //    gStyle->SetTimeOffset. For example like that:
00916    //
00917    //          TDatime da(2003,02,28,12,00,00);
00918    //          gStyle->SetTimeOffset(da.Convert());
00919 
00920    TString timeformat = tformat;
00921 
00922    if (timeformat.Index("%F")>=0 || timeformat.IsNull()) {
00923       fTimeFormat = timeformat;
00924       return;
00925    }
00926 
00927    Int_t idF = fTimeFormat.Index("%F");
00928    if (idF>=0) {
00929       Int_t lnF = fTimeFormat.Length();
00930       TString stringtimeoffset = fTimeFormat(idF,lnF);
00931       fTimeFormat = tformat;
00932       fTimeFormat.Append(stringtimeoffset);
00933    } else {
00934       fTimeFormat = tformat;
00935       SetTimeOffset(gStyle->GetTimeOffset());
00936    }
00937 }
00938 
00939 
00940 //______________________________________________________________________________
00941 void TAxis::SetTimeOffset(Double_t toffset, Option_t *option)
00942 {
00943    // Change the time offset
00944    // If option = "gmt" the time offset is treated as a GMT time.
00945 
00946    TString opt = option;
00947    opt.ToLower();
00948 
00949    Bool_t gmt = kFALSE;
00950    if (opt.Contains("gmt")) gmt = kTRUE;
00951 
00952    char tmp[20];
00953    time_t timeoff;
00954    struct tm* utctis;
00955    Int_t idF = fTimeFormat.Index("%F");
00956    if (idF>=0) fTimeFormat.Remove(idF);
00957    fTimeFormat.Append("%F");
00958 
00959    timeoff = (time_t)((Long_t)(toffset));
00960    utctis = gmtime(&timeoff);
00961 
00962    strftime(tmp,20,"%Y-%m-%d %H:%M:%S",utctis);
00963    fTimeFormat.Append(tmp);
00964 
00965    // append the decimal part of the time offset
00966    Double_t ds = toffset-(Int_t)toffset;
00967    if(ds!= 0) {
00968       snprintf(tmp,20,"s%g",ds);
00969       fTimeFormat.Append(tmp);
00970    }
00971 
00972    // If the time is GMT, stamp fTimeFormat
00973    if (gmt) fTimeFormat.Append(" GMT");
00974 }
00975 
00976 
00977 //______________________________________________________________________________
00978 void TAxis::Streamer(TBuffer &R__b)
00979 {
00980    // Stream an object of class TAxis.
00981 
00982    if (R__b.IsReading()) {
00983       UInt_t R__s, R__c;
00984       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
00985       if (R__v > 5) {
00986          R__b.ReadClassBuffer(TAxis::Class(), this, R__v, R__s, R__c);
00987          return;
00988       }
00989       //====process old versions before automatic schema evolution
00990       TNamed::Streamer(R__b);
00991       TAttAxis::Streamer(R__b);
00992       R__b >> fNbins;
00993       if (R__v < 5) {
00994          Float_t xmin,xmax;
00995          R__b >> xmin; fXmin = xmin;
00996          R__b >> xmax; fXmax = xmax;
00997          Float_t *xbins = 0;
00998          Int_t n = R__b.ReadArray(xbins);
00999          fXbins.Set(n);
01000          for (Int_t i=0;i<n;i++) fXbins.fArray[i] = xbins[i];
01001          delete [] xbins;
01002       } else {
01003          R__b >> fXmin;
01004          R__b >> fXmax;
01005          fXbins.Streamer(R__b);
01006       }
01007       if (R__v > 2) {
01008          R__b >> fFirst;
01009          R__b >> fLast;
01010           // following lines required to repair for a bug in Root version 1.03
01011          if (fFirst < 0 || fFirst > fNbins) fFirst = 0;
01012          if (fLast  < 0 || fLast  > fNbins) fLast  = 0;
01013          if (fLast  < fFirst) { fFirst = 0; fLast = 0;}
01014          if (fFirst ==0 && fLast == 0) SetBit(kAxisRange,0);
01015       }
01016       if (R__v > 3) {
01017          R__b >> fTimeDisplay;
01018          fTimeFormat.Streamer(R__b);
01019       } else {
01020          SetTimeFormat();
01021       }
01022       R__b.CheckByteCount(R__s, R__c, TAxis::IsA());
01023       //====end of old versions
01024 
01025    } else {
01026       R__b.WriteClassBuffer(TAxis::Class(),this);
01027    }
01028 }
01029 
01030 //______________________________________________________________________________
01031 void TAxis::UnZoom()
01032 {
01033    // Reset first & last bin to the full range
01034 
01035 
01036    gPad->SetView();
01037 
01038    //unzoom object owning this axis
01039    SetRange(0,0);
01040    TH1 *hobj1 = (TH1*)GetParent();
01041    if (!strstr(GetName(),"xaxis")) {
01042       if (!hobj1) return;
01043       if (hobj1->GetDimension() == 2) {
01044          if (strstr(GetName(),"zaxis")) {
01045             hobj1->SetMinimum();
01046             hobj1->SetMaximum();
01047             hobj1->ResetBit(TH1::kIsZoomed);
01048          }
01049          return;
01050       }
01051       if (strcmp(hobj1->GetName(),"hframe") == 0 ) {
01052          hobj1->SetMinimum(fXmin);
01053          hobj1->SetMaximum(fXmax);
01054       } else {
01055          hobj1->SetMinimum();
01056          hobj1->SetMaximum();
01057          hobj1->ResetBit(TH1::kIsZoomed);
01058       }
01059    }
01060    //must unzoom all histograms in the pad
01061    TIter next(gPad->GetListOfPrimitives());
01062    TObject *obj;
01063    while ((obj= next())) {
01064       if (!obj->InheritsFrom(TH1::Class())) continue;
01065       TH1 *hobj = (TH1*)obj;
01066       if (hobj == hobj1) continue;
01067       if (!strstr(GetName(),"xaxis")) {
01068          if (hobj->GetDimension() == 2) {
01069             if (strstr(GetName(),"zaxis")) {
01070                hobj->SetMinimum();
01071                hobj->SetMaximum();
01072                hobj->ResetBit(TH1::kIsZoomed);
01073             }
01074             return;
01075          }
01076          if (strcmp(hobj->GetName(),"hframe") == 0 ) {
01077             hobj->SetMinimum(fXmin);
01078             hobj->SetMaximum(fXmax);
01079          } else {
01080             hobj->SetMinimum();
01081             hobj->SetMaximum();
01082             hobj->ResetBit(TH1::kIsZoomed);
01083          }
01084       } else {
01085          hobj->GetXaxis()->SetRange(0,0);
01086       }
01087    }
01088 }
01089 
01090 //______________________________________________________________________________
01091 void TAxis::ZoomOut(Double_t factor, Double_t offset)
01092 {
01093    // Zoom out by a factor of 'factor' (default =2)
01094    //   uses previous zoom factor by default
01095    // Keep center defined by 'offset' fixed
01096    //   ie. -1 at left of current range, 0 in center, +1 at right
01097    
01098    if (factor <= 0) factor = 2;
01099    Double_t center = (GetFirst()*(1-offset) + GetLast()*(1+offset))/2.;
01100    Int_t first = int(TMath::Floor(center+(GetFirst()-center)*factor + 0.4999999));
01101    Int_t last  = int(TMath::Floor(center+(GetLast() -center)*factor + 0.5000001));
01102    if (first==GetFirst() && last==GetLast()) { first--; last++; }
01103    SetRange(first,last);
01104 }

Generated on Tue Jul 5 14:24:15 2011 for ROOT_528-00b_version by  doxygen 1.5.1