ROOT logo
// @(#)root/roostats:$Id: HybridCalculator.cxx 31876 2009-12-14 11:11:27Z brun $

/*************************************************************************
 * Project: RooStats                                                     *
 * Package: RooFit/RooStats                                              *
 * Authors:                                                              *
 *   Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke       *
 * Other author of this class: Danilo Piparo                             *
 *************************************************************************
 * 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.             *
 *************************************************************************/

//_________________________________________________________________
/**
HybridCalculator class: this class is a fresh rewrite in RooStats of
	RooStatsCms/LimitCalculator developped by D. Piparo and G. Schott
Authors: D. Piparo, G. Schott - Universitaet Karlsruhe

The class is born from the need to have an implementation of the CLs 
method that could take advantage from the RooFit Package.
The basic idea is the following: 
- Instantiate an object specifying a signal+background model, a background model and a dataset.
- Perform toy MC experiments to know the distributions of -2lnQ 
- Calculate the CLsb and CLs values as "integrals" of these distributions.

The class allows the user to input models as RooAbsPdf ( TH1 object could be used 
by using the RooHistPdf class)
The pdfs must be "extended": for more information please refer to 
http://roofit.sourceforge.net). The dataset can be entered as a 
RooAbsData objects.  

Unlike the TLimit Class a complete MC generation is performed at each step 
and not a simple Poisson fluctuation of the contents of the bins.
Another innovation is the treatment of the nuisance parameters. The user 
can input in the constructor nuisance parameters.
To include the information that we have about the nuisance parameters a prior
PDF (RooAbsPdf) should be specified

Different test statistic can be used (likelihood ratio, number of events or 
profile likelihood ratio. The default is the likelihood ratio. 
See the method SetTestStatistic.

The number of toys to be generated is controlled by SetNumberOfToys(n).

The result of the calculations is returned as a HybridResult object pointer.

see also the following interesting references:
- Alex Read, "Presentation of search results: the CLs technique",
  Journal of Physics G: Nucl. Part. Phys. 28 2693-2704 (2002).
  see http://www.iop.org/EJ/abstract/0954-3899/28/10/313/

- Alex Read, "Modified Frequentist Analysis of Search Results (The CLs Method)" CERN 2000-005 (30 May 2000)

- V. Bartsch, G.Quast, "Expected signal observability at future experiments" CMS NOTE 2005/004

- http://root.cern.ch/root/html/src/TLimit.html
*/


#include "RooDataHist.h"
#include "RooDataSet.h"
#include "RooGlobalFunc.h"
#include "RooNLLVar.h"
#include "RooRealVar.h"
#include "RooAbsData.h"
#include "RooWorkspace.h"

#include "TH1.h"

#include "RooStats/HybridCalculator.h"

ClassImp(RooStats::HybridCalculator)

using namespace RooStats;

///////////////////////////////////////////////////////////////////////////

HybridCalculator::HybridCalculator(const char *name) :
   TNamed(name,name),
   fSbModel(0),
   fBModel(0),
   fObservables(0),
   fNuisanceParameters(0),
   fPriorPdf(0),
   fData(0),
   fUsePriorPdf(false)
{
   // constructor with name and title
   // set default parameters
   SetTestStatistic(1); 
   SetNumberOfToys(1000); 
}


/// constructor without the data - is it needed ???????????
HybridCalculator::HybridCalculator( RooAbsPdf& sbModel,
                                    RooAbsPdf& bModel,
                                    RooArgList& observables,
                                    const RooArgSet* nuisance_parameters,
                                    RooAbsPdf* priorPdf ,
				    bool GenerateBinned,
                                    int testStatistics, 
                                    int numToys) :
   fSbModel(&sbModel),
   fBModel(&bModel),
   fNuisanceParameters(nuisance_parameters),
   fPriorPdf(priorPdf),
   fData(0),
   fGenerateBinned(GenerateBinned),
   fUsePriorPdf(false)
{
   /// HybridCalculator constructor without specifying a data set
   /// the user need to specify the models in the S+B case and B-only case,
   /// the list of observables of the model(s) (for MC-generation), the list of parameters 
   /// that are marginalised and the prior distribution of those parameters

   // observables are managed by the class (they are copied in) 
  fObservables = new RooArgList(observables);
  //Try to recover the informations from the pdf's
  //fObservables=new RooArgList("fObservables");
  //fNuisanceParameters=new RooArgSet("fNuisanceParameters");
  // if (priorPdf){
      

  SetTestStatistic(testStatistics); 
  SetNumberOfToys(numToys); 

  if (priorPdf) UseNuisance(true); 
  
   // this->Print();
   /* if ( _verbose ) */ //this->PrintMore("v"); /// TO DO: add the verbose mode
}


