rsbivand / rgrass

Interpreted interface between the GRASS geographical information system and R
https://rsbivand.github.io/rgrass/
26 stars 9 forks source link

initGRASS() fails on MacOS X unless home and gisDbase are both set to tempdir() #11

Closed ltalluto closed 3 years ago

ltalluto commented 4 years ago

Strangely, this issue started affecting a script which was working a week ago, and is now failing on two separate computers. I haven't knowingly installed any updates, though a background OS X update isn't out of the question.

As it says in the title, I am not able to run initGRASS unless I set both home and gisDbase to tempdir(). It fails with the error:

Error in if (!compatible) { : argument is of length zero
In addition: Warning message:
In system(paste("g.version", get("addEXE", envir = .GRASS_CACHE),  : running command
'g.version' had status 1
ERROR: Variable 'LOCATION_NAME' not set

The following reproduces the error on my system: library(rgrass7) gisbase <- "/Applications/GRASS-7.6.app/Contents/Resources"

testdir <- "~/rgrass-test"
if(!dir.exists(testdir))
    dir.create(testdir)

# Fails
initGRASS(gisBase = gisbase, home = testdir, gisDbase = testdir, location='test', 
    mapset="PERMANENT", override = TRUE)
# Fails
initGRASS(gisBase = gisbase, home = testdir, gisDbase = tempdir(), location='test', 
    mapset="PERMANENT", override = TRUE)
# Fails
initGRASS(gisBase = gisbase, home = tempdir(), gisDbase = testdir, location='test', 
    mapset="PERMANENT", override = TRUE)
# Fails
initGRASS(gisBase = gisbase, home = testdir, gisDbase = testdir, override = TRUE)

# Succeeds
initGRASS(gisBase = gisbase, home = tempdir(), gisDbase = tempdir(), location='test', 
    mapset="PERMANENT", override = TRUE)

It does manage to create directories for my chosen mapset and location name, and it also creates ~/rgrass-test/.grassrc7, which looks like this:

GISDBASE: ~/rgrass-test
LOCATION_NAME: <UNKNOWN>
MAPSET: <UNKNOWN>

I have tried using base R, Rstudio, and running R from the command line, both as my normal user and with sudo, with the same results every time. System information: MaxOS X 10.14.6 R 3.6.0 rgrass7 0.2.3 (installed from this repository) It is also failaing with rgrass7 0.2.1 installed from CRAN

rsbivand commented 4 years ago

No idea at all. Please post on the GRASS stats mailing list after subscribing https://lists.osgeo.org/mailman/listinfo/grass-stats. I do not use that argument, so do not know what consequences there may be if your platform changes. When you post - issues are for code rather than usage - also show what succeeds with just gisBase and home set. My recollection is that initGRASS() on an existing location may use gisDbase, but that there is no need to when using a throw-away location.

veroandreo commented 4 years ago

If your intention is to use a throw-away location, this works fine for me in fedora 31 with compiled grass:

library(rgrass7)
myGRASS <- "home/veroandreo/software/grass79-dev/dist.x86_64-pc-linux-gnu" 
initGRASS(gisBase = myGRASS, home = tempdir())

Otherwise, I think you need to provide names of existent location and mapset. In the code of initGRASS(), there's no option (as far as I can understand) to create location and mapset aside from L193 and L198; but they point to the basename of tempdir() not to a given name. Others will know better.

I normally use R within GRASS moreover or, if the other way around, I provide existent location and mapset to read my maps from, and that works also fine:

# path to GRASS database 
myGISDbase <- "/home/veroandreo/grassdata/" 
# path to location 
myLocation <- "nc_spm_08_grass7" 
# path to mapset 
myMapset <- "user1"

initGRASS(gisBase = myGRASS,
          gisDbase = myGISDbase,          
          location = myLocation,           
          mapset = myMapset,
          SG="elevation",           
          override = TRUE)
rsbivand commented 4 years ago

I feel that it is not possible for the code inside initGRASS() to know the intentions of the user, so banning values passed through the arguments which apply in principle when accessing an existing location when the location does not exist isn't straightforward. I can try to trap this behviour, but it may impact other behaviours. Here, some possible upgrade to OSX appears to have modified the behaviour of the user's script, not rgrass7, probably not R, probably not GRASS, maybe permissions? I don't use OSX, so testing is impossible for me, hence the advice to post on the list, which has not been followed, and the questioner has not followed up.

ltalluto commented 4 years ago

Sorry for my slowness, I'm travelling and didn't expect such a quick response.

My intention here is to use a throwaway location, but outside of /var (which is where tempdir() usually points on Mac OS X). This is because for scripts that run for a very long time, /var can get cleaned up mid-script. So if it's not intended behavior to create a new location/mapset outside of tempdir(), this is fine, I think the simplest workaround is to modify the environment variables that R uses to decide where tempdir() points. I just tested this, and it succeeds as long as the variable is set before starting R.

Thanks for the clarification!

rsbivand commented 4 years ago

OK, thanks. Motivation clear, and work-around reasonable. I'll look again at the logic when time permits.