Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

efforts for using the job id for various utility functions #328

Merged
merged 12 commits into from Mar 4, 2017
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions DESCRIPTION
@@ -1,8 +1,8 @@
Package: geoknife
Type: Package
Title: Web-Processing of Large Gridded Datasets
Version: 1.5.2
Date: 2016-12-27
Version: 1.5.3
Date: 2017-03-03
Authors@R: c( person("Jordan", "Read", role = c("aut","cre"),
email = "jread@usgs.gov"),
person("Jordan", "Walker", role = c("aut"),
Expand Down
11 changes: 9 additions & 2 deletions R/check.R
Expand Up @@ -3,7 +3,8 @@
#' two fields: \code{status} and \code{URL}. If the \linkS4class{geojob} object has not been executed
#' (see \code{\link{start}}), this method returns \code{status}='none' and \code{URL}=NULL.
#'
#'@param .Object a \linkS4class{geojob} object with an active GDP process request.
#'@param .Object a \linkS4class{geojob} object with an active GDP process request,
#' or a \code{character} URL of an existing job
#'@return \code{process}, a list containing
#' \code{status} and \code{URL}.
#'
Expand Down Expand Up @@ -61,4 +62,10 @@ setMethod(f = "check",signature(.Object = "geojob"), definition = function(.Obje

setJobState(process$status)
return(process)
})
})

#'@rdname check-geojob
#'@aliases check
setMethod(f = "check",signature(.Object = "character"), definition = function(.Object){
check(geojob(id = .Object))
})
20 changes: 16 additions & 4 deletions R/download-geojob.R
Expand Up @@ -2,10 +2,10 @@
#'
#' download the result of a processing job to a local destination.
#'
#'@param .Object a \code{\link{geojob}} that has completed
#'@param .Object a \code{\link{geojob}} or job id that has completed
#'@param destination a file destination. If missing, a temp directory will be used
#'@param ... additional arguments passed to \code{\link[httr]{write_disk}}, such as overwrite = TRUE
#'@return the file handle
#'@return the destination of the downloaded file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the file is downloaded, this should be location rather that destination, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right. Changing.

