ROOT logo
// @(#)root/tmva $Id: MethodSeedDistance.cxx 31458 2009-11-30 13:58:20Z stelzer $    
// Author: Andreas Hoecker, Peter Speckmayer

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : MethodSeedDistance                                                    *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation                                                            *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Peter Speckmayer <speckmay@mail.cern.ch>  - CERN, Switzerland             *
 *                                                                                *
 * Copyright (c) 2005-2006:                                                       *
 *      CERN, Switzerland                                                         *
 *      MPI-K Heidelberg, Germany                                                 *
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

//_______________________________________________________________________
/* Begin_Html
   This method is experimental only. It does not show any improvements
   compared to any of the traditional methods.
End_Html */
//_______________________________________________________________________

#include <sstream>

#include "TList.h"
#include "TFormula.h"
#include "TString.h"
#include "TObjString.h"
#include "TRandom3.h"
#include "TMath.h"

#include "TMVA/ClassifierFactory.h"
#include "TMVA/MethodSeedDistance.h"
#include "TMVA/Tools.h"
#include "TMVA/Interval.h"
#include "TMVA/Timer.h"
#include "TMVA/GeneticFitter.h"
#include "TMVA/SimulatedAnnealingFitter.h"
#include "TMVA/MinuitFitter.h"
#include "TMVA/MCFitter.h"
#include "TMVA/MetricEuler.h"
#include "TMVA/MetricManhattan.h"
#include "TMVA/SeedDistance.h"

REGISTER_METHOD(SeedDistance)

ClassImp(TMVA::MethodSeedDistance)

//_______________________________________________________________________
TMVA::MethodSeedDistance::MethodSeedDistance( const TString& jobName,
                                              const TString& methodTitle,
                                              DataSetInfo& theData, 
                                              const TString& theOption,
                                              TDirectory* theTargetDir ) :
   TMVA::MethodBase( jobName, Types::kSeedDistance, methodTitle, theData, theOption, theTargetDir ), 
   IFitterTarget(),
   fSeedRangeStringP(""),
   fSeedRangeStringT(""),
   fScalingFactor(1),
   fMetric(0),
   fSeedDistance(0),
   fSeeds(),
   fMetricPars(),
   fPars(),
   fDataSeeds(0),
   fBackSeeds(0),
   fMetricType(""),
   fPow2Estimator(kTRUE),
   fNPars(0),
   fParRange(),
   fFitMethod(""),
   fConverger(""),
   fFitter(0),
   fIntermediateFitter(0),
   fEventsSig(),
   fEventsBkg(),
   fSumOfWeightsSig(0),
   fSumOfWeightsBkg(0)
{
   // standard constructor
}

//_______________________________________________________________________
TMVA::MethodSeedDistance::MethodSeedDistance( DataSetInfo& theData, 
                                              const TString& theWeightFile,  
                                              TDirectory* theTargetDir ) :
   TMVA::MethodBase( Types::kSeedDistance, theData, theWeightFile, theTargetDir ),
   IFitterTarget(),
   fSeedRangeStringP(""),
   fSeedRangeStringT(""),
   fScalingFactor(1),
   fMetric(0),
   fSeedDistance(0),
   fSeeds(),
   fMetricPars(),
   fPars(),
   fDataSeeds(0),
   fBackSeeds(0),
   fMetricType(""),
   fPow2Estimator(kTRUE),
   fNPars(0),
   fParRange(),
   fFitMethod(""),
   fConverger(""),
   fFitter(0),
   fIntermediateFitter(0),
   fEventsSig(),
   fEventsBkg(),
   fSumOfWeightsSig(0),
   fSumOfWeightsBkg(0)
{
   // constructor from weight file
}

//_______________________________________________________________________
Bool_t TMVA::MethodSeedDistance::HasAnalysisType( Types::EAnalysisType type, UInt_t numberClasses, UInt_t /*numberTargets*/ )
{
   // SeedDistance can handle classification with 2 classes
   if( type == Types::kClassification && numberClasses == 2 ) return kTRUE;
   return kFALSE;
}

