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

//_________________________________________________________________
/**
   HypoTestInverterOriginal class for performing an hypothesis test inversion by scanning the hypothesis test results of the 
  HybridCalculator  for various values of the parameter of interest. By looking at the confidence level curve of 
 the result  an upper limit, where it intersects the desired confidence level, can be derived.
 The class implements the RooStats::IntervalCalculator interface and returns an  RooStats::HypoTestInverterResult class.
 The result is a SimpleInterval, which via the method UpperLimit returns to the user the upper limit value.

The  HypoTestInverterOriginal implements various option for performing the scan. HypoTestInverterOriginal::RunFixedScan will scan using a fixed grid the parameter of interest. HypoTestInverterOriginal::RunAutoScan will perform an automatic scan to find optimally the curve and it will stop until the desired precision is obtained.
The confidence level value at a given point can be done via  HypoTestInverterOriginal::RunOnePoint.
The class can scan the CLs+b values or alternativly CLs (if the method HypoTestInverterOriginal::UseCLs has been called).


   New contributions to this class have been written by Matthias Wolf (advanced AutoRun algorithm)
**/

// include other header files

#include "RooAbsPdf.h"
#include "RooAbsData.h"
#include "RooRealVar.h"
#include "TMath.h"

#include "RooStats/HybridCalculatorOriginal.h"
#include "RooStats/HybridResult.h"

// include header file of this class 
#include "RooStats/HypoTestInverterOriginal.h"


ClassImp(RooStats::HypoTestInverterOriginal)

using namespace RooStats;
using namespace std;


HypoTestInverterOriginal::HypoTestInverterOriginal( ) :
   fCalculator0(0),
   fScannedVariable(0),
   fResults(0),
   fUseCLs(false),
   fSize(0)
{
  // default constructor (doesn't do anything) 
}


HypoTestInverterOriginal::HypoTestInverterOriginal( HypoTestCalculator& myhc0,
				    RooRealVar& scannedVariable, double size ) :
   TNamed( ),
   fCalculator0(&myhc0),
   fScannedVariable(&scannedVariable), 
   fResults(0),
   fUseCLs(false),
   fSize(size)
{
   // constructor from a reference to an HypoTestCalculator 
   // (it must be an HybridCalculator type) and a RooRealVar for the variable
   SetName("HypoTestInverterOriginal");


   HybridCalculatorOriginal * hc = dynamic_cast<HybridCalculatorOriginal *> (fCalculator0);
   if (hc == 0) { 
      Fatal("HypoTestInverterOriginal","Using non HybridCalculatorOriginal class IS NOT SUPPORTED");
   }

}


HypoTestInverterOriginal::~HypoTestInverterOriginal()
{
  // destructor
  
  // delete the HypoTestInverterResult
  if (fResults) delete fResults;
}

void  HypoTestInverterOriginal::CreateResults() { 
  // create a new HypoTestInverterResult to hold all computed results
   if (fResults == 0) {
      TString results_name = this->GetName();
      results_name += "_results";
      fResults = new HypoTestInverterResult(results_name,*fScannedVariable,ConfidenceLevel());
      fResults->SetTitle("HypoTestInverterOriginal Result");
   }
   fResults->UseCLs(fUseCLs);
}


