/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 *    File: $Id: RooAbsGoodnessOfFit.h,v 1.15 2007/05/11 09:11:30 verkerke Exp $
 * 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)             *
 *****************************************************************************/
#ifndef ROO_ABS_TEST_STATISTIC
#define ROO_ABS_TEST_STATISTIC

#include "Riosfwd.h"
#include "RooAbsReal.h"
#include "RooSetProxy.h"
#include "RooRealProxy.h"
#include "TStopwatch.h"
#include <string>

class RooArgSet ;
class RooAbsData ;
class RooAbsReal ;
class RooSimultaneous ;
class RooRealMPFE ;

class RooAbsTestStatistic ;
typedef RooAbsTestStatistic* pRooAbsTestStatistic ;
typedef RooAbsData* pRooAbsData ;
typedef RooRealMPFE* pRooRealMPFE ;

class RooAbsTestStatistic : public RooAbsReal {
    friend class RooRealMPFE;
public:

  // Constructors, assignment etc
  RooAbsTestStatistic() ;
  RooAbsTestStatistic(const char *name, const char *title, RooAbsReal& real, RooAbsData& data,
		      const RooArgSet& projDeps, const char* rangeName=0, const char* addCoefRangeName=0, 
		      Int_t nCPU=1, RooFit::MPSplit interleave=RooFit::BulkPartition, Bool_t verbose=kTRUE, Bool_t splitCutRange=kTRUE) ;
  RooAbsTestStatistic(const RooAbsTestStatistic& other, const char* name=0);
  virtual ~RooAbsTestStatistic();
  virtual RooAbsTestStatistic* create(const char *name, const char *title, RooAbsReal& real, RooAbsData& data,
				      const RooArgSet& projDeps, const char* rangeName=0, const char* addCoefRangeName=0, 
				      Int_t nCPU=1, RooFit::MPSplit interleave=RooFit::BulkPartition, Bool_t verbose=kTRUE, Bool_t splitCutRange=kFALSE, Bool_t binnedL=kFALSE) = 0 ;

  virtual void constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTrackingOpt=kTRUE) ;

  virtual Double_t combinedValue(RooAbsReal** gofArray, Int_t nVal) const = 0 ;
  virtual Double_t globalNormalization() const { 
    // Default value of global normalization factor is 1.0
    return 1.0 ; 
  }
  
  Bool_t setData(RooAbsData& data, Bool_t cloneData=kTRUE) ;

  void enableOffsetting(Bool_t flag) ;
  Bool_t isOffsetting() const { return _doOffset ; }
  virtual Double_t offset() const { return _offset ; }
  virtual Double_t offsetCarry() const { return _offsetCarry; }

