// @(#)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.             *
 *************************************************************************/

#include "RooStats/SimpleLikelihoodRatioTestStat.h"
#include "RooStats/RooStatsUtils.h"


Bool_t RooStats::SimpleLikelihoodRatioTestStat::fgAlwaysReuseNll = kTRUE ;

void RooStats::SimpleLikelihoodRatioTestStat::SetAlwaysReuseNLL(Bool_t flag) { fgAlwaysReuseNll = flag ; }

Double_t RooStats::SimpleLikelihoodRatioTestStat::Evaluate(RooAbsData& data, RooArgSet& nullPOI) {

   if (fFirstEval && ParamsAreEqual()) {
      oocoutW(fNullParameters,InputArguments)
         << "Same RooArgSet used for null and alternate, so you must explicitly SetNullParameters and SetAlternateParameters or the likelihood ratio will always be 1."
         << std::endl;
   }
   
   // strip pdfs of constraints (which cancel out in the ratio) to avoid unnecessary computations and computational errors
   if (fFirstEval) {
      fNullPdf = RooStats::MakeUnconstrainedPdf(*fNullPdf, *fNullPdf->getObservables(data));
      fAltPdf  = RooStats::MakeUnconstrainedPdf(*fAltPdf , *fAltPdf->getObservables(data) );
   }

   fFirstEval = false;

   RooFit::MsgLevel msglevel = RooMsgService::instance().globalKillBelow();
   RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL);

   Bool_t reuse = (fReuseNll || fgAlwaysReuseNll) ;

   Bool_t created = kFALSE ;
   if (!fNllNull) {
      RooArgSet* allParams = fNullPdf->getParameters(data);
      fNllNull = fNullPdf->createNLL(data, RooFit::CloneData(kFALSE),RooFit::Constrain(*allParams),RooFit::ConditionalObservables(fConditionalObs));
      delete allParams;
      created = kTRUE ;
   }
   if (reuse && !created) {
      fNllNull->setData(data, kFALSE) ;
   }

   // make sure we set the variables attached to this nll
   RooArgSet* attachedSet = fNllNull->getVariables();
   *attachedSet = *fNullParameters;
   *attachedSet = nullPOI;
   double nullNLL = fNllNull->getVal();
         
   //std::cout << std::endl << "SLRTS: null params:" << std::endl;
   //attachedSet->Print("v");
         

   if (!reuse) {
      delete fNllNull ; fNllNull = NULL ;
   }
   delete attachedSet;

   created = kFALSE ;
   if (!fNllAlt) {
      RooArgSet* allParams = fAltPdf->getParameters(data);
      fNllAlt = fAltPdf->createNLL(data, RooFit::CloneData(kFALSE),RooFit::Constrain(*allParams),RooFit::ConditionalObservables(fConditionalObs));
      delete allParams;
      created = kTRUE ;
   }
   if (reuse && !created) {
      fNllAlt->setData(data, kFALSE) ;
   }
   // make sure we set the variables attached to this nll
   attachedSet = fNllAlt->getVariables();
   *attachedSet = *fAltParameters;
   double altNLL = fNllAlt->getVal();

   //std::cout << std::endl << "SLRTS: alt params:" << std::endl;
   //attachedSet->Print("v");