HybridCalculator::HybridCalculator( RooAbsData & data, 
                                    RooAbsPdf& sbModel,
                                    RooAbsPdf& bModel,
                                    const RooArgSet* nuisance_parameters,
                                    RooAbsPdf* priorPdf,
				    bool GenerateBinned,
                                    int testStatistics, 
                                    int numToys) :
   fSbModel(&sbModel),
   fBModel(&bModel),
   fObservables(0),
   fNuisanceParameters(nuisance_parameters),
   fPriorPdf(priorPdf),
   fData(&data),
   fGenerateBinned(GenerateBinned),
   fUsePriorPdf(false)
{
   /// HybridCalculator constructor for performing hypotesis test 
   /// the user need to specify the data set, the models in the S+B case and B-only case. 
   /// In case of treatment of nuisance parameter, the user need to specify the  
   /// the list of parameters  that are marginalised and the prior distribution of those parameters


   SetTestStatistic(testStatistics);
   SetNumberOfToys(numToys); 

   if (priorPdf) UseNuisance(true); 
}



HybridCalculator::HybridCalculator( RooAbsData& data, 
                                    const ModelConfig& sbModel, 
                                    const ModelConfig& bModel, 
				    bool GenerateBinned,
                                    int testStatistics, 
                                    int numToys) :
   fSbModel(sbModel.GetPdf()),
   fBModel(bModel.GetPdf()),
   fObservables(0),  // no need to set them - can be taken from the data
   fNuisanceParameters((sbModel.GetNuisanceParameters()) ? sbModel.GetNuisanceParameters()  :  bModel.GetNuisanceParameters()),
   fPriorPdf((sbModel.GetPriorPdf()) ? sbModel.GetPriorPdf()  :  bModel.GetPriorPdf()),
   fData(&data),
   fGenerateBinned(GenerateBinned),
   fUsePriorPdf(false)
{
  /// Constructor with a ModelConfig object representing the signal + background model and 
  /// another model config representig the background only model
  /// a Prior pdf for the nuiscane parameter of the signal and background can be specified in 
  /// the s+b model or the b model. If it is specified in the s+b model, the one of the s+b model will be used 

  if (fPriorPdf) UseNuisance(true);

  SetTestStatistic(testStatistics);
  SetNumberOfToys(numToys); 
}

///////////////////////////////////////////////////////////////////////////

HybridCalculator::~HybridCalculator()
{
   /// HybridCalculator destructor
   if (fObservables) delete fObservables; 
}

///////////////////////////////////////////////////////////////////////////

void HybridCalculator::SetNullModel(const ModelConfig& model)
{
   // Set the model describing the null hypothesis
   fBModel = model.GetPdf();
   // only if it has not been set before
   if (!fPriorPdf) fPriorPdf = model.GetPriorPdf(); 
   if (!fNuisanceParameters) fNuisanceParameters = model.GetNuisanceParameters(); 
}

void HybridCalculator::SetAlternateModel(const ModelConfig& model)
{
   // Set the model describing the alternate hypothesis
   fSbModel = model.GetPdf();
   fPriorPdf = model.GetPriorPdf(); 
   fNuisanceParameters = model.GetNuisanceParameters(); 
}

void HybridCalculator::SetTestStatistic(int index)
{
   /// set the desired test statistics:
   /// index=1 : likelihood ratio: 2 * log( L_sb / L_b )  (DEFAULT)
   /// index=2 : number of generated events
   /// index=3 : profiled likelihood ratio
   /// if the index is different to any of those values, the default is used
   fTestStatisticsIdx = index;
}

///////////////////////////////////////////////////////////////////////////

HybridResult* HybridCalculator::Calculate(TH1& data, unsigned int nToys, bool usePriors) const
{
   /// first compute the test statistics for data and then prepare and run the toy-MC experiments

   /// convert data TH1 histogram to a RooDataHist
   TString dataHistName = GetName(); dataHistName += "_roodatahist";
   RooDataHist dataHist(dataHistName,"Data distribution as RooDataHist converted from TH1",*fObservables,&data);

   HybridResult* result = Calculate(dataHist,nToys,usePriors);

   return result;
}

///////////////////////////////////////////////////////////////////////////

HybridResult* HybridCalculator::Calculate(RooAbsData& data, unsigned int nToys, bool usePriors) const
{
   /// first compute the test statistics for data and then prepare and run the toy-MC experiments

   double testStatData = 0;
   if ( fTestStatisticsIdx==2 ) {
      /// number of events used as test statistics
      double nEvents = data.sumEntries();
      testStatData = nEvents;
   } else if ( fTestStatisticsIdx==3 ) {
      /// profiled likelihood ratio used as test statistics
      RooNLLVar sb_nll("sb_nll","sb_nll",*fSbModel,data,RooFit::Extended());
      fSbModel->fitTo(data);
      double sb_nll_val = sb_nll.getVal();
      RooNLLVar b_nll("b_nll","b_nll",*fBModel,data,RooFit::Extended());
      fBModel->fitTo(data);
      double b_nll_val = b_nll.getVal();
      double m2lnQ = 2*(sb_nll_val-b_nll_val);
      testStatData = m2lnQ;
   } else if ( fTestStatisticsIdx==1 ) {
      /// likelihood ratio used as test statistics (default)
      RooNLLVar sb_nll("sb_nll","sb_nll",*fSbModel,data,RooFit::Extended());
      RooNLLVar b_nll("b_nll","b_nll",*fBModel,data,RooFit::Extended());
      double m2lnQ = 2*(sb_nll.getVal()-b_nll.getVal());
      testStatData = m2lnQ;
   }

   HybridResult* result = Calculate(nToys,usePriors);
   result->SetDataTestStatistics(testStatData);

   return result;
}

