danlwarren / ENMTools

ENMTools R Package
104 stars 30 forks source link

SpatRaster error in enmtools.maxent() #235

Closed ascanioalfredoa closed 11 months ago

ascanioalfredoa commented 1 year ago

Hi Dan. Hope you are doing well.

I'm finding an issue with the current version of ENMTools that the example is able to replicate. If I run a maxent model using a SpatRaster environmental dataset

try(enmtools.maxent(iberolacerta.clade$species$monticola, env = euro.worldclim))

Returns the following error:

Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘maxent’ for signature ‘"SpatRaster", "data.frame"’

I see that the issue comes from dismo::maxent(), which requires the env object to be a rasterlayer or rasterstack (already tested it and it runs). However, if I try converting the SpatRaster into a RasterStack and pass it to the enmtools.maxent() tool I get:

try(enmtools.maxent(iberolacerta.clade$species$monticola, env = raster::stack(euro.worldclim)))

Error : [compareGeom] SRS do not match In addition: Warning message: In check.raster(env, "env") : env is not the expected SpatRaster class (instead, it is of class RasterStack). ENMTools will attempt to coerce using terra::rast(...), but we cannot guaranteed the correctness of the result. Please consider using SpatRaster format directly in the future, to minimize unexpected results.

For dismo, something like this seems to be working

dismo::maxent(raster::stack(euro.worldclim), p = crds(iberolacerta.clade$species$monticola$presence.points))

danlwarren commented 1 year ago

Thank you for the feedback! This is all new functionality so we're still ironing the kinks out. Just out of curiosity, in the second example is it returning a model despite complaining?

stiatragul commented 1 year ago

Hey @danlwarren, thanks for developing this great package. And thanks @ascanioalfredoa for raising the issue. I wanted to point out that when trying to run maxent in enmtools.aoc() I got the same error. I am using a slightly different example, still from the code you provided using GBIF and anoles where brev.clade is a list of objects from your custom function species.from.gbif() and

hisp.env <- worldclim_global(var='bio', res=10, path = "./")
hisp.env <- crop(hisp.env, extent(-75, -65, 16, 21))

Command: R> enmtools.aoc(clade = brev.clade, env = hisp.env, nreps = 50, overlap.source = "mx")

Output:

Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘maxent’ for signature ‘"SpatRaster", "data.frame"’

I was able to run maxent in dismo directly with raster::stack(hisp.env) although that only dismo::maxent(raster::stack(hisp.env), p = crds(brev.clade$species[[5]]$presence.points))

Thanks again for your attention

danlwarren commented 1 year ago

That makes sense - down the line it's still just calling the enmtools.maxent function. We tried to have it convert to something dismo::maxent() would understand on the fly, but clearly we weren't fully successful in that. We'll try to get a fix ASAP. Thanks!

ascanioalfredoa commented 1 year ago

Thank you for the feedback! This is all new functionality so we're still ironing the kinks out. Just out of curiosity, in the second example is it returning a model despite complaining?

Sorry, I meant that I was able to run the dismo::maxent() with a rasterstack, but not with a SpatRaster. Trying to do the SpatRaster prompted the errors I copied above. My temporary fix was to create a enmtools.maxent2() function where I used raster::stack(env) inside the dismo::maxent() calls. And then used this updated function inside the other enmtools tests I needed. With that change, everything ran smoothly.

danlwarren commented 1 year ago

@rdinnager has just made an update to the master branch that should fix this - can you try it and see if it works for you?

bloomer3 commented 1 year ago

Hello! I have been having the same issue. I downloaded the latest 'develop' version of ENMTools to try the fix.

For the develop version of enmtools.maxent, the species presence points have to be in a data frame (I just used read.csv) and 'env' has to be a RasterStack. The SpatRaster and SpatVector don't work with the update.

When running enmtools.maxent, it started but I eventually got the error: Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘raster’ for signature ‘"numeric"’

Not sure where it has gone wrong, any insight to next steps to try would be great.

rdinnager commented 1 year ago

Hi @bloomer3,

Do you mean that you installed ENMTools from the develop branch on github? If so, please install from the master branch, as this is the official development version of ENMTools (the release version is on CRAN). The develop branch is for internal development purposes and isn't necessarily kept in a working state. If you still have a problem after installing from master, please let us know.

bloomer3 commented 1 year ago

Hi @rdinnager

Thanks for the quick reply. I have reinstalled from the master branch and am still getting the same error: Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘raster’ for signature ‘"numeric"’

My 'env' are in SpatRaster format, and my presence and background points are SpatVectors.

rdinnager commented 1 year ago

Okay, would you be able to make a minimal reproducible example? If you don't know how to do that, could you at least paste the code you ran before you got this error (including everything before enmtools.maxent())? Also, after you get the error, can you run traceback() and then paste the results here?

bloomer3 commented 1 year ago

enmtools_code.txt traceback.txt

Hi @rdinnager Attached are text files for my current code and the traceback error message.

Thanks!

ascanioalfredoa commented 1 year ago

Hi everyone. For me the enmtools.maxent is now running. I didn't have a chance to try with my own data, but the example code is running without any issues now

try(enmtools.maxent(iberolacerta.clade$species$monticola, env = euro.worldclim))

Thanks for the quick fix!

ascanioalfredoa commented 1 year ago

enmtools_code.txt traceback.txt

Hi @rdinnager Attached are text files for my current code and the traceback error message.

Thanks!

Hi @bloomer3. I think one issue may be that one of your rasters is converted to factor before stacking, but there is no indication of which variable it is in the maxent line. If you check the help for dismo::maxent, it has an argument called factors, so you should add that to your code and see if it runs

fodiens.mx<-enmtools.maxent(fodiens,env,test.prop=0.25,args=my.args.mt, env.nback=10000, verbose=TRUE, factors = "nlcd")