/*****************************************************************************
 * 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)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// 
// BEGIN_HTML
// Class RooFoamGenerator is a generic toy monte carlo generator that implement
// the TFOAM sampling technique on any positively valued function.
// The RooFoamGenerator generator is used by the various generator context
// classes to take care of generation of observables for which p.d.fs
// do not define internal methods
// END_HTML
//


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

#include "RooFoamGenerator.h"
#include "RooAbsReal.h"
#include "RooCategory.h"
#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooRandom.h"
#include "RooErrorHandler.h"

#include "TString.h"
#include "TIterator.h"
#include "RooMsgService.h"
#include "TClass.h"
#include "TFoam.h"
#include "RooTFoamBinding.h"
#include "RooNumGenFactory.h"
#include "RooNumGenConfig.h"

#include <assert.h>

using namespace std;

ClassImp(RooFoamGenerator)
  ;


//_____________________________________________________________________________
void RooFoamGenerator::registerSampler(RooNumGenFactory& fact)
{
  // Register RooIntegrator1D, is parameters and capabilities with RooNumIntFactory

  // Register RooIntegrator1D, is parameters and capabilities with RooNumIntFactory
  RooRealVar nSample("nSample","Number of samples per cell",200,0,1e6) ;
  RooRealVar nCell1D("nCell1D","Number of cells for 1-dim generation",30,0,1e6) ;
  RooRealVar nCell2D("nCell2D","Number of cells for 2-dim generation",500,0,1e6) ;
  RooRealVar nCell3D("nCell3D","Number of cells for 3-dim generation",5000,0,1e6) ;
  RooRealVar nCellND("nCellND","Number of cells for N-dim generation",10000,0,1e6) ;
  RooRealVar chatLevel("chatLevel","TFOAM 'chat level' (verbosity)",0,0,2) ;

  RooFoamGenerator* proto = new RooFoamGenerator ;
  fact.storeProtoSampler(proto,RooArgSet(nSample,nCell1D,nCell2D,nCell3D,nCellND,chatLevel)) ;
}




//_____________________________________________________________________________
RooFoamGenerator::RooFoamGenerator(const RooAbsReal &func, const RooArgSet &genVars, const RooNumGenConfig& config, Bool_t verbose, const RooAbsReal* maxFuncVal) :
  RooAbsNumGenerator(func,genVars,verbose,maxFuncVal)
{
  _rvIter = _realVars.createIterator() ;
  _binding = new RooTFoamBinding(*_funcClone,_realVars) ;
 
  _tfoam = new TFoam("TFOAM") ;
  _tfoam->SetkDim(_realVars.getSize()) ;
  _tfoam->SetRho(_binding) ;
  _tfoam->SetPseRan(RooRandom::randomGenerator()) ;
  switch(_realVars.getSize()) {
  case 1:_tfoam->SetnCells((Int_t)config.getConfigSection("RooFoamGenerator").getRealValue("nCell1D")) ; break ;
  case 2:_tfoam->SetnCells((Int_t)config.getConfigSection("RooFoamGenerator").getRealValue("nCell2D")) ; break ;
  case 3:_tfoam->SetnCells((Int_t)config.getConfigSection("RooFoamGenerator").getRealValue("nCell3D")) ; break ;
  default:_tfoam->SetnCells((Int_t)config.getConfigSection("RooFoamGenerator").getRealValue("nCellND")) ; break ;
  }
  _tfoam->SetnSampl((Int_t)config.getConfigSection("RooFoamGenerator").getRealValue("nSample")) ;
  _tfoam->SetPseRan(RooRandom::randomGenerator()) ;
  _tfoam->SetChat((Int_t)config.getConfigSection("RooFoamGenerator").getRealValue("chatLevel")) ;
  _tfoam->Initialize() ;

  _vec = new Double_t[_realVars.getSize()] ;
  _xmin  = new Double_t[_realVars.getSize()] ;
  _range = new Double_t[_realVars.getSize()] ;
  
  TIterator* iter = _realVars.createIterator() ;
  RooRealVar* var ;
  Int_t i(0) ;
  while((var=(RooRealVar*)iter->Next())) {
    _xmin[i] = var->getMin() ;
    _range[i] = var->getMax() - var->getMin() ;
    i++ ;
  }
  delete iter ;

}


//_____________________________________________________________________________
RooFoamGenerator::~RooFoamGenerator() 
{
  // Destructor
  delete[] _vec ;
  delete[] _xmin ;
  delete[] _range ;
  delete _tfoam ;
  delete _binding ;
  delete _rvIter ;
}



//_____________________________________________________________________________
const RooArgSet *RooFoamGenerator::generateEvent(UInt_t /*remaining*/, Double_t& /*resampleRatio*/) 
{
  // are we actually generating anything? (the cache always contains at least our function value)
  const RooArgSet *event= _cache->get();
  if(event->getSize() == 1) return event;

  _tfoam->MakeEvent() ;
  _tfoam->GetMCvect(_vec) ;
  
  // Transfer contents to dataset
  RooRealVar* var ;  
  _rvIter->Reset() ;
  Int_t i(0) ;
  while((var=(RooRealVar*)_rvIter->Next())) {
    var->setVal(_xmin[i] + _range[i]*_vec[i]) ;
    i++ ;
  }
  return &_realVars ;
}
 RooFoamGenerator.cxx:1
 RooFoamGenerator.cxx:2
 RooFoamGenerator.cxx:3
 RooFoamGenerator.cxx:4
 RooFoamGenerator.cxx:5
 RooFoamGenerator.cxx:6
 RooFoamGenerator.cxx:7
 RooFoamGenerator.cxx:8
 RooFoamGenerator.cxx:9
 RooFoamGenerator.cxx:10
 RooFoamGenerator.cxx:11
 RooFoamGenerator.cxx:12
 RooFoamGenerator.cxx:13
 RooFoamGenerator.cxx:14
 RooFoamGenerator.cxx:15
 RooFoamGenerator.cxx:16
 RooFoamGenerator.cxx:17
 RooFoamGenerator.cxx:18
 RooFoamGenerator.cxx:19
 RooFoamGenerator.cxx:20
 RooFoamGenerator.cxx:21
 RooFoamGenerator.cxx:22
 RooFoamGenerator.cxx:23
 RooFoamGenerator.cxx:24
 RooFoamGenerator.cxx:25
 RooFoamGenerator.cxx:26
 RooFoamGenerator.cxx:27
 RooFoamGenerator.cxx:28
 RooFoamGenerator.cxx:29
 RooFoamGenerator.cxx:30
 RooFoamGenerator.cxx:31
 RooFoamGenerator.cxx:32
 RooFoamGenerator.cxx:33
 RooFoamGenerator.cxx:34
 RooFoamGenerator.cxx:35
 RooFoamGenerator.cxx:36
 RooFoamGenerator.cxx:37
 RooFoamGenerator.cxx:38
 RooFoamGenerator.cxx:39
 RooFoamGenerator.cxx:40
 RooFoamGenerator.cxx:41
 RooFoamGenerator.cxx:42
 RooFoamGenerator.cxx:43
 RooFoamGenerator.cxx:44
 RooFoamGenerator.cxx:45
 RooFoamGenerator.cxx:46
 RooFoamGenerator.cxx:47
 RooFoamGenerator.cxx:48
 RooFoamGenerator.cxx:49
 RooFoamGenerator.cxx:50
 RooFoamGenerator.cxx:51
 RooFoamGenerator.cxx:52
 RooFoamGenerator.cxx:53
 RooFoamGenerator.cxx:54
 RooFoamGenerator.cxx:55
 RooFoamGenerator.cxx:56
 RooFoamGenerator.cxx:57
 RooFoamGenerator.cxx:58
 RooFoamGenerator.cxx:59
 RooFoamGenerator.cxx:60
 RooFoamGenerator.cxx:61
 RooFoamGenerator.cxx:62
 RooFoamGenerator.cxx:63
 RooFoamGenerator.cxx:64
 RooFoamGenerator.cxx:65
 RooFoamGenerator.cxx:66
 RooFoamGenerator.cxx:67
 RooFoamGenerator.cxx:68
 RooFoamGenerator.cxx:69
 RooFoamGenerator.cxx:70
 RooFoamGenerator.cxx:71
 RooFoamGenerator.cxx:72
 RooFoamGenerator.cxx:73
 RooFoamGenerator.cxx:74
 RooFoamGenerator.cxx:75
 RooFoamGenerator.cxx:76
 RooFoamGenerator.cxx:77
 RooFoamGenerator.cxx:78
 RooFoamGenerator.cxx:79
 RooFoamGenerator.cxx:80
 RooFoamGenerator.cxx:81
 RooFoamGenerator.cxx:82
 RooFoamGenerator.cxx:83
 RooFoamGenerator.cxx:84
 RooFoamGenerator.cxx:85
 RooFoamGenerator.cxx:86
 RooFoamGenerator.cxx:87
 RooFoamGenerator.cxx:88
 RooFoamGenerator.cxx:89
 RooFoamGenerator.cxx:90
 RooFoamGenerator.cxx:91
 RooFoamGenerator.cxx:92
 RooFoamGenerator.cxx:93
 RooFoamGenerator.cxx:94
 RooFoamGenerator.cxx:95
 RooFoamGenerator.cxx:96
 RooFoamGenerator.cxx:97
 RooFoamGenerator.cxx:98
 RooFoamGenerator.cxx:99
 RooFoamGenerator.cxx:100
 RooFoamGenerator.cxx:101
 RooFoamGenerator.cxx:102
 RooFoamGenerator.cxx:103
 RooFoamGenerator.cxx:104
 RooFoamGenerator.cxx:105
 RooFoamGenerator.cxx:106
 RooFoamGenerator.cxx:107
 RooFoamGenerator.cxx:108
 RooFoamGenerator.cxx:109
 RooFoamGenerator.cxx:110
 RooFoamGenerator.cxx:111
 RooFoamGenerator.cxx:112
 RooFoamGenerator.cxx:113
 RooFoamGenerator.cxx:114
 RooFoamGenerator.cxx:115
 RooFoamGenerator.cxx:116
 RooFoamGenerator.cxx:117
 RooFoamGenerator.cxx:118
 RooFoamGenerator.cxx:119
 RooFoamGenerator.cxx:120
 RooFoamGenerator.cxx:121
 RooFoamGenerator.cxx:122
 RooFoamGenerator.cxx:123
 RooFoamGenerator.cxx:124
 RooFoamGenerator.cxx:125
 RooFoamGenerator.cxx:126
 RooFoamGenerator.cxx:127
 RooFoamGenerator.cxx:128
 RooFoamGenerator.cxx:129
 RooFoamGenerator.cxx:130
 RooFoamGenerator.cxx:131
 RooFoamGenerator.cxx:132
 RooFoamGenerator.cxx:133
 RooFoamGenerator.cxx:134
 RooFoamGenerator.cxx:135
 RooFoamGenerator.cxx:136
 RooFoamGenerator.cxx:137
 RooFoamGenerator.cxx:138
 RooFoamGenerator.cxx:139
 RooFoamGenerator.cxx:140
 RooFoamGenerator.cxx:141
 RooFoamGenerator.cxx:142
 RooFoamGenerator.cxx:143
 RooFoamGenerator.cxx:144
 RooFoamGenerator.cxx:145
 RooFoamGenerator.cxx:146
 RooFoamGenerator.cxx:147
 RooFoamGenerator.cxx:148
 RooFoamGenerator.cxx:149