[GRASS-SVN] r36098 - grass-addons/raster/r.univar2.zonal

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Feb 25 14:20:03 EST 2009


Author: mmetz
Date: 2009-02-25 14:20:03 -0500 (Wed, 25 Feb 2009)
New Revision: 36098

Modified:
   grass-addons/raster/r.univar2.zonal/Makefile
   grass-addons/raster/r.univar2.zonal/globals.h
   grass-addons/raster/r.univar2.zonal/r.univar.zonal.html
   grass-addons/raster/r.univar2.zonal/r.univar_main.c
   grass-addons/raster/r.univar2.zonal/r3.univar_main.c
   grass-addons/raster/r.univar2.zonal/stats.c
Log:
behaves like r.univar without zones input, 3D zoning (untested)

Modified: grass-addons/raster/r.univar2.zonal/Makefile
===================================================================
--- grass-addons/raster/r.univar2.zonal/Makefile	2009-02-25 13:32:52 UTC (rev 36097)
+++ grass-addons/raster/r.univar2.zonal/Makefile	2009-02-25 19:20:03 UTC (rev 36098)
@@ -5,19 +5,19 @@
 DEPENDENCIES = $(G3DDEP) $(GISDEP)
 
 #needed for htmlmulti
-PROGRAMS = r.univar.zonal
+PROGRAMS = r.univar.zonal r3.univar.zonal
 
 include $(MODULE_TOPDIR)/include/Make/Multi.make
 
-#R3UNIVAR = $(BIN)/r3.univar.zonal$(EXE)
+R3UNIVAR = $(BIN)/r3.univar.zonal$(EXE)
 RUNIVAR = $(BIN)/r.univar.zonal$(EXE)
 
-default: $(RUNIVAR)
+default: $(RUNIVAR) $(R3UNIVAR)
 	$(MAKE) htmlmulti
 
 $(RUNIVAR): $(OBJDIR)/r.univar_main.o $(OBJDIR)/sort.o $(OBJDIR)/stats.o
 	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
 
-#$(R3UNIVAR): $(OBJDIR)/r3.univar_main.o $(OBJDIR)/sort.o $(OBJDIR)/stats.o
-#	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
+$(R3UNIVAR): $(OBJDIR)/r3.univar_main.o $(OBJDIR)/sort.o $(OBJDIR)/stats.o
+	$(CC) $(LDFLAGS) -o $@ $^ $(FMODE_OBJ) $(LIBES) $(XDRLIB) $(MATHLIB)
 

Modified: grass-addons/raster/r.univar2.zonal/globals.h
===================================================================
--- grass-addons/raster/r.univar2.zonal/globals.h	2009-02-25 13:32:52 UTC (rev 36097)
+++ grass-addons/raster/r.univar2.zonal/globals.h	2009-02-25 19:20:03 UTC (rev 36098)
@@ -70,8 +70,8 @@
 void heapsort_float(float *data, int n);
 void heapsort_int(int *data, int n);
 int print_stats(univar_stat * stats);
-int print_stats2(univar_stat * stats);
-univar_stat *create_univar_stat_struct(int map_type, int size, int n_perc);
+int print_stats_table(univar_stat * stats);
+univar_stat *create_univar_stat_struct(int map_type, int n_perc);
 void free_univar_stat_struct(univar_stat * stats);
 
 #endif

Modified: grass-addons/raster/r.univar2.zonal/r.univar.zonal.html
===================================================================
--- grass-addons/raster/r.univar2.zonal/r.univar.zonal.html	2009-02-25 13:32:52 UTC (rev 36097)
+++ grass-addons/raster/r.univar2.zonal/r.univar.zonal.html	2009-02-25 19:20:03 UTC (rev 36098)
@@ -4,14 +4,14 @@
 This includes the number of cells counted, minimum and maximum cell values,
 range, arithmetic mean, population variance, standard deviation, and 
 coefficient of variation. Statistics are calculated separately for every