///////////////////////////////////////////////////////////////////////////

HybridResult* HybridCalculator::Calculate(unsigned int nToys, bool usePriors) const
{
   std::vector<double> bVals;
   bVals.reserve(nToys);

   std::vector<double> sbVals;
   sbVals.reserve(nToys);

   RunToys(bVals,sbVals,nToys,usePriors);

   HybridResult* result;

   TString name = "HybridResult_" + TString(GetName() );

   if ( fTestStatisticsIdx==2 )
     result = new HybridResult(name,sbVals,bVals,false);
   else 
     result = new HybridResult(name,sbVals,bVals);

   return result;
}

///////////////////////////////////////////////////////////////////////////

void HybridCalculator::RunToys(std::vector<double>& bVals, std::vector<double>& sbVals, unsigned int nToys, bool usePriors) const
{
   /// do the actual run-MC processing
   std::cout << "HybridCalculator: run " << nToys << " toy-MC experiments\n";
   std::cout << "with test statistics index: " << fTestStatisticsIdx << "\n";
   if (usePriors) std::cout << "marginalize nuisance parameters \n";

   assert(nToys > 0);
   assert(fBModel);
   assert(fSbModel);
   if (usePriors)  { 
      assert(fPriorPdf); 
      assert(fNuisanceParameters);
   }

   std::vector<double> parameterValues; /// array to hold the initial parameter values
   /// backup the initial values of the parameters that are varied by the prior MC-integration
   int nParameters = (fNuisanceParameters) ? fNuisanceParameters->getSize() : 0;
   RooArgList parametersList("parametersList");  /// transforms the RooArgSet in a RooArgList (needed for .at())
   if (usePriors && nParameters>0) {
      parametersList.add(*fNuisanceParameters);
      parameterValues.resize(nParameters);
      for (int iParameter=0; iParameter<nParameters; iParameter++) {
         RooRealVar* oneParam = (RooRealVar*) parametersList.at(iParameter);
         parameterValues[iParameter] = oneParam->getVal();
      }
   }

   for (unsigned int iToy=0; iToy<nToys; iToy++) {

      /// prints a progress report every 500 iterations
      /// TO DO: add a global verbose flag
     if ( /*verbose && */ iToy%500==0 ) {
       std::cout << "....... toy number " << iToy << " / " << nToys << std::endl;
     }

      /// vary the value of the integrated parameters according to the prior pdf
      if (usePriors && nParameters>0) {
         /// generation from the prior pdf (TO DO: RooMCStudy could be used here)
         RooDataSet* tmpValues = (RooDataSet*) fPriorPdf->generate(*fNuisanceParameters,1);
         for (int iParameter=0; iParameter<nParameters; iParameter++) {
            RooRealVar* oneParam = (RooRealVar*) parametersList.at(iParameter);
            oneParam->setVal(tmpValues->get()->getRealValue(oneParam->GetName()));
         }
         delete tmpValues;
      }

      /// generate the dataset in the B-only hypothesis
      RooAbsData* bData;
      if (fGenerateBinned)
	bData = static_cast<RooAbsData*> (fBModel->generateBinned(*fObservables,RooFit::Extended()));	
      else 
	bData = static_cast<RooAbsData*> (fBModel->generate(*fObservables,RooFit::Extended()));

      /// work-around in case of an empty dataset (TO DO: need a debug in RooFit?)
      bool bIsEmpty = false;
      if (bData==NULL) {
         bIsEmpty = true;
         // if ( _verbose ) std::cout << "empty B-only dataset!\n";
         RooDataSet* bDataDummy=new RooDataSet("bDataDummy","empty dataset",*fObservables);
         bData = static_cast<RooAbsData*>(new RooDataHist ("bDataEmpty","",*fObservables,*bDataDummy));
         delete bDataDummy;
      }

      /// generate the dataset in the S+B hypothesis
      RooAbsData* sbData;
      if (fGenerateBinned)    
	sbData = static_cast<RooAbsData*> (fSbModel->generateBinned(*fObservables,RooFit::Extended()));
      else
	sbData = static_cast<RooAbsData*> (fSbModel->generate(*fObservables,RooFit::Extended()));

      /// work-around in case of an empty dataset (TO DO: need a debug in RooFit?)
      bool sbIsEmpty = false;
      if (sbData==NULL) {
         sbIsEmpty = true;
         // if ( _verbose ) std::cout << "empty S+B dataset!\n";
         RooDataSet* sbDataDummy=new RooDataSet("sbDataDummy","empty dataset",*fObservables);
         sbData = static_cast<RooAbsData*>(new RooDataHist ("sbDataEmpty","",*fObservables,*sbDataDummy));
         delete sbDataDummy;
      }

      /// restore the parameters to their initial values
      if (usePriors && nParameters>0) {
         for (int iParameter=0; iParameter<nParameters; iParameter++) {
            RooRealVar* oneParam = (RooRealVar*) parametersList.at(iParameter);
            oneParam->setVal(parameterValues[iParameter]);
         }
      }

      /// evaluate the test statistic in the S+B case
      if ( fTestStatisticsIdx==2 ) {
         /// number of events used as test statistics
         double nEvents = 0;
         if ( !sbIsEmpty ) nEvents = sbData->numEntries();
         sbVals.push_back(nEvents);
      } else if ( fTestStatisticsIdx==3 ) {
         /// profiled likelihood ratio used as test statistics
         RooNLLVar sb_nll("sb_nll","sb_nll",*fSbModel,*sbData,RooFit::Extended());
         fSbModel->fitTo(*sbData);
         double sb_nll_val = sb_nll.getVal();
         RooNLLVar b_nll("b_nll","b_nll",*fBModel,*sbData,RooFit::Extended());
         fBModel->fitTo(*sbData);
         double b_nll_val = b_nll.getVal();
         double m2lnQ = 2*(sb_nll_val-b_nll_val);
         sbVals.push_back(m2lnQ);
      } else if ( fTestStatisticsIdx==1 ) {
         /// likelihood ratio used as test statistics (default)
         RooNLLVar sb_nll("sb_nll","sb_nll",*fSbModel,*sbData,RooFit::Extended());
         RooNLLVar b_nll("b_nll","b_nll",*fBModel,*sbData,RooFit::Extended());
         double m2lnQ = 2*(sb_nll.getVal()-b_nll.getVal());
         sbVals.push_back(m2lnQ);
      }

      /// evaluate the test statistic in the B-only case
      if ( fTestStatisticsIdx==2 ) {
         /// number of events used as test statistics
         double nEvents = 0;
         if ( !bIsEmpty ) nEvents = bData->numEntries();
         bVals.push_back(nEvents);
      } else if ( fTestStatisticsIdx==3 ) {
         /// profiled likelihood ratio used as test statistics
         RooNLLVar sb_nll("sb_nll","sb_nll",*fSbModel,*bData,RooFit::Extended());
         fSbModel->fitTo(*bData);
         double sb_nll_val = sb_nll.getVal();
         RooNLLVar b_nll("b_nll","b_nll",*fBModel,*bData,RooFit::Extended());
         fBModel->fitTo(*bData);
         double b_nll_val = b_nll.getVal();
         double m2lnQ = 2*(sb_nll_val-b_nll_val);
         bVals.push_back(m2lnQ);
      } else if ( fTestStatisticsIdx==1 ) {
         /// likelihood ratio used as test statistics (default)
         RooNLLVar sb_nll("sb_nll","sb_nll",*fSbModel,*bData,RooFit::Extended());
         RooNLLVar b_nll("b_nll","b_nll",*fBModel,*bData,RooFit::Extended());
         double m2lnQ = 2*(sb_nll.getVal()-b_nll.getVal());
         bVals.push_back(m2lnQ);
      }

      /// delete the toy-MC datasets
      delete sbData;
      delete bData;

   } /// end of loop over toy-MC experiments

   /// restore the parameters to their initial values (for safety) and delete the array of values
   if (usePriors && nParameters>0) {
      for (int iParameter=0; iParameter<nParameters; iParameter++) {
         RooRealVar* oneParam = (RooRealVar*) parametersList.at(iParameter);
         oneParam->setVal(parameterValues[iParameter]);
      }
   }

   return;
}

///////////////////////////////////////////////////////////////////////////

void HybridCalculator::PrintMore(const char* options) const
{
   /// Print out some information about the input models

   if (fSbModel) { 
      std::cout << "Signal plus background model:\n";
      fSbModel->Print(options);
   }

   if (fBModel) { 
      std::cout << "\nBackground model:\n";
      fBModel->Print(options);
   }
      
   if (fObservables) {  
      std::cout << "\nObservables:\n";
      fObservables->Print(options);
   }

   if (fNuisanceParameters) { 
      std::cout << "\nParameters being integrated:\n";
      fNuisanceParameters->Print(options);
   }

   if (fPriorPdf) { 
      std::cout << "\nPrior PDF model for integration:\n";
      fPriorPdf->Print(options);
   }

   return;
}
///////////////////////////////////////////////////////////////////////////
// implementation of inherited methods from HypoTestCalculator

HybridResult* HybridCalculator::GetHypoTest() const {  
   // perform the hypothesis test and return result of hypothesis test 

   // check first that everything needed is there 
   if (!DoCheckInputs()) return 0;  
   RooAbsData * treeData = dynamic_cast<RooAbsData *> (fData); 
   if (!treeData) { 
      std::cerr << "Error in HybridCalculator::GetHypoTest - invalid data type - return NULL" << std::endl;
      return 0; 
   }
   bool usePrior = (fUsePriorPdf && fPriorPdf ); 
   return Calculate( *treeData, fNToys, usePrior);  
}


