ROOT logo
/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 * @(#)root/roofitcore:$Id: RooChi2Var.cxx 29139 2009-06-22 14:31:47Z brun $
 * 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)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// 
// Class RooChi2Var implements a simple chi^2 calculation from a binned dataset
// and a PDF. The chi^2 is calculated as 
//
//             / (f_PDF * N_tot/ V_bin) - N_bin \+2
//  Sum[bins] |  ------------------------------ |
//             \         err_bin                /
//
// If no user-defined errors are defined for the dataset, poisson errors
// are used. In extended PDF mode, N_tot is substituted with N_expected.
//

#include "RooFit.h"

#include "RooChi2Var.h"
#include "RooChi2Var.h"
#include "RooDataHist.h"
#include "RooAbsPdf.h"
#include "RooCmdConfig.h"
#include "RooMsgService.h"

#include "Riostream.h"

#include "RooRealVar.h"


ClassImp(RooChi2Var)
;

RooArgSet RooChi2Var::_emptySet ;


//_____________________________________________________________________________
RooChi2Var::RooChi2Var(const char *name, const char* title, RooAbsReal& func, RooDataHist& hdata,
		       const RooCmdArg& arg1,const RooCmdArg& arg2,const RooCmdArg& arg3,
		       const RooCmdArg& arg4,const RooCmdArg& arg5,const RooCmdArg& arg6,
		       const RooCmdArg& arg7,const RooCmdArg& arg8,const RooCmdArg& arg9) :
  RooAbsOptTestStatistic(name,title,func,hdata,_emptySet,
			 RooCmdConfig::decodeStringOnTheFly("RooChi2Var::RooChi2Var","RangeWithName",0,"",arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
			 0,
			 RooCmdConfig::decodeIntOnTheFly("RooChi2Var::RooChi2Var","NumCPU",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
			 RooCmdConfig::decodeIntOnTheFly("RooChi2Var::RooChi2Var","Verbose",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
			 0)
  //  RooChi2Var constructor. Optional arguments taken
  //
  //  DataError()  -- Choose between Poisson errors and Sum-of-weights errors
  //  NumCPU()     -- Activate parallel processing feature
  //  Range()      -- Fit only selected region
  //  Verbose()    -- Verbose output of GOF framework
{
  RooCmdConfig pc("RooChi2Var::RooChi2Var") ;
  pc.defineInt("etype","DataError",0,(Int_t)RooDataHist::SumW2) ;  
  pc.allowUndefined() ;

  pc.process(arg1) ;  pc.process(arg2) ;  pc.process(arg3) ;
  pc.process(arg4) ;  pc.process(arg5) ;  pc.process(arg6) ;
  pc.process(arg7) ;  pc.process(arg8) ;  pc.process(arg9) ;

  _funcMode = Function ;
  _etype = (RooDataHist::ErrorType) pc.getInt("etype") ;
}



//_____________________________________________________________________________
RooChi2Var::RooChi2Var(const char *name, const char* title, RooAbsPdf& pdf, RooDataHist& hdata,
		       const RooCmdArg& arg1,const RooCmdArg& arg2,const RooCmdArg& arg3,
		       const RooCmdArg& arg4,const RooCmdArg& arg5,const RooCmdArg& arg6,
		       const RooCmdArg& arg7,const RooCmdArg& arg8,const RooCmdArg& arg9) :
  RooAbsOptTestStatistic(name,title,pdf,hdata,
			 *(const RooArgSet*)RooCmdConfig::decodeObjOnTheFly("RooChi2Var::RooChi2Var","ProjectedObservables",0,&_emptySet
									    ,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
			 RooCmdConfig::decodeStringOnTheFly("RooChi2Var::RooChi2Var","RangeWithName",0,"",arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
			 RooCmdConfig::decodeStringOnTheFly("RooChi2Var::RooChi2Var","AddCoefRange",0,"",arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
			 RooCmdConfig::decodeIntOnTheFly("RooChi2Var::RooChi2Var","NumCPU",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
			 RooCmdConfig::decodeIntOnTheFly("RooChi2Var::RooChi2Var","Verbose",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
			 RooCmdConfig::decodeIntOnTheFly("RooChi2Var::RooChi2Var","SplitRange",0,0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9))             
  //  RooChi2Var constructor. Optional arguments taken
  //
  //  Extended()   -- Include extended term in calculation
  //  DataError()  -- Choose between Poisson errors and Sum-of-weights errors
  //  NumCPU()     -- Activate parallel processing feature
  //  Range()      -- Fit only selected region
  //  SumCoefRange() -- Set the range in which to interpret the coefficients of RooAddPdf components 
  //  SplitRange() -- Fit range is split by index catory of simultaneous PDF
  //  ConditionalObservables() -- Define projected observables 
  //  Verbose()    -- Verbose output of GOF framework
{
  RooCmdConfig pc("RooChi2Var::RooChi2Var") ;
  pc.defineInt("extended","Extended",0,kFALSE) ;
  pc.defineInt("etype","DataError",0,(Int_t)RooDataHist::SumW2) ;  
  pc.allowUndefined() ;

  pc.process(arg1) ;  pc.process(arg2) ;  pc.process(arg3) ;
  pc.process(arg4) ;  pc.process(arg5) ;  pc.process(arg6) ;
  pc.process(arg7) ;  pc.process(arg8) ;  pc.process(arg9) ;

  _funcMode = pc.getInt("extended") ? ExtendedPdf : Pdf ;
  _etype = (RooDataHist::ErrorType) pc.getInt("etype") ;
}



//_____________________________________________________________________________
RooChi2Var::RooChi2Var(const char *name, const char *title, RooAbsPdf& pdf, RooDataHist& hdata,
		       Bool_t extended, const char* cutRange, const char* addCoefRange,
		       Int_t nCPU, Bool_t interleave, Bool_t verbose, Bool_t splitCutRange, RooDataHist::ErrorType etype) : 
  RooAbsOptTestStatistic(name,title,pdf,hdata,RooArgSet(),cutRange,addCoefRange,nCPU,interleave,verbose,splitCutRange),
   _etype(etype), _funcMode(extended?ExtendedPdf:Pdf)
{
  // Constructor of a chi2 for given p.d.f. with respect given binned
  // dataset. If cutRange is specified the calculation of the chi2 is
  // restricted to that named range. If addCoefRange is specified, the
  // interpretation of fractions for all component RooAddPdfs that do
  // not have a frozen range interpretation is set to chosen range
  // name. If nCPU is greater than one the chi^2 calculation is
  // paralellized over the specified number of processors. If
  // interleave is true the partitioning of event over processors
  // follows a (i % n == i_set) strategy rather than a bulk
  // partitioning strategy which may result in unequal load balancing
  // in binned datasets with many (adjacent) zero bins. If
  // splitCutRange is true the cutRange is used to construct an
  // individual cutRange for each RooSimultaneous index category state
  // name cutRange_{indexStateName}.
}



//_____________________________________________________________________________
RooChi2Var::RooChi2Var(const char *name, const char *title, RooAbsReal& func, RooDataHist& hdata,
		       const RooArgSet& projDeps, RooChi2Var::FuncMode fmode, const char* cutRange, const char* addCoefRange, 
		       Int_t nCPU, Bool_t interleave, Bool_t verbose, Bool_t splitCutRange, RooDataHist::ErrorType etype) : 
  RooAbsOptTestStatistic(name,title,func,hdata,projDeps,cutRange,addCoefRange,nCPU,interleave,verbose,splitCutRange),
  _etype(etype), _funcMode(fmode)
{
  // Constructor of a chi2 for given p.d.f. with respect given binned
  // dataset taking the observables specified in projDeps as projected
  // observables. If cutRange is specified the calculation of the chi2
  // is restricted to that named range. If addCoefRange is specified,
  // the interpretation of fractions for all component RooAddPdfs that
  // do not have a frozen range interpretation is set to chosen range
  // name. If nCPU is greater than one the chi^2 calculation is
  // paralellized over the specified number of processors. If
  // interleave is true the partitioning of event over processors
  // follows a (i % n == i_set) strategy rather than a bulk
  // partitioning strategy which may result in unequal load balancing
  // in binned datasets with many (adjacent) zero bins. If
  // splitCutRange is true the cutRange is used to construct an
  // individual cutRange for each RooSimultaneous index category state
  // name cutRange_{indexStateName}.
}



//_____________________________________________________________________________
RooChi2Var::RooChi2Var(const RooChi2Var& other, const char* name) : 
  RooAbsOptTestStatistic(other,name),
  _etype(other._etype),
  _funcMode(other._funcMode)
{
  // Copy constructor
}



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



//_____________________________________________________________________________
Double_t RooChi2Var::evaluatePartition(Int_t firstEvent, Int_t lastEvent, Int_t stepSize) const 
{
  // Calculate chi^2 in partition from firstEvent to lastEvent using given stepSize

  Int_t i ;
  Double_t result(0) ;


  // Determine normalization factor depending on type of input function
  Double_t normFactor(Function) ;
  switch (_funcMode) {
  case Function: normFactor=1 ; break ;
  case Pdf: normFactor = _dataClone->sumEntries() ; break ;
  case ExtendedPdf: normFactor = ((RooAbsPdf*)_funcClone)->expectedEvents(_dataClone->get()) ; break ;
  }

  // Loop over bins of dataset
  RooDataHist* hdata = (RooDataHist*) _dataClone ;
    for (i=firstEvent ; i<lastEvent ; i+=stepSize) {
    
    // get the data values for this event
    hdata->get(i);

    if (!hdata->valid()) {
      continue ;
    }

    Double_t nData = hdata->weight() ;

    Double_t nPdf = _funcClone->getVal(_normSet) * normFactor * hdata->binVolume() ;

    Double_t eExt = nPdf-nData ;

    Double_t eIntLo,eIntHi ;
    hdata->weightError(eIntLo,eIntHi,_etype) ;
    Double_t eInt = (eExt>0) ? eIntHi : eIntLo ;

    
    // Skip cases where pdf=0 and there is no data
    if (eInt==0. && nData==0. && nPdf==0) continue ;

    // Return 0 if eInt=0, special handling in MINUIT will follow
    if (eInt==0.) {
      coutE(Eval) << "RooChi2Var::RooChi2Var(" << GetName() << ") INFINITY ERROR: bin " << i 
		  << " has zero error, but function is not zero (" << nPdf << ")" << endl ;
      return 0 ;
    }

    //cout << "Chi2Var[" << i << "] nData = " << nData << " nPdf = " << nPdf << " errorExt = " << eExt << " errorInt = " << eInt << " contrib = " << eExt*eExt/(eInt*eInt) << endl ;

    result += eExt*eExt/(eInt*eInt) ;
  }
  

  return result ;
}



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