//_______________________________________________________________________
void TMVA::MethodSeedDistance::Init( void )
{
   // default initialisation
}

//_______________________________________________________________________
void TMVA::MethodSeedDistance::DeclareOptions() 
{
   // define the options (their key words) that can be set in the option string 
   //
   // format of function string:
   //    "x0*(0)+((1)/x1)**(2)..."
   // where "[i]" are the parameters, and "xi" the input variables
   //
   // format of parameter string:
   //    "(-1.2,3.4);(-2.3,4.55);..."
   // where the numbers in "(a,b)" correspond to the a=min, b=max parameter ranges;
   // each parameter defined in the function string must have a corresponding range
   //
   DeclareOptionRef( fSeedRangeStringP = "", "SeedRanges", "Range intervals confining the variables for the seeds" );
   DeclareOptionRef( fDataSeeds = 1, "DataSeeds", "Number of used data seeds" );
   DeclareOptionRef( fBackSeeds = 1, "BackSeeds", "Number of used background seeds" );
   DeclareOptionRef( fMetricType = "Euler", "Metric", "Type of metric used (Euler, Manhattan)" );
   AddPreDefVal(TString("Euler"));
   AddPreDefVal(TString("Manhattan"));

   DeclareOptionRef( fPow2Estimator = false, "Pow2Estimator", "Squared deviation from desired result (true) or number of correct classifications (false) as estimator" );
   DeclareOptionRef( fScalingFactor = true, "Scaling", "Produces an additional free parameter for a Seed which scales the calculated distance" );

   // fitter
   DeclareOptionRef( fFitMethod = "MINUIT", "FitMethod", "Optimisation Method");
   AddPreDefVal(TString("MC"));
   AddPreDefVal(TString("GA"));
   AddPreDefVal(TString("SA"));
   AddPreDefVal(TString("MINUIT"));

   DeclareOptionRef( fConverger = "None", "Converger", "FitMethod uses Converger to improve result");
   AddPreDefVal(TString("None"));
   AddPreDefVal(TString("MINUIT"));
}

//_______________________________________________________________________
void TMVA::MethodSeedDistance::ProcessOptions() 
{
   // the option string is decoded, for availabel options see "DeclareOptions"
   // clean up first
   ClearAll();

   if (IgnoreEventsWithNegWeightsInTraining()) {
      Log() << kFATAL << "Mechanism to ignore events with negative weights in training not yet available for method: "
            << GetMethodTypeName() 
            << " --> please remove \"IgnoreNegWeightsInTraining\" option from booking string."
            << Endl;
   }

   // process transient strings
   //   fFormulaStringT  = fFormulaStringP;
   fSeedRangeStringT = fSeedRangeStringP;

   // interpret parameter string   
   fSeedRangeStringT.ReplaceAll( " ", "" );
   fNPars = fSeedRangeStringT.CountChar( ')' );
   //   fNPars = 4;

   //   Log() << kINFO << "rangestring " << fSeedRangeStringT << Endl;
   //   Log() << kINFO << "rangestring number ) " << fNPars << Endl;

   TList* parList = gTools().ParseFormatLine( fSeedRangeStringT, ";" );
   //   if (parList->GetSize()*2 != fNPars) {
   //      Log() << kFATAL << "<ProcessOptions> Mismatch in parameter string: " 
   //              << "the number of parameters: " << fNPars << " != ranges defined: " 
   //              << parList->GetSize() << "; the format of the \"SeedRanges\" string "
   //              << "must be: \"(-1.2,3.4);(-2.3,4.55);...\", "
   //              << "where the numbers in \"(a,b)\" correspond to the a=min, b=max parameter ranges; "
   //              << "each parameter defined in the function string must have a corresponding rang."
   //              << Endl;
   //   }

   fParRange.resize( fNPars );
   for (Int_t ipar=0; ipar<fNPars; ipar++) fParRange[ipar] = 0;

   for (Int_t ipar=0; ipar<fNPars; ipar++) {
      // parse (a,b)
      TString str = ((TObjString*)parList->At(ipar))->GetString();
      Ssiz_t istr = str.First( ',' );
      TString pminS(str(1,istr-1));
      TString pmaxS(str(istr+1,str.Length()-2-istr));
      std::stringstream st;
      st.precision( 16 );
      st << std::scientific << pminS.Data();
      Float_t pmin;
      st >> pmin;
      st << std::scientific << pmaxS.Data();
      Float_t pmax;
      st >> pmax;

      // sanity check
      if (pmin > pmax) Log() << kFATAL << "<ProcessOptions> max > min in interval for parameter: [" 
                               << ipar << "] : [" << pmin  << ", " << pmax << "] " << Endl;

      fParRange[ipar] = new Interval( pmin, pmax );
   }

   delete parList;

   if( fScalingFactor ){
      fParRange.push_back( new Interval( 0.0, 1.0 ) );
   }
   
   
   for( Int_t i = 0; i< fDataSeeds+fBackSeeds; i++ ){
      fSeeds.push_back( std::vector< Double_t >() );
      for(std::vector<TMVA::Interval*>::const_iterator parIt = fParRange.begin(); parIt != fParRange.end(); parIt++) {
         fSeeds[i].push_back( (*parIt)->GetMean() );
      }
   }

   std::vector<Interval*>::iterator maxpos;
   for( Int_t i = 1; i< fDataSeeds+fBackSeeds; i++ ){
      maxpos = fParRange.begin();
      for( Int_t j=0; j< fNPars; j++ ){
         maxpos++;
      }
      if( fScalingFactor ){
         maxpos++;
      }
      fParRange.insert( fParRange.end(), fParRange.begin(), maxpos );
   }

   for( Int_t i = 0; i < fNPars; i++) {
      fMetricPars.push_back( 0.5 );
      fParRange.push_back( new Interval( 0.0, 1.0 ) );
   }
   
   if( fMetricType == "Euler" )     fMetric = new MetricEuler();
   if( fMetricType == "Manhattan" ) fMetric = new MetricManhattan();

   fMetric->SetParameters( &fMetricPars );
   fSeedDistance = new SeedDistance( *fMetric, fSeeds );

   fIntermediateFitter = (TMVA::IFitterTarget*)this;
   if (fConverger == "MINUIT")
      fIntermediateFitter = new TMVA::MinuitFitter( *this, Form("%s_MINUIT", GetName()), fParRange, GetOptions() );
   if      (fFitMethod == "MC")     fFitter = new TMVA::MCFitter                ( *fIntermediateFitter, Form("%sFitter_MC", GetName()), fParRange, GetOptions() );
   else if (fFitMethod == "GA")     fFitter = new TMVA::GeneticFitter           ( *fIntermediateFitter, Form("%sFitter_GA", GetName()), fParRange, GetOptions() );
   else if (fFitMethod == "SA")     fFitter = new TMVA::SimulatedAnnealingFitter( *fIntermediateFitter, Form("%sFitter_SA", GetName()), fParRange, GetOptions() );
   else if (fFitMethod == "MINUIT") fFitter = new TMVA::MinuitFitter            ( *fIntermediateFitter, Form("%sFitter_MINUIT", GetName()), fParRange, GetOptions() );
   else {
      Log() << kFATAL << "<Train> Do not understand fit method: " << fFitMethod << Endl;
   }
   
   fFitter->CheckForUnusedOptions();
   
}

//_______________________________________________________________________
TMVA::MethodSeedDistance::~MethodSeedDistance( void )
{
   // destructor
   ClearAll();
}

//_______________________________________________________________________
void TMVA::MethodSeedDistance::ClearAll( void )
{
   // reset all parameters of the method
   std::map< Interval*, Int_t > delmap;
    
   for (UInt_t ipar=0; ipar<fParRange.size(); ipar++) {
      delmap[fParRange[ipar]] = ipar;
      fParRange[ipar] = 0;
   }
   for( std::map< Interval*, Int_t >::iterator it = delmap.begin(); it != delmap.end(); it++ ){
      delete it->first;
   }
   fParRange.clear(); 

   fMetricPars.clear();

   fPars.clear();
}

//_______________________________________________________________________
void TMVA::MethodSeedDistance::Train( void )
{
   // FDA training 

   // cache training events
   fSumOfWeightsSig = 0;
   fSumOfWeightsBkg = 0;

   for (Int_t ievt=0; ievt<Data()->GetNEvents(); ievt++) {

      const Event*  ev = Data()->GetEvent(ievt);
      Float_t w  = ev->GetWeight();

      if (ev->IsSignal()) { fEventsSig.push_back( ev ); fSumOfWeightsSig += w; }
      else                { fEventsBkg.push_back( ev ); fSumOfWeightsBkg += w; }
   }

   // sanity check
   if (fSumOfWeightsSig <= 0 || fSumOfWeightsBkg <= 0) {
      Log() << kFATAL << "<Train> Troubles in sum of weights: " 
              << fSumOfWeightsSig << " (S) : " << fSumOfWeightsBkg << " (B)" << Endl;
   }

   // starting values (not used by all fitters)
   fPars.clear();

   MakeListFromStructure( fPars, fSeeds, fMetricPars );

   // execute the fit
//   Double_t estimator = fFitter->Run( fPars );
   Double_t estimator = fFitter->Run( fPars );

   MakeStructureFromList( fPars, fSeeds, fMetricPars );

   // print results
   PrintResults( fFitMethod, fPars, estimator );

   // free cache 
   std::vector<const Event*>::const_iterator itev;
   for (itev = fEventsSig.begin(); itev != fEventsSig.end(); itev++) delete *itev;
   for (itev = fEventsBkg.begin(); itev != fEventsBkg.end(); itev++) delete *itev;

   fEventsSig.clear();
   fEventsBkg.clear();

   if (fConverger == "MINUIT") delete fIntermediateFitter;
   delete fFitter; fFitter = 0;
}

//_______________________________________________________________________
void TMVA::MethodSeedDistance::PrintResults( const TString& fitter, std::vector<Double_t>& , const Double_t estimator ) const
{
   //MakeStructureFromList( pars, fSeeds, fMetricPars );

   // display fit parameters
   // check maximum length of variable name
   Log() << kINFO;
   Log() << "Results for distance to seed method using fitter: \"" << fitter << Endl;
   Log() << "Value of estimator at minimum: " << estimator << Endl;

   // print seeds
   Log() << kINFO << "Number of Seeds: " << fSeeds.size() << Endl;
   for( Int_t i = 0; i< (Int_t)fSeeds.size(); i++ ){
      if( i < fDataSeeds ){
         Log() << kINFO << "Seed " << i << " -- DATA" << Endl;
      }else{
         Log() << kINFO << "Seed " << i << " -- BACKGROUND" << Endl;
      }
      for( Int_t j = 0; j< (Int_t)fSeeds[i].size(); j++ ){
         if( fScalingFactor && j >= (Int_t)fSeeds[i].size()-1 ){
            Log() << kINFO << "   scaling factor " << ": " << fSeeds[i][j] << Endl;
         }else{
            Log() << kINFO << "   dimension " << j << ": " << fSeeds[i][j] << Endl;
         }
      }
   }
   
   // print metric parameters
   Log() << kINFO << Endl;
   Log() << kINFO << "Metric: " << fMetricType << " with " << fMetricPars.size() << " parameters" << Endl;
   for( Int_t i = 0; i< (Int_t)fMetricPars.size(); i++ ){
      Log() << kINFO << "   par " << i << ": " << fMetricPars[i] << Endl;
   }

}

