openModeller
Version 1.4.0
|
00001 00031 #include "envelope_score.hh" 00032 00033 #include <openmodeller/Configuration.hh> 00034 00035 #include <openmodeller/Exceptions.hh> 00036 00037 #include <string.h> 00038 #include <stdio.h> 00039 #include <math.h> 00040 00041 /****************************************************************/ 00042 /********************** Algorithm's Metadata ********************/ 00043 00044 #define NUM_PARAM 0 00045 00046 00047 /*************************************/ 00048 /*** Algorithm parameters metadata ***/ 00049 00050 //static AlgParamMetadata parameters[NUM_PARAM] = {}; 00051 00052 00053 /************************************/ 00054 /*** Algorithm's general metadata ***/ 00055 00056 static AlgMetadata metadata = { 00057 00058 "ENVSCORE", // Id. 00059 "Envelope Score", // Name. 00060 "0.1", // Version. 00061 00062 // Overview 00063 "Uses the minimum and maximum observed value for each\ 00064 environmental variable to define bioclimatic envelopes.\ 00065 Probability of occurrence for a point is determined by\ 00066 the number of environmental variables within which the\ 00067 environmental values at the point fall into the min/max\ 00068 criteria.", 00069 // Description. 00070 "Implements a lax Bioclimatic Envelope Algorithm. For\ 00071 each given environmental variable the algorithm finds\ 00072 the minimum and maximum at all occurrence sites. During\ 00073 model projection, the probability of occurrences is\ 00074 determined as:\n\n\ 00075 p = layers within min-max threshold / number of layers\n\n\ 00076 Thus choosing a threshold of p=1 gives you the same model\ 00077 output as the original Bioclim model taking both the\ 00078 Suitable & Marginal classes as predicted presences.\ 00079 The Envelope Score algorithm is equivalent to the\ 00080 inclusive 'OR' implementation of Bioclim described\ 00081 in Pineiro et al (2007).", 00082 00083 "Nix, H. A.", // Author 00084 00085 // Bibliography. 00086 "Nix, H.A. (1986) A biogeographic analysis of Australian elapid\ 00087 snakes. In: Atlas of Elapid Snakes of Australia. (Ed.) R. Longmore,\ 00088 pp. 4-15. Australian Flora and Fauna Series Number 7. Australian\ 00089 Government Publishing Service: Canberra.\n\n\ 00090 PiƱeiro, R., Aguilar, J. F., Munt, D. D. & Feliner, G. N. (2007)\ 00091 Ecology matters: Atlantic-Mediterranean disjunction in the sand-dune\ 00092 shrub Armeria pungens (Plumbaginaceae).\ 00093 Molecular Ecology. 16, 2155-2171.", 00094 00095 "Tim Sutton and Chris Yesson", // Code author. 00096 "tim [at] linfiniti.com", // Code author's contact. 00097 00098 0, // Does not accept categorical data. 00099 0, // Does not need (pseudo)absence points. 00100 00101 NUM_PARAM // Algorithm's parameters. 00102 00103 }; 00104 00105 00106 00107 /****************************************************************/ 00108 /****************** Algorithm's factory function ****************/ 00109 00110 OM_ALG_DLL_EXPORT 00111 AlgorithmImpl * 00112 algorithmFactory() 00113 { 00114 return new EnvelopeScore(); 00115 } 00116 00117 OM_ALG_DLL_EXPORT 00118 AlgMetadata const * 00119 algorithmMetadata() 00120 { 00121 return &metadata; 00122 } 00123 00124 00125 /****************************************************************/ 00126 /**************************** EnvelopeScore ***************************/ 00127 00128 /*******************/ 00129 /*** constructor ***/ 00130 00131 EnvelopeScore::EnvelopeScore() : 00132 AlgorithmImpl( &metadata ), 00133 _done( false ), 00134 _minimum(), 00135 _maximum() 00136 { } 00137 00138 00139 /******************/ 00140 /*** destructor ***/ 00141 00142 EnvelopeScore::~EnvelopeScore() 00143 { 00144 } 00145 00146 00147 /******************/ 00148 /*** initialize ***/ 00149 int 00150 EnvelopeScore::initialize() 00151 { 00152 00153 // Number of independent variables. 00154 int dim = _samp->numIndependent(); 00155 Log::instance()->info( "Reading %d-dimensional occurrence points.\n", dim ); 00156 00157 // Check the number of sampled points. 00158 int npnt = _samp->numPresence(); 00159 if ( npnt < 1 ) { 00160 Log::instance()->error( "EnvelopeScore needs at least 1 point inside the mask!\n" ); 00161 return 0; 00162 } 00163 00164 Log::instance()->info( "Using %d points to find the bioclimatic envelope.\n", npnt ); 00165 00166 computeStats( _samp->getPresences() ); 00167 00168 _done = true; 00169 00170 return 1; 00171 } 00172 00173 00174 /***************/ 00175 /*** iterate ***/ 00176 int 00177 EnvelopeScore::iterate() 00178 { 00179 return 1; 00180 } 00181 00182 00183 /************/ 00184 /*** done ***/ 00185 int 00186 EnvelopeScore::done() const 00187 { 00188 // This is not an iterative algorithm. 00189 return _done; 00190 } 00191 00192 00193 /*****************/ 00194 /*** get Value ***/ 00195 Scalar 00196 EnvelopeScore::getValue( const Sample& x ) const 00197 { 00198 00199 unsigned int myMatchCount=0; 00200 unsigned int myLayerCount = x.size(); 00201 00202 for( unsigned int i=0; i<x.size(); i++) { 00203 00204 if ( (x[i] >= _minimum[i]) && (x[i] <= _maximum[i]) ) { 00205 ++myMatchCount; 00206 } 00207 } 00208 if (myMatchCount==0) { 00209 return 0; 00210 } 00211 Scalar myProbability = myMatchCount / static_cast<double>(myLayerCount) ; 00212 00213 return myProbability; 00214 } 00215 00216 00217 /***********************/ 00218 /*** get Convergence ***/ 00219 int 00220 EnvelopeScore::getConvergence( Scalar * const val ) const 00221 { 00222 *val = 1.0; 00223 return 1; 00224 } 00225 00226 00227 /*******************/ 00228 /*** get Minimum ***/ 00229 void 00230 EnvelopeScore::computeStats( const OccurrencesPtr& occs ) 00231 { 00232 00233 // Compute minimum and maximum. 00234 { 00235 OccurrencesImpl::const_iterator oc = occs->begin(); 00236 OccurrencesImpl::const_iterator end = occs->end(); 00237 00238 // Initialize _minimum and _maximum to the values of the first point 00239 // and increment to get it out of the loop. 00240 Sample const & sample = (*oc)->environment(); 00241 _minimum = sample; 00242 _maximum = sample; 00243 00244 ++oc; 00245 00246 // For each Occurrence, update the statistics for _minimum and 00247 // _maximum. 00248 while ( oc != end ) { 00249 00250 Sample const& sample = (*oc)->environment(); 00251 00252 _minimum &= sample; 00253 _maximum |= sample; 00254 00255 ++oc; 00256 } 00257 00258 } 00259 00260 } 00261 00262 /****************************************************************/ 00263 /****************** configuration *******************************/ 00264 void 00265 EnvelopeScore::_getConfiguration( ConfigurationPtr& config ) const 00266 { 00267 if ( !_done ) 00268 return; 00269 00270 ConfigurationPtr model_config( new ConfigurationImpl("EnvelopeScore") ); 00271 config->addSubsection( model_config ); 00272 00273 model_config->addNameValue( "Minimum", _minimum ); 00274 model_config->addNameValue( "Maximum", _maximum ); 00275 00276 } 00277 00278 void 00279 EnvelopeScore::_setConfiguration( const ConstConfigurationPtr& config ) 00280 { 00281 ConstConfigurationPtr model_config = config->getSubsection("EnvelopeScore"); 00282 00283 if (!model_config) 00284 return; 00285 00286 _done = true; 00287 00288 _minimum = model_config->getAttributeAsSample( "Minimum" ); 00289 _maximum = model_config->getAttributeAsSample( "Maximum" ); 00290 00291 return; 00292 } 00293 00294 /********************/ 00295 /*** log Envelope ***/ 00296 void 00297 EnvelopeScore::logEnvelope() 00298 { 00299 Log::instance()->info( "Envelope with %d dimensions (variables).\n\n", _minimum.size() ); 00300 00301 for ( unsigned int i = 0; i < _minimum.size(); i++ ) 00302 { 00303 Log::instance()->info( "Variable %02d:", i ); 00304 Log::instance()->info( " Minimum : %f\n", _minimum[i] ); 00305 Log::instance()->info( " Maximum : %f\n", _maximum[i] ); 00306 Log::instance()->info( "\n" ); 00307 } 00308 } 00309