Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RooStepFunction.cxx
Go to the documentation of this file.
1 
2 /*****************************************************************************
3  * Project: RooFit *
4  * Package: RooFitBabar *
5  * @(#)root/roofit:$Id$
6  * Author: *
7  * Tristan du Pree, Nikhef, Amsterdam, tdupree@nikhef.nl *
8  * Wouter Verkerke, Nikhef, Amsterdam, verkerke@nikhef.nl
9  * *
10  * Copyright (c) 2009, NIKHEF. All rights reserved. *
11  *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 
17 /** \class RooStepFunction
18  \ingroup Roofit
19 
20 The Step Function is a binned function whose parameters
21 are the heights of each bin.
22 
23 This function may be used to describe oddly shaped distributions. A RooStepFunction
24 has free parameters. In particular, any statistical uncertainty
25 used to model this efficiency may be understood with these free parameters.
26 
27 Note that in contrast to RooParametricStepFunction, a RooStepFunction is NOT a PDF,
28 but a not-normalized function (RooAbsReal)
29 **/
30 
31 #include "RooFit.h"
32 
33 #include "Riostream.h"
34 #include "TArrayD.h"
35 #include <math.h>
36 
37 #include "RooStepFunction.h"
38 #include "RooAbsReal.h"
39 #include "RooRealVar.h"
40 #include "RooArgList.h"
41 #include "RooMsgService.h"
42 #include "RooMath.h"
43 
44 using namespace std;
45 
46 ClassImp(RooStepFunction);
47 
48 ////////////////////////////////////////////////////////////////////////////////
49 /// Constructor
50 
51 RooStepFunction::RooStepFunction()
52 {
53  _coefIter = _coefList.createIterator() ;
54  _boundIter = _boundaryList.createIterator() ;
55  _interpolate = kFALSE ;
56 }
57 
58 ////////////////////////////////////////////////////////////////////////////////
59 /// Constructor
60 
61 RooStepFunction::RooStepFunction(const char* name, const char* title,
62  RooAbsReal& x, const RooArgList& coefList, const RooArgList& boundaryList, Bool_t interpolate) :
63  RooAbsReal(name, title),
64  _x("x", "Dependent", this, x),
65  _coefList("coefList","List of coefficients",this),
66  _boundaryList("boundaryList","List of boundaries",this),
67  _interpolate(interpolate)
68 {
69  _coefIter = _coefList.createIterator() ;
70  TIterator* coefIter = coefList.createIterator() ;
71  RooAbsArg* coef ;
72  while((coef = (RooAbsArg*)coefIter->Next())) {
73  if (!dynamic_cast<RooAbsReal*>(coef)) {
74  cout << "RooStepFunction::ctor(" << GetName() << ") ERROR: coefficient " << coef->GetName()
75  << " is not of type RooAbsReal" << endl ;
76  assert(0) ;
77  }
78  _coefList.add(*coef) ;
79  }
80  delete coefIter ;
81 
82  _boundIter = _boundaryList.createIterator() ;
83  TIterator* boundaryIter = boundaryList.createIterator() ;
84  RooAbsArg* boundary ;
85  while((boundary = (RooAbsArg*)boundaryIter->Next())) {
86  if (!dynamic_cast<RooAbsReal*>(boundary)) {
87  cout << "RooStepFunction::ctor(" << GetName() << ") ERROR: boundary " << boundary->GetName()
88  << " is not of type RooAbsReal" << endl ;
89  assert(0) ;
90  }
91  _boundaryList.add(*boundary) ;
92  }
93 
94  if (_boundaryList.getSize()!=_coefList.getSize()+1) {
95  coutE(InputArguments) << "RooStepFunction::ctor(" << GetName() << ") ERROR: Number of boundaries must be number of coefficients plus 1" << endl ;
96  throw string("RooStepFunction::ctor() ERROR: Number of boundaries must be number of coefficients plus 1") ;
97  }
98 
99 }
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 /// Copy constructor
103 
104 RooStepFunction::RooStepFunction(const RooStepFunction& other, const char* name) :
105  RooAbsReal(other, name),
106  _x("x", this, other._x),
107  _coefList("coefList",this,other._coefList),
108  _boundaryList("boundaryList",this,other._boundaryList),
109  _interpolate(other._interpolate)
110 {
111  _coefIter = _coefList.createIterator();
112  _boundIter = _boundaryList.createIterator();
113 }
114 
115 ////////////////////////////////////////////////////////////////////////////////
116 /// Destructor
117 
118 RooStepFunction::~RooStepFunction()
119 {
120  delete _coefIter ;
121  delete _boundIter ;
122 }
123 
124 ////////////////////////////////////////////////////////////////////////////////
125 /// Transfer contents to vector for use below
126 
127 Double_t RooStepFunction::evaluate() const
128 {
129  vector<double> b(_boundaryList.getSize()) ;
130  vector<double> c(_coefList.getSize()+3) ;
131  Int_t nb(0) ;
132  _boundIter->Reset() ;
133  RooAbsReal* boundary ;
134  while ((boundary=(RooAbsReal*)_boundIter->Next())) {
135  b[nb++] = boundary->getVal() ;
136  }
137 
138  // Return zero if outside any boundaries
139  if ((_x<b[0]) || (_x>b[nb-1])) return 0 ;
140 
141  if (!_interpolate) {
142 
143  // No interpolation -- Return values bin-by-bin
144  for (Int_t i=0;i<nb-1;i++){
145  if (_x>b[i]&&_x<=b[i+1]) {
146  return ((RooAbsReal*)_coefList.at(i))->getVal() ;
147  }
148  }
149  return 0 ;
150 
151  } else {
152 
153  // Interpolation
154 
155  // Make array of (b[0],bin centers,b[last])
156  c[0] = b[0] ; c[nb] = b[nb-1] ;
157  for (Int_t i=0 ; i<nb-1 ; i++) {
158  c[i+1] = (b[i]+b[i+1])/2 ;
159  }
160 
161  // Make array of (0,coefficient values,0)
162  Int_t nc(0) ;
163  _coefIter->Reset() ;
164  RooAbsReal* coef ;
165  vector<double> y(_coefList.getSize()+3) ;
166  y[nc++] = 0 ;
167  while ((coef=(RooAbsReal*)_coefIter->Next())) {
168  y[nc++] = coef->getVal() ;
169  }
170  y[nc++] = 0 ;
171 
172  for (Int_t i=0;i<nc-1;i++){
173  if (_x>c[i]&&_x<=c[i+1]) {
174  Double_t xx[2] ; xx[0]=c[i] ; xx[1]=c[i+1] ;
175  Double_t yy[2] ; yy[0]=y[i] ; yy[1]=y[i+1] ;
176  return RooMath::interpolate(xx,yy,2,_x) ;
177  }
178  }
179  return 0;
180  }
181 }