55 #define PARAM_USE_SURFACE_LAYERS "UseSurfaceLayers"
56 #define PARAM_USE_DEPTH_RANGE "UseDepthRange"
57 #define PARAM_USE_ICE_CONCENTRATION "UseIceConcentration"
58 #define PARAM_USE_DISTANCE_TO_LAND "UseDistanceToLand"
59 #define PARAM_USE_PRIMARY_PRODUCTION "UsePrimaryProduction"
60 #define PARAM_USE_SALINITY "UseSalinity"
61 #define PARAM_USE_TEMPERATURE "UseTemperature"
66 "Use surface layers (only for temperature and salinity)",
68 "Use surface layers (1=yes, 0=no, -1=let the algorithm decide)",
69 "Use surface layers (1=yes, 0=no, -1=let the algorithm decide). By default (-1), aquamaps will try to find the species' depth range in its internal database. If the minimum depth is equals or less than 200m, then aquamaps will use sea surface layers for temperature and salinity. Otherwise it will use bottom layers. This parameter can be used to force aquamaps to use surface or bottom layers.",
80 "Use depth range when calculating probabilities",
81 "Use depth range provided by experts (if available) when calculating probabilities",
90 "Use ice concentration",
92 "Use ice concentration envelope when calculating probabilities",
93 "Use ice concentration when calculating probabilities",
102 "Use distance to land",
104 "Use distance to land envelope when calculating probabilities",
105 "Use distance to land envelope when calculating probabilities",
114 "Use primary production",
116 "Use primary production envelope when calculating probabilities",
117 "Use primary production envelope when calculating probabilities",
128 "Use salinity envelope when calculating probabilities",
129 "Use salinity envelope when calculating probabilities",
140 "Use temperature envelope when calculating probabilities",
141 "Use temperature envelope when calculating probabilities",
157 "AquaMaps (beta version)",
161 "Environmental envelope modelling algorithm for marine organisms. \
162 Needs 9 predefined layers (see detailed description) to calculate the \
163 preferred and accepted envelopes, and also needs a scientific name (genus \
164 plus species) labeling each occurrence group." ,
167 "AquaMaps is a niche modelling tool developed as part of the Incofish \
168 project and particularly tailored towards modelling marine organisms distribution.\n \
169 The basic idea follows the environmental envelope type modelling approach, \
170 where each variable has an associated preferred range and a broader accepted \
171 range. Within the preferred range the probabilty of presence is 1, between the \
172 preferred range and the acceptable range the probability varies from 1 to 0 \
173 (linear decay), and outside the accepted range the probability is 0. The \
174 overall probability is calculated by multiplying all individual probabilities.\n\
175 This algorithm differs from other traditional ones since it requires a specific \
176 set of layers to work, which should also be in this order: maximum depth in meters, \
177 minimum depth in meters, mean annual sea ice concentration, mean annual distance to \
178 land in kilometers, mean annual primary production (chlorophyll A, measured in \
179 mgC per square meter per day), mean annual bottom salinity in psu, mean annual \
180 surface salinity in psu, mean annual bottom temperature in celsius, mean annual \
181 surface temperature in celsius. These layers can be downloaded from: \n\
182 http://openmodeller.cria.org.br/download/marine2.zip \n\
183 Preferred ranges are usually calculated based on percentiles 10th and 90th. \
184 They are further adjusted using interquartile values but also ensuring a minimum \
185 envelope size based on pre-defined values. Under certain circumstances, AquaMaps can \
186 make use of expert information to define the envelopes. This can happen for mammals \
187 (any envelope) or for fishes (depth range envelope). Expert information comes from \
188 FishBase and is stored in a local SQLite database (aquamaps.db) accessed by the \
189 algorithm. To find information in the database, all occurrences provided to \
190 openModeller must be labeled with the scientific name (only genus and species). \
191 Matches are exact, using case-sensitive equals operation. In this version, the \
192 internal database contains information for more then 7000 marine species.",
194 "Kaschner, K., J. S. Ready, E. Agbayani, J. Rius, K. Kesner-Reyes, P. D. Eastwood, A. B. South, S. O. Kullander, T. Rees, C. H. Close, R. Watson, D. Pauly, and R. Froese",
197 "Kaschner, K., J. S. Ready, E. Agbayani, J. Rius, K. Kesner-Reyes, P. D. Eastwood, A. B. South, S. O. Kullander, T. Rees, C. H. Close, R. Watson, D. Pauly, and R. Froese. 2007 AquaMaps: Predicted range maps for aquatic species. World wide web electronic publication, www.aquamaps.org, Version 12/2007.",
199 "Renato De Giovanni",
200 "renato [at] cria dot org dot br",
246 _use_surface_layers(-1),
247 _has_expert_range( NULL ),
276 for (
int i = 0; i < 7; ++i ) {
330 int dim =
_samp->numIndependent();
336 Log::instance()->
error(
"AquaMaps needs precisely 9 layers to work, and they should be in this order: maximum depth in meters, minimum depth in meters, mean annual sea ice concentration, mean annual distance to land in Kilometers, mean annual primary production (chlorophyll A), mean annual sea bottom salinity in psu,, mean annual sea surface salinity in psu, mean annual sea bottom temperature in Celsius, mean annual sea surface temperature in Celsius.\n" );
341 _samp->spatiallyUnique();
344 int npnt =
_samp->numPresence();
410 if ( *value != 0 && *value != 1 ) {
412 Log::instance()->
error(
"Parameter '%s' not set properly. It must be 0 or 1.\n", name.c_str() );
444 Sample const & sample = (*oc)->environment();
453 while ( oc != ocEnd ) {
455 Sample const& sample = (*oc)->environment();
466 mean /= occs->numOccurrences();
488 for (
int i = 0; i < 7; ++i ) {
502 std::vector<ScalarVector> matrix = occs->getEnvironmentMatrix();
508 ScalarVector::iterator lStart, lEnd;
510 for (
int j = 2; j < num_layers; j++ ) {
515 if ( j == 5 || j == 7 ) {
527 if ( j == 6 || j == 8 ) {
565 lStart = matrix[j].begin();
566 lEnd = matrix[j].end();
567 sort( lStart, lEnd );
569 int numOccurrences = occs->numOccurrences();
582 Scalar v10, v25, v75, v90;
584 _percentile( &v10, numOccurrences, 0.10, &matrix, j );
585 _percentile( &v25, numOccurrences, 0.25, &matrix, j );
586 _percentile( &v75, numOccurrences, 0.75, &matrix, j );
587 _percentile( &v90, numOccurrences, 0.90, &matrix, j );
594 Scalar interquartile = fabs( v25 - v75 );
598 Scalar adjmin = v25 - ( 1.5 * interquartile );
599 Scalar adjmax = v75 + ( 1.5 * interquartile );
648 iPrev = (int) floor( k );
649 iNext = (int) ceil( k );
655 if ( iPrev == iNext ) {
658 *result = ( (*matrix)[layerIndex][iPrev] + (*matrix)[layerIndex][iNext] ) / 2;
663 *result = (*matrix)[layerIndex][iNext];
676 dbfullname.append(
"/" );
678 dbfullname.append(
"\\" );
681 dbfullname.append(
"aquamaps.db" );
685 ifstream dbfile( dbfullname.c_str(), ios::in );
689 Log::instance()->
warn(
"Could not find internal database with species data.\n" );
697 int rc = sqlite3_open( dbfullname.c_str(), &db);
703 Log::instance()->
warn(
"Could not open internal database: %s\n", sqlite3_errmsg( db ) );
711 sqlite3_stmt *ppStmt;
713 char* sql = sqlite3_mprintf(
"select pelagic, provider, depthmin, depthmax, depthprefmin, depthprefmax, iceconmin, iceconmax, iceconprefmin, iceconprefmax, landdistmin, landdistmax, landdistprefmin, landdistprefmax, primprodmin, primprodmax, primprodprefmin, primprodprefmax, salinitymin, salinitymax, salinityprefmin, salinityprefmax, tempmin, tempmax, tempprefmin, tempprefmax from spinfo where species = '%q'", species );
715 rc = sqlite3_prepare( db, sql, strlen( sql ), &ppStmt, &pzTail );
717 if ( rc == SQLITE_OK ) {
720 int result_code = sqlite3_step( ppStmt );
722 if ( result_code == SQLITE_ROW ) {
724 int pelagic = sqlite3_column_int( ppStmt, 0 );
725 const char * provider = (
char *)sqlite3_column_text( ppStmt, 1 );
726 double depthmin = sqlite3_column_double( ppStmt, 2 );
727 double depthmax = sqlite3_column_double( ppStmt, 3 );
728 double depthprefmin = sqlite3_column_double( ppStmt, 4 );
729 double depthprefmax = sqlite3_column_double( ppStmt, 5 );
751 if ( sqlite3_column_bytes( ppStmt, 1 ) ) {
753 string prov_code( provider );
755 if ( prov_code ==
"MM" ) {
776 else if ( result_code == SQLITE_DONE ) {
782 Log::instance()->
warn(
"Could not fetch data from species database: %s\n", sqlite3_errmsg( db ) );
787 Log::instance()->
warn(
"Could not prepare SQL statement to query species database: %s\n", sqlite3_errmsg( db ) );
794 sqlite3_finalize( ppStmt );
833 if ( ! sqlite3_column_bytes( stmt, index ) ) {
838 double value = sqlite3_column_double( stmt, index );
844 if ( ! sqlite3_column_bytes( stmt, index ) ) {
849 value = sqlite3_column_double( stmt, index );
855 if ( ! sqlite3_column_bytes( stmt, index ) ) {
860 value = sqlite3_column_double( stmt, index );
866 if ( ! sqlite3_column_bytes( stmt, index ) ) {
871 value = sqlite3_column_double( stmt, index );
909 Scalar new_pref_min = center - halfSize;
911 if ( new_pref_min >=
_minimum[layerIndex] ) {
916 Scalar new_pref_max = center + halfSize;
918 if ( new_pref_max <=
_maximum[layerIndex] ) {
965 int num_variables_used = 0;
971 ++num_variables_used;
978 if ( x[MAXDEPTH] <
_minimum[MAXDEPTH] ) {
1031 int numLayers = x.
size();
1033 for (
int i = 2; i < numLayers; i++ ) {
1061 if ( i == 5 || i == 7 ) {
1069 if ( i == 6 || i == 8 ) {
1075 ++num_variables_used;
1104 return pow( prob, (
Scalar)1/num_variables_used );
1119 config->addSubsection( model_config );
1121 model_config->addNameValue(
"UseLayer",
_use_layer, 7 );
1123 model_config->addNameValue(
"Pelagic",
_pelagic );
1124 model_config->addNameValue(
"Minimum",
_minimum );
1125 model_config->addNameValue(
"PreferedMinimum",
_pref_minimum );
1126 model_config->addNameValue(
"PreferedMaximum",
_pref_maximum );
1127 model_config->addNameValue(
"Maximum",
_maximum );
1136 if ( ! model_config ) {
1145 model_config->getAttributeAsIntArray(
"UseLayer", &
_use_layer, &size );
1151 Log::instance()->
error(
"Could not find attribute '%s' in serialized model. You may be trying to load a model that was generated with an older version (< 0.2) of this algorithm.\n", exception.
getName().c_str() );
1156 _pelagic = model_config->getAttributeAsInt(
"Pelagic", -1 );
1157 _minimum = model_config->getAttributeAsSample(
"Minimum" );
1158 _pref_minimum = model_config->getAttributeAsSample(
"PreferedMinimum" );
1159 _pref_maximum = model_config->getAttributeAsSample(
"PreferedMaximum" );
1160 _maximum = model_config->getAttributeAsSample(
"Maximum" );
1193 else if ( index > 5 ) {
std::string omDataPath(std::string dir)
OM_ALG_DLL_EXPORT AlgMetadata const * algorithmMetadata()
void warn(const char *format,...)
'Warn' level.
double Scalar
Type of map values.
const std::string & getName() const
void _calculateEnvelopes(const OccurrencesPtr &)
static Log * instance()
Returns the instance pointer, creating the object on the first call.
Scalar getValue(const Sample &x) const
virtual void _setConfiguration(const ConstConfigurationPtr &)
OM_ALG_DLL_EXPORT AlgorithmImpl * algorithmFactory()
const Scalar INNER_SIZE[7]
void error(const char *format,...)
'Error' level.
int getParameter(std::string const &name, std::string *value)
#define PARAM_USE_DEPTH_RANGE
#define PARAM_USE_PRIMARY_PRODUCTION
void _adjustInterquartile(int layerIndex, Scalar adjmin, Scalar adjmax)
const int ICE_CONCENTRATION
int _getAndCheckParameter(std::string const &name, int *value)
const Scalar BOTTOM_UPPER_LIMIT[7]
bool _hasExpertRange(sqlite3_stmt *stmt, int varIndex)
#define PARAM_USE_ICE_CONCENTRATION
float getProgress() const
#define PARAM_USE_TEMPERATURE
void _ensureEnvelopeSize(int layerIndex)
void _readSpeciesData(const char *species)
#define PARAM_USE_DISTANCE_TO_LAND
void info(const char *format,...)
'Info' level.
#define PARAM_USE_SURFACE_LAYERS
void _percentile(Scalar *result, int n, double percent, std::vector< ScalarVector > *matrix, int layerIndex)
virtual void _getConfiguration(ConfigurationPtr &) const
const Scalar SURFACE_UPPER_LIMIT[7]
#define PARAM_USE_SALINITY
static AlgMetadata metadata
const Scalar SURFACE_LOWER_LIMIT[7]
std::vector< OccurrencePtr >::const_iterator const_iterator
const Scalar BOTTOM_LOWER_LIMIT[7]
const int DISTANCE_TO_LAND
int _getRelatedIndex(int index)
int getConvergence(Scalar *const val) const
void debug(const char *format,...)
'Debug' level.
const int PRIMARY_PRODUCTION
static AlgParamMetadata parameters[NUM_PARAM]
const std::string NAME[7]