예제 #1
0
파일: main.c 프로젝트: rashadkm/grass_cmake
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct
    {
	struct Option *quant, *perc, *slots, *basemap, *covermap, *output;
    } opt;
    struct {
	struct Flag *r, *p;
    } flag;
    const char *basemap, *covermap;
    char **outputs;
    int reclass, print;
    int cover_fd, base_fd;
    struct Range range;
    struct FPRange fprange;
    int i;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("statistics"));
    module->description = _("Compute category quantiles using two passes.");

    opt.basemap = G_define_standard_option(G_OPT_R_BASE);

    opt.covermap = G_define_standard_option(G_OPT_R_COVER);

    opt.quant = G_define_option();
    opt.quant->key = "quantiles";
    opt.quant->type = TYPE_INTEGER;
    opt.quant->required = NO;
    opt.quant->description = _("Number of quantiles");

    opt.perc = G_define_option();
    opt.perc->key = "percentiles";
    opt.perc->type = TYPE_DOUBLE;
    opt.perc->multiple = YES;
    opt.perc->description = _("List of percentiles");
    opt.perc->answer = "50";

    opt.slots = G_define_option();
    opt.slots->key = "bins";
    opt.slots->type = TYPE_INTEGER;
    opt.slots->required = NO;
    opt.slots->description = _("Number of bins to use");
    opt.slots->answer = "1000";

    opt.output = G_define_standard_option(G_OPT_R_OUTPUT);
    opt.output->description = _("Resultant raster map(s)");
    opt.output->required = NO;
    opt.output->multiple = YES;

    flag.r = G_define_flag();
    flag.r->key = 'r';
    flag.r->description =
	_("Create reclass map with statistics as category labels");

    flag.p = G_define_flag();
    flag.p->key = 'p';
    flag.p->description =
	_("Do not create output maps; just print statistics");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    basemap = opt.basemap->answer;
    covermap = opt.covermap->answer;
    outputs = opt.output->answers;
    reclass = flag.r->answer;
    print = flag.p->answer;

    if (!print && !opt.output->answers)
	G_fatal_error(_("Either -%c or %s= must be given"),
			flag.p->key, opt.output->key);

    if (print && opt.output->answers)
	G_fatal_error(_("-%c and %s= are mutually exclusive"),
			flag.p->key, opt.output->key);

    num_slots = atoi(opt.slots->answer);

    if (opt.quant->answer) {
	num_quants = atoi(opt.quant->answer) - 1;
	quants = G_calloc(num_quants, sizeof(DCELL));
	for (i = 0; i < num_quants; i++)
	    quants[i] = 1.0 * (i + 1) / (num_quants + 1);
    }
    else {
	for (i = 0; opt.perc->answers[i]; i++)
	    ;
	num_quants = i;
	quants = G_calloc(num_quants, sizeof(DCELL));
	for (i = 0; i < num_quants; i++)
	    quants[i] = atof(opt.perc->answers[i]) / 100;
	qsort(quants, num_quants, sizeof(DCELL), compare_dcell);
    }

    if (opt.output->answer) {
	for (i = 0; opt.output->answers[i]; i++)
	    ;
	if (i != num_quants)
	    G_fatal_error(_("Number of quantiles (%d) does not match number of output maps (%d)"),
			  num_quants, i);
    }

    base_fd = Rast_open_old(basemap, "");

    cover_fd = Rast_open_old(covermap, "");

    if (Rast_map_is_fp(basemap, "") != 0)
	G_fatal_error(_("The base map must be an integer (CELL) map"));

    if (Rast_read_range(basemap, "", &range) < 0)
	G_fatal_error(_("Unable to read range of base map <%s>"), basemap);

    Rast_get_range_min_max(&range, &min, &max);
    num_cats = max - min + 1;
    if (num_cats > MAX_CATS)
	G_fatal_error(_("Base map <%s> has too many categories (max: %d)"),
		      basemap, MAX_CATS);

    Rast_read_fp_range(covermap, "", &fprange);
    Rast_get_fp_range_min_max(&fprange, &f_min, &f_max);
    slot_size = (f_max - f_min) / num_slots;

    basecats = G_calloc(num_cats, sizeof(struct basecat));

    for (i = 0; i < num_cats; i++)
	basecats[i].slots = G_calloc(num_slots, sizeof(unsigned int));

    rows = Rast_window_rows();
    cols = Rast_window_cols();

    get_slot_counts(base_fd, cover_fd);

    initialize_bins();
    fill_bins(base_fd, cover_fd);


    sort_bins();
    compute_quantiles();

    if (print)
	print_quantiles();
    else if (reclass)
	do_reclass(basemap, outputs);
    else
	do_output(base_fd, outputs, covermap);

    Rast_close(cover_fd);
    Rast_close(base_fd);

    return (EXIT_SUCCESS);
}
int xybinning_quantiles(deque<type> &c, deque<type> &d, int number_of_bins, deque<double> & xs, deque<double> & ys, deque<double> & var, deque<int> & nums, deque<deque<double> > & Mq, double qa, double qb) {		
	
	
	// so, this function takes two datasets (c and d) and gathers the data in bin, takes xs and ys as the average in each bin, var is the variance of the y average 
	// the difference with the same stuff called not_norm_histogram is that the other one averages x with y weights.
	
	xs.clear();
	ys.clear();
	var.clear();
	nums.clear();
	Mq.clear();
	
	
	double min=double(c[0]);
	double max=double(c[0]);
	
	for (int i=0; i<int(c.size()); i++) {
		
		if (min>double(c[i]))
			min=double(c[i]);
		
		if (max<double(c[i]))
			max=double(c[i]);
		
	}
	
	
	
	min-=1e-6;
	max+=1e-6;
	
	
	
			
	if (max==min)
		max+=1e-3;
	
	
	
	deque<deque<double> > hist_x;		// x values in the bin
	deque<deque<double> >  hist_y;		// y values in the bin
		
	double step=min;
	double bin=(max-min)/number_of_bins;		// bin width
	
	deque<double> f;
	while (step<=max+2*bin) {
	
		hist_x.push_back(f);			
		hist_y.push_back(f);			
		step+=bin;
	}
	

	
		
	
	
	for (int i=0; i<int(c.size()); i++) {
		
		
		
		double data=double(c[i]);
		
		if (data>=min && data<=max) {
			
			
			
			int index=int((data-min)/bin);		
			//cout<<data<<" "<<exp(data)<<" "<<index<<endl;
				
			hist_x[index].push_back(double(c[i]));
			hist_y[index].push_back(double(d[i]));
		
		}
		
	}
	
	for (int i=0; i<hist_x.size()-1; i++) {
		
		
		
				
		double x=average_func(hist_x[i]);
		double y=average_func(hist_y[i]);
		
		
		
		//cout<<x<<" "<<exp(x)<<" "<<y<<endl;
		
		if (hist_y[i].size()>0) {
			xs.push_back(x);
			ys.push_back(y);
			var.push_back(variance_func(hist_y[i])/double(hist_y[i].size()));
			nums.push_back(hist_y[i].size());
			sort(hist_y[i].begin(), hist_y[i].end());
			
			deque<double> qs;
			compute_quantiles(qa, hist_y[i], qs);
			compute_quantiles(qb, hist_y[i], qs);
			
			Mq.push_back(qs);
			//cout<<x<<" "<<exp(x)<<" "<<y<<" "<<(hist_y[i].size())<<" "<<variance_func(hist_y[i])<<endl;

			
		}
		
		
	
	}
	
	
		
	
	for(int i=0; i<var.size(); i++)
		if(var[i]<1e-8)
			var[i]=1e-8;
	
	



	return 0;

}