bool HypoTestInverterOriginal::RunAutoScan( double xMin, double xMax, double target, double epsilon, unsigned int numAlgorithm  )
{
  /// Search for the value of the parameter of interest (vary the
  /// hypothesis being tested) in the specified range [xMin,xMax]
  /// until the confidence level is compatible with the target value
  /// within one time the estimated error (and the estimated error
  /// should also become smaller than the specified parameter epsilon)

  // various sanity checks on the input parameters
  if ( xMin>=xMax || xMin< fScannedVariable->getMin() || xMax>fScannedVariable->getMax() ) {
    std::cout << "Error: problem with the specified range\n";
    return false;
  }
  if ( target<=0 || target>=1 ) {
    std::cout << "Error: problem with target value\n";
    return false;
  }
  if ( epsilon>0.5-fabs(0.5-target) ) {
    std::cout << "Error: problem with error value\n";
    return false;
  }
  if ( numAlgorithm!=0 && numAlgorithm!=1 ) {
    std::cout << "Error: invalid interpolation algorithm\n";
    return false;
  }

  CreateResults();

  // if ( TMath::AreEqualRel(target,1-Size()/2,DBL_EPSILON) ) {  // to uncomment for ROOT 5.26
  if ( fabs(1-target/(1-Size()/2))<DBL_EPSILON ) {
    fResults->fInterpolateLowerLimit = false;
    std::cout << "Target matches lower limit: de-activate interpolation in HypoTestInverterResult\n";
  }
  // if ( TMath::AreEqualRel(target,Size()/2,DBL_EPSILON) ) {  // to uncomment for ROOT 5.26
  if ( fabs(1-target/((Size()/2)))<DBL_EPSILON ) {
    fResults->fInterpolateUpperLimit = false;
    std::cout << "Target matches upper limit: de-activate interpolation in HypoTestInverterResult\n";
  }

  // parameters of the algorithm that are hard-coded
  const double nSigma = 1; // number of times the estimated error the final p-value should be from the target

  // backup some values to be restored at the end 
  const unsigned int nToys_backup = ((HybridCalculatorOriginal*)fCalculator0)->GetNumberOfToys();

  // check the 2 hypothesis tests specified as extrema in the constructor
  double leftX = xMin;
  if (!RunOnePoint(leftX)) return false;
  double leftCL = fResults->GetYValue(fResults->ArraySize()-1);
  double leftCLError = fResults->GetYError(fResults->ArraySize()-1);
 
  double rightX = xMax;
  if (!RunOnePoint(rightX)) return false;
  double rightCL = fResults->GetYValue(fResults->ArraySize()-1);
  double rightCLError = fResults->GetYError(fResults->ArraySize()-1);
  
  if ( rightCL>target && leftCL>target ) {
    std::cout << "The confidence level at both boundaries are both too large ( " << leftCL << " and " <<  rightCL << std::endl << "Run again with other boundaries or larger toy-MC statistics\n";
    return false;
  }
  if ( rightCL<target && leftCL<target ) {
    std::cout << "The confidence level at both boundaries are both too small ( " << leftCL << " and " <<  rightCL << std::endl << "Run again with other boundaries or larger toy-MC statistics\n";
    return false;
  }

  unsigned int nIteration = 2;  // number of iteration performed by the algorithm
  bool quitThisLoop = false;  // flag to interrupt the search and quit cleanly

  double centerCL = 0;
  double centerCLError = 0;

  // search for the value of the searched variable where the CL is
  // within 1 sigma of the desired level and sigma smaller than
  // epsilon.
  do {
    double x = 0;

    // safety checks
    if (leftCL==rightCL) {
      std::cout << "This cannot (and should not) happen... quit\n";
      quitThisLoop = true;
    } else if (leftX==rightX) {
      std::cout << "This cannot (and should not) happen... quit\n";
      quitThisLoop = true;
    } else {

      // apply chosen type of interpolation algorithm
      if (numAlgorithm==0) {
	// exponential interpolation

	// add safety checks
	if (!leftCL) leftCL = DBL_EPSILON;
	if (!rightCL) rightCL = DBL_EPSILON;

	double a = (log(leftCL) - log(rightCL)) / (leftX - rightX);
	double b = leftCL / exp(a * leftX);
	x = (log(target) - log(b)) / a;

	// to do: do not allow next iteration outside the xMin,xMax interval
	if (x<xMin || x>xMax || TMath::IsNaN(x)) {
	  std::cout << "Extrapolated value out of range or nan: exits\n";
	  quitThisLoop = true;
	}
      } else if (numAlgorithm==1) {
	// linear interpolation
	
	double a = (leftCL-rightCL)/(leftX-rightX);
	double b = leftCL-a*leftX;
	x = (target-b)/a;

	if (x<xMin || x>xMax || TMath::IsNaN(x)) {
	  std::cout << "Extrapolated value out of range or nan: exits\n";
	  quitThisLoop = true;
	}
      }  // end of interpolation algorithms
    }

    if ( x==leftX || x==rightX ) {
      std::cout << "Error: exit because interpolated value equals to a previous iteration\n";
      quitThisLoop = true;
    }

    // perform another hypothesis-test for value x
    bool success = false;
    if (!quitThisLoop) success = RunOnePoint(x);

    if (success) {

      nIteration++;  // succeeded, increase the iteration counter
      centerCL = fResults->GetYValue(fResults->ArraySize()-1);
      centerCLError = fResults->GetYError(fResults->ArraySize()-1);

      // replace either the left or right point by this new point
    
      // test if the interval points are on different sides, then
      // replace the one on the correct side with the center
      if ( (leftCL > target) == (rightCL < target) ) {
	if ( (centerCL > target) == (leftCL > target) ) {
	  leftX = x;
	  leftCL = centerCL;
	  leftCLError = centerCLError;
	} else {
	  rightX = x;
	  rightCL = centerCL;
	  rightCLError = centerCLError;
	}
	// Otherwise replace the point farest away from target (measured in
	// sigmas)
      } else if ( (fabs(leftCL - target) / leftCLError) >
		  (fabs(rightCL - target) / rightCLError) ) {
	leftX = x;
	leftCL = centerCL;
	leftCLError = centerCLError;
      } else {
	rightX = x;
	rightCL = centerCL;
	rightCLError = centerCLError;
      }

      // if a point is found compatible with the target CL but with too
      // large error, increase the number of toyMC
      if ( fabs(centerCL-target) < nSigma*centerCLError && centerCLError > epsilon  ) {
	do {

	  int nToys = ((HybridCalculatorOriginal*)fCalculator0)->GetNumberOfToys();  // current number of toys
	  int nToysTarget = (int) TMath::Max(nToys*1.5, 1.2*nToys*pow(centerCLError/epsilon,2));  // estimated number of toys until the target precision is reached
	  
	  std::cout << "Increasing the number of toys to: " << nToysTarget << std::endl;
	  
	  // run again the same point with more toyMC (run the complement number of toys)
	  ((HybridCalculatorOriginal*)fCalculator0)->SetNumberOfToys(nToysTarget-nToys);
	  
	  if (!RunOnePoint(x)) quitThisLoop=true;
	  nIteration++;  // succeeded, increase the iteration counter
	  centerCL = fResults->GetYValue(fResults->ArraySize()-1);
	  centerCLError = fResults->GetYError(fResults->ArraySize()-1);
	  
	  // set the number of toys to reach the target 
	  ((HybridCalculatorOriginal*)fCalculator0)->SetNumberOfToys(nToysTarget);
	} while ( fabs(centerCL-target) < nSigma*centerCLError && centerCLError > epsilon && quitThisLoop==false );  // run this block again if it's still compatible with the target and the error still too large
      }
      
      if (leftCL==rightCL) {
	std::cout << "Algorithm failed: left and right CL are equal (no intrapolation possible or more toy-MC statistics needed)\n";
	  quitThisLoop = true;
      }
    } // end running one more iteration

  } while ( ( fabs(centerCL-target) > nSigma*centerCLError || centerCLError > epsilon ) && quitThisLoop==false );  // end of the main 'do' loop 

  // restore some parameters that might have been changed by the algorithm
  ((HybridCalculatorOriginal*)fCalculator0)->SetNumberOfToys(nToys_backup);
  
  if ( quitThisLoop==true ) {
    // abort and return 'false' to indicate fail status
    std::cout << "Aborted the search because something happened\n";
    return false;
  }

  std::cout << "Converged in " << fResults->ArraySize() << " iterations\n";

  // finished: return 'true' for success status
  return true;
}