protected:

  virtual void printCompactTreeHook(std::ostream& os, const char* indent="") ;

  virtual Bool_t redirectServersHook(const RooAbsCollection& newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursive) ;
  virtual Double_t evaluate() const ;

  virtual Double_t evaluatePartition(Int_t firstEvent, Int_t lastEvent, Int_t stepSize) const = 0 ;
  virtual Double_t getCarry() const;

  void setMPSet(Int_t setNum, Int_t numSets) ; 
  void setSimCount(Int_t simCount) { 
    // Store total number of components p.d.f. of a RooSimultaneous in this component test statistic
    _simCount = simCount ; 
  }
  
  void setEventCount(Int_t nEvents) { 
    // Store total number of events in this component test statistic
    _nEvents = nEvents ; 
  }

  Int_t numSets() const { 
    // Return total number of sets for parallel calculation
    return _numSets ; 
  }
  Int_t setNum() const { 
    // Return parallel calculation set number for this instance
    return _setNum ; 
  }
  
  RooSetProxy _paramSet ;          // Parameters of the test statistic (=parameters of the input function)

  enum GOFOpMode { SimMaster,MPMaster,Slave } ;
  GOFOpMode operMode() const { 
    // Return test statistic operation mode of this instance (SimMaster, MPMaster or Slave)
    return _gofOpMode ; 
  }

  // Original arguments
  RooAbsReal* _func ;              // Pointer to original input function
  RooAbsData* _data ;              // Pointer to original input dataset
  const RooArgSet* _projDeps ;     // Pointer to set with projected observables
  std::string _rangeName ;         // Name of range in which to calculate test statistic
  std::string _addCoefRangeName ;  // Name of reference to be used for RooAddPdf components
  Bool_t _splitRange ;             // Split rangeName in RooSimultaneous index labels if true
  Int_t _simCount ;                // Total number of component p.d.f.s in RooSimultaneous (if any)
  Bool_t _verbose ;                // Verbose messaging if true

  virtual Bool_t setDataSlave(RooAbsData& /*data*/, Bool_t /*cloneData*/=kTRUE, Bool_t /*ownNewDataAnyway*/=kFALSE) { return kTRUE ; }

  //private:  


  virtual Bool_t processEmptyDataSets() const { return kTRUE ; }

  Bool_t initialize() ;
  void initSimMode(RooSimultaneous* pdf, RooAbsData* data, const RooArgSet* projDeps, const char* rangeName, const char* addCoefRangeName) ;    
  void initMPMode(RooAbsReal* real, RooAbsData* data, const RooArgSet* projDeps, const char* rangeName, const char* addCoefRangeName) ;

  mutable Bool_t _init ;          //! Is object initialized  
  GOFOpMode   _gofOpMode ;        // Operation mode of test statistic instance 

  Int_t       _nEvents ;          // Total number of events in test statistic calculation
  Int_t       _setNum ;           // Partition number of this instance in parallel calculation mode
  Int_t       _numSets ;          // Total number of partitions in parallel calculation mode
  Int_t       _extSet ;           //! Number of designated set to calculated extended term

  // Simultaneous mode data
  Int_t          _nGof        ; // Number of sub-contexts 
  pRooAbsTestStatistic* _gofArray ; //! Array of sub-contexts representing part of the combined test statistic
  std::vector<RooFit::MPSplit> _gofSplitMode ; //! GOF MP Split mode specified by component (when Auto is active)
  
  // Parallel mode data
  Int_t          _nCPU ;      //  Number of processors to use in parallel calculation mode
  pRooRealMPFE*  _mpfeArray ; //! Array of parallel execution frond ends

  RooFit::MPSplit        _mpinterl ; // Use interleaving strategy rather than N-wise split for partioning of dataset for multiprocessor-split
  Bool_t         _doOffset ; // Apply interval value offset to control numeric precision?
  mutable Double_t _offset ; //! Offset
  mutable Double_t _offsetCarry; //! avoids loss of precision
  mutable Double_t _evalCarry; //! carry of Kahan sum in evaluatePartition

  ClassDef(RooAbsTestStatistic,2) // Abstract base class for real-valued test statistics

};

