diff --git a/DESCRIPTION b/DESCRIPTION index 099c6bb..b385b6b 100755 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: rerddapXtracto Type: Package Title: Extracts Environmental Data from 'ERDDAP' Web Services -Version: 1.1.1 -Date: 2021-06-01 +Version: 1.1.2 +Date: 2021-09-24 Authors@R: person("Roy", "Mendelssohn", email = "roy.mendelssohn@noaa.gov", role = c("aut","cre")) Description: Contains three functions that access environmental data from any 'ERDDAP' data web service. The rxtracto() function extracts @@ -41,7 +41,7 @@ Suggests: maptools, rgdal, rmarkdown -RoxygenNote: 7.1.1 +RoxygenNote: 7.1.2 Encoding: UTF-8 LazyData: TRUE VignetteBuilder: knitr diff --git a/NEWS.md b/NEWS.md index 9f03c57..fe1493b 100755 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ +# rerddapXtracto 1.1.2 + Fixed problem with CRAN Solaris checks + Functions now will always return a result + Either the data requsted or an error string + # rerddapXtracto 1.1.1 Fixed problem with 'rxtracto()' example diff --git a/R/checkBounds.R b/R/checkBounds.R index a73a11a..51d0316 100755 --- a/R/checkBounds.R +++ b/R/checkBounds.R @@ -62,8 +62,8 @@ checkBounds <- function(dataCoordList, dimargs, cross_dateline_180) { if (returnCode != 0) { - stop("Coordinates out of dataset bounds - see messages above") + print("Coordinates out of dataset bounds - see messages above") } - # return(returnCode) + return(returnCode) } diff --git a/R/checkInput.R b/R/checkInput.R index 7b45614..c257635 100755 --- a/R/checkInput.R +++ b/R/checkInput.R @@ -3,13 +3,13 @@ checkInput <- function(dataInfo, parameter, urlbase, callDims) { # check that a valid rerddap info structure is being passed if (!(methods::is(dataInfo, "info"))) { print("error - dataInfo is not a valid info structure from rerddap") - return() + return(-999) } # check that the dataset is a grid if (!("Grid" %in% dataInfo$alldata$NC_GLOBAL$value)) { print("error - dataset is not a Grid") - return() + return(-999) } @@ -29,7 +29,8 @@ checkInput <- function(dataInfo, parameter, urlbase, callDims) { print('Requested coordinate names do no match dataset coordinate names') print(paste('Requested coordinate names:', names(callDims))) print(paste('Dataset coordinate names:', allCoords)) - stop(sprintf("Execution halted"), call. = FALSE) + #stop(sprintf("Execution halted"), call. = FALSE) + return(-999) } if (!(length(callDims) == length(allCoords))) { print("Ranges not given for all of the dataset dimensions") @@ -37,7 +38,9 @@ checkInput <- function(dataInfo, parameter, urlbase, callDims) { print(names(callDims)) print("Dataset Coordinates: ") print(allCoords) - stop(sprintf("Execution halted"), call. = FALSE) + #stop(sprintf("Execution halted"), call. = FALSE) + print("Execution halted") + return(-999) } # check that the field given part of the dataset @@ -46,7 +49,9 @@ checkInput <- function(dataInfo, parameter, urlbase, callDims) { cat("Parameter given: ", parameter) cat("Dataset Parameters: ", allvars[(length(allCoords) + 1):length(allvars)]) - stop("execution halted", call. = FALSE) + #stop(sprintf("Execution halted"), call. = FALSE) + print("Execution halted") + return(-999) } # check that the base url ends in / lenURL <- nchar(urlbase) @@ -55,9 +60,15 @@ checkInput <- function(dataInfo, parameter, urlbase, callDims) { } # check that urlbase connects to an ERDDAP - myHTTP <- httr::HEAD(urlbase) + suppressMessages(try(myHTTP <- httr::HEAD(urlbase), silent = TRUE)) + if (!exists('myHTTP')) { + print('failed to connect to given ERDDAP') + return(-1000) + } if (!(myHTTP$status_code == 200)) { - stop("urlbase did not resolve to a valid server", call. = FALSE) + print('error in accessing ERDDAP server') +# stop("urlbase did not resolve to a valid server", call. = FALSE) + return(-1000) } diff --git a/R/data_extract_read.R b/R/data_extract_read.R index c1d8367..6d453ab 100755 --- a/R/data_extract_read.R +++ b/R/data_extract_read.R @@ -1,6 +1,7 @@ data_extract_read <- function(dataInfo, callDims, urlbase, xName, yName, zName, tName, parameter, - erddapXcoord, erddapYcoord, erddapTcoord, erddapZcoord, + erddapXcoord, erddapYcoord, erddapTcoord, + erddapZcoord, verbose, cache_remove) { griddapCmd <- makeCmd(dataInfo, urlbase, xName, yName, zName, tName, parameter, @@ -18,7 +19,7 @@ data_extract_read <- function(dataInfo, callDims, urlbase, if (!class(griddapExtract)[1] == "try-error") { goodtry <- 1 } else{ - rerddap::cache_delete_all() + suppressWarnings(try(rerddap::cache_delete_all())) # rerddap::cache_list() Sys.sleep(tryn * 0.5) } @@ -72,7 +73,9 @@ data_extract_read <- function(dataInfo, callDims, urlbase, # remove netcdf file from cache if (cache_remove) { - rerddap::cache_delete(griddapExtract) + if(exists('griddapExtract')) { + suppressWarnings(try(rerddap::cache_delete(griddapExtract), silent = TRUE)) + } } # create output list ------------------------------------------------------ diff --git a/R/getFIleCoords.R b/R/getFIleCoords.R index 4fc399c..8ba60eb 100755 --- a/R/getFIleCoords.R +++ b/R/getFIleCoords.R @@ -30,7 +30,9 @@ getfileCoords <- function(datasetID, dataCoords, urlbase) { while ((tryn <= numtries) & (goodtry == -1)) { tryn <- tryn + 1 r1 <- try( httr::GET(myURL), silent = TRUE) - if (r1$status_code == 200) { + if (class(r1) == 'try-error') { + Sys.sleep(tryn * 0.5) + } else if (r1$status_code == 200) { goodtry <- 1 } else{ Sys.sleep(tryn * 0.5) @@ -40,7 +42,8 @@ getfileCoords <- function(datasetID, dataCoords, urlbase) { if (goodtry == -1) { print('error in trying to retrieve the dataset coordinate variables') print(paste('failed on dimension ', dataCoords[i] )) - stop('check on the ERDDAP server that the dataset is active') + print('check on the ERDDAP server that the dataset is active') + return(-999) } if (dataCoords[i] == "time" ) { coordVals <- suppressMessages(readr::read_csv(r1$content, diff --git a/R/rxtracto.R b/R/rxtracto.R index adcff34..8a1c4a5 100755 --- a/R/rxtracto.R +++ b/R/rxtracto.R @@ -26,7 +26,7 @@ #' if the the URL request should be verbose #' @param progress_bar - logical variable (default FALSE) #' should a progress bar be displayed -#' @return A dataframe containing: +#' @return If success a dataframe containing: #' \itemize{ #' \item column 1 = mean of data within search radius #' \item column 2 = standard deviation of data within search radius @@ -40,6 +40,7 @@ #' \item column 10 = median of data within search radius #' \item column 11 = median absolute deviation of data within search radius #' } +#' else an error string #' @examples #' # toy example to show use #' # but keep execution time down @@ -109,6 +110,13 @@ rxtracto <- function(dataInfo, parameter = NULL, xcoord=NULL, ycoord = NULL, } } urlbase <- checkInput(dataInfo1, parameter, urlbase, callDims) + if (is.numeric(urlbase)) { + if (urlbase == -999) { + return("error in inputs") + } else { + return('url is not a valid erddap server') + } + } # Check and readjust coordinate variables --------------------------------- @@ -117,8 +125,8 @@ rxtracto <- function(dataInfo, parameter = NULL, xcoord=NULL, ycoord = NULL, # get the actual coordinate values from ERDDAP dataCoordList <- getfileCoords(attr(dataInfo1, "datasetid"), allCoords, urlbase) - if (length(dataCoordList) == 0) { - stop("Error retrieving coordinate variable") + if (is.numeric(dataCoordList)) { + return("Error retrieving coordinate variable") } # remap coordinates as needed, so requested longtiudes are same as dataset @@ -134,7 +142,7 @@ rxtracto <- function(dataInfo, parameter = NULL, xcoord=NULL, ycoord = NULL, working_coords$tcoord) if(return_code == 1){ print("Errors in interpolation information, see above") - return() + return("Errors in interpolation information") } extract <- erddap_interp(urlbase, attr(dataInfo1, "datasetid"), parameter, working_coords$xcoord, working_coords$ycoord, @@ -196,7 +204,10 @@ rxtracto <- function(dataInfo, parameter = NULL, xcoord=NULL, ycoord = NULL, names(dimargs) <- c(xName, yName, zName, tName) dimargs <- Filter(Negate(is.null), dimargs) #check that coordinate bounds are contained in the dataset - checkBounds(dataCoordList, dimargs, cross_dateline_180) + bound_check <- checkBounds(dataCoordList, dimargs, cross_dateline_180) + if (bound_check != 0){ + return( 'error in given bounds') + } # create structures to store request -------------------------------------- @@ -296,7 +307,8 @@ rxtracto <- function(dataInfo, parameter = NULL, xcoord=NULL, ycoord = NULL, extract1 <- data_extract_read(dataInfo1, callDims, urlbase, xName, yName, zName, tName, parameter, xcoord_temp, erddapCoords$erddapYcoord, - erddapCoords$erddapTcoord, erddapCoords$erddapZcoord, + erddapCoords$erddapTcoord, + erddapCoords$erddapZcoord, verbose, cache_remove = TRUE) if (!is.list(extract1)) { text1 <- "There was an error in the url call, perhaps a time out." @@ -304,8 +316,12 @@ rxtracto <- function(dataInfo, parameter = NULL, xcoord=NULL, ycoord = NULL, print(paste(text1, text2)) print("Returning incomplete download") out_dataframe <- out_dataframe[1:(i - 1), ] - remove('paramdata') - rerddap::cache_delete(extract1) + if (exists('paramdata')) { + suppressWarnings(try(remove('paramdata'), silent = TRUE)) + } + if (exists('extract1')) { + suppressWarnings(try(rerddap::cache_delete(extract1), silent = TRUE)) + } return(out_dataframe) } # lower_bound <- round(min(dataCoordList$longitude), 3) @@ -314,7 +330,8 @@ rxtracto <- function(dataInfo, parameter = NULL, xcoord=NULL, ycoord = NULL, extract2 <- data_extract_read(dataInfo1, callDims, urlbase, xName, yName, zName, tName, parameter, xcoord_temp, erddapCoords$erddapYcoord, - erddapCoords$erddapTcoord, erddapCoords$erddapZcoord, + erddapCoords$erddapTcoord, + erddapCoords$erddapZcoord, verbose, cache_remove = TRUE) if (!is.list(extract2)) { text1 <- "There was an error in the url call, perhaps a time out." @@ -322,8 +339,12 @@ rxtracto <- function(dataInfo, parameter = NULL, xcoord=NULL, ycoord = NULL, print(paste(text1, text2)) print("Returning incomplete download") out_dataframe <- out_dataframe[1:(i - 1), ] - remove('paramdata') - rerddap::cache_delete(extract2) + if (exists('paramdata')) { + suppressWarnings(try(remove('paramdata'), silent = TRUE)) + } + if (exists('extract2')) { + suppressWarnings(try(rerddap::cache_delete(extract1), silent = TRUE)) + } return(out_dataframe) } extract2$longitude = make360(extract2$longitude) @@ -349,8 +370,10 @@ rxtracto <- function(dataInfo, parameter = NULL, xcoord=NULL, ycoord = NULL, }else { extract <- data_extract_read(dataInfo1, callDims, urlbase, xName, yName, zName, tName, parameter, - erddapCoords$erddapXcoord, erddapCoords$erddapYcoord, - erddapCoords$erddapTcoord, erddapCoords$erddapZcoord, + erddapCoords$erddapXcoord, + erddapCoords$erddapYcoord, + erddapCoords$erddapTcoord, + erddapCoords$erddapZcoord, verbose, cache_remove = TRUE) if (!is.list(extract)) { @@ -359,8 +382,12 @@ rxtracto <- function(dataInfo, parameter = NULL, xcoord=NULL, ycoord = NULL, print(paste(text1, text2)) print("Returning incomplete download") out_dataframe <- out_dataframe[1:(i - 1), ] - remove('paramdata') - rerddap::cache_delete(extract) + if (exists('paramdata')) { + suppressWarnings(try(remove('paramdata'), silent = TRUE)) + } + if (exists('extract')) { + suppressWarnings(try(rerddap::cache_delete(extract1), silent = TRUE)) + } if (progress_bar) { close(pb) } diff --git a/R/rxtracto_3D.R b/R/rxtracto_3D.R index 4476bee..095297b 100755 --- a/R/rxtracto_3D.R +++ b/R/rxtracto_3D.R @@ -19,7 +19,7 @@ #' @param tName - character string with name of the tcoord in the 'ERDDAP' dataset (default "time") #' @param verbose - logical variable (default FALSE) if the the URL request should be verbose #' @param cache_remove - logical variable (default TRUE) whether to delete 'rerddap' cache -#' @return structure with data and dimensions: +#' @return If successful a structure with data and dimensions: #' \itemize{ #' \item extract$data - the data array dimensioned (lon,lat,time) #' \item extract$varname - the name of the parameter extracted @@ -28,6 +28,7 @@ #' \item extract$latitude - the latitudes always going south to north #' \item extract$time - the times of the extracts #' } +#' else an error string #' @examples #' # toy example to show use #' # and keep execution time low @@ -61,6 +62,13 @@ rxtracto_3D <- function(dataInfo, parameter = NULL, xcoord = NULL, dataInfo1 <- dataInfo urlbase <- dataInfo1$base_url urlbase <- checkInput(dataInfo1, parameter, urlbase, callDims) + if (is.numeric(urlbase)) { + if (urlbase == -999) { + return("error in inputs") + } else { + return('url is not a valid erddap server') + } + } @@ -68,8 +76,8 @@ rxtracto_3D <- function(dataInfo, parameter = NULL, xcoord = NULL, # get the actual coordinate values for the dataset allCoords <- dimvars(dataInfo1) dataCoordList <- getfileCoords(attr(dataInfo1, "datasetid"), allCoords, urlbase) -if (length(dataCoordList) == 0) { - stop("Error retrieving coordinate variable") +if (is.numeric(dataCoordList) ) { + return("Error retrieving coordinate variable") } @@ -109,7 +117,10 @@ names(dimargs) <- c(xName, yName, zName, tName) dimargs <- Filter(Negate(is.null), dimargs) #check that coordinate bounds are contained in the dataset -checkBounds(dataCoordList, dimargs, cross_dateline_180) +bound_check <- checkBounds(dataCoordList, dimargs, cross_dateline_180) +if (bound_check != 0){ + return( 'error in given bounds') +} # Find dataset coordinates closest to requested coordinates --------------- @@ -136,7 +147,7 @@ if (cross_dateline_180) { text1 <- "There was an error in the url call, perhaps a time out." text2 <- "See message on screen and URL called" print(paste(text1, text2)) - stop("stopping download") + return("URL cal error") } # lower_bound <- round(min(dataCoordList$longitude), 3) lower_bound <- min(dataCoordList$longitude) + 0.0001 @@ -150,7 +161,7 @@ if (cross_dateline_180) { text1 <- "There was an error in the url call, perhaps a time out." text2 <- "See message on screen and URL called" print(paste(text1, text2)) - stop("stopping download") + return("URL cal error") } extract2$longitude = make360(extract2$longitude) # extract <- list(NA, NA, NA, NA, NA, NA) @@ -184,7 +195,7 @@ if (!is.list(extract)) { text1 <- "There was an error in the url call, perhaps a time out." text2 <- "See message on screen and URL called" print(paste(text1, text2)) - stop("stopping download") + return("URL call error") } extract <- structure(extract, class = c('list', 'rxtracto3D')) diff --git a/R/rxtractogon.R b/R/rxtractogon.R index a72c785..44840f0 100755 --- a/R/rxtractogon.R +++ b/R/rxtractogon.R @@ -17,7 +17,7 @@ #' @param tName - character string with name of the tcoord in the 'ERDDAP' dataset (default "time") #' @param verbose - logical variable (default FALSE) if the the URL request should be verbose #' @param cache_remove - logical variable (default TRUE) whether to delete 'rerddap' cache -#' @return structure with data and dimensions +#' @return If successful a structure with data and dimensions #' \itemize{ #' \item extract$data - the masked data array dimensioned (lon,lat,time) #' \item extract$varname - the name of the parameter extracted @@ -26,6 +26,7 @@ #' \item extract$latitude - the latitudes always going south to north #' \item extract$time - the times of the extracts #' } +#' else an error string #' @examples #' # toy example to show use #' # and keep execution time low @@ -69,18 +70,18 @@ rxtractogon <- function(dataInfo, parameter, xcoord = NULL, ycoord = NULL, rerddap::cache_setup(temp_dir = TRUE) if (!(methods::is(dataInfo, "info"))) { print("error - dataInfo is not a valid info structure from rerddap") - return() + return("bad info structure") } # check that the dataset is a grid if (!("Grid" %in% dataInfo$alldata$NC_GLOBAL$value)) { print("error - dataset is not a Grid") - return() + return("dataset not a grid") } if (length(xcoord) != length(ycoord)) { print('xcoord and ycoord are not of the same length') - stop('program stops') + return('bad xcoord, ycoord values') } #extend out tpos to be length 2 if not @@ -99,6 +100,11 @@ extract <- rxtracto_3D(dataInfo, parameter = parameter, xcoord = xcoord1, xName = xName, yName = yName, zName = zName, verbose = verbose, cache_remove = cache_remove) # extract <- xtracto_3D(xcoord1,ycoord1,tpos1,dtype, verbose) +if (!is.list(extract)) { + print('error in call to rxtracto_3D') + print('see messages above') + return("rxtracto_3D error") +} if (length(dim(extract[[1]])) == 2) { extract[[1]] <- array(extract[[1]], c(dim(extract[[1]]), 1)) } diff --git a/cran-comments.md b/cran-comments.md index b06974a..8b29502 100755 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,15 +1,11 @@ -## Version 1.1.1 +## Version 1.1.2 -Fixed 'rxtracto()' example error - -## Version 1.1.0 - -Fixing present warnings and errors: - -Believe existing problms are fixed. Two are from 3.6.x releases, the DESCRIPION clearly states requires at least R4.0.0 +Fixed CRAN check problem on Solaris. +Fixed Debian error on auto check +Functions will now always return something and end. ## Test environments -* local OS X install, R 4.1.0 +* local OS X install, R 4.1.1 * rhub check_for_cran Debian * rhub check_for_cran Ubuntu * rhub macos-highsierra-release-cran @@ -18,26 +14,20 @@ Believe existing problms are fixed. Two are from 3.6.x releases, the DESCRIPION ## R CMD check result -On Mac OS X R 4.1.0 I get: +On Mac OS X R 4.1.1 I get: -Duration: 1m 18.8s +Duration: 1m 20.3s 0 errors ✓ | 0 warnings ✓ | 0 notes ✓ on winbuilder_release: -Installation time in seconds: 7 -Check time in seconds: 119 Status: OK -R version 4.1.0 (2021-05-18) on winbuilder_develop: -Installation time in seconds: 5 -Check time in seconds: 87 Status: OK -R Under development (unstable) (2021-05-28 r80404) rhub Ubuntu Linux 20.04.1 LTS, R-release, GCC: OK diff --git a/man/rxtracto.Rd b/man/rxtracto.Rd index a4a19cf..d1c1546 100755 --- a/man/rxtracto.Rd +++ b/man/rxtracto.Rd @@ -64,7 +64,7 @@ if the the URL request should be verbose} should a progress bar be displayed} } \value{ -A dataframe containing: +If success a dataframe containing: \itemize{ \item column 1 = mean of data within search radius \item column 2 = standard deviation of data within search radius @@ -78,6 +78,7 @@ A dataframe containing: \item column 10 = median of data within search radius \item column 11 = median absolute deviation of data within search radius } + else an error string } \description{ \code{rxtracto_new} uses the R program 'rerddap' to extract environmental diff --git a/man/rxtracto_3D.Rd b/man/rxtracto_3D.Rd index 213df9e..8f2ec38 100755 --- a/man/rxtracto_3D.Rd +++ b/man/rxtracto_3D.Rd @@ -47,7 +47,7 @@ decimal degrees N; -90 to 90)} \item{cache_remove}{- logical variable (default TRUE) whether to delete 'rerddap' cache} } \value{ -structure with data and dimensions: +If successful a structure with data and dimensions: \itemize{ \item extract$data - the data array dimensioned (lon,lat,time) \item extract$varname - the name of the parameter extracted @@ -56,6 +56,7 @@ structure with data and dimensions: \item extract$latitude - the latitudes always going south to north \item extract$time - the times of the extracts } + else an error string } \description{ \code{rxtracto_3D} uses the R program 'rerddap' to extract environmental data diff --git a/man/rxtractogon.Rd b/man/rxtractogon.Rd index b5d4f0d..86404e9 100755 --- a/man/rxtractogon.Rd +++ b/man/rxtractogon.Rd @@ -47,7 +47,7 @@ degrees N; -90 to 90)of polygon} \item{cache_remove}{- logical variable (default TRUE) whether to delete 'rerddap' cache} } \value{ -structure with data and dimensions +If successful a structure with data and dimensions \itemize{ \item extract$data - the masked data array dimensioned (lon,lat,time) \item extract$varname - the name of the parameter extracted @@ -56,6 +56,7 @@ structure with data and dimensions \item extract$latitude - the latitudes always going south to north \item extract$time - the times of the extracts } + else an error string } \description{ \code{rxtractogon} uses the R program 'rerddap' to extract environmental data