RooRealVar.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooRealVar.cxx 36848 2010-11-22 16:21:09Z 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 // RooRealVar represents a fundamental (non-derived) real valued object
00021 // 
00022 // This class also holds an (asymmetic) error, a default range and
00023 // a optionally series of alternate named ranges.
00024 // END_HTML
00025 //
00026 
00027 
00028 #include "RooFit.h"
00029 #include "Riostream.h"
00030 
00031 #include <math.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <ctype.h>
00035 #include <iomanip>
00036 #include "TObjString.h"
00037 #include "TTree.h"
00038 #include "RooRealVar.h"
00039 #include "RooStreamParser.h"
00040 #include "RooErrorVar.h"
00041 #include "RooRangeBinning.h"
00042 #include "RooCmdConfig.h"
00043 #include "RooMsgService.h"
00044 #include "RooParamBinning.h"
00045 
00046 
00047 ClassImp(RooRealVar)
00048 ;
00049 
00050 Bool_t RooRealVar::_printScientific(kFALSE) ;
00051 Int_t  RooRealVar::_printSigDigits(5) ;
00052 RooSharedPropertiesList RooRealVar::_sharedPropList ;
00053 RooRealVarSharedProperties RooRealVar::_nullProp("00000000-0000-0000-0000-000000000000") ;
00054 
00055 
00056 //_____________________________________________________________________________
00057 RooRealVar::RooRealVar()  :  _error(0), _asymErrLo(0), _asymErrHi(0), _binning(0), _sharedProp(0)
00058 {  
00059   // Default constructor
00060 }
00061 
00062 
00063 //_____________________________________________________________________________
00064 RooRealVar::RooRealVar(const char *name, const char *title,
00065                        Double_t value, const char *unit) :
00066   RooAbsRealLValue(name, title, unit), _error(-1), _asymErrLo(1), _asymErrHi(-1), _sharedProp(0)
00067 {
00068   // Constructor with value and unit
00069 
00070   // _instanceList.registerInstance(this) ;
00071   _binning = new RooUniformBinning(-1,1,100) ;
00072   _value = value ;
00073   removeRange();
00074   setConstant(kTRUE) ;
00075 }  
00076 
00077 
00078 //_____________________________________________________________________________
00079 RooRealVar::RooRealVar(const char *name, const char *title,
00080                        Double_t minValue, Double_t maxValue,
00081                        const char *unit) :
00082   RooAbsRealLValue(name, title, unit), _error(-1), _asymErrLo(1), _asymErrHi(-1), _sharedProp(0)
00083 {
00084   // Constructor with range and unit. Initial value is center of range
00085 
00086   _binning = new RooUniformBinning(minValue,maxValue,100) ;
00087 
00088   if (RooNumber::isInfinite(minValue)) {
00089     if (RooNumber::isInfinite(maxValue)) {
00090       // [-inf,inf]
00091       _value = 0 ;
00092     } else {
00093       // [-inf,X]
00094       _value= maxValue ;
00095     }
00096   } else {
00097     if (RooNumber::isInfinite(maxValue)) {
00098       // [X,inf]
00099       _value = minValue ;
00100     } else {
00101       // [X,X]
00102       _value= 0.5*(minValue + maxValue);
00103     }
00104   }
00105 
00106   //   setPlotRange(minValue,maxValue) ;
00107   setRange(minValue,maxValue) ;
00108 }  
00109 
00110 
00111 //_____________________________________________________________________________
00112 RooRealVar::RooRealVar(const char *name, const char *title,
00113                        Double_t value, Double_t minValue, Double_t maxValue,
00114                        const char *unit) :
00115   RooAbsRealLValue(name, title, unit), _error(-1), _asymErrLo(1), _asymErrHi(-1), _sharedProp(0)
00116 {
00117   // Constructor with value, range and unit
00118 
00119   _value = value ;
00120 
00121   _binning = new RooUniformBinning(minValue,maxValue,100) ;
00122   setRange(minValue,maxValue) ;
00123 }  
00124 
00125 
00126 //_____________________________________________________________________________
00127 RooRealVar::RooRealVar(const RooRealVar& other, const char* name) :
00128   RooAbsRealLValue(other,name), 
00129   _error(other._error),
00130   _asymErrLo(other._asymErrLo),
00131   _asymErrHi(other._asymErrHi)
00132 {
00133   // Copy Constructor
00134 
00135   _sharedProp =  (RooRealVarSharedProperties*) _sharedPropList.registerProperties(other.sharedProp()) ;
00136   _binning = other._binning->clone() ;
00137   _binning->insertHook(*this) ;
00138 
00139   //cout << "RooRealVar::cctor(this = " << this << " name = " << GetName() << ", other = " << &other << ")" << endl ;
00140   
00141   RooAbsBinning* ab ;
00142   TIterator* iter = other._altNonSharedBinning.MakeIterator() ;
00143   while((ab=(RooAbsBinning*)iter->Next())) {
00144     RooAbsBinning* abc = ab->clone() ;
00145     //cout << "cloning binning " << ab << " into " << abc << endl ;
00146     _altNonSharedBinning.Add(abc) ;
00147     abc->insertHook(*this) ;
00148   }
00149   delete iter ;
00150   
00151   
00152 }
00153 
00154 
00155 
00156 //_____________________________________________________________________________
00157 RooRealVar::~RooRealVar() 
00158 {
00159   // Destructor
00160 
00161   delete _binning ;
00162   _altNonSharedBinning.Delete() ;
00163 
00164   if (_sharedProp) {
00165     _sharedPropList.unregisterProperties(_sharedProp) ;
00166   }
00167 }
00168 
00169 
00170 //_____________________________________________________________________________
00171 Double_t RooRealVar::getVal(const RooArgSet*) const 
00172 { 
00173   // Return value of variable
00174 
00175   return _value ; 
00176 }
00177 
00178 
00179 
00180 //_____________________________________________________________________________
00181 void RooRealVar::setVal(Double_t value) 
00182 {
00183   // Set value of variable to 'value'. If 'value' is outside
00184   // range of object, clip value into range
00185 
00186   Double_t clipValue ;
00187   inRange(value,0,&clipValue) ;
00188 
00189   if (clipValue != _value) {
00190     setValueDirty() ;
00191     _value = clipValue;
00192   }
00193 }
00194 
00195 
00196 
00197 //_____________________________________________________________________________
00198 void RooRealVar::setVal(Double_t value, const char* rangeName) 
00199 {
00200   // Set value of variable to 'value'. If 'value' is outside
00201   // range named 'rangeName' of object, clip value into that range
00202 
00203   Double_t clipValue ;
00204   inRange(value,rangeName,&clipValue) ;
00205 
00206   if (clipValue != _value) {
00207     setValueDirty() ;
00208     _value = clipValue;
00209   }
00210 }
00211 
00212 
00213 
00214 //_____________________________________________________________________________
00215 RooErrorVar* RooRealVar::errorVar() const 
00216 {
00217   // Return a RooAbsRealLValue representing the error associated
00218   // with this variable. The callers takes ownership of the
00219   // return object
00220 
00221   TString name(GetName()), title(GetTitle()) ;
00222   name.Append("err") ;
00223   title.Append(" Error") ;
00224 
00225   return new RooErrorVar(name,title,*this) ;
00226 }
00227 
00228 
00229 
00230 //_____________________________________________________________________________
00231 Bool_t RooRealVar::hasBinning(const char* name) const
00232 {
00233   // Returns true if variable has a binning with 'name'
00234 
00235   return sharedProp()->_altBinning.FindObject(name) ? kTRUE : kFALSE ;
00236 }
00237 
00238 
00239 
00240 //_____________________________________________________________________________
00241 const RooAbsBinning& RooRealVar::getBinning(const char* name, Bool_t verbose, Bool_t createOnTheFly) const 
00242 {
00243   // Return binning definition with name. If binning with 'name' is not found it is created
00244   // on the fly as a clone of the default binning if createOnTheFly is true, otherwise
00245   // a reference to the default binning is returned. If verbose is true a message
00246   // is printed if a binning is created on the gly
00247 
00248   return const_cast<RooRealVar*>(this)->getBinning(name, verbose, createOnTheFly) ;
00249 }
00250 
00251 
00252 
00253 //_____________________________________________________________________________
00254 RooAbsBinning& RooRealVar::getBinning(const char* name, Bool_t verbose, Bool_t createOnTheFly) 
00255 {
00256   // Return binning definition with name. If binning with 'name' is not found it is created
00257   // on the fly as a clone of the default binning if createOnTheFly is true, otherwise
00258   // a reference to the default binning is returned. If verbose is true a message
00259   // is printed if a binning is created on the gly
00260 
00261   // Return default (normalization) binning and range if no name is specified
00262   if (name==0) {
00263     return *_binning ;
00264   }
00265   
00266   // Check if non-shared binning with this name has been created already
00267   RooAbsBinning* binning = (RooAbsBinning*) _altNonSharedBinning.FindObject(name) ;
00268   if (binning) {
00269     return *binning ;
00270   }
00271 
00272   // Check if binning with this name has been created already
00273   binning = (RooAbsBinning*) (sharedProp()->_altBinning).FindObject(name) ;
00274   if (binning) {
00275     return *binning ;
00276   }
00277 
00278 
00279   // Return default binning if requested binning doesn't exist
00280   if (!createOnTheFly) {
00281     return *_binning ;
00282   }  
00283 
00284   // Create a new RooRangeBinning with this name with default range
00285   binning = new RooRangeBinning(getMin(),getMax(),name) ;
00286   if (verbose) {
00287     coutI(Eval) << "RooRealVar::getBinning(" << GetName() << ") new range named '" 
00288                 << name << "' created with default bounds" << endl ;
00289   }
00290   sharedProp()->_altBinning.Add(binning) ;
00291   
00292   return *binning ;
00293 }
00294 
00295 
00296 
00297 //_____________________________________________________________________________
00298 void RooRealVar::setBinning(const RooAbsBinning& binning, const char* name) 
00299 {
00300   // Add given binning under name 'name' with this variable. If name is null
00301   // the binning is installed as the default binning
00302 
00303   // Process insert hooks required for parameterized binnings
00304   if (!name) {
00305     RooAbsBinning* newBinning = binning.clone() ;
00306     if (_binning) {
00307       _binning->removeHook(*this) ;
00308       delete _binning ;
00309     }
00310     newBinning->insertHook(*this) ;
00311     _binning = newBinning ;
00312   } else {
00313 
00314     RooLinkedList* altBinning = binning.isShareable() ? &(sharedProp()->_altBinning) : &_altNonSharedBinning ;
00315 
00316     RooAbsBinning* newBinning = binning.clone() ;
00317 
00318     // Remove any old binning with this name
00319     RooAbsBinning* oldBinning = (RooAbsBinning*) altBinning->FindObject(name) ;
00320     if (oldBinning) {
00321       altBinning->Remove(oldBinning) ;
00322       oldBinning->removeHook(*this) ;
00323       delete oldBinning ;
00324     }
00325 
00326     // Insert new binning in list of alternative binnings
00327     newBinning->SetName(name) ;
00328     newBinning->SetTitle(name) ;
00329     newBinning->insertHook(*this) ;
00330     altBinning->Add(newBinning) ;
00331     
00332   }
00333   
00334 
00335 }
00336 
00337 
00338 
00339 //_____________________________________________________________________________
00340 void RooRealVar::setMin(const char* name, Double_t value) 
00341 {
00342   // Set minimum of name range to given value. If name is null
00343   // minimum of default range is set
00344 
00345   // Set new minimum of fit range 
00346   RooAbsBinning& binning = getBinning(name,kTRUE,kTRUE) ;
00347 
00348   // Check if new limit is consistent
00349   if (value >= getMax()) {
00350     coutW(InputArguments) << "RooRealVar::setMin(" << GetName() 
00351                           << "): Proposed new fit min. larger than max., setting min. to max." << endl ;
00352     binning.setMin(getMax()) ;
00353   } else {
00354     binning.setMin(value) ;
00355   }
00356 
00357   // Clip current value in window if it fell out
00358   if (!name) {
00359     Double_t clipValue ;
00360     if (!inRange(_value,0,&clipValue)) {
00361       setVal(clipValue) ;
00362     }
00363   }
00364     
00365   setShapeDirty() ;
00366 }
00367 
00368 
00369 //_____________________________________________________________________________
00370 void RooRealVar::setMax(const char* name, Double_t value)
00371 {
00372   // Set maximum of name range to given value. If name is null
00373   // maximum of default range is set
00374 
00375   // Set new maximum of fit range 
00376   RooAbsBinning& binning = getBinning(name,kTRUE,kTRUE) ;
00377 
00378   // Check if new limit is consistent
00379   if (value < getMin()) {
00380     coutW(InputArguments) << "RooRealVar::setMax(" << GetName() 
00381                           << "): Proposed new fit max. smaller than min., setting max. to min." << endl ;
00382     binning.setMax(getMin()) ;
00383   } else {
00384     binning.setMax(value) ;
00385   }
00386 
00387   // Clip current value in window if it fell out
00388   if (!name) {
00389     Double_t clipValue ;
00390     if (!inRange(_value,0,&clipValue)) {
00391       setVal(clipValue) ;
00392     }
00393   }
00394 
00395   setShapeDirty() ;
00396 }
00397 
00398 
00399 //_____________________________________________________________________________
00400 void RooRealVar::setRange(const char* name, Double_t min, Double_t max) 
00401 {
00402   // Set range named 'name to [min,max]. If name is null
00403   // range of default range is adjusted. If no range with
00404   // 'name' exists it is created on the fly
00405 
00406   Bool_t exists = name ? (sharedProp()->_altBinning.FindObject(name)?kTRUE:kFALSE) : kTRUE ;
00407 
00408   // Set new fit range 
00409   RooAbsBinning& binning = getBinning(name,kFALSE,kTRUE) ;
00410 
00411   // Check if new limit is consistent
00412   if (min>max) {
00413     coutW(InputArguments) << "RooRealVar::setRange(" << GetName() 
00414                           << "): Proposed new fit max. smaller than min., setting max. to min." << endl ;
00415     binning.setRange(min,min) ;
00416   } else {
00417     binning.setRange(min,max) ;
00418   }
00419 
00420   if (!exists) {
00421     coutI(Eval) << "RooRealVar::setRange(" << GetName() 
00422                 << ") new range named '" << name << "' created with bounds [" 
00423                 << min << "," << max << "]" << endl ;
00424   }
00425 
00426   setShapeDirty() ;  
00427 }
00428 
00429 
00430 
00431 //_____________________________________________________________________________
00432 void RooRealVar::setRange(const char* name, RooAbsReal& min, RooAbsReal& max) 
00433 {
00434   // Create or modify a parameterized range named 'name' that has external functions
00435   // min and max parameterizing its boundaries.
00436 
00437   RooParamBinning pb(min,max,100) ;
00438   setBinning(pb,name) ;
00439 }
00440 
00441 
00442 
00443 //_____________________________________________________________________________
00444 Bool_t RooRealVar::readFromStream(istream& is, Bool_t compact, Bool_t verbose) 
00445 {
00446   // Read object contents from given stream
00447 
00448   TString token,errorPrefix("RooRealVar::readFromStream(") ;
00449   errorPrefix.Append(GetName()) ;
00450   errorPrefix.Append(")") ;
00451   RooStreamParser parser(is,errorPrefix) ;
00452   Double_t value(0) ;
00453 
00454   if (compact) {
00455     // Compact mode: Read single token
00456     if (parser.readDouble(value,verbose)) return kTRUE ;
00457     if (isValidReal(value,verbose)) {
00458       setVal(value) ;
00459       return kFALSE ;
00460     } else {
00461       return kTRUE ;
00462     }
00463 
00464   } else {
00465     // Extended mode: Read multiple tokens on a single line   
00466     Bool_t haveValue(kFALSE) ;
00467     Bool_t haveConstant(kFALSE) ;
00468     removeError() ;
00469     removeAsymError() ;
00470 
00471     Bool_t reprocessToken = kFALSE ;
00472     while(1) {      
00473       if (parser.atEOL() || parser.atEOF()) break ;
00474 
00475       if (!reprocessToken) {
00476         token=parser.readToken() ;
00477       }
00478       reprocessToken = kFALSE ;
00479 
00480       if (!token.CompareTo("+")) {
00481         
00482         // Expect +/- as 3-token sequence
00483         if (parser.expectToken("/",kTRUE) ||
00484             parser.expectToken("-",kTRUE)) {
00485           break ;
00486         }
00487 
00488         // Next token is error or asymmetric error, check if first char of token is a '('
00489         TString tmp = parser.readToken() ;
00490         if (tmp.CompareTo("(")) {
00491           // Symmetric error, convert token do double
00492 
00493           Double_t error ;
00494           parser.convertToDouble(tmp,error) ;
00495           setError(error) ;
00496 
00497         } else {
00498           // Have error
00499           Double_t asymErrLo, asymErrHi ;
00500           if (parser.readDouble(asymErrLo,kTRUE) ||
00501               parser.expectToken(",",kTRUE) || 
00502               parser.readDouble(asymErrHi,kTRUE) ||
00503               parser.expectToken(")",kTRUE)) break ;                  
00504           setAsymError(asymErrLo,asymErrHi) ;
00505         }
00506 
00507       } else if (!token.CompareTo("C")) {
00508 
00509         // Set constant
00510         setConstant(kTRUE) ;
00511         haveConstant = kTRUE ;
00512 
00513       } else if (!token.CompareTo("P")) {
00514 
00515         // Next tokens are plot limits
00516         Double_t plotMin(0), plotMax(0) ;
00517         Int_t plotBins(0) ;
00518         if (parser.expectToken("(",kTRUE) ||
00519             parser.readDouble(plotMin,kTRUE) ||
00520             parser.expectToken("-",kTRUE) ||
00521             parser.readDouble(plotMax,kTRUE) ||
00522             parser.expectToken(":",kTRUE) ||
00523             parser.readInteger(plotBins,kTRUE) || 
00524             parser.expectToken(")",kTRUE)) break ;
00525 //      setPlotRange(plotMin,plotMax) ;
00526         coutW(Eval) << "RooRealVar::readFromStrem(" << GetName() 
00527              << ") WARNING: plot range deprecated, removed P(...) token" << endl ;
00528 
00529       } else if (!token.CompareTo("F")) {
00530 
00531         // Next tokens are fit limits
00532         Double_t fitMin, fitMax ;
00533         Int_t fitBins ;
00534         if (parser.expectToken("(",kTRUE) ||
00535             parser.readDouble(fitMin,kTRUE) ||
00536             parser.expectToken("-",kTRUE) ||
00537             parser.readDouble(fitMax,kTRUE) ||
00538             parser.expectToken(":",kTRUE) ||
00539             parser.readInteger(fitBins,kTRUE) ||
00540             parser.expectToken(")",kTRUE)) break ;
00541         //setBins(fitBins) ;
00542         //setRange(fitMin,fitMax) ;
00543         coutW(Eval) << "RooRealVar::readFromStream(" << GetName() 
00544              << ") WARNING: F(lo-hi:bins) token deprecated, use L(lo-hi) B(bins)" << endl ;     
00545         if (!haveConstant) setConstant(kFALSE) ;
00546 
00547       } else if (!token.CompareTo("L")) {
00548 
00549         // Next tokens are fit limits
00550         Double_t fitMin, fitMax ;
00551 //      Int_t fitBins ;
00552         if (parser.expectToken("(",kTRUE) ||
00553             parser.readDouble(fitMin,kTRUE) ||
00554             parser.expectToken("-",kTRUE) ||
00555             parser.readDouble(fitMax,kTRUE) ||
00556             parser.expectToken(")",kTRUE)) break ;
00557         setRange(fitMin,fitMax) ;
00558         if (!haveConstant) setConstant(kFALSE) ;
00559 
00560       } else if (!token.CompareTo("B")) { 
00561 
00562         // Next tokens are fit limits
00563         Int_t fitBins ;
00564         if (parser.expectToken("(",kTRUE) ||
00565             parser.readInteger(fitBins,kTRUE) ||
00566             parser.expectToken(")",kTRUE)) break ;
00567         setBins(fitBins) ;
00568         
00569       } else {
00570         // Token is value
00571         if (parser.convertToDouble(token,value)) { parser.zapToEnd() ; break ; }
00572         haveValue = kTRUE ;
00573         // Defer value assignment to end
00574       }
00575     }    
00576     if (haveValue) setVal(value) ;
00577     return kFALSE ;
00578   }
00579 }
00580 
00581 
00582 //_____________________________________________________________________________
00583 void RooRealVar::writeToStream(ostream& os, Bool_t compact) const
00584 {
00585   // Write object contents to given stream
00586 
00587   if (compact) {
00588     // Write value only
00589     os << getVal() ;
00590   } else {    
00591 
00592     // Write value with error (if not zero)    
00593     if (_printScientific) {
00594       char fmtVal[16], fmtErr[16] ;
00595       snprintf(fmtVal,16,"%%.%de",_printSigDigits) ;
00596       snprintf(fmtErr,16,"%%.%de",(_printSigDigits+1)/2) ;
00597       if (_value>=0) os << " " ;
00598       os << Form(fmtVal,_value) ;
00599 
00600       if (hasAsymError()) {
00601         os << " +/- (" << Form(fmtErr,getAsymErrorLo())
00602            << ", " << Form(fmtErr,getAsymErrorHi()) << ")" ;
00603       } else  if (hasError()) {
00604         os << " +/- " << Form(fmtErr,getError()) ;
00605       } 
00606 
00607       os << " " ;
00608     } else {
00609       TString* tmp = format(_printSigDigits,"EFA") ;
00610       os << tmp->Data() << " " ;
00611       delete tmp ;
00612     }
00613 
00614     // Append limits if not constants
00615     if (isConstant()) {
00616       os << "C " ;
00617     }      
00618 
00619     // Append fit limits
00620     os << "L(" ;
00621     if(hasMin()) {
00622       os << getMin();
00623     }
00624     else {
00625       os << "-INF";
00626     }
00627     if(hasMax()) {
00628       os << " - " << getMax() ;
00629     }
00630     else {
00631       os << " - +INF";
00632     }
00633     os << ") " ;
00634 
00635     if (getBins()!=100) {
00636       os << "B(" << getBins() << ") " ;
00637     }
00638 
00639     // Add comment with unit, if unit exists
00640     if (!_unit.IsNull())
00641       os << "// [" << getUnit() << "]" ;
00642   }
00643 }
00644 
00645 
00646 
00647 //_____________________________________________________________________________
00648 void RooRealVar::printValue(ostream& os) const 
00649 {
00650   // Print value of variable
00651   os << getVal() ;
00652 
00653   if(hasError() && !hasAsymError()) {
00654     os << " +/- " << getError() ;
00655   } else if (hasAsymError()) {
00656     os << " +/- (" << getAsymErrorLo() << "," << getAsymErrorHi() << ")" ;
00657   }
00658 
00659 
00660 }
00661 
00662 
00663 //_____________________________________________________________________________
00664 void RooRealVar::printExtras(ostream& os) const
00665 {
00666   // Print extras of variable: (asymmetric) error, constant flag, limits and binning
00667 
00668   // Append limits if not constants
00669   if (isConstant()) {
00670     os << "C " ;
00671   }      
00672 
00673   // Append fit limits
00674   os << " L(" ;
00675   if(hasMin()) {
00676     os << getMin();
00677   }
00678   else {
00679     os << "-INF";
00680   }
00681   if(hasMax()) {
00682     os << " - " << getMax() ;
00683   }
00684   else {
00685     os << " - +INF";
00686   }
00687   os << ") " ;
00688   
00689   if (getBins()!=100) {
00690     os << "B(" << getBins() << ") " ;
00691   }
00692   
00693   // Add comment with unit, if unit exists
00694   if (!_unit.IsNull())
00695     os << "// [" << getUnit() << "]" ;
00696   
00697 }
00698 
00699 
00700 //_____________________________________________________________________________
00701 Int_t RooRealVar::defaultPrintContents(Option_t* opt) const 
00702 {
00703   // Mapping of Print() option string to RooPrintable contents specifications
00704 
00705   if (opt && TString(opt)=="I") {
00706     return kName|kClassName|kValue ;
00707   }
00708   return kName|kClassName|kValue|kExtras ;
00709 }
00710 
00711 
00712 //_____________________________________________________________________________
00713 void RooRealVar::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
00714 {
00715   // Detailed printing interface
00716 
00717   RooAbsRealLValue::printMultiline(os,contents,verbose,indent);
00718   os << indent << "--- RooRealVar ---" << endl;
00719   TString unit(_unit);
00720   if(!unit.IsNull()) unit.Prepend(' ');
00721   os << indent << "  Error = " << getError() << unit << endl;
00722 }
00723 
00724 
00725 
00726 //_____________________________________________________________________________
00727 TString* RooRealVar::format(const RooCmdArg& formatArg) const 
00728 {
00729   // Format contents of RooRealVar for pretty printing on RooPlot
00730   // parameter boxes. This function processes the named arguments
00731   // taken by paramOn() and translates them to an option string
00732   // parsed by RooRealVar::format(Int_t sigDigits, const char *options) 
00733 
00734   RooCmdArg tmp(formatArg) ;
00735   tmp.setProcessRecArgs(kTRUE) ;
00736 
00737   RooCmdConfig pc(Form("RooRealVar::format(%s)",GetName())) ;
00738   pc.defineString("what","FormatArgs",0,"") ;
00739   pc.defineInt("autop","FormatArgs::AutoPrecision",0,2) ;
00740   pc.defineInt("fixedp","FormatArgs::FixedPrecision",0,2) ;
00741   pc.defineInt("tlatex","FormatArgs::TLatexStyle",0,0) ;
00742   pc.defineInt("latex","FormatArgs::LatexStyle",0,0) ;
00743   pc.defineInt("latext","FormatArgs::LatexTableStyle",0,0) ;
00744   pc.defineInt("verbn","FormatArgs::VerbatimName",0,0) ;
00745   pc.defineMutex("FormatArgs::TLatexStyle","FormatArgs::LatexStyle","FormatArgs::LatexTableStyle") ;
00746   pc.defineMutex("FormatArgs::AutoPrecision","FormatArgs::FixedPrecision") ;
00747 
00748   // Process & check varargs 
00749   pc.process(tmp) ;
00750   if (!pc.ok(kTRUE)) {
00751     return 0 ;
00752   }
00753 
00754   // Extract values from named arguments
00755   TString options ;
00756   options = pc.getString("what") ;
00757   
00758   if (pc.getInt("tlatex")) {
00759     options += "L" ;
00760   } else if (pc.getInt("latex")) {
00761     options += "X" ;
00762   } else if (pc.getInt("latext")) {
00763     options += "Y" ;
00764   }   
00765 
00766   if (pc.getInt("verbn")) options += "V" ;
00767   Int_t sigDigits = 2 ;
00768   if (pc.hasProcessed("FormatArgs::AutoPrecision")) {
00769     options += "P" ;
00770     sigDigits = pc.getInt("autop") ;
00771   } else if (pc.hasProcessed("FormatArgs::FixedPrecision")) {
00772     options += "F" ;
00773     sigDigits = pc.getInt("fixedp") ;
00774   }
00775   
00776   return format(sigDigits,options) ;
00777 }
00778 
00779 
00780 
00781 
00782 //_____________________________________________________________________________
00783 TString *RooRealVar::format(Int_t sigDigits, const char *options) const 
00784 {
00785   // Format numeric value of RooRealVar and its error in a variety of ways
00786   //
00787   // To control what is shown use the following options
00788   // N = show name
00789   // H = hide value
00790   // E = show error
00791   // A = show asymmetric error instead of parabolic error (if available)
00792   // U = show unit
00793   //
00794   // To control how it is shown use these options
00795   // L = TLatex mode
00796   // X = Latex mode
00797   // Y = Latex table mode ( '=' replaced by '&' )
00798   // V = Make name \verbatim in Latex mode
00799   // P = use error to control shown precision
00800   // F = force fixed precision
00801   //
00802   
00803   //cout << "format = " << options << endl ;
00804 
00805   // parse the options string
00806   TString opts(options);
00807   opts.ToLower();
00808   Bool_t showName= opts.Contains("n");
00809   Bool_t hideValue= opts.Contains("h");
00810   Bool_t showError= opts.Contains("e");
00811   Bool_t showUnit= opts.Contains("u");
00812   Bool_t tlatexMode= opts.Contains("l");
00813   Bool_t latexMode= opts.Contains("x");
00814   Bool_t latexTableMode = opts.Contains("y") ;
00815   Bool_t latexVerbatimName = opts.Contains("v") ;
00816 
00817   if (latexTableMode) latexMode = kTRUE ;
00818   Bool_t asymError= opts.Contains("a") ;
00819   Bool_t useErrorForPrecision= (((showError && hasError(kFALSE) && !isConstant()) || opts.Contains("p")) && !opts.Contains("f")) ;
00820   // calculate the precision to use
00821   if(sigDigits < 1) sigDigits= 1;
00822   Int_t leadingDigitVal = 0;
00823   if (useErrorForPrecision) {    
00824     leadingDigitVal = (Int_t)floor(log10(fabs(_error+1e-10)));
00825     if (_value==0&&_error==0) leadingDigitVal=0 ;
00826   } else {
00827     leadingDigitVal = (Int_t)floor(log10(fabs(_value+1e-10)));
00828     if (_value==0) leadingDigitVal=0 ;
00829   }
00830   Int_t leadingDigitErr= (Int_t)floor(log10(fabs(_error)));
00831   Int_t whereVal= leadingDigitVal - sigDigits + 1;
00832   Int_t whereErr= leadingDigitErr - sigDigits + 1;
00833   char fmtVal[16], fmtErr[16];
00834 
00835   if (_value<0) whereVal -= 1 ;
00836   snprintf(fmtVal,16,"%%.%df", whereVal < 0 ? -whereVal : 0);
00837   snprintf(fmtErr,16,"%%.%df", whereErr < 0 ? -whereErr : 0);
00838   TString *text= new TString();
00839   if(latexMode) text->Append("$");
00840   // begin the string with "<name> = " if requested
00841   if(showName) {
00842     if (latexTableMode && latexVerbatimName) {
00843       text->Append("\\verb+") ;
00844     }
00845     text->Append(getPlotLabel());
00846     if (latexVerbatimName) text->Append("+") ;
00847 
00848     if (!latexTableMode) {
00849       text->Append(" = ");
00850     } else {
00851       text->Append(" $ & $ ");
00852     }
00853   }
00854 
00855   // Add leading space if value is positive
00856   if (_value>=0) text->Append(" ") ;
00857 
00858   // append our value if requested
00859   char buffer[256];
00860   if(!hideValue) {
00861     chopAt(_value, whereVal);
00862     snprintf(buffer, 256,fmtVal, _value);
00863     text->Append(buffer);
00864   }
00865 
00866   // append our error if requested and this variable is not constant
00867   if(hasError(kFALSE) && showError && !(asymError && hasAsymError(kFALSE))) {
00868     if(tlatexMode) {
00869       text->Append(" #pm ");
00870     }
00871     else if(latexMode) {
00872       text->Append("\\pm ");
00873     }
00874     else {
00875       text->Append(" +/- ");
00876     }
00877     snprintf(buffer, 256,fmtErr, getError());
00878     text->Append(buffer);
00879   }
00880   
00881   if (asymError && hasAsymError() && showError) {
00882     if(tlatexMode) {
00883       text->Append(" #pm ");
00884       text->Append("_{") ;      
00885       snprintf(buffer, 256,fmtErr, getAsymErrorLo());
00886       text->Append(buffer);
00887       text->Append("}^{+") ;
00888       snprintf(buffer, 256,fmtErr, getAsymErrorHi());
00889       text->Append(buffer);
00890       text->Append("}") ;
00891     }
00892     else if(latexMode) {
00893       text->Append("\\pm ");
00894       text->Append("_{") ;      
00895       snprintf(buffer, 256,fmtErr, getAsymErrorLo());
00896       text->Append(buffer);
00897       text->Append("}^{+") ;
00898       snprintf(buffer, 256,fmtErr, getAsymErrorHi());
00899       text->Append(buffer);
00900       text->Append("}") ;
00901     }
00902     else {
00903       text->Append(" +/- ");
00904       text->Append(" (") ;      
00905       snprintf(buffer, 256, fmtErr, getAsymErrorLo());
00906       text->Append(buffer);
00907       text->Append(", ") ;
00908       snprintf(buffer, 256, fmtErr, getAsymErrorHi());
00909       text->Append(buffer);
00910       text->Append(")") ;
00911     }
00912 
00913   }
00914 
00915   // append our units if requested
00916   if(!_unit.IsNull() && showUnit) {
00917     text->Append(' ');
00918     text->Append(_unit);
00919   }
00920   if(latexMode) text->Append("$");
00921   return text;
00922 }
00923 
00924 
00925 
00926 //_____________________________________________________________________________
00927 Double_t RooRealVar::chopAt(Double_t what, Int_t where) const 
00928 {
00929   // Utility to calculate number of decimals to show
00930   // based on magnitude of error
00931 
00932   Double_t scale= pow(10.0,where);
00933   Int_t trunc= (Int_t)floor(what/scale + 0.5);
00934   return (Double_t)trunc*scale;
00935 }
00936 
00937 
00938 
00939 //_____________________________________________________________________________
00940 void RooRealVar::attachToTree(TTree& t, Int_t bufSize)
00941 {
00942   // Overload RooAbsReal::attachToTree to also attach
00943   // branches for errors  and/or asymmetric errors
00944   // attribute StoreError and/or StoreAsymError are set
00945 
00946   // Follow usual procedure for value
00947   RooAbsReal::attachToTree(t,bufSize) ;
00948 
00949   // Attach/create additional branch for error
00950   if (getAttribute("StoreError")) {
00951     TString errName(GetName()) ;
00952     errName.Append("_err") ;
00953     TBranch* branch = t.GetBranch(errName) ;
00954     if (branch) {     
00955       t.SetBranchAddress(errName,&_error) ;
00956     } else {
00957       TString format2(errName);
00958       format2.Append("/D");
00959       t.Branch(errName, &_error, (const Text_t*)format2, bufSize);
00960     }
00961   }
00962 
00963   // Attach/create additional branches for asymmetric error
00964   if (getAttribute("StoreAsymError")) {
00965     TString loName(GetName()) ;
00966     loName.Append("_aerr_lo") ;
00967     TBranch* lobranch = t.GetBranch(loName) ;
00968     if (lobranch) {     
00969       t.SetBranchAddress(loName,&_asymErrLo) ;
00970     } else {
00971       TString format2(loName);
00972       format2.Append("/D");
00973       t.Branch(loName, &_asymErrLo, (const Text_t*)format2, bufSize);
00974     }
00975 
00976     TString hiName(GetName()) ;
00977     hiName.Append("_aerr_hi") ;
00978     TBranch* hibranch = t.GetBranch(hiName) ;
00979     if (hibranch) {     
00980       t.SetBranchAddress(hiName,&_asymErrHi) ;
00981     } else {
00982       TString format2(hiName);
00983       format2.Append("/D");
00984       t.Branch(hiName, &_asymErrHi, (const Text_t*)format2, bufSize);
00985     }
00986   }
00987 }
00988 
00989 
00990 //_____________________________________________________________________________
00991 void RooRealVar::fillTreeBranch(TTree& t) 
00992 {
00993   // Overload RooAbsReal::fillTreeBranch to also
00994   // fill tree branches with (asymmetric) errors
00995   // if requested.
00996 
00997   // First determine if branch is taken
00998   TString cleanName(cleanBranchName()) ;
00999   TBranch* valBranch = t.GetBranch(cleanName) ;
01000   if (!valBranch) { 
01001     coutE(Eval) << "RooAbsReal::fillTreeBranch(" << GetName() << ") ERROR: not attached to tree" << endl ;
01002     assert(0) ;
01003   }
01004   valBranch->Fill() ;
01005 
01006   if (getAttribute("StoreError")) {
01007     TString errName(GetName()) ;
01008     errName.Append("_err") ;
01009     TBranch* errBranch = t.GetBranch(errName) ;
01010     if (errBranch) errBranch->Fill() ;
01011   }
01012 
01013   if (getAttribute("StoreAsymError")) {
01014     TString loName(GetName()) ;
01015     loName.Append("_aerr_lo") ;
01016     TBranch* loBranch = t.GetBranch(loName) ;
01017     if (loBranch) loBranch->Fill() ;
01018 
01019     TString hiName(GetName()) ;
01020     hiName.Append("_aerr_hi") ;
01021     TBranch* hiBranch = t.GetBranch(hiName) ;
01022     if (hiBranch) hiBranch->Fill() ;
01023   }
01024 }
01025 
01026 
01027 
01028 //_____________________________________________________________________________
01029 void RooRealVar::copyCache(const RooAbsArg* source, Bool_t valueOnly) 
01030 {
01031   // Copy the cached value of another RooAbsArg to our cache
01032   // Warning: This function copies the cached values of source,
01033   //          it is the callers responsibility to make sure the cache is clean
01034 
01035   // Follow usual procedure for valueklog
01036   RooAbsReal::copyCache(source) ;
01037 
01038   if (valueOnly) return ;
01039 
01040   // Copy error too, if source has one
01041   RooRealVar* other = dynamic_cast<RooRealVar*>(const_cast<RooAbsArg*>(source)) ;
01042   if (other) {
01043     // Copy additional error value
01044     _error = other->_error ;
01045     _asymErrLo = other->_asymErrLo ;
01046     _asymErrHi = other->_asymErrHi ;
01047   }
01048 }
01049 
01050 
01051 
01052 //_____________________________________________________________________________
01053 void RooRealVar::Streamer(TBuffer &R__b)
01054 {
01055   // Stream an object of class RooRealVar.
01056 
01057   UInt_t R__s, R__c;
01058   if (R__b.IsReading()) {
01059     
01060     Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
01061     RooAbsRealLValue::Streamer(R__b);
01062     if (R__v==1) {
01063       coutI(Eval) << "RooRealVar::Streamer(" << GetName() << ") converting version 1 data format" << endl ;
01064       Double_t fitMin, fitMax ;
01065       Int_t fitBins ; 
01066       R__b >> fitMin;
01067       R__b >> fitMax;
01068       R__b >> fitBins;
01069       _binning = new RooUniformBinning(fitMin,fitMax,fitBins) ;
01070     }
01071     R__b >> _error;
01072     R__b >> _asymErrLo;
01073     R__b >> _asymErrHi;
01074     if (R__v>=2) {
01075       R__b >> _binning;
01076     }
01077     if (R__v==3) {
01078       R__b >> _sharedProp ;
01079       _sharedProp = (RooRealVarSharedProperties*) _sharedPropList.registerProperties(_sharedProp,kFALSE) ;
01080     }
01081     if (R__v>=4) {
01082       RooRealVarSharedProperties* tmpSharedProp = new RooRealVarSharedProperties() ;
01083       tmpSharedProp->Streamer(R__b) ;
01084       if (!(_nullProp==*tmpSharedProp)) {
01085         _sharedProp = (RooRealVarSharedProperties*) _sharedPropList.registerProperties(tmpSharedProp,kFALSE) ;
01086       } else {
01087         delete tmpSharedProp ;
01088         _sharedProp = 0 ;
01089       }
01090     }
01091     
01092     R__b.CheckByteCount(R__s, R__c, RooRealVar::IsA());
01093     
01094   } else {
01095     
01096     R__c = R__b.WriteVersion(RooRealVar::IsA(), kTRUE);
01097     RooAbsRealLValue::Streamer(R__b);
01098     R__b << _error;
01099     R__b << _asymErrLo;
01100     R__b << _asymErrHi;
01101     R__b << _binning;      
01102     if (_sharedProp) {
01103       _sharedProp->Streamer(R__b) ;
01104     } else {
01105       _nullProp.Streamer(R__b) ;
01106     }
01107     R__b.SetByteCount(R__c, kTRUE);      
01108     
01109   }
01110 }
01111 
01112 
01113 
01114 //_____________________________________________________________________________
01115 void RooRealVar::deleteSharedProperties()
01116 {
01117   // No longer used?
01118 
01119   if (_sharedProp) {
01120     _sharedPropList.unregisterProperties(_sharedProp) ;
01121     _sharedProp = 0 ;
01122   }  
01123 }
01124 
01125 
01126 //_____________________________________________________________________________
01127 void RooRealVar::printScientific(Bool_t flag) 
01128 { 
01129   // If true, contents of RooRealVars will be printed in scientific notation
01130 
01131   _printScientific = flag ; 
01132 }
01133 
01134 
01135 //_____________________________________________________________________________
01136 void RooRealVar::printSigDigits(Int_t ndig) 
01137 { 
01138   // Set number of digits to show when printing RooRealVars
01139 
01140   _printSigDigits = ndig>1?ndig:1 ; 
01141 }

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