-category/zone found in the <b>zones</b> input map.
+category/zone found in the <b>zones</b> input map if given.
 If the <b>-e</b> extended statistics flag is given the 1st quartile, median,
 3rd quartile, and given <b>percentile</b> are calculated.
 If the <b>-g</b> flag is given the results are presented in a format suitable
 for use in a shell script.
 If the <b>-t</b> flag is given the results are presented in tabular format
 with "|" as field separator. The table can immediately be converted to a
-proper attribute table which can then be linked to a vector, e.g. the vector
+vector attribute table which can then be linked to a vector, e.g. the vector
 that was rasterized to create the <b>zones</b> input raster.
 
 <h2>NOTES</h2>
@@ -101,10 +101,7 @@
 <h2>TODO</h2>
 
 <i>mode, skewness, kurtosis</i>
-<br>
-<i>3D zonal statistics</i>
 
-
 <h2>SEE ALSO</h2>
 
 <em>

Modified: grass-addons/raster/r.univar2.zonal/r.univar_main.c
===================================================================
--- grass-addons/raster/r.univar2.zonal/r.univar_main.c	2009-02-25 13:32:52 UTC (rev 36097)
+++ grass-addons/raster/r.univar2.zonal/r.univar_main.c	2009-02-25 19:20:03 UTC (rev 36098)
@@ -27,11 +27,11 @@
 /* ************************************************************************* */
 void set_params()
 {
-    param.inputfile = G_define_standard_option(G_OPT_R_MAP);
+    param.inputfile = G_define_standard_option(G_OPT_R_MAPS);
 
     param.zonefile = G_define_standard_option(G_OPT_R_MAP);
     param.zonefile->key = "zones";
-    param.zonefile->required = YES;
+    param.zonefile->required = NO;
     param.zonefile->description =
 	_("Raster map used for zoning, must be of type CELL");
 
@@ -61,13 +61,13 @@
 
     param.table = G_define_flag();
     param.table->key = 't';
-    param.table->description = _("Table output format instead of r.univar like output format");
+    param.table->description = _("Table output format instead of standard output format");
 
     return;
 }
 
 static int open_raster(const char *infile);
-static univar_stat *univar_stat_with_percentiles(int map_type, int size);
+static univar_stat *univar_stat_with_percentiles(int map_type);
 static void process_raster(univar_stat * stats, int fd, int fdz,
 			   const struct Cell_head *region);
 
@@ -77,12 +77,12 @@
 int main(int argc, char *argv[])
 {
     unsigned int rows, cols;	/*  totals  */
-    /* int rasters; */
+    int rasters;
 
     struct Cell_head region;
     struct GModule *module;
     univar_stat *stats;
-    char *p, *z;
+    char **p, *z;
     int fd, fdz, cell_type, min, max;
     struct Range zone_range;
     char *mapset, *name;
@@ -108,79 +108,90 @@
 	}
     }
 
-    /* TODO: make it an option */
-    zone_info.sep = "|";
-
     G_get_window(&region);
     rows = region.rows;
     cols = region.cols;
 
+    /* TODO: make table field separator an option */
+    zone_info.sep = "|";
+
     zone_info.min = 0.0 / 0.0;	/*set to nan as default */
     zone_info.max = 0.0 / 0.0;	/*set to nan as default */
     zone_info.n_zones = 0;
 
+    fdz = -1;
+    
     /* open zoning raster */
-    z = param.zonefile->answer;
-    mapset = G_find_cell2(z, "");
+    if ((z = param.zonefile->answer)) {
+	mapset = G_find_cell2(z, "");
 
-    fdz = open_raster(z);
-    
-    cell_type = G_get_raster_map_type(fdz);
-    if (cell_type != CELL_TYPE)
-	G_fatal_error("Zoning raster must be of type CELL");
+	fdz = open_raster(z);
+	
+	cell_type = G_get_raster_map_type(fdz);
+	if (cell_type != CELL_TYPE)
+	    G_fatal_error("Zoning raster must be of type CELL");
 
-    if (G_read_range(z, mapset, &zone_range) == -1)
-	G_fatal_error("Can not read range for zoning raster");
-    if (G_get_range_min_max(&zone_range, &min, &max))
-	G_fatal_error("Can not read range for zoning raster");
-    if (G_read_raster_cats(z, mapset, &(zone_info.cats)))
-	G_warning("no category support for zoning raster");
+	if (G_read_range(z, mapset, &zone_range) == -1)
+	    G_fatal_error("Can not read range for zoning raster");
+	if (G_get_range_min_max(&zone_range, &min, &max))
+	    G_fatal_error("Can not read range for zoning raster");
+	if (G_read_raster_cats(z, mapset, &(zone_info.cats)))
+	    G_warning("no category support for zoning raster");
 
-    zone_info.min = min;
-    zone_info.max = max;
-    zone_info.n_zones = max - min + 1;
+	zone_info.min = min;
+	zone_info.max = max;
+	zone_info.n_zones = max - min + 1;
+    }
 
