ROOT logo
 /***************************************************************************** 
  * Project: RooFit                                                           * 
  *                                                                           * 
  * 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 RooNumRunningInt is an implementation of RooAbsCachedReal that represents a running integral
// <pre>
// RI(f(x)) = Int[x_lo,x] f(x') dx'
// </pre>
// that is calculated internally with a numeric technique: The input function
// is first sampled into a histogram, which is then numerically integrated.
// The output function is an interpolated version of the integrated histogram.
// The sampling density is controlled by the binning named "cache" in the observable x.
// The shape of the p.d.f is always calculated for the entire domain in x and
// cached in a histogram. The cache histogram is automatically recalculated
// when any of the parameters of the input p.d.f. has changed.
// END_HTML
//

#include "Riostream.h" 

#include "RooAbsPdf.h"
#include "RooNumRunningInt.h" 
#include "RooAbsReal.h" 
#include "RooMsgService.h"
#include "RooDataHist.h"
#include "RooHistPdf.h"
#include "RooRealVar.h"

ClassImp(RooNumRunningInt) 
  ;



//_____________________________________________________________________________
RooNumRunningInt::RooNumRunningInt(const char *name, const char *title, RooAbsReal& _func, RooRealVar& _x, const char* bname) :
   RooAbsCachedReal(name,title), 
   func("func","func",this,_func),
   x("x","x",this,_x),
   _binningName(bname?bname:"cache")
 { 
   // Construct running integral of function '_func' over x_print from
   // the lower bound on _x to the present value of _x using a numeric
   // sampling technique. The sampling frequency is controlled by the
   // binning named 'bname' and a default second order interpolation
   // is applied to smooth the histogram-based c.d.f.

   setInterpolationOrder(2) ;
 } 




//_____________________________________________________________________________
RooNumRunningInt::RooNumRunningInt(const RooNumRunningInt& other, const char* name) :  
   RooAbsCachedReal(other,name), 
   func("func",this,other.func),
   x("x",this,other.x),
   _binningName(other._binningName)
 { 
   // Copy constructor
 } 



//_____________________________________________________________________________
RooNumRunningInt::~RooNumRunningInt() 
{
  // Destructor
}


//_____________________________________________________________________________
const char* RooNumRunningInt::inputBaseName() const 
{
  // Return unique name for RooAbsCachedPdf cache components
  // constructed from input function name

  static string ret ;
  ret = func.arg().GetName() ;
  ret += "_NUMRUNINT" ;
  return ret.c_str() ;
} ;



//_____________________________________________________________________________
RooNumRunningInt::RICacheElem::RICacheElem(const RooNumRunningInt& self, const RooArgSet* nset) : 
  FuncCacheElem(self,nset), _self(&const_cast<RooNumRunningInt&>(self))
{
  // Construct RunningIntegral CacheElement
  
  // Instantiate temp arrays
  _ax = new Double_t[hist()->numEntries()] ;
  _ay = new Double_t[hist()->numEntries()] ;

  // Copy X values from histo  
  _xx = (RooRealVar*) hist()->get()->find(self.x.arg().GetName()) ;
  for (int i=0 ; i<hist()->numEntries() ; i++) {
    hist()->get(i) ;
    _ax[i] = _xx->getVal() ;
    _ay[i] = -1 ;
  }

}


//_____________________________________________________________________________
RooNumRunningInt::RICacheElem::~RICacheElem() 
{
  // Destructor

  // Delete temp arrays 
  delete[] _ax ;
  delete[] _ay ;    
}


//_____________________________________________________________________________
RooArgList RooNumRunningInt::RICacheElem::containedArgs(Action action) 
{
  // Return all RooAbsArg components contained in cache element

  RooArgList ret ;
  ret.add(FuncCacheElem::containedArgs(action)) ;
  ret.add(*_self) ;
  ret.add(*_xx) ;
  return ret ;  
}



//_____________________________________________________________________________
void RooNumRunningInt::RICacheElem::calculate(Bool_t cdfmode) 
{
  // Calculate the numeric running integral and store
  // the result in the cache histogram provided
  // by RooAbsCachedPdf

  // Update contents of histogram
  Int_t nbins = hist()->numEntries() ;
  
  Double_t xsave = _self->x ;

  Int_t lastHi=0 ;
  Int_t nInitRange=32 ;
  for (int i=1 ; i<=nInitRange ; i++) {
    Int_t hi = (i*nbins)/nInitRange -1 ;
    Int_t lo = lastHi ;
    addRange(lo,hi,nbins) ;
    lastHi=hi ;
  }

  // Perform numeric integration
  for (int i=1 ; i<nbins ; i++) {
    _ay[i] += _ay[i-1] ;
  }
 
  // Normalize and transfer to cache histogram
  Double_t binv = (_self->x.max()-_self->x.min())/nbins ;
  for (int i=0 ; i<nbins ; i++) {
    hist()->get(i) ;
    if (cdfmode) {
      hist()->set(_ay[i]/_ay[nbins-1]) ;
    } else {
      hist()->set(_ay[i]*binv) ;
    }
  }

  if (cdfmode) {
    func()->setCdfBoundaries(kTRUE) ;
  }
  _self->x = xsave ;
}



//_____________________________________________________________________________
void RooNumRunningInt::RICacheElem::addRange(Int_t ixlo, Int_t ixhi, Int_t nbins) 
{
  // Fill all empty histogram bins in the range [ixlo,ixhi] where nbins is the
  // total number of histogram bins. This method samples the mid-point of the
  // range and if the mid-point value is within small tolerance of the interpolated
  // mid-point value fills all remaining elements through linear interpolation.
  // If the tolerance is exceeded, the algorithm is recursed on the two subranges
  // [xlo,xmid] and [xmid,xhi]

  // Add first and last point, if not there already
  if (_ay[ixlo]<0) {
    addPoint(ixlo) ;
  }
  if (_ay[ixhi]<0) {
    addPoint(ixhi) ;
  }

  // Terminate here if there is no gap
  if (ixhi-ixlo==1) {
    return ;
  }

  // If gap size is one, simply fill gap and return
  if (ixhi-ixlo==2) {
    addPoint(ixlo+1) ;
    return ;
  }

  // Add mid-point
  Int_t ixmid = (ixlo+ixhi)/2 ;
  addPoint(ixmid) ;
  
  // Calculate difference of mid-point w.r.t interpolated value
  Double_t yInt = _ay[ixlo] + (_ay[ixhi]-_ay[ixlo])*(ixmid-ixlo)/(ixhi-ixlo) ;
  
  // If relative deviation is greater than tolerance divide and iterate
  if (fabs(yInt-_ay[ixmid])*(_ax[nbins]-_ax[0])>1e-6) {    
    addRange(ixlo,ixmid,nbins) ;
    addRange(ixmid,ixhi,nbins) ;
  } else {
    for (Int_t j=ixlo+1 ; j<ixmid ; j++) { 
      _ay[j] = _ay[ixlo] + (_ay[ixmid]-_ay[ixlo])*(j-ixlo)/(ixmid-ixlo) ; 
    }
    for (Int_t j=ixmid+1 ; j<ixhi ; j++) { 
      _ay[j] = _ay[ixmid] + (_ay[ixhi]-_ay[ixmid])*(j-ixmid)/(ixhi-ixmid) ; 
    }
  }

}


//_____________________________________________________________________________
void RooNumRunningInt::RICacheElem::addPoint(Int_t ix)
{
  // Sample function at bin ix

  hist()->get(ix) ;
  _self->x = _xx->getVal() ;
  _ay[ix] = _self->func.arg().getVal(*_xx) ;

}



//_____________________________________________________________________________
void RooNumRunningInt::fillCacheObject(RooAbsCachedReal::FuncCacheElem& cache) const 
{
  // Fill the cache object by calling its calculate() method
  RICacheElem& riCache = static_cast<RICacheElem&>(cache) ;
  riCache.calculate(kFALSE) ;
}



//_____________________________________________________________________________
RooArgSet* RooNumRunningInt::actualObservables(const RooArgSet& /*nset*/) const 
{
  // Return observable in nset to be cached by RooAbsCachedPdf
  // this is always the x observable that is integrated

  RooArgSet* ret = new RooArgSet ;
  ret->add(x.arg()) ;
  return ret ;
}



//_____________________________________________________________________________
RooArgSet* RooNumRunningInt::actualParameters(const RooArgSet& /*nset*/) const 
{
  // Return the parameters of the cache created by RooAbsCachedPdf.
  // These are always the input functions parameter, but never the
  // integrated variable x.

  RooArgSet* ret = func.arg().getParameters(RooArgSet()) ;
  ret->remove(x.arg(),kTRUE,kTRUE) ;
  return ret ;
}


//_____________________________________________________________________________
RooAbsCachedReal::FuncCacheElem* RooNumRunningInt::createCache(const RooArgSet* nset) const 
{
  // Create custom cache element for running integral calculations

  return new RICacheElem(*const_cast<RooNumRunningInt*>(this),nset) ; 
}


//_____________________________________________________________________________
Double_t RooNumRunningInt::evaluate() const 
{
  // Dummy function that is never called

  cout << "RooNumRunningInt::evaluate(" << GetName() << ")" << endl ;
  return 0 ;
}


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