void gpWrapper::evaluate(array_1d<double> &pt, double *chiout, int *dex, int validity){ if(chisq==NULL){ printf("WARNING chisq is NULL but you just called evaluate\n"); exit(1); } dex[0]=-1; if(validity==-1){ validity=is_valid(pt,chiout); } if(validity==0){ return; } else{ chiout[0]=(*chisq)(pt); if(chiout[0]<chisq_exception){ /* Add the point to the Gaussian Process */ add_pt(pt,chiout[0]); dex[0]=gg->get_pts()-1; whereFrom.set(dex[0],iWhere); whereCt.add_val(iWhere,1); } } }
int init_vars(int argc, char *argv[]) { int r, c; int ele_fd, wat_fd, fd = -1; int seg_rows, seg_cols, num_cseg_total, num_open_segs, num_open_array_segs; double memory_divisor, heap_mem, seg_factor, disk_space; /* int page_block, num_cseg; */ int max_bytes; CELL *buf, alt_value, *alt_value_buf, block_value; char asp_value; DCELL wat_value; DCELL dvalue; WAT_ALT wa, *wabuf; ASP_FLAG af, af_nbr, *afbuf; char MASK_flag; void *elebuf, *ptr, *watbuf, *watptr; int ele_map_type, wat_map_type; size_t ele_size, wat_size; int ct_dir, r_nbr, c_nbr; G_gisinit(argv[0]); /* input */ ele_flag = pit_flag = run_flag = ril_flag = 0; /* output */ wat_flag = asp_flag = bas_flag = seg_flag = haf_flag = tci_flag = 0; bas_thres = 0; /* shed, unused */ arm_flag = dis_flag = 0; /* RUSLE */ ob_flag = st_flag = sl_flag = sg_flag = ls_flag = er_flag = 0; nxt_avail_pt = 0; /* dep_flag = 0; */ max_length = d_zero = 0.0; d_one = 1.0; ril_value = -1.0; /* dep_slope = 0.0; */ max_bytes = 0; sides = 8; mfd = 1; c_fac = 5; abs_acc = 0; ele_scale = 1; segs_mb = 300; /* scan options */ for (r = 1; r < argc; r++) { if (sscanf(argv[r], "elevation=%s", ele_name) == 1) ele_flag++; else if (sscanf(argv[r], "accumulation=%s", wat_name) == 1) wat_flag++; else if (sscanf(argv[r], "tci=%s", tci_name) == 1) tci_flag++; else if (sscanf(argv[r], "drainage=%s", asp_name) == 1) asp_flag++; else if (sscanf(argv[r], "depression=%s", pit_name) == 1) pit_flag++; else if (sscanf(argv[r], "threshold=%d", &bas_thres) == 1) ; else if (sscanf(argv[r], "max_slope_length=%lf", &max_length) == 1) ; else if (sscanf(argv[r], "basin=%s", bas_name) == 1) bas_flag++; else if (sscanf(argv[r], "stream=%s", seg_name) == 1) seg_flag++; else if (sscanf(argv[r], "half_basin=%s", haf_name) == 1) haf_flag++; else if (sscanf(argv[r], "flow=%s", run_name) == 1) run_flag++; else if (sscanf(argv[r], "ar=%s", arm_name) == 1) arm_flag++; /* slope length else if (sscanf(argv[r], "slope_length=%s", sl_name) == 1) sl_flag++; */ else if (sscanf(argv[r], "slope_steepness=%s", sg_name) == 1) sg_flag++; else if (sscanf(argv[r], "length_slope=%s", ls_name) == 1) ls_flag++; else if (sscanf(argv[r], "blocking=%s", ob_name) == 1) ob_flag++; else if (sscanf(argv[r], "memory=%lf", &segs_mb) == 1) ; else if (sscanf(argv[r], "disturbed_land=%s", ril_name) == 1) { if (sscanf(ril_name, "%lf", &ril_value) == 0) { ril_value = -1.0; ril_flag++; } } /* slope deposition else if (sscanf (argv[r], "sd=%[^\n]", dep_name) == 1) dep_flag++; */ else if (sscanf(argv[r], "-%d", &sides) == 1) { if (sides != 4) usage(argv[0]); } else if (sscanf(argv[r], "convergence=%d", &c_fac) == 1) ; else if (strcmp(argv[r], "-s") == 0) mfd = 0; else if (strcmp(argv[r], "-a") == 0) abs_acc = 1; else usage(argv[0]); } /* check options */ if (mfd == 1 && (c_fac < 1 || c_fac > 10)) { G_fatal_error("Convergence factor must be between 1 and 10."); } if ((ele_flag != 1) || ((arm_flag == 1) && ((bas_thres <= 0) || ((haf_flag != 1) && (bas_flag != 1)))) || ((bas_thres <= 0) && ((bas_flag == 1) || (seg_flag == 1) || (haf_flag == 1) || (sl_flag == 1) || (sg_flag == 1) || (ls_flag == 1))) ) usage(argv[0]); tot_parts = 4; if (sl_flag || sg_flag || ls_flag) er_flag = 1; /* do RUSLE */ if (er_flag) tot_parts++; /* define basins */ if (seg_flag || bas_flag || haf_flag) tot_parts++; G_message(_n("SECTION 1 beginning: Initiating Variables. %d section total.", "SECTION 1 beginning: Initiating Variables. %d sections total.", tot_parts), tot_parts); this_mapset = G_mapset(); /* for sd factor if (dep_flag) { if (sscanf (dep_name, "%lf", &dep_slope) != 1) { dep_flag = -1; } } */ G_get_set_window(&window); nrows = Rast_window_rows(); ncols = Rast_window_cols(); if (max_length <= d_zero) max_length = 10 * nrows * window.ns_res + 10 * ncols * window.ew_res; if (window.ew_res < window.ns_res) half_res = .5 * window.ew_res; else half_res = .5 * window.ns_res; diag = sqrt(window.ew_res * window.ew_res + window.ns_res * window.ns_res); if (sides == 4) diag *= 0.5; /* Segment rows and cols: 64 */ seg_rows = SROW; seg_cols = SCOL; /* seg_factor * <size in bytes> = segment size in KB */ seg_factor = seg_rows * seg_rows / 1024.; if (segs_mb < 3.0) { segs_mb = 3; G_warning(_("Maximum memory to be used was smaller than 3 MB," " set to 3 MB.")); } /* balance segment files */ /* elevation + accumulation: * 2 */ memory_divisor = sizeof(WAT_ALT) * 2; disk_space = sizeof(WAT_ALT); /* aspect and flags: * 4 */ memory_divisor += sizeof(ASP_FLAG) * 4; disk_space += sizeof(ASP_FLAG); /* astar_points: / 16 */ /* ideally only a few but large segments */ memory_divisor += sizeof(POINT) / 16.; disk_space += sizeof(POINT); /* heap points: / 4 */ memory_divisor += sizeof(HEAP_PNT) / 4.; disk_space += sizeof(HEAP_PNT); /* TCI: as is */ if (tci_flag) { memory_divisor += sizeof(double); disk_space += sizeof(double); } /* RUSLE */ if (er_flag) { /* r_h */ memory_divisor += 4; disk_space += 4; /* s_l */ memory_divisor += 8; disk_space += 8; /* s_g */ if (sg_flag) { memory_divisor += 8; disk_space += 8; } /* l_s */ if (ls_flag) { memory_divisor += 8; disk_space += 8; } /* ril */ if (ril_flag) { memory_divisor += 8; disk_space += 8; } } /* KB -> MB */ memory_divisor = memory_divisor * seg_factor / 1024.; disk_space = disk_space * seg_factor / 1024.; num_open_segs = segs_mb / memory_divisor; heap_mem = num_open_segs * seg_factor * sizeof(HEAP_PNT) / (4. * 1024.); G_debug(1, "segs MB: %.0f", segs_mb); G_debug(1, "region rows: %d", nrows); G_debug(1, "seg rows: %d", seg_rows); G_debug(1, "region cols: %d", ncols); G_debug(1, "seg cols: %d", seg_cols); num_cseg_total = nrows / SROW + 1; G_debug(1, " row segments:\t%d", num_cseg_total); num_cseg_total = ncols / SCOL + 1; G_debug(1, "column segments:\t%d", num_cseg_total); num_cseg_total = (ncols / seg_cols + 1) * (nrows / seg_rows + 1); G_debug(1, " total segments:\t%d", num_cseg_total); G_debug(1, " open segments:\t%d", num_open_segs); /* nonsense to have more segments open than exist */ if (num_open_segs > num_cseg_total) num_open_segs = num_cseg_total; G_debug(1, " open segments after adjusting:\t%d", num_open_segs); disk_space *= num_cseg_total; if (disk_space < 1024.0) G_verbose_message(_("Will need up to %.2f MB of disk space"), disk_space); else G_verbose_message(_("Will need up to %.2f GB (%.0f MB) of disk space"), disk_space / 1024.0, disk_space); if (er_flag) { cseg_open(&r_h, seg_rows, seg_cols, num_open_segs); cseg_read_cell(&r_h, ele_name, ""); } /* read elevation input and mark NULL/masked cells */ /* scattered access: alt, watalt, bitflags, asp */ seg_open(&watalt, nrows, ncols, seg_rows, seg_cols, num_open_segs * 2, sizeof(WAT_ALT)); seg_open(&aspflag, nrows, ncols, seg_rows, seg_cols, num_open_segs * 4, sizeof(ASP_FLAG)); if (tci_flag) dseg_open(&tci, seg_rows, seg_cols, num_open_segs); /* open elevation input */ ele_fd = Rast_open_old(ele_name, ""); ele_map_type = Rast_get_map_type(ele_fd); ele_size = Rast_cell_size(ele_map_type); elebuf = Rast_allocate_buf(ele_map_type); afbuf = G_malloc(ncols * sizeof(ASP_FLAG)); if (ele_map_type == FCELL_TYPE || ele_map_type == DCELL_TYPE) ele_scale = 1000; /* should be enough to do the trick */ /* initial flow accumulation */ if (run_flag) { wat_fd = Rast_open_old(run_name, ""); wat_map_type = Rast_get_map_type(ele_fd); wat_size = Rast_cell_size(ele_map_type); watbuf = Rast_allocate_buf(ele_map_type); } else { watbuf = watptr = NULL; wat_fd = wat_size = wat_map_type = -1; } wabuf = G_malloc(ncols * sizeof(WAT_ALT)); alt_value_buf = Rast_allocate_buf(CELL_TYPE); /* read elevation input and mark NULL/masked cells */ G_message("SECTION 1a: Mark masked and NULL cells"); MASK_flag = 0; do_points = (GW_LARGE_INT) nrows * ncols; for (r = 0; r < nrows; r++) { G_percent(r, nrows, 1); Rast_get_row(ele_fd, elebuf, r, ele_map_type); ptr = elebuf; if (run_flag) { Rast_get_row(wat_fd, watbuf, r, wat_map_type); watptr = watbuf; } for (c = 0; c < ncols; c++) { afbuf[c].flag = 0; afbuf[c].asp = 0; /* check for masked and NULL cells */ if (Rast_is_null_value(ptr, ele_map_type)) { FLAG_SET(afbuf[c].flag, NULLFLAG); FLAG_SET(afbuf[c].flag, INLISTFLAG); FLAG_SET(afbuf[c].flag, WORKEDFLAG); Rast_set_c_null_value(&alt_value, 1); /* flow accumulation */ Rast_set_d_null_value(&wat_value, 1); do_points--; } else { if (ele_map_type == CELL_TYPE) { alt_value = *((CELL *)ptr); } else if (ele_map_type == FCELL_TYPE) { dvalue = *((FCELL *)ptr); dvalue *= ele_scale; alt_value = ele_round(dvalue); } else if (ele_map_type == DCELL_TYPE) { dvalue = *((DCELL *)ptr); dvalue *= ele_scale; alt_value = ele_round(dvalue); } /* flow accumulation */ if (run_flag) { if (Rast_is_null_value(watptr, wat_map_type)) { wat_value = 0; /* ok ? */ } else { if (wat_map_type == CELL_TYPE) { wat_value = *((CELL *)watptr); } else if (wat_map_type == FCELL_TYPE) { wat_value = *((FCELL *)watptr); } else if (wat_map_type == DCELL_TYPE) { wat_value = *((DCELL *)watptr); } } } else { wat_value = 1; } } wabuf[c].wat = wat_value; wabuf[c].ele = alt_value; alt_value_buf[c] = alt_value; ptr = G_incr_void_ptr(ptr, ele_size); if (run_flag) { watptr = G_incr_void_ptr(watptr, wat_size); } } seg_put_row(&watalt, (char *) wabuf, r); seg_put_row(&aspflag, (char *)afbuf, r); if (er_flag) { cseg_put_row(&r_h, alt_value_buf, r); } } G_percent(nrows, nrows, 1); /* finish it */ Rast_close(ele_fd); G_free(wabuf); G_free(afbuf); if (run_flag) { Rast_close(wat_fd); G_free(watbuf); } MASK_flag = (do_points < nrows * ncols); /* do RUSLE */ if (er_flag) { if (ob_flag) { fd = Rast_open_old(ob_name, ""); buf = Rast_allocate_c_buf(); for (r = 0; r < nrows; r++) { G_percent(r, nrows, 1); Rast_get_c_row(fd, buf, r); for (c = 0; c < ncols; c++) { block_value = buf[c]; if (!Rast_is_c_null_value(&block_value) && block_value) { seg_get(&aspflag, (char *)&af, r, c); FLAG_SET(af.flag, RUSLEBLOCKFLAG); seg_put(&aspflag, (char *)&af, r, c); } } } G_percent(nrows, nrows, 1); /* finish it */ Rast_close(fd); G_free(buf); } if (ril_flag) { dseg_open(&ril, seg_rows, seg_cols, num_open_segs); dseg_read_cell(&ril, ril_name, ""); } /* dseg_open(&slp, SROW, SCOL, num_open_segs); */ dseg_open(&s_l, seg_rows, seg_cols, num_open_segs); if (sg_flag) dseg_open(&s_g, seg_rows, seg_cols, num_open_segs); if (ls_flag) dseg_open(&l_s, seg_rows, seg_cols, num_open_segs); } G_debug(1, "open segments for A* points"); /* columns per segment */ seg_cols = seg_rows * seg_rows; num_cseg_total = do_points / seg_cols; if (do_points % seg_cols > 0) num_cseg_total++; /* no need to have more segments open than exist */ num_open_array_segs = num_open_segs / 16.; if (num_open_array_segs > num_cseg_total) num_open_array_segs = num_cseg_total; if (num_open_array_segs < 1) num_open_array_segs = 1; seg_open(&astar_pts, 1, do_points, 1, seg_cols, num_open_array_segs, sizeof(POINT)); /* one-based d-ary search_heap with astar_pts */ G_debug(1, "open segments for A* search heap"); G_debug(1, "heap memory %.2f MB", heap_mem); /* columns per segment */ /* larger is faster */ seg_cols = seg_rows * seg_rows; num_cseg_total = do_points / seg_cols; if (do_points % seg_cols > 0) num_cseg_total++; /* no need to have more segments open than exist */ num_open_array_segs = (1 << 20) * heap_mem / (seg_cols * sizeof(HEAP_PNT)); if (num_open_array_segs > num_cseg_total) num_open_array_segs = num_cseg_total; if (num_open_array_segs < 2) num_open_array_segs = 2; G_debug(1, "A* search heap open segments %d, total %d", num_open_array_segs, num_cseg_total); /* the search heap will not hold more than 5% of all points at any given time ? */ /* chances are good that the heap will fit into one large segment */ seg_open(&search_heap, 1, do_points + 1, 1, seg_cols, num_open_array_segs, sizeof(HEAP_PNT)); G_message(_("SECTION 1b: Determining Offmap Flow.")); /* heap is empty */ heap_size = 0; if (pit_flag) { buf = Rast_allocate_c_buf(); fd = Rast_open_old(pit_name, ""); } else buf = NULL; first_astar = first_cum = -1; for (r = 0; r < nrows; r++) { G_percent(r, nrows, 1); if (pit_flag) Rast_get_c_row(fd, buf, r); for (c = 0; c < ncols; c++) { seg_get(&aspflag, (char *)&af, r, c); if (!FLAG_GET(af.flag, NULLFLAG)) { if (er_flag) dseg_put(&s_l, &half_res, r, c); asp_value = af.asp; if (r == 0 || c == 0 || r == nrows - 1 || c == ncols - 1) { /* dseg_get(&wat, &wat_value, r, c); */ seg_get(&watalt, (char *)&wa, r, c); wat_value = wa.wat; if (wat_value > 0) { wat_value = -wat_value; /* dseg_put(&wat, &wat_value, r, c); */ wa.wat = wat_value; seg_put(&watalt, (char *)&wa, r, c); } if (r == 0) asp_value = -2; else if (c == 0) asp_value = -4; else if (r == nrows - 1) asp_value = -6; else if (c == ncols - 1) asp_value = -8; /* cseg_get(&alt, &alt_value, r, c); */ alt_value = wa.ele; add_pt(r, c, alt_value); FLAG_SET(af.flag, INLISTFLAG); FLAG_SET(af.flag, EDGEFLAG); af.asp = asp_value; seg_put(&aspflag, (char *)&af, r, c); } else { seg_get(&watalt, (char *)&wa, r, c); for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (r_nbr, c_nbr) for neighbours */ r_nbr = r + nextdr[ct_dir]; c_nbr = c + nextdc[ct_dir]; seg_get(&aspflag, (char *)&af_nbr, r_nbr, c_nbr); if (FLAG_GET(af_nbr.flag, NULLFLAG)) { af.asp = -1 * drain[r - r_nbr + 1][c - c_nbr + 1]; add_pt(r, c, wa.ele); FLAG_SET(af.flag, INLISTFLAG); FLAG_SET(af.flag, EDGEFLAG); seg_put(&aspflag, (char *)&af, r, c); wat_value = wa.wat; if (wat_value > 0) { wa.wat = -wat_value; seg_put(&watalt, (char *)&wa, r, c); } break; } } } /* real depression ? */ if (pit_flag && asp_value == 0) { if (!Rast_is_c_null_value(&buf[c]) && buf[c] != 0) { seg_get(&watalt, (char *)&wa, r, c); add_pt(r, c, wa.ele); FLAG_SET(af.flag, INLISTFLAG); FLAG_SET(af.flag, EDGEFLAG); seg_put(&aspflag, (char *)&af, r, c); wat_value = wa.wat; if (wat_value > 0) { wa.wat = -wat_value; seg_put(&watalt, (char *)&wa, r, c); } } } } /* end non-NULL cell */ } /* end column */ } G_percent(r, nrows, 1); /* finish it */ return 0; }
int do_astar(void) { int doer, count; int upr, upc, r = -1, c = -1, ct_dir; CELL alt_val, alt_nbr[8]; WAT_ALT wa; char asp_val; char flag_value, is_in_list, is_worked; HEAP_PNT heap_p; /* sides * |7|1|4| * |2| |3| * |5|0|6| */ int nbr_ew[8] = { 0, 1, 2, 3, 1, 0, 0, 1 }; int nbr_ns[8] = { 0, 1, 2, 3, 3, 2, 3, 2 }; double dx, dy, dist_to_nbr[8], ew_res, ns_res; double slope[8]; int skip_diag; int count_edge = 0, count_diag = 0, count_edge_sink = 0, count_diag_sink = 0; G_message(_("SECTION 2: A* Search.")); for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (upr, upc) for neighbours */ upr = nextdr[ct_dir]; upc = nextdc[ct_dir]; /* account for rare cases when ns_res != ew_res */ dy = ABS(upr) * window.ns_res; dx = ABS(upc) * window.ew_res; if (ct_dir < 4) dist_to_nbr[ct_dir] = dx + dy; else dist_to_nbr[ct_dir] = sqrt(dx * dx + dy * dy); } ew_res = window.ew_res; ns_res = window.ns_res; if (heap_size == 0) G_fatal_error(_("No seeds for A* Search")); G_debug(1, "heap size %d, points %d", heap_size, do_points); count = 0; doer = do_points - 1; /* A* Search: search uphill, get downhill paths */ while (heap_size > 0) { G_percent(count++, do_points, 1); heap_p = drop_pt(); r = heap_p.pnt.r; c = heap_p.pnt.c; G_debug(3, "heap size %d, r %d, c %d", heap_size, r, c); alt_val = heap_p.ele; /* check all neighbours, breadth first search */ for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (upr, upc) for this neighbour */ upr = r + nextdr[ct_dir]; upc = c + nextdc[ct_dir]; slope[ct_dir] = alt_nbr[ct_dir] = 0; /* check if upr, upc are within region */ if (upr >= 0 && upr < nrows && upc >= 0 && upc < ncols) { bseg_get(&bitflags, &flag_value, upr, upc); is_in_list = FLAG_GET(flag_value, INLISTFLAG); is_worked = FLAG_GET(flag_value, WORKEDFLAG); skip_diag = 0; /* avoid diagonal flow direction bias */ if (!is_worked) { seg_get(&watalt, (char *)&wa, upr, upc); alt_nbr[ct_dir] = wa.ele; slope[ct_dir] = get_slope2(alt_val, alt_nbr[ct_dir], dist_to_nbr[ct_dir]); } if (!is_in_list) { if (ct_dir > 3 && slope[ct_dir] > 0) { if (slope[nbr_ew[ct_dir]] > 0) { /* slope to ew nbr > slope to center */ if (slope[ct_dir] < get_slope2(alt_nbr[nbr_ew[ct_dir]], alt_nbr[ct_dir], ew_res)) skip_diag = 1; } if (!skip_diag && slope[nbr_ns[ct_dir]] > 0) { /* slope to ns nbr > slope to center */ if (slope[ct_dir] < get_slope2(alt_nbr[nbr_ns[ct_dir]], alt_nbr[ct_dir], ns_res)) skip_diag = 1; } } } /* add neighbour as new point if not in the list */ if (is_in_list == 0 && skip_diag == 0) { /* set flow direction */ asp_val = drain[upr - r + 1][upc - c + 1]; add_pt(upr, upc, alt_nbr[ct_dir]); bseg_put(&asp, &asp_val, upr, upc); FLAG_SET(flag_value, INLISTFLAG); bseg_put(&bitflags, &flag_value, upr, upc); if (alt_nbr[ct_dir] < alt_val) { if (ct_dir < 4) count_edge_sink++; else count_diag_sink++; } /* includes flat areas */ else { if (ct_dir < 4) count_edge++; else count_diag++; } } else if (is_in_list && is_worked == 0 && FLAG_GET(flag_value, EDGEFLAG)) { /* neighbour is edge in list, not yet worked */ bseg_get(&asp, &asp_val, upr, upc); if (asp_val < 0) { /* adjust flow direction for edge cell */ asp_val = drain[upr - r + 1][upc - c + 1]; bseg_put(&asp, &asp_val, upr, upc); seg_get(&watalt, (char *)&wa, r, c); if (wa.wat > 0) { wa.wat = -wa.wat; seg_put(&watalt, (char *)&wa, r, c); } } /* neighbour is inside real depression, not yet worked */ else if (asp_val == 0) { asp_val = drain[upr - r + 1][upc - c + 1]; bseg_put(&asp, &asp_val, upr, upc); } } } } /* add astar points to sorted list for flow accumulation */ seg_put(&astar_pts, (char *)&heap_p.pnt, 0, doer); doer--; bseg_get(&bitflags, &flag_value, r, c); FLAG_SET(flag_value, WORKEDFLAG); bseg_put(&bitflags, &flag_value, r, c); } if (doer != -1) G_fatal_error(_("bug in A* Search: doer %d heap size %d count %d"), doer, heap_size, count); seg_close(&search_heap); G_percent(count, do_points, 1); /* finish it */ G_debug(1, "edge direction: %d (%.2f%%)", count_edge, (double) 100. * count_edge / (count_edge + count_diag)); G_debug(1, "diag direction: %d (%.2f%%)", count_diag, (double) 100. * count_diag / (count_edge + count_diag)); G_debug(1, "edge out of depression: %d (%.2f%%)", count_edge_sink, (double) 100. * count_edge_sink / (count_edge_sink + count_diag_sink)); G_debug(1, "diag out of depression: %d (%.2f%%)", count_diag_sink, (double) 100. * count_diag_sink / (count_edge_sink + count_diag_sink)); return 0; }