Open-EO / openeo-r-client

R client package for working with openEO backends
https://open-eo.github.io/openeo-r-client
Apache License 2.0
61 stars 17 forks source link

proposal: add Math and Ops generics for ProcessNode #141

Open edzer opened 1 year ago

edzer commented 1 year ago

To take a sin of a datacube, we now need p$sin(dc), rather than sin(dc).We can get this with

Math.ProcessNode = function(x, ..., p = openeo::processes()) {
  if (!.Generic %in% names(p))
    stop(paste(.Generic, "is not an available process")
  p$[[.Generic]](x)
}

this would unlock the whole Math group, see ?Math:

            • ‘abs’, ‘sign’, ‘sqrt’,
              ‘floor’, ‘ceiling’, ‘trunc’,
              ‘round’, ‘signif’

            • ‘exp’, ‘log’, ‘expm1’, ‘log1p’,
              ‘cos’, ‘sin’, ‘tan’,
              ‘cospi’, ‘sinpi’, ‘tanpi’,
              ‘acos’, ‘asin’, ‘atan’

              ‘cosh’, ‘sinh’, ‘tanh’,
              ‘acosh’, ‘asinh’, ‘atanh’

            • ‘lgamma’, ‘gamma’, ‘digamma’, ‘trigamma’

            • ‘cumsum’, ‘cumprod’, ‘cummax’, ‘cummin’

The Ops group,

            • ‘"+"’, ‘"-"’, ‘"*"’, ‘"/"’, ‘"^"’, ‘"%%"’, ‘"%/%"’

            • ‘"&"’, ‘"|"’, ‘"!"’

            • ‘"=="’, ‘"!="’, ‘"<"’, ‘"<="’, ‘">="’, ‘">"’

could be implemented similarly, but needs a translation from the operator to the process:

get_fn = function(op) {
  tbl = data.frame(sym = c("==", "!=", "<", ">", "<=", ">="), fn = c("eq", "neq", "lt", "gt", "lte", "gte")) # etc...
  fn = tbl[match(x, tbl$sym),]$fn
  if (is.na(fn))
    stop(paste(op, "not available as operator"))
  fn
}
Ops.ProcessNode = function(e1, e2) {
  p = openeo::processes() # can't pass as parameter here
  fn = get_fn(.Generic)
  if (!fn %in% names(p))
    stop(paste(.Generic, "not available as a process")
  p[[fn]](e1, e1)
}

Which would give us the ability to write things like sin(3 * dc1 / dc2) and so on.

I discussed with @hurielreichel today to do this in tidyopeneo, but I don't see why it doesn't fit (also?) here?

flahn commented 1 year ago

Those are actually implemented to a large amount: https://github.com/Open-EO/openeo-r-client/blob/master/R/ops.R

edzer commented 1 year ago

Wow, I didn't know you could do it that way. Nevertheless, an opportunity to get rid of like 800 l.o.c.?