RooAbsRealLValue.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooAbsRealLValue.cxx 36210 2010-10-08 21:59:38Z 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 // RooAbsRealLValue is the common abstract base class for objects that represent a
00021 // real value that may appear on the left hand side of an equation ('lvalue')
00022 // Each implementation must provide a setVal() member to allow direct modification 
00023 // of the value. RooAbsRealLValue may be derived, but its functional relation
00024 // to other RooAbsArg must be invertible
00025 //
00026 // This class has methods that export the defined range of the lvalue,
00027 // but doesn't hold its values because these limits may be derived
00028 // from limits of client object.  The range serve as integration
00029 // range when interpreted as a observable and a boundaries when
00030 // interpreted as a parameter.
00031 // END_HTML
00032 //
00033 //
00034 
00035 #include "RooFit.h"
00036 
00037 #include <math.h>
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include <ctype.h>
00041 #include "Riostream.h"
00042 #include "TObjString.h"
00043 #include "TTree.h"
00044 #include "TH1.h"
00045 #include "TH2.h"
00046 #include "TH3.h"
00047 #include "RooAbsRealLValue.h"
00048 #include "RooStreamParser.h"
00049 #include "RooRandom.h"
00050 #include "RooPlot.h"
00051 #include "RooArgList.h"
00052 #include "RooAbsBinning.h"
00053 #include "RooBinning.h"
00054 #include "RooUniformBinning.h"
00055 #include "RooCmdConfig.h"
00056 #include "RooTreeData.h"
00057 #include "RooRealVar.h"
00058 #include "RooMsgService.h"
00059 
00060 
00061 
00062 ClassImp(RooAbsRealLValue)
00063 
00064 //_____________________________________________________________________________
00065 RooAbsRealLValue::RooAbsRealLValue(const char *name, const char *title, const char *unit) :
00066   RooAbsReal(name, title, 0, 0, unit)
00067 {
00068   // Constructor
00069 }  
00070 
00071 
00072 
00073 //_____________________________________________________________________________
00074 RooAbsRealLValue::RooAbsRealLValue(const RooAbsRealLValue& other, const char* name) :
00075   RooAbsReal(other,name), RooAbsLValue(other)
00076 {
00077   // Copy constructor
00078 }
00079 
00080 
00081 //_____________________________________________________________________________
00082 RooAbsRealLValue::~RooAbsRealLValue() 
00083 {
00084   // Destructor
00085 }
00086 
00087 
00088 
00089 //_____________________________________________________________________________
00090 Bool_t RooAbsRealLValue::inRange(Double_t value, const char* rangeName, Double_t* clippedValPtr) const
00091 {
00092   // Return kTRUE if the input value is within our fit range. Otherwise, return
00093   // kFALSE and write a clipped value into clippedValPtr if it is non-zero.
00094 
00095   // Double_t range = getMax() - getMin() ; // ok for +/-INIFINITY
00096   Double_t clippedValue(value);
00097   Bool_t isInRange(kTRUE) ;
00098 
00099   // test this value against our upper fit limit
00100   if(hasMax() && value > (getMax(rangeName)+1e-6)) {
00101     if (clippedValPtr) {
00102 //       coutW(InputArguments) << "RooAbsRealLValue::inFitRange(" << GetName() << "): value " << value
00103 //                          << " rounded down to max limit " << getMax(rangeName) << endl ;
00104     }
00105     clippedValue = getMax(rangeName);
00106     isInRange = kFALSE ;
00107   }
00108   // test this value against our lower fit limit
00109   if(hasMin() && value < getMin(rangeName)-1e-6) {
00110     if (clippedValPtr) {
00111 //       coutW(InputArguments) << "RooAbsRealLValue::inFitRange(" << GetName() << "): value " << value
00112 //                          << " rounded up to min limit " << getMin(rangeName) << endl;
00113     }
00114     clippedValue = getMin(rangeName);
00115     isInRange = kFALSE ;
00116   } 
00117 
00118   if (clippedValPtr) *clippedValPtr=clippedValue ;
00119   return isInRange ;
00120 }
00121 
00122 
00123 
00124 //_____________________________________________________________________________
00125 Bool_t RooAbsRealLValue::isValidReal(Double_t value, Bool_t verbose) const 
00126 {
00127   // Check if given value is valid
00128 
00129   if (!inRange(value,0)) {
00130     if (verbose)
00131       coutI(InputArguments) << "RooRealVar::isValid(" << GetName() << "): value " << value
00132                             << " out of range (" << getMin() << " - " << getMax() << ")" << endl ;
00133     return kFALSE ;
00134   }
00135   return kTRUE ;
00136 }                                                                                                                         
00137 
00138 
00139 
00140 //_____________________________________________________________________________
00141 Bool_t RooAbsRealLValue::readFromStream(istream& /*is*/, Bool_t /*compact*/, Bool_t /*verbose*/) 
00142 {
00143   // Read object contents from given stream
00144 
00145   return kTRUE ;
00146 }
00147 
00148 
00149 
00150 //_____________________________________________________________________________
00151 void RooAbsRealLValue::writeToStream(ostream& /*os*/, Bool_t /*compact*/) const
00152 {
00153   // Write object contents to given stream
00154 }
00155 
00156 
00157 
00158 //_____________________________________________________________________________
00159 RooAbsArg& RooAbsRealLValue::operator=(Double_t newValue) 
00160 {
00161   // Assignment operator from a Double_t
00162 
00163   Double_t clipValue ;
00164   // Clip 
00165   inRange(newValue,0,&clipValue) ;
00166   setVal(clipValue) ;
00167 
00168   return *this ;
00169 }
00170 
00171 
00172 //_____________________________________________________________________________
00173 RooAbsArg& RooAbsRealLValue::operator=(const RooAbsReal& arg) 
00174 {
00175   // Assignment operator from other RooAbsReal
00176   return operator=(arg.getVal()) ;
00177 }
00178 
00179 
00180 
00181 //_____________________________________________________________________________
00182 RooPlot* RooAbsRealLValue::frame(const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
00183                                  const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const 
00184 
00185   // Create a new RooPlot on the heap with a drawing frame initialized for this
00186   // object, but no plot contents. Use x.frame() as the first argument to a
00187   // y.plotOn(...) method, for example. The caller is responsible for deleting
00188   // the returned object.
00189   //
00190   // This function takes the following named arguments
00191   //
00192   // Range(double lo, double hi)          -- Make plot frame for the specified range
00193   // Range(const char* name)              -- Make plot frame for range with the specified name
00194   // Bins(Int_t nbins)                    -- Set default binning for datasets to specified number of bins
00195   // AutoRange(const RooAbsData& data,    -- Specifies range so that all points in given data set fit 
00196   //                    double margin)       inside the range with given margin.
00197   // AutoSymRange(const RooAbsData& data, -- Specifies range so that all points in given data set fit 
00198   //                    double margin)       inside the range and center of range coincides with mean
00199   //                                         of distribution in given dataset. 
00200   // Name(const char* name)               -- Give specified name to RooPlot object 
00201   // Title(const char* title)             -- Give specified title to RooPlot object
00202   //  
00203 {
00204   RooLinkedList cmdList ;
00205   cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
00206   cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
00207   cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
00208   cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
00209 
00210   return frame(cmdList) ;
00211 }
00212 
00213 
00214 
00215 //_____________________________________________________________________________
00216 RooPlot* RooAbsRealLValue::frame(const RooLinkedList& cmdList) const 
00217 {
00218   // Back-end function for named argument frame() method
00219 
00220   // Define configuration for this method
00221   RooCmdConfig pc(Form("RooAbsRealLValue::frame(%s)",GetName())) ;
00222   pc.defineDouble("min","Range",0,getMin()) ;
00223   pc.defineDouble("max","Range",1,getMax()) ;
00224   pc.defineInt("nbins","Bins",0,getBins()) ;
00225   pc.defineString("rangeName","RangeWithName",0,"") ;
00226   pc.defineString("name","Name",0,"") ;
00227   pc.defineString("title","Title",0,"") ;
00228   pc.defineMutex("Range","RangeWithName","AutoRange") ;
00229   pc.defineObject("rangeData","AutoRange",0,0) ;
00230   pc.defineDouble("rangeMargin","AutoRange",0,0.1) ;
00231   pc.defineInt("rangeSym","AutoRange",0,0) ;
00232 
00233   // Process & check varargs 
00234   pc.process(cmdList) ;
00235   if (!pc.ok(kTRUE)) {
00236     return 0 ;
00237   }
00238 
00239   // Extract values from named arguments
00240   Double_t xmin,xmax ;
00241   if (pc.hasProcessed("Range")) {
00242     xmin = pc.getDouble("min") ;
00243     xmax = pc.getDouble("max") ;
00244     if (xmin==xmax) {
00245       xmin = getMin() ;
00246       xmax = getMax() ;
00247     }
00248   } else if (pc.hasProcessed("RangeWithName")) {
00249     const char* rangeName=pc.getString("rangeName",0,kTRUE) ;
00250     xmin = getMin(rangeName) ;
00251     xmax = getMax(rangeName) ;
00252   } else if (pc.hasProcessed("AutoRange")) {
00253     RooTreeData* rangeData = static_cast<RooTreeData*>(pc.getObject("rangeData")) ;
00254     rangeData->getRange((RooRealVar&)*this,xmin,xmax) ;
00255     if (pc.getInt("rangeSym")==0) {
00256       // Regular mode: range is from xmin to xmax with given extra margin
00257       Double_t margin = pc.getDouble("rangeMargin")*(xmax-xmin) ;    
00258       xmin -= margin ;
00259       xmax += margin ; 
00260       if (xmin<getMin()) xmin = getMin() ;
00261       if (xmin>getMax()) xmax = getMax() ;
00262     } else {
00263       // Symmetric mode: range is centered at mean of distribution with enough width to include
00264       // both lowest and highest point with margin
00265       Double_t dmean = rangeData->moment((RooRealVar&)*this,1) ;
00266       Double_t ddelta = ((xmax-dmean)>(dmean-xmin)?(xmax-dmean):(dmean-xmin))*(1+pc.getDouble("rangeMargin")) ;
00267       xmin = dmean-ddelta ;
00268       xmax = dmean+ddelta ;
00269       if (xmin<getMin()) xmin = getMin() ;
00270       if (xmin>getMax()) xmax = getMax() ;
00271     }
00272   } else {
00273     xmin = getMin() ;
00274     xmax = getMax() ;
00275   }
00276 
00277   Int_t nbins = pc.getInt("nbins") ;
00278   const char* name = pc.getString("name",0,kTRUE) ;
00279   const char* title = pc.getString("title",0,kTRUE) ;
00280 
00281   RooPlot* theFrame = new RooPlot(*this,xmin,xmax,nbins) ;
00282 
00283   if (name) {
00284     theFrame->SetName(name) ;
00285   }
00286   if (title) {
00287     theFrame->SetTitle(title) ;
00288   }
00289 
00290   return theFrame ;
00291 }
00292 
00293 
00294 
00295 //_____________________________________________________________________________
00296 RooPlot *RooAbsRealLValue::frame(Double_t xlo, Double_t xhi, Int_t nbins) const 
00297 {
00298   // Create a new RooPlot on the heap with a drawing frame initialized for this
00299   // object, but no plot contents. Use x.frame() as the first argument to a
00300   // y.plotOn(...) method, for example. The caller is responsible for deleting
00301   // the returned object.
00302 
00303   return new RooPlot(*this,xlo,xhi,nbins);
00304 }
00305 
00306 
00307 
00308 //_____________________________________________________________________________
00309 RooPlot *RooAbsRealLValue::frame(Double_t xlo, Double_t xhi) const 
00310 {
00311   // Create a new RooPlot on the heap with a drawing frame initialized for this
00312   // object, but no plot contents. Use x.frame() as the first argument to a
00313   // y.plotOn(...) method, for example. The caller is responsible for deleting
00314   // the returned object.
00315 
00316   return new RooPlot(*this,xlo,xhi,getBins());
00317 }
00318 
00319 
00320 
00321 //_____________________________________________________________________________
00322 RooPlot *RooAbsRealLValue::frame(Int_t nbins) const 
00323 {
00324   // Create a new RooPlot on the heap with a drawing frame initialized for this
00325   // object, but no plot contents. Use x.frame() as the first argument to a
00326   // y.plotOn(...) method, for example. The caller is responsible for deleting
00327   // the returned object.
00328   //
00329   // The current fit range may not be open ended or empty.
00330 
00331   // Plot range of variable may not be infinite or empty
00332   if (getMin()==getMax()) {
00333     coutE(InputArguments) << "RooAbsRealLValue::frame(" << GetName() << ") ERROR: empty fit range, must specify plot range" << endl ;
00334     return 0 ;
00335   }
00336   if (RooNumber::isInfinite(getMin())||RooNumber::isInfinite(getMax())) {
00337     coutE(InputArguments) << "RooAbsRealLValue::frame(" << GetName() << ") ERROR: open ended fit range, must specify plot range" << endl ;
00338     return 0 ;
00339   }
00340 
00341   return new RooPlot(*this,getMin(),getMax(),nbins);
00342 }
00343 
00344 
00345 
00346 //_____________________________________________________________________________
00347 RooPlot *RooAbsRealLValue::frame() const 
00348 {
00349   // Create a new RooPlot on the heap with a drawing frame initialized for this
00350   // object, but no plot contents. Use x.frame() as the first argument to a
00351   // y.plotOn(...) method, for example. The caller is responsible for deleting
00352   // the returned object.
00353   //
00354   // The current fit range may not be open ended or empty.
00355 
00356   // Plot range of variable may not be infinite or empty
00357   if (getMin()==getMax()) {
00358     coutE(InputArguments) << "RooAbsRealLValue::frame(" << GetName() << ") ERROR: empty fit range, must specify plot range" << endl ;
00359     return 0 ;
00360   }
00361   if (RooNumber::isInfinite(getMin())||RooNumber::isInfinite(getMax())) {
00362     coutE(InputArguments) << "RooAbsRealLValue::frame(" << GetName() << ") ERROR: open ended fit range, must specify plot range" << endl ;
00363     return 0 ;
00364   }
00365 
00366   return new RooPlot(*this,getMin(),getMax(),getBins());
00367 }
00368 
00369 
00370 
00371 //_____________________________________________________________________________
00372 void RooAbsRealLValue::copyCache(const RooAbsArg* source, Bool_t /*valueOnly*/) 
00373 {
00374   // Copy cache of another RooAbsArg to our cache
00375 
00376   RooAbsReal::copyCache(source) ;
00377   setVal(_value) ; // force back-propagation
00378 }
00379 
00380 
00381 //_____________________________________________________________________________
00382 void RooAbsRealLValue::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
00383 {  
00384   // Structure printing
00385 
00386   RooAbsReal::printMultiline(os,contents,verbose,indent);
00387   os << indent << "--- RooAbsRealLValue ---" << endl;
00388   TString unit(_unit);
00389   if(!unit.IsNull()) unit.Prepend(' ');
00390   os << indent << "  Fit range is [ ";
00391   if(hasMin()) {
00392     os << getMin() << unit << " , ";
00393   }
00394   else {
00395     os << "-INF , ";
00396   }
00397   if(hasMax()) {
00398     os << getMax() << unit << " ]" << endl;
00399   }
00400   else {
00401     os << "+INF ]" << endl;
00402   }
00403 }
00404 
00405 
00406 
00407 //_____________________________________________________________________________
00408 void RooAbsRealLValue::randomize(const char* rangeName) 
00409 {
00410   // Set a new value sampled from a uniform distribution over the fit range.
00411   // Prints a warning and does nothing if the fit range is not finite.
00412   
00413   if(hasMin(rangeName) && hasMax(rangeName)) {
00414     Double_t range= getMax(rangeName)-getMin(rangeName);
00415     setVal(getMin(rangeName) + RooRandom::uniform()*range);
00416   }
00417   else {
00418     coutE(Generation) << fName << "::" << ClassName() << ":randomize: fails with unbounded fit range" << endl;
00419   }
00420 }
00421 
00422 
00423 
00424 //_____________________________________________________________________________
00425 void RooAbsRealLValue::setBin(Int_t ibin, const char* rangeName) 
00426 {
00427   // Set value to center of bin 'ibin' of binning 'rangeName' (or of 
00428   // default binning if no range is specified)
00429 
00430   // Check range of plot bin index
00431   if (ibin<0 || ibin>=numBins(rangeName)) {
00432     coutE(InputArguments) << "RooAbsRealLValue::setBin(" << GetName() << ") ERROR: bin index " << ibin
00433                           << " is out of range (0," << getBins(rangeName)-1 << ")" << endl ;
00434     return ;
00435   }
00436  
00437   // Set value to center of requested bin
00438   setVal(getBinning(rangeName).binCenter(ibin)) ;
00439 }
00440 
00441 
00442 
00443 
00444 
00445 //_____________________________________________________________________________
00446 void RooAbsRealLValue::setBin(Int_t ibin, const RooAbsBinning& binning) 
00447 {
00448   // Set value to center of bin 'ibin' of binning 'binning' 
00449 
00450   // Set value to center of requested bin
00451   setVal(binning.binCenter(ibin)) ;
00452 }
00453 
00454 
00455 
00456 
00457 
00458 //_____________________________________________________________________________
00459 void RooAbsRealLValue::randomize(const RooAbsBinning& binning) 
00460 {
00461   // Set a new value sampled from a uniform distribution over the fit range.
00462   // Prints a warning and does nothing if the fit range is not finite.
00463   
00464   Double_t range= binning.highBound() - binning.lowBound() ;
00465   setVal(binning.lowBound() + RooRandom::uniform()*range);
00466 }
00467 
00468 
00469 
00470 
00471 
00472 //_____________________________________________________________________________
00473 void RooAbsRealLValue::setBinFast(Int_t ibin, const RooAbsBinning& binning) 
00474 {
00475   // Set value to center of bin 'ibin' of binning 'rangeName' (or of 
00476   // default binning if no range is specified)
00477 
00478   // Set value to center of requested bin
00479   setValFast(binning.binCenter(ibin)) ;
00480 }
00481 
00482 
00483 
00484 //_____________________________________________________________________________
00485 Bool_t RooAbsRealLValue::fitRangeOKForPlotting() const 
00486 {
00487   // Check if fit range is usable as plot range, i.e. it is neither
00488   // open ended, nor empty
00489   return (hasMin() && hasMax() && (getMin()!=getMax())) ;
00490 }
00491 
00492 
00493 
00494 //_____________________________________________________________________________
00495 Bool_t RooAbsRealLValue::inRange(const char* name) const 
00496 {
00497   // Check if current value is inside range with given name
00498 
00499   return (getVal() >= getMin(name) && getVal() <= getMax(name)) ;
00500 }
00501 
00502 
00503 
00504 //_____________________________________________________________________________
00505 TH1* RooAbsRealLValue::createHistogram(const char *name, const RooCmdArg& arg1, const RooCmdArg& arg2, 
00506                                         const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5, 
00507                                         const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const 
00508 
00509   // Create an empty ROOT histogram TH1,TH2 or TH3 suitabe to store information represent by the RooAbsRealLValue
00510   //
00511   // This function accepts the following arguments
00512   //
00513   // name -- Name of the ROOT histogram
00514   //
00515   // Binning(const char* name)                    -- Apply binning with given name to x axis of histogram
00516   // Binning(RooAbsBinning& binning)              -- Apply specified binning to x axis of histogram
00517   // Binning(int_t nbins)                         -- Apply specified binning to x axis of histogram
00518   // Binning(int_t nbins, double lo, double hi)   -- Apply specified binning to x axis of histogram
00519   // ConditionalObservables(const RooArgSet& set) -- Do not normalized PDF over following observables when projecting PDF into histogram
00520   //
00521   // YVar(const RooAbsRealLValue& var,...)    -- Observable to be mapped on y axis of ROOT histogram
00522   // ZVar(const RooAbsRealLValue& var,...)    -- Observable to be mapped on z axis of ROOT histogram
00523   //
00524   // The YVar() and ZVar() arguments can be supplied with optional Binning() arguments to control the binning of the Y and Z axes, e.g.
00525   // createHistogram("histo",x,Binning(-1,1,20), YVar(y,Binning(-1,1,30)), ZVar(z,Binning("zbinning")))
00526   //
00527   // The caller takes ownership of the returned histogram
00528 {
00529   RooLinkedList l ;
00530   l.Add((TObject*)&arg1) ;  l.Add((TObject*)&arg2) ;  
00531   l.Add((TObject*)&arg3) ;  l.Add((TObject*)&arg4) ;
00532   l.Add((TObject*)&arg5) ;  l.Add((TObject*)&arg6) ;  
00533   l.Add((TObject*)&arg7) ;  l.Add((TObject*)&arg8) ;
00534 
00535   return createHistogram(name,l) ;
00536 }
00537 
00538 
00539 
00540 //_____________________________________________________________________________
00541 TH1* RooAbsRealLValue::createHistogram(const char *name, const RooLinkedList& cmdList) const 
00542 {  
00543   // Create empty 1,2 or 3D histogram
00544   // Arguments recognized
00545   //
00546   // YVar() -- RooRealVar defining Y dimension with optional range/binning
00547   // ZVar() -- RooRealVar defining Z dimension with optional range/binning
00548   // AxisLabel() -- Vertical axis label
00549   // Binning() -- Range/Binning specification of X axis
00550 
00551   // Define configuration for this method
00552   RooCmdConfig pc(Form("RooAbsRealLValue::createHistogram(%s)",GetName())) ;
00553 
00554   pc.defineObject("xbinning","Binning",0,0) ;
00555   pc.defineString("xbinningName","BinningName",0,"") ;
00556   pc.defineInt("nxbins","BinningSpec",0) ;
00557   pc.defineDouble("xlo","BinningSpec",0,0) ;
00558   pc.defineDouble("xhi","BinningSpec",1,0) ;
00559 
00560   pc.defineObject("yvar","YVar",0,0) ;
00561   pc.defineObject("ybinning","YVar::Binning",0,0) ;
00562   pc.defineString("ybinningName","YVar::BinningName",0,"") ;
00563   pc.defineInt("nybins","YVar::BinningSpec",0) ;
00564   pc.defineDouble("ylo","YVar::BinningSpec",0,0) ;
00565   pc.defineDouble("yhi","YVar::BinningSpec",1,0) ;
00566 
00567   pc.defineObject("zvar","ZVar",0,0) ;
00568   pc.defineObject("zbinning","ZVar::Binning",0,0) ;
00569   pc.defineString("zbinningName","ZVar::BinningName",0,"") ;
00570   pc.defineInt("nzbins","ZVar::BinningSpec",0) ;
00571   pc.defineDouble("zlo","ZVar::BinningSpec",0,0) ;
00572   pc.defineDouble("zhi","ZVar::BinningSpec",1,0) ;
00573 
00574   pc.defineString("axisLabel","AxisLabel",0,"Events") ;
00575 
00576   pc.defineDependency("ZVar","YVar") ;
00577 
00578   // Process & check varargs 
00579   pc.process(cmdList) ;
00580   if (!pc.ok(kTRUE)) {
00581     return 0 ;
00582   }
00583 
00584   // Initialize arrays for call to implementation version of createHistogram
00585   const char* axisLabel = pc.getString("axisLabel") ;
00586   const RooAbsBinning* binning[3] ;
00587   Bool_t ownBinning[3]  = { kFALSE, kFALSE, kFALSE } ;
00588   RooArgList vars ;
00589 
00590   // Prepare X dimension
00591   vars.add(*this) ;
00592   if (pc.hasProcessed("Binning")) {
00593     binning[0] = static_cast<RooAbsBinning*>(pc.getObject("xbinning")) ;
00594   } else if (pc.hasProcessed("BinningName")) {
00595     binning[0] = &getBinning(pc.getString("xbinningName",0,kTRUE)) ;
00596   } else if (pc.hasProcessed("BinningSpec")) { 
00597     Double_t xlo = pc.getDouble("xlo") ;
00598     Double_t xhi = pc.getDouble("xhi") ;
00599     binning[0] = new RooUniformBinning((xlo==xhi)?getMin():xlo,(xlo==xhi)?getMax():xhi,pc.getInt("nxbins")) ;
00600     ownBinning[0] = kTRUE ;
00601   } else { 
00602     binning[0] = &getBinning() ;
00603   }
00604 
00605   if (pc.hasProcessed("YVar")) {
00606     RooAbsRealLValue& yvar = *static_cast<RooAbsRealLValue*>(pc.getObject("yvar")) ;
00607     vars.add(yvar) ;
00608     if (pc.hasProcessed("YVar::Binning")) {
00609       binning[1] = static_cast<RooAbsBinning*>(pc.getObject("ybinning")) ;
00610     } else if (pc.hasProcessed("YVar::BinningName")) {
00611       binning[1] = &yvar.getBinning(pc.getString("ybinningName",0,kTRUE)) ;
00612     } else if (pc.hasProcessed("YVar::BinningSpec")) {
00613       Double_t ylo = pc.getDouble("ylo") ;
00614       Double_t yhi = pc.getDouble("yhi") ;
00615       binning[1] = new RooUniformBinning((ylo==yhi)?yvar.getMin():ylo,(ylo==yhi)?yvar.getMax():yhi,pc.getInt("nybins")) ;
00616       ownBinning[1] = kTRUE ;
00617     } else {
00618       binning[1] = &yvar.getBinning() ;
00619     }
00620   }
00621 
00622   if (pc.hasProcessed("ZVar")) {
00623     RooAbsRealLValue& zvar = *static_cast<RooAbsRealLValue*>(pc.getObject("zvar")) ;
00624     vars.add(zvar) ;
00625     if (pc.hasProcessed("ZVar::Binning")) {
00626       binning[2] = static_cast<RooAbsBinning*>(pc.getObject("zbinning")) ;
00627     } else if (pc.hasProcessed("ZVar::BinningName")) {
00628       binning[2] = &zvar.getBinning(pc.getString("zbinningName",0,kTRUE)) ;
00629     } else if (pc.hasProcessed("ZVar::BinningSpec")) {
00630       Double_t zlo = pc.getDouble("zlo") ;
00631       Double_t zhi = pc.getDouble("zhi") ;
00632       binning[2] = new RooUniformBinning((zlo==zhi)?zvar.getMin():zlo,(zlo==zhi)?zvar.getMax():zhi,pc.getInt("nzbins")) ;
00633       ownBinning[2] = kTRUE ;
00634     } else {
00635       binning[2] = &zvar.getBinning() ;
00636     }
00637   }
00638 
00639 
00640   TH1* ret = createHistogram(name, vars, axisLabel, binning) ;
00641 
00642   if (ownBinning[0]) delete binning[0] ;
00643   if (ownBinning[1]) delete binning[1] ;
00644   if (ownBinning[2]) delete binning[2] ;
00645   
00646   return ret ;
00647 }
00648 
00649 
00650 
00651 //_____________________________________________________________________________
00652 TH1F *RooAbsRealLValue::createHistogram(const char *name, const char *yAxisLabel) const 
00653 {
00654   // Create an empty 1D-histogram with appropriate scale and labels for this variable.
00655   // This method uses the default plot range which can be changed using the
00656   // setPlotMin(),setPlotMax() methods, and the default binning which can be
00657   // changed with setPlotBins(). The caller takes ownership of the returned
00658   // object and is responsible for deleting it.
00659 
00660   // Check if the fit range is usable as plot range
00661   if (!fitRangeOKForPlotting()) {
00662     coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName() 
00663                           << ") ERROR: fit range empty or open ended, must explicitly specify range" << endl ;
00664     return 0 ;
00665   }
00666 
00667   RooArgList list(*this) ;
00668   Double_t xlo = getMin() ;
00669   Double_t xhi = getMax() ;
00670   Int_t nbins = getBins() ;
00671 
00672   // coverity[ARRAY_VS_SINGLETON]
00673   return (TH1F*)createHistogram(name, list, yAxisLabel, &xlo, &xhi, &nbins);
00674 }
00675 
00676 
00677 
00678 //_____________________________________________________________________________
00679 TH1F *RooAbsRealLValue::createHistogram(const char *name, const char *yAxisLabel, Double_t xlo, Double_t xhi, Int_t nBins) const 
00680 {
00681   // Create an empty 1D-histogram with appropriate scale and labels for this variable.
00682   // This method uses the default plot range which can be changed using the
00683   // setPlotMin(),setPlotMax() methods, and the default binning which can be
00684   // changed with setPlotBins(). The caller takes ownership of the returned
00685   // object and is responsible for deleting it.
00686 
00687   RooArgList list(*this) ;
00688 
00689   // coverity[ARRAY_VS_SINGLETON]
00690   return (TH1F*)createHistogram(name, list, yAxisLabel, &xlo, &xhi, &nBins);
00691 }
00692 
00693 
00694 
00695 //_____________________________________________________________________________
00696 TH1F *RooAbsRealLValue::createHistogram(const char *name, const char *yAxisLabel, const RooAbsBinning& bins) const 
00697 {
00698   // Create an empty 1D-histogram with appropriate scale and labels for this variable.
00699 
00700   RooArgList list(*this) ;
00701   const RooAbsBinning* pbins = &bins ;
00702 
00703   // coverity[ARRAY_VS_SINGLETON]
00704   return (TH1F*)createHistogram(name, list, yAxisLabel, &pbins);
00705 }
00706 
00707 
00708 
00709 //_____________________________________________________________________________
00710 TH2F *RooAbsRealLValue::createHistogram(const char *name, const RooAbsRealLValue &yvar, const char *zAxisLabel, 
00711                                         Double_t* xlo, Double_t* xhi, Int_t* nBins) const 
00712 {
00713   // Create an empty 2D-histogram with appropriate scale and labels for this variable (x)
00714   // and the specified y variable. This method uses the default plot ranges for x and y which
00715   // can be changed using the setPlotMin(),setPlotMax() methods, and the default binning which
00716   // can be changed with setPlotBins(). The caller takes ownership of the returned object
00717   // and is responsible for deleting it.
00718 
00719   if ((!xlo && xhi) || (xlo && !xhi)) {
00720     coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName() 
00721                           << ") ERROR must specify either no range, or both limits" << endl ;
00722     return 0 ;
00723   }
00724 
00725   Double_t xlo_fit[2] ;
00726   Double_t xhi_fit[2] ;
00727   Int_t nbins_fit[2] ;
00728 
00729   Double_t *xlo2 = xlo;
00730   Double_t *xhi2 = xhi;
00731   Int_t *nBins2 = nBins;
00732 
00733   if (!xlo2) {
00734 
00735     if (!fitRangeOKForPlotting()) {
00736       coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName() 
00737            << ") ERROR: fit range empty or open ended, must explicitly specify range" << endl ;      
00738       return 0 ;
00739     }
00740     if (!yvar.fitRangeOKForPlotting()) {
00741       coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName() 
00742            << ") ERROR: fit range of " << yvar.GetName() << " empty or open ended, must explicitly specify range" << endl ;      
00743       return 0 ;
00744     }
00745 
00746     xlo_fit[0] = getMin() ;
00747     xhi_fit[0] = getMax() ;    
00748 
00749     xlo_fit[1] = yvar.getMin() ;
00750     xhi_fit[1] = yvar.getMax() ;
00751 
00752     xlo2 = xlo_fit ;
00753     xhi2 = xhi_fit ;
00754   }
00755   
00756   if (!nBins2) {
00757     nbins_fit[0] = getBins() ;
00758     nbins_fit[1] = yvar.getBins() ;
00759     nBins2 = nbins_fit ;
00760   }
00761 
00762 
00763   RooArgList list(*this,yvar) ;
00764   // coverity[OVERRUN_STATIC] 
00765   return (TH2F*)createHistogram(name, list, zAxisLabel, xlo2, xhi2, nBins2);
00766 }
00767 
00768 
00769 
00770 //_____________________________________________________________________________
00771 TH2F *RooAbsRealLValue::createHistogram(const char *name, const RooAbsRealLValue &yvar, 
00772                                         const char *zAxisLabel, const RooAbsBinning** bins) const 
00773 {
00774   // Create an empty 2D-histogram with appropriate scale and labels for this variable (x)
00775   // and the specified y variable. 
00776 
00777   RooArgList list(*this,yvar) ;
00778   return (TH2F*)createHistogram(name, list, zAxisLabel, bins);
00779 }
00780 
00781 
00782 
00783 //_____________________________________________________________________________
00784 TH3F *RooAbsRealLValue::createHistogram(const char *name, const RooAbsRealLValue &yvar, const RooAbsRealLValue &zvar,
00785                                         const char *tAxisLabel, Double_t* xlo, Double_t* xhi, Int_t* nBins) const 
00786 {
00787   // Create an empty 3D-histogram with appropriate scale and labels for this variable (x)
00788   // and the specified y,z variables. This method uses the default plot ranges for x,y,z which
00789   // can be changed using the setPlotMin(),setPlotMax() methods, and the default binning which
00790   // can be changed with setPlotBins(). The caller takes ownership of the returned object
00791   // and is responsible for deleting it.
00792 
00793   if ((!xlo && xhi) || (xlo && !xhi)) {
00794     coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName() 
00795                           << ") ERROR must specify either no range, or both limits" << endl ;
00796     return 0 ;
00797   }
00798 
00799   Double_t xlo_fit[3] ;
00800   Double_t xhi_fit[3] ;
00801   Int_t nbins_fit[3] ;
00802 
00803   Double_t *xlo2 = xlo;
00804   Double_t *xhi2 = xhi;
00805   Int_t* nBins2 = nBins;
00806   if (!xlo2) {
00807 
00808     if (!fitRangeOKForPlotting()) {
00809       coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName() 
00810                             << ") ERROR: fit range empty or open ended, must explicitly specify range" << endl ;      
00811       return 0 ;
00812     }
00813     if (!yvar.fitRangeOKForPlotting()) {
00814       coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName() 
00815                             << ") ERROR: fit range of " << yvar.GetName() << " empty or open ended, must explicitly specify range" << endl ;      
00816       return 0 ;
00817     }
00818     if (!zvar.fitRangeOKForPlotting()) {
00819       coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName() 
00820                             << ") ERROR: fit range of " << zvar.GetName() << " empty or open ended, must explicitly specify range" << endl ;      
00821       return 0 ;
00822     }
00823 
00824     xlo_fit[0] = getMin() ;
00825     xhi_fit[0] = getMax() ;    
00826 
00827     xlo_fit[1] = yvar.getMin() ;
00828     xhi_fit[1] = yvar.getMax() ;
00829 
00830     xlo_fit[2] = zvar.getMin() ;
00831     xhi_fit[2] = zvar.getMax() ;
00832 
00833     xlo2 = xlo_fit ;
00834     xhi2 = xhi_fit ;
00835   }
00836   
00837   if (!nBins2) {
00838     nbins_fit[0] = getBins() ;
00839     nbins_fit[1] = yvar.getBins() ;
00840     nbins_fit[2] = zvar.getBins() ;
00841     nBins2 = nbins_fit ;
00842   }
00843 
00844   RooArgList list(*this,yvar,zvar) ;
00845   return (TH3F*)createHistogram(name, list, tAxisLabel, xlo2, xhi2, nBins2);
00846 }
00847 
00848 
00849 TH3F *RooAbsRealLValue::createHistogram(const char *name, const RooAbsRealLValue &yvar, const RooAbsRealLValue &zvar, 
00850                                         const char* tAxisLabel, const RooAbsBinning** bins) const 
00851 {
00852   // Create an empty 3D-histogram with appropriate scale and labels for this variable (x)
00853   // and the specified y,z variables. 
00854 
00855   RooArgList list(*this,yvar,zvar) ;
00856   return (TH3F*)createHistogram(name, list, tAxisLabel, bins);
00857 }
00858 
00859 
00860 
00861 
00862 //_____________________________________________________________________________
00863 TH1 *RooAbsRealLValue::createHistogram(const char *name, RooArgList &vars, const char *tAxisLabel, 
00864                                        Double_t* xlo, Double_t* xhi, Int_t* nBins)
00865 {
00866   // Create 1-, 2- or 3-d ROOT histogram with labels taken
00867   // from the variables in 'vars' and the with range and binning
00868   // specified in xlo,xhi and nBins. The dimensions of the arrays xlo,xhi,
00869   // nBins should match the number of objects in vars.
00870 
00871   const RooAbsBinning* bin[3] ;
00872   Int_t ndim = vars.getSize() ;
00873   bin[0] = new RooUniformBinning(xlo[0],xhi[0],nBins[0]) ;
00874   bin[1] = (ndim>1) ? new RooUniformBinning(xlo[1],xhi[1],nBins[1]) : 0 ;
00875   bin[2] = (ndim>2) ? new RooUniformBinning(xlo[2],xhi[2],nBins[2]) : 0 ;
00876 
00877   TH1* ret = createHistogram(name,vars,tAxisLabel,bin) ;
00878 
00879   if (bin[0]) delete bin[0] ;
00880   if (bin[1]) delete bin[1] ;
00881   if (bin[2]) delete bin[2] ;
00882   return ret ;  
00883 }
00884 
00885 
00886 
00887 //_____________________________________________________________________________
00888 TH1 *RooAbsRealLValue::createHistogram(const char *name, RooArgList &vars, const char *tAxisLabel, const RooAbsBinning** bins) 
00889 {
00890   // Create a 1,2, or 3D-histogram with appropriate scale and labels.
00891   // Binning and ranges are taken from the variables themselves and can be changed by
00892   // calling their setPlotMin/Max() and setPlotBins() methods. A histogram can be filled
00893   // using RooAbsReal::fillHistogram() or RooTreeData::fillHistogram().
00894   // The caller takes ownership of the returned object and is responsible for deleting it.
00895 
00896   // Check that we have 1-3 vars
00897   Int_t dim= vars.getSize();
00898   if(dim < 1 || dim > 3) {
00899     oocoutE((TObject*)0,InputArguments) << "RooAbsReal::createHistogram: dimension not supported: " << dim << endl;
00900     return 0;
00901   }
00902 
00903   // Check that all variables are AbsReals and prepare a name of the form <name>_<var1>_...
00904   TString histName(name);
00905   histName.Append("_");
00906   const RooAbsRealLValue *xyz[3];
00907 
00908   Int_t index;
00909   for(index= 0; index < dim; index++) {
00910     const RooAbsArg *arg= vars.at(index);
00911     xyz[index]= dynamic_cast<const RooAbsRealLValue*>(arg);
00912     if(!xyz[index]) {
00913       oocoutE((TObject*)0,InputArguments) << "RooAbsRealLValue::createHistogram: variable is not real lvalue: " << arg->GetName() << endl;
00914       return 0;
00915     }
00916     histName.Append("_");
00917     histName.Append(arg->GetName());
00918   }
00919   TString histTitle(histName);
00920   histTitle.Prepend("Histogram of ");
00921 
00922   // Create the histogram
00923   TH1 *histogram = 0;
00924   switch(dim) {
00925   case 1:
00926     if (bins[0]->isUniform()) {
00927       histogram= new TH1F(histName.Data(), histTitle.Data(),
00928                           bins[0]->numBins(),bins[0]->lowBound(),bins[0]->highBound());
00929     } else {
00930       histogram= new TH1F(histName.Data(), histTitle.Data(),
00931                           bins[0]->numBins(),bins[0]->array());
00932     }
00933     break;
00934   case 2:
00935     if (bins[0]->isUniform() && bins[1]->isUniform()) {
00936       histogram= new TH2F(histName.Data(), histTitle.Data(),
00937                           bins[0]->numBins(),bins[0]->lowBound(),bins[0]->highBound(),
00938                           bins[1]->numBins(),bins[1]->lowBound(),bins[1]->highBound());
00939     } else {
00940       histogram= new TH2F(histName.Data(), histTitle.Data(),
00941                           bins[0]->numBins(),bins[0]->array(),
00942                           bins[1]->numBins(),bins[1]->array());
00943     }
00944     break;
00945   case 3:
00946     if (bins[0]->isUniform() && bins[1]->isUniform() && bins[2]->isUniform()) {
00947       histogram= new TH3F(histName.Data(), histTitle.Data(),
00948                           bins[0]->numBins(),bins[0]->lowBound(),bins[0]->highBound(),
00949                           bins[1]->numBins(),bins[1]->lowBound(),bins[1]->highBound(),
00950                           bins[2]->numBins(),bins[2]->lowBound(),bins[2]->highBound()) ;
00951     } else {
00952       histogram= new TH3F(histName.Data(), histTitle.Data(),
00953                           bins[0]->numBins(),bins[0]->array(),
00954                           bins[1]->numBins(),bins[1]->array(),
00955                           bins[2]->numBins(),bins[2]->array()) ;
00956     }
00957     break;
00958   }
00959   if(!histogram) {
00960     oocoutE((TObject*)0,InputArguments) << "RooAbsReal::createHistogram: unable to create a new histogram" << endl;
00961     return 0;
00962   }
00963 
00964   // Set the histogram coordinate axis labels from the titles of each variable, adding units if necessary.
00965   for(index= 0; index < dim; index++) {
00966     TString axisTitle(xyz[index]->getTitle(kTRUE));
00967     switch(index) {
00968     case 0:
00969       histogram->SetXTitle(axisTitle.Data());
00970       break;
00971     case 1:
00972       histogram->SetYTitle(axisTitle.Data());
00973       break;
00974     case 2:
00975       histogram->SetZTitle(axisTitle.Data());
00976       break;
00977     default:
00978       assert(0);
00979       break;
00980     }
00981   }
00982 
00983   // Set the t-axis title if given one
00984   if((0 != tAxisLabel) && (0 != strlen(tAxisLabel))) {
00985     TString axisTitle(tAxisLabel);
00986     axisTitle.Append(" / ( ");
00987     for(Int_t index2= 0; index2 < dim; index2++) {
00988       Double_t delta= bins[index2]->averageBinWidth() ; // xyz[index2]->getBins();
00989       if(index2 > 0) axisTitle.Append(" x ");
00990       axisTitle.Append(Form("%g",delta));
00991       if(strlen(xyz[index2]->getUnit())) {
00992         axisTitle.Append(" ");
00993         axisTitle.Append(xyz[index2]->getUnit());
00994       }
00995     }
00996     axisTitle.Append(" )");
00997     switch(dim) {
00998     case 1:
00999       histogram->SetYTitle(axisTitle.Data());
01000       break;
01001     case 2:
01002       histogram->SetZTitle(axisTitle.Data());
01003       break;
01004     case 3:
01005       // not supported in TH1
01006       break;
01007     default:
01008       assert(0);
01009       break;
01010     }
01011   }
01012 
01013   return histogram;
01014 }
01015 
01016 
01017 Bool_t RooAbsRealLValue::isJacobianOK(const RooArgSet&) const 
01018 { 
01019   // Interface function to indicate that this lvalue
01020   // has a unit or constant jacobian terms with respect to
01021   // the observable passed as argument. This default implementation
01022   // always returns true (i.e. jacobian is constant)
01023   return kTRUE ; 
01024 }

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