/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 *    File: $Id: RooRealVar.cc,v 1.57 2005/06/20 15:44:57 wverkerke Exp $
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

// -- CLASS DESCRIPTION [REAL] --
// RooRealVar represents a fundamental (non-derived) real valued object
// 
// This class also holds an error and a fit range associated with the real value


#include "RooFit.h"

#include <math.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <iomanip>
#include "TObjString.h"
#include "TTree.h"
#include "RooRealVar.h"
#include "RooStreamParser.h"
#include "RooErrorVar.h"
#include "RooRangeBinning.h"
#include "RooCmdConfig.h"

ClassImp(RooRealVar)
;

Bool_t RooRealVar::_printScientific(kFALSE) ;
Int_t  RooRealVar::_printSigDigits(5) ;


 RooRealVar::RooRealVar() 
{
  // Default constructor
}

 RooRealVar::RooRealVar(const char *name, const char *title,
		       Double_t value, const char *unit) :
  RooAbsRealLValue(name, title, unit), _error(-1), _asymErrLo(1), _asymErrHi(-1) //, _fitBins(100)
{
  // Constructor with value and unit
  _binning = new RooUniformBinning(-1,1,100) ;
  _value = value ;
  removeRange();
  setConstant(kTRUE) ;
}  

 RooRealVar::RooRealVar(const char *name, const char *title,
		       Double_t minValue, Double_t maxValue,
		       const char *unit) :
  RooAbsRealLValue(name, title, unit), _error(-1), _asymErrLo(1), _asymErrHi(-1) // , _fitBins(100)
{
  // Constructor with range and unit. Value is set to middle of range

  _binning = new RooUniformBinning(minValue,maxValue,100) ;

  _value= 0.5*(minValue + maxValue);

//   setPlotRange(minValue,maxValue) ;
  setRange(minValue,maxValue) ;
}  

 RooRealVar::RooRealVar(const char *name, const char *title,
		       Double_t value, Double_t minValue, Double_t maxValue,
		       const char *unit) :
  RooAbsRealLValue(name, title, unit), _error(-1), _asymErrLo(1), _asymErrHi(-1)  //, _fitBins(100)
{
  // Constructor with value, range and unit
  _value = value ;

  _binning = new RooUniformBinning(minValue,maxValue,100) ;
  setRange(minValue,maxValue) ;
}  

 RooRealVar::RooRealVar(const RooRealVar& other, const char* name) :
  RooAbsRealLValue(other,name), 
  _error(other._error),
  _asymErrLo(other._asymErrLo),
  _asymErrHi(other._asymErrHi)
{
  // Copy Constructor
  _binning = other._binning->clone() ;

  TIterator* iter = other._altBinning.MakeIterator() ;
  RooAbsBinning* binning ;
  while((binning=(RooAbsBinning*)iter->Next())) {
    _altBinning.Add(binning->clone()) ;
  }
  delete iter ;
}


 RooRealVar::~RooRealVar() 
{
  // Destructor
  delete _binning ;
  _altBinning.Delete() ;
}

 Double_t RooRealVar::getVal(const RooArgSet*) const 
{ 
  return _value ; 
}


 void RooRealVar::setVal(Double_t value) {
  // Set current value
  Double_t clipValue ;
  inRange(value,&clipValue) ;

  setValueDirty() ;
  _value = clipValue;
}

 RooErrorVar* RooRealVar::errorVar() const 
{
  TString name(GetName()), title(GetTitle()) ;
  name.Append("err") ;
  title.Append(" Error") ;

  return new RooErrorVar(name,title,*this) ;
}


 Bool_t RooRealVar::hasBinning(const char* name) const
{
  return _altBinning.FindObject(name) ? kTRUE : kFALSE ;
}


 const RooAbsBinning& RooRealVar::getBinning(const char* name, Bool_t verbose, Bool_t createOnTheFly) const 
{
  return const_cast<RooRealVar*>(this)->getBinning(name, verbose, createOnTheFly) ;
}


 RooAbsBinning& RooRealVar::getBinning(const char* name, Bool_t verbose, Bool_t createOnTheFly) 
{
  // Return default (normalization) binning and range if no name is specified
  if (name==0) {
    return *_binning ;
  }
  
  // Check if binning with this name has been created already
  RooAbsBinning* binning = (RooAbsBinning*) _altBinning.FindObject(name) ;
  if (binning) {
    return *binning ;
  }

  // Return default binning if requested binning doesn't exist
  if (!createOnTheFly) {
    return *_binning ;
  }  

  // Create a new RooRangeBinning with this name with default range
  binning = new RooRangeBinning(getMin(),getMax(),name) ;
  if (verbose) {
    cout << "RooRealVar::getBinning(" << GetName() << ") new range named '" 
	 << name << "' created with default bounds" << endl ;
  }
  _altBinning.Add(binning) ;
  
  return *binning ;
}



 void RooRealVar::setBinning(const RooAbsBinning& binning, const char* name) 
{
  if (!name) {
    if (_binning) delete _binning ;
    _binning = binning.clone() ;
  } else {

    // Remove any old binning with this name
    RooAbsBinning* oldBinning = (RooAbsBinning*) _altBinning.FindObject(name) ;
    if (oldBinning) {
      _altBinning.Remove(oldBinning) ;
      delete oldBinning ;
    }

    // Insert new binning in list of alternative binnings
    RooAbsBinning* newBinning = binning.clone() ;
    newBinning->SetName(name) ;
    newBinning->SetTitle(name) ;
    _altBinning.Add(newBinning) ;

  }
  

}


 void RooRealVar::setMin(const char* name, Double_t value) 
{
  // Set new minimum of fit range 
  RooAbsBinning& binning = getBinning(name,kTRUE,kTRUE) ;

  // Check if new limit is consistent
  if (value >= getMax()) {
    cout << "RooRealVar::setMin(" << GetName() 
	 << "): Proposed new fit min. larger than max., setting min. to max." << endl ;
    binning.setMin(getMax()) ;
  } else {
    binning.setMin(value) ;
  }

  // Clip current value in window if it fell out
  if (!name) {
    Double_t clipValue ;
    if (!inRange(_value,&clipValue)) {
      setVal(clipValue) ;
    }
  }
    
  setShapeDirty() ;
}

 void RooRealVar::setMax(const char* name, Double_t value)
{
  // Set new maximum of fit range 
  RooAbsBinning& binning = getBinning(name,kTRUE,kTRUE) ;

  // Check if new limit is consistent
  if (value < getMin()) {
    cout << "RooRealVar::setMax(" << GetName() 
	 << "): Proposed new fit max. smaller than min., setting max. to min." << endl ;
    binning.setMax(getMin()) ;
  } else {
    binning.setMax(value) ;
  }

  // Clip current value in window if it fell out
  if (!name) {
    Double_t clipValue ;
    if (!inRange(_value,&clipValue)) {
      setVal(clipValue) ;
    }
  }

  setShapeDirty() ;
}

 void RooRealVar::setRange(const char* name, Double_t min, Double_t max) 
{
  Bool_t exists = name ? (_altBinning.FindObject(name)?kTRUE:kFALSE) : kTRUE ;

  // Set new fit range 
  RooAbsBinning& binning = getBinning(name,kFALSE,kTRUE) ;

  // Check if new limit is consistent
  if (min>max) {
    cout << "RooRealVar::setRange(" << GetName() 
	 << "): Proposed new fit max. smaller than min., setting max. to min." << endl ;
    binning.setRange(min,min) ;
  } else {
    binning.setRange(min,max) ;
  }

  if (!exists) {
    cout << "RooRealVar::setRange(" << GetName() 
	 << ") new range named '" << name << "' created with bounds [" 
	 << min << "," << max << "]" << endl ;
  }

  setShapeDirty() ;  
}



 Bool_t RooRealVar::readFromStream(istream& is, Bool_t compact, Bool_t verbose) 
{
  // Read object contents from given stream

  TString token,errorPrefix("RooRealVar::readFromStream(") ;
  errorPrefix.Append(GetName()) ;
  errorPrefix.Append(")") ;
  RooStreamParser parser(is,errorPrefix) ;
  Double_t value(0) ;

  if (compact) {
    // Compact mode: Read single token
    if (parser.readDouble(value,verbose)) return kTRUE ;
    if (isValidReal(value,verbose)) {
      setVal(value) ;
      return kFALSE ;
    } else {
      return kTRUE ;
    }

  } else {
    // Extended mode: Read multiple tokens on a single line   
    Bool_t haveValue(kFALSE) ;
    Bool_t haveConstant(kFALSE) ;
    removeError() ;
    removeAsymError() ;

    Bool_t reprocessToken = kFALSE ;
    while(1) {      
      if (parser.atEOL() || parser.atEOF()) break ;

      if (!reprocessToken) {
	token=parser.readToken() ;
      }
      reprocessToken = kFALSE ;

      if (!token.CompareTo("+")) {
	
	// Expect +/- as 3-token sequence
	if (parser.expectToken("/",kTRUE) ||
	    parser.expectToken("-",kTRUE)) {
	  break ;
	}

	// Next token is error or asymmetric error, check if first char of token is a '('
	TString tmp = parser.readToken() ;
	if (tmp.CompareTo("(")) {
	  // Symmetric error, convert token do double

	  Double_t error ;
	  parser.convertToDouble(tmp,error) ;
	  setError(error) ;

	} else {
	  // Have error
	  Double_t asymErrLo, asymErrHi ;
	  if (parser.readDouble(asymErrLo,kTRUE) ||
	      parser.expectToken(",",kTRUE) || 
	      parser.readDouble(asymErrHi,kTRUE) ||
	      parser.expectToken(")",kTRUE)) break ;		      
	  setAsymError(asymErrLo,asymErrHi) ;
	}

      } else if (!token.CompareTo("C")) {

	// Set constant
	setConstant(kTRUE) ;
	haveConstant = kTRUE ;

      } else if (!token.CompareTo("P")) {

	// Next tokens are plot limits
	Double_t plotMin(0), plotMax(0) ;
        Int_t plotBins(0) ;
	if (parser.expectToken("(",kTRUE) ||
	    parser.readDouble(plotMin,kTRUE) ||
	    parser.expectToken("-",kTRUE) ||
	    parser.readDouble(plotMax,kTRUE) ||
            parser.expectToken(":",kTRUE) ||
            parser.readInteger(plotBins,kTRUE) || 
	    parser.expectToken(")",kTRUE)) break ;
//   	setPlotRange(plotMin,plotMax) ;
	cout << "RooRealVar::readFromStrem(" << GetName() 
	     << ") WARNING: plot range deprecated, removed P(...) token" << endl ;

      } else if (!token.CompareTo("F")) {

	// Next tokens are fit limits
	Double_t fitMin, fitMax ;
	Int_t fitBins ;
	if (parser.expectToken("(",kTRUE) ||
	    parser.readDouble(fitMin,kTRUE) ||
	    parser.expectToken("-",kTRUE) ||
	    parser.readDouble(fitMax,kTRUE) ||
	    parser.expectToken(":",kTRUE) ||
	    parser.readInteger(fitBins,kTRUE) ||
	    parser.expectToken(")",kTRUE)) break ;
	//setBins(fitBins) ;
	//setRange(fitMin,fitMax) ;
	cout << "RooRealVar::readFromStream(" << GetName() 
	     << ") WARNING: F(lo-hi:bins) token deprecated, use L(lo-hi) B(bins)" << endl ;	
	if (!haveConstant) setConstant(kFALSE) ;

      } else if (!token.CompareTo("L")) {

	// Next tokens are fit limits
	Double_t fitMin, fitMax ;
//	Int_t fitBins ;
	if (parser.expectToken("(",kTRUE) ||
	    parser.readDouble(fitMin,kTRUE) ||
	    parser.expectToken("-",kTRUE) ||
	    parser.readDouble(fitMax,kTRUE) ||
	    parser.expectToken(")",kTRUE)) break ;
	setRange(fitMin,fitMax) ;
	if (!haveConstant) setConstant(kFALSE) ;

      } else if (!token.CompareTo("B")) { 

	// Next tokens are fit limits
	Int_t fitBins ;
	if (parser.expectToken("(",kTRUE) ||
	    parser.readInteger(fitBins,kTRUE) ||
	    parser.expectToken(")",kTRUE)) break ;
	setBins(fitBins) ;
	
      } else {
	// Token is value
	if (parser.convertToDouble(token,value)) { parser.zapToEnd() ; break ; }
	haveValue = kTRUE ;
	// Defer value assignment to end
      }
    }    
    if (haveValue) setVal(value) ;
    return kFALSE ;
  }
}

 void RooRealVar::writeToStream(ostream& os, Bool_t compact) const
{
  // Write object contents to given stream

  if (compact) {
    // Write value only
    os << getVal() ;
  } else {    

    // Write value with error (if not zero)    
    if (_printScientific) {
      char fmtVal[16], fmtErr[16] ;
      sprintf(fmtVal,"%%.%de",_printSigDigits) ;
      sprintf(fmtErr,"%%.%de",(_printSigDigits+1)/2) ;
      if (_value>=0) os << " " ;
      os << Form(fmtVal,_value) ;

      if (hasAsymError()) {
	os << " +/- (" << Form(fmtErr,getAsymErrorLo())
	   << ", " << Form(fmtErr,getAsymErrorHi()) << ")" ;
      } else  if (hasError()) {
	os << " +/- " << Form(fmtErr,getError()) ;
      } 

      os << " " ;
    } else {
      os << format(_printSigDigits,"EFA")->Data() << " " ;
    }

    // Append limits if not constants
    if (isConstant()) {
      os << "C " ;
    }      

    // Append fit limits if not +Inf:-Inf
    if (hasMin() || hasMax()) {
      os << "L(" ;
      if(hasMin()) {
	os << getMin();
      }
      else {
	os << "-INF";
      }
      if(hasMax()) {
	os << " - " << getMax() ;
      }
      else {
	os << " - +INF";
      }
      os << ") " ;
    }

    if (getBins()!=100) {
      os << "B(" << getBins() << ") " ;
    }

    // Add comment with unit, if unit exists
    if (!_unit.IsNull())
      os << "// [" << getUnit() << "]" ;
  }
}


 void RooRealVar::printToStream(ostream& os, PrintOption opt, TString indent) const {
  // Print info about this object to the specified stream. In addition to the info
  // from RooAbsRealLValue::printToStream() we add:
  //
  //   Verbose : fit range and error

  RooAbsRealLValue::printToStream(os,opt,indent);
  if(opt >= Verbose) {
    os << indent << "--- RooRealVar ---" << endl;
    TString unit(_unit);
    if(!unit.IsNull()) unit.Prepend(' ');
    if(opt >= Verbose) {
      os << indent << "  Error = " << getError() << unit << endl;
    }
  }
}


 TString* RooRealVar::format(const RooCmdArg& formatArg) const 
{
  RooCmdArg tmp(formatArg) ;
  tmp.setProcessRecArgs(kTRUE) ;

  RooCmdConfig pc(Form("RooRealVar::format(%s)",GetName())) ;
  pc.defineString("what","FormatArgs",0,"") ;
  pc.defineInt("autop","FormatArgs::AutoPrecision",0,2) ;
  pc.defineInt("fixedp","FormatArgs::FixedPrecision",0,2) ;
  pc.defineInt("tlatex","FormatArgs::TLatexStyle",0,0) ;
  pc.defineInt("latex","FormatArgs::LatexStyle",0,0) ;
  pc.defineInt("latext","FormatArgs::LatexTableStyle",0,0) ;
  pc.defineInt("verbn","FormatArgs::VerbatimName",0,0) ;
  pc.defineMutex("FormatArgs::TLatexStyle","FormatArgs::LatexStyle","FormatArgs::LatexTableStyle") ;
  pc.defineMutex("FormatArgs::AutoPrecision","FormatArgs::FixedPrecision") ;

  // Process & check varargs 
  pc.process(tmp) ;
  if (!pc.ok(kTRUE)) {
    return 0 ;
  }

  // Extract values from named arguments
  TString options ;
  options = pc.getString("what") ;
  
  if (pc.getInt("tlatex")) {
    options += "L" ;
  } else if (pc.getInt("latex")) {
    options += "X" ;
  } else if (pc.getInt("latext")) {
    options += "Y" ;
  }   

  if (pc.getInt("verbn")) options += "V" ;
  Int_t sigDigits = 2 ;
  if (pc.hasProcessed("FormatArgs::AutoPrecision")) {
    options += "P" ;
    sigDigits = pc.getInt("autop") ;
  } else if (pc.hasProcessed("FormatArgs::FixedPrecision")) {
    options += "F" ;
    sigDigits = pc.getInt("fixedp") ;
  }
  
  return format(sigDigits,options) ;
}




 TString *RooRealVar::format(Int_t sigDigits, const char *options) const {
  // Format numeric value in a variety of ways
  //
  // What is shown?
  // N = show name
  // H = hide value
  // E = show error
  // A = show asymmetric error instead of parabolic error (if available)
  // U = show unit
  //
  // How is it shown?
  // L = TLatex mode
  // X = Latex mode
  // Y = Latex table mode ( '=' replaced by '&' )
  // V = Make name \verbatim in Latex mode
  // P = use error to control shown precision
  // F = force fixed precision
  //
  
  //cout << "format = " << options << endl ;

  // parse the options string
  TString opts(options);
  opts.ToLower();
  Bool_t showName= opts.Contains("n");
  Bool_t hideValue= opts.Contains("h");
  Bool_t showError= opts.Contains("e");
  Bool_t showUnit= opts.Contains("u");
  Bool_t tlatexMode= opts.Contains("l");
  Bool_t latexMode= opts.Contains("x");
  Bool_t latexTableMode = opts.Contains("y") ;
  Bool_t latexVerbatimName = opts.Contains("v") ;

  if (latexTableMode) latexMode = kTRUE ;
  Bool_t asymError= opts.Contains("a") ;
  Bool_t useErrorForPrecision= (((showError && !isConstant()) || opts.Contains("p")) && !opts.Contains("f")) ;
  // calculate the precision to use
  if(sigDigits < 1) sigDigits= 1;
  Int_t leadingDigitVal = 0;
  if (useErrorForPrecision) {    
    leadingDigitVal = (Int_t)floor(log10(fabs(_error+1e-10)));
    if (_value==0&&_error==0) leadingDigitVal=0 ;
  } else {
    leadingDigitVal = (Int_t)floor(log10(fabs(_value+1e-10)));
    if (_value==0) leadingDigitVal=0 ;
  }
  Int_t leadingDigitErr= (Int_t)floor(log10(fabs(_error)));
  Int_t whereVal= leadingDigitVal - sigDigits + 1;
  Int_t whereErr= leadingDigitErr - sigDigits + 1;
  char fmtVal[16], fmtErr[16];

  if (_value<0) whereVal -= 1 ;
  sprintf(fmtVal,"%%.%df", whereVal < 0 ? -whereVal : 0);
  sprintf(fmtErr,"%%.%df", whereErr < 0 ? -whereErr : 0);
  TString *text= new TString();
  if(latexMode) text->Append("$");
  // begin the string with "<name> = " if requested
  if(showName) {
    if (latexTableMode && latexVerbatimName) {
      text->Append("\\verb+") ;
    }
    text->Append(getPlotLabel());
    if (latexVerbatimName) text->Append("+") ;

    if (!latexTableMode) {
      text->Append(" = ");
    } else {
      text->Append(" $ & $ ");
    }
  }

  // Add leading space if value is positive
  if (_value>=0) text->Append(" ") ;

  // append our value if requested
  char buffer[256];
  if(!hideValue) {
    chopAt(_value, whereVal);
    sprintf(buffer, fmtVal, _value);
    text->Append(buffer);
  }
  // append our error if requested and this variable is not constant
  if(hasError() && showError && !(asymError && hasAsymError())) {
    if(tlatexMode) {
      text->Append(" #pm ");
    }
    else if(latexMode) {
      text->Append("\\pm ");
    }
    else {
      text->Append(" +/- ");
    }
    sprintf(buffer, fmtErr, getError());
    text->Append(buffer);
  }
  
  if (asymError && hasAsymError() && showError) {
    if(tlatexMode) {
      text->Append(" #pm ");
      text->Append("_{") ;      
      sprintf(buffer, fmtErr, getAsymErrorLo());
      text->Append(buffer);
      text->Append("}^{+") ;
      sprintf(buffer, fmtErr, getAsymErrorHi());
      text->Append(buffer);
      text->Append("}") ;
    }
    else if(latexMode) {
      text->Append("\\pm ");
      text->Append("_{") ;      
      sprintf(buffer, fmtErr, getAsymErrorLo());
      text->Append(buffer);
      text->Append("}^{+") ;
      sprintf(buffer, fmtErr, getAsymErrorHi());
      text->Append(buffer);
      text->Append("}") ;
    }
    else {
      text->Append(" +/- ");
      text->Append(" (") ;      
      sprintf(buffer, fmtErr, getAsymErrorLo());
      text->Append(buffer);
      text->Append(", ") ;
      sprintf(buffer, fmtErr, getAsymErrorHi());
      text->Append(buffer);
      text->Append(")") ;
    }

  }

  // append our units if requested
  if(!_unit.IsNull() && showUnit) {
    text->Append(' ');
    text->Append(_unit);
  }
  if(latexMode) text->Append("$");
  return text;
}


 Double_t RooRealVar::chopAt(Double_t what, Int_t where) const {
  // What does this do?
  Double_t scale= pow(10.0,where);
  Int_t trunc= (Int_t)floor(what/scale + 0.5);
  return (Double_t)trunc*scale;
}



 void RooRealVar::attachToTree(TTree& t, Int_t bufSize)
{
  // Follow usual procedure for value
  RooAbsReal::attachToTree(t,bufSize) ;

  // Attach/create additional branch for error
  if (getAttribute("StoreError")) {
    TString errName(GetName()) ;
    errName.Append("_err") ;
    TBranch* branch = t.GetBranch(errName) ;
    if (branch) {     
      t.SetBranchAddress(errName,&_error) ;
    } else {
      TString format(errName);
      format.Append("/D");
      t.Branch(errName, &_error, (const Text_t*)format, bufSize);
    }
  }

  // Attach/create additional branches for asymmetric error
  if (getAttribute("StoreAsymError")) {
    TString loName(GetName()) ;
    loName.Append("_aerr_lo") ;
    TBranch* lobranch = t.GetBranch(loName) ;
    if (lobranch) {     
      t.SetBranchAddress(loName,&_asymErrLo) ;
    } else {
      TString format(loName);
      format.Append("/D");
      t.Branch(loName, &_asymErrLo, (const Text_t*)format, bufSize);
    }

    TString hiName(GetName()) ;
    hiName.Append("_aerr_hi") ;
    TBranch* hibranch = t.GetBranch(hiName) ;
    if (hibranch) {     
      t.SetBranchAddress(hiName,&_asymErrHi) ;
    } else {
      TString format(hiName);
      format.Append("/D");
      t.Branch(hiName, &_asymErrHi, (const Text_t*)format, bufSize);
    }
  }
}

 void RooRealVar::fillTreeBranch(TTree& t) 
{
  // Attach object to a branch of given TTree

  // First determine if branch is taken
  TString cleanName(cleanBranchName()) ;
  TBranch* valBranch = t.GetBranch(cleanName) ;
  if (!valBranch) { 
    cout << "RooAbsReal::fillTreeBranch(" << GetName() << ") ERROR: not attached to tree" << endl ;
    assert(0) ;
  }
  valBranch->Fill() ;

  if (getAttribute("StoreError")) {
    TString errName(GetName()) ;
    errName.Append("_err") ;
    TBranch* errBranch = t.GetBranch(errName) ;
    if (errBranch) errBranch->Fill() ;
  }

  if (getAttribute("StoreAsymError")) {
    TString loName(GetName()) ;
    loName.Append("_aerr_lo") ;
    TBranch* loBranch = t.GetBranch(loName) ;
    if (loBranch) loBranch->Fill() ;

    TString hiName(GetName()) ;
    hiName.Append("_aerr_hi") ;
    TBranch* hiBranch = t.GetBranch(hiName) ;
    if (hiBranch) hiBranch->Fill() ;
  }
}


 void RooRealVar::copyCache(const RooAbsArg* source) 
{
  // Copy the cached value of another RooAbsArg to our cache

  // Warning: This function copies the cached values of source,
  //          it is the callers responsibility to make sure the cache is clean

  // Follow usual procedure for valueklog
  RooAbsReal::copyCache(source) ;

  // Copy error too, if source has one
  RooRealVar* other = dynamic_cast<RooRealVar*>(const_cast<RooAbsArg*>(source)) ;
  if (other) {
    // Copy additional error value
    _error = other->_error ;
    _asymErrLo = other->_asymErrLo ;
    _asymErrHi = other->_asymErrHi ;
  }
}


 void RooRealVar::Streamer(TBuffer &R__b)
{
   // Stream an object of class RooRealVar.

   UInt_t R__s, R__c;
   if (R__b.IsReading()) {
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
      RooAbsRealLValue::Streamer(R__b);
      if (R__v==1) {
	cout << "RooRealVar::Streamer(" << GetName() << ") converting version 1 data format" << endl ;
	Double_t fitMin, fitMax ;
	Int_t fitBins ; 
	R__b >> fitMin;
	R__b >> fitMax;
	R__b >> fitBins;
	_binning = new RooUniformBinning(fitMin,fitMax,fitBins) ;
      }
      R__b >> _error;
      R__b >> _asymErrLo;
      R__b >> _asymErrHi;
      if (R__v!=1) {
	R__b >> _binning;
      }
      R__b.CheckByteCount(R__s, R__c, RooRealVar::IsA());
   } else {
      R__c = R__b.WriteVersion(RooRealVar::IsA(), kTRUE);
      RooAbsRealLValue::Streamer(R__b);
      R__b << _error;
      R__b << _asymErrLo;
      R__b << _asymErrHi;
      R__b << _binning;
      R__b.SetByteCount(R__c, kTRUE);
   }
}


 void RooRealVar::setFitBins(Int_t nBins) 
{
  cout << "WARNING setFitBins() IS OBSOLETE, PLEASE USE setBins()" << endl ;
  setBins(nBins) ;
}

 void RooRealVar::setFitMin(Double_t value) 
{
  cout << "WARNING setFitMin() IS OBSOLETE, PLEASE USE setMin()" << endl ;
  setMin(value) ;
}

 void RooRealVar::setFitMax(Double_t value) 
{
  cout << "WARNING setFitMax() IS OBSOLETE, PLEASE USE setMin()" << endl ;
  setMax(value) ;
}

 void RooRealVar::setFitRange(Double_t min, Double_t max) 
{
  cout << "WARNING setFitRange() IS OBSOLETE, PLEASE USE setRange()" << endl ;
  setRange(min,max) ;
}

 void RooRealVar::removeFitMin() 
{
  cout << "WARNING removeFitMin() IS OBSOLETE, PLEASE USE removeMin()" << endl ;
  removeMin() ;
}

 void RooRealVar::removeFitMax() 
{
  cout << "WARNING removeFitMax() IS OBSOLETE, PLEASE USE removeMax()" << endl ;
  removeMax() ;
}

 void RooRealVar::removeFitRange() 
{
  cout << "WARNING removeFitRange() IS OBSOLETE, PLEASE USE removeRange()" << endl ;
  removeRange() ;
}





ROOT page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.