#include "TMVA/QuickMVAProbEstimator.h"
 
#include <iostream>

#include "TMath.h"

#ifndef ROOT_TMVA_MsgLogger
#include "TMVA/MsgLogger.h"
#endif


void TMVA::QuickMVAProbEstimator::AddEvent(Double_t val, Double_t weight, Int_t type){
  EventInfo ev;
  ev.eventValue=val; ev.eventWeight=weight; ev.eventType=type; 
  
  fEvtVector.push_back(ev);
  if (fIsSorted) fIsSorted=false;
                       
}

 
Double_t TMVA::QuickMVAProbEstimator::GetMVAProbAt(Double_t value){
  // Well.. if it's fast is actually another question all together, merely
  // it's a quick and dirty simple kNN approach to the 1-Dim signal/backgr. MVA
  // distributions. 


  if (!fIsSorted) {
    std::sort(fEvtVector.begin(),fEvtVector.end(),TMVA::QuickMVAProbEstimator::compare), fIsSorted=true;
  }

  Double_t     percentage = 0.1;
  UInt_t  nRange = TMath::Max(fNMin,(UInt_t) (fEvtVector.size() * percentage));
  nRange = TMath::Min(fNMax,nRange);
  // just make sure that nRange > you total number of events
  if (nRange > fEvtVector.size()) {
    nRange = fEvtVector.size()/3.;
    Log() << kWARNING  << " !!  you have only " << fEvtVector.size() << " of events.. . I choose "
              << nRange << " for the quick and dirty kNN MVAProb estimate" << Endl;
  }

  EventInfo tmp; tmp.eventValue=value;
  std::vector<EventInfo>::iterator it = std::upper_bound(fEvtVector.begin(),fEvtVector.end(),tmp,TMVA::QuickMVAProbEstimator::compare);
  
  UInt_t iLeft=0, iRight=0;
  Double_t nSignal=0;
  Double_t nBackgr=0;

  while ( (iLeft+iRight) < nRange){
    if ( fEvtVector.end() > it+iRight+1){
      iRight++;
      if ( ((it+iRight))->eventType == 0) nSignal+=((it+iRight))->eventWeight;
      else                                nBackgr+=((it+iRight))->eventWeight;
    }
    if ( fEvtVector.begin() <= it-iLeft-1){
      iLeft++;
      if ( ((it-iLeft))->eventType == 0) nSignal+=((it-iLeft))->eventWeight;
      else                               nBackgr+=((it-iLeft))->eventWeight;
    }    
  }

  Double_t mvaProb = (nSignal+nBackgr) ? nSignal/(nSignal+nBackgr) : -1 ;
  return mvaProb;

}
 QuickMVAProbEstimator.cxx:1
 QuickMVAProbEstimator.cxx:2
 QuickMVAProbEstimator.cxx:3
 QuickMVAProbEstimator.cxx:4
 QuickMVAProbEstimator.cxx:5
 QuickMVAProbEstimator.cxx:6
 QuickMVAProbEstimator.cxx:7
 QuickMVAProbEstimator.cxx:8
 QuickMVAProbEstimator.cxx:9
 QuickMVAProbEstimator.cxx:10
 QuickMVAProbEstimator.cxx:11
 QuickMVAProbEstimator.cxx:12
 QuickMVAProbEstimator.cxx:13
 QuickMVAProbEstimator.cxx:14
 QuickMVAProbEstimator.cxx:15
 QuickMVAProbEstimator.cxx:16
 QuickMVAProbEstimator.cxx:17
 QuickMVAProbEstimator.cxx:18
 QuickMVAProbEstimator.cxx:19
 QuickMVAProbEstimator.cxx:20
 QuickMVAProbEstimator.cxx:21
 QuickMVAProbEstimator.cxx:22
 QuickMVAProbEstimator.cxx:23
 QuickMVAProbEstimator.cxx:24
 QuickMVAProbEstimator.cxx:25
 QuickMVAProbEstimator.cxx:26
 QuickMVAProbEstimator.cxx:27
 QuickMVAProbEstimator.cxx:28
 QuickMVAProbEstimator.cxx:29
 QuickMVAProbEstimator.cxx:30
 QuickMVAProbEstimator.cxx:31
 QuickMVAProbEstimator.cxx:32
 QuickMVAProbEstimator.cxx:33
 QuickMVAProbEstimator.cxx:34
 QuickMVAProbEstimator.cxx:35
 QuickMVAProbEstimator.cxx:36
 QuickMVAProbEstimator.cxx:37
 QuickMVAProbEstimator.cxx:38
 QuickMVAProbEstimator.cxx:39
 QuickMVAProbEstimator.cxx:40
 QuickMVAProbEstimator.cxx:41
 QuickMVAProbEstimator.cxx:42
 QuickMVAProbEstimator.cxx:43
 QuickMVAProbEstimator.cxx:44
 QuickMVAProbEstimator.cxx:45
 QuickMVAProbEstimator.cxx:46
 QuickMVAProbEstimator.cxx:47
 QuickMVAProbEstimator.cxx:48
 QuickMVAProbEstimator.cxx:49
 QuickMVAProbEstimator.cxx:50
 QuickMVAProbEstimator.cxx:51
 QuickMVAProbEstimator.cxx:52
 QuickMVAProbEstimator.cxx:53
 QuickMVAProbEstimator.cxx:54
 QuickMVAProbEstimator.cxx:55
 QuickMVAProbEstimator.cxx:56
 QuickMVAProbEstimator.cxx:57
 QuickMVAProbEstimator.cxx:58
 QuickMVAProbEstimator.cxx:59
 QuickMVAProbEstimator.cxx:60
 QuickMVAProbEstimator.cxx:61
 QuickMVAProbEstimator.cxx:62
 QuickMVAProbEstimator.cxx:63
 QuickMVAProbEstimator.cxx:64
 QuickMVAProbEstimator.cxx:65