#'@author Jordan S Read
#'@rdname download
#'@importFrom httr write_disk progress
Expand All @@ -17,19 +17,31 @@ setGeneric("download", function(.Object, destination, ...) {
#'@rdname download
#'@aliases download
setMethod("download", signature("geojob",'missing'), function(.Object, destination, ...) {
download(id(.Object), ...)
})

#'@rdname download
#'@aliases download
setMethod("download", signature("character",'missing'), function(.Object, destination, ...) {

status <- check(.Object)
if (is.null(status)) stop('geojob must be completed for download. See "check(geojob)"')

filename <- strsplit(status$URL, '?id=')[[1]][2]
destination = file.path(tempdir(), filename)

download(.Object, destination)
download(.Object, destination, ...)
})

#'@rdname download
#'@aliases download
setMethod("download", signature("geojob",'character'), function(.Object, destination, ...) {
download(id(.Object), destination, ...)
})

#'@rdname download
#'@aliases download
setMethod("download", signature("character",'character'), function(.Object, destination, ...) {

status <- check(.Object)
gGET(url=status$URL, write_disk(destination, ...))
Expand Down
43 changes: 26 additions & 17 deletions R/result.R
Expand Up @@ -2,9 +2,10 @@
#'
#' a \code{geojob} method for loading data into R from a completed processing request
#'
#' @param .Object a \code{\link{geojob}} object with a successful processID.
#' @param .Object a \code{\link{geojob}} object with a successful processID,
#' or a \code{character} URL of a completed job.
#' (See \code{\link{check}}).
#' @param ... additional arguments passed to parsers (e.g., keep.units = TRUE)
#' @param ... additional arguments passed to parsers (e.g., with.units = TRUE)
#' @return data.frame of timeseries values.
#' @rdname result-methods
#' @aliases result
Expand All @@ -18,6 +19,10 @@
#' \dontrun{
#' job <- geoknife(stencil = c(-89,42), fabric = 'prism', wait = TRUE)
#' result(job, with.units = TRUE) # load and print output
#'
#' # or use the job id:
#' id <- id(job)
#' result(id, with.units = TRUE) # load and print output
#' }
#'
setGeneric(name="result",def=function(.Object, ...){standardGeneric("result")})
Expand All @@ -26,48 +31,52 @@ setGeneric(name="result",def=function(.Object, ...){standardGeneric("result")})
#' @aliases result
setMethod(f = "result",signature="geojob",
definition = function(.Object, ...){
result(id(.Object), ...)
})

#' @rdname result-methods
#' @aliases result
setMethod(f = "result",signature="character",
definition = function(.Object, ...){
if (successful(.Object)){
output <- outputParse(.Object, ...)
output <- outputParse(job.id = .Object, ...)
return(output)
} else {
stop('processing is incomplete or has failed. See check(). Processing status: ',
check(.Object)$statusType)
}

}
)

outputParse = function(.Object, ...){
funcInfo <- algorithmParseDetails(.Object)
fileLocation <- check(.Object)$URL
})
outputParse = function(job.id, ...){
funcInfo <- algorithmParseDetails(job.id)
fileLocation <- check(job.id)$URL
output <- do.call(funcInfo[['function.name']], args = list(file = fileLocation, 'delim' = funcInfo[['delimiter']], ...))
return(output)
}

#' @importFrom utils tail
algorithmParseDetails <- function(job){
algorithmParseDetails <- function(job.id){
function.handlers <- list("FeatureWeightedGridStatisticsAlgorithm" = c('function.name'='parseTimeseries'),
"FeatureGridStatisticsAlgorithm" = c('function.name'='parseTimeseries'),
"FeatureCategoricalGridCoverageAlgorithm" = c('function.name'='parseCategorical'))
doc <- xmlParse(xml(job))
algorithm <- xmlValue(getNodeSet(doc,"/wps:Execute/ows:Identifier")[[1]])
xmlProcess <- gcontent(gGET(job.id))
algorithm <- xmlValue(getNodeSet(xmlProcess,"/wps:ExecuteResponse/wps:Process/ows:Identifier")[[1]])

algorithm.name <- tail(strsplit(algorithm, '[.]')[[1]], 1)
rm(doc) # is this necessary w/ XML package?

if (!algorithm.name %in% names(function.handlers)){
stop('parser for ',algorithm.name,
' not currently supported. Create an issue to suggest it: https://github.com/USGS-R/geoknife/issues/new', call. = FALSE)
}
parse.details <- c(function.handlers[[algorithm.name]], 'delimiter'=outputDelimiter(job))
parse.details <- c(function.handlers[[algorithm.name]], 'delimiter'=outputDelimiter(job.id))
return(parse.details)
}

outputDelimiter <- function(job){
outputDelimiter <- function(job.id){
delimiters <- c("text/tab-separated-values" = '\t',
"text/csv" = ',',
'text/plain' = ' ')
# find output type
resp <- rawToChar(GET(id(job))$content)
resp <- rawToChar(GET(job.id)$content)
doc <- htmlParse(resp, useInternalNodes = TRUE)
type <- xmlGetAttr(getNodeSet(doc,"//reference[@mimetype]")[[1]],'mimetype')
if (!type %in% names(delimiters)){
Expand Down
27 changes: 18 additions & 9 deletions R/successful.R
Expand Up @@ -35,48 +35,57 @@ setGeneric(name="successful",def=function(.Object, retry){standardGeneric("succe
#'@rdname successful-methods
#'@aliases successful
setMethod(f = "successful",signature(.Object = "geojob"), definition = function(.Object, retry = FALSE){

successful(id(.Object))
})
#'@rdname successful-methods
#'@aliases successful
setMethod(f = "successful",signature(.Object = "character"), definition = function(.Object, retry = FALSE){
process = check(.Object)
if (process$status == 'unknown' && retry){
Sys.sleep(gconfig('sleep.time'))
process = check(.Object)
}

return(process$statusType == "ProcessSucceeded")


return(process$statusType == "ProcessSucceeded")
})


#'@export
setGeneric(name="running",def=function(.Object, retry){standardGeneric("running")})

#'@rdname successful-methods
#'@aliases running
setMethod(f = "running",signature(.Object = "geojob"), definition = function(.Object, retry = FALSE){
running(id(.Object))
})
#'@rdname successful-methods
#'@aliases running
setMethod(f = "running",signature(.Object = "character"), definition = function(.Object, retry = FALSE){

process = check(.Object)
if (process$status == 'unknown' && retry){
Sys.sleep(gconfig('sleep.time'))
process = check(.Object)
}

return(process$statusType == "ProcessStarted" | process$statusType == "ProcessAccepted")
})


#'@export
setGeneric(name="error",def=function(.Object, retry){standardGeneric("error")})

#'@rdname successful-methods
#'@aliases error
setMethod(f = "error",signature = "geojob", definition = function(.Object, retry = FALSE){
error(id(.Object))
})

#'@rdname successful-methods
#'@aliases error
setMethod(f = "error",signature = "character", definition = function(.Object, retry = FALSE){

process = check(.Object)
if (process$status == 'unknown' && retry){
Sys.sleep(gconfig('sleep.time'))
process = check(.Object)
}


return(process$statusType == "ProcessFailed")
})
4 changes: 2 additions & 2 deletions README.md
@@ -1,4 +1,4 @@
`geoknife` package version 1.5.0
`geoknife` package version 1.5.2
================================

[![Build status](https://ci.appveyor.com/api/projects/status/0iacmg82mp50426o/branch/master)](https://ci.appveyor.com/project/jread-usgs/geoknife/branch/master) [![Build Status](https://travis-ci.org/USGS-R/geoknife.svg)](https://travis-ci.org/USGS-R/geoknife) [![Coverage Status](https://coveralls.io/repos/USGS-R/geoknife/badge.svg)](https://coveralls.io/r/USGS-R/geoknife) [![Download Count](http://cranlogs.r-pkg.org/badges/geoknife)](https://cran.r-project.org/package=geoknife)
Expand Down Expand Up @@ -87,7 +87,7 @@ check(job)
## [1] "Process successful"
##
## $URL
## [1] "https://cida.usgs.gov:443/gdp/process/RetrieveResultServlet?id=056d8e89-6d18-418f-b62c-af76ded6b83dOUTPUT"
## [1] "https://cida.usgs.gov:443/gdp/process/RetrieveResultServlet?id=289eb8f9-858a-4234-b19c-cf0d6a6ba505OUTPUT"
##
## $statusType
## [1] "ProcessSucceeded"
Expand Down
2 changes: 1 addition & 1 deletion cran-comments.md
@@ -1,5 +1,5 @@
## Resubmission
This is a resubmission. In this version I have:

* removed a test that used a service that now requires authentication (Errors on CRAN checks were the result of these service changes)
* added the ability to download, check, and load results based on job id (in addition to the geojob object)

11 changes: 3 additions & 8 deletions inst/doc/geoknife.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions inst/doc/plot_geotiff.html

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions inst/extdata/completed_request.xml
@@ -0,0 +1,102 @@
<wps:ExecuteResponse xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" statusLocation="https://cida.usgs.gov:443/gdp/process/RetrieveResultServlet?id=e0577fe5-2690-4140-8e95-7be4fa7ebec7">
<wps:Process>
<ows:Identifier>
gov.usgs.cida.gdp.wps.algorithm.FeatureWeightedGridStatisticsAlgorithm
</ows:Identifier>
<ows:Title>Area Grid Statistics (weighted)</ows:Title>
</wps:Process>
<wps:Status creationTime="2017-03-03T07:51:54.155-06:00">
<wps:ProcessSucceeded>Process successful</wps:ProcessSucceeded>
</wps:Status>
<wps:DataInputs>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>TIME_START</ows:Identifier>
<wps:Data>
<wps:LiteralData>1895-01-01T00:00:00.000Z</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>TIME_END</ows:Identifier>
<wps:Data>
<wps:LiteralData>1899-01-01T00:00:00.000Z</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>SUMMARIZE_TIMESTEP</ows:Identifier>
<wps:Data>
<wps:LiteralData>false</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>SUMMARIZE_FEATURE_ATTRIBUTE</ows:Identifier>
<wps:Data>
<wps:LiteralData>false</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>DATASET_URI</ows:Identifier>
<wps:Data>
<wps:LiteralData>dods://cida.usgs.gov/thredds/dodsC/prism_v2</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>REQUIRE_FULL_COVERAGE</ows:Identifier>
<wps:Data>
<wps:LiteralData>true</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>STATISTICS</ows:Identifier>
<wps:Data>
<wps:LiteralData>MEAN</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>GROUP_BY</ows:Identifier>
<wps:Data>
<wps:LiteralData>STATISTIC</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>FEATURE_ATTRIBUTE_NAME</ows:Identifier>
<wps:Data>
<wps:LiteralData>STATE</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>DELIMITER</ows:Identifier>
<wps:Data>
<wps:LiteralData>COMMA</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>DATASET_ID</ows:Identifier>
<wps:Data>
<wps:LiteralData>ppt</wps:LiteralData>
</wps:Data>
</wps:Input>
<wps:Input xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink">
<ows:Identifier>FEATURE_COLLECTION</ows:Identifier>
<wps:Reference xlink:href="https://cida.usgs.gov/gdp/geoserver/wfs">
<wps:Body>
<wfs:GetFeature xmlns:gml="http://www.opengis.net/gml" xmlns:wfs="http://www.opengis.net/wfs" outputFormat="text/xml; subtype=gml/3.1.1" service="WFS" version="1.1.0">
<wfs:Query typeName="sample:CONUS_states">
<wfs:PropertyName>the_geom</wfs:PropertyName>
<wfs:PropertyName>STATE</wfs:PropertyName>
<ogc:Filter>
<ogc:GmlObjectId gml:id="CONUS_states.48"/>
</ogc:Filter>
</wfs:Query>
</wfs:GetFeature>
</wps:Body>
</wps:Reference>
</wps:Input>
</wps:DataInputs>
<wps:ProcessOutputs>
<wps:Output>
<ows:Identifier>OUTPUT</ows:Identifier>
<ows:Title>Output File</ows:Title>
<wps:Reference mimeType="text/csv" href="https://cida.usgs.gov:443/gdp/process/RetrieveResultServlet?id=e0577fe5-2690-4140-8e95-7be4fa7ebec7OUTPUT"/>
</wps:Output>
</wps:ProcessOutputs>
</wps:ExecuteResponse>
6 changes: 5 additions & 1 deletion man/check-geojob.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.