openModeller  Version 1.4.0
garp_run.cpp
Go to the documentation of this file.
00001 
00030 #include <openmodeller/om.hh>
00031 
00032 #include "garp_run.hh"
00033 #include "garp_run_thread.hh"
00034 #include "bs_algorithm_factory.hh"
00035 #include <openmodeller/AlgParameter.hh>
00036 
00037 /****************************************************************/
00038 /************************ GARP Run Thread ***********************/
00039 
00040 // TODO: modify strategy to reuse threads instead of creating a 
00041 //       new one for every garp run
00042 
00043 THREAD_PROC_RETURN_TYPE AlgorithmRunThreadProc(void * threadData)
00044 {
00045   AlgorithmRun * algRun = (AlgorithmRun *) threadData;
00046 
00047   //Log::instance()->debug("Starting new thread (%d).\n", algRun->getId());
00048 
00049   while (!algRun->done())
00050     algRun->iterate();
00051 
00052   algRun->calculateCommission();
00053   algRun->calculateOmission();
00054   algRun->finalize();
00055   
00056   //Log::instance()->debug("Finishing thread (%d).\n", algRun->getId());
00057 
00058   THREAD_PROC_RETURN_STATEMENT;
00059 }
00060 
00061 
00062 /****************************************************************/
00063 /************************* GARP Run *****************************/
00064 
00065 AlgorithmRun::AlgorithmRun() :
00066   _id(-1),
00067   _running( false ),
00068   _omission( -1.0 ),
00069   _commission( -1.0 ),
00070   _commission_samples( 0 ),
00071   _alg( NULL ),
00072   _train_sampler(),
00073   _test_sampler()
00074 {
00075   //Log::instance()->info("Creating an AlgorithmRun at: %x\n",this);
00076 }
00077 
00078 AlgorithmRun::AlgorithmRun( const AlgorithmPtr& alg ) :
00079   _id(-1),
00080   _running( false ),
00081   _omission( -1.0 ),
00082   _commission( -1.0 ),
00083   _commission_samples( 0 ),
00084   _alg( alg ),
00085   _train_sampler(),
00086   _test_sampler()
00087 {
00088   //Log::instance()->info("Creating an AlgorithmRun at: %x\n",this);
00089 }
00090 
00091 /****************************************************************/
00092 AlgorithmRun::~AlgorithmRun() 
00093 {
00094   //Log::instance()->info("Deleting an AlgorithmRun at: %x\n",this);
00095 }
00096 
00097 /****************************************************************/
00098 int AlgorithmRun::initialize(int id, int comm_samples,
00099            const SamplerPtr& train_sampler, 
00100            const SamplerPtr& test_sampler, 
00101            int nparam, AlgParameter * param,
00102            BSAlgorithmFactory * factory)
00103 {
00104   Log::instance()->debug( "Initializing garp run (%d)\n", id );
00105 
00106   _id = id;
00107   _commission_samples = comm_samples;
00108 
00109   _train_sampler = train_sampler;
00110   _test_sampler = test_sampler;
00111 
00112   _alg = factory->getBSAlgorithm();
00113   _alg->setSampler(train_sampler);
00114   _alg->setParameters(nparam, param);
00115   _alg->initialize();
00116 
00117   return 1;
00118 }
00119 
00120 /****************************************************************/
00121 int AlgorithmRun::run()
00122 {
00123   //Log::instance()->debug("Starting new garp run (%d).\n", _id);
00124   _running = true;
00125   THREAD_START(AlgorithmRunThreadProc, this); 
00126   return 1;  
00127 }
00128 
00129 /****************************************************************/
00130 bool AlgorithmRun::running() const
00131 { return _running; }
00132 
00133 /****************************************************************/
00134 int AlgorithmRun::iterate()
00135 {
00136   //Log::instance()->debug("Iteration %6d on run %d.\n", _alg->getGeneration(), _id);
00137   return _alg->iterate();
00138 }
00139 
00140 /****************************************************************/
00141 int AlgorithmRun::done() const
00142 { return _alg->done(); }
00143 
00144 /****************************************************************/
00145 float AlgorithmRun::getProgress() const
00146 { return _alg->getProgress(); }
00147 
00148 /****************************************************************/
00149 int AlgorithmRun::finalize()           
00150 {
00151   //Log::instance()->debug("Finishing up garp run.(%d)\n", _id);
00152   _running = false;
00153   //_alg->deleteTempDataMembers(); // this is not in Algorithm interface
00154   THREAD_END();
00155   return 1;
00156 }
00157 
00158 /****************************************************************/
00159 int AlgorithmRun::calculateCommission()           
00160 {
00161   int i;
00162   double sum = 0.0;
00163 
00164   // TODO: check how to use absences in computing commission
00165 
00166   //Log::instance()->debug("Calculating commission error (%d).\n", _id);
00167 
00168   // get random points from the background to estimate 
00169   // area predicted present
00170   bool hasAbsences = (_train_sampler->numAbsence() != 0);
00171   for (i = 0; i < _commission_samples; i++) {
00172 
00173     Scalar value;
00174     if (hasAbsences) {
00175 
00176       ConstOccurrencePtr occ = _train_sampler->getAbsence();
00177       value = _alg->getValue(occ->environment()); 
00178     }
00179     else {
00180 
00181       OccurrencePtr occ = _train_sampler->getPseudoAbsence();
00182       value = _alg->getValue(occ->environment()); 
00183     }
00184 
00185     // discard novalue (-1); zero is irrelevant to the sum
00186     if (value > 0)
00187       sum += value;
00188   }
00189 
00190   _commission = sum / (double) _commission_samples;
00191 
00192   return 1;
00193 }
00194 
00195 /****************************************************************/
00196 int AlgorithmRun::calculateOmission()           
00197 {
00198   // TODO: check how to use absences in computing omission
00199 
00200   //Log::instance()->debug("Calculating omission error (%d).\n", _id);
00201 
00202   // test which kind of test (intrinsic or extrinsic) should be performed
00203   SamplerPtr sampler;
00204 
00205   if (!_test_sampler)
00206     { sampler = _train_sampler; }
00207   else
00208     { sampler = _test_sampler; }
00209 
00210   int nomitted = 0;
00211   OccurrencesPtr presences = sampler->getPresences();
00212   OccurrencesImpl::const_iterator it  = presences->begin();
00213   OccurrencesImpl::const_iterator end = presences->end();
00214 
00215   while (it != end)
00216     {
00217       nomitted = !_alg->getValue((*it)->environment()); 
00218       ++it;
00219     }
00220 
00221   _omission = (double) nomitted / (double) presences->numOccurrences();
00222 
00223   return 1;
00224 }
00225 
00226 /****************************************************************/
00227 double AlgorithmRun::getOmission() const
00228 { return _omission; }
00229 
00230 /****************************************************************/
00231 double AlgorithmRun::getCommission() const
00232 { return _commission; }
00233 
00234 /****************************************************************/
00235 double AlgorithmRun::getError(int type) const
00236 {
00237   if (!type)
00238     { return _omission; }
00239   else
00240     { return _commission; }
00241 }
00242 
00243 /****************************************************************/
00244 double AlgorithmRun::getValue(const Sample& x) const   
00245 { return _alg->getValue(x); }
00246