knitr::opts_chunk$set(echo = TRUE)
# if you set echo=FALSE, then the code will be hidden from output
library(ggplot2)
library(apsimx)

Now attempting to generate a soil profile from ISRIC database. Following the example in https://search.r-project.org/CRAN/refmans/apsimx/html/get_isric_soil_profile.html.

(This is the approximate lon/lat near Gemena, Democratic Republic of the Congo.)

sp1 <- get_isric_soil_profile(lonlat = c(19.75, 3.26))
# Soil profile at lon/lat 19.75/3.26 is now plotted.
plot(sp1)

plot(sp1, property = "BD")

Now creating a new apsimx file from the Wheat.apsimx example, that uses sp1 rather than whatever is there now.

# Recall that some of the newer versions of the APSIMX app do not work on macs;
# Here we are using an older version that does work on macs.
sdir <- "/Applications/APSIM2022.12.7130.0.app/Contents/Resources/Examples/"
tdir <- "/Users/rick/AG-CODE--FETCH-SOIL-PROFILES--v01/MODELS/"
edit_apsimx_replace_soil_profile(
  file = "Wheat.apsimx",
  src.dir = sdir,
  wrt.dir = tdir,
  soil.profile = sp1,
  edit.tag = "-lonlat_19.75_3.26",
  overwrite = FALSE,
  verbose = TRUE
)
## Created:  /Users/rick/AG-CODE--FETCH-SOIL-PROFILES--v01/MODELS//Wheat-lonlat_19.75_3.26.apsimx

Now creating a function that, given a lon/lat and an apsimx model, fetches the soil profile for the lon/lat from ISRIC, and creates a new apsimx model from the old one by substituting in the fetched soil profile.

Since the modified apsimx models are being stored as files, we also have the function “stringify_coord” so that we can systematically name the new files being created. Will convert negative coordinates (e.g., -52.3) to positive numbers with “m” as prefix (e.g., m52.3)

stringify_coord <- function(coord) {
  if (coord < 0) {
      # print("coord is negative")
      scoord <- paste("m", as.character(-1*coord), sep = "")
  } else {
      # print("coord is non-negative")
      scoord <- as.character(coord)
  }
  # print(paste("scoord is:", scoord, sep = ""))
  return(scoord)
}

# sdir is for source directory; tdir is for target directory
inject_soil_profile <- function(sdir, tdir, lon, lat, model) {
  sp <- get_isric_soil_profile(lonlat = c(lon, lat))
  tag <- paste("-lonlat_", stringify_coord(lon), "_", stringify_coord(lat), sep="")
  edit_apsimx_replace_soil_profile(
    file = model,
    src.dir = sdir,
    wrt.dir = tdir,
    soil.profile = sp,
    edit.tag = tag,
    overwrite = FALSE,
    verbose = TRUE
  )
}
sdir <- "/Applications/APSIM2022.12.7130.0.app/Contents/Resources/Examples/"
tdir <- "/Users/rick/AG-CODE--FETCH-SOIL-PROFILES--v01/MODELS"
model_prefix <- "Wheat"
model_suffix <- ".apsimx"
model <- paste(model_prefix, model_suffix, sep="")
lon <- 19.76
lat <- 3.26
tag <- paste("-lonlat_", stringify_coord(lon), "_", stringify_coord(lat), sep="")

inject_soil_profile(sdir, tdir, lon, lat, model)
## Created:  /Users/rick/AG-CODE--FETCH-SOIL-PROFILES--v01/MODELS/Wheat-lonlat_19.76_3.26.apsimx

We can run several lon/lat’s in a systematic way.

lll <- list(c(147.3,-35.42), c(-85.18, 32.43), c(-75.82, 41.57))
sdir <- "/Applications/APSIM2022.12.7130.0.app/Contents/Resources/Examples/"
tdir <- "/Users/rick/AG-CODE--FETCH-SOIL-PROFILES--v01/MODELS"
model_prefix <- "Maize"
model_suffix <- ".apsimx"
model <- paste(model_prefix, model_suffix, sep="")
for (lonlat in lll) {
  tag <- paste("-lonlat_", stringify_coord(lonlat[1]), "_", stringify_coord(lonlat[2]), sep="")
  inject_soil_profile(sdir, tdir, lonlat[1], lonlat[2], model)
}
## Created:  /Users/rick/AG-CODE--FETCH-SOIL-PROFILES--v01/MODELS/Maize-lonlat_147.3_m35.42.apsimx 
## Created:  /Users/rick/AG-CODE--FETCH-SOIL-PROFILES--v01/MODELS/Maize-lonlat_m85.18_32.43.apsimx 
## Created:  /Users/rick/AG-CODE--FETCH-SOIL-PROFILES--v01/MODELS/Maize-lonlat_m75.82_41.57.apsimx

In case it is useful, here is an example of an R function that catches errors.

outmsg <- tryCatch({
sp_19.75_3.26 <- get_isric_soil_profile(
  lonlat = c(19.75, 3.26),
  statistic = c("mean", "Q0.5"),
  soil.profile,     # something breaks here
  find.location.name = TRUE
)
}, error = function(err) {
    print(paste("There was an error, spez.: ", err))
  } )  # end tryCatch
## [1] "There was an error, spez.:  Error in get_isric_soil_profile(lonlat = c(19.75, 3.26), statistic = c(\"mean\", : object 'soil.profile' not found\n"