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

t.rast.univar, t.rast3d.univar: Add support for zones #2588

Merged
merged 39 commits into from
Oct 24, 2022
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
6f7574a
add support for zones
ninsbl Sep 20, 2022
255c48e
add support for zones
ninsbl Sep 20, 2022
8d5ea03
add test for zones
ninsbl Sep 20, 2022
7ea547a
clean properly
ninsbl Sep 20, 2022
d0218b5
add test for zones
ninsbl Sep 20, 2022
97a98b9
add support for zones
ninsbl Sep 20, 2022
ac60f47
add credits
ninsbl Sep 20, 2022
757d196
add credits
ninsbl Sep 20, 2022
a8dc0ea
add zones in manual
ninsbl Sep 22, 2022
f2f25c0
add check for zones map
ninsbl Oct 2, 2022
ddfd99b
black
ninsbl Oct 2, 2022
261a412
use RasterRow context manager
ninsbl Oct 2, 2022
5550e61
fix zones existence test
ninsbl Oct 2, 2022
c3bab26
try if centos fails because of context manager
ninsbl Oct 2, 2022
eb2038a
fix indent
ninsbl Oct 2, 2022
965286c
change import order
ninsbl Oct 2, 2022
16c76b3
zones check for t.rast3d.univar
ninsbl Oct 2, 2022
c317781
avoid RasterRow
ninsbl Oct 2, 2022
bfbf890
avoid RasterRow
ninsbl Oct 2, 2022
c30a717
fix if
ninsbl Oct 2, 2022
b9bf39d
fix if
ninsbl Oct 2, 2022
a8e1fb6
fix raster_info
ninsbl Oct 2, 2022
7e7e815
fix raster_info
ninsbl Oct 2, 2022
ba510de
fix raster_info
ninsbl Oct 2, 2022
b917495
fix raster_info
ninsbl Oct 2, 2022
ff28a30
import as gs
ninsbl Oct 6, 2022
10c93c0
import as gs and zones
ninsbl Oct 6, 2022
4ab35d6
string formating
ninsbl Oct 6, 2022
b3ac1f8
clean test
ninsbl Oct 6, 2022
fa99052
add semantic labels
ninsbl Oct 6, 2022
df48260
black
ninsbl Oct 6, 2022
e2a741c
remove gscript
ninsbl Oct 6, 2022
5e8c340
name tests
ninsbl Oct 7, 2022
f6b9729
name tests
ninsbl Oct 7, 2022
5ba0978
move parser, use kwargs
ninsbl Oct 7, 2022
086b431
move parser, use kwargs, allow DCELL
ninsbl Oct 7, 2022
85285da
Import tgis after parser
ninsbl Oct 10, 2022
5705f4d
Import tgis after parser
ninsbl Oct 10, 2022
f01e44c
Fix typo
ninsbl Oct 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 89 additions & 33 deletions python/grass/temporal/univar_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@


def print_gridded_dataset_univar_statistics(
type, input, output, where, extended, no_header=False, fs="|", rast_region=False
type,
input,
output,
where,
extended,
no_header=False,
fs="|",
rast_region=False,
zones=None,
):
"""Print univariate statistics for a space time raster or raster3d dataset

Expand All @@ -43,8 +51,14 @@ def print_gridded_dataset_univar_statistics(
:param rast_region: If set True ignore the current region settings
and use the raster map regions for univar statistical calculation.
Only available for strds.
:param zones: raster map with zones to calculate statistics for
"""

stats_module = {
"strds": "r.univar",
"str3ds": "r3.univar",
}[type]

# We need a database interface
dbif = SQLDatabaseInterfaceConnection()
dbif.connect()
Expand All @@ -54,9 +68,14 @@ def print_gridded_dataset_univar_statistics(
if output is not None:
out_file = open(output, "w")

rows = sp.get_registered_maps("id,start_time,end_time", where, "start_time", dbif)
strds_cols = (
"id,start_time,end_time,semantic_label"
if type == "strds"
else "id,start_time,end_time"
)
rows = sp.get_registered_maps(strds_cols, where, "start_time", dbif)

if not rows:
if not rows and rows != [""]:
dbif.close()
err = "Space time %(sp)s dataset <%(i)s> is empty"
if where:
Expand All @@ -66,40 +85,60 @@ def print_gridded_dataset_univar_statistics(
)

if no_header is False:
string = ""
string += "id" + fs + "start" + fs + "end" + fs + "mean" + fs
string += "min" + fs + "max" + fs
string += "mean_of_abs" + fs + "stddev" + fs + "variance" + fs
string += "coeff_var" + fs + "sum" + fs + "null_cells" + fs + "cells"
string += fs + "non_null_cells"
cols = (
["id", "semantic_label", "start", "end"]
if type == "strds"
else ["id", "start", "end"]
)
if zones:
cols.append("zone")
cols.extend(
[
"mean",
"min",
"max",
"mean_of_abs",
"stddev",
"variance",
"coeff_var",
"sum",
"null_cells",
"cells",
"non_null_cells",
]
)
if extended is True:
string += fs + "first_quartile" + fs + "median" + fs
string += "third_quartile" + fs + "percentile_90"
cols.extend(["first_quartile", "median", "third_quartile", "percentile_90"])
string = fs.join(cols)

if output is None:
print(string)
else:
out_file.write(string + "\n")

flag = "g"

if extended is True:
flag += "e"
if type == "strds" and rast_region is True:
flag += "r"

for row in rows:
string = ""
id = row["id"]
start = row["start_time"]
end = row["end_time"]
semantic_label = (
""
if type != "strds" or not row["semantic_label"]
else row["semantic_label"]
)

flag = "g"

if extended is True:
flag += "e"
if type == "strds" and rast_region is True:
flag += "r"

if type == "strds":
stats = gscript.parse_command("r.univar", map=id, flags=flag)
elif type == "str3ds":
stats = gscript.parse_command("r3.univar", map=id, flags=flag)
univar_stats = gscript.read_command(
stats_module, map=id, flags=flag, zones=zones
).rstrip()

if not stats:
if not univar_stats:
if type == "strds":
gscript.warning(
_("Unable to get statistics for raster map " "<%s>") % id
Expand All @@ -109,19 +148,36 @@ def print_gridded_dataset_univar_statistics(
_("Unable to get statistics for 3d raster map" " <%s>") % id
)
continue
eol = ""

string += str(id) + fs + str(start) + fs + str(end)
string += fs + str(stats["mean"]) + fs + str(stats["min"])
string += fs + str(stats["max"]) + fs + str(stats["mean_of_abs"])
string += fs + str(stats["stddev"]) + fs + str(stats["variance"])
string += fs + str(stats["coeff_var"]) + fs + str(stats["sum"])
string += fs + str(stats["null_cells"]) + fs + str(stats["cells"])
string += fs + str(int(stats["cells"]) - int(stats["null_cells"]))
if extended is True:
string += fs + str(stats["first_quartile"]) + fs + str(stats["median"])
for idx, stats_kv in enumerate(univar_stats.split(";")):
stats = gscript.utils.parse_key_val(stats_kv)
string += (
fs + str(stats["third_quartile"]) + fs + str(stats["percentile_90"])
f"{id}{fs}{semantic_label}{fs}{start}{fs}{end}"
if type == "strds"
else f"{id}{fs}{start}{fs}{end}"
)
if zones:
if idx == 0:
zone = str(stats["zone"])
string = ""
continue
string += f"{fs}{zone}"
if "zone" in stats:
zone = str(stats["zone"])
eol = "\n"
else:
eol = ""
string += f'{fs}{stats["mean"]}{fs}{stats["min"]}'
string += f'{fs}{stats["max"]}{fs}{stats["mean_of_abs"]}'
string += f'{fs}{stats["stddev"]}{fs}{stats["variance"]}'
string += f'{fs}{stats["coeff_var"]}{fs}{stats["sum"]}'
string += f'{fs}{stats["null_cells"]}{fs}{stats["n"]}'
string += f'{fs}{stats["n"]}'
if extended is True:
string += f'{fs}{stats["first_quartile"]}{fs}{stats["median"]}'
string += f'{fs}{stats["third_quartile"]}{fs}{stats["percentile_90"]}'
string += eol

if output is None:
print(string)
Expand Down
9 changes: 8 additions & 1 deletion temporal/t.rast.univar/t.rast.univar.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ <h2>DESCRIPTION</h2>
By default it returns the name of the map, the start and end date of
dataset and the following values: mean, minimum and maximum vale,
mean_of_abs, standard deviation, variance, coeff_var, number of null
cells, total number of cell.
cells, total number of cells.
<p>
Using the <em>e</em> flag it can calculate also extended statistics:
first quartile, median value, third quartile and percentile 90.
<p>
If a <em>zones</em> raster map is provided, statistics are computed for
each zone (category) in that input raster map. The <em>zones</em> option
does not support Spatio-Temporal-Raster-Datasets (STRDS) but only a single,
static raster map.

<h2>EXAMPLE</h2>

Expand All @@ -32,8 +37,10 @@ <h2>SEE ALSO</h2>
<em>
<a href="t.create.html">t.create</a>,
<a href="t.info.html">t.info</a>
<a href="r.univar.html">t.create</a>,
</em>

<h2>AUTHOR</h2>

S&ouml;ren Gebbert, Th&uuml;nen Institute of Climate-Smart Agriculture
Stefan Blumentrath, (Support for zones)
29 changes: 24 additions & 5 deletions temporal/t.rast.univar/t.rast.univar.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
# %option G_OPT_STRDS_INPUT
# %end

# %option G_OPT_R_INPUT
# % key: zones
# % description: Raster map used for zoning, must be of type CELL
# % required: no
# %end

# %option G_OPT_F_OUTPUT
# % required: no
# %end
Expand Down Expand Up @@ -60,8 +66,7 @@
# % guisection: Formatting
# %end

import grass.script as grass

import grass.script as gs

############################################################################

Expand All @@ -72,12 +77,13 @@ def main():

# Get the options
input = options["input"]
zones = options["zones"]
output = options["output"]
where = options["where"]
extended = flags["e"]
no_header = flags["u"]
rast_region = bool(flags["r"])
separator = grass.separator(options["separator"])
separator = gs.separator(options["separator"])

# Make sure the temporal database exists
tgis.init()
Expand All @@ -87,11 +93,24 @@ def main():
if output == "-":
output = None

# Check if zones map exists and is of type CELL
if zones:
if gs.raster.raster_info(zones)["datatype"] != "CELL":
gs.fatal(_("Zoning raster must be of type CELL"))

tgis.print_gridded_dataset_univar_statistics(
"strds", input, output, where, extended, no_header, separator, rast_region
"strds",
input,
output,
where,
extended,
no_header,
separator,
rast_region,
zones,
)


if __name__ == "__main__":
options, flags = grass.parser()
options, flags = gs.parser()
wenzeslaus marked this conversation as resolved.
Show resolved Hide resolved
main()
Loading