//_______________________________________________________________________
Double_t TMVA::MethodSeedDistance::EstimatorFunction( std::vector<Double_t>& pars )
{
   // compute estimator for given parameter set (to be minimised)

   MakeStructureFromList( pars, fSeeds, fMetricPars );
   std::vector< Double_t > point;
   Double_t looksLike = 0.0;
   
   // species-specific stuff
   const std::vector<const Event*>* eventVecs[] = { &fEventsSig, &fEventsBkg };
   const Double_t sumOfWeights[]                = { fSumOfWeightsSig, fSumOfWeightsBkg };
   const Double_t desiredVal[]                  = { 1, 0 };
   Double_t estimator[]                         = { 0, 0 };
   std::vector<const Event*>::const_iterator itev;

   Double_t distData;
   Double_t distBack;
   Double_t deviation;
   
   // loop over species
   for (Int_t itype=0; itype<2; itype++) {

      // loop over specific events
      for (itev = eventVecs[itype]->begin(); itev != eventVecs[itype]->end(); itev++) {
         point.clear();
         for (UInt_t ivar=0;  ivar<GetNvar();   ivar++) point.push_back( (**itev).GetValue(ivar) );

         std::vector< Double_t >& distances = fSeedDistance->GetDistances( point );
         
         distData = distances[0];
         for( Int_t i=1; i< fDataSeeds; i++ ){
            distData = TMath::Min( distData, distances[i] );
         }
         distBack = distances[fDataSeeds];
         for( Int_t i=fDataSeeds; i< fDataSeeds+fBackSeeds; i++ ){
            distBack = TMath::Min( distBack, distances[i] );
         }
         
         if( !fPow2Estimator ){
            if( distData < distBack ){ 
               deviation = 1-desiredVal[itype];
            }else{
               deviation = desiredVal[itype];
            }
         }else{
            looksLike = distBack/(distData+distBack);
            deviation = (looksLike - desiredVal[itype])*(looksLike - desiredVal[itype]);
         }

         estimator[itype] += deviation * (*itev)->GetWeight();
      }
      estimator[itype] /= sumOfWeights[itype];
   }

   // return value is sum over normalised signal and background contributions
   return estimator[0] + estimator[1];
}

//_______________________________________________________________________
Double_t TMVA::MethodSeedDistance::GetMvaValue( Double_t* err )
{
   // returns MVA value for given event
   std::vector< Double_t > point;
   const Event* ev = GetEvent();

   // cannot determine error
   if (err != 0) *err = -1;

   Double_t distData;
   Double_t distBack;

   point.clear();
   for (UInt_t ivar=0;  ivar<GetNvar();   ivar++) point.push_back( ev->GetValue(ivar) );

   std::vector< Double_t >& distances = fSeedDistance->GetDistances( point );

   distData = distances[0];
   for( Int_t i=1; i< fDataSeeds; i++ ){
      distData = TMath::Min( distData, distances[i] );
   }
   distBack = distances[fDataSeeds];
   for( Int_t i=fDataSeeds; i< fDataSeeds+fBackSeeds; i++ ){
      distBack = TMath::Min( distBack, distances[i] );
   }
   

   if( distData+distBack == 0 ){
      Log() << kINFO << "backgroundseed=dataseed";
      return 0.0;
   }
   Double_t looksLike = distBack/(distData+distBack);

   return looksLike;
}

//_______________________________________________________________________
void TMVA::MethodSeedDistance::AddWeightsXMLTo( void* /*parent*/ ) const 
{
   Log() << kFATAL << "Please implement writing of weights as XML" << Endl;
}
 
