| Next changeset 1:099d42f5804c (2024-05-06) |
|
Commit message:
planemo upload for repository https://github.com/galaxyecology/tools-ecology/tree/master/tools/ogc_api_processes_wrapper commit 4089d69de9c54df0930f55572e95bf3d22bf5e70 |
|
added:
macros.xml ogc_api_processes_wrapper.R test-data/otb_band_math_test_input.txt test-data/otb_mean_shift_smoothing_test_input.txt zoo_project_ogc_api_processes.xml |
| b |
| diff -r 000000000000 -r f6288dd4b77a macros.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/macros.xml Sat May 04 08:42:42 2024 +0000 |
| b |
| @@ -0,0 +1,60 @@ +<macros> + <xml name="requirements"> + <requirements> + <requirement type="package" version="4.3.1">r-base</requirement> + <requirement type="package" version="1.20.4">r-getopt</requirement> + <requirement type="package" version="0.2.3">r-httr2</requirement> + <requirement type="package" version="1.8.7">r-jsonlite</requirement> + </requirements> + </xml> + <xml name="out_options"> + <option value="uint8">uint8</option> + <option value="uint16">uint16</option> + <option value="int16">int16</option> + <option value="int32">int32</option> + <option value="float">float</option> + <option value="double">double</option> + </xml> + <xml name="format_options"> + <option value="image/tiff">image/tiff</option> + <option value="image/jpeg">image/jpeg</option> + <option value="image/png">image/png</option> + </xml> + <xml name="citations"> + <citations> + <citation type="bibtex">@Manual{httr2, title = {httr2: Perform HTTP Requests and Process the Responses}, author = {Hadley Wickham}, year = {2023}, note = {R package version 1.0.0, https://github.com/r-lib/httr2}, url = {https://httr2.r-lib.org},}</citation> + <citation type="doi">10.48550/arXiv.1403.2805</citation> + </citations> + </xml> + <xml name="help"> + <help>This tool is a wrapper for OGC API Processes coming from the Zoo Project (https://zoo-project.github.io/docs/intro.html) and was created using the OGC-API-Process2Galaxy tool (https://github.com/AquaINFRA/OGC-API-Process2Galaxy). Check the README in the repository for more information.</help> + </xml> + <xml name="tests"> + <tests> + <test> + <param name="select_process" value="OTB.BandMath"/> + <param name="il" value="otb_band_math_test_input.txt"/> + <param name="out" value="float"/> + <param name="ram" value="256"/> + <param name="exp" value="im1b3,im1b2,im1b1"/> + <param name="out_outformat" value="image/png"/> + <output_collection name="output_data" type="list" count="2"/> + </test> + <test> + <param name="select_process" value="OTB.MeanShiftSmoothing"/> + <param name="in" value="otb_mean_shift_smoothing_test_input.txt"/> + <param name="fout" value="float"/> + <param name="foutpos" value="float"/> + <param name="spatialr" value="5"/> + <param name="ranger" value="15"/> + <param name="thres" value="0.1"/> + <param name="maxiter" value="100"/> + <param name="rangeramp" value="0"/> + <param name="modesearch" value="False"/> + <param name="fout_outformat" value="image/png"/> + <param name="foutpos_outformat" value="image/png"/> + <output_collection name="output_data" type="list" count="2"/> + </test> + </tests> + </xml> +</macros> |
| b |
| diff -r 000000000000 -r f6288dd4b77a ogc_api_processes_wrapper.R --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ogc_api_processes_wrapper.R Sat May 04 08:42:42 2024 +0000 |
| [ |
| @@ -0,0 +1,170 @@ +library("httr2") +library("jsonlite") +library("getopt") + +cat("start generic wrapper service \n") + +getParameters <- function(){ + args <- commandArgs(trailingOnly = TRUE) + con <- file("inputs.json", "r") + line <- readLines(con, n = 1) + json <- fromJSON(line) + close(con) + return(json$conditional_process) +} + +parseResponseBody <- function(body) { + hex <- c(body) + intValues <- as.integer(hex) + rawVector <- as.raw(intValues) + readableOutput <- rawToChar(rawVector) + jsonObject <- jsonlite::fromJSON(readableOutput) + return(jsonObject) +} + +getOutputs <- function(inputs, output, server) { + url <- paste(paste(server, "/processes/", sep = ""), inputs$select_process, sep = "") + request <- request(url) + response <- req_perform(request) + responseBody <- parseResponseBody(response$body) + outputs <- list() + + for (x in 1:length(responseBody$outputs)) { + outputformatName <- paste(names(responseBody$outputs[x]), "_outformat", sep="") + output_item <- list() + + for (p in names(inputs)) { + if(p == outputformatName){ + format <- list("mediaType" = inputs[[outputformatName]]) + output_item$format <- format + } + } + output_item$transmissionMode <- "reference" + outputs[[x]] <- output_item + } + + names(outputs) <- names(responseBody$outputs) + return(outputs) +} + +executeProcess <- function(url, process, requestBodyData, output) { + url <- paste(paste(paste(url, "processes/", sep = ""), process, sep = ""), "/execution", sep = "") + response <- request(url) %>% + req_headers( + "accept" = "/*", + "Prefer" = "respond-async;return=representation", + "Content-Type" = "application/json" + ) %>% + req_body_json(requestBodyData) %>% + req_perform() + + cat("\n Process executed") + cat("\n status: ", response$status_code) + cat("\n jobID: ", parseResponseBody(response$body)$jobID, "\n") + + jobID <- parseResponseBody(response$body)$jobID + + return(jobID) +} + +checkJobStatus <- function(server, jobID) { + response <- request(paste0(server, "jobs/", jobID)) %>% + req_headers( + 'accept' = 'application/json' + ) %>% + req_perform() + jobStatus <- parseResponseBody(response$body)$status + jobProgress <- parseResponseBody(response$body)$progress + cat(paste0("\n status: ", jobStatus, ", progress: ", jobProgress)) + return(jobStatus) +} + +getStatusCode <- function(server, jobID) { + url <- paste0(server, "jobs/", jobID) + response <- request(url) %>% + req_headers( + 'accept' = 'application/json' + ) %>% + req_perform() + return(response$status_code) +} + +getResult <- function (server, jobID) { + response <- request(paste0(server, "jobs/", jobID, "/results")) %>% + req_headers( + 'accept' = 'application/json' + ) %>% + req_perform() + return(response) +} + +retrieveResults <- function(server, jobID, outputData) { + status_code <- getStatusCode(server, jobID) + if(status_code == 200){ + status <- "running" + cat(status) + while(status == "running"){ + jobStatus <- checkJobStatus(server, jobID) + if (jobStatus == "successful") { + status <- jobStatus + result <- getResult(server, jobID) + if (result$status_code == 200) { + resultBody <- parseResponseBody(result$body) + urls <- unname(unlist(lapply(resultBody, function(x) x$href))) + urls_with_newline <- paste(urls, collapse = "\n") + sink(paste0(outputData, "_result_urls.txt")) + cat(urls_with_newline, "\n") + sink() + } + } else if (jobStatus == "failed") { + status <- jobStatus + } + Sys.sleep(3) + } + cat("\n done \n") + } else if (status_code1 == 400) { + print("A query parameter has an invalid value.") + } else if (status_code1 == 404) { + print("The requested URI was not found.") + } else if (status_code1 == 500) { + print("The requested URI was not found.") + } else { + print(paste("HTTP", status_code1, "Error:", resp1$status_message)) + } +} + +is_url <- function(x) { + grepl("^https?://", x) +} + +server <- "https://ospd.geolabs.fr:8300/ogc-api/" + +inputParameters <- getParameters() + +outputLocation <- inputParameters$outputData + +outputs <- getOutputs(inputParameters, outputLocation, server) + +for (key in names(inputParameters)) { + print(inputParameters[[key]]) + if (is.character(inputParameters[[key]]) && (endsWith(inputParameters[[key]], ".dat") || endsWith(inputParameters[[key]], ".txt"))) { + con <- file(inputParameters[[key]], "r") + url_list <- list() + while (length(line <- readLines(con, n = 1)) > 0) { + if (is_url(line)) { + url_list <- c(url_list, list(list(href = trimws(line)))) + } + } + close(con) + inputParameters[[key]] <- url_list + } +} + +jsonData <- list( + "inputs" = inputParameters, + "outputs" = outputs +) + +jobID <- executeProcess(server, inputParameters$select_process, jsonData, outputLocation) + +retrieveResults(server, jobID, outputLocation) \ No newline at end of file |
| b |
| diff -r 000000000000 -r f6288dd4b77a test-data/otb_band_math_test_input.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/otb_band_math_test_input.txt Sat May 04 08:42:42 2024 +0000 |
| b |
| @@ -0,0 +1,1 @@ +https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/31/U/ET/2019/4/S2B_31UET_20190421_0_L2A/TCI.tif |
| b |
| diff -r 000000000000 -r f6288dd4b77a test-data/otb_mean_shift_smoothing_test_input.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/otb_mean_shift_smoothing_test_input.txt Sat May 04 08:42:42 2024 +0000 |
| b |
| @@ -0,0 +1,1 @@ +https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/31/U/ET/2019/4/S2B_31UET_20190421_0_L2A/TCI.tif |
| b |
| diff -r 000000000000 -r f6288dd4b77a zoo_project_ogc_api_processes.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zoo_project_ogc_api_processes.xml Sat May 04 08:42:42 2024 +0000 |
| [ |
| b'@@ -0,0 +1,18173 @@\n+<tool id="zoo_project_ogc_api_processes" name="Zoo Project OGC API Processes" version="0.1.0" profile="22.05" >\n+\t<description>executes remote processes</description>\n+\t<macros>\n+\t\t<import>macros.xml</import>\n+\t</macros>\n+\t<expand macro="requirements"/>\n+\t<command detect_errors="exit_code"><![CDATA[\n+\tRscript \'$__tool_directory__/ogc_api_processes_wrapper.R\'\n+\t\t--outputData \'$output_data\'\n+]]></command>\n+\t<configfiles>\n+\t\t<inputs name="inputs" filename="inputs.json" data_style="paths"/>\n+\t</configfiles>\n+\t<inputs>\n+\t\t<conditional name="conditional_process">\n+\t\t\t<param name="select_process" type="select" label="Select process">\n+\t\t\t\t<option value="RVoronoi">RVoronoi: Voronoi Diagram. </option>\n+\t\t\t\t<option value="OTB.MorphologicalMultiScaleDecomposition">OTB.MorphologicalMultiScaleDecomposition: Perform a geodesic morphology based image analysis on an input image channel</option>\n+\t\t\t\t<option value="OTB.Convert">OTB.Convert: Convert an image to a different format, optionally rescaling the data and/or changing the pixel type.</option>\n+\t\t\t\t<option value="OTB.PredictRegression">OTB.PredictRegression: Performs a prediction of the input image according to a regression model file.</option>\n+\t\t\t\t<option value="OTB.SARPolarMatrixConvert">OTB.SARPolarMatrixConvert: This applications allows converting classical polarimetric matrices to each other.</option>\n+\t\t\t\t<option value="OTB.ImageClassifier">OTB.ImageClassifier: Performs a classification of the input image according to a model file.</option>\n+\t\t\t\t<option value="OTB.ManageNoData">OTB.ManageNoData: Manage No-Data</option>\n+\t\t\t\t<option value="OTB.SFSTextureExtraction">OTB.SFSTextureExtraction: Computes Structural Feature Set textures on every pixel of the input image selected channel</option>\n+\t\t\t\t<option value="OTB.VectorDataExtractROI">OTB.VectorDataExtractROI: Perform an extract ROI on the input vector data according to the input image extent</option>\n+\t\t\t\t<option value="OTB.HyperspectralUnmixing">OTB.HyperspectralUnmixing: Estimate abundance maps from an hyperspectral image and a set of endmembers.</option>\n+\t\t\t\t<option value="OTB.HooverCompareSegmentation">OTB.HooverCompareSegmentation: Compare two segmentations with Hoover metrics</option>\n+\t\t\t\t<option value="OTB.ComputeConfusionMatrix">OTB.ComputeConfusionMatrix: Computes the confusion matrix of a classification</option>\n+\t\t\t\t<option value="OTB.ConcatenateImages">OTB.ConcatenateImages: Concatenate a list of images of the same size into a single multi-channel one.</option>\n+\t\t\t\t<option value="OTB.SampleAugmentation">OTB.SampleAugmentation: Generates synthetic samples from a sample data file.</option>\n+\t\t\t\t<option value="OTB.HaralickTextureExtraction">OTB.HaralickTextureExtraction: Computes Haralick textural features on the selected channel of the input image</option>\n+\t\t\t\t<option value="OTB.ConvertSensorToGeoPoint">OTB.ConvertSensorToGeoPoint: Sensor to geographic coordinates conversion.</option>\n+\t\t\t\t<option value="OTB.DSFuzzyModelEstimation">OTB.DSFuzzyModelEstimation: Estimate feature fuzzy model parameters using 2 vector data (ground truth samples and wrong samples).</option>\n+\t\t\t\t<option value="OTB.OrthoRectification">OTB.OrthoRectification: This application allows ortho-rectifying optical and radar images from supported sensors.</option>\n+\t\t\t\t<option value="OTB.BinaryMorphologicalOperation">OTB.BinaryMorphologicalOperation: Performs morphological operations on an input image channel</option>\n+\t\t\t\t<option value="OTB.BlockMatching">OTB.BlockMatching: Performs block-matching to estimate pixel-wise disparities between two images.</option>\n+\t\t\t\t<option value="OTB.KmzExport">OTB.KmzExport: Export the input image in a KMZ product.</option>\n+\t\t\t\t<option value="OTB.ConnectedComponentSegmentation">OTB.ConnectedComponentSegmentation: Connected component segmentation and object based image filtering of the input image according to user-defined criterions.</option>\n+\t\t\t\t<option value="OTB.TrainImagesClassifier">OT'..b'txt"/>\n+\t\t\t\t<param name="InputEntity2" label="InputEntity2" optional="false" help="the other geometry." type="data" format="txt"/>\n+\t\t\t</when>\n+\t\t\t<when value="SymDifference">\n+\t\t\t\t<param name="InputEntity1" label="InputEntity1" optional="false" help="the first geometry to compare against." type="data" format="txt"/>\n+\t\t\t\t<param name="InputEntity2" label="InputEntity2" optional="false" help="the other geometry to compare against." type="data" format="txt"/>\n+\t\t\t\t<param type="select" name="Result_outformat" label="Result_outformat" help="Output format">\n+\t\t\t\t\t<option value="text/xml">text/xml</option>\n+\t\t\t\t\t<option value="application/json">application/json</option>\n+\t\t\t\t</param>\n+\t\t\t</when>\n+\t\t\t<when value="Distance">\n+\t\t\t\t<param name="InputEntity1" label="InputEntity1" optional="false" help="the first geometry to compare against." type="data" format="txt"/>\n+\t\t\t\t<param name="InputEntity2" label="InputEntity2" optional="false" help="the other geometry to compare against." type="data" format="txt"/>\n+\t\t\t</when>\n+\t\t\t<when value="Boundary">\n+\t\t\t\t<param name="InputPolygon" label="InputPolygon" optional="false" help="URI to a set of GML that describes the polygon." type="data" format="txt"/>\n+\t\t\t\t<param type="select" name="Result_outformat" label="Result_outformat" help="Output format">\n+\t\t\t\t\t<option value="text/xml">text/xml</option>\n+\t\t\t\t\t<option value="application/json">application/json</option>\n+\t\t\t\t</param>\n+\t\t\t</when>\n+\t\t\t<when value="Gdal_Warp">\n+\t\t\t\t<param name="Format" label="Format" optional="true" value="GTiff" help="Select the output format by usig short name of the format (use gda-config --formats for list of available formats on your platform)." type="text"/>\n+\t\t\t\t<param name="InputDSN" label="InputDSN" optional="false" help="The input data source name to use as source for convertion." type="text"/>\n+\t\t\t\t<param name="OutputDSN" label="OutputDSN" optional="false" help="The output data source name to use as source for convertion." type="text"/>\n+\t\t\t\t<param name="s_srs" label="s_srs" optional="true" help="The coordinate systems that can be passed are anything supported by the OGRSpatialReference.SetFromUserInput() call, which includes EPSG PCS and GCSes (ie. EPSG:4296), PROJ.4 declarations (as above), or the name of a .prf file containing well known text." type="text"/>\n+\t\t\t\t<param name="t_srs" label="t_srs" optional="true" help="The coordinate systems that can be passed are anything supported by the OGRSpatialReference.SetFromUserInput() call, which includes EPSG PCS and GCSes (ie. EPSG:4296), PROJ.4 declarations (as above), or the name of a .prf file containing well known text." type="text"/>\n+\t\t\t\t<param name="tps" label="tps" optional="true" help="Force use of thin plate spline transformer based on available GCPs" type="boolean" truevalue="True" falsevalue="False"/>\n+\t\t\t\t<param name="geoloc" label="geoloc" optional="true" help="Force use of Geolocation Arrays" type="boolean" truevalue="True" falsevalue="False"/>\n+\t\t\t\t<param name="rpc" label="rpc" optional="true" help="Force use of RPCs" type="boolean" truevalue="True" falsevalue="False"/>\n+\t\t\t\t<param name="r" label="r" optional="true" help="Available methods are: near (nearest neighbour resampling - default, fastest algorithm, worst interpolation quality), bilinear, cubic, cubicspline, lanczos (Lanczos windowed sinc resampling)" type="boolean" truevalue="True" falsevalue="False"/>\n+\t\t\t\t<param name="order" label="order" optional="true" value="1" help="The default is to select a polynomial order based on the number of GCPs." type="text"/>\n+\t\t\t\t<param name="te" label="te" optional="true" help="set georeferenced extents of output file to be created (in target SRS)." type="text"/>\n+\t\t\t</when>\n+\t\t</conditional>\n+\t</inputs>\n+\t<outputs>\n+\t\t<collection name="output_data" type="list" label="$select_process">\n+\t\t\t<discover_datasets pattern="__name_and_ext__"/>\n+\t\t</collection>\n+\t</outputs>\n+\t<expand macro="tests"/>\n+\t<expand macro="help"/>\n+\t<expand macro="citations"/>\n+</tool>\n' |