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

//////////////////////////////////////////////////////////////////////////////
//
// BEGIN_HTML
// RooHistPdf implements a probablity density function sampled from a 
// multidimensional histogram. The histogram distribution is explicitly
// normalized by RooHistPdf and can have an arbitrary number of real or 
// discrete dimensions.
// END_HTML
//

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

#include "RooHistPdf.h"
#include "RooDataHist.h"
#include "RooMsgService.h"
#include "RooRealVar.h"
#include "RooCategory.h"
#include "RooWorkspace.h"
#include "RooGlobalFunc.h"

#include "TError.h"

using namespace std;

ClassImp(RooHistPdf)
;



//_____________________________________________________________________________
RooHistPdf::RooHistPdf() : _dataHist(0), _totVolume(0), _unitNorm(kFALSE)
{
  // Default constructor
  // coverity[UNINIT_CTOR]
  _histObsIter = _histObsList.createIterator() ;
  _pdfObsIter = _pdfObsList.createIterator() ;
}


//_____________________________________________________________________________
RooHistPdf::RooHistPdf(const char *name, const char *title, const RooArgSet& vars, 
		       const RooDataHist& dhist, Int_t intOrder) :
  RooAbsPdf(name,title), 
  _pdfObsList("pdfObs","List of p.d.f. observables",this),
  _dataHist((RooDataHist*)&dhist), 
  _codeReg(10),
  _intOrder(intOrder),
  _cdfBoundaries(kFALSE),
  _totVolume(0),
  _unitNorm(kFALSE)
{
  // Constructor from a RooDataHist. RooDataHist dimensions
  // can be either real or discrete. See RooDataHist::RooDataHist for details on the binning.
  // RooHistPdf neither owns or clone 'dhist' and the user must ensure the input histogram exists
  // for the entire life span of this PDF.

  _histObsList.addClone(vars) ;
  _pdfObsList.add(vars) ;

  // Verify that vars and dhist.get() have identical contents
  const RooArgSet* dvars = dhist.get() ;
  if (vars.getSize()!=dvars->getSize()) {
    coutE(InputArguments) << "RooHistPdf::ctor(" << GetName() 
			  << ") ERROR variable list and RooDataHist must contain the same variables." << endl ;
    assert(0) ;
  }
  TIterator* iter = vars.createIterator() ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter->Next())) {
    if (!dvars->find(arg->GetName())) {
      coutE(InputArguments) << "RooHistPdf::ctor(" << GetName() 
			    << ") ERROR variable list and RooDataHist must contain the same variables." << endl ;
      assert(0) ;
    }
  }
  delete iter ;

  _histObsIter = _histObsList.createIterator() ;
  _pdfObsIter = _pdfObsList.createIterator() ;


  // Adjust ranges of _histObsList to those of _dataHist 
  RooFIter oiter = _histObsList.fwdIterator() ;
  RooAbsArg* hobs ;
  while ((hobs = oiter.next())) {
    // Guaranteed to succeed, since checked above in ctor
    RooAbsArg* dhobs = dhist.get()->find(hobs->GetName()) ;
    RooRealVar* dhreal = dynamic_cast<RooRealVar*>(dhobs) ;
    if (dhreal){
      ((RooRealVar*)hobs)->setRange(dhreal->getMin(),dhreal->getMax()) ;
    }
  }
  
}




//_____________________________________________________________________________
RooHistPdf::RooHistPdf(const char *name, const char *title, const RooArgList& pdfObs, 
		       const RooArgList& histObs, const RooDataHist& dhist, Int_t intOrder) :
  RooAbsPdf(name,title), 
  _pdfObsList("pdfObs","List of p.d.f. observables",this),
  _dataHist((RooDataHist*)&dhist), 
  _codeReg(10),
  _intOrder(intOrder),
  _cdfBoundaries(kFALSE),
  _totVolume(0),
  _unitNorm(kFALSE)
{
  // Constructor from a RooDataHist. The first list of observables are the p.d.f.
  // observables, which may any RooAbsReal (function or variable). The second list
  // are the corresponding observables in the RooDataHist which must be of type
  // RooRealVar or RooCategory This constructor thus allows to apply a coordinate transformation
  // on the histogram data to be applied.

  _histObsList.addClone(histObs) ;
  _pdfObsList.add(pdfObs) ;

  // Verify that vars and dhist.get() have identical contents
  const RooArgSet* dvars = dhist.get() ;
  if (histObs.getSize()!=dvars->getSize()) {
    coutE(InputArguments) << "RooHistPdf::ctor(" << GetName() 
			  << ") ERROR histogram variable list and RooDataHist must contain the same variables." << endl ;
    throw(string("RooHistPdf::ctor() ERROR: histogram variable list and RooDataHist must contain the same variables")) ;
  }
  TIterator* iter = histObs.createIterator() ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter->Next())) {
    if (!dvars->find(arg->GetName())) {
      coutE(InputArguments) << "RooHistPdf::ctor(" << GetName() 
			    << ") ERROR variable list and RooDataHist must contain the same variables." << endl ;
      throw(string("RooHistPdf::ctor() ERROR: histogram variable list and RooDataHist must contain the same variables")) ;
    }
    if (!arg->isFundamental()) {
      coutE(InputArguments) << "RooHistPdf::ctor(" << GetName() 
			    << ") ERROR all elements of histogram observables set must be of type RooRealVar or RooCategory." << endl ;
      throw(string("RooHistPdf::ctor() ERROR all elements of histogram observables set must be of type RooRealVar or RooCategory.")) ;
    }
  }
  delete iter ;

  _histObsIter = _histObsList.createIterator() ;
  _pdfObsIter = _pdfObsList.createIterator() ;

  // Adjust ranges of _histObsList to those of _dataHist 
  RooFIter oiter = _histObsList.fwdIterator() ;
  RooAbsArg* hobs ;
  while ((hobs = oiter.next())) {
    // Guaranteed to succeed, since checked above in ctor
    RooAbsArg* dhobs = dhist.get()->find(hobs->GetName()) ;
    RooRealVar* dhreal = dynamic_cast<RooRealVar*>(dhobs) ;
    if (dhreal){
      ((RooRealVar*)hobs)->setRange(dhreal->getMin(),dhreal->getMax()) ;
    }
  }
}



//_____________________________________________________________________________
RooHistPdf::RooHistPdf(const RooHistPdf& other, const char* name) :
  RooAbsPdf(other,name), 
  _pdfObsList("pdfObs",this,other._pdfObsList),
  _dataHist(other._dataHist),
  _codeReg(other._codeReg),
  _intOrder(other._intOrder),
  _cdfBoundaries(other._cdfBoundaries),
  _totVolume(other._totVolume),
  _unitNorm(other._unitNorm)
{
  // Copy constructor

  _histObsList.addClone(other._histObsList) ;

  _histObsIter = _histObsList.createIterator() ;
  _pdfObsIter = _pdfObsList.createIterator() ;
}




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

  delete _histObsIter ;
  delete _pdfObsIter ;
}





//_____________________________________________________________________________
Double_t RooHistPdf::evaluate() const
{
  // Return the current value: The value of the bin enclosing the current coordinates
  // of the observables, normalized by the histograms contents. Interpolation
  // is applied if the RooHistPdf is configured to do that

  // Transfer values from   
  if (_pdfObsList.getSize()>0) {
    _histObsIter->Reset() ;
    _pdfObsIter->Reset() ;
    RooAbsArg* harg, *parg ;
    while((harg=(RooAbsArg*)_histObsIter->Next())) {
      parg = (RooAbsArg*)_pdfObsIter->Next() ;
      if (harg != parg) {
	parg->syncCache() ;
	harg->copyCache(parg,kTRUE) ;
	if (!harg->inRange(0)) {
	  return 0 ;
	}
      }
    }
  }

  Double_t ret =  _dataHist->weight(_histObsList,_intOrder,_unitNorm?kFALSE:kTRUE,_cdfBoundaries) ;  
  //cout << "RooHistPdf::evaluate(" << GetName() << ") ret = " << ret << endl ;
  if (ret<0) {
    ret=0 ;
  }  
  return ret ;
}


//_____________________________________________________________________________
Double_t RooHistPdf::totVolume() const
{
  // Return the total volume spanned by the observables of the RooHistPdf

  // Return previously calculated value, if any
  if (_totVolume>0) {
    return _totVolume ;
  }
  _totVolume = 1. ;
  TIterator* iter = _histObsList.createIterator() ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter->Next())) {
    RooRealVar* real = dynamic_cast<RooRealVar*>(arg) ;
    if (real) {
      _totVolume *= (real->getMax()-real->getMin()) ;
    } else {
      RooCategory* cat = dynamic_cast<RooCategory*>(arg) ;
      if (cat) {
	_totVolume *= cat->numTypes() ;
      }
    }
  }
  delete iter ;
  return _totVolume ;
}

namespace {
    bool fullRange(const RooAbsArg& x, const RooAbsArg& y ,const char* range)
    {
      const RooAbsRealLValue *_x = dynamic_cast<const RooAbsRealLValue*>(&x);
      const RooAbsRealLValue *_y = dynamic_cast<const RooAbsRealLValue*>(&y);
      if (!_x || !_y) return false;
      if (!range || !strlen(range) || !_x->hasRange(range) ||
	  _x->getBinningPtr(range)->isParameterized()) {
	// parameterized ranges may be full range now, but that might change,
	// so return false
	if (range && strlen(range) && _x->getBinningPtr(range)->isParameterized())
	    return false;
	return (_x->getMin() == _y->getMin() && _x->getMax() == _y->getMax());
      }
      return (_x->getMin(range) == _y->getMin() && _x->getMax(range) == _y->getMax());
    }
}


//_____________________________________________________________________________
Int_t RooHistPdf::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* rangeName) const 
{
  // Determine integration scenario. If no interpolation is used,
  // RooHistPdf can perform all integrals over its dependents
  // analytically via partial or complete summation of the input
  // histogram. If interpolation is used on the integral over
  // all histogram observables is supported

  // First make list of pdf observables to histogram observables
  // and select only those for which the integral is over the full range

  RooFIter it = _pdfObsList.fwdIterator();
  RooFIter jt = _histObsList.fwdIterator();
  Int_t code = 0, frcode = 0, n = 0;
  for (RooAbsArg *pa = 0, *ha = 0; (pa = it.next()) && (ha = jt.next()); ++n) {
    if (allVars.find(*pa)) {
      code |= 2 << n;
      analVars.add(*pa);
      if (fullRange(*pa, *ha, rangeName)) {
	frcode |= 2 << n;
      }
    }
  }

  if (code == frcode) {
    // integrate over full range of all observables - use bit 0 to indicate
    // full range integration over all observables
    code |= 1;
  }
  // Disable partial analytical integrals if interpolation is used, and we
  // integrate over sub-ranges, but leave them enabled when we integrate over
  // the full range of one or several variables
  if (_intOrder > 1 && !(code & 1)) {
    analVars.removeAll();
    return 0;
  }
  return (code >= 2) ? code : 0;
}