bool HybridCalculator::DoCheckInputs() const { 
   if (!fData) { 
      std::cerr << "Error in HybridCalculator - data have not been set" << std::endl;
      return false; 
   }

   // if observable have not been set take them from data 
   if (!fObservables && fData->get() ) fObservables =  new RooArgList( *fData->get() );
   if (!fObservables) { 
      std::cerr << "Error in HybridCalculator - no observables" << std::endl;
      return false; 
   }

   if (!fSbModel) { 
      std::cerr << "Error in HybridCalculator - S+B pdf has not been set " << std::endl;
      return false; 
   }

   if (!fBModel) { 
      std::cerr << "Error in HybridCalculator - B pdf has not been set" << std::endl;
      return false; 
   }
   if (fUsePriorPdf && !fNuisanceParameters) { 
      std::cerr << "Error in HybridCalculator - nuisance parameters have not been set " << std::endl;
      return false; 
   }
   if (fUsePriorPdf && !fPriorPdf) { 
      std::cerr << "Error in HybridCalculator - prior pdf has not been set " << std::endl;
      return false; 
   }
   return true; 
}


 HybridCalculator.cxx:1
 HybridCalculator.cxx:2
 HybridCalculator.cxx:3
 HybridCalculator.cxx:4
 HybridCalculator.cxx:5
 HybridCalculator.cxx:6
 HybridCalculator.cxx:7
 HybridCalculator.cxx:8
 HybridCalculator.cxx:9
 HybridCalculator.cxx:10
 HybridCalculator.cxx:11
 HybridCalculator.cxx:12
 HybridCalculator.cxx:13
 HybridCalculator.cxx:14
 HybridCalculator.cxx:15
 HybridCalculator.cxx:16
 HybridCalculator.cxx:17
 HybridCalculator.cxx:18
 HybridCalculator.cxx:19
 HybridCalculator.cxx:20
 HybridCalculator.cxx:21
 HybridCalculator.cxx:22
 HybridCalculator.cxx:23
 HybridCalculator.cxx:24
 HybridCalculator.cxx:25
 HybridCalculator.cxx:26
 HybridCalculator.cxx:27
 HybridCalculator.cxx:28
 HybridCalculator.cxx:29
 HybridCalculator.cxx:30
 HybridCalculator.cxx:31
 HybridCalculator.cxx:32
 HybridCalculator.cxx:33
 HybridCalculator.cxx:34
 HybridCalculator.cxx:35
 HybridCalculator.cxx:36
 HybridCalculator.cxx:37
 HybridCalculator.cxx:38
 HybridCalculator.cxx:39
 HybridCalculator.cxx:40
 HybridCalculator.cxx:41
 HybridCalculator.cxx:42
 HybridCalculator.cxx:43
 HybridCalculator.cxx:44
 HybridCalculator.cxx:45
 HybridCalculator.cxx:46
 HybridCalculator.cxx:47
 HybridCalculator.cxx:48
 HybridCalculator.cxx:49
 HybridCalculator.cxx:50
 HybridCalculator.cxx:51
 HybridCalculator.cxx:52
 HybridCalculator.cxx:53
 HybridCalculator.cxx:54
 HybridCalculator.cxx:55
 HybridCalculator.cxx:56
 HybridCalculator.cxx:57
 HybridCalculator.cxx:58
 HybridCalculator.cxx:59
 HybridCalculator.cxx:60
 HybridCalculator.cxx:61
 HybridCalculator.cxx:62
 HybridCalculator.cxx:63
 HybridCalculator.cxx:64
 HybridCalculator.cxx:65
 HybridCalculator.cxx:66
 HybridCalculator.cxx:67
 HybridCalculator.cxx:68
 HybridCalculator.cxx:69
 HybridCalculator.cxx:70
 HybridCalculator.cxx:71
 HybridCalculator.cxx:72
 HybridCalculator.cxx:73
 HybridCalculator.cxx:74
 HybridCalculator.cxx:75
 HybridCalculator.cxx:76
 HybridCalculator.cxx:77
 HybridCalculator.cxx:78
 HybridCalculator.cxx:79
 HybridCalculator.cxx:80
 HybridCalculator.cxx:81
 HybridCalculator.cxx:82
 HybridCalculator.cxx:83
 HybridCalculator.cxx:84
 HybridCalculator.cxx:85
 HybridCalculator.cxx:86
 HybridCalculator.cxx:87
 HybridCalculator.cxx:88
 HybridCalculator.cxx:89
 HybridCalculator.cxx:90
 HybridCalculator.cxx:91
 HybridCalculator.cxx:92
 HybridCalculator.cxx:93
 HybridCalculator.cxx:94
 HybridCalculator.cxx:95
 HybridCalculator.cxx:96
 HybridCalculator.cxx:97
 HybridCalculator.cxx:98
 HybridCalculator.cxx:99
 HybridCalculator.cxx:100
 HybridCalculator.cxx:101
 HybridCalculator.cxx:102
 HybridCalculator.cxx:103
 HybridCalculator.cxx:104
 HybridCalculator.cxx:105
 HybridCalculator.cxx:106
 HybridCalculator.cxx:107
 HybridCalculator.cxx:108
 HybridCalculator.cxx:109
 HybridCalculator.cxx:110
 HybridCalculator.cxx:111
 HybridCalculator.cxx:112
 HybridCalculator.cxx:113
 HybridCalculator.cxx:114
 HybridCalculator.cxx:115
 HybridCalculator.cxx:116
 HybridCalculator.cxx:117
 HybridCalculator.cxx:118
 HybridCalculator.cxx:119
 HybridCalculator.cxx:120
 HybridCalculator.cxx:121
 HybridCalculator.cxx:122
 HybridCalculator.cxx:123
 HybridCalculator.cxx:124
 HybridCalculator.cxx:125
 HybridCalculator.cxx:126
 HybridCalculator.cxx:127
 HybridCalculator.cxx:128
 HybridCalculator.cxx:129
 HybridCalculator.cxx:130
 HybridCalculator.cxx:131
 HybridCalculator.cxx:132
 HybridCalculator.cxx:133
 HybridCalculator.cxx:134
 HybridCalculator.cxx:135
 HybridCalculator.cxx:136
 HybridCalculator.cxx:137
 HybridCalculator.cxx:138
 HybridCalculator.cxx:139
 HybridCalculator.cxx:140
 HybridCalculator.cxx:141
 HybridCalculator.cxx:142
 HybridCalculator.cxx:143
 HybridCalculator.cxx:144
 HybridCalculator.cxx:145
 HybridCalculator.cxx:146
 HybridCalculator.cxx:147
 HybridCalculator.cxx:148
 HybridCalculator.cxx:149
 HybridCalculator.cxx:150
 HybridCalculator.cxx:151
 HybridCalculator.cxx:152
 HybridCalculator.cxx:153
 HybridCalculator.cxx:154
 HybridCalculator.cxx:155
 HybridCalculator.cxx:156
 HybridCalculator.cxx:157
 HybridCalculator.cxx:158
 HybridCalculator.cxx:159
 HybridCalculator.cxx:160
 HybridCalculator.cxx:161
 HybridCalculator.cxx:162
 HybridCalculator.cxx:163
 HybridCalculator.cxx:164
 HybridCalculator.cxx:165
 HybridCalculator.cxx:166
 HybridCalculator.cxx:167
 HybridCalculator.cxx:168
 HybridCalculator.cxx:169
 HybridCalculator.cxx:170
 HybridCalculator.cxx:171
 HybridCalculator.cxx:172
 HybridCalculator.cxx:173
 HybridCalculator.cxx:174
 HybridCalculator.cxx:175
 HybridCalculator.cxx:176
 HybridCalculator.cxx:177
 HybridCalculator.cxx:178
 HybridCalculator.cxx:179
 HybridCalculator.cxx:180
 HybridCalculator.cxx:181
 HybridCalculator.cxx:182
 HybridCalculator.cxx:183
 HybridCalculator.cxx:184
 HybridCalculator.cxx:185
 HybridCalculator.cxx:186
 HybridCalculator.cxx:187
 HybridCalculator.cxx:188
 HybridCalculator.cxx:189
 HybridCalculator.cxx:190
 HybridCalculator.cxx:191
 HybridCalculator.cxx:192
 HybridCalculator.cxx:193
 HybridCalculator.cxx:194
 HybridCalculator.cxx:195
 HybridCalculator.cxx:196
 HybridCalculator.cxx:197
 HybridCalculator.cxx:198
 HybridCalculator.cxx:199
 HybridCalculator.cxx:200
 HybridCalculator.cxx:201
 HybridCalculator.cxx:202
 HybridCalculator.cxx:203
 HybridCalculator.cxx:204
 HybridCalculator.cxx:205
 HybridCalculator.cxx:206
 HybridCalculator.cxx:207
 HybridCalculator.cxx:208
 HybridCalculator.cxx:209
 HybridCalculator.cxx:210
 HybridCalculator.cxx:211
 HybridCalculator.cxx:212
 HybridCalculator.cxx:213
 HybridCalculator.cxx:214
 HybridCalculator.cxx:215
 HybridCalculator.cxx:216
 HybridCalculator.cxx:217
 HybridCalculator.cxx:218
 HybridCalculator.cxx:219
 HybridCalculator.cxx:220
 HybridCalculator.cxx:221
 HybridCalculator.cxx:222
 HybridCalculator.cxx:223
 HybridCalculator.cxx:224
 HybridCalculator.cxx:225
 HybridCalculator.cxx:226
 HybridCalculator.cxx:227
 HybridCalculator.cxx:228
 HybridCalculator.cxx:229
 HybridCalculator.cxx:230
 HybridCalculator.cxx:231
 HybridCalculator.cxx:232
 HybridCalculator.cxx:233
 HybridCalculator.cxx:234
 HybridCalculator.cxx:235
 HybridCalculator.cxx:236
 HybridCalculator.cxx:237
 HybridCalculator.cxx:238
 HybridCalculator.cxx:239
 HybridCalculator.cxx:240
 HybridCalculator.cxx:241
 HybridCalculator.cxx:242
 HybridCalculator.cxx:243
 HybridCalculator.cxx:244
 HybridCalculator.cxx:245
 HybridCalculator.cxx:246
 HybridCalculator.cxx:247
 HybridCalculator.cxx:248
 HybridCalculator.cxx:249
 HybridCalculator.cxx:250
 HybridCalculator.cxx:251
 HybridCalculator.cxx:252
 HybridCalculator.cxx:253
 HybridCalculator.cxx:254
 HybridCalculator.cxx:255
 HybridCalculator.cxx:256
 HybridCalculator.cxx:257
 HybridCalculator.cxx:258
 HybridCalculator.cxx:259
 HybridCalculator.cxx:260
 HybridCalculator.cxx:261
 HybridCalculator.cxx:262
 HybridCalculator.cxx:263
 HybridCalculator.cxx:264
 HybridCalculator.cxx:265
 HybridCalculator.cxx:266
 HybridCalculator.cxx:267
 HybridCalculator.cxx:268
 HybridCalculator.cxx:269
 HybridCalculator.cxx:270
 HybridCalculator.cxx:271
 HybridCalculator.cxx:272
 HybridCalculator.cxx:273
 HybridCalculator.cxx:274
 HybridCalculator.cxx:275
 HybridCalculator.cxx:276
 HybridCalculator.cxx:277
 HybridCalculator.cxx:278
 HybridCalculator.cxx:279
 HybridCalculator.cxx:280
 HybridCalculator.cxx:281
 HybridCalculator.cxx:282
 HybridCalculator.cxx:283
 HybridCalculator.cxx:284
 HybridCalculator.cxx:285
 HybridCalculator.cxx:286
 HybridCalculator.cxx:287
 HybridCalculator.cxx:288
 HybridCalculator.cxx:289
 HybridCalculator.cxx:290
 HybridCalculator.cxx:291
 HybridCalculator.cxx:292
 HybridCalculator.cxx:293
 HybridCalculator.cxx:294
 HybridCalculator.cxx:295
 HybridCalculator.cxx:296
 HybridCalculator.cxx:297
 HybridCalculator.cxx:298
 HybridCalculator.cxx:299
 HybridCalculator.cxx:300
 HybridCalculator.cxx:301
 HybridCalculator.cxx:302
 HybridCalculator.cxx:303
 HybridCalculator.cxx:304
 HybridCalculator.cxx:305
 HybridCalculator.cxx:306
 HybridCalculator.cxx:307
 HybridCalculator.cxx:308
 HybridCalculator.cxx:309
 HybridCalculator.cxx:310
 HybridCalculator.cxx:311
 HybridCalculator.cxx:312
 HybridCalculator.cxx:313
 HybridCalculator.cxx:314
 HybridCalculator.cxx:315
 HybridCalculator.cxx:316
 HybridCalculator.cxx:317
 HybridCalculator.cxx:318
 HybridCalculator.cxx:319
 HybridCalculator.cxx:320
 HybridCalculator.cxx:321
 HybridCalculator.cxx:322
 HybridCalculator.cxx:323
 HybridCalculator.cxx:324
 HybridCalculator.cxx:325
 HybridCalculator.cxx:326
 HybridCalculator.cxx:327
 HybridCalculator.cxx:328
 HybridCalculator.cxx:329
 HybridCalculator.cxx:330
 HybridCalculator.cxx:331
 HybridCalculator.cxx:332
 HybridCalculator.cxx:333
 HybridCalculator.cxx:334
 HybridCalculator.cxx:335
 HybridCalculator.cxx:336
 HybridCalculator.cxx:337
 HybridCalculator.cxx:338
 HybridCalculator.cxx:339
 HybridCalculator.cxx:340
 HybridCalculator.cxx:341
 HybridCalculator.cxx:342
 HybridCalculator.cxx:343
 HybridCalculator.cxx:344
 HybridCalculator.cxx:345
 HybridCalculator.cxx:346
 HybridCalculator.cxx:347
 HybridCalculator.cxx:348
 HybridCalculator.cxx:349
 HybridCalculator.cxx:350
 HybridCalculator.cxx:351
 HybridCalculator.cxx:352
 HybridCalculator.cxx:353
 HybridCalculator.cxx:354
 HybridCalculator.cxx:355
 HybridCalculator.cxx:356
 HybridCalculator.cxx:357
 HybridCalculator.cxx:358
 HybridCalculator.cxx:359
 HybridCalculator.cxx:360
 HybridCalculator.cxx:361
 HybridCalculator.cxx:362
 HybridCalculator.cxx:363
 HybridCalculator.cxx:364
 HybridCalculator.cxx:365
 HybridCalculator.cxx:366
 HybridCalculator.cxx:367
 HybridCalculator.cxx:368
 HybridCalculator.cxx:369
 HybridCalculator.cxx:370
 HybridCalculator.cxx:371
 HybridCalculator.cxx:372
 HybridCalculator.cxx:373
 HybridCalculator.cxx:374
 HybridCalculator.cxx:375
 HybridCalculator.cxx:376
 HybridCalculator.cxx:377
 HybridCalculator.cxx:378
 HybridCalculator.cxx:379
 HybridCalculator.cxx:380
 HybridCalculator.cxx:381
 HybridCalculator.cxx:382
 HybridCalculator.cxx:383
 HybridCalculator.cxx:384
 HybridCalculator.cxx:385
 HybridCalculator.cxx:386
 HybridCalculator.cxx:387
 HybridCalculator.cxx:388
 HybridCalculator.cxx:389
 HybridCalculator.cxx:390
 HybridCalculator.cxx:391
 HybridCalculator.cxx:392
 HybridCalculator.cxx:393
 HybridCalculator.cxx:394
 HybridCalculator.cxx:395
 HybridCalculator.cxx:396
 HybridCalculator.cxx:397
 HybridCalculator.cxx:398
 HybridCalculator.cxx:399
 HybridCalculator.cxx:400
 HybridCalculator.cxx:401
 HybridCalculator.cxx:402
 HybridCalculator.cxx:403
 HybridCalculator.cxx:404
 HybridCalculator.cxx:405
 HybridCalculator.cxx:406
 HybridCalculator.cxx:407
 HybridCalculator.cxx:408
 HybridCalculator.cxx:409
 HybridCalculator.cxx:410
 HybridCalculator.cxx:411
 HybridCalculator.cxx:412
 HybridCalculator.cxx:413
 HybridCalculator.cxx:414
 HybridCalculator.cxx:415
 HybridCalculator.cxx:416
 HybridCalculator.cxx:417
 HybridCalculator.cxx:418
 HybridCalculator.cxx:419
 HybridCalculator.cxx:420
 HybridCalculator.cxx:421
 HybridCalculator.cxx:422
 HybridCalculator.cxx:423
 HybridCalculator.cxx:424
 HybridCalculator.cxx:425
 HybridCalculator.cxx:426
 HybridCalculator.cxx:427
 HybridCalculator.cxx:428
 HybridCalculator.cxx:429
 HybridCalculator.cxx:430
 HybridCalculator.cxx:431
 HybridCalculator.cxx:432
 HybridCalculator.cxx:433
 HybridCalculator.cxx:434
 HybridCalculator.cxx:435
 HybridCalculator.cxx:436
 HybridCalculator.cxx:437
 HybridCalculator.cxx:438
 HybridCalculator.cxx:439
 HybridCalculator.cxx:440
 HybridCalculator.cxx:441
 HybridCalculator.cxx:442
 HybridCalculator.cxx:443
 HybridCalculator.cxx:444
 HybridCalculator.cxx:445
 HybridCalculator.cxx:446
 HybridCalculator.cxx:447
 HybridCalculator.cxx:448
 HybridCalculator.cxx:449
 HybridCalculator.cxx:450
 HybridCalculator.cxx:451
 HybridCalculator.cxx:452
 HybridCalculator.cxx:453
 HybridCalculator.cxx:454
 HybridCalculator.cxx:455
 HybridCalculator.cxx:456
 HybridCalculator.cxx:457
 HybridCalculator.cxx:458
 HybridCalculator.cxx:459
 HybridCalculator.cxx:460
 HybridCalculator.cxx:461
 HybridCalculator.cxx:462
 HybridCalculator.cxx:463
 HybridCalculator.cxx:464
 HybridCalculator.cxx:465
 HybridCalculator.cxx:466
 HybridCalculator.cxx:467
 HybridCalculator.cxx:468
 HybridCalculator.cxx:469
 HybridCalculator.cxx:470
 HybridCalculator.cxx:471
 HybridCalculator.cxx:472
 HybridCalculator.cxx:473
 HybridCalculator.cxx:474
 HybridCalculator.cxx:475
 HybridCalculator.cxx:476
 HybridCalculator.cxx:477
 HybridCalculator.cxx:478
 HybridCalculator.cxx:479
 HybridCalculator.cxx:480
 HybridCalculator.cxx:481
 HybridCalculator.cxx:482
 HybridCalculator.cxx:483
 HybridCalculator.cxx:484
 HybridCalculator.cxx:485
 HybridCalculator.cxx:486
 HybridCalculator.cxx:487
 HybridCalculator.cxx:488
 HybridCalculator.cxx:489
 HybridCalculator.cxx:490
 HybridCalculator.cxx:491
 HybridCalculator.cxx:492
 HybridCalculator.cxx:493
 HybridCalculator.cxx:494
 HybridCalculator.cxx:495
 HybridCalculator.cxx:496
 HybridCalculator.cxx:497
 HybridCalculator.cxx:498
 HybridCalculator.cxx:499
 HybridCalculator.cxx:500
 HybridCalculator.cxx:501
 HybridCalculator.cxx:502
 HybridCalculator.cxx:503
 HybridCalculator.cxx:504
 HybridCalculator.cxx:505
 HybridCalculator.cxx:506
 HybridCalculator.cxx:507
 HybridCalculator.cxx:508
 HybridCalculator.cxx:509
 HybridCalculator.cxx:510
 HybridCalculator.cxx:511
 HybridCalculator.cxx:512
 HybridCalculator.cxx:513
 HybridCalculator.cxx:514
 HybridCalculator.cxx:515
 HybridCalculator.cxx:516
 HybridCalculator.cxx:517
 HybridCalculator.cxx:518
 HybridCalculator.cxx:519
 HybridCalculator.cxx:520
 HybridCalculator.cxx:521
 HybridCalculator.cxx:522
 HybridCalculator.cxx:523
 HybridCalculator.cxx:524
 HybridCalculator.cxx:525
 HybridCalculator.cxx:526
 HybridCalculator.cxx:527
 HybridCalculator.cxx:528
 HybridCalculator.cxx:529
 HybridCalculator.cxx:530
 HybridCalculator.cxx:531
 HybridCalculator.cxx:532
 HybridCalculator.cxx:533
 HybridCalculator.cxx:534
 HybridCalculator.cxx:535
 HybridCalculator.cxx:536
 HybridCalculator.cxx:537
 HybridCalculator.cxx:538
 HybridCalculator.cxx:539
 HybridCalculator.cxx:540
 HybridCalculator.cxx:541
 HybridCalculator.cxx:542
 HybridCalculator.cxx:543
 HybridCalculator.cxx:544
 HybridCalculator.cxx:545
 HybridCalculator.cxx:546
 HybridCalculator.cxx:547