//   std::cout << std::endl << "SLRTS null NLL: " << nullNLL << "    alt NLL: " << altNLL << std::endl << std::endl;


   if (!reuse) { 
      delete fNllAlt ; fNllAlt = NULL ;
   }
   delete attachedSet;



   // save this snapshot
   if( fDetailedOutputEnabled ) {
      if( !fDetailedOutput ) {
         fDetailedOutput = new RooArgSet( *(new RooRealVar("nullNLL","null NLL",0)), "detailedOut_SLRTS" );
         fDetailedOutput->add( *(new RooRealVar("altNLL","alternate NLL",0)) );
      }
      fDetailedOutput->setRealValue( "nullNLL", nullNLL );
      fDetailedOutput->setRealValue( "altNLL", altNLL );

//             std::cout << std::endl << "STORING THIS AS DETAILED OUTPUT:" << std::endl;
//             fDetailedOutput->Print("v");
//             std::cout << std::endl;
   }


   RooMsgService::instance().setGlobalKillBelow(msglevel);
   return nullNLL - altNLL;
}
 SimpleLikelihoodRatioTestStat.cxx:1
 SimpleLikelihoodRatioTestStat.cxx:2
 SimpleLikelihoodRatioTestStat.cxx:3
 SimpleLikelihoodRatioTestStat.cxx:4
 SimpleLikelihoodRatioTestStat.cxx:5
 SimpleLikelihoodRatioTestStat.cxx:6
 SimpleLikelihoodRatioTestStat.cxx:7
 SimpleLikelihoodRatioTestStat.cxx:8
 SimpleLikelihoodRatioTestStat.cxx:9
 SimpleLikelihoodRatioTestStat.cxx:10
 SimpleLikelihoodRatioTestStat.cxx:11
 SimpleLikelihoodRatioTestStat.cxx:12
 SimpleLikelihoodRatioTestStat.cxx:13
 SimpleLikelihoodRatioTestStat.cxx:14
 SimpleLikelihoodRatioTestStat.cxx:15
 SimpleLikelihoodRatioTestStat.cxx:16
 SimpleLikelihoodRatioTestStat.cxx:17
 SimpleLikelihoodRatioTestStat.cxx:18
 SimpleLikelihoodRatioTestStat.cxx:19
 SimpleLikelihoodRatioTestStat.cxx:20
 SimpleLikelihoodRatioTestStat.cxx:21
 SimpleLikelihoodRatioTestStat.cxx:22
 SimpleLikelihoodRatioTestStat.cxx:23
 SimpleLikelihoodRatioTestStat.cxx:24
 SimpleLikelihoodRatioTestStat.cxx:25
 SimpleLikelihoodRatioTestStat.cxx:26
 SimpleLikelihoodRatioTestStat.cxx:27
 SimpleLikelihoodRatioTestStat.cxx:28
 SimpleLikelihoodRatioTestStat.cxx:29
 SimpleLikelihoodRatioTestStat.cxx:30
 SimpleLikelihoodRatioTestStat.cxx:31
 SimpleLikelihoodRatioTestStat.cxx:32
 SimpleLikelihoodRatioTestStat.cxx:33
 SimpleLikelihoodRatioTestStat.cxx:34
 SimpleLikelihoodRatioTestStat.cxx:35
 SimpleLikelihoodRatioTestStat.cxx:36
 SimpleLikelihoodRatioTestStat.cxx:37
 SimpleLikelihoodRatioTestStat.cxx:38
 SimpleLikelihoodRatioTestStat.cxx:39
 SimpleLikelihoodRatioTestStat.cxx:40
 SimpleLikelihoodRatioTestStat.cxx:41
 SimpleLikelihoodRatioTestStat.cxx:42
 SimpleLikelihoodRatioTestStat.cxx:43
 SimpleLikelihoodRatioTestStat.cxx:44
 SimpleLikelihoodRatioTestStat.cxx:45
 SimpleLikelihoodRatioTestStat.cxx:46
 SimpleLikelihoodRatioTestStat.cxx:47
 SimpleLikelihoodRatioTestStat.cxx:48
 SimpleLikelihoodRatioTestStat.cxx:49
 SimpleLikelihoodRatioTestStat.cxx:50
 SimpleLikelihoodRatioTestStat.cxx:51
 SimpleLikelihoodRatioTestStat.cxx:52
 SimpleLikelihoodRatioTestStat.cxx:53
 SimpleLikelihoodRatioTestStat.cxx:54
 SimpleLikelihoodRatioTestStat.cxx:55
 SimpleLikelihoodRatioTestStat.cxx:56
 SimpleLikelihoodRatioTestStat.cxx:57
 SimpleLikelihoodRatioTestStat.cxx:58
 SimpleLikelihoodRatioTestStat.cxx:59
 SimpleLikelihoodRatioTestStat.cxx:60
 SimpleLikelihoodRatioTestStat.cxx:61
 SimpleLikelihoodRatioTestStat.cxx:62
 SimpleLikelihoodRatioTestStat.cxx:63
 SimpleLikelihoodRatioTestStat.cxx:64
 SimpleLikelihoodRatioTestStat.cxx:65
 SimpleLikelihoodRatioTestStat.cxx:66
 SimpleLikelihoodRatioTestStat.cxx:67
 SimpleLikelihoodRatioTestStat.cxx:68
 SimpleLikelihoodRatioTestStat.cxx:69
 SimpleLikelihoodRatioTestStat.cxx:70
 SimpleLikelihoodRatioTestStat.cxx:71
 SimpleLikelihoodRatioTestStat.cxx:72
 SimpleLikelihoodRatioTestStat.cxx:73
 SimpleLikelihoodRatioTestStat.cxx:74
 SimpleLikelihoodRatioTestStat.cxx:75
 SimpleLikelihoodRatioTestStat.cxx:76
 SimpleLikelihoodRatioTestStat.cxx:77
 SimpleLikelihoodRatioTestStat.cxx:78
 SimpleLikelihoodRatioTestStat.cxx:79
 SimpleLikelihoodRatioTestStat.cxx:80
 SimpleLikelihoodRatioTestStat.cxx:81
 SimpleLikelihoodRatioTestStat.cxx:82
 SimpleLikelihoodRatioTestStat.cxx:83
 SimpleLikelihoodRatioTestStat.cxx:84
 SimpleLikelihoodRatioTestStat.cxx:85
 SimpleLikelihoodRatioTestStat.cxx:86
 SimpleLikelihoodRatioTestStat.cxx:87
 SimpleLikelihoodRatioTestStat.cxx:88
 SimpleLikelihoodRatioTestStat.cxx:89
 SimpleLikelihoodRatioTestStat.cxx:90
 SimpleLikelihoodRatioTestStat.cxx:91
 SimpleLikelihoodRatioTestStat.cxx:92
 SimpleLikelihoodRatioTestStat.cxx:93
 SimpleLikelihoodRatioTestStat.cxx:94
 SimpleLikelihoodRatioTestStat.cxx:95
 SimpleLikelihoodRatioTestStat.cxx:96
 SimpleLikelihoodRatioTestStat.cxx:97
 SimpleLikelihoodRatioTestStat.cxx:98
 SimpleLikelihoodRatioTestStat.cxx:99
 SimpleLikelihoodRatioTestStat.cxx:100
 SimpleLikelihoodRatioTestStat.cxx:101
 SimpleLikelihoodRatioTestStat.cxx:102
 SimpleLikelihoodRatioTestStat.cxx:103
 SimpleLikelihoodRatioTestStat.cxx:104
 SimpleLikelihoodRatioTestStat.cxx:105
 SimpleLikelihoodRatioTestStat.cxx:106
 SimpleLikelihoodRatioTestStat.cxx:107
 SimpleLikelihoodRatioTestStat.cxx:108
 SimpleLikelihoodRatioTestStat.cxx:109
 SimpleLikelihoodRatioTestStat.cxx:110
 SimpleLikelihoodRatioTestStat.cxx:111
 SimpleLikelihoodRatioTestStat.cxx:112