//_____________________________________________________________________________
Double_t RooHistPdf::analyticalIntegral(Int_t code, const char* rangeName) const 
{
  // Return integral identified by 'code'. The actual integration
  // is deferred to RooDataHist::sum() which implements partial
  // or complete summation over the histograms contents

  // Simplest scenario, full-range integration over all dependents
  if (((2 << _histObsList.getSize()) - 1) == code) {
    return _dataHist->sum(kFALSE);
  }

  // Partial integration scenario, retrieve set of variables, calculate partial
  // sum, figure out integration ranges (if needed)
  RooArgSet intSet;
  std::map<const RooAbsArg*, std::pair<Double_t, Double_t> > ranges;
  RooFIter it = _pdfObsList.fwdIterator();
  RooFIter jt = _histObsList.fwdIterator();
  Int_t n(0);
  for (RooAbsArg *pa = 0, *ha = 0; (pa = it.next()) && (ha = jt.next()); ++n) {
    if (code & (2 << n)) {
      intSet.add(*ha);
    }
    if (!(code & 1)) {
      RooAbsRealLValue* rlv = dynamic_cast<RooAbsRealLValue*>(pa);
      if (rlv) {
	const RooAbsBinning* binning = rlv->getBinningPtr(rangeName);
	if (rangeName && rlv->hasRange(rangeName)) {
	  ranges[ha] = std::make_pair(
	      rlv->getMin(rangeName), rlv->getMax(rangeName));
	} else if (binning) {
	  if (!binning->isParameterized()) {
	    ranges[ha] = std::make_pair(
		binning->lowBound(), binning->highBound());
	  } else {
	    ranges[ha] = std::make_pair(
		binning->lowBoundFunc()->getVal(), binning->highBoundFunc()->getVal());
	  }
	}
      }
    }
    // WVE must sync hist slice list values to pdf slice list
    // Transfer values from
    if (ha != pa) {
      pa->syncCache();
      ha->copyCache(pa,kTRUE);
    }
  }

  Double_t ret = (code & 1) ?
    _dataHist->sum(intSet,_histObsList,kTRUE,kTRUE) :
    _dataHist->sum(intSet,_histObsList,kFALSE,kTRUE, ranges);
  
  //    cout << "intSet = " << intSet << endl ;
  //    cout << "slice position = " << endl ;
  //    _histObsList.Print("v") ;
  //    cout << "RooHistPdf::ai(" << GetName() << ") code = " << code << " ret = " << ret << endl ;
  
  return ret ;
}



//_____________________________________________________________________________
list<Double_t>* RooHistPdf::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
{
  // Return sampling hint for making curves of (projections) of this function
  // as the recursive division strategy of RooCurve cannot deal efficiently
  // with the vertical lines that occur in a non-interpolated histogram

  // No hints are required when interpolation is used
  if (_intOrder>0) {
    return 0 ;
  }

  // Check that observable is in dataset, if not no hint is generated
  _histObsIter->Reset() ;
  _pdfObsIter->Reset() ;
  RooAbsArg *pdfObs, *histObs, *dhObs(0) ;
  while ((pdfObs = (RooAbsArg*)_pdfObsIter->Next()) && !dhObs) {
    histObs = (RooAbsArg*) _histObsIter->Next() ;
    if (TString(obs.GetName())==pdfObs->GetName()) {
      dhObs = _dataHist->get()->find(histObs->GetName()) ;
    }
  }

  if (!dhObs) {
    return 0 ;
  }
  RooAbsLValue* lval = dynamic_cast<RooAbsLValue*>(dhObs) ;
  if (!lval) {
    return 0 ;
  }

  // Retrieve position of all bin boundaries
  
  const RooAbsBinning* binning = lval->getBinningPtr(0) ;
  Double_t* boundaries = binning->array() ;

  list<Double_t>* hint = new list<Double_t> ;

  // Widen range slighty
  xlo = xlo - 0.01*(xhi-xlo) ;
  xhi = xhi + 0.01*(xhi-xlo) ;

  Double_t delta = (xhi-xlo)*1e-8 ;
 
  // Construct array with pairs of points positioned epsilon to the left and
  // right of the bin boundaries
  for (Int_t i=0 ; i<binning->numBoundaries() ; i++) {
    if (boundaries[i]>=xlo && boundaries[i]<=xhi) {
      hint->push_back(boundaries[i]-delta) ;
      hint->push_back(boundaries[i]+delta) ;
    }
  }

  return hint ;
}



//______________________________________________________________________________
std::list<Double_t>* RooHistPdf::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const 
{
  // Return sampling hint for making curves of (projections) of this function
  // as the recursive division strategy of RooCurve cannot deal efficiently
  // with the vertical lines that occur in a non-interpolated histogram

  // No hints are required when interpolation is used
  if (_intOrder>0) {
    return 0 ;
  }

  // Check that observable is in dataset, if not no hint is generated
  RooAbsLValue* lvarg = dynamic_cast<RooAbsLValue*>(_dataHist->get()->find(obs.GetName())) ;
  if (!lvarg) {
    return 0 ;
  }

  // Retrieve position of all bin boundaries
  const RooAbsBinning* binning = lvarg->getBinningPtr(0) ;
  Double_t* boundaries = binning->array() ;

  list<Double_t>* hint = new list<Double_t> ;

  // Construct array with pairs of points positioned epsilon to the left and
  // right of the bin boundaries
  for (Int_t i=0 ; i<binning->numBoundaries() ; i++) {
    if (boundaries[i]>=xlo && boundaries[i]<=xhi) {
      hint->push_back(boundaries[i]) ;
    }
  }

  return hint ;
}




