Ejemplo n.º 1
0
/* useful to create randomised samples for statistical tests */
void do_split_sample ( char *input, char *output, int in_types, double percentage, char *map,  
						int all, int processing_mode, int quiet) {
        CELL *cellbuf;
	DCELL *dcellbuf;
	GT_Row_cache_t *cache;
	int fd;
	int i,j,k,l;
	int no_sites;
	int sites_tried = 0;
	struct Cell_head region;
	int error;
	char *mapset, errmsg [200];
	unsigned int *taken; /* this is an array of 0/1 which signals, if
	                       a certain site has already been 'drawn' */
	long row_idx, col_idx;
	struct Map_info in_vect_map;
	struct Map_info out_vect_map;
  	struct line_pnts *vect_points;
	struct line_cats *vect_cats;
	double x,y,z;
	int n_points = 1;
	int cur_type;
	
	
	cellbuf = NULL;
	dcellbuf = NULL;
	cache = NULL;
	
	/* get current region */
	G_get_window (&region);
	
	
	/* attempt to create new file for output */
	Vect_set_open_level (2);
	if (0 > Vect_open_new (&out_vect_map, output, 0) ) {
		G_fatal_error ("Could not open output vector map.\n");
	}

	/* open input vector map */  	
	if ((mapset = G_find_vector2 (input, "")) == NULL) {
	     sprintf (errmsg, "Could not find input %s\n", input);
	     G_fatal_error ("%s",errmsg);
	}

  	if (1 > Vect_open_old (&in_vect_map, input, "")) {
    		sprintf (errmsg, "Could not open input map %s.\n", input);
    		G_fatal_error ("%s",errmsg);
  	}

	vect_points = Vect_new_line_struct ();
	vect_cats = Vect_new_cats_struct ();

	/* set constraints specified */
	if (in_types != 0) {
		Vect_set_constraint_type (&in_vect_map, in_types);	
	}
	if (all != 1) {
		Vect_set_constraint_region (&in_vect_map, region.north, region.south, 
			region.east, region.west, 0.0, 0.0);
	}

	
	/* get total number of objects with constraints */
	i = 0;
	while ((cur_type = Vect_read_next_line (&in_vect_map, vect_points, vect_cats) > 0)) {
		i ++;
	}
	
	k = ( ((float) i/100)) * percentage; /* k now has the number of objects wanted */
	
	if ( quiet != 1 ) {
		fprintf (stderr,"Creating randomised sample of size n = %i.\n",k);
	}
	
	/* now, we need to acquire exactly 'k' random objects that fall in NON-NULL */
	/* coverage raster cells. */	
	taken = G_calloc (i, sizeof (unsigned int));
	for ( l = 0; l < k; l ++ ) {
		taken[l] = 0;
	}
	no_sites = i; /* store this for later use */
	
	/* does user want to filter objects through a raster map? */
	if ( map != NULL) {
		/* open raster map */
		fd = G_open_cell_old (map, G_find_cell (map, ""));
		if (fd < 0)
		{
			G_fatal_error ("Could not open raster map for reading!\n");
		}
		/* allocate cache and buffer, according to type of coverage */
		if ( processing_mode == CELL_TYPE) {
			/* INT coverage */
			cache = (GT_Row_cache_t *) G_malloc (sizeof (GT_Row_cache_t));
			/* TODO: check error value */
			error = GT_RC_open (cache, cachesize, fd, CELL_TYPE);
			cellbuf = G_allocate_raster_buf (CELL_TYPE);			
		}
		if ( (processing_mode == FCELL_TYPE) || (processing_mode == DCELL_TYPE) ) {
			/* FP coverage */
			cache = (GT_Row_cache_t *) G_malloc (sizeof (GT_Row_cache_t));
			/* TODO: check error value */
			error = GT_RC_open (cache, cachesize, fd, DCELL_TYPE);
			dcellbuf = G_allocate_raster_buf (DCELL_TYPE);	
		}
	}
	
	srand ( ((unsigned int) time (NULL)) + getpid()); /* set seed for random number generator from system time and process ID*/
	i = 0;
	
	/* MAIN LOOP */
	while ( i < k ) {
		/* get a random index, but one that was not taken already */
		l = 0;
		while ( l == 0 ) {
			j = rand () % ( no_sites - 1 + 1) + 1; /* j now has the random position to try */
			if ( taken[j-1] == 0 ) {
				l = 1; /* exit loop */
			}
		}
		taken [j-1] = 1; /* mark this index as 'taken' */
		sites_tried ++; /* keep track of this so we do not enter an infinite loop */
		if ( sites_tried > no_sites ) {
			/* could not create a large enough sample */
			G_fatal_error ("Could not find enough objects for split sampling.\nDecrease split sample size.\n");
		}
		/* get next vector object */
		cur_type = Vect_read_line (&in_vect_map, vect_points, vect_cats, j);
		if (cur_type < 0 ) {
			G_fatal_error ("Error reading vector map: premature EOF.\n");	
		}	
		/* now, check if coverage under site is NON-NULL and within region */
		/* convert site northing to row! */
		/* for this check, we use only the first pair of coordinates! */
		Vect_copy_pnts_to_xyz (vect_points, &x, &y, &z, &n_points);	
		row_idx =
			(long) G_northing_to_row (y,
				  &region);
				
		col_idx =
			(long) G_easting_to_col (x,
				 &region);
		/* do region check, first... OBSOLETE */
			/* read row from cache and check for NULL */
			/* if required */
			if ( map != NULL ) {
				if ( processing_mode == CELL_TYPE ) {
					cellbuf = GT_RC_get (cache, row_idx);			
					if (!G_is_c_null_value(&cellbuf[col_idx])) {
						i ++;
						Vect_write_line (&out_vect_map, cur_type, 
								vect_points, vect_cats );
						fflush (stdout);
					}
				}
				if ( (processing_mode == FCELL_TYPE) || (processing_mode == DCELL_TYPE) ) {
					dcellbuf = GT_RC_get (cache, row_idx);
					if (!G_is_d_null_value(&dcellbuf[col_idx])) {
						i ++;
						Vect_write_line (&out_vect_map, cur_type, 
								vect_points, vect_cats );
						fflush (stdout);
					}
				}
			} else {
				i ++;
				Vect_write_line (&out_vect_map, GV_POINT, 
								vect_points, vect_cats );
				fflush (stdout);
			}
		/* disregard region setting and map, if -a flag is given */
		if ( all == 1 ) {
			i ++;
			Vect_write_line (&out_vect_map, cur_type, 
					vect_points, vect_cats );
			fflush (stdout);
		}
		
		if ( quiet != 1 ) {
			G_percent(i,k,1);
		}
	}
	/* END OF MAIN LOOP */
	Vect_copy_head_data (&in_vect_map, &out_vect_map);
	fprintf (stdout, "Building topology information for output map.\n");
	Vect_build (&out_vect_map);
	Vect_close (&in_vect_map);
	Vect_close (&out_vect_map);
	
	if ( map != NULL ) {
		/* close cache, free buffers! */
		GT_RC_close (cache);
		if ( processing_mode == CELL_TYPE ) {
			G_free (cellbuf);
		}
		if ( (processing_mode == FCELL_TYPE) || (processing_mode == DCELL_TYPE) ) {
			G_free (dcellbuf);
		}
		G_free (cache);
		}
}
Ejemplo n.º 2
0
/* create the actual report */
void do_report_CELL ( char *map, char *mapset, char *sites,
					int precision, int null_flag, int uncat_flag,
					int all_flag, int quiet_flag, int skip_flag,
				  	char *logfile, int background, int gain, int show_progress) {
    	CELL *cellbuf;
	struct Cell_head region;
	GT_Row_cache_t *cache;
	unsigned long row_idx, col_idx;	
	int fd;
	unsigned long i,j,k;
	unsigned long no_sites;
	FILE *lp;	
	unsigned long nrows, ncols;
	unsigned long *share_smp = NULL; /* array that keeps percentage of sites */
	double total = 0;
	double map_total = 0;
	double kvamme_gain;
	long null_count = 0; /* keeps count of sites on NULL cells */
	long nocat_count = 0;
	/* category counts and descriptions */
	int cats;
	char **cats_description; /* category labels */
	long *cat_count; /* category counts */
	long null_count_map; /* number of NULL cells in input map */
	long nocat_count_map; /* number of cells that do not fall into the category range [0 .. n] */		
	int debug_mode = 0;		/* 1 to enable writing additional output to logfile */
	time_t systime;

	char errmsg [200];
	struct Map_info in_vect_map;
  	struct line_pnts *vect_points;
	double x,y,z;
	int n_points = 1;
	int cur_type;
	

	/* get current region */
	G_get_window (&region);
	nrows = G_window_rows ();
	ncols = G_window_cols ();	
	
	/* check logfile */
	if (logfile != NULL) {
		debug_mode = 1;	
		if ( !G_legal_filename (logfile) ) {
			delete_tmpfile (map);
			G_fatal_error ("Please specify a legal filename for the logfile.\n");
		}
		/* attempt to write to logfile */
		if ( (lp = fopen ( logfile, "w+" ) ) == NULL )	{
			delete_tmpfile (map);
			G_fatal_error ("Could not create logfile.\n");
		}
		/* we want unbuffered output for the logfile */
		setvbuf (lp,NULL,_IONBF,0);	
		fprintf (lp,"This is %s, version %.2f\n",PROGNAME, PROGVERSION);
		systime = time (NULL);
		fprintf (lp,"Started on %s",ctime(&systime));
		fprintf (lp,"\tlocation    = %s\n",G_location());
		fprintf (lp,"\tmapset      = %s\n",G_mapset());
		fprintf (lp,"\tinput map   = %s\n",map);
		fprintf (lp,"\tsample file = %s\n",sites);
	} else {		
		/* log output to stderr by default */
		lp = stderr;
	}

  	if (1 > Vect_open_old (&in_vect_map, sites, "")) {
		delete_tmpfile (map);
    		sprintf (errmsg, "Could not open input map %s.\n", sites);
    		G_fatal_error (errmsg);
  	}

	vect_points = Vect_new_line_struct ();

	if (all_flag != 1) {
		Vect_set_constraint_region (&in_vect_map, region.north, region.south, 
			region.east, region.west, 0.0, 0.0);
	}
		
	/* get total number of sampling points */
	i = 0;	
	while ((cur_type = Vect_read_next_line (&in_vect_map, vect_points, NULL) > 0)) {
		i ++;
	}

	no_sites = i; /* store this for later use */
			
	/* open raster map */
	fd = G_open_cell_old (map, G_find_cell (map, ""));
	if (fd < 0)
	{
		delete_tmpfile (map);
		G_fatal_error ("Could not open raster map for reading!\n");
	}
	/* allocate a cache and a raster buffer */
	cache = (GT_Row_cache_t *) G_malloc (sizeof (GT_Row_cache_t));
	GT_RC_open (cache, CACHESIZE, fd, CELL_TYPE);
	cellbuf = G_allocate_raster_buf (CELL_TYPE);			
	
	cats = GT_get_stats (map,mapset,&null_count_map, &nocat_count_map, show_progress);
	if ( cats < 2 ) {
		delete_tmpfile (map);
		G_fatal_error ("Input map must have at least two categories.");
	}
	
	/* get category labels and counts */
	cats_description = GT_get_labels (map,mapset);
	if (cats_description == NULL) {
		delete_tmpfile (map);
		G_fatal_error ("Could not read category labels from input map.");
	}
	cat_count = GT_get_c_counts (map,mapset, show_progress);
	if (cat_count == NULL) {
		delete_tmpfile (map);
		G_fatal_error ("Could not count categories in input map.");
	}		
	
	/* allocate a double array to hold statistics */
	share_smp = (unsigned long *) G_malloc ((signed)(cats * sizeof (unsigned long)));
	for (i = 0; i < cats; i++)
	{
		share_smp[i] = 0;
		
	}	
	
	/* count raster values under sampling points */
	i = 0;
	k = 0; /* progress counter for status display */
	
	Vect_rewind (&in_vect_map);	
	
	if ( !quiet_flag ) {
		fprintf (stdout, "Counting sample: \n");
		fflush (stdout);	
	}
	
	/* we MUST not set constraints so that no raster values outside the current region are
	   accessed, which would give an "illegal cache request" error */
	Vect_set_constraint_region (&in_vect_map, region.north, region.south, 
				     region.east, region.west, 0.0, 0.0);
	
	while ((cur_type = Vect_read_next_line (&in_vect_map, vect_points, NULL) > 0)) {	
		Vect_copy_pnts_to_xyz (vect_points, &x, &y, &z, &n_points);		
		k ++;
		if ( !quiet_flag ) {
			G_percent ((signed) k, (signed) no_sites, 1);
		}
		/* get raster row with same northing as sample and perform
		   quantification */
		row_idx = (long) G_northing_to_row (y, &region);
		col_idx = (long) G_easting_to_col (x, &region);				
				
		cellbuf = GT_RC_get (cache, (signed) row_idx);
		/* now read the raster value under the current site */
		if (G_is_c_null_value (&cellbuf[col_idx]) == 0) {
			/* site on cell within category range [0..cats] ? */
			if ( (cellbuf[col_idx] > -1) && (cellbuf[col_idx] <= cats) ) {
				share_smp [cellbuf[col_idx] ] ++;
				/* i keeps track of samples on non-null coverage only */
				/* inside the current region */
				i ++;
			} else {
				if ( uncat_flag ) {
					/* also keep count of sites on uncategorised cells? */
					i ++;
					nocat_count++;
				}
			}				
		}
		if (G_is_c_null_value (&cellbuf[col_idx]) == 1) { 
			/* got a NULL value under this site */
			if (null_flag) { /* only count this, if null flag is set */
				null_count ++;
				i ++;
			}
		}
	}
	
	Vect_close (&in_vect_map);		
	
	fprintf (lp,"\n");
	if ( background ) {
		fprintf (lp,"Distribution of categories under %lu points (%lu in region) and in input map:\n",i,no_sites);	
	} else {
		fprintf (lp,"Distribution of categories under %lu points (%lu in region):\n",i,no_sites);	
	}
	/* determine starting value for total of sites analysed */
	total = 0;
	for ( j=0; j < cats; j ++) {
		total = total + share_smp[j];
		map_total = map_total + cat_count[j];
	}
	if (null_flag) { /* add NULL values to total */	
		total = total + null_count;
		map_total = map_total + null_count_map;
	}
	if (uncat_flag) { /* add uncategorised cells to total */
		total = total + nocat_count;
		map_total = map_total + nocat_count_map;
		
	}
	
	/* Now display those values which the user has chosen */
	if ( (background) && (gain) ) {	
		fprintf (lp,"Cat.\tPts.\t(%%)\tMap\t(%%)\tGain\tDescription\n");				
	}
	if ( (background) && (!gain) ) {	
		fprintf (lp,"Cat.\tPts.\t(%%)\tMap\t(%%)\tDescription\n");		
	}
	if ( (!background) && (gain) ) {	
		fprintf (lp,"Cat.\tPts.\t(%%)\tGain\tDescription\n");
	}
	if ( (!background) && (!gain) ) {	
		fprintf (lp,"Cat.\tPts.\t(%%)\tDescription\n");
	}	
	for ( j = 0; j < cats; j ++) {
		/* if skip_flag is not set: only show categories that have count > 0 */
		if ((skip_flag == 1) || ((skip_flag == 0) && (share_smp[j] > 0))) {
			if ( (background) && (gain) ) {
				/* Kvamme's Gain = 1 - (%area/%sites) */
				kvamme_gain = gstats_gain_K(((double) share_smp[j]*(100/total)),
							    ((double) cat_count[j]*(100/map_total)));							    				
				fprintf (lp, "%lu\t%6lu\t%6.2f\t%8lu %6.2f\t%6.2f\t%s\n", j, share_smp[j], (float) share_smp[j]*(100/total),
						cat_count[j], (float) cat_count[j]*(100/map_total),
						kvamme_gain, cats_description[j]);
			} 
			if ( (background) && (!gain) ) {
				fprintf (lp, "%lu\t%6lu\t%6.2f\t%8lu %6.2f\t%s\n", j, share_smp[j], (float) share_smp[j]*(100/total),
						cat_count[j], (float) cat_count[j]*(100/map_total),
						cats_description[j]);
				
			} 			
			if ( (!background) && (gain) ) {
				kvamme_gain = 1-( (float) cat_count[j]*(100/map_total) / (float) share_smp[j]*(100/total) );
				fprintf (lp, "%lu\t%6lu\t%6.2f\t%6.2f\t%s\n", j, share_smp[j], (float) share_smp[j]*(100/total),						
						kvamme_gain, cats_description[j]);				
			} 			
			if ( (!background) && (!gain) ) {
				fprintf (lp, "%lu\t%6lu\t%6.2f\t%s\n", j, share_smp[j], (float) share_smp[j]*(100/total),
						cats_description[j]);
			} 									
		}
	}
	if (null_flag) {		
		if ( background ) {
			fprintf (lp,"NULL\t%6lu\t%6.2f\t%8lu %6.2f\n",null_count, (float) null_count * 100 / total
						,null_count_map, (float) null_count_map * 100 / map_total);
		} else {
			fprintf (lp,"NULL\t%6lu\t%6.2f\n",null_count, (float) null_count * 100 / total);
		}
	}
	if (uncat_flag) {
		if ( background ) {
			fprintf (lp,"NOCAT\t%6lu\t%6.2f\t%8lu %6.2f\n",nocat_count, (float) nocat_count * 100 / total
						,nocat_count_map, (float) nocat_count_map * 100 / map_total);
		} else {
			fprintf (lp,"NOCAT\t%6lu\t%6.2f\n",nocat_count, (float) nocat_count * 100 / total);
		}		
	}	
	if ( background) {
		fprintf (lp,"TOTAL\t%6lu\t%6.2f\t%8lu %6.2f\n",(long) total, (float) 100, (long) map_total, (float) 100);
	} else {
		fprintf (lp,"TOTAL\t%6lu\t%6.2f\n",(long) total, (float) 100);
	}
	
	/* close cache and sites file; free buffers. */
	GT_RC_close (cache);
	G_free (cellbuf);
	G_free (cache);	
}