# OSMOSE (Object-oriented Simulator of Marine Ecosystems)
# http://www.osmose-model.org
#
# Copyright (C) IRD (Institut de Recherche pour le Développement) 2009-2020
#
# Osmose is a computer program whose purpose is to simulate fish
# populations and their interactions with their biotic and abiotic environment.
# OSMOSE is a spatial, multispecies and individual-based model which assumes
# size-based opportunistic predation based on spatio-temporal co-occurrence
# and size adequacy between a predator and its prey. It represents fish
# individuals grouped into schools, which are characterized by their size,
# weight, age, taxonomy and geographical location, and which undergo major
# processes of fish life cycle (growth, explicit predation, additional and
# starvation mortalities, reproduction and migration) and fishing mortalities
# (Shin and Cury 2001, 2004).
#
# Contributor(s):
# Yunne SHIN (yunne.shin@ird.fr),
# Morgane TRAVERS (morgane.travers@ifremer.fr)
# Ricardo OLIVEROS RAMOS (ricardo.oliveros@gmail.com)
# Philippe VERLEY (philippe.verley@ird.fr)
# Laure VELEZ (laure.velez@ird.fr)
# Nicolas Barrier (nicolas.barrier@ird.fr)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation (version 3 of the License). Full description
# is provided on the LICENSE file.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# createOsmoseMaps - main -------------------------------------------------
#' Create osmose maps
#'
#' @param ... Several object containing maps for species distribution
#' @param outdir Directory to write maps, only used if \code{write} is TRUE.
#' @param confdir Directory to save the configuration file.
#' @param write Boolean, write maps to csv files for osmose?
#' @param confile File to save osmose configuration for choosen maps.
#' @param prefixPath Path where the maps are located, used to write the full
#' path in the configuration files.
#'
#' @return \code{NULL}, it writes the maps to the disk.
#' @export
#'
createOsmoseMaps = function(..., outdir=NULL, confdir=NULL, write=TRUE,
confile = "maps-parameters.csv", prefixPath="maps") {
.par = function(par, i=NULL, type=NULL) {
if(!is.null(type)) par = paste(par, type, sep=".")
sprintf(paste("movement", "map%1d", par, sep="."), i)
}
maps = list(...)
if(length(maps)==1 & is.list(maps[[1]])) maps = maps[[1]]
nmap = 0
conf = list()
for(i in seq_along(maps)) {
obj = maps[[i]]
if(write) writeMaps(obj, outdir=outdir)
n = obj$info$nmap
for(j in seq_len(n)) {
conf[[.par("age.max", nmap)]] = max(obj$info$ages)
conf[[.par("age.min", nmap)]] = min(obj$info$ages)
conf[[.par("file", nmap)]] = file.path(prefixPath, paste0(obj$files[j], ".csv"))
conf[[.par("season", nmap)]] = obj$info$steps[j,]
conf[[.par("species", nmap)]] = obj$info$sp
conf[[.par("year.min", nmap)]] = obj$info$year.min[j]
conf[[.par("year.max", nmap)]] = obj$info$year.max[j]
nmap = nmap + 1
}
}
writeOsmoseParameters(conf=conf, file=file.path(confdir, confile))
message(paste(nmap, "maps written.", sep=" "))
return(invisible())
}
#' Set maps of species distribution for OSMOSE
#'
#' @param object An object with species distribution maps. Currently only work
#' with the \code{predict.niche.models} class from package \code{kali}.
#' @param type Types of maps used: climatology (average for each time step),
#' seasonal (average for each season: summer, winter, spring, fall) and annual
#' (average for all year) are available.
#' @param sp Species name as used in the osmose model.
#' @param lifespan Life span os the species.
#' @param frequency Number of simulation time steps per year.
#' @param ages set of ages corresponding to the maps. Default it \code{NULL} which
#' means for all ages (from 0 to \code{lifespan})
#' @param normalize boolean, make all probabilities add up to 1?
#' @param interannual boolean, uses the specified type for each year
#' independently or for all the period.
#' @param ... Additional arguments for specific methods.
#'
#' @return A list with the information to write osmose maps to the disk.
#'
setOsmoseMaps = function(object, type, sp, lifespan, frequency=24,
ages=NULL, normalize=TRUE, interannual=FALSE, ...) {
UseMethod("setOsmoseMaps")
}
# @param start argument to extract a window from the time series: c(year, month)
# @param end argument to extract a window from the time series: c(year, month)
# @param toPA boolean, transform map information in presence/absence (0/1)?
# @param prob boolean, keep probabilities inside the presence area?
# @param criteria criteria used to calculate the threshold for toPA.
# @param lat
# @param lon
#' @export
setOsmoseMaps.prediction.niche.models =
function(object, type, sp, lifespan, frequency=24, ages=NULL, normalize=TRUE,
interannual=FALSE, start=NULL, end=NULL,
toPA=TRUE, prob=TRUE, criteria="MinROCdist", lat=NULL, lon=NULL, ...) {
if(!requireNamespace("kali", quietly = TRUE))
stop("You need to install the 'kali' package.")
if(is.null(ages)) ages = seq_len(ceiling(lifespan) + 1) - 1
object = kali::window.prediction.niche.models(object, start=start, end=end)
nstep = switch(type,
climatology = frequency/12,
seasonal = frequency/4,
annual = frequency,
frequency)
# take care of different ages
if(interannual) {
map = switch(type,
climatology = object$prediction,
seasonal = kali::getSeasonalMap(object),
annual = kali::climatology(object$prediction,
object$info$time$year),
object$prediction) # create arrayts package
index = switch(type,
climatology = "month",
seasonal = "season",
annual = "year",
"month")
year.min = kali::getYearMin(object, index)
year.max = kali::getYearMax(object, index)
nmap = if(is.matrix(map)) 1 else dim(map)[3]
} else {
map = switch(type,
climatology = object$climatology,
seasonal = object$season,
annual = object$mean,
object$mean)
year.min = 0
year.max = max(object$info$time$year) - min(object$info$time$year)
nmap = if(is.matrix(map)) 1 else dim(map)[3]
year.min = rep(year.min, nmap)
year.max = rep(year.max, nmap)
}
map = kali::removeSector(map, coords=object$info$coords, lat=lat, lon=lon)
thr = kali::getThreshold(x=object, criteria=criteria)
if(toPA) map = kali::toPA.default(map, thr=thr, prob=prob)
if(normalize) map = kali::normalize(map)
mapNames = paste(sp, .niceSeq(nmap), sep="-")
# generalize 'steps'
steps = matrix(seq_len(frequency)-1, ncol=nstep, nrow=nmap, byrow=TRUE)
info = list(nmap = nmap, sp=sp, lifespan=lifespan, ages=ages,
frequency=frequency, steps=steps, year.min=year.min,
year.max=year.max)
output = list(map = map, files=mapNames, info=info)
return(output)
}
# createOsmoseMaps - auxiliar functions -----------------------------------
# Write maps for osmose species distribution
#
# @param object
# @param files
# @param outdir
#
# @return
#
writeMaps = function(object, files=NULL, outdir="maps") {
if(!requireNamespace("kali", quietly = TRUE))
stop("You need to install the 'kali' package.")
if(!requireNamespace("fields", quietly = TRUE))
stop("You need to install the 'fields' package.")
if(is.null(files)) files = object$files
if(!file.exists(outdir)) dir.create(outdir, recursive = TRUE)
if(!file.exists(file.path(outdir, "_images")))
dir.create(file.path(outdir, "_images"))
maps = kali::rotate(object$map, direction="anticlockwise")
nmap = if(is.matrix(maps)) 1 else dim(maps)[3]
for(i in seq_len(nmap)) {
file = file.path(outdir, paste0(files[i], ".csv"))
png(filename=file.path(outdir, "_images", paste0(files[i], ".png")))
fields::image.plot(kali::rotate(maps[,,i]))
dev.off()
write.table(maps[,,i], file=file, sep=";", quote=FALSE,
row.names=FALSE, col.names=FALSE, na="-99")
}
return(invisible())
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.