// @(#)root/roostats:$Id$
// Author: Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/*****************************************************************************
 * Project: RooStats
 * Package: RooFit/RooStats  
 * @(#)root/roofit/roostats:$Id$
 * Original Author: Kyle Cranmer
 *   Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke
 *
 *****************************************************************************/



//_________________________________________________________
//
// BEGIN_HTML
// PointSetInterval is a concrete implementation of the ConfInterval interface.  
// It implements simple general purpose interval of arbitrary dimensions and shape.
// It does not assume the interval is connected.
// It uses either a RooDataSet (eg. a list of parameter points in the interval) or
// a RooDataHist (eg. a Histogram-like object for small regions of the parameter space) to
// store the interval.  
// END_HTML
//
//

#ifndef RooStats_PointSetInterval
#include "RooStats/PointSetInterval.h"
#endif

#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooDataHist.h"

using namespace std;

ClassImp(RooStats::PointSetInterval) ;

using namespace RooStats;


//____________________________________________________________________
PointSetInterval::PointSetInterval(const char* name) :
   ConfInterval(name), fConfidenceLevel(0.95), fParameterPointsInInterval(0)
{
   // Default constructor
}

//____________________________________________________________________
PointSetInterval::PointSetInterval(const char* name, RooAbsData& data) :
   ConfInterval(name), fConfidenceLevel(0.95), fParameterPointsInInterval(&data)
{
   // Alternate constructor passing the dataset 
}



//____________________________________________________________________
PointSetInterval::~PointSetInterval()
{
   // Destructor

}


//____________________________________________________________________
Bool_t PointSetInterval::IsInInterval(const RooArgSet &parameterPoint) const
{  
   // Method to determine if a parameter point is in the interval

  RooDataSet*  tree = dynamic_cast<RooDataSet*>(  fParameterPointsInInterval );
  RooDataHist* hist = dynamic_cast<RooDataHist*>( fParameterPointsInInterval );
  
  if( !this->CheckParameters(parameterPoint) ){
    //    std::cout << "problem with parameters" << std::endl;
    return false; 
  }
  
  if( hist ) {
    if ( hist->weight( parameterPoint , 0 ) > 0 ) // positive value indicates point is in interval
      return true; 
    else
      return false;
  }
  else if( tree ){
    const RooArgSet* thisPoint = 0;
    // need to check if the parameter point is the same as any point in tree. 
    for(Int_t i = 0; i<tree->numEntries(); ++i){
      // This method is not complete
      thisPoint = tree->get(i); 
      bool samePoint = true;
      TIter it = parameterPoint.createIterator();
      RooRealVar *myarg; 
      while ( samePoint && (myarg = (RooRealVar *)it.Next())) { 
	if(myarg->getVal() != thisPoint->getRealValue(myarg->GetName()))
	  samePoint = false;
      }
      if(samePoint) 
	return true;

      //      delete thisPoint;
    }
    return false; // didn't find a good point
  }
  else {
      std::cout << "dataset is not initialized properly" << std::endl;
  }

   return true;
  
}

//____________________________________________________________________
RooArgSet* PointSetInterval::GetParameters() const
{  
   // returns list of parameters
   return new RooArgSet(*(fParameterPointsInInterval->get()) );
}

//____________________________________________________________________
Bool_t PointSetInterval::CheckParameters(const RooArgSet &parameterPoint) const
{  
   if (parameterPoint.getSize() != fParameterPointsInInterval->get()->getSize() ) {
     std::cout << "PointSetInterval: argument size is wrong, parameters don't match: arg=" << parameterPoint
	       << " interval=" << (*fParameterPointsInInterval->get()) << std::endl;
      return false;
   }
   if ( ! parameterPoint.equals( *(fParameterPointsInInterval->get() ) ) ) {
      std::cout << "PointSetInterval: size is ok, but parameters don't match" << std::endl;
      return false;
   }
   return true;
}


//____________________________________________________________________
Double_t PointSetInterval::UpperLimit(RooRealVar& param ) 
{  
  RooDataSet*  tree = dynamic_cast<RooDataSet*>(  fParameterPointsInInterval );
  Double_t low = 0, high = 0;
  if( tree ){
    tree->getRange(param, low, high);
    return high;
 }
  return param.getMax();
}

//____________________________________________________________________
Double_t PointSetInterval::LowerLimit(RooRealVar& param ) 
{  
  RooDataSet*  tree = dynamic_cast<RooDataSet*>(  fParameterPointsInInterval );
  Double_t low = 0, high = 0;
  if( tree ){
    tree->getRange(param, low, high);
    return low;
 }
  return param.getMin();
}
 PointSetInterval.cxx:1
 PointSetInterval.cxx:2
 PointSetInterval.cxx:3
 PointSetInterval.cxx:4
 PointSetInterval.cxx:5
 PointSetInterval.cxx:6
 PointSetInterval.cxx:7
 PointSetInterval.cxx:8
 PointSetInterval.cxx:9
 PointSetInterval.cxx:10
 PointSetInterval.cxx:11
 PointSetInterval.cxx:12
 PointSetInterval.cxx:13
 PointSetInterval.cxx:14
 PointSetInterval.cxx:15
 PointSetInterval.cxx:16
 PointSetInterval.cxx:17
 PointSetInterval.cxx:18
 PointSetInterval.cxx:19
 PointSetInterval.cxx:20
 PointSetInterval.cxx:21
 PointSetInterval.cxx:22
 PointSetInterval.cxx:23
 PointSetInterval.cxx:24
 PointSetInterval.cxx:25
 PointSetInterval.cxx:26
 PointSetInterval.cxx:27
 PointSetInterval.cxx:28
 PointSetInterval.cxx:29
 PointSetInterval.cxx:30
 PointSetInterval.cxx:31
 PointSetInterval.cxx:32
 PointSetInterval.cxx:33
 PointSetInterval.cxx:34
 PointSetInterval.cxx:35
 PointSetInterval.cxx:36
 PointSetInterval.cxx:37
 PointSetInterval.cxx:38
 PointSetInterval.cxx:39
 PointSetInterval.cxx:40
 PointSetInterval.cxx:41
 PointSetInterval.cxx:42
 PointSetInterval.cxx:43
 PointSetInterval.cxx:44
 PointSetInterval.cxx:45
 PointSetInterval.cxx:46
 PointSetInterval.cxx:47
 PointSetInterval.cxx:48
 PointSetInterval.cxx:49
 PointSetInterval.cxx:50
 PointSetInterval.cxx:51
 PointSetInterval.cxx:52
 PointSetInterval.cxx:53
 PointSetInterval.cxx:54
 PointSetInterval.cxx:55
 PointSetInterval.cxx:56
 PointSetInterval.cxx:57
 PointSetInterval.cxx:58
 PointSetInterval.cxx:59
 PointSetInterval.cxx:60
 PointSetInterval.cxx:61
 PointSetInterval.cxx:62
 PointSetInterval.cxx:63
 PointSetInterval.cxx:64
 PointSetInterval.cxx:65
 PointSetInterval.cxx:66
 PointSetInterval.cxx:67
 PointSetInterval.cxx:68
 PointSetInterval.cxx:69
 PointSetInterval.cxx:70
 PointSetInterval.cxx:71
 PointSetInterval.cxx:72
 PointSetInterval.cxx:73
 PointSetInterval.cxx:74
 PointSetInterval.cxx:75
 PointSetInterval.cxx:76
 PointSetInterval.cxx:77
 PointSetInterval.cxx:78
 PointSetInterval.cxx:79
 PointSetInterval.cxx:80
 PointSetInterval.cxx:81
 PointSetInterval.cxx:82
 PointSetInterval.cxx:83
 PointSetInterval.cxx:84
 PointSetInterval.cxx:85
 PointSetInterval.cxx:86
 PointSetInterval.cxx:87
 PointSetInterval.cxx:88
 PointSetInterval.cxx:89
 PointSetInterval.cxx:90
 PointSetInterval.cxx:91
 PointSetInterval.cxx:92
 PointSetInterval.cxx:93
 PointSetInterval.cxx:94
 PointSetInterval.cxx:95
 PointSetInterval.cxx:96
 PointSetInterval.cxx:97
 PointSetInterval.cxx:98
 PointSetInterval.cxx:99
 PointSetInterval.cxx:100
 PointSetInterval.cxx:101
 PointSetInterval.cxx:102
 PointSetInterval.cxx:103
 PointSetInterval.cxx:104
 PointSetInterval.cxx:105
 PointSetInterval.cxx:106
 PointSetInterval.cxx:107
 PointSetInterval.cxx:108
 PointSetInterval.cxx:109
 PointSetInterval.cxx:110
 PointSetInterval.cxx:111
 PointSetInterval.cxx:112
 PointSetInterval.cxx:113
 PointSetInterval.cxx:114
 PointSetInterval.cxx:115
 PointSetInterval.cxx:116
 PointSetInterval.cxx:117
 PointSetInterval.cxx:118
 PointSetInterval.cxx:119
 PointSetInterval.cxx:120
 PointSetInterval.cxx:121
 PointSetInterval.cxx:122
 PointSetInterval.cxx:123
 PointSetInterval.cxx:124
 PointSetInterval.cxx:125
 PointSetInterval.cxx:126
 PointSetInterval.cxx:127
 PointSetInterval.cxx:128
 PointSetInterval.cxx:129
 PointSetInterval.cxx:130
 PointSetInterval.cxx:131
 PointSetInterval.cxx:132
 PointSetInterval.cxx:133
 PointSetInterval.cxx:134
 PointSetInterval.cxx:135
 PointSetInterval.cxx:136
 PointSetInterval.cxx:137
 PointSetInterval.cxx:138
 PointSetInterval.cxx:139
 PointSetInterval.cxx:140
 PointSetInterval.cxx:141
 PointSetInterval.cxx:142
 PointSetInterval.cxx:143
 PointSetInterval.cxx:144
 PointSetInterval.cxx:145
 PointSetInterval.cxx:146
 PointSetInterval.cxx:147
 PointSetInterval.cxx:148
 PointSetInterval.cxx:149
 PointSetInterval.cxx:150
 PointSetInterval.cxx:151
 PointSetInterval.cxx:152
 PointSetInterval.cxx:153
 PointSetInterval.cxx:154
 PointSetInterval.cxx:155
 PointSetInterval.cxx:156
 PointSetInterval.cxx:157
 PointSetInterval.cxx:158
 PointSetInterval.cxx:159
 PointSetInterval.cxx:160
 PointSetInterval.cxx:161
 PointSetInterval.cxx:162
 PointSetInterval.cxx:163
 PointSetInterval.cxx:164
 PointSetInterval.cxx:165
 PointSetInterval.cxx:166