-    /* process input raster */
-    size_t cells = cols * rows;
+    /* count the input rasters given */
+    for (p = (char **)param.inputfile->answers, rasters = 0;
+	 *p; p++, rasters++) ;
+
+    /* process all input rasters */
     int map_type = param.extended->answer ? -2 : -1;
 
     stats = ((map_type == -1)
-	     ? create_univar_stat_struct(-1, cells, 0)
+	     ? create_univar_stat_struct(-1, 0)
 	     : 0);
 
-    p = param.inputfile->answer;
-    fd = open_raster(p);
+    for (p = param.inputfile->answers; *p; p++) {
+	fd = open_raster(*p);
 
-    if (map_type != -1) {
-	/* NB: map_type must match when doing extended stats */
-	int this_type = G_get_raster_map_type(fd);
+	if (map_type != -1) {
+	    /* NB: map_type must match when doing extended stats */
+	    int this_type = G_get_raster_map_type(fd);
 
-	assert(this_type > -1);
-	if (map_type < -1) {
-	    assert(stats == 0);
-	    map_type = this_type;
-	    stats = univar_stat_with_percentiles(map_type, cells);
+	    assert(this_type > -1);
+	    if (map_type < -1) {
+		/* extended stats */
+		assert(stats == 0);
+		map_type = this_type;
+		stats = univar_stat_with_percentiles(map_type);
+	    }
+	    else if (this_type != map_type) {
+		G_fatal_error(_("Raster <%s> type mismatch"), *p);
+	    }
 	}
-	else if (this_type != map_type) {
-	    G_fatal_error(_("Raster <%s> type mismatch"), p);
-	}
+
+	process_raster(stats, fd, fdz, &region);
+
+	/* close input raster */
+	G_close_cell(fd);
     }
 
-    process_raster(stats, fd, fdz, &region);
+    /* close zoning raster */
+    if (z)
+	G_close_cell(fdz);
 
     /* create the output */
     if (param.table->answer)
-	print_stats2(stats);
+	print_stats_table(stats);
     else
 	print_stats(stats);
 	
     /* release memory */
     free_univar_stat_struct(stats);
 
-    /* closing raster maps */
-    G_close_cell(fd);
-    G_close_cell(fdz);
-
     exit(EXIT_SUCCESS);
 }
 
@@ -202,16 +213,20 @@
     return fd;
 }
 
