RooPlot.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooPlot.cxx 36230 2010-10-09 20:21:02Z wouter $
00005  * Authors:                                                                  *
00006  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
00007  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
00008  *                                                                           *
00009  * Copyright (c) 2000-2005, Regents of the University of California          *
00010  *                          and Stanford University. All rights reserved.    *
00011  *                                                                           *
00012  * Redistribution and use in source and binary forms,                        *
00013  * with or without modification, are permitted according to the terms        *
00014  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00015  *****************************************************************************/
00016 
00017 //////////////////////////////////////////////////////////////////////////////
00018 //
00019 // BEGIN_HTML
00020 // A RooPlot is a plot frame and a container for graphics objects
00021 // within that frame. As a frame, it provides the TH1-style public interface
00022 // for settting plot ranges, configuring axes, etc. As a container, it
00023 // holds an arbitrary set of objects that might be histograms of data,
00024 // curves representing a fit model, or text labels. Use the Draw()
00025 // method to draw a frame and the objects it contains. Use the various
00026 // add...() methods to add objects to be drawn.  In general, the
00027 // add...() methods create a private copy of the object you pass them
00028 // and return a pointer to this copy. The caller owns the input object
00029 // and this class owns the returned object.
00030 // <p>
00031 // All RooAbsReal and RooAbsData derived classes implement plotOn()
00032 // functions that facilitate to plot themselves on a given RooPlot, e.g.
00033 // <pre>
00034 // RooPlot *frame = x.frame() ;
00035 // data.plotOn(frame) ;
00036 // pdf.plotOn(frame) ;
00037 // </pre>
00038 // These high level functions also take care of any projections
00039 // or other mappings that need to be made to plot a multi-dimensional
00040 // object onto a one-dimensional plot.
00041 // END_HTML
00042 //
00043 
00044 
00045 #include "RooFit.h"
00046 
00047 #include "TClass.h"
00048 #include "TH1D.h"
00049 #include "TBrowser.h"
00050 #include "TPad.h"
00051 
00052 #include "RooPlot.h"
00053 #include "RooAbsReal.h"
00054 #include "RooAbsRealLValue.h"
00055 #include "RooPlotable.h"
00056 #include "RooArgSet.h"
00057 #include "RooCurve.h"
00058 #include "RooHist.h"
00059 #include "RooMsgService.h"
00060 
00061 #include "TAttLine.h"
00062 #include "TAttFill.h"
00063 #include "TAttMarker.h"
00064 #include "TAttText.h"
00065 #include "TDirectory.h"
00066 #include "TDirectoryFile.h"
00067 
00068 #include "Riostream.h"
00069 #include <string.h>
00070 #include <assert.h>
00071 
00072 ClassImp(RooPlot)
00073 ;
00074 
00075 
00076 //_____________________________________________________________________________
00077 RooPlot::RooPlot() : _hist(0), _plotVarClone(0), _plotVarSet(0), _normVars(0), _normObj(0), _dir(0)
00078 {
00079   // Default constructor
00080   // coverity[UNINIT_CTOR]
00081 
00082   _iterator= _items.MakeIterator() ;
00083 
00084   if (gDirectory) {
00085     _dir = gDirectory ;
00086     gDirectory->Append(this) ;
00087   }
00088 }
00089 
00090 
00091 //_____________________________________________________________________________
00092 RooPlot::RooPlot(Double_t xmin, Double_t xmax) :
00093   _hist(0), _items(), _plotVarClone(0), _plotVarSet(0), _normObj(0),
00094   _defYmin(1e-5), _defYmax(1), _dir(0)
00095 {
00096   // Constructor of RooPlot with range [xmin,xmax]
00097 
00098   TH1::AddDirectory(kFALSE) ;
00099   _hist = new TH1D(histName(),"A RooPlot",100,xmin,xmax) ;
00100   TH1::AddDirectory(kTRUE) ;
00101 
00102   // Create an empty frame with the specified x-axis limits.
00103   initialize();
00104 
00105 }
00106 
00107 
00108 
00109 //_____________________________________________________________________________
00110 RooPlot::RooPlot(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax) :
00111   _hist(0), _items(), _plotVarClone(0),
00112   _plotVarSet(0), _normObj(0), _defYmin(1e-5), _defYmax(0), _dir(0)
00113 {
00114   // Construct of a two-dimensioanl RooPlot with ranges [xmin,xmax] x [ymin,ymax]
00115 
00116   TH1::AddDirectory(kFALSE) ;
00117   _hist = new TH1D(histName(),"A RooPlot",100,xmin,xmax) ;
00118   TH1::AddDirectory(kFALSE) ;
00119 
00120   SetMinimum(ymin);
00121   SetMaximum(ymax);
00122   initialize();
00123 }
00124 
00125 
00126 //_____________________________________________________________________________
00127 RooPlot::RooPlot(const RooAbsRealLValue &var1, const RooAbsRealLValue &var2) :
00128   _hist(0), _items(),
00129   _plotVarClone(0), _plotVarSet(0), _normObj(0), _defYmin(1e-5), _defYmax(0), _dir(0)
00130 {
00131   // Construct a two-dimensional RooPlot with ranges and properties taken
00132   // from variables var1 and var2
00133 
00134   TH1::AddDirectory(kFALSE) ;
00135   _hist = new TH1D(histName(),"A RooPlot",100,var1.getMin(),var1.getMax()) ;
00136   TH1::AddDirectory(kTRUE) ;
00137 
00138   if(!var1.hasMin() || !var1.hasMax()) {
00139     coutE(InputArguments) << "RooPlot::RooPlot: cannot create plot for variable without finite limits: "
00140          << var1.GetName() << endl;
00141     return;
00142   }
00143   if(!var2.hasMin() || !var2.hasMax()) {
00144     coutE(InputArguments) << "RooPlot::RooPlot: cannot create plot for variable without finite limits: "
00145          << var1.GetName() << endl;
00146     return;
00147   }
00148   SetMinimum(var2.getMin());
00149   SetMaximum(var2.getMax());
00150   SetXTitle(var1.getTitle(kTRUE));
00151   SetYTitle(var2.getTitle(kTRUE));
00152   initialize();
00153 }
00154 
00155 
00156 //_____________________________________________________________________________
00157 RooPlot::RooPlot(const RooAbsRealLValue &var1, const RooAbsRealLValue &var2,
00158                  Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax) :
00159   _hist(0), _items(), _plotVarClone(0),
00160   _plotVarSet(0), _normObj(0), _defYmin(1e-5), _defYmax(0), _dir(0)
00161 {
00162   // Construct a two-dimensional RooPlot with ranges and properties taken
00163   // from variables var1 and var2 but with an overriding range definition
00164   // of [xmin,xmax] x [ymin,ymax]
00165 
00166   TH1::AddDirectory(kFALSE) ;
00167   _hist = new TH1D(histName(),"A RooPlot",100,xmin,xmax) ;
00168   TH1::AddDirectory(kTRUE) ;
00169 
00170   SetMinimum(ymin);
00171   SetMaximum(ymax);
00172   SetXTitle(var1.getTitle(kTRUE));
00173   SetYTitle(var2.getTitle(kTRUE));
00174   initialize();
00175 }
00176 
00177 
00178 //_____________________________________________________________________________
00179 RooPlot::RooPlot(const char* name, const char* title, const RooAbsRealLValue &var, Double_t xmin, Double_t xmax, Int_t nbins) :
00180   _hist(0), _items(),
00181   _plotVarClone(0), _plotVarSet(0), _normObj(0), _defYmin(1e-5), _defYmax(1), _dir(0)
00182 {
00183   // Create an 1-dimensional with all properties taken from 'var', but
00184   // with an explicit range [xmin,xmax] and a default binning of 'nbins'
00185 
00186   TH1::AddDirectory(kFALSE) ;
00187   _hist = new TH1D(name,title,nbins,xmin,xmax) ;
00188   TH1::AddDirectory(kTRUE) ;
00189 
00190   // plotVar can be a composite in case of a RooDataSet::plot, need deepClone
00191   _plotVarSet = (RooArgSet*) RooArgSet(var).snapshot() ;
00192   _plotVarClone= (RooAbsRealLValue*)_plotVarSet->find(var.GetName()) ;
00193 
00194   TString xtitle= var.getTitle(kTRUE);
00195   SetXTitle(xtitle.Data());
00196 
00197   initialize();
00198 
00199   _normBinWidth = (xmax-xmin)/nbins ;
00200 }
00201 
00202 
00203 //_____________________________________________________________________________
00204 RooPlot::RooPlot(const RooAbsRealLValue &var, Double_t xmin, Double_t xmax, Int_t nbins) :
00205   _hist(0), _items(),
00206   _plotVarClone(0), _plotVarSet(0), _normObj(0), _defYmin(1e-5), _defYmax(1), _dir(0)
00207 {
00208   // Create an 1-dimensional with all properties taken from 'var', but
00209   // with an explicit range [xmin,xmax] and a default binning of 'nbins'
00210 
00211   TH1::AddDirectory(kFALSE) ;
00212   _hist = new TH1D(histName(),"RooPlot",nbins,xmin,xmax) ;
00213   TH1::AddDirectory(kTRUE) ;
00214 
00215   // plotVar can be a composite in case of a RooDataSet::plot, need deepClone
00216   _plotVarSet = (RooArgSet*) RooArgSet(var).snapshot() ;
00217   _plotVarClone= (RooAbsRealLValue*)_plotVarSet->find(var.GetName()) ;
00218 
00219   TString xtitle= var.getTitle(kTRUE);
00220   SetXTitle(xtitle.Data());
00221 
00222   TString title("A RooPlot of \"");
00223   title.Append(var.getTitle());
00224   title.Append("\"");
00225   SetTitle(title.Data());
00226   initialize();
00227 
00228   _normBinWidth = (xmax-xmin)/nbins ;
00229 }
00230 
00231 
00232 
00233 //_____________________________________________________________________________
00234 RooPlot* RooPlot::emptyClone(const char* name)
00235 {
00236   // Return empty clone of current RooPlot
00237 
00238   RooPlot* clone = new RooPlot(*_plotVarClone,_hist->GetXaxis()->GetXmin(),_hist->GetXaxis()->GetXmax(),_hist->GetNbinsX()) ;
00239   clone->SetName(name) ;
00240   return clone ;
00241 }
00242 
00243 
00244 //_____________________________________________________________________________
00245 void RooPlot::initialize()
00246 {
00247   // Perform initialization that is common to all constructors.
00248 
00249   SetName(histName()) ;
00250 
00251   if (gDirectory) {
00252     _dir = gDirectory ;
00253     gDirectory->Append(this) ;
00254   }
00255 
00256   // We do not have useful stats of our own
00257   _hist->SetStats(kFALSE);
00258   // Default vertical padding of our enclosed objects
00259   setPadFactor(0.05);
00260   // We don't know our normalization yet
00261   _normNumEvts= 0;
00262   _normBinWidth = 0;
00263   _normVars= 0;
00264   // Create an iterator over our enclosed objects
00265   _iterator= _items.MakeIterator();
00266   assert(0 != _iterator);
00267 }
00268 
00269 
00270 //_____________________________________________________________________________
00271 TString RooPlot::histName() const
00272 {
00273   // Construct automatic name of internal TH1
00274   if (_plotVarClone) {
00275     return TString(Form("frame_%s_%lx",_plotVarClone->GetName(),(ULong_t)this)) ;
00276   } else {
00277     return TString(Form("frame_%lx",(ULong_t)this)) ;
00278   }
00279 }
00280 
00281 
00282 //_____________________________________________________________________________
00283 RooPlot::~RooPlot()
00284 {
00285   // Destructor
00286 
00287   // Delete the items in our container and our iterator.
00288   if (_dir) {
00289     if (!_dir->TestBit(TDirectoryFile::kCloseDirectory)) {
00290       _dir->GetList()->RecursiveRemove(this) ;
00291     }
00292   }
00293 
00294   _items.Delete();
00295   delete _iterator;
00296   if(_plotVarSet) delete _plotVarSet;
00297   if(_normVars) delete _normVars;
00298   delete _hist ;
00299 
00300 }
00301 
00302 
00303 //_____________________________________________________________________________
00304 void RooPlot::updateNormVars(const RooArgSet &vars)
00305 {
00306   // Install the given set of observables are reference normalization
00307   // variables for this frame. These observables are e.g. later used
00308   // to automatically project out observables when plotting functions
00309   // on this frame. This function is only effective when called the
00310   // first time on a frame
00311 
00312   if(0 == _normVars) _normVars= (RooArgSet*) vars.snapshot(kTRUE);
00313 }
00314 
00315 
00316 //_____________________________________________________________________________
00317 Stat_t RooPlot::GetBinContent(Int_t /*i*/) const {
00318   // A plot object is a frame without any bin contents of its own so this
00319   // method always returns zero.
00320   return 0;
00321 }
00322 
00323 
00324 //_____________________________________________________________________________
00325 Stat_t RooPlot::GetBinContent(Int_t, Int_t) const
00326 {
00327   // A plot object is a frame without any bin contents of its own so this
00328   // method always returns zero.
00329   return 0;
00330 }
00331 
00332 
00333 //_____________________________________________________________________________
00334 Stat_t RooPlot::GetBinContent(Int_t, Int_t, Int_t) const
00335 {
00336   // A plot object is a frame without any bin contents of its own so this
00337   // method always returns zero.
00338   return 0;
00339 }
00340 
00341 
00342 
00343 //_____________________________________________________________________________
00344 void RooPlot::addObject(TObject *obj, Option_t *drawOptions, Bool_t invisible)
00345 {
00346   // Add a generic object to this plot. The specified options will be
00347   // used to Draw() this object later. The caller transfers ownership
00348   // of the object with this call, and the object will be deleted
00349   // when its containing plot object is destroyed.
00350 
00351   if(0 == obj) {
00352     coutE(InputArguments) << fName << "::addObject: called with a null pointer" << endl;
00353     return;
00354   }
00355   DrawOpt opt(drawOptions) ;
00356   opt.invisible = invisible ;
00357   _items.Add(obj,opt.rawOpt());
00358 }
00359 
00360 
00361 //_____________________________________________________________________________
00362 void RooPlot::addTH1(TH1 *hist, Option_t *drawOptions, Bool_t invisible)
00363 {
00364   // Add a TH1 histogram object to this plot. The specified options
00365   // will be used to Draw() this object later. "SAME" will be added to
00366   // the options if they are not already present. The caller transfers
00367   // ownership of the object with this call, and the object will be
00368   // deleted when its containing plot object is destroyed.
00369 
00370   if(0 == hist) {
00371     coutE(InputArguments) << fName << "::addTH1: called with a null pointer" << endl;
00372     return;
00373   }
00374   // check that this histogram is really 1D
00375   if(1 != hist->GetDimension()) {
00376     coutE(InputArguments) << fName << "::addTH1: cannot plot histogram with "
00377          << hist->GetDimension() << " dimensions" << endl;
00378     return;
00379   }
00380 
00381   // add option "SAME" if necessary
00382   TString options(drawOptions);
00383   options.ToUpper();
00384   if(!options.Contains("SAME")) options.Append("SAME");
00385 
00386   // update our y-axis label and limits
00387   updateYAxis(hist->GetMinimum(),hist->GetMaximum(),hist->GetYaxis()->GetTitle());
00388 
00389   // use this histogram's normalization if necessary
00390   updateFitRangeNorm(hist);
00391 
00392   // add the histogram to our list
00393   addObject(hist,options.Data(),invisible);
00394 }
00395 
00396 
00397 //_____________________________________________________________________________
00398 void RooPlot::addPlotable(RooPlotable *plotable, Option_t *drawOptions, Bool_t invisible, Bool_t refreshNorm)
00399 {
00400   // Add the specified plotable object to our plot. Increase our y-axis
00401   // limits to fit this object if necessary. The default lower-limit
00402   // is zero unless we are plotting an object that takes on negative values.
00403   // This call transfers ownership of the plotable object to this class.
00404   // The plotable object will be deleted when this plot object is deleted.
00405 
00406   // update our y-axis label and limits
00407   updateYAxis(plotable->getYAxisMin(),plotable->getYAxisMax(),plotable->getYAxisLabel());
00408 
00409   // use this object's normalization if necessary
00410   updateFitRangeNorm(plotable,refreshNorm) ;
00411 
00412   // add this element to our list and remember its drawing option
00413   TObject *obj= plotable->crossCast();
00414   if(0 == obj) {
00415     coutE(InputArguments) << fName << "::add: cross-cast to TObject failed (nothing added)" << endl;
00416   }
00417   else {
00418     DrawOpt opt(drawOptions) ;
00419     opt.invisible = invisible ;
00420     _items.Add(obj,opt.rawOpt());
00421   }
00422 }
00423 
00424 
00425 //_____________________________________________________________________________
00426 void RooPlot::updateFitRangeNorm(const TH1* hist)
00427 {
00428   // Update our plot normalization over our plot variable's fit range,
00429   // which will be determined by the first suitable object added to our plot.
00430 
00431   const TAxis* xa = ((TH1*)hist)->GetXaxis() ;
00432   _normBinWidth = (xa->GetXmax()-xa->GetXmin())/hist->GetNbinsX() ;
00433   _normNumEvts = hist->GetEntries()/_normBinWidth ;
00434 }
00435 
00436 
00437 //_____________________________________________________________________________
00438 void RooPlot::updateFitRangeNorm(const RooPlotable* rp, Bool_t refreshNorm)
00439 {
00440   // Update our plot normalization over our plot variable's fit range,
00441   // which will be determined by the first suitable object added to our plot.
00442 
00443   if (_normNumEvts != 0) {
00444 
00445     // If refresh feature is disabled stop here
00446     if (!refreshNorm) return ;
00447 
00448     Double_t corFac(1.0) ;
00449     if (dynamic_cast<const RooHist*>(rp)) corFac = _normBinWidth/rp->getFitRangeBinW() ;
00450 
00451 
00452     if (fabs(rp->getFitRangeNEvt()/corFac-_normNumEvts)>1e-6) {
00453       coutI(Plotting) << "RooPlot::updateFitRangeNorm: New event count of " << rp->getFitRangeNEvt()/corFac
00454                       << " will supercede previous event count of " << _normNumEvts << " for normalization of PDF projections" << endl ;
00455     }
00456 
00457     // Nominal bin width (i.e event density) is already locked in by previously drawn histogram
00458     // scale this histogram to match that density
00459     _normNumEvts = rp->getFitRangeNEvt()/corFac ;
00460     _normObj = rp ;
00461     // cout << "correction factor = " << _normBinWidth << "/" << rp->getFitRangeBinW() << endl ;
00462     // cout << "updating numevts to " << _normNumEvts << endl ;
00463 
00464   } else {
00465 
00466     _normObj = rp ;
00467     _normNumEvts = rp->getFitRangeNEvt() ;
00468     if (rp->getFitRangeBinW()) {
00469       _normBinWidth = rp->getFitRangeBinW() ;
00470     }
00471 
00472     // cout << "updating numevts to " << _normNumEvts << endl ;
00473   }
00474 
00475 }
00476 
00477 
00478 
00479 //_____________________________________________________________________________
00480 void RooPlot::updateYAxis(Double_t ymin, Double_t ymax, const char *label)
00481 {
00482   // Update our y-axis limits to accomodate an object whose spread
00483   // in y is (ymin,ymax). Use the specified y-axis label if we don't
00484   // have one assigned already.
00485 
00486   // force an implicit lower limit of zero if appropriate
00487   if(GetMinimum() == 0 && ymin > 0) ymin= 0;
00488 
00489   // calculate padded values
00490   Double_t ypad= getPadFactor()*(ymax-ymin);
00491   ymax+= ypad;
00492   if(ymin < 0) ymin-= ypad;
00493 
00494   // update our limits if necessary
00495   if(GetMaximum() < ymax) {
00496     _defYmax = ymax ;
00497     SetMaximum(ymax);
00498   }
00499   if(GetMinimum() > ymin) {
00500     _defYmin = ymin ;
00501     SetMinimum(ymin);
00502   }
00503 
00504   // use the specified y-axis label if we don't have one already
00505   if(0 == strlen(_hist->GetYaxis()->GetTitle())) _hist->SetYTitle(label);
00506 }
00507 
00508 
00509 //_____________________________________________________________________________
00510 void RooPlot::Draw(Option_t *options)
00511 {
00512   // Draw this plot and all of the elements it contains. The specified options
00513   // only apply to the drawing of our frame. The options specified in our add...()
00514   // methods will be used to draw each object we contain.
00515 
00516   _hist->Draw(options);
00517   _iterator->Reset();
00518   TObject *obj = 0;
00519   while((obj= _iterator->Next())) {
00520     DrawOpt opt(_iterator->GetOption()) ;
00521     if (!opt.invisible) {
00522       obj->Draw(opt.drawOptions);
00523     }
00524   }
00525 
00526   _hist->Draw("AXISSAME");
00527 }
00528 
00529 
00530 
00531 //_____________________________________________________________________________
00532 void RooPlot::printName(ostream& os) const
00533 {
00534   // Print frame name
00535   os << GetName() ;
00536 }
00537 
00538 
00539 //_____________________________________________________________________________
00540 void RooPlot::printTitle(ostream& os) const
00541 {
00542   // Print frame title
00543   os << GetTitle() ;
00544 }
00545 
00546 
00547 //_____________________________________________________________________________
00548 void RooPlot::printClassName(ostream& os) const
00549 {
00550   // Print frame class name
00551   os << IsA()->GetName() ;
00552 }
00553 
00554 
00555 
00556 //_____________________________________________________________________________
00557 void RooPlot::printArgs(ostream& os) const
00558 {
00559   if (_plotVarClone) {
00560     os << "[" ;
00561     _plotVarClone->printStream(os,kName,kInline) ;
00562     os << "]" ;
00563   }
00564 }
00565 
00566 
00567 
00568 //_____________________________________________________________________________
00569 void RooPlot::printValue(ostream& os) const
00570 {
00571   // Print frame arguments
00572   os << "(" ;
00573   _iterator->Reset();
00574   TObject *obj = 0;
00575   Bool_t first(kTRUE) ;
00576   while((obj= _iterator->Next())) {
00577     if (first) {
00578       first=kFALSE ;
00579     } else {
00580       os << "," ;
00581     }
00582     if(obj->IsA()->InheritsFrom(RooPrintable::Class())) {
00583       RooPrintable* po = dynamic_cast<RooPrintable*>(obj) ;
00584       // coverity[FORWARD_NULL]
00585       po->printStream(os,kClassName|kName,kInline) ;
00586     }
00587     // is it a TNamed subclass?
00588     else {
00589       os << obj->ClassName() << "::" << obj->GetName() ;
00590     }
00591   }
00592   os << ")" ;
00593 }
00594 
00595 
00596 //_____________________________________________________________________________
00597 void RooPlot::printMultiline(ostream& os, Int_t /*content*/, Bool_t verbose, TString indent) const
00598 {
00599   // Frame detailed printing
00600 
00601   TString deeper(indent);
00602   deeper.Append("    ");
00603   if(0 != _plotVarClone) {
00604     os << indent << "RooPlot " << GetName() << " (" << GetTitle() << ") plots variable ";
00605     _plotVarClone->printStream(os,kName|kTitle,kSingleLine,"");
00606   }
00607   else {
00608     os << indent << "RooPlot " << GetName() << " (" << GetTitle() << ") has no associated plot variable" << endl ;
00609   }
00610   os << indent << "  Plot frame contains " << _items.GetSize() << " object(s):" << endl;
00611 
00612   if(verbose) {
00613     _iterator->Reset();
00614     TObject *obj = 0;
00615     Int_t i=0 ;
00616     while((obj= _iterator->Next())) {
00617       os << deeper << "[" << i++ << "] (Options=\"" << _iterator->GetOption() << "\") ";
00618       // Is this a printable object?
00619       if(obj->IsA()->InheritsFrom(RooPrintable::Class())) {
00620         RooPrintable* po = dynamic_cast<RooPrintable*>(obj) ;
00621         if (po) {
00622           po->printStream(os,kName|kClassName|kArgs|kExtras,kSingleLine) ;
00623         }
00624       }
00625       // is it a TNamed subclass?
00626       else {
00627         os << obj->ClassName() << "::" << obj->GetName() << endl;
00628       }
00629     }
00630   }
00631 }
00632 
00633 
00634 
00635 //_____________________________________________________________________________
00636 const char* RooPlot::nameOf(Int_t idx) const
00637 {
00638   // Return the name of the object at slot 'idx' in this RooPlot.
00639   // If the given index is out of range, return a null pointer
00640 
00641   TObject* obj = _items.At(idx) ;
00642   if (!obj) {
00643     coutE(InputArguments) << "RooPlot::nameOf(" << GetName() << ") index " << idx << " out of range" << endl ;
00644     return 0 ;
00645   }
00646   return obj->GetName() ;
00647 }
00648 
00649 
00650 
00651 //_____________________________________________________________________________
00652 TObject* RooPlot::getObject(Int_t idx) const
00653 {
00654   // Return the name of the object at slot 'idx' in this RooPlot.
00655   // If the given index is out of range, return a null pointer
00656 
00657   TObject* obj = _items.At(idx) ;
00658   if (!obj) {
00659     coutE(InputArguments) << "RooPlot::getObject(" << GetName() << ") index " << idx << " out of range" << endl ;
00660     return 0 ;
00661   }
00662   return obj ;
00663 }
00664 
00665 
00666 
00667 //_____________________________________________________________________________
00668 TAttLine *RooPlot::getAttLine(const char *name) const
00669 {
00670   // Return a pointer to the line attributes of the named object in this plot,
00671   // or zero if the named object does not exist or does not have line attributes.
00672 
00673   return dynamic_cast<TAttLine*>(findObject(name));
00674 }
00675 
00676 
00677 //_____________________________________________________________________________
00678 TAttFill *RooPlot::getAttFill(const char *name) const
00679 {
00680   // Return a pointer to the fill attributes of the named object in this plot,
00681   // or zero if the named object does not exist or does not have fill attributes.
00682 
00683   return dynamic_cast<TAttFill*>(findObject(name));
00684 }
00685 
00686 
00687 //_____________________________________________________________________________
00688 TAttMarker *RooPlot::getAttMarker(const char *name) const
00689 {
00690   // Return a pointer to the marker attributes of the named object in this plot,
00691   // or zero if the named object does not exist or does not have marker attributes.
00692 
00693   return dynamic_cast<TAttMarker*>(findObject(name));
00694 }
00695 
00696 
00697 //_____________________________________________________________________________
00698 TAttText *RooPlot::getAttText(const char *name) const
00699 {
00700   // Return a pointer to the text attributes of the named object in this plot,
00701   // or zero if the named object does not exist or does not have text attributes.
00702 
00703   return dynamic_cast<TAttText*>(findObject(name));
00704 }
00705 
00706 
00707 
00708 //_____________________________________________________________________________
00709 RooCurve* RooPlot::getCurve(const char* name) const
00710 {
00711   // Return a RooCurve pointer of the named object in this plot,
00712   // or zero if the named object does not exist or is not a RooCurve
00713 
00714   return dynamic_cast<RooCurve*>(findObject(name)) ;
00715 }
00716 
00717 
00718 //_____________________________________________________________________________
00719 RooHist* RooPlot::getHist(const char* name) const
00720 {
00721   // Return a RooCurve pointer of the named object in this plot,
00722   // or zero if the named object does not exist or is not a RooCurve
00723 
00724   return dynamic_cast<RooHist*>(findObject(name)) ;
00725 }
00726 
00727 
00728 
00729 //_____________________________________________________________________________
00730 void RooPlot::remove(const char* name, Bool_t deleteToo)
00731 {
00732   // Remove object with given name, or last object added if no name is given.
00733   // If deleteToo is true (default), the object removed from the RooPlot is
00734   // also deleted.
00735 
00736   TObject* obj = findObject(name) ;
00737   if (!obj) {
00738     if (name) {
00739       coutE(InputArguments) << "RooPlot::remove(" << GetName() << ") ERROR: no object found with name " << name << endl ;
00740     } else {
00741       coutE(InputArguments) << "RooPlot::remove(" << GetName() << ") ERROR: plot frame is empty, cannot remove last object" << endl ;
00742     }
00743     return ;
00744   }
00745 
00746   _items.Remove(obj) ;
00747 
00748   if (deleteToo) {
00749     delete obj ;
00750   }
00751 }
00752 
00753 
00754 //_____________________________________________________________________________
00755 Bool_t RooPlot::drawBefore(const char *before, const char *target)
00756 {
00757   // Change the order in which our contained objects are drawn so that
00758   // the target object is drawn just before the specified object.
00759   // Returns kFALSE if either object does not exist.
00760 
00761   return _items.moveBefore(before, target, caller("drawBefore"));
00762 }
00763 
00764 
00765 //_____________________________________________________________________________
00766 Bool_t RooPlot::drawAfter(const char *after, const char *target)
00767 {
00768   // Change the order in which our contained objects are drawn so that
00769   // the target object is drawn just after the specified object.
00770   // Returns kFALSE if either object does not exist.
00771 
00772   return _items.moveAfter(after, target, caller("drawAfter"));
00773 }
00774 
00775 
00776 //_____________________________________________________________________________
00777 TObject *RooPlot::findObject(const char *name, const TClass* clas) const
00778 {
00779   // Find the named object in our list of items and return a pointer
00780   // to it. Return zero and print a warning message if the named
00781   // object cannot be found. If no name is supplied the last object
00782   // added is returned.
00783   //
00784   // Note that the returned pointer is to a
00785   // TObject and so will generally need casting. Use the getAtt...()
00786   // methods to change the drawing style attributes of a contained
00787   // object directly.
00788 
00789   TObject *obj = 0;
00790   TObject *ret = 0;
00791 
00792   TIterator* iter = _items.MakeIterator() ;
00793   while((obj=iter->Next())) {
00794     if ((!name || !TString(name).CompareTo(obj->GetName())) &&
00795         (!clas || (obj->IsA()==clas))) {
00796       ret = obj ;
00797     }
00798   }
00799   delete iter ;
00800 
00801   if (ret==0) {
00802     coutE(InputArguments) << "RooPlot::findObject(" << GetName() << ") cannot find object " << (name?name:"<last>") << endl ;
00803   }
00804   return ret ;
00805 }
00806 
00807 
00808 //_____________________________________________________________________________
00809 TString RooPlot::getDrawOptions(const char *name) const
00810 {
00811   // Return the Draw() options registered for the named object. Return
00812   // an empty string if the named object cannot be found.
00813 
00814   TObjOptLink *link= _items.findLink(name,caller("getDrawOptions"));
00815   DrawOpt opt(0 == link ? "" : link->GetOption()) ;
00816   return TString(opt.drawOptions) ;
00817 }
00818 
00819 
00820 //_____________________________________________________________________________
00821 Bool_t RooPlot::setDrawOptions(const char *name, TString options)
00822 {
00823   // Register the specified drawing options for the named object.
00824   // Return kFALSE if the named object cannot be found.
00825 
00826   TObjOptLink *link= _items.findLink(name,caller("setDrawOptions"));
00827   if(0 == link) return kFALSE;
00828 
00829   DrawOpt opt(link->GetOption()) ;
00830   strlcpy(opt.drawOptions,options,128) ;
00831   link->SetOption(opt.rawOpt());
00832   return kTRUE;
00833 }
00834 
00835 
00836 //_____________________________________________________________________________
00837 Bool_t RooPlot::getInvisible(const char* name) const
00838 {
00839   // Returns true of object with given name is set to be invisible
00840   TObjOptLink *link= _items.findLink(name,caller("getInvisible"));
00841   if(0 == link) return kFALSE;
00842 
00843   return DrawOpt(link->GetOption()).invisible ;
00844 }
00845 
00846 
00847 //_____________________________________________________________________________
00848 void RooPlot::setInvisible(const char* name, Bool_t flag)
00849 {
00850   // If flag is true object with 'name' is set to be invisible
00851   // i.e. it is not drawn when Draw() is called
00852 
00853   TObjOptLink *link= _items.findLink(name,caller("getInvisible"));
00854 
00855   DrawOpt opt ;
00856 
00857   if(link) {
00858     opt.initialize(link->GetOption()) ;
00859     opt.invisible = flag ;
00860     link->SetOption(opt.rawOpt()) ;
00861   }
00862 
00863 }
00864 
00865 
00866 
00867 //_____________________________________________________________________________
00868 TString RooPlot::caller(const char *method) const
00869 {
00870   // Utility function
00871   TString name(fName);
00872   if(strlen(method)) {
00873     name.Append("::");
00874     name.Append(method);
00875   }
00876   return name;
00877 }
00878 
00879 
00880 
00881 //_____________________________________________________________________________
00882 void RooPlot::SetMaximum(Double_t maximum)
00883 {
00884   // Set maximum value of Y axis
00885   _hist->SetMaximum(maximum==-1111?_defYmax:maximum) ;
00886 }
00887 
00888 
00889 
00890 //_____________________________________________________________________________
00891 void RooPlot::SetMinimum(Double_t minimum)
00892 {
00893   // Set minimum value of Y axis
00894   _hist->SetMinimum(minimum==-1111?_defYmin:minimum) ;
00895 }
00896 
00897 
00898 
00899 //_____________________________________________________________________________
00900 Double_t RooPlot::chiSquare(const char* curvename, const char* histname, Int_t nFitParam) const
00901 {
00902   // Calculate and return reduced chi-squared of curve with given name with respect
00903   // to histogram with given name. If nFitParam is non-zero, it is used to reduce the
00904   // number of degrees of freedom for a chi^2 for a curve that was fitted to the
00905   // data with that number of floating parameters
00906 
00907 
00908   // Find curve object
00909   RooCurve* curve = (RooCurve*) findObject(curvename,RooCurve::Class()) ;
00910   if (!curve) {
00911     coutE(InputArguments) << "RooPlot::chiSquare(" << GetName() << ") cannot find curve" << endl ;
00912     return -1. ;
00913   }
00914 
00915   // Find histogram object
00916   RooHist* hist = (RooHist*) findObject(histname,RooHist::Class()) ;
00917   if (!hist) {
00918     coutE(InputArguments) << "RooPlot::chiSquare(" << GetName() << ") cannot find histogram" << endl ;
00919     return -1. ;
00920   }
00921 
00922   return curve->chiSquare(*hist,nFitParam) ;
00923 }
00924 
00925 
00926 //_____________________________________________________________________________
00927 RooHist* RooPlot::residHist(const char* histname, const char* curvename,bool normalize) const
00928 {
00929   // Return a RooHist containing the residuals of histogram 'histname' with respect
00930   // to curve 'curvename'. If normalize is true the residuals are divided by the error
00931   // on the histogram, effectively returning a pull histogram
00932 
00933   // Find curve object
00934   RooCurve* curve = (RooCurve*) findObject(curvename,RooCurve::Class()) ;
00935   if (!curve) {
00936     coutE(InputArguments) << "RooPlot::residHist(" << GetName() << ") cannot find curve" << endl ;
00937     return 0 ;
00938   }
00939 
00940   // Find histogram object
00941   RooHist* hist = (RooHist*) findObject(histname,RooHist::Class()) ;
00942   if (!hist) {
00943     coutE(InputArguments) << "RooPlot::residHist(" << GetName() << ") cannot find histogram" << endl ;
00944     return 0 ;
00945   }
00946 
00947   return hist->makeResidHist(*curve,normalize) ;
00948 }
00949 
00950 
00951 
00952 //_____________________________________________________________________________
00953 void RooPlot::DrawOpt::initialize(const char* inRawOpt)
00954 {
00955   // Initialize the DrawOpt helper class
00956 
00957   if (!inRawOpt) {
00958     drawOptions[0] = 0 ;
00959     invisible=kFALSE ;
00960     return ;
00961   }
00962   strlcpy(drawOptions,inRawOpt,128) ;
00963   strtok(drawOptions,":") ;
00964   const char* extraOpt = strtok(0,":") ;
00965   if (extraOpt) {
00966     invisible =  (extraOpt[0]=='I') ;
00967   }
00968 }
00969 
00970 
00971 //_____________________________________________________________________________
00972 const char* RooPlot::DrawOpt::rawOpt() const
00973 {
00974   // Return the raw draw options
00975   static char buf[128] ;
00976   strlcpy(buf,drawOptions,128) ;
00977   if (invisible) {
00978     strlcat(buf,":I",128) ;
00979   }
00980   return buf ;
00981 }
00982 
00983 
00984 
00985 //_____________________________________________________________________________
00986 Double_t RooPlot::getFitRangeNEvt(Double_t xlo, Double_t xhi) const
00987 {
00988   // Return the number of events that is associated with the range [xlo,xhi]
00989   // This method is only fully functional for ranges not equal to the full
00990   // range if the object that inserted the normalization data provided
00991   // a link to an external object that can calculate the event count in
00992   // in sub ranges. An error will be printed if this function is used
00993   // on sub-ranges while that information is not available
00994 
00995   Double_t scaleFactor = 1.0 ;
00996   if (_normObj) {
00997     scaleFactor = _normObj->getFitRangeNEvt(xlo,xhi)/_normObj->getFitRangeNEvt() ;
00998   } else {
00999     coutW(Plotting) << "RooPlot::getFitRangeNEvt(" << GetName() << ") WARNING: Unable to obtain event count in range "
01000                     << xlo << " to " << xhi << ", substituting full event count" << endl ;
01001   }
01002   return getFitRangeNEvt()*scaleFactor ;
01003 }
01004 
01005 
01006 //_____________________________________________________________________________
01007 void RooPlot::SetName(const char *name)
01008 {
01009   // Set the name of the RooPlot to 'name'
01010 
01011   if (_dir) _dir->GetList()->Remove(this);
01012   TNamed::SetName(name) ;
01013   if (_dir) _dir->GetList()->Add(this);
01014 }
01015 
01016 
01017 //_____________________________________________________________________________
01018 void RooPlot::SetNameTitle(const char *name, const char* title)
01019 {
01020   // Set the name and title of the RooPlot to 'name' and 'title'
01021   if (_dir) _dir->GetList()->Remove(this);
01022   TNamed::SetNameTitle(name,title) ;
01023   if (_dir) _dir->GetList()->Add(this);
01024 }
01025 
01026 
01027 //_____________________________________________________________________________
01028 void RooPlot::SetTitle(const char* title)
01029 {
01030   // Set the title of the RooPlot to 'title'
01031   TNamed::SetTitle(title) ;
01032   _hist->SetTitle(title) ;
01033 }
01034 
01035 
01036 
01037 //_____________________________________________________________________________
01038 Int_t RooPlot::defaultPrintContents(Option_t* /*opt*/) const
01039 {
01040   // Define default print options, for a given print style
01041 
01042   return kName|kArgs|kValue ;
01043 }
01044 
01045 
01046 
01047 TAxis* RooPlot::GetXaxis() const { return _hist->GetXaxis() ; }
01048 TAxis* RooPlot::GetYaxis() const { return _hist->GetYaxis() ; }
01049 Int_t  RooPlot::GetNbinsX() const { return _hist->GetNbinsX() ; }
01050 Int_t  RooPlot::GetNdivisions(Option_t* axis) const { return _hist->GetNdivisions(axis) ; }
01051 Double_t  RooPlot::GetMinimum(Double_t minval) const { return _hist->GetMinimum(minval) ; }
01052 Double_t   RooPlot::GetMaximum(Double_t maxval) const { return _hist->GetMaximum(maxval) ; }
01053 
01054 
01055 void RooPlot::SetAxisColor(Color_t color, Option_t* axis) { _hist->SetAxisColor(color,axis) ; }
01056 void RooPlot::SetAxisRange(Double_t xmin, Double_t xmax, Option_t* axis) { _hist->SetAxisRange(xmin,xmax,axis) ; }
01057 void RooPlot::SetBarOffset(Float_t offset) { _hist->SetBarOffset(offset) ; }
01058 void RooPlot::SetBarWidth(Float_t width) { _hist->SetBarWidth(width) ; }
01059 void RooPlot::SetContour(Int_t nlevels, const Double_t* levels) { _hist->SetContour(nlevels,levels) ; }
01060 void RooPlot::SetContourLevel(Int_t level, Double_t value) { _hist->SetContourLevel(level,value) ; }
01061 void RooPlot::SetDrawOption(Option_t* option) { _hist->SetDrawOption(option) ; }
01062 void RooPlot::SetFillAttributes() { _hist->SetFillAttributes() ; }
01063 void RooPlot::SetFillColor(Color_t fcolor) { _hist->SetFillColor(fcolor) ; }
01064 void RooPlot::SetFillStyle(Style_t fstyle) { _hist->SetFillStyle(fstyle) ; }
01065 void RooPlot::SetLabelColor(Color_t color, Option_t* axis) { _hist->SetLabelColor(color,axis) ; }
01066 void RooPlot::SetLabelFont(Style_t font, Option_t* axis) { _hist->SetLabelFont(font,axis) ; }
01067 void RooPlot::SetLabelOffset(Float_t offset, Option_t* axis) { _hist->SetLabelOffset(offset,axis) ; }
01068 void RooPlot::SetLabelSize(Float_t size, Option_t* axis) { _hist->SetLabelSize(size,axis) ; }
01069 void RooPlot::SetLineAttributes() { _hist->SetLineAttributes() ; }
01070 void RooPlot::SetLineColor(Color_t lcolor) { _hist->SetLineColor(lcolor) ; }
01071 void RooPlot::SetLineStyle(Style_t lstyle) { _hist->SetLineStyle(lstyle) ; }
01072 void RooPlot::SetLineWidth(Width_t lwidth) { _hist->SetLineWidth(lwidth) ; }
01073 void RooPlot::SetMarkerAttributes() { _hist->SetMarkerAttributes() ; }
01074 void RooPlot::SetMarkerColor(Color_t tcolor) { _hist->SetMarkerColor(tcolor) ; }
01075 void RooPlot::SetMarkerSize(Size_t msize) { _hist->SetMarkerSize(msize) ; }
01076 void RooPlot::SetMarkerStyle(Style_t mstyle) { _hist->SetMarkerStyle(mstyle) ; }
01077 void RooPlot::SetNdivisions(Int_t n, Option_t* axis) { _hist->SetNdivisions(n,axis) ; }
01078 void RooPlot::SetOption(Option_t* option) { _hist->SetOption(option) ; }
01079 void RooPlot::SetStats(Bool_t stats) { _hist->SetStats(stats) ; }
01080 void RooPlot::SetTickLength(Float_t length, Option_t* axis) { _hist->SetTickLength(length,axis) ; }
01081 void RooPlot::SetTitleFont(Style_t font, Option_t* axis) { _hist->SetTitleFont(font,axis) ; }
01082 void RooPlot::SetTitleOffset(Float_t offset, Option_t* axis) { _hist->SetTitleOffset(offset,axis) ; }
01083 void RooPlot::SetTitleSize(Float_t size, Option_t* axis) { _hist->SetTitleSize(size,axis) ; }
01084 void RooPlot::SetXTitle(const char *title) { _hist->SetXTitle(title) ; }
01085 void RooPlot::SetYTitle(const char *title) { _hist->SetYTitle(title) ; }
01086 void RooPlot::SetZTitle(const char *title) { _hist->SetZTitle(title) ; }
01087 
01088 
01089 
01090 
01091 //______________________________________________________________________________
01092 void RooPlot::Browse(TBrowser * /*b*/)
01093 {
01094   // Plot RooPlot when double-clicked in browser
01095   Draw();
01096   gPad->Update();
01097 }
01098 
01099 
01100 
01101 
01102 //_____________________________________________________________________________
01103 void RooPlot::Streamer(TBuffer &R__b)
01104 {
01105 
01106   // Custom streamer, needed for backward compatibility
01107 
01108   if (R__b.IsReading()) {
01109 
01110     TH1::AddDirectory(kFALSE) ;
01111 
01112     UInt_t R__s, R__c;
01113     Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01114     if (R__v > 1) {
01115       R__b.ReadClassBuffer(RooPlot::Class(),this,R__v,R__s,R__c);
01116     } else {
01117       // backward compatible streamer code here
01118       // Version 1 of RooPlot was deriving from TH1 and RooPrintable
01119       // Version 2 derives instead from TNamed and RooPrintable
01120       _hist = new TH1F();
01121       _hist->TH1::Streamer(R__b);
01122       SetName(_hist->GetName());
01123       SetTitle(_hist->GetTitle());
01124       RooPrintable::Streamer(R__b);
01125       _items.Streamer(R__b);
01126       R__b >> _padFactor;
01127       R__b >> _plotVarClone;
01128       R__b >> _plotVarSet;
01129       R__b >> _normVars;
01130       R__b >> _normNumEvts;
01131       R__b >> _normBinWidth;
01132       R__b >> _defYmin;
01133       R__b >> _defYmax;
01134       R__b.CheckByteCount(R__s, R__c, RooPlot::IsA());
01135     }
01136 
01137     TH1::AddDirectory(kTRUE) ;
01138 
01139 
01140   } else {
01141     R__b.WriteClassBuffer(RooPlot::Class(),this);
01142   }
01143 }

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