#endif
 RooAbsTestStatistic.h:1
 RooAbsTestStatistic.h:2
 RooAbsTestStatistic.h:3
 RooAbsTestStatistic.h:4
 RooAbsTestStatistic.h:5
 RooAbsTestStatistic.h:6
 RooAbsTestStatistic.h:7
 RooAbsTestStatistic.h:8
 RooAbsTestStatistic.h:9
 RooAbsTestStatistic.h:10
 RooAbsTestStatistic.h:11
 RooAbsTestStatistic.h:12
 RooAbsTestStatistic.h:13
 RooAbsTestStatistic.h:14
 RooAbsTestStatistic.h:15
 RooAbsTestStatistic.h:16
 RooAbsTestStatistic.h:17
 RooAbsTestStatistic.h:18
 RooAbsTestStatistic.h:19
 RooAbsTestStatistic.h:20
 RooAbsTestStatistic.h:21
 RooAbsTestStatistic.h:22
 RooAbsTestStatistic.h:23
 RooAbsTestStatistic.h:24
 RooAbsTestStatistic.h:25
 RooAbsTestStatistic.h:26
 RooAbsTestStatistic.h:27
 RooAbsTestStatistic.h:28
 RooAbsTestStatistic.h:29
 RooAbsTestStatistic.h:30
 RooAbsTestStatistic.h:31
 RooAbsTestStatistic.h:32
 RooAbsTestStatistic.h:33
 RooAbsTestStatistic.h:34
 RooAbsTestStatistic.h:35
 RooAbsTestStatistic.h:36
 RooAbsTestStatistic.h:37
 RooAbsTestStatistic.h:38
 RooAbsTestStatistic.h:39
 RooAbsTestStatistic.h:40
 RooAbsTestStatistic.h:41
 RooAbsTestStatistic.h:42
 RooAbsTestStatistic.h:43
 RooAbsTestStatistic.h:44
 RooAbsTestStatistic.h:45
 RooAbsTestStatistic.h:46
 RooAbsTestStatistic.h:47
 RooAbsTestStatistic.h:48
 RooAbsTestStatistic.h:49
 RooAbsTestStatistic.h:50
 RooAbsTestStatistic.h:51
 RooAbsTestStatistic.h:52
 RooAbsTestStatistic.h:53
 RooAbsTestStatistic.h:54
 RooAbsTestStatistic.h:55
 RooAbsTestStatistic.h:56
 RooAbsTestStatistic.h:57
 RooAbsTestStatistic.h:58
 RooAbsTestStatistic.h:59
 RooAbsTestStatistic.h:60
 RooAbsTestStatistic.h:61
 RooAbsTestStatistic.h:62
 RooAbsTestStatistic.h:63
 RooAbsTestStatistic.h:64
 RooAbsTestStatistic.h:65
 RooAbsTestStatistic.h:66
 RooAbsTestStatistic.h:67
 RooAbsTestStatistic.h:68
 RooAbsTestStatistic.h:69
 RooAbsTestStatistic.h:70
 RooAbsTestStatistic.h:71
 RooAbsTestStatistic.h:72
 RooAbsTestStatistic.h:73
 RooAbsTestStatistic.h:74
 RooAbsTestStatistic.h:75
 RooAbsTestStatistic.h:76
 RooAbsTestStatistic.h:77
 RooAbsTestStatistic.h:78
 RooAbsTestStatistic.h:79
 RooAbsTestStatistic.h:80
 RooAbsTestStatistic.h:81
 RooAbsTestStatistic.h:82
 RooAbsTestStatistic.h:83
 RooAbsTestStatistic.h:84
 RooAbsTestStatistic.h:85
 RooAbsTestStatistic.h:86
 RooAbsTestStatistic.h:87
 RooAbsTestStatistic.h:88
 RooAbsTestStatistic.h:89
 RooAbsTestStatistic.h:90
 RooAbsTestStatistic.h:91
 RooAbsTestStatistic.h:92
 RooAbsTestStatistic.h:93
 RooAbsTestStatistic.h:94
 RooAbsTestStatistic.h:95
 RooAbsTestStatistic.h:96
 RooAbsTestStatistic.h:97
 RooAbsTestStatistic.h:98
 RooAbsTestStatistic.h:99
 RooAbsTestStatistic.h:100
 RooAbsTestStatistic.h:101
 RooAbsTestStatistic.h:102
 RooAbsTestStatistic.h:103
 RooAbsTestStatistic.h:104
 RooAbsTestStatistic.h:105
 RooAbsTestStatistic.h:106
 RooAbsTestStatistic.h:107
 RooAbsTestStatistic.h:108
 RooAbsTestStatistic.h:109
 RooAbsTestStatistic.h:110
 RooAbsTestStatistic.h:111
 RooAbsTestStatistic.h:112
 RooAbsTestStatistic.h:113
 RooAbsTestStatistic.h:114
 RooAbsTestStatistic.h:115
 RooAbsTestStatistic.h:116
 RooAbsTestStatistic.h:117
 RooAbsTestStatistic.h:118
 RooAbsTestStatistic.h:119
 RooAbsTestStatistic.h:120
 RooAbsTestStatistic.h:121
 RooAbsTestStatistic.h:122
 RooAbsTestStatistic.h:123
 RooAbsTestStatistic.h:124
 RooAbsTestStatistic.h:125
 RooAbsTestStatistic.h:126
 RooAbsTestStatistic.h:127
 RooAbsTestStatistic.h:128
 RooAbsTestStatistic.h:129
 RooAbsTestStatistic.h:130
 RooAbsTestStatistic.h:131
 RooAbsTestStatistic.h:132
 RooAbsTestStatistic.h:133
 RooAbsTestStatistic.h:134
 RooAbsTestStatistic.h:135
 RooAbsTestStatistic.h:136
 RooAbsTestStatistic.h:137
 RooAbsTestStatistic.h:138
 RooAbsTestStatistic.h:139
 RooAbsTestStatistic.h:140
 RooAbsTestStatistic.h:141
 RooAbsTestStatistic.h:142
 RooAbsTestStatistic.h:143
 RooAbsTestStatistic.h:144
 RooAbsTestStatistic.h:145
 RooAbsTestStatistic.h:146
 RooAbsTestStatistic.h:147
 RooAbsTestStatistic.h:148
 RooAbsTestStatistic.h:149
 RooAbsTestStatistic.h:150
 RooAbsTestStatistic.h:151
 RooAbsTestStatistic.h:152
 RooAbsTestStatistic.h:153