bool HypoTestInverterOriginal::RunFixedScan( int nBins, double xMin, double xMax )
{
   // Run a Fixed scan in npoints between min and max

   CreateResults();
  // safety checks
  if ( nBins<=0 ) {
    std::cout << "Please provide nBins>0\n";
    return false;
  }
  if ( nBins==1 && xMin!=xMax ) {
    std::cout << "nBins==1 -> I will run for xMin (" << xMin << ")\n";
  }
  if ( xMin==xMax && nBins>1 ) { 
    std::cout << "xMin==xMax -> I will enforce nBins==1\n";
    nBins = 1;
  }
  if ( xMin>xMax ) {
    std::cout << "Please provide xMin (" << xMin << ") smaller that xMax (" << xMax << ")\n";
    return false;
  } 
  
  for (int i=0; i<nBins; i++) {
    double thisX = xMin+i*(xMax-xMin)/(nBins-1);
    bool status = RunOnePoint(thisX);
    
    // check if failed status
    if ( status==false ) {
      std::cout << "Loop interrupted because of failed status\n";
      return false;
    }
  }

  return true;
}


bool HypoTestInverterOriginal::RunOnePoint( double thisX )
{
   // run only one point 

   CreateResults();

   // check if thisX is in the range specified for fScannedVariable
   if ( thisX<fScannedVariable->getMin() ) {
     std::cout << "Out of range: using the lower bound on the scanned variable rather than " << thisX<< "\n";
     thisX = fScannedVariable->getMin();
   }
   if ( thisX>fScannedVariable->getMax() ) {
     std::cout << "Out of range: using the upper bound on the scanned variable rather than " << thisX<< "\n";
     thisX = fScannedVariable->getMax();
   }

   double oldValue = fScannedVariable->getVal();

   fScannedVariable->setVal(thisX);
   std::cout << "Running for " << fScannedVariable->GetName() << " = " << thisX << endl;
   
   // compute the results
   HypoTestResult* myHybridResult = fCalculator0->GetHypoTest(); 
   
   double lastXtested;
   if ( fResults->ArraySize()!=0 ) lastXtested = fResults->GetXValue(fResults->ArraySize()-1);
   else lastXtested = -999;

   if ( lastXtested==thisX ) {
     
     std::cout << "Merge with previous result\n";
     HybridResult* latestResult = (HybridResult*) fResults->GetResult(fResults->ArraySize()-1);
     latestResult->Add((HybridResult*)myHybridResult);
     delete myHybridResult;

   } else {
     
     // fill the results in the HypoTestInverterResult array
     fResults->fXValues.push_back(thisX);
     fResults->fYObjects.Add(myHybridResult);
   }


   std::cout << "computed: " << fResults->GetYValue(fResults->ArraySize()-1) << endl;

   fScannedVariable->setVal(oldValue);
   
   return true;
}
 HypoTestInverterOriginal.cxx:1
 HypoTestInverterOriginal.cxx:2
 HypoTestInverterOriginal.cxx:3
 HypoTestInverterOriginal.cxx:4
 HypoTestInverterOriginal.cxx:5
 HypoTestInverterOriginal.cxx:6
 HypoTestInverterOriginal.cxx:7
 HypoTestInverterOriginal.cxx:8
 HypoTestInverterOriginal.cxx:9
 HypoTestInverterOriginal.cxx:10
 HypoTestInverterOriginal.cxx:11
 HypoTestInverterOriginal.cxx:12
 HypoTestInverterOriginal.cxx:13
 HypoTestInverterOriginal.cxx:14
 HypoTestInverterOriginal.cxx:15
 HypoTestInverterOriginal.cxx:16
 HypoTestInverterOriginal.cxx:17
 HypoTestInverterOriginal.cxx:18
 HypoTestInverterOriginal.cxx:19
 HypoTestInverterOriginal.cxx:20
 HypoTestInverterOriginal.cxx:21
 HypoTestInverterOriginal.cxx:22
 HypoTestInverterOriginal.cxx:23
 HypoTestInverterOriginal.cxx:24
 HypoTestInverterOriginal.cxx:25
 HypoTestInverterOriginal.cxx:26
 HypoTestInverterOriginal.cxx:27
 HypoTestInverterOriginal.cxx:28
 HypoTestInverterOriginal.cxx:29
 HypoTestInverterOriginal.cxx:30
 HypoTestInverterOriginal.cxx:31
 HypoTestInverterOriginal.cxx:32
 HypoTestInverterOriginal.cxx:33
 HypoTestInverterOriginal.cxx:34
 HypoTestInverterOriginal.cxx:35
 HypoTestInverterOriginal.cxx:36
 HypoTestInverterOriginal.cxx:37
 HypoTestInverterOriginal.cxx:38
 HypoTestInverterOriginal.cxx:39
 HypoTestInverterOriginal.cxx:40
 HypoTestInverterOriginal.cxx:41
 HypoTestInverterOriginal.cxx:42
 HypoTestInverterOriginal.cxx:43
 HypoTestInverterOriginal.cxx:44
 HypoTestInverterOriginal.cxx:45
 HypoTestInverterOriginal.cxx:46
 HypoTestInverterOriginal.cxx:47
 HypoTestInverterOriginal.cxx:48
 HypoTestInverterOriginal.cxx:49
 HypoTestInverterOriginal.cxx:50
 HypoTestInverterOriginal.cxx:51
 HypoTestInverterOriginal.cxx:52
 HypoTestInverterOriginal.cxx:53
 HypoTestInverterOriginal.cxx:54
 HypoTestInverterOriginal.cxx:55
 HypoTestInverterOriginal.cxx:56
 HypoTestInverterOriginal.cxx:57
 HypoTestInverterOriginal.cxx:58
 HypoTestInverterOriginal.cxx:59
 HypoTestInverterOriginal.cxx:60
 HypoTestInverterOriginal.cxx:61
 HypoTestInverterOriginal.cxx:62
 HypoTestInverterOriginal.cxx:63
 HypoTestInverterOriginal.cxx:64
 HypoTestInverterOriginal.cxx:65
 HypoTestInverterOriginal.cxx:66
 HypoTestInverterOriginal.cxx:67
 HypoTestInverterOriginal.cxx:68
 HypoTestInverterOriginal.cxx:69
 HypoTestInverterOriginal.cxx:70
 HypoTestInverterOriginal.cxx:71
 HypoTestInverterOriginal.cxx:72
 HypoTestInverterOriginal.cxx:73
 HypoTestInverterOriginal.cxx:74
 HypoTestInverterOriginal.cxx:75
 HypoTestInverterOriginal.cxx:76
 HypoTestInverterOriginal.cxx:77
 HypoTestInverterOriginal.cxx:78
 HypoTestInverterOriginal.cxx:79
 HypoTestInverterOriginal.cxx:80
 HypoTestInverterOriginal.cxx:81
 HypoTestInverterOriginal.cxx:82
 HypoTestInverterOriginal.cxx:83
 HypoTestInverterOriginal.cxx:84
 HypoTestInverterOriginal.cxx:85
 HypoTestInverterOriginal.cxx:86
 HypoTestInverterOriginal.cxx:87
 HypoTestInverterOriginal.cxx:88
 HypoTestInverterOriginal.cxx:89
 HypoTestInverterOriginal.cxx:90
 HypoTestInverterOriginal.cxx:91
 HypoTestInverterOriginal.cxx:92
 HypoTestInverterOriginal.cxx:93
 HypoTestInverterOriginal.cxx:94
 HypoTestInverterOriginal.cxx:95
 HypoTestInverterOriginal.cxx:96
 HypoTestInverterOriginal.cxx:97
 HypoTestInverterOriginal.cxx:98
 HypoTestInverterOriginal.cxx:99
 HypoTestInverterOriginal.cxx:100
 HypoTestInverterOriginal.cxx:101
 HypoTestInverterOriginal.cxx:102
 HypoTestInverterOriginal.cxx:103
 HypoTestInverterOriginal.cxx:104
 HypoTestInverterOriginal.cxx:105
 HypoTestInverterOriginal.cxx:106
 HypoTestInverterOriginal.cxx:107
 HypoTestInverterOriginal.cxx:108
 HypoTestInverterOriginal.cxx:109
 HypoTestInverterOriginal.cxx:110
 HypoTestInverterOriginal.cxx:111
 HypoTestInverterOriginal.cxx:112
 HypoTestInverterOriginal.cxx:113
 HypoTestInverterOriginal.cxx:114
 HypoTestInverterOriginal.cxx:115
 HypoTestInverterOriginal.cxx:116
 HypoTestInverterOriginal.cxx:117
 HypoTestInverterOriginal.cxx:118
 HypoTestInverterOriginal.cxx:119
 HypoTestInverterOriginal.cxx:120
 HypoTestInverterOriginal.cxx:121
 HypoTestInverterOriginal.cxx:122
 HypoTestInverterOriginal.cxx:123
 HypoTestInverterOriginal.cxx:124
 HypoTestInverterOriginal.cxx:125
 HypoTestInverterOriginal.cxx:126
 HypoTestInverterOriginal.cxx:127
 HypoTestInverterOriginal.cxx:128
 HypoTestInverterOriginal.cxx:129
 HypoTestInverterOriginal.cxx:130
 HypoTestInverterOriginal.cxx:131
 HypoTestInverterOriginal.cxx:132
 HypoTestInverterOriginal.cxx:133
 HypoTestInverterOriginal.cxx:134
 HypoTestInverterOriginal.cxx:135
 HypoTestInverterOriginal.cxx:136
 HypoTestInverterOriginal.cxx:137
 HypoTestInverterOriginal.cxx:138
 HypoTestInverterOriginal.cxx:139
 HypoTestInverterOriginal.cxx:140
 HypoTestInverterOriginal.cxx:141
 HypoTestInverterOriginal.cxx:142
 HypoTestInverterOriginal.cxx:143
 HypoTestInverterOriginal.cxx:144
 HypoTestInverterOriginal.cxx:145
 HypoTestInverterOriginal.cxx:146
 HypoTestInverterOriginal.cxx:147
 HypoTestInverterOriginal.cxx:148
 HypoTestInverterOriginal.cxx:149
 HypoTestInverterOriginal.cxx:150
 HypoTestInverterOriginal.cxx:151
 HypoTestInverterOriginal.cxx:152
 HypoTestInverterOriginal.cxx:153
 HypoTestInverterOriginal.cxx:154
 HypoTestInverterOriginal.cxx:155
 HypoTestInverterOriginal.cxx:156
 HypoTestInverterOriginal.cxx:157
 HypoTestInverterOriginal.cxx:158
 HypoTestInverterOriginal.cxx:159
 HypoTestInverterOriginal.cxx:160
 HypoTestInverterOriginal.cxx:161
 HypoTestInverterOriginal.cxx:162
 HypoTestInverterOriginal.cxx:163
 HypoTestInverterOriginal.cxx:164
 HypoTestInverterOriginal.cxx:165
 HypoTestInverterOriginal.cxx:166
 HypoTestInverterOriginal.cxx:167
 HypoTestInverterOriginal.cxx:168
 HypoTestInverterOriginal.cxx:169
 HypoTestInverterOriginal.cxx:170
 HypoTestInverterOriginal.cxx:171
 HypoTestInverterOriginal.cxx:172
 HypoTestInverterOriginal.cxx:173
 HypoTestInverterOriginal.cxx:174
 HypoTestInverterOriginal.cxx:175
 HypoTestInverterOriginal.cxx:176
 HypoTestInverterOriginal.cxx:177
 HypoTestInverterOriginal.cxx:178
 HypoTestInverterOriginal.cxx:179
 HypoTestInverterOriginal.cxx:180
 HypoTestInverterOriginal.cxx:181
 HypoTestInverterOriginal.cxx:182
 HypoTestInverterOriginal.cxx:183
 HypoTestInverterOriginal.cxx:184
 HypoTestInverterOriginal.cxx:185
 HypoTestInverterOriginal.cxx:186
 HypoTestInverterOriginal.cxx:187
 HypoTestInverterOriginal.cxx:188
 HypoTestInverterOriginal.cxx:189
 HypoTestInverterOriginal.cxx:190
 HypoTestInverterOriginal.cxx:191
 HypoTestInverterOriginal.cxx:192
 HypoTestInverterOriginal.cxx:193
 HypoTestInverterOriginal.cxx:194
 HypoTestInverterOriginal.cxx:195
 HypoTestInverterOriginal.cxx:196
 HypoTestInverterOriginal.cxx:197
 HypoTestInverterOriginal.cxx:198
 HypoTestInverterOriginal.cxx:199
 HypoTestInverterOriginal.cxx:200
 HypoTestInverterOriginal.cxx:201
 HypoTestInverterOriginal.cxx:202
 HypoTestInverterOriginal.cxx:203
 HypoTestInverterOriginal.cxx:204
 HypoTestInverterOriginal.cxx:205
 HypoTestInverterOriginal.cxx:206
 HypoTestInverterOriginal.cxx:207
 HypoTestInverterOriginal.cxx:208
 HypoTestInverterOriginal.cxx:209
 HypoTestInverterOriginal.cxx:210
 HypoTestInverterOriginal.cxx:211
 HypoTestInverterOriginal.cxx:212
 HypoTestInverterOriginal.cxx:213
 HypoTestInverterOriginal.cxx:214
 HypoTestInverterOriginal.cxx:215
 HypoTestInverterOriginal.cxx:216
 HypoTestInverterOriginal.cxx:217
 HypoTestInverterOriginal.cxx:218
 HypoTestInverterOriginal.cxx:219
 HypoTestInverterOriginal.cxx:220
 HypoTestInverterOriginal.cxx:221
 HypoTestInverterOriginal.cxx:222
 HypoTestInverterOriginal.cxx:223
 HypoTestInverterOriginal.cxx:224
 HypoTestInverterOriginal.cxx:225
 HypoTestInverterOriginal.cxx:226
 HypoTestInverterOriginal.cxx:227
 HypoTestInverterOriginal.cxx:228
 HypoTestInverterOriginal.cxx:229
 HypoTestInverterOriginal.cxx:230
 HypoTestInverterOriginal.cxx:231
 HypoTestInverterOriginal.cxx:232
 HypoTestInverterOriginal.cxx:233
 HypoTestInverterOriginal.cxx:234
 HypoTestInverterOriginal.cxx:235
 HypoTestInverterOriginal.cxx:236
 HypoTestInverterOriginal.cxx:237
 HypoTestInverterOriginal.cxx:238
 HypoTestInverterOriginal.cxx:239
 HypoTestInverterOriginal.cxx:240
 HypoTestInverterOriginal.cxx:241
 HypoTestInverterOriginal.cxx:242
 HypoTestInverterOriginal.cxx:243
 HypoTestInverterOriginal.cxx:244
 HypoTestInverterOriginal.cxx:245
 HypoTestInverterOriginal.cxx:246
 HypoTestInverterOriginal.cxx:247
 HypoTestInverterOriginal.cxx:248
 HypoTestInverterOriginal.cxx:249
 HypoTestInverterOriginal.cxx:250
 HypoTestInverterOriginal.cxx:251
 HypoTestInverterOriginal.cxx:252
 HypoTestInverterOriginal.cxx:253
 HypoTestInverterOriginal.cxx:254
 HypoTestInverterOriginal.cxx:255
 HypoTestInverterOriginal.cxx:256
 HypoTestInverterOriginal.cxx:257
 HypoTestInverterOriginal.cxx:258
 HypoTestInverterOriginal.cxx:259
 HypoTestInverterOriginal.cxx:260
 HypoTestInverterOriginal.cxx:261
 HypoTestInverterOriginal.cxx:262
 HypoTestInverterOriginal.cxx:263
 HypoTestInverterOriginal.cxx:264
 HypoTestInverterOriginal.cxx:265
 HypoTestInverterOriginal.cxx:266
 HypoTestInverterOriginal.cxx:267
 HypoTestInverterOriginal.cxx:268
 HypoTestInverterOriginal.cxx:269
 HypoTestInverterOriginal.cxx:270
 HypoTestInverterOriginal.cxx:271
 HypoTestInverterOriginal.cxx:272
 HypoTestInverterOriginal.cxx:273
 HypoTestInverterOriginal.cxx:274
 HypoTestInverterOriginal.cxx:275
 HypoTestInverterOriginal.cxx:276
 HypoTestInverterOriginal.cxx:277
 HypoTestInverterOriginal.cxx:278
 HypoTestInverterOriginal.cxx:279
 HypoTestInverterOriginal.cxx:280
 HypoTestInverterOriginal.cxx:281
 HypoTestInverterOriginal.cxx:282
 HypoTestInverterOriginal.cxx:283
 HypoTestInverterOriginal.cxx:284
 HypoTestInverterOriginal.cxx:285
 HypoTestInverterOriginal.cxx:286
 HypoTestInverterOriginal.cxx:287
 HypoTestInverterOriginal.cxx:288
 HypoTestInverterOriginal.cxx:289
 HypoTestInverterOriginal.cxx:290
 HypoTestInverterOriginal.cxx:291
 HypoTestInverterOriginal.cxx:292
 HypoTestInverterOriginal.cxx:293
 HypoTestInverterOriginal.cxx:294
 HypoTestInverterOriginal.cxx:295
 HypoTestInverterOriginal.cxx:296
 HypoTestInverterOriginal.cxx:297
 HypoTestInverterOriginal.cxx:298
 HypoTestInverterOriginal.cxx:299
 HypoTestInverterOriginal.cxx:300
 HypoTestInverterOriginal.cxx:301
 HypoTestInverterOriginal.cxx:302
 HypoTestInverterOriginal.cxx:303
 HypoTestInverterOriginal.cxx:304
 HypoTestInverterOriginal.cxx:305
 HypoTestInverterOriginal.cxx:306
 HypoTestInverterOriginal.cxx:307
 HypoTestInverterOriginal.cxx:308
 HypoTestInverterOriginal.cxx:309
 HypoTestInverterOriginal.cxx:310
 HypoTestInverterOriginal.cxx:311
 HypoTestInverterOriginal.cxx:312
 HypoTestInverterOriginal.cxx:313
 HypoTestInverterOriginal.cxx:314
 HypoTestInverterOriginal.cxx:315
 HypoTestInverterOriginal.cxx:316
 HypoTestInverterOriginal.cxx:317
 HypoTestInverterOriginal.cxx:318
 HypoTestInverterOriginal.cxx:319
 HypoTestInverterOriginal.cxx:320
 HypoTestInverterOriginal.cxx:321
 HypoTestInverterOriginal.cxx:322
 HypoTestInverterOriginal.cxx:323
 HypoTestInverterOriginal.cxx:324
 HypoTestInverterOriginal.cxx:325
 HypoTestInverterOriginal.cxx:326
 HypoTestInverterOriginal.cxx:327
 HypoTestInverterOriginal.cxx:328
 HypoTestInverterOriginal.cxx:329
 HypoTestInverterOriginal.cxx:330
 HypoTestInverterOriginal.cxx:331
 HypoTestInverterOriginal.cxx:332
 HypoTestInverterOriginal.cxx:333
 HypoTestInverterOriginal.cxx:334
 HypoTestInverterOriginal.cxx:335
 HypoTestInverterOriginal.cxx:336
 HypoTestInverterOriginal.cxx:337
 HypoTestInverterOriginal.cxx:338
 HypoTestInverterOriginal.cxx:339
 HypoTestInverterOriginal.cxx:340
 HypoTestInverterOriginal.cxx:341
 HypoTestInverterOriginal.cxx:342
 HypoTestInverterOriginal.cxx:343
 HypoTestInverterOriginal.cxx:344
 HypoTestInverterOriginal.cxx:345
 HypoTestInverterOriginal.cxx:346
 HypoTestInverterOriginal.cxx:347
 HypoTestInverterOriginal.cxx:348
 HypoTestInverterOriginal.cxx:349
 HypoTestInverterOriginal.cxx:350
 HypoTestInverterOriginal.cxx:351
 HypoTestInverterOriginal.cxx:352
 HypoTestInverterOriginal.cxx:353
 HypoTestInverterOriginal.cxx:354
 HypoTestInverterOriginal.cxx:355
 HypoTestInverterOriginal.cxx:356
 HypoTestInverterOriginal.cxx:357
 HypoTestInverterOriginal.cxx:358
 HypoTestInverterOriginal.cxx:359
 HypoTestInverterOriginal.cxx:360
 HypoTestInverterOriginal.cxx:361
 HypoTestInverterOriginal.cxx:362
 HypoTestInverterOriginal.cxx:363
 HypoTestInverterOriginal.cxx:364
 HypoTestInverterOriginal.cxx:365
 HypoTestInverterOriginal.cxx:366
 HypoTestInverterOriginal.cxx:367
 HypoTestInverterOriginal.cxx:368
 HypoTestInverterOriginal.cxx:369
 HypoTestInverterOriginal.cxx:370
 HypoTestInverterOriginal.cxx:371
 HypoTestInverterOriginal.cxx:372
 HypoTestInverterOriginal.cxx:373
 HypoTestInverterOriginal.cxx:374
 HypoTestInverterOriginal.cxx:375
 HypoTestInverterOriginal.cxx:376
 HypoTestInverterOriginal.cxx:377
 HypoTestInverterOriginal.cxx:378
 HypoTestInverterOriginal.cxx:379
 HypoTestInverterOriginal.cxx:380
 HypoTestInverterOriginal.cxx:381
 HypoTestInverterOriginal.cxx:382
 HypoTestInverterOriginal.cxx:383
 HypoTestInverterOriginal.cxx:384
 HypoTestInverterOriginal.cxx:385
 HypoTestInverterOriginal.cxx:386
 HypoTestInverterOriginal.cxx:387
 HypoTestInverterOriginal.cxx:388
 HypoTestInverterOriginal.cxx:389
 HypoTestInverterOriginal.cxx:390
 HypoTestInverterOriginal.cxx:391