//_____________________________________________________________________________
Int_t RooHistPdf::getMaxVal(const RooArgSet& vars) const 
{
  // Only handle case of maximum in all variables
  RooAbsCollection* common = _pdfObsList.selectCommon(vars) ;
  if (common->getSize()==_pdfObsList.getSize()) {
    delete common ;
    return 1;
  }
  delete common ;
  return 0 ;
}


//_____________________________________________________________________________
Double_t RooHistPdf::maxVal(Int_t code) const 
{
  R__ASSERT(code==1) ;

  Double_t max(-1) ;
  for (Int_t i=0 ; i<_dataHist->numEntries() ; i++) {
    _dataHist->get(i) ;
    Double_t wgt = _dataHist->weight() ;
    if (wgt>max) max=wgt ;
  }

  return max*1.05 ;
}




//_____________________________________________________________________________
Bool_t RooHistPdf::areIdentical(const RooDataHist& dh1, const RooDataHist& dh2) 
{
  if (fabs(dh1.sumEntries()-dh2.sumEntries())>1e-8) return kFALSE ;
  if (dh1.numEntries() != dh2.numEntries()) return kFALSE ;
  for (int i=0 ; i < dh1.numEntries() ; i++) {
    dh1.get(i) ;
    dh2.get(i) ;
    if (fabs(dh1.weight()-dh2.weight())>1e-8) return kFALSE ;
  }
  return kTRUE ;
}



