changeset 0:6c6e8b16dba6 draft

planemo upload for repository https://github.com/galaxyecology/tools-ecology/tree/master/tools/interpolation commit bd6f07bf29bad450af2e552f2524f23277edfef5-dirty
author ecology
date Wed, 13 Mar 2024 19:12:46 +0000
parents
children dd397752ad21
files OTB_MeanShiftSmoothing.R OTB_MeanShiftSmoothing.xml test-data/otb_mean_shift_smoothing_test_input.txt
diffstat 3 files changed, 303 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OTB_MeanShiftSmoothing.R	Wed Mar 13 19:12:46 2024 +0000
@@ -0,0 +1,187 @@
+# Run with Rscript ./OTB_MeanShiftSmoothing.R
+#--file otb_band_math_test_input.txt
+#--fOut float --fOutpos float --processingMemory 1024 --spatialR 5 --rangeR 15
+#--thresHold 0.1 --maxIter 100 --rangeRamp 0 --modeSearch False
+#--outputType png
+#--outputFormat download --outputData test1.png
+
+library("httr2")
+library("jsonlite")
+library("getopt")
+
+args <- commandArgs(trailingOnly = TRUE)
+option_specification <- matrix(c(
+  "file", "i1", 1, "character",
+  "fOut", "i2", 1, "character",
+  "fOutpos", "i3", 1, "character",
+  "processingMemory", "i4", 1, "integer",
+  "spatialR", "i5", 2, "integer",
+  "rangeR", "i6", 2, "double",
+  "thresHold", "i7", 2, "double",
+  "maxIter", "i8", 2, "integer",
+  "rangeRamp", "i9", 2, "double",
+  "modeSearch", "i10", 1, "character",
+  "outputType", "i11", 1, "character",
+  "outputFormat", "i12", 1, "character",
+  "outputData", "o", 1, "character"
+), byrow = TRUE, ncol = 4)
+options <- getopt(option_specification)
+
+file <- options$file
+fout <- options$fOut
+foutpos <- options$fOutpos
+processing_memory <- options$processingMemory
+spatialr <- options$spatialR
+ranger <- options$rangeR
+threshold <- options$thresHold
+maxiter <- options$maxIter
+rangeramp <- options$rangeRamp
+modesearch <- options$modeSearch
+output_type <- paste0("image/", options$outputType)
+output_format <- options$outputFormat
+output_data <- options$outputData
+
+cat("\n file: ", file)
+cat("\n fout: ", fout)
+cat("\n foutpos: ", foutpos)
+cat("\n processing_memory: ", processing_memory)
+cat("\n spatialr: ", spatialr)
+cat("\n ranger: ", ranger)
+cat("\n threshold: ", threshold)
+cat("\n maxiter: ", maxiter)
+cat("\n rangeramp: ", rangeramp)
+cat("\n modesearch: ", modesearch)
+cat("\n output_type: ", output_type)
+cat("\n output_format: ", output_format)
+
+base_url <- "https://ospd.geolabs.fr:8300/ogc-api/"
+execute <- "processes/OTB.MeanShiftSmoothing/execution"
+get_status <- "jobs/"
+get_result <- "/results"
+
+file_urls <- readLines(file, warn = FALSE)
+
+il_list <- lapply(file_urls, function(url) {
+  list("href" = url)
+})
+
+json_data <- list(
+  "inputs" = list(
+    "in" = il_list,
+    "fout" = fout,
+    "foutpos" = foutpos,
+    "ram" = processing_memory,
+    "spatialr" = spatialr,
+    "ranger" = ranger,
+    "thres" = threshold,
+    "maxiter" = maxiter,
+    "rangeramp" = rangeramp,
+    "modesearch" = modesearch
+  ),
+  "outputs" = list(
+    "fout" = list(
+      "format" = list(
+        "mediaType" = output_type
+      ),
+      "transmissionMode" = "reference"
+    ),
+    "foutpos" = list(
+      "format" = list(
+        "mediaType" = output_type
+      ),
+      "transmissionMode" = "reference"
+    )
+  )
+)
+
+make_response_body_readable <- function(body) {
+  hex <- c(body)
+  int_values <- as.integer(hex)
+  raw_vector <- as.raw(int_values)
+  readable_output <- rawToChar(raw_vector)
+  json_object <- jsonlite::fromJSON(readable_output)
+  return(json_object)
+}
+
+tryCatch({
+  # Request 1
+  resp1 <- request(paste0(base_url, execute)) %>%
+    req_headers(
+      "accept" = "/*",
+      "Prefer" = "respond-async;return=representation",
+      "Content-Type" = "application/json"
+    ) %>%
+    req_body_json(json_data) %>%
+    req_perform()
+  response <- make_response_body_readable(resp1$body)
+  status_code1 <- resp1$status_code
+  if (status_code1 == 201) {
+    status <- "running"
+    attempt <- 1
+    while (status == "running") {
+      # Request 2
+      resp2 <- request(paste0(base_url, get_status, response$jobID)) %>%
+        req_headers(
+          "accept" = "application/json"
+        ) %>%
+        req_perform()
+      status_code2 <- resp2$status_code
+      if (status_code2 == 200) {
+        response2 <- make_response_body_readable(resp2$body)
+        cat("\n", response2$status)
+        if (response2$status == "successful") {
+          status <- "successful"
+          # Request 3
+          resp3 <- request(paste0(
+            base_url,
+            get_status, response2$jobID, get_result
+          )) %>%
+            req_headers(
+              "accept" = "application/json"
+            ) %>%
+            req_perform()
+          status_code3 <- resp3$status_code
+          if (status_code3 == 200) {
+            response3 <- make_response_body_readable(resp3$body)
+            if (output_format == "download") {
+              options(timeout = 600)
+              download.file(response3$fout$href,
+                destfile = paste0("output1.", options$outputType),
+                mode = "wb"
+              )
+              download.file(response3$foutpos$href,
+                destfile = paste0("output2.", options$outputType),
+                mode = "wb"
+              )
+            } else if (output_format == "getUrl") {
+              writeLines(paste(response3$fout$href, response3$foutpos$href,
+                           sep = "\n"
+                         ), con = "output.txt")
+            }
+          } else if (status_code3 == 404) {
+            print("The requested URI was not found.")
+          } else if (status_code3 == 500) {
+            print("A server error occurred.")
+          } else {
+            print(paste("HTTP", status_code3, "Error:", resp3$status_message))
+          }
+        } else if (response2$status == "failed") {
+          status <- "failed"
+        }
+      } else {
+        status <- "failed"
+        print(paste("HTTP", status_code2, "Error:", resp2$status_message))
+      }
+      Sys.sleep(3)
+    }
+    print(status)
+  } 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))
+  }
+})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OTB_MeanShiftSmoothing.xml	Wed Mar 13 19:12:46 2024 +0000
@@ -0,0 +1,115 @@
+<tool id="otb_mean_shift_smoothing" name="OTB.MeanShiftSmoothing" version="1.0" profile="22.05">
+    <description> smooths an image using the MeanShift algorithm</description>
+    <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>
+    <command detect_errors='exit_code'><![CDATA[
+    Rscript '$__tool_directory__/OTB_MeanShiftSmoothing.R'
+        --file '$file'
+        --fOut '$f_out'
+        --fOutpos '$f_outpos'
+        --processingMemory '$processing_memory' 
+        --spatialR '$spatial_r'
+        --rangeR '$range_r'
+        --thresHold '$thres_hold'
+        --maxIter '$max_iter'
+        --rangeRamp '$range_ramp'
+        --modeSearch '$mode_search'
+        --outputType '$output_type' 
+        --outputFormat '$output_format' 
+        --outputData '$output_data'
+]]>
+    </command>
+    <inputs>
+        <param type="data" format="txt" name="file" label="List of images" help="The input image can be any single or multiband image. Beware of potential imbalance between band ranges as it may alter euclidean distance" />
+        <param type="integer" name="processing_memory" label="Random-Access Memory (RAM)" value="256" min="128" max="16384" optional="true" help="Available memory for processing (in MB)" />
+        <param type="integer" name="spatial_r" label="Radius" value="5" min="0" optional="true" help="Radius of the spatial neighborhood for averaging. Higher values will result in more smoothing and higher processing time."/>
+        <param type="float" name="range_r" label="Range" value="15" min="0" optional="true"  help="Threshold on spectral signature euclidean distance (expressed in radiometry unit) to consider neighborhood pixel for averaging. Higher values will be less edge-preserving (more similar to simple average in neighborhood), whereas lower values will result in less noise smoothing. Note that this parameter has no effect on processing time"/>
+        <param type="float" name="thres_hold" label="Threshold" value="0.1" min="0" optional="true"  help="Algorithm will stop if update of average spectral signature and spatial position is below this threshold" />
+        <param type="integer" name="max_iter" label="Maximum iterations" optional="true" value="100" min="1" help="Algorithm will stop if convergence threshold is not met after the maximum number of iterations" />
+        <param type="float" name="range_ramp" label="Range radius" optional="true" value="0" min="0" help="Vary the range radius linearly with the central pixel intensity (experimental)" />
+        <param type="boolean" name="mode_search" label="Search mode" truevalue="True" falsevalue="False" help="If activated pixel iterative convergence is stopped if the path crosses an already converged pixel. Be careful, with this option, the result will slightly depend on thread number and the results will not be stable"/>
+        <param type="select" name="f_out" label="Output image (1)" help="This output image contains the final average spectral signatures of each pixel. The output type should be at least as wide as the input image type. Floating point encoding is advised. This output can be used as input image (in) of the LSMSSegmentation application">
+            <option value="float">float</option>
+            <option value="uint8">uint8</option>
+            <option value="uint16">uint16</option>
+            <option value="int16">int16</option>
+            <option value="int32">int32</option>
+            <option value="double">double</option>
+        </param>
+        <param type="select" name="f_outpos" label="Output image (2)" help="This output image contains the 2D displacement between the input pixel spatial position and the final position after convergence. Floating point encoding is mandatory. This output can be used as input image (in) of the LSMSSegmentation application">
+            <option value="float">float</option>
+            <option value="uint8">uint8</option>
+            <option value="uint16">uint16</option>
+            <option value="int16">int16</option>
+            <option value="int32">int32</option>
+            <option value="double">double</option>
+        </param>
+        <param type="select" name="output_type" label="Output format of the images">
+            <option value="png">.png (for OGC web services)</option>
+            <option value="tiff">.tiff (for workflows)</option>
+            <option value="jpeg">.jpeg (for workflows)</option>
+        </param>
+        <param type="select" name="output_format" label="Do you want to download the result to your Galaxy history or get the URL?">
+            <option value="download">Download</option>
+            <option value="getUrl">Get URL</option>
+        </param>
+    </inputs>
+    <outputs>
+        <collection name="output_data" type="list" label="MeanShiftSmoothing output">
+            <discover_datasets pattern="__name_and_ext__"/>
+        </collection>
+    </outputs>
+    <tests>
+        <test>
+            <param name="file" value="otb_mean_shift_smoothing_test_input.txt"/>
+            <param name="processing_memory" value="256"/>
+            <param name="spatial_r" value="5"/>
+            <param name="range_r" value="15"/>
+            <param name="thres_hold" value="0.1"/>
+            <param name="max_iter" value="100"/>
+            <param name="range_ramp" value="0"/>
+            <param name="mode_search" value="False"/>
+            <param name="f_out" value="float"/>
+            <param name="f_outpos" value="float"/>
+            <param name="output_type" value="png"/>
+            <param name="output_format" value="download"/>
+            <output_collection name="output_data" type="list" count="2" />
+        </test>
+        <test>
+            <param name="file" value="otb_mean_shift_smoothing_test_input.txt"/>
+            <param name="processing_memory" value="256"/>
+            <param name="spatial_r" value="5"/>
+            <param name="range_r" value="15"/>
+            <param name="thres_hold" value="0.1"/>
+            <param name="max_iter" value="100"/>
+            <param name="range_ramp" value="0"/>
+            <param name="mode_search" value="False"/>
+            <param name="f_out" value="float"/>
+            <param name="f_outpos" value="float"/>
+            <param name="output_type" value="png"/>
+            <param name="output_format" value="getUrl"/>
+            <output_collection name="output_data" type="list" count="1" />
+        </test>
+    </tests>
+    <help><![CDATA[
+        OGC API Process documentation: https://ospd.geolabs.fr:8300/ogc-api/processes/OTB.MeanShiftSmoothing.html
+
+        MeanShift [1,2,3] is an iterative edge-preserving image smoothing algorithm often used in image processing and as a first step for image segmentation. The MeanShift algorithm can be applied to multispectral images.At first iteration, for any given pixel of the input image, the filtered value correspond to the average spectral signature of neighborhood pixels that are both spatially closer than the spatial radius parameter (spatialr) and with spectral signature that have an euclidean distance to the input pixel lower than the range radius (ranger), that is, pixels that are both close in space and in spectral signatures. Subsequent iterations will repeat this process by considering that the pixel signature corresponds to the average spectral signature computed during previous iteration, and that the pixel position corresponds to the average position of pixels used to compute the average signature.The algorithm stops when the maximum number of iterations (maxiter) is reached, or when the position and spectral signature does not change much between iterations, according to the convergence threshold (thres). If the modesearch option is used then convergence will also stops if the spatial position reaches a pixel that has already converged. This will speed-up convergence, at the expense of stability of the result.The application outputs the image of the final averaged spectral signatures (fout), and can also optionally output the 2D displacement field between input pixel position and final pixel position after convergence (foutpos).Note that computing an euclidean distance between spectral signatures may be inaccurate and that techniques such as color space transform or image normalisation could be applied before using this application. Also note that most satellite images noise model is not gaussian, since noise variance linearly depends on radiance (the higher the radiance, the higher the noise variance). To account for such noise model, the application provides the range radius ramp option (rangeramp), which will vary the range radius linearly with the central pixel intensity. Default value is 1. (no ramp).This application is the first step of the large scale MeanShift method depicted in [4]. Both outputs (fout and foutpos) can be passed to the large scale MeanShift segmentation application [5]. If the application is used for large scale MeanShift, modesearch option should be off.
+    ]]></help>
+    <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>
+</tool>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/otb_mean_shift_smoothing_test_input.txt	Wed Mar 13 19:12:46 2024 +0000
@@ -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