-static univar_stat *univar_stat_with_percentiles(int map_type, int size)
+static univar_stat *univar_stat_with_percentiles(int map_type)
 {
     univar_stat *stats;
     int i, j;
+    int n_zones = zone_info.n_zones;
 
+    if (n_zones == 0)
+	n_zones = 1;
+
     i = 0;
     while (param.percentile->answers[i])
 	i++;
-    stats = create_univar_stat_struct(map_type, size, i);
-    for (i = 0; i < zone_info.n_zones; i++) {
+    stats = create_univar_stat_struct(map_type, i);
+    for (i = 0; i < n_zones; i++) {
 	for (j = 0; j < stats[i].n_perc; j++) {
 	    sscanf(param.percentile->answers[j], "%i", &(stats[i].perc[j]));
 	}
@@ -233,42 +248,49 @@
     unsigned int row;
     void *raster_row;
     CELL *zoneraster_row;
-
+    int n_zones = zone_info.n_zones;
+    
     raster_row = G_allocate_raster_buf(map_type);
-    zoneraster_row = G_allocate_c_raster_buf();
+    if (n_zones)
+	zoneraster_row = G_allocate_c_raster_buf();
 
     for (row = 0; row < rows; row++) {
 	void *ptr;
 	CELL *zptr;
 	unsigned int col;
-	int zone;
 
 	if (G_get_raster_row(fd, raster_row, row, map_type) < 0)
 	    G_fatal_error(_("Reading row %d"), row);
-	if (G_get_c_raster_row(fdz, zoneraster_row, row) < 0)
-	    G_fatal_error(_("Reading row %d"), row);
+	if (n_zones) {
+	    if (G_get_c_raster_row(fdz, zoneraster_row, row) < 0)
+		G_fatal_error(_("Reading row %d"), row);
+	    zptr = zoneraster_row;
+	}
 
 	ptr = raster_row;
-	zptr = zoneraster_row;
 
 	for (col = 0; col < cols; col++) {
 	    double val;
+	    int zone = 0;
 
-	    /* skip NULL cells in zone map */
-	    if (G_is_c_null_value(zptr)) {
-		ptr = G_incr_void_ptr(ptr, value_sz);
-		zptr++;
-		continue;
+	    if (n_zones) {
+		/* skip NULL cells in zone map */
+		if (G_is_c_null_value(zptr)) {
+		    ptr = G_incr_void_ptr(ptr, value_sz);
+		    zptr++;
+		    continue;
+		}
+		zone = *zptr - zone_info.min;
 	    }
 
 	    /* count NULL cells in input map */
-	    zone = *zptr - zone_info.min;
 	    stats[zone].size++;
 	    
 	    /* can't do stats with NULL cells in input map */
 	    if (G_is_null_value(ptr, map_type)) {
 		ptr = G_incr_void_ptr(ptr, value_sz);
-		zptr++;
+		if (n_zones)
+		    zptr++;
 		continue;
 	    }
 
@@ -326,11 +348,14 @@
 	    }
 
 	    ptr = G_incr_void_ptr(ptr, value_sz);
-	    zptr++;
+	    if (n_zones)
+		zptr++;
 	    stats[zone].n++;
 	}
-	G_percent(row, rows, 2);
+	if (!(param.shell_style->answer))
+	    G_percent(row, rows, 2);
     }
-    G_percent(rows, rows, 2);	/* finish it off */
+    if (!(param.shell_style->answer))
+	G_percent(rows, rows, 2);	/* finish it off */
 
 }

Modified: grass-addons/raster/r.univar2.zonal/r3.univar_main.c
===================================================================
--- grass-addons/raster/r.univar2.zonal/r3.univar_main.c	2009-02-25 13:32:52 UTC (rev 36097)
+++ grass-addons/raster/r.univar2.zonal/r3.univar_main.c	2009-02-25 19:20:03 UTC (rev 36098)
@@ -15,8 +15,10 @@
  *
  */
 
+#include <string.h>
 #define MAIN
 #include "globals.h"
+#include "grass/G3d.h"
 
 /* local proto */
 void set_params();
@@ -28,6 +30,17 @@
 {
     param.inputfile = G_define_standard_option(G_OPT_R3_INPUT);
 
+    param.zonefile = G_define_standard_option(G_OPT_R3_INPUT);
+    param.zonefile->key = "zones";
+    param.zonefile->required = NO;
+    param.zonefile->description =
+	_("3D Raster map used for zoning, must be of type CELL");
+
+    param.output_file = G_define_standard_option(G_OPT_F_OUTPUT);
+    param.output_file->required = NO;
+    param.output_file->description =
+	_("Name for output file (if omitted or \"-\" output to stdout)");
+
     param.percentile = G_define_option();
     param.percentile->key = "percentile";
     param.percentile->type = TYPE_INTEGER;
@@ -47,6 +60,10 @@
     param.extended->key = 'e';
     param.extended->description = _("Calculate extended statistics");
 
+    param.table = G_define_flag();
+    param.table->key = 't';
+    param.table->description = _("Table output format instead of standard output format");
+
     return;
 }
 
@@ -61,15 +78,19 @@
     double val_d;		/* for misc use */
     int first = TRUE;		/* min/max init flag */
 
-    int map_type;
+    int map_type, zmap_type;
     univar_stat *stats;
 
-    char *infile;
-    void *map;
+    char *infile, *zonemap;
+    void *map, *zmap;
     G3D_Region region;
     unsigned int i;
     unsigned int rows, cols, depths;
     unsigned int x, y, z;
+    double dmin, dmax;
+    int zone, use_zone = 0;
+    char *mapset, *name;
+    struct FPRange zone_range;
 
     struct GModule *module;
 
@@ -86,7 +107,6 @@
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
-
     /*Set the defaults */
     G3d_initDefaults();
 
@@ -97,13 +117,69 @@
     rows = region.rows;
     depths = region.depths;
 
+    name = param.output_file->answer;
+    if (name != NULL && strcmp(name, "-") != 0) {
+	if (NULL == freopen(name, "w", stdout)) {
+	    G_fatal_error(_("Unable to open file <%s> for writing"), name);
+	}
+    }
 
+    /* TODO: make table field separator an option */
+    zone_info.sep = "|";
+
+    dmin = 0.0 / 0.0;	/*set to nan as default */
+    dmax = 0.0 / 0.0;	/*set to nan as default */
+    zone_info.min = 0.0 / 0.0;	/*set to nan as default */
+    zone_info.max = 0.0 / 0.0;	/*set to nan as default */
+    zone_info.n_zones = 0;
+
+    /* open 3D zoning raster with default region */
+    if ((zonemap = param.zonefile->answer)) {
+	if (NULL == (mapset = G_find_grid3(zonemap, "")))
+	    G3d_fatalError(_("Requested g3d map <%s> not found"), zonemap);
+
+	zmap =
+	    G3d_openCellOld(zonemap, G_find_grid3(zonemap, ""), &region,
+			    G3D_TILE_SAME_AS_FILE, G3D_USE_CACHE_DEFAULT);
+
+	if (zmap == NULL)
+	    G3d_fatalError(_("Error opening g3d map <%s>"), zonemap);
+
+	if (G3d_tileTypeMap(zmap) != CELL_TYPE)
+	    G_fatal_error("Zoning raster must be of type CELL");
+
+	zmap_type = G3d_tileTypeMap(zmap);
+	
+	if (zmap_type != CELL_TYPE)
+	    G_fatal_error("Zoning raster must be of type CELL");
+
+	if (G3d_readRange(zonemap, mapset, &zone_range) == -1)
+	    G_fatal_error("Can not read range for zoning raster");
+	G3d_range_min_max(zmap, &dmin, &dmax);
+	if (G_read_raster_cats(zonemap, mapset, &(zone_info.cats)))
+	    G_warning("no category support for zoning raster");
+
+	/* properly round dmin and dmax */
+	if (dmin < 0)
+	    zone_info.min = dmin - 0.5;
+	else
+	    zone_info.min = dmin + 0.5;
+	if (dmax < 0)
+	    zone_info.max = dmax - 0.5;
+	else
+	    zone_info.max = dmax + 0.5;
+	    
+	zone_info.n_zones = zone_info.max - zone_info.min + 1;
+
+	use_zone = 1;
+    }
+
+    /*Open 3D input raster with default region */
     infile = param.inputfile->answer;
 
     if (NULL == G_find_grid3(infile, ""))
 	G3d_fatalError(_("Requested g3d map <%s> not found"), infile);
 
-    /*Open all maps with default region */
     map =
 	G3d_openCellOld(infile, G_find_grid3(infile, ""), &region,
 			G3D_TILE_SAME_AS_FILE, G3D_USE_CACHE_DEFAULT);
@@ -116,7 +192,7 @@
     i = 0;
     while (param.percentile->answers[i])
 	i++;
-    stats = create_univar_stat_struct(map_type, cols * rows * depths, i);
+    stats = create_univar_stat_struct(map_type, i);
     for (i = 0; i < stats->n_perc; i++) {
 	sscanf(param.percentile->answers[i], "%i", &stats->perc[i]);
     }
@@ -127,60 +203,89 @@
 	    G_percent(z, depths - 1, 10);
 	for (y = 0; y < rows; y++) {
 	    for (x = 0; x < cols; x++) {
+		zone = 0;
+		if (zone_info.n_zones)
+		    G3d_getValue(zmap, x, y, z, &zone, CELL_TYPE);
 		if (map_type == FCELL_TYPE) {
 		    G3d_getValue(map, x, y, z, &val_f, map_type);
 		    if (!G3d_isNullValueNum(&val_f, map_type)) {
-			if (param.extended->answer)
-			    stats->fcell_array[stats->n] = val_f;
+			if (param.extended->answer) {
+			    if (stats[zone].n >= stats[zone].n_alloc) {
+				size_t msize;
+				stats[zone].n_alloc += 1000;
+				msize = stats[zone].n_alloc * sizeof(FCELL);
+				stats[zone].fcell_array =
+				    (FCELL *)G_realloc((void *)stats[zone].fcell_array, msize);
+			    }
 
-			stats->sum += val_f;
-			stats->sumsq += (val_f * val_f);
-			stats->sum_abs += fabs(val_f);
+			    stats[zone].fcell_array[stats[zone].n] = val_f;
+			}
 
-			if (first) {
-			    stats->max = val_f;
-			    stats->min = val_f;
-			    first = FALSE;
+			stats[zone].sum += val_f;
+			stats[zone].sumsq += (val_f * val_f);
+			stats[zone].sum_abs += fabs(val_f);
+
+			if (stats[zone].first) {
+			    stats[zone].max = val_f;
+			    stats[zone].min = val_f;
+			    stats[zone].first = FALSE;
 			}
 			else {
-			    if (val_f > stats->max)
-				stats->max = val_f;
-			    if (val_f < stats->min)
-				stats->min = val_f;
+			    if (val_f > stats[zone].max)
+				stats[zone].max = val_f;
+			    if (val_f < stats[zone].min)
+				stats[zone].min = val_f;
 			}
-			stats->n++;
+			stats[zone].n++;
 		    }
 		}
 		else if (map_type == DCELL_TYPE) {
 		    G3d_getValue(map, x, y, z, &val_d, map_type);
 		    if (!G3d_isNullValueNum(&val_d, map_type)) {
-			if (param.extended->answer)
-			    stats->dcell_array[stats->n] = val_d;
+			if (param.extended->answer) {
+			    if (stats[zone].n >= stats[zone].n_alloc) {
+				size_t msize;
+				stats[zone].n_alloc += 1000;
+				msize = stats[zone].n_alloc * sizeof(DCELL);
+				stats[zone].dcell_array =
+				    (DCELL *)G_realloc((void *)stats[zone].dcell_array, msize);
+				}
 
-			stats->sum += val_d;
-			stats->sumsq += val_d * val_d;
-			stats->sum_abs += fabs(val_d);
+			    stats[zone].dcell_array[stats[zone].n] = val_d;
+			}
 
+			stats[zone].sum += val_d;
+			stats[zone].sumsq += val_d * val_d;
+			stats[zone].sum_abs += fabs(val_d);
+
 			if (first) {
-			    stats->max = val_d;
-			    stats->min = val_d;
-			    first = FALSE;
+			    stats[zone].max = val_d;
+			    stats[zone].min = val_d;
+			    stats[zone].first = FALSE;
 			}
 			else {
-			    if (val_d > stats->max)
-				stats->max = val_d;
-			    if (val_d < stats->min)
-				stats->min = val_d;
+			    if (val_d > stats[zone].max)
+				stats[zone].max = val_d;
+			    if (val_d < stats[zone].min)
+				stats[zone].min = val_d;
 			}
-			stats->n++;
+			stats[zone].n++;
 		    }
 		}
 	    }
 	}
     }
 
+    /* close maps */
+    G3d_closeCell(map);
+    if (zone_info.n_zones)
+	G3d_closeCell(zmap);
+
     /* create the output */
-    print_stats(stats);
+    if (param.table->answer)
+	print_stats_table(stats);
+    else
+	print_stats(stats);
 
     /* release memory */
     free_univar_stat_struct(stats);

Modified: grass-addons/raster/r.univar2.zonal/stats.c
===================================================================
--- grass-addons/raster/r.univar2.zonal/stats.c	2009-02-25 13:32:52 UTC (rev 36097)
+++ grass-addons/raster/r.univar2.zonal/stats.c	2009-02-25 19:20:03 UTC (rev 36098)
@@ -16,12 +16,15 @@
 /* *************************************************************** */
 /* **** univar_stat constructor ********************************** */
 /* *************************************************************** */
-univar_stat *create_univar_stat_struct(int map_type, int size, int n_perc)
+univar_stat *create_univar_stat_struct(int map_type, int n_perc)
 {
     univar_stat *stats;
     int i;
     int n_zones = zone_info.n_zones;
 
+    if (n_zones == 0)
+	n_zones = 1;
+
     stats = (univar_stat *) G_calloc(n_zones, sizeof(univar_stat));
 
     for (i = 0; i < n_zones; i++) {
@@ -74,16 +77,20 @@
 void free_univar_stat_struct(univar_stat * stats)
 {
     int i;
+    int n_zones = zone_info.n_zones;
 
-    for (i = 0; i < zone_info.n_zones; i++){
-    if (stats[i].perc)
-	G_free(stats[i].perc);
-    if (stats[i].dcell_array)
-	G_free(stats[i].dcell_array);
-    if (stats[i].fcell_array)
-	G_free(stats[i].fcell_array);
-    if (stats[i].cell_array)
-	G_free(stats[i].cell_array);
+    if (n_zones == 0)
+	n_zones = 1;
+
+    for (i = 0; i < n_zones; i++){
+	if (stats[i].perc)
+	    G_free(stats[i].perc);
+	if (stats[i].dcell_array)
+	    G_free(stats[i].dcell_array);
+	if (stats[i].fcell_array)
+	    G_free(stats[i].fcell_array);
+	if (stats[i].cell_array)
+	    G_free(stats[i].cell_array);
     }
 
     G_free(stats);
@@ -97,9 +104,12 @@
 /* *************************************************************** */
 int print_stats(univar_stat * stats)
 {
-    int z;
+    int z, n_zones = zone_info.n_zones;
 
-    for (z = 0; z < zone_info.n_zones; z++) {
+    if (n_zones == 0)
+	n_zones = 1;
+
+    for (z = 0; z < n_zones; z++) {
 	char sum_str[100];
 	double mean, variance, stdev, var_coef;
 
@@ -125,7 +135,8 @@
 	sprintf(sum_str, "%.10f", stats[z].sum);
 	G_trim_decimal(sum_str);
 
-	fprintf(stdout, "\nzone %d %s\n\n", z + zone_info.min, G_get_cat(z + zone_info.min, &(zone_info.cats)));
+	if (zone_info.n_zones)
+	    fprintf(stdout, "\nzone %d %s\n\n", z + zone_info.min, G_get_cat(z + zone_info.min, &(zone_info.cats)));
 
 	if (!param.shell_style->answer) {
 	    fprintf(stdout, "total null and non-null cells: %d\n", stats[z].size);
@@ -270,15 +281,20 @@
     return 1;
 }
 
-int print_stats2(univar_stat * stats)
+int print_stats_table(univar_stat * stats)
 {
-    int z;
     unsigned int i;
+    int z, n_zones = zone_info.n_zones;
 
+    if (n_zones == 0)
+	n_zones = 1;
+
     /* print column headers */
 
-    fprintf(stdout, "zone%s", zone_info.sep);
-    fprintf(stdout, "label%s", zone_info.sep);
+    if (zone_info.n_zones) {
+	fprintf(stdout, "zone%s", zone_info.sep);
+	fprintf(stdout, "label%s", zone_info.sep);
+    }
     fprintf(stdout, "non_null_cells%s", zone_info.sep);
     fprintf(stdout, "null_cells%s", zone_info.sep);
     fprintf(stdout, "min%s", zone_info.sep);
@@ -290,22 +306,21 @@
     fprintf(stdout, "variance%s", zone_info.sep);
     fprintf(stdout, "coeff_var%s", zone_info.sep);
     fprintf(stdout, "sum%s", zone_info.sep);
-    fprintf(stdout, "sum_abs%s", zone_info.sep);
+    fprintf(stdout, "sum_abs");
 
     if (param.extended->answer) {
-	fprintf(stdout, "first_quart%s", zone_info.sep);
-	fprintf(stdout, "median%s", zone_info.sep);
-	fprintf(stdout, "third_quart%s", zone_info.sep);
+	fprintf(stdout, "%sfirst_quart", zone_info.sep);
+	fprintf(stdout, "%smedian", zone_info.sep);
+	fprintf(stdout, "%sthird_quart", zone_info.sep);
 	for (i = 0; i < stats[0].n_perc; i++) {
-	    fprintf(stdout, "perc_%d%s", stats[0].perc[i],
-		    zone_info.sep);
+	    fprintf(stdout, "%sperc_%d", zone_info.sep, stats[0].perc[i]);
 	}
     }
     fprintf(stdout, "\n");
 
     /* print stats */
 
-    for (z = 0; z < zone_info.n_zones; z++) {
+    for (z = 0; z < n_zones; z++) {
 	char sum_str[100];
 	double mean, variance, stdev, var_coef;
 
@@ -320,7 +335,6 @@
 
 	i = 0;
 
-
 	/* all these calculations get promoted to doubles, so any DIV0 becomes nan */
 	mean = stats[z].sum / stats[z].n;
 	variance = (stats[z].sumsq - stats[z].sum * stats[z].sum / stats[z].n) / stats[z].n;
@@ -329,10 +343,12 @@
 	stdev = sqrt(variance);
 	var_coef = (stdev / mean) * 100.;	/* perhaps stdev/fabs(mean) ? */
 
-	/* zone number */
-	fprintf(stdout, "%d%s", z + zone_info.min, zone_info.sep);
-	/* zone label */
-	fprintf(stdout,"%s%s", G_get_cat(z + zone_info.min, &(zone_info.cats)), zone_info.sep);
+	if (zone_info.n_zones) {
+	    /* zone number */
+	    fprintf(stdout, "%d%s", z + zone_info.min, zone_info.sep);
+	    /* zone label */
+	    fprintf(stdout,"%s%s", G_get_cat(z + zone_info.min, &(zone_info.cats)), zone_info.sep);
+	}
 
 	/* total cells */
 	fprintf(stdout, "%d%s", stats[z].n, zone_info.sep);
@@ -361,7 +377,7 @@
 	/* absolute sum */
 	sprintf(sum_str, "%.10f", stats[z].sum_abs);
 	G_trim_decimal(sum_str);
-	fprintf(stdout, "%s%s", sum_str, zone_info.sep);
+	fprintf(stdout, "%s", sum_str);
 
 	/* TODO: mode, skewness, kurtosis */
 	if (param.extended->answer) {
@@ -427,15 +443,15 @@
 	    }
 
 	    /* first quartile */
-	    fprintf(stdout, "%g%s", quartile_25, zone_info.sep);
+	    fprintf(stdout, "%s%g", zone_info.sep, quartile_25);
 	    /* median */
-	    fprintf(stdout, "%g%s", median, zone_info.sep);
+	    fprintf(stdout, "%s%g", zone_info.sep, median);
 	    /* third quartile */
-	    fprintf(stdout, "%g%s", quartile_75, zone_info.sep);
+	    fprintf(stdout, "%s%g", zone_info.sep, quartile_75);
 	    /* percentiles */
 	    for (i = 0; i < stats[z].n_perc; i++) {
-		fprintf(stdout, "%g%s", 
-			quartile_perc[i], zone_info.sep);
+		fprintf(stdout, "%s%g", zone_info.sep , 
+			quartile_perc[i]);
 	    }
 
 	    G_free((void *)quartile_perc);



More information about the grass-commit mailing list