Skip to content
Snippets Groups Projects
Commit 9a679c28 authored by David Schäfer's avatar David Schäfer
Browse files

renamed generic to flagGeneric to make naming room for a future

generic processinf function
parent e3c449c0
No related branches found
No related tags found
No related merge requests found
...@@ -8,7 +8,7 @@ Generic funtions are used in the same manner as their ...@@ -8,7 +8,7 @@ Generic funtions are used in the same manner as their
[non-generic counterparts](docs/FunctionDescriptions.md). The basic [non-generic counterparts](docs/FunctionDescriptions.md). The basic
signature looks like that: signature looks like that:
```sh ```sh
generic(func=<expression>, flag=<flagging_constant>) flagGeneric(func=<expression>, flag=<flagging_constant>)
``` ```
where `<expression>` is composed of the [supported constructs](#supported-constructs) where `<expression>` is composed of the [supported constructs](#supported-constructs)
and `<flag_constant>` is either one of the predefined and `<flag_constant>` is either one of the predefined
...@@ -24,9 +24,9 @@ Flag all values of variable `x` when variable `y` falls below a certain threasho ...@@ -24,9 +24,9 @@ Flag all values of variable `x` when variable `y` falls below a certain threasho
#### Configuration file #### Configuration file
| varname | test | | varname | test |
|---------|-----------------------| |---------|---------------------------|
| `x` | `generic(func=y < 0)` | | `x` | `flagGeneric(func=y < 0)` |
### Calculations ### Calculations
...@@ -35,9 +35,9 @@ Flag all values of variable `x` that exceed 3 standard deviations of variable `y ...@@ -35,9 +35,9 @@ Flag all values of variable `x` that exceed 3 standard deviations of variable `y
#### Configuration file #### Configuration file
| varname | test | | varname | test |
|---------|-----------------------------------| |---------|---------------------------------------|
| `x` | `generic(func=this > std(y) * 3)` | | `x` | `flagGeneric(func=this > std(y) * 3)` |
### Special functions ### Special functions
...@@ -46,9 +46,9 @@ Flag variable `x` where variable `y` is flagged and variable `x` has missing val ...@@ -46,9 +46,9 @@ Flag variable `x` where variable `y` is flagged and variable `x` has missing val
#### Configuration file #### Configuration file
| varname | test | | varname | test |
|---------|---------------------------------------------------| |---------|-------------------------------------------------------|
| `x` | `generic(func=this > isflagged(y) & ismissing(z)` | | `x` | `flagGeneric(func=this > isflagged(y) & ismissing(z)` |
## Variable References ## Variable References
...@@ -57,9 +57,9 @@ arbitrary cross references are possible. The variable of intereset ...@@ -57,9 +57,9 @@ arbitrary cross references are possible. The variable of intereset
is furthermore available with the special reference `this`, so the second is furthermore available with the special reference `this`, so the second
[example](#calculations) could be rewritten as: [example](#calculations) could be rewritten as:
| varname | test | | varname | test |
|---------|--------------------------------| |---------|------------------------------------|
| `x` | `generic(func=x > std(y) * 3)` | | `x` | `flagGeneric(func=x > std(y) * 3)` |
When referencing other variables, their flags will be respected during evaluation When referencing other variables, their flags will be respected during evaluation
of the generic expression. So, in the example above only previously of the generic expression. So, in the example above only previously
......
...@@ -179,7 +179,7 @@ series. Also, you can write your own tests using a python-based ...@@ -179,7 +179,7 @@ series. Also, you can write your own tests using a python-based
varname;test;plot varname;test;plot
SM2;harmonize_shift2Grid(freq="15Min");False SM2;harmonize_shift2Grid(freq="15Min");False
SM2;generic(func=(SM2 < 30));True SM2;flagGeneric(func=(SM2 < 30));True
The above executes an internal framework that harmonizes the timestamps of SM2 The above executes an internal framework that harmonizes the timestamps of SM2
to a 15min-grid (see data below). Further information about this routine can be to a 15min-grid (see data below). Further information about this routine can be
......
...@@ -12,5 +12,5 @@ class Fields: ...@@ -12,5 +12,5 @@ class Fields:
class Params: class Params:
GENERIC = "generic" FLAG_GENERIC = "flagGeneric"
FUNC = "func" FUNC = "func"
...@@ -142,7 +142,7 @@ class ConfigTransformer(ast.NodeTransformer): ...@@ -142,7 +142,7 @@ class ConfigTransformer(ast.NodeTransformer):
def visit_keyword(self, node): def visit_keyword(self, node):
key, value = node.arg, node.value key, value = node.arg, node.value
if self.func_name == Params.GENERIC and key == Params.FUNC: if self.func_name == Params.FLAG_GENERIC and key == Params.FUNC:
node = ast.keyword(arg=key, value=self.dsl_transformer.visit(value)) node = ast.keyword(arg=key, value=self.dsl_transformer.visit(value))
return node return node
...@@ -159,8 +159,6 @@ class ConfigTransformer(ast.NodeTransformer): ...@@ -159,8 +159,6 @@ class ConfigTransformer(ast.NodeTransformer):
f"unknown variable: {value.id}" f"unknown variable: {value.id}"
) )
return self.generic_visit(node) return self.generic_visit(node)
def generic_visit(self, node): def generic_visit(self, node):
...@@ -200,6 +198,6 @@ def evalExpression(expr, data, field, flagger, nodata=np.nan): ...@@ -200,6 +198,6 @@ def evalExpression(expr, data, field, flagger, nodata=np.nan):
local_env, code = compileExpression(expr, data_in, field, flagger, nodata) local_env, code = compileExpression(expr, data_in, field, flagger, nodata)
data_result, flagger_result = evalCode(code, FUNC_MAP, local_env) data_result, flagger_result = evalCode(code, FUNC_MAP, local_env)
# NOTE: # NOTE:
# reinject the original values, as we don't want to throw away values # reinject the original values, as we don't want to loose them
data_result[mask] = data[mask] data_result[mask] = data[mask]
return data_result, flagger_result return data_result, flagger_result
...@@ -9,7 +9,7 @@ from saqc.lib.tools import sesonalMask, flagWindow ...@@ -9,7 +9,7 @@ from saqc.lib.tools import sesonalMask, flagWindow
from saqc.funcs.register import register from saqc.funcs.register import register
@register("generic") @register("flagGeneric")
def flagGeneric(data, field, flagger, func, **kwargs): def flagGeneric(data, field, flagger, func, **kwargs):
# NOTE: # NOTE:
# - The naming of the func parameter is pretty confusing # - The naming of the func parameter is pretty confusing
......
...@@ -41,7 +41,7 @@ def test_flagPropagation(data, flagger): ...@@ -41,7 +41,7 @@ def test_flagPropagation(data, flagger):
var2_flags = flagger.isFlagged(var2) var2_flags = flagger.isFlagged(var2)
var2_data = data[var2].mask(var2_flags) var2_data = data[var2].mask(var2_flags)
data, flagger_result = evalExpression( data, flagger_result = evalExpression(
"generic(func=var2 < mean(var2))", data, this, flagger, np.nan "flagGeneric(func=var2 < mean(var2))", data, this, flagger, np.nan
) )
expected = var2_flags | (var2_data < var2_data.mean()) expected = var2_flags | (var2_data < var2_data.mean())
...@@ -54,8 +54,8 @@ def test_missingIdentifier(data, flagger): ...@@ -54,8 +54,8 @@ def test_missingIdentifier(data, flagger):
flagger = flagger.initFlags(data) flagger = flagger.initFlags(data)
tests = [ tests = [
"generic(func=fff(var2) < 5)", "flagGeneric(func=fff(var2) < 5)",
"generic(func=var3 != NODATA)" "flagGeneric(func=var3 != NODATA)"
] ]
for expr in tests: for expr in tests:
with pytest.raises(NameError): with pytest.raises(NameError):
...@@ -80,12 +80,37 @@ def test_comparisonOperators(data, flagger): ...@@ -80,12 +80,37 @@ def test_comparisonOperators(data, flagger):
# check within the usually enclosing scope # check within the usually enclosing scope
for expr, mask in tests: for expr, mask in tests:
_, result_flagger = evalExpression( _, result_flagger = evalExpression(
f"generic(func={expr})", data, this, flagger, np.nan f"flagGeneric(func={expr})", data, this, flagger, np.nan
) )
expected_flagger = flagger.setFlags(this, loc=mask, test="generic") expected_flagger = flagger.setFlags(this, loc=mask, test="generic")
assert np.all(result_flagger.isFlagged() == expected_flagger.isFlagged()) assert np.all(result_flagger.isFlagged() == expected_flagger.isFlagged())
# @pytest.mark.parametrize("flagger", TESTFLAGGER)
# def test_arithmeticOperators(data, flagger):
# flagger = flagger.initFlags(data)
# var1, *_ = data.columns
# this = var1
# tests = [
# ("this + 100", data[this] + 100),
# ("this - 100", data[this] - 100),
# ("this * 100", data[this] * 100),
# ("this / 100", data[this] / 100),
# ("this // 2", data[this] // 2),
# ("this % 2", data[this] % 2),
# ("this ** 2", data[this] ** 2),
# ]
# # check within the usually enclosing scope
# for expr, mask in tests:
# _, result_flagger = evalExpression(
# f"flagGeneric(func={expr})", data, this, flagger, np.nan
# )
# # expected_flagger = flagger.setFlags(this, loc=mask, test="generic")
# # assert np.all(result_flagger.isFlagged() == expected_flagger.isFlagged())
@pytest.mark.parametrize("flagger", TESTFLAGGER) @pytest.mark.parametrize("flagger", TESTFLAGGER)
def test_nonReduncingBuiltins(data, flagger): def test_nonReduncingBuiltins(data, flagger):
flagger = flagger.initFlags(data) flagger = flagger.initFlags(data)
...@@ -155,13 +180,13 @@ def test_bitOps(data, flagger, nodata): ...@@ -155,13 +180,13 @@ def test_bitOps(data, flagger, nodata):
flagger = flagger.initFlags(data) flagger = flagger.initFlags(data)
tests = [ tests = [
(f"generic(func=~(this > mean(this)))", ~(data[this] > np.nanmean(data[this]))), (f"flagGeneric(func=~(this > mean(this)))", ~(data[this] > np.nanmean(data[this]))),
( (
f"generic(func=(this <= 0) | (0 < {var1}))", f"flagGeneric(func=(this <= 0) | (0 < {var1}))",
(data[this] <= 0) | (0 < data[var1]), (data[this] <= 0) | (0 < data[var1]),
), ),
( (
f"generic(func=({var2} >= 0) & (0 > this))", f"flagGeneric(func=({var2} >= 0) & (0 > this))",
(data[var2] >= 0) & (0 > data[this]), (data[var2] >= 0) & (0 > data[this]),
), ),
] ]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment