4
* Calculates univariate statistics from the non-null cells of a GRASS raster map
6
* Copyright (C) 2004-2006 by the GRASS Development Team
7
* Author(s): Hamish Bowman, University of Otago, New Zealand
8
* Extended stats: Martin Landa
10
* This program is free software under the GNU General Public
11
* License (>=v2). Read the file COPYING that comes with GRASS
14
* This program is a replacement for the r.univar shell script
23
/* ************************************************************************* */
24
/* Set up the arguments we are expecting ********************************** */
25
/* ************************************************************************* */
28
param.inputfile = G_define_standard_option(G_OPT_R_MAPS);
30
param.percentile = G_define_option();
31
param.percentile->key = "percentile";
32
param.percentile->type = TYPE_INTEGER;
33
param.percentile->required = NO;
34
param.percentile->multiple = YES;
35
param.percentile->options = "0-100";
36
param.percentile->answer = "90";
37
param.percentile->description =
38
_("Percentile to calculate (requires extended statistics flag)");
40
param.shell_style = G_define_flag();
41
param.shell_style->key = 'g';
42
param.shell_style->description =
43
_("Print the stats in shell script style");
45
param.extended = G_define_flag();
46
param.extended->key = 'e';
47
param.extended->description = _("Calculate extended statistics");
52
static int open_raster(const char *infile);
53
static univar_stat *univar_stat_with_percentiles(int map_type, int size);
54
static void process_raster(univar_stat * stats, int fd,
55
const struct Cell_head *region);
57
/* *************************************************************** */
58
/* **** the main functions for r.univar ************************** */
59
/* *************************************************************** */
60
int main(int argc, char *argv[])
62
unsigned int rows, cols; /* totals */
65
struct Cell_head region;
66
struct GModule *module;
72
module = G_define_module();
73
module->keywords = _("raster, statistics");
75
_("Calculates univariate statistics from the non-null cells of a raster map.");
77
/* Define the different options */
80
if (G_parser(argc, argv))
83
G_get_window(®ion);
87
/* count the rasters given */
91
for (p = (const char **)param.inputfile->answers, rasters = 0;
95
/* process them all */
97
size_t cells = rasters * cols * rows;
98
int map_type = param.extended->answer ? -2 : -1;
101
stats = ((map_type == -1)
102
? create_univar_stat_struct(-1, cells, 0)
105
for (p = param.inputfile->answers; *p; p++) {
106
int fd = open_raster(*p);
108
if (map_type != -1) {
109
/* NB: map_type must match when doing extended stats */
110
int this_type = G_get_raster_map_type(fd);
112
assert(this_type > -1);
115
map_type = this_type;
116
stats = univar_stat_with_percentiles(map_type, cells);
118
else if (this_type != map_type) {
119
G_fatal_error(_("Raster <%s> type mismatch"), *p);
123
process_raster(stats, fd, ®ion);
127
if (!(param.shell_style->answer))
128
G_percent(rows, rows, 2); /* finish it off */
130
/* create the output */
134
free_univar_stat_struct(stats);
139
static int open_raster(const char *infile)
144
mapset = G_find_cell2(infile, "");
145
if (mapset == NULL) {
146
G_fatal_error(_("Raster map <%s> not found"), infile);
149
fd = G_open_cell_old(infile, mapset);
151
G_fatal_error(_("Unable to open raster map <%s>"), infile);
157
static univar_stat *univar_stat_with_percentiles(int map_type, int size)
163
while (param.percentile->answers[i])
165
stats = create_univar_stat_struct(map_type, size, i);
166
for (i = 0; i < stats->n_perc; i++) {
167
sscanf(param.percentile->answers[i], "%i", &stats->perc[i]);
175
process_raster(univar_stat * stats, int fd, const struct Cell_head *region)
177
/* use G_window_rows(), G_window_cols() here? */
178
const int rows = region->rows;
179
const int cols = region->cols;
180
int first = (stats->n < 1);
182
const RASTER_MAP_TYPE map_type = G_get_raster_map_type(fd);
184
= ((!param.extended->answer) ? 0
185
: (map_type == DCELL_TYPE) ? (void *)stats->dcell_array
186
: (map_type == FCELL_TYPE) ? (void *)stats->fcell_array
187
: (void *)stats->cell_array);
188
const size_t value_sz = G_raster_size(map_type);
192
raster_row = G_calloc(cols, value_sz);
194
for (row = 0; row < rows; row++) {
198
if (G_get_raster_row(fd, raster_row, row, map_type) < 0)
199
G_fatal_error(_("Reading row %d"), row);
203
for (col = 0; col < cols; col++) {
205
if (G_is_null_value(ptr, map_type)) {
206
ptr = G_incr_void_ptr(ptr, value_sz);
211
/* put the value into stats->XXXcell_array */
212
memcpy(nextp, ptr, value_sz);
213
nextp = G_incr_void_ptr(nextp, value_sz);
217
double val = ((map_type == DCELL_TYPE) ? *((DCELL *) ptr)
218
: (map_type == FCELL_TYPE) ? *((FCELL *) ptr)
222
stats->sumsq += val * val;
223
stats->sum_abs += fabs(val);
231
if (val > stats->max)
233
if (val < stats->min)
238
ptr = G_incr_void_ptr(ptr, value_sz);
241
if (!(param.shell_style->answer))
242
G_percent(row, rows, 2);