/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 * @(#)root/roofitcore:$Id$
 * 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)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
//
// RooFormulaVar is a generic implementation of a real valued object
// which takes a RooArgList of servers and a C++ expression string defining how
// its value should be calculated from the given list of servers.
// RooFormulaVar uses a RooFormula object to perform the expression evaluation.
//
// If RooAbsPdf objects are supplied to RooFormulaVar as servers, their
// raw (unnormalized) values will be evaluated. Use RooGenericPdf, which
// constructs generic PDF functions, to access their properly normalized
// values.
//
// The string expression can be any valid TFormula expression referring to the
// listed servers either by name or by their ordinal list position:
//
//   RooFormulaVar("gen","x*y",RooArgList(x,y))  or
//   RooFormulaVar("gen","@0*@1",RooArgList(x,y)) 
//
// The latter form, while slightly less readable, is more versatile because it
// doesn't hardcode any of the variable names it expects
//


#include "RooFit.h"
#include "Riostream.h"

#include "RooFormulaVar.h"
#include "RooFormulaVar.h"
#include "RooStreamParser.h"
#include "RooNLLVar.h"
#include "RooChi2Var.h"
#include "RooMsgService.h"
#include "RooTrace.h"


using namespace std;

ClassImp(RooFormulaVar)



//_____________________________________________________________________________
RooFormulaVar::RooFormulaVar(const char *name, const char *title, const char* inFormula, const RooArgList& dependents) : 
  RooAbsReal(name,title), 
  _actualVars("actualVars","Variables used by formula expression",this),
  _formula(0), _formExpr(inFormula)
{  
  // Constructor with formula expression and list of input variables

  _actualVars.add(dependents) ; 

  if (_actualVars.getSize()==0) _value = traceEval(0) ;
}



//_____________________________________________________________________________
RooFormulaVar::RooFormulaVar(const char *name, const char *title, const RooArgList& dependents) : 
  RooAbsReal(name,title),
  _actualVars("actualVars","Variables used by formula expression",this),
  _formula(0), _formExpr(title)
{  
  // Constructor with formula expression, title and list of input variables

  _actualVars.add(dependents) ; 

  if (_actualVars.getSize()==0) _value = traceEval(0) ;
}



//_____________________________________________________________________________
RooFormulaVar::RooFormulaVar(const RooFormulaVar& other, const char* name) : 
  RooAbsReal(other, name), 
  _actualVars("actualVars",this,other._actualVars),
  _formula(0), _formExpr(other._formExpr)
{
  // Copy constructor
}



//_____________________________________________________________________________
RooFormulaVar::~RooFormulaVar() 
{
  // Destructor

  if (_formula) delete _formula ;
}



//_____________________________________________________________________________
RooFormula& RooFormulaVar::formula() const
{
  // Return reference to internal RooFormula object

  if (!_formula) {
    _formula = new RooFormula(GetName(),_formExpr,_actualVars) ;    
  }
  return *_formula ;
}



//_____________________________________________________________________________
Double_t RooFormulaVar::evaluate() const
{
  // Calculate current value of object from internal formula
  return formula().eval(_lastNSet) ;
}



//_____________________________________________________________________________
Bool_t RooFormulaVar::isValidReal(Double_t /*value*/, Bool_t /*printError*/) const 
{
  // Check if given value is valid
  return kTRUE ;
}



//_____________________________________________________________________________
Bool_t RooFormulaVar::redirectServersHook(const RooAbsCollection& newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t /*isRecursive*/)
{
  // Propagate server change information to embedded RooFormula object
  return formula().changeDependents(newServerList,mustReplaceAll,nameChange) ;
}



//_____________________________________________________________________________
void RooFormulaVar::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
{
  // Print info about this object to the specified stream.   

  RooAbsReal::printMultiline(os,contents,verbose,indent);
  if(verbose) {
    indent.Append("  ");
    os << indent;
    formula().printMultiline(os,contents,verbose,indent);
  }
}



//_____________________________________________________________________________
void RooFormulaVar::printMetaArgs(ostream& os) const 
{
  // Add formula expression as meta argument in printing interface
  os << "formula=\"" << _formExpr << "\" " ;
}




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

  coutE(InputArguments) << "RooFormulaVar::readFromStream(" << GetName() << "): can't read" << endl ;
  return kTRUE ;
}



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

  if (compact) {
    cout << getVal() << endl ;
  } else {
    os << GetTitle() ;
  }
}



//_____________________________________________________________________________
std::list<Double_t>* RooFormulaVar::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
{
  // Forward the plot sampling hint from the p.d.f. that defines the observable obs  
  RooFIter iter = _actualVars.fwdIterator() ;
  RooAbsReal* func ;
  while((func=(RooAbsReal*)iter.next())) {
    list<Double_t>* binb = func->binBoundaries(obs,xlo,xhi) ;      
    if (binb) {
      return binb ;
    }
  }
  
  return 0 ;  
}



//_____________________________________________________________________________
std::list<Double_t>* RooFormulaVar::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
{
  // Forward the plot sampling hint from the p.d.f. that defines the observable obs  
  RooFIter iter = _actualVars.fwdIterator() ;
  RooAbsReal* func ;
  while((func=(RooAbsReal*)iter.next())) {
    list<Double_t>* hint = func->plotSamplingHint(obs,xlo,xhi) ;      
    if (hint) {
      return hint ;
    }
  }
  
  return 0 ;
}



//_____________________________________________________________________________
Double_t RooFormulaVar::defaultErrorLevel() const 
{
  // Return the default error level for MINUIT error analysis
  // If the formula contains one or more RooNLLVars and 
  // no RooChi2Vars, return the defaultErrorLevel() of
  // RooNLLVar. If the addition contains one ore more RooChi2Vars
  // and no RooNLLVars, return the defaultErrorLevel() of
  // RooChi2Var. If the addition contains neither or both
  // issue a warning message and return a value of 1

  RooAbsReal* nllArg(0) ;
  RooAbsReal* chi2Arg(0) ;

  TIterator* iter = _actualVars.createIterator() ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter->Next())) {
    if (dynamic_cast<RooNLLVar*>(arg)) {
      nllArg = (RooAbsReal*)arg ;
    }
    if (dynamic_cast<RooChi2Var*>(arg)) {
      chi2Arg = (RooAbsReal*)arg ;
    }
  }
  delete iter ;

  if (nllArg && !chi2Arg) {
    coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() 
			<< ") Formula contains a RooNLLVar, using its error level" << endl ;
    return nllArg->defaultErrorLevel() ;
  } else if (chi2Arg && !nllArg) {
    coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() 
	 << ") Formula contains a RooChi2Var, using its error level" << endl ;
    return chi2Arg->defaultErrorLevel() ;
  } else if (!nllArg && !chi2Arg) {
    coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
		      << "Formula contains neither RooNLLVar nor RooChi2Var server, using default level of 1.0" << endl ;
  } else {
    coutI(Minimization) << "RooFormulaVar::defaultErrorLevel(" << GetName() << ") WARNING: "
			<< "Formula contains BOTH RooNLLVar and RooChi2Var server, using default level of 1.0" << endl ;
  }

  return 1.0 ;
}




 RooFormulaVar.cxx:1
 RooFormulaVar.cxx:2
 RooFormulaVar.cxx:3
 RooFormulaVar.cxx:4
 RooFormulaVar.cxx:5
 RooFormulaVar.cxx:6
 RooFormulaVar.cxx:7
 RooFormulaVar.cxx:8
 RooFormulaVar.cxx:9
 RooFormulaVar.cxx:10
 RooFormulaVar.cxx:11
 RooFormulaVar.cxx:12
 RooFormulaVar.cxx:13
 RooFormulaVar.cxx:14
 RooFormulaVar.cxx:15
 RooFormulaVar.cxx:16
 RooFormulaVar.cxx:17
 RooFormulaVar.cxx:18
 RooFormulaVar.cxx:19
 RooFormulaVar.cxx:20
 RooFormulaVar.cxx:21
 RooFormulaVar.cxx:22
 RooFormulaVar.cxx:23
 RooFormulaVar.cxx:24
 RooFormulaVar.cxx:25
 RooFormulaVar.cxx:26
 RooFormulaVar.cxx:27
 RooFormulaVar.cxx:28
 RooFormulaVar.cxx:29
 RooFormulaVar.cxx:30
 RooFormulaVar.cxx:31
 RooFormulaVar.cxx:32
 RooFormulaVar.cxx:33
 RooFormulaVar.cxx:34
 RooFormulaVar.cxx:35
 RooFormulaVar.cxx:36
 RooFormulaVar.cxx:37
 RooFormulaVar.cxx:38
 RooFormulaVar.cxx:39
 RooFormulaVar.cxx:40
 RooFormulaVar.cxx:41
 RooFormulaVar.cxx:42
 RooFormulaVar.cxx:43
 RooFormulaVar.cxx:44
 RooFormulaVar.cxx:45
 RooFormulaVar.cxx:46
 RooFormulaVar.cxx:47
 RooFormulaVar.cxx:48
 RooFormulaVar.cxx:49
 RooFormulaVar.cxx:50
 RooFormulaVar.cxx:51
 RooFormulaVar.cxx:52
 RooFormulaVar.cxx:53
 RooFormulaVar.cxx:54
 RooFormulaVar.cxx:55
 RooFormulaVar.cxx:56
 RooFormulaVar.cxx:57
 RooFormulaVar.cxx:58
 RooFormulaVar.cxx:59
 RooFormulaVar.cxx:60
 RooFormulaVar.cxx:61
 RooFormulaVar.cxx:62
 RooFormulaVar.cxx:63
 RooFormulaVar.cxx:64
 RooFormulaVar.cxx:65
 RooFormulaVar.cxx:66
 RooFormulaVar.cxx:67
 RooFormulaVar.cxx:68
 RooFormulaVar.cxx:69
 RooFormulaVar.cxx:70
 RooFormulaVar.cxx:71
 RooFormulaVar.cxx:72
 RooFormulaVar.cxx:73
 RooFormulaVar.cxx:74
 RooFormulaVar.cxx:75
 RooFormulaVar.cxx:76
 RooFormulaVar.cxx:77
 RooFormulaVar.cxx:78
 RooFormulaVar.cxx:79
 RooFormulaVar.cxx:80
 RooFormulaVar.cxx:81
 RooFormulaVar.cxx:82
 RooFormulaVar.cxx:83
 RooFormulaVar.cxx:84
 RooFormulaVar.cxx:85
 RooFormulaVar.cxx:86
 RooFormulaVar.cxx:87
 RooFormulaVar.cxx:88
 RooFormulaVar.cxx:89
 RooFormulaVar.cxx:90
 RooFormulaVar.cxx:91
 RooFormulaVar.cxx:92
 RooFormulaVar.cxx:93
 RooFormulaVar.cxx:94
 RooFormulaVar.cxx:95
 RooFormulaVar.cxx:96
 RooFormulaVar.cxx:97
 RooFormulaVar.cxx:98
 RooFormulaVar.cxx:99
 RooFormulaVar.cxx:100
 RooFormulaVar.cxx:101
 RooFormulaVar.cxx:102
 RooFormulaVar.cxx:103
 RooFormulaVar.cxx:104
 RooFormulaVar.cxx:105
 RooFormulaVar.cxx:106
 RooFormulaVar.cxx:107
 RooFormulaVar.cxx:108
 RooFormulaVar.cxx:109
 RooFormulaVar.cxx:110
 RooFormulaVar.cxx:111
 RooFormulaVar.cxx:112
 RooFormulaVar.cxx:113
 RooFormulaVar.cxx:114
 RooFormulaVar.cxx:115
 RooFormulaVar.cxx:116
 RooFormulaVar.cxx:117
 RooFormulaVar.cxx:118
 RooFormulaVar.cxx:119
 RooFormulaVar.cxx:120
 RooFormulaVar.cxx:121
 RooFormulaVar.cxx:122
 RooFormulaVar.cxx:123
 RooFormulaVar.cxx:124
 RooFormulaVar.cxx:125
 RooFormulaVar.cxx:126
 RooFormulaVar.cxx:127
 RooFormulaVar.cxx:128
 RooFormulaVar.cxx:129
 RooFormulaVar.cxx:130
 RooFormulaVar.cxx:131
 RooFormulaVar.cxx:132
 RooFormulaVar.cxx:133
 RooFormulaVar.cxx:134
 RooFormulaVar.cxx:135
 RooFormulaVar.cxx:136
 RooFormulaVar.cxx:137
 RooFormulaVar.cxx:138
 RooFormulaVar.cxx:139
 RooFormulaVar.cxx:140
 RooFormulaVar.cxx:141
 RooFormulaVar.cxx:142
 RooFormulaVar.cxx:143
 RooFormulaVar.cxx:144
 RooFormulaVar.cxx:145
 RooFormulaVar.cxx:146
 RooFormulaVar.cxx:147
 RooFormulaVar.cxx:148
 RooFormulaVar.cxx:149
 RooFormulaVar.cxx:150
 RooFormulaVar.cxx:151
 RooFormulaVar.cxx:152
 RooFormulaVar.cxx:153
 RooFormulaVar.cxx:154
 RooFormulaVar.cxx:155
 RooFormulaVar.cxx:156
 RooFormulaVar.cxx:157
 RooFormulaVar.cxx:158
 RooFormulaVar.cxx:159
 RooFormulaVar.cxx:160
 RooFormulaVar.cxx:161
 RooFormulaVar.cxx:162
 RooFormulaVar.cxx:163
 RooFormulaVar.cxx:164
 RooFormulaVar.cxx:165
 RooFormulaVar.cxx:166
 RooFormulaVar.cxx:167
 RooFormulaVar.cxx:168
 RooFormulaVar.cxx:169
 RooFormulaVar.cxx:170
 RooFormulaVar.cxx:171
 RooFormulaVar.cxx:172
 RooFormulaVar.cxx:173
 RooFormulaVar.cxx:174
 RooFormulaVar.cxx:175
 RooFormulaVar.cxx:176
 RooFormulaVar.cxx:177
 RooFormulaVar.cxx:178
 RooFormulaVar.cxx:179
 RooFormulaVar.cxx:180
 RooFormulaVar.cxx:181
 RooFormulaVar.cxx:182
 RooFormulaVar.cxx:183
 RooFormulaVar.cxx:184
 RooFormulaVar.cxx:185
 RooFormulaVar.cxx:186
 RooFormulaVar.cxx:187
 RooFormulaVar.cxx:188
 RooFormulaVar.cxx:189
 RooFormulaVar.cxx:190
 RooFormulaVar.cxx:191
 RooFormulaVar.cxx:192
 RooFormulaVar.cxx:193
 RooFormulaVar.cxx:194
 RooFormulaVar.cxx:195
 RooFormulaVar.cxx:196
 RooFormulaVar.cxx:197
 RooFormulaVar.cxx:198
 RooFormulaVar.cxx:199
 RooFormulaVar.cxx:200
 RooFormulaVar.cxx:201
 RooFormulaVar.cxx:202
 RooFormulaVar.cxx:203
 RooFormulaVar.cxx:204
 RooFormulaVar.cxx:205
 RooFormulaVar.cxx:206
 RooFormulaVar.cxx:207
 RooFormulaVar.cxx:208
 RooFormulaVar.cxx:209
 RooFormulaVar.cxx:210
 RooFormulaVar.cxx:211
 RooFormulaVar.cxx:212
 RooFormulaVar.cxx:213
 RooFormulaVar.cxx:214
 RooFormulaVar.cxx:215
 RooFormulaVar.cxx:216
 RooFormulaVar.cxx:217
 RooFormulaVar.cxx:218
 RooFormulaVar.cxx:219
 RooFormulaVar.cxx:220
 RooFormulaVar.cxx:221
 RooFormulaVar.cxx:222
 RooFormulaVar.cxx:223
 RooFormulaVar.cxx:224
 RooFormulaVar.cxx:225
 RooFormulaVar.cxx:226
 RooFormulaVar.cxx:227
 RooFormulaVar.cxx:228
 RooFormulaVar.cxx:229
 RooFormulaVar.cxx:230
 RooFormulaVar.cxx:231
 RooFormulaVar.cxx:232
 RooFormulaVar.cxx:233
 RooFormulaVar.cxx:234
 RooFormulaVar.cxx:235
 RooFormulaVar.cxx:236
 RooFormulaVar.cxx:237
 RooFormulaVar.cxx:238
 RooFormulaVar.cxx:239
 RooFormulaVar.cxx:240
 RooFormulaVar.cxx:241
 RooFormulaVar.cxx:242
 RooFormulaVar.cxx:243
 RooFormulaVar.cxx:244
 RooFormulaVar.cxx:245
 RooFormulaVar.cxx:246
 RooFormulaVar.cxx:247
 RooFormulaVar.cxx:248
 RooFormulaVar.cxx:249
 RooFormulaVar.cxx:250
 RooFormulaVar.cxx:251
 RooFormulaVar.cxx:252
 RooFormulaVar.cxx:253
 RooFormulaVar.cxx:254
 RooFormulaVar.cxx:255
 RooFormulaVar.cxx:256
 RooFormulaVar.cxx:257
 RooFormulaVar.cxx:258
 RooFormulaVar.cxx:259
 RooFormulaVar.cxx:260
 RooFormulaVar.cxx:261
 RooFormulaVar.cxx:262
 RooFormulaVar.cxx:263
 RooFormulaVar.cxx:264
 RooFormulaVar.cxx:265
 RooFormulaVar.cxx:266
 RooFormulaVar.cxx:267
 RooFormulaVar.cxx:268
 RooFormulaVar.cxx:269
 RooFormulaVar.cxx:270
 RooFormulaVar.cxx:271
 RooFormulaVar.cxx:272
 RooFormulaVar.cxx:273
 RooFormulaVar.cxx:274
 RooFormulaVar.cxx:275
 RooFormulaVar.cxx:276
 RooFormulaVar.cxx:277
 RooFormulaVar.cxx:278
 RooFormulaVar.cxx:279
 RooFormulaVar.cxx:280
 RooFormulaVar.cxx:281
 RooFormulaVar.cxx:282