//_______________________________________________________________________
void  TMVA::MethodSeedDistance::ReadWeightsFromStream( istream& istr )
{
   // read back the training results from a file (stream)

   Int_t size;
   Double_t val;
   istr >> size;
//   Log() << kINFO << size << " ";
   fSeeds.clear();
   for( Int_t i = 0; i<size; i++ ){
      fSeeds.push_back( std::vector< Double_t >() );
      Int_t subSize;
      istr >> subSize;
//      Log() << kINFO << subSize << " ";
      for( Int_t j = 0; j<subSize; j++ ){
         istr >> val;
//         Log() << kINFO << val << " ";
         fSeeds[i].push_back( val );
      }
   }

   istr >> fDataSeeds;
   istr >> fBackSeeds;
   istr >> fScalingFactor;

   istr >> fMetricType;
   istr >> size;
//   Log() << kINFO << size << " ";
   fMetricPars.clear();
   for( Int_t i = 0; i<size; i++ ){
      istr >> val;
//      Log() << kINFO << val << " ";
      fMetricPars.push_back( val );
   }

   if( fMetricType == "Euler" ) fMetric = new MetricEuler();
   else if( fMetricType == "Manhattan" ) fMetric = new MetricManhattan();
   else{
      Log() << kFATAL << "unknown metric" << Endl;
   }
   fMetric->SetParameters( &fMetricPars );
   fSeedDistance = new SeedDistance( *fMetric, fSeeds );
}

//_______________________________________________________________________
void TMVA::MethodSeedDistance::MakeClassSpecific( std::ostream& fout, const TString& /*className*/ ) const
{
   //    fout << "Bool_t                 fScalingFactor = " << fScalingFactor << ";" << endl;
   //    fout << "IMetric*               fMetric = new Metric" << fMetricType << "();" << endl;
   //    fout << "SeedDistance*          fSeedDistance;" << endl;
   //    fout << "std::vector< std::vector< Double_t > > fSeeds;" << endl;
   //    fout << "std::vector<Double_t>  fMetricPars;" << endl;
   //    fout << "Int_t                  fDataSeeds = " << fDataSeeds << ";" << endl;
   //    fout << "Int_t                  fBackSeeds = " << fBackSeeds << ";" << endl;
   //    fout << "TString                fMetricType = \"" << fMetricType << "\";" << endl;
   //    fout << "Int_t                  fNPars = " << fNPars << ";" << endl;
   fout << "not implemented for class" << std::endl;
}


//_______________________________________________________________________
void TMVA::MethodSeedDistance::MakeListFromStructure( std::vector<Double_t>& linear, 
                                  std::vector< std::vector< Double_t > >& seeds,
                                  std::vector<Double_t>& metricParams )
{
   // linear: / /-seed1-//-seed-2//...//-seed n-/ /metricParams/ /
   linear.clear();
   for( std::vector< std::vector< Double_t > >::iterator itSeed = seeds.begin(); itSeed != seeds.end(); itSeed++ ){
      linear.insert( linear.end(), (*itSeed).begin(), (*itSeed).end() );
   }
   linear.insert( linear.end(), metricParams.begin(), metricParams.end() );
}

//_______________________________________________________________________
void TMVA::MethodSeedDistance::MakeStructureFromList( std::vector<Double_t>& linear, 
                                  std::vector< std::vector< Double_t > >& seeds,
                                  std::vector<Double_t>& metricParams )
{
   // makes the structure from the list
   std::vector<Double_t>::iterator loc = linear.begin();
   for( std::vector< std::vector<Double_t> >::iterator itSeed = seeds.begin(); itSeed != seeds.end(); itSeed++ ){
      for( std::vector<Double_t>::iterator it = (*itSeed).begin(); it != (*itSeed).end(); it++ ){
         (*it) = (*loc);
         loc++;
      }
   }
   for( std::vector<Double_t>::iterator it = metricParams.begin(); it != metricParams.end(); it++ ){
      (*it) = (*loc);
      loc++;
   }
}


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