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; }