//_____________________________________________________________________________
Bool_t RooHistPdf::importWorkspaceHook(RooWorkspace& ws) 
{  
  // Check if our datahist is already in the workspace
  std::list<RooAbsData*> allData = ws.allData() ;
  std::list<RooAbsData*>::const_iterator iter ;
  for (iter = allData.begin() ; iter != allData.end() ; ++iter) {
    // If your dataset is already in this workspace nothing needs to be done
    if (*iter == _dataHist) {
      return kFALSE ;
    }
  }

  // Check if dataset with given name already exists
  RooAbsData* wsdata = ws.embeddedData(_dataHist->GetName()) ;

  if (wsdata) {

    // Yes it exists - now check if it is identical to our internal histogram 
    if (wsdata->InheritsFrom(RooDataHist::Class())) {

      // Check if histograms are identical
      if (areIdentical((RooDataHist&)*wsdata,*_dataHist)) {

	// Exists and is of correct type, and identical -- adjust internal pointer to WS copy
	_dataHist = (RooDataHist*) wsdata ;
      } else {

	// not identical, clone rename and import
	TString uniqueName = Form("%s_%s",_dataHist->GetName(),GetName()) ;
	Bool_t flag = ws.import(*_dataHist,RooFit::Rename(uniqueName.Data()),RooFit::Embedded()) ;
	if (flag) {
	  coutE(ObjectHandling) << " RooHistPdf::importWorkspaceHook(" << GetName() << ") unable to import clone of underlying RooDataHist with unique name " << uniqueName << ", abort" << endl ;
	  return kTRUE ;
	}
	_dataHist = (RooDataHist*) ws.embeddedData(uniqueName.Data()) ;
      }

    } else {

      // Exists and is NOT of correct type: clone rename and import
      TString uniqueName = Form("%s_%s",_dataHist->GetName(),GetName()) ;
      Bool_t flag = ws.import(*_dataHist,RooFit::Rename(uniqueName.Data()),RooFit::Embedded()) ;
      if (flag) {
	coutE(ObjectHandling) << " RooHistPdf::importWorkspaceHook(" << GetName() << ") unable to import clone of underlying RooDataHist with unique name " << uniqueName << ", abort" << endl ;
	return kTRUE ;
      }
      _dataHist = (RooDataHist*) ws.embeddedData(uniqueName.Data()) ;
      
    }
    return kFALSE ;
  }
  
  // We need to import our datahist into the workspace
  ws.import(*_dataHist,RooFit::Embedded()) ;

  // Redirect our internal pointer to the copy in the workspace
  _dataHist = (RooDataHist*) ws.embeddedData(_dataHist->GetName()) ;
  return kFALSE ;
}


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

   if (R__b.IsReading()) {
      R__b.ReadClassBuffer(RooHistPdf::Class(),this);
      // WVE - interim solution - fix proxies here
      //_proxyList.Clear() ;
      //registerProxy(_pdfObsList) ;
   } else {
      R__b.WriteClassBuffer(RooHistPdf::Class(),this);
   }
}

 RooHistPdf.cxx:1
 RooHistPdf.cxx:2
 RooHistPdf.cxx:3
 RooHistPdf.cxx:4
 RooHistPdf.cxx:5
 RooHistPdf.cxx:6
 RooHistPdf.cxx:7
 RooHistPdf.cxx:8
 RooHistPdf.cxx:9
 RooHistPdf.cxx:10
 RooHistPdf.cxx:11
 RooHistPdf.cxx:12
 RooHistPdf.cxx:13
 RooHistPdf.cxx:14
 RooHistPdf.cxx:15
 RooHistPdf.cxx:16
 RooHistPdf.cxx:17
 RooHistPdf.cxx:18
 RooHistPdf.cxx:19
 RooHistPdf.cxx:20
 RooHistPdf.cxx:21
 RooHistPdf.cxx:22
 RooHistPdf.cxx:23
 RooHistPdf.cxx:24
 RooHistPdf.cxx:25
 RooHistPdf.cxx:26
 RooHistPdf.cxx:27
 RooHistPdf.cxx:28
 RooHistPdf.cxx:29
 RooHistPdf.cxx:30
 RooHistPdf.cxx:31
 RooHistPdf.cxx:32
 RooHistPdf.cxx:33
 RooHistPdf.cxx:34
 RooHistPdf.cxx:35
 RooHistPdf.cxx:36
 RooHistPdf.cxx:37
 RooHistPdf.cxx:38
 RooHistPdf.cxx:39
 RooHistPdf.cxx:40
 RooHistPdf.cxx:41
 RooHistPdf.cxx:42
 RooHistPdf.cxx:43
 RooHistPdf.cxx:44
 RooHistPdf.cxx:45
 RooHistPdf.cxx:46
 RooHistPdf.cxx:47
 RooHistPdf.cxx:48
 RooHistPdf.cxx:49
 RooHistPdf.cxx:50
 RooHistPdf.cxx:51
 RooHistPdf.cxx:52
 RooHistPdf.cxx:53
 RooHistPdf.cxx:54
 RooHistPdf.cxx:55
 RooHistPdf.cxx:56
 RooHistPdf.cxx:57
 RooHistPdf.cxx:58
 RooHistPdf.cxx:59
 RooHistPdf.cxx:60
 RooHistPdf.cxx:61
 RooHistPdf.cxx:62
 RooHistPdf.cxx:63
 RooHistPdf.cxx:64
 RooHistPdf.cxx:65
 RooHistPdf.cxx:66
 RooHistPdf.cxx:67
 RooHistPdf.cxx:68
 RooHistPdf.cxx:69
 RooHistPdf.cxx:70
 RooHistPdf.cxx:71
 RooHistPdf.cxx:72
 RooHistPdf.cxx:73
 RooHistPdf.cxx:74
 RooHistPdf.cxx:75
 RooHistPdf.cxx:76
 RooHistPdf.cxx:77
 RooHistPdf.cxx:78
 RooHistPdf.cxx:79
 RooHistPdf.cxx:80
 RooHistPdf.cxx:81
 RooHistPdf.cxx:82
 RooHistPdf.cxx:83
 RooHistPdf.cxx:84
 RooHistPdf.cxx:85
 RooHistPdf.cxx:86
 RooHistPdf.cxx:87
 RooHistPdf.cxx:88
 RooHistPdf.cxx:89
 RooHistPdf.cxx:90
 RooHistPdf.cxx:91
 RooHistPdf.cxx:92
 RooHistPdf.cxx:93
 RooHistPdf.cxx:94
 RooHistPdf.cxx:95
 RooHistPdf.cxx:96
 RooHistPdf.cxx:97
 RooHistPdf.cxx:98
 RooHistPdf.cxx:99
 RooHistPdf.cxx:100
 RooHistPdf.cxx:101
 RooHistPdf.cxx:102
 RooHistPdf.cxx:103
 RooHistPdf.cxx:104
 RooHistPdf.cxx:105
 RooHistPdf.cxx:106
 RooHistPdf.cxx:107
 RooHistPdf.cxx:108
 RooHistPdf.cxx:109
 RooHistPdf.cxx:110
 RooHistPdf.cxx:111
 RooHistPdf.cxx:112
 RooHistPdf.cxx:113
 RooHistPdf.cxx:114
 RooHistPdf.cxx:115
 RooHistPdf.cxx:116
 RooHistPdf.cxx:117
 RooHistPdf.cxx:118
 RooHistPdf.cxx:119
 RooHistPdf.cxx:120
 RooHistPdf.cxx:121
 RooHistPdf.cxx:122
 RooHistPdf.cxx:123
 RooHistPdf.cxx:124
 RooHistPdf.cxx:125
 RooHistPdf.cxx:126
 RooHistPdf.cxx:127
 RooHistPdf.cxx:128
 RooHistPdf.cxx:129
 RooHistPdf.cxx:130
 RooHistPdf.cxx:131
 RooHistPdf.cxx:132
 RooHistPdf.cxx:133
 RooHistPdf.cxx:134
 RooHistPdf.cxx:135
 RooHistPdf.cxx:136
 RooHistPdf.cxx:137
 RooHistPdf.cxx:138
 RooHistPdf.cxx:139
 RooHistPdf.cxx:140
 RooHistPdf.cxx:141
 RooHistPdf.cxx:142
 RooHistPdf.cxx:143
 RooHistPdf.cxx:144
 RooHistPdf.cxx:145
 RooHistPdf.cxx:146
 RooHistPdf.cxx:147
 RooHistPdf.cxx:148
 RooHistPdf.cxx:149
 RooHistPdf.cxx:150
 RooHistPdf.cxx:151
 RooHistPdf.cxx:152
 RooHistPdf.cxx:153
 RooHistPdf.cxx:154
 RooHistPdf.cxx:155
 RooHistPdf.cxx:156
 RooHistPdf.cxx:157
 RooHistPdf.cxx:158
 RooHistPdf.cxx:159
 RooHistPdf.cxx:160
 RooHistPdf.cxx:161
 RooHistPdf.cxx:162
 RooHistPdf.cxx:163
 RooHistPdf.cxx:164
 RooHistPdf.cxx:165
 RooHistPdf.cxx:166
 RooHistPdf.cxx:167
 RooHistPdf.cxx:168
 RooHistPdf.cxx:169
 RooHistPdf.cxx:170
 RooHistPdf.cxx:171
 RooHistPdf.cxx:172
 RooHistPdf.cxx:173
 RooHistPdf.cxx:174
 RooHistPdf.cxx:175
 RooHistPdf.cxx:176
 RooHistPdf.cxx:177
 RooHistPdf.cxx:178
 RooHistPdf.cxx:179
 RooHistPdf.cxx:180
 RooHistPdf.cxx:181
 RooHistPdf.cxx:182
 RooHistPdf.cxx:183
 RooHistPdf.cxx:184
 RooHistPdf.cxx:185
 RooHistPdf.cxx:186
 RooHistPdf.cxx:187
 RooHistPdf.cxx:188
 RooHistPdf.cxx:189
 RooHistPdf.cxx:190
 RooHistPdf.cxx:191
 RooHistPdf.cxx:192
 RooHistPdf.cxx:193
 RooHistPdf.cxx:194
 RooHistPdf.cxx:195
 RooHistPdf.cxx:196
 RooHistPdf.cxx:197
 RooHistPdf.cxx:198
 RooHistPdf.cxx:199
 RooHistPdf.cxx:200
 RooHistPdf.cxx:201
 RooHistPdf.cxx:202
 RooHistPdf.cxx:203
 RooHistPdf.cxx:204
 RooHistPdf.cxx:205
 RooHistPdf.cxx:206
 RooHistPdf.cxx:207
 RooHistPdf.cxx:208
 RooHistPdf.cxx:209
 RooHistPdf.cxx:210
 RooHistPdf.cxx:211
 RooHistPdf.cxx:212
 RooHistPdf.cxx:213
 RooHistPdf.cxx:214
 RooHistPdf.cxx:215
 RooHistPdf.cxx:216
 RooHistPdf.cxx:217
 RooHistPdf.cxx:218
 RooHistPdf.cxx:219
 RooHistPdf.cxx:220
 RooHistPdf.cxx:221
 RooHistPdf.cxx:222
 RooHistPdf.cxx:223
 RooHistPdf.cxx:224
 RooHistPdf.cxx:225
 RooHistPdf.cxx:226
 RooHistPdf.cxx:227
 RooHistPdf.cxx:228
 RooHistPdf.cxx:229
 RooHistPdf.cxx:230
 RooHistPdf.cxx:231
 RooHistPdf.cxx:232
 RooHistPdf.cxx:233
 RooHistPdf.cxx:234
 RooHistPdf.cxx:235
 RooHistPdf.cxx:236
 RooHistPdf.cxx:237
 RooHistPdf.cxx:238
 RooHistPdf.cxx:239
 RooHistPdf.cxx:240
 RooHistPdf.cxx:241
 RooHistPdf.cxx:242
 RooHistPdf.cxx:243
 RooHistPdf.cxx:244
 RooHistPdf.cxx:245
 RooHistPdf.cxx:246
 RooHistPdf.cxx:247
 RooHistPdf.cxx:248
 RooHistPdf.cxx:249
 RooHistPdf.cxx:250
 RooHistPdf.cxx:251
 RooHistPdf.cxx:252
 RooHistPdf.cxx:253
 RooHistPdf.cxx:254
 RooHistPdf.cxx:255
 RooHistPdf.cxx:256
 RooHistPdf.cxx:257
 RooHistPdf.cxx:258
 RooHistPdf.cxx:259
 RooHistPdf.cxx:260
 RooHistPdf.cxx:261
 RooHistPdf.cxx:262
 RooHistPdf.cxx:263
 RooHistPdf.cxx:264
 RooHistPdf.cxx:265
 RooHistPdf.cxx:266
 RooHistPdf.cxx:267
 RooHistPdf.cxx:268
 RooHistPdf.cxx:269
 RooHistPdf.cxx:270
 RooHistPdf.cxx:271
 RooHistPdf.cxx:272
 RooHistPdf.cxx:273
 RooHistPdf.cxx:274
 RooHistPdf.cxx:275
 RooHistPdf.cxx:276
 RooHistPdf.cxx:277
 RooHistPdf.cxx:278
 RooHistPdf.cxx:279
 RooHistPdf.cxx:280
 RooHistPdf.cxx:281
 RooHistPdf.cxx:282
 RooHistPdf.cxx:283
 RooHistPdf.cxx:284
 RooHistPdf.cxx:285
 RooHistPdf.cxx:286
 RooHistPdf.cxx:287
 RooHistPdf.cxx:288
 RooHistPdf.cxx:289
 RooHistPdf.cxx:290
 RooHistPdf.cxx:291
 RooHistPdf.cxx:292
 RooHistPdf.cxx:293
 RooHistPdf.cxx:294
 RooHistPdf.cxx:295
 RooHistPdf.cxx:296
 RooHistPdf.cxx:297
 RooHistPdf.cxx:298
 RooHistPdf.cxx:299
 RooHistPdf.cxx:300
 RooHistPdf.cxx:301
 RooHistPdf.cxx:302
 RooHistPdf.cxx:303
 RooHistPdf.cxx:304
 RooHistPdf.cxx:305
 RooHistPdf.cxx:306
 RooHistPdf.cxx:307
 RooHistPdf.cxx:308
 RooHistPdf.cxx:309
 RooHistPdf.cxx:310
 RooHistPdf.cxx:311
 RooHistPdf.cxx:312
 RooHistPdf.cxx:313
 RooHistPdf.cxx:314
 RooHistPdf.cxx:315
 RooHistPdf.cxx:316
 RooHistPdf.cxx:317
 RooHistPdf.cxx:318
 RooHistPdf.cxx:319
 RooHistPdf.cxx:320
 RooHistPdf.cxx:321
 RooHistPdf.cxx:322
 RooHistPdf.cxx:323
 RooHistPdf.cxx:324
 RooHistPdf.cxx:325
 RooHistPdf.cxx:326
 RooHistPdf.cxx:327
 RooHistPdf.cxx:328
 RooHistPdf.cxx:329
 RooHistPdf.cxx:330
 RooHistPdf.cxx:331
 RooHistPdf.cxx:332
 RooHistPdf.cxx:333
 RooHistPdf.cxx:334
 RooHistPdf.cxx:335
 RooHistPdf.cxx:336
 RooHistPdf.cxx:337
 RooHistPdf.cxx:338
 RooHistPdf.cxx:339
 RooHistPdf.cxx:340
 RooHistPdf.cxx:341
 RooHistPdf.cxx:342
 RooHistPdf.cxx:343
 RooHistPdf.cxx:344
 RooHistPdf.cxx:345
 RooHistPdf.cxx:346
 RooHistPdf.cxx:347
 RooHistPdf.cxx:348
 RooHistPdf.cxx:349
 RooHistPdf.cxx:350
 RooHistPdf.cxx:351
 RooHistPdf.cxx:352
 RooHistPdf.cxx:353
 RooHistPdf.cxx:354
 RooHistPdf.cxx:355
 RooHistPdf.cxx:356
 RooHistPdf.cxx:357
 RooHistPdf.cxx:358
 RooHistPdf.cxx:359
 RooHistPdf.cxx:360
 RooHistPdf.cxx:361
 RooHistPdf.cxx:362
 RooHistPdf.cxx:363
 RooHistPdf.cxx:364
 RooHistPdf.cxx:365
 RooHistPdf.cxx:366
 RooHistPdf.cxx:367
 RooHistPdf.cxx:368
 RooHistPdf.cxx:369
 RooHistPdf.cxx:370
 RooHistPdf.cxx:371
 RooHistPdf.cxx:372
 RooHistPdf.cxx:373
 RooHistPdf.cxx:374
 RooHistPdf.cxx:375
 RooHistPdf.cxx:376
 RooHistPdf.cxx:377
 RooHistPdf.cxx:378
 RooHistPdf.cxx:379
 RooHistPdf.cxx:380
 RooHistPdf.cxx:381
 RooHistPdf.cxx:382
 RooHistPdf.cxx:383
 RooHistPdf.cxx:384
 RooHistPdf.cxx:385
 RooHistPdf.cxx:386
 RooHistPdf.cxx:387
 RooHistPdf.cxx:388
 RooHistPdf.cxx:389
 RooHistPdf.cxx:390
 RooHistPdf.cxx:391
 RooHistPdf.cxx:392
 RooHistPdf.cxx:393
 RooHistPdf.cxx:394
 RooHistPdf.cxx:395
 RooHistPdf.cxx:396
 RooHistPdf.cxx:397
 RooHistPdf.cxx:398
 RooHistPdf.cxx:399
 RooHistPdf.cxx:400
 RooHistPdf.cxx:401
 RooHistPdf.cxx:402
 RooHistPdf.cxx:403
 RooHistPdf.cxx:404
 RooHistPdf.cxx:405
 RooHistPdf.cxx:406
 RooHistPdf.cxx:407
 RooHistPdf.cxx:408
 RooHistPdf.cxx:409
 RooHistPdf.cxx:410
 RooHistPdf.cxx:411
 RooHistPdf.cxx:412
 RooHistPdf.cxx:413
 RooHistPdf.cxx:414
 RooHistPdf.cxx:415
 RooHistPdf.cxx:416
 RooHistPdf.cxx:417
 RooHistPdf.cxx:418
 RooHistPdf.cxx:419
 RooHistPdf.cxx:420
 RooHistPdf.cxx:421
 RooHistPdf.cxx:422
 RooHistPdf.cxx:423
 RooHistPdf.cxx:424
 RooHistPdf.cxx:425
 RooHistPdf.cxx:426
 RooHistPdf.cxx:427
 RooHistPdf.cxx:428
 RooHistPdf.cxx:429
 RooHistPdf.cxx:430
 RooHistPdf.cxx:431
 RooHistPdf.cxx:432
 RooHistPdf.cxx:433
 RooHistPdf.cxx:434
 RooHistPdf.cxx:435
 RooHistPdf.cxx:436
 RooHistPdf.cxx:437
 RooHistPdf.cxx:438
 RooHistPdf.cxx:439
 RooHistPdf.cxx:440
 RooHistPdf.cxx:441
 RooHistPdf.cxx:442
 RooHistPdf.cxx:443
 RooHistPdf.cxx:444
 RooHistPdf.cxx:445
 RooHistPdf.cxx:446
 RooHistPdf.cxx:447
 RooHistPdf.cxx:448
 RooHistPdf.cxx:449
 RooHistPdf.cxx:450
 RooHistPdf.cxx:451
 RooHistPdf.cxx:452
 RooHistPdf.cxx:453
 RooHistPdf.cxx:454
 RooHistPdf.cxx:455
 RooHistPdf.cxx:456
 RooHistPdf.cxx:457
 RooHistPdf.cxx:458
 RooHistPdf.cxx:459
 RooHistPdf.cxx:460
 RooHistPdf.cxx:461
 RooHistPdf.cxx:462
 RooHistPdf.cxx:463
 RooHistPdf.cxx:464
 RooHistPdf.cxx:465
 RooHistPdf.cxx:466
 RooHistPdf.cxx:467
 RooHistPdf.cxx:468
 RooHistPdf.cxx:469
 RooHistPdf.cxx:470
 RooHistPdf.cxx:471
 RooHistPdf.cxx:472
 RooHistPdf.cxx:473
 RooHistPdf.cxx:474
 RooHistPdf.cxx:475
 RooHistPdf.cxx:476
 RooHistPdf.cxx:477
 RooHistPdf.cxx:478
 RooHistPdf.cxx:479
 RooHistPdf.cxx:480
 RooHistPdf.cxx:481
 RooHistPdf.cxx:482
 RooHistPdf.cxx:483
 RooHistPdf.cxx:484
 RooHistPdf.cxx:485
 RooHistPdf.cxx:486
 RooHistPdf.cxx:487
 RooHistPdf.cxx:488
 RooHistPdf.cxx:489
 RooHistPdf.cxx:490
 RooHistPdf.cxx:491
 RooHistPdf.cxx:492
 RooHistPdf.cxx:493
 RooHistPdf.cxx:494
 RooHistPdf.cxx:495
 RooHistPdf.cxx:496
 RooHistPdf.cxx:497
 RooHistPdf.cxx:498
 RooHistPdf.cxx:499
 RooHistPdf.cxx:500
 RooHistPdf.cxx:501
 RooHistPdf.cxx:502
 RooHistPdf.cxx:503
 RooHistPdf.cxx:504
 RooHistPdf.cxx:505
 RooHistPdf.cxx:506
 RooHistPdf.cxx:507
 RooHistPdf.cxx:508
 RooHistPdf.cxx:509
 RooHistPdf.cxx:510
 RooHistPdf.cxx:511
 RooHistPdf.cxx:512
 RooHistPdf.cxx:513
 RooHistPdf.cxx:514
 RooHistPdf.cxx:515
 RooHistPdf.cxx:516
 RooHistPdf.cxx:517
 RooHistPdf.cxx:518
 RooHistPdf.cxx:519
 RooHistPdf.cxx:520
 RooHistPdf.cxx:521
 RooHistPdf.cxx:522
 RooHistPdf.cxx:523
 RooHistPdf.cxx:524
 RooHistPdf.cxx:525
 RooHistPdf.cxx:526
 RooHistPdf.cxx:527
 RooHistPdf.cxx:528
 RooHistPdf.cxx:529
 RooHistPdf.cxx:530
 RooHistPdf.cxx:531
 RooHistPdf.cxx:532
 RooHistPdf.cxx:533
 RooHistPdf.cxx:534
 RooHistPdf.cxx:535
 RooHistPdf.cxx:536
 RooHistPdf.cxx:537
 RooHistPdf.cxx:538
 RooHistPdf.cxx:539
 RooHistPdf.cxx:540
 RooHistPdf.cxx:541
 RooHistPdf.cxx:542
 RooHistPdf.cxx:543
 RooHistPdf.cxx:544
 RooHistPdf.cxx:545
 RooHistPdf.cxx:546
 RooHistPdf.cxx:547
 RooHistPdf.cxx:548
 RooHistPdf.cxx:549
 RooHistPdf.cxx:550
 RooHistPdf.cxx:551
 RooHistPdf.cxx:552
 RooHistPdf.cxx:553
 RooHistPdf.cxx:554
 RooHistPdf.cxx:555
 RooHistPdf.cxx:556
 RooHistPdf.cxx:557
 RooHistPdf.cxx:558
 RooHistPdf.cxx:559
 RooHistPdf.cxx:560
 RooHistPdf.cxx:561
 RooHistPdf.cxx:562
 RooHistPdf.cxx:563
 RooHistPdf.cxx:564
 RooHistPdf.cxx:565
 RooHistPdf.cxx:566
 RooHistPdf.cxx:567
 RooHistPdf.cxx:568
 RooHistPdf.cxx:569
 RooHistPdf.cxx:570
 RooHistPdf.cxx:571
 RooHistPdf.cxx:572
 RooHistPdf.cxx:573
 RooHistPdf.cxx:574
 RooHistPdf.cxx:575
 RooHistPdf.cxx:576
 RooHistPdf.cxx:577
 RooHistPdf.cxx:578
 RooHistPdf.cxx:579
 RooHistPdf.cxx:580
 RooHistPdf.cxx:581
 RooHistPdf.cxx:582
 RooHistPdf.cxx:583
 RooHistPdf.cxx:584
 RooHistPdf.cxx:585
 RooHistPdf.cxx:586
 RooHistPdf.cxx:587
 RooHistPdf.cxx:588
 RooHistPdf.cxx:589
 RooHistPdf.cxx:590
 RooHistPdf.cxx:591
 RooHistPdf.cxx:592
 RooHistPdf.cxx:593
 RooHistPdf.cxx:594
 RooHistPdf.cxx:595
 RooHistPdf.cxx:596
 RooHistPdf.cxx:597
 RooHistPdf.cxx:598
 RooHistPdf.cxx:599
 RooHistPdf.cxx:600
 RooHistPdf.cxx:601
 RooHistPdf.cxx:602
 RooHistPdf.cxx:603
 RooHistPdf.cxx:604
 RooHistPdf.cxx:605
 RooHistPdf.cxx:606
 RooHistPdf.cxx:607
 RooHistPdf.cxx:608
 RooHistPdf.cxx:609
 RooHistPdf.cxx:610
 RooHistPdf.cxx:611
 RooHistPdf.cxx:612
 RooHistPdf.cxx:613
 RooHistPdf.cxx:614
 RooHistPdf.cxx:615
 RooHistPdf.cxx:616