int grid_id(GRID_ID_ARGS) { int gdt, res, scan, nx, ny, n; unsigned int npnts; if (axes_earth(sec, r_major, r_minor)) fatal_error("grid_id: axes undefined",""); gdt = code_table_3_1(sec); switch (gdt) { case 0: *proj_id = p_latlon; break; case 1: *proj_id = p_rotated_latlon; break; case 10: *proj_id = p_mercator; break; case 20: *proj_id = p_polar_stereographic; break; case 30: *proj_id = p_lambert_conic; break; default: *proj_id = p_unknown; break; } /* get nx, ny n */ get_nxny(sec, &nx, &ny, &npnts, &res, &scan); n = (int) npnts; grid_defn->nx = nx; grid_defn->ny = ny; grid_defn->n = npnts; /* get xy_list */ grid_defn->valid_xy_list = 0; return 0; }
int irr_grid2ll(unsigned char **sec, double **lat, double **lon) { unsigned char *gds; int i; double *llat, *llon; int nnx, nny, nres, nscan; unsigned int nnpnts; get_nxny(sec, &nnx, &nny, &nnpnts, &nres, &nscan); if (nnpnts == 0) return 0; if ((*lat = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("space_view2ll memory allocation failed",""); } if ((*lon = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("space_view2ll memory allocation failed",""); } llat = *lat; llon = *lon; gds = sec[3]; for (i = 0; i < nnpnts; i++) { *llat++ = (double) 1e-6 * int4(gds+30+i*8); *llon++ = (double) 1e-6 * int4(gds+34+i*8); } return 0; }
int rd_grib_rec2(FILE *input, long int pos, unsigned char **pds, unsigned char **gds, float **data, int *ndata, int *scale10, int *scale2) { int len, nxny; unsigned char *lpds, *lgds, *lbms, *lbds; static float *array = NULL; static int array_size = 0; len = rd_grib_msg(input, pos, &lpds, &lgds, &lbms, &lbds); if (len <= 0) return len; *scale10 = PDS_DecimalScale((lpds)); *scale2 = BDS_BinScale((lbds)); nxny = get_nxny(lpds, lgds, lbms, lbds); if (nxny > array_size) { if (array_size) free(array); if ((array = (float *) malloc(nxny * sizeof (float))) == NULL) { fprintf(stderr,"malloc failure in " __FILE__); exit(8); } array_size = nxny; } unpk_bds(array, lpds, lgds, lbms, lbds, nxny); *pds = lpds; *gds = lgds; *data = array; *ndata = nxny; return len; }
int cyclic(unsigned char **sec) { int grid_template, nx, ny, res, scan, flag_3_3, no_dx, basic_ang, sub_ang; unsigned int npnts; unsigned char *gds; double dlon, units, lon1, lon2; get_nxny(sec, &nx, &ny, &npnts, &res, &scan); if (GDS_Scan_staggered(scan)) return 0; if (nx <= 1 || ny <= 0) return 0; grid_template = code_table_3_1(sec); gds = sec[3]; flag_3_3 = flag_table_3_3(sec); no_dx = 0; if (flag_3_3 != -1) { if ((flag_3_3 & 0x20) == 0) no_dx = 1; } if (no_dx) return 0; if (grid_template == 0) { basic_ang = GDS_LatLon_basic_ang(gds); sub_ang = GDS_LatLon_sub_ang(gds); units = basic_ang == 0 ? 0.000001 : (double) basic_ang / (double) sub_ang; /* dlon has to be defined */ dlon = units * GDS_LatLon_dlon(gds); return (fabs(nx*dlon-360.0) < ERROR); } if (grid_template == 10) { if (output_order != wesn) return 0; // only works with we:sn order lon1 = GDS_Mercator_lon1(gds); lon2 = GDS_Mercator_lon2(gds); if (lon2 < lon1) lon2 += 360.0; dlon = (lon2-lon1)*nx/(nx-1.0); return (fabs(dlon-360.0) < ERROR); } if (grid_template == 40) { basic_ang = GDS_Gaussian_basic_ang(gds); sub_ang = GDS_Gaussian_sub_ang(gds); units = basic_ang == 0 ? 0.000001 : (double) basic_ang / (double) sub_ang; /* dlon has to be defined */ dlon = units * GDS_Gaussian_dlon(gds); return (fabs(nx*dlon-360.0) < ERROR); } return 0; }
int cyclic(unsigned char **sec) { int grid_template, nx, ny, res, scan, flag_3_3, no_dx, basic_ang, sub_ang; unsigned int npnts; unsigned char *gds; double dlon, units; get_nxny(sec, &nx, &ny, &npnts, &res, &scan); if ((unsigned) (nx * ny) != npnts) return 0; if (nx <= 0 || ny <= 0) return 0; grid_template = code_table_3_1(sec); gds = sec[3]; flag_3_3 = flag_table_3_3(sec); no_dx = 0; if (flag_3_3 != -1) { if ((flag_3_3 & 0x20) == 0) no_dx = 1; } if (grid_template == 0) { basic_ang = GDS_LatLon_basic_ang(gds); sub_ang = GDS_LatLon_sub_ang(gds); units = basic_ang == 0 ? 0.000001 : (double) basic_ang / (double) sub_ang; dlon = units * GDS_LatLon_dlon(gds); if (no_dx) dlon = 0.0; dlon = nx * dlon; return (fabs(dlon-360.0) < ERROR); } if (grid_template == 10) { dlon = GDS_Mercator_dx(gds); if (no_dx) dlon = 0.0; dlon = nx * dlon; return (fabs(dlon-360.0) < ERROR); } // need to add gaussian grid - a bit more complicated return 0; }
int gctpc_get_latlon(unsigned char **sec, double **lon, double **lat) { int gdt; unsigned char *gds; double r_maj; /* major axis */ double r_min; /* minor axis */ double lat1; /* first standard parallel */ double lat2; /* second standard parallel */ double c_lon; /* center longitude */ double c_lat; /* center latitude */ double false_east; /* x offset in meters */ double false_north; double dx, dy; double x0, y0; long int (*inv_fn)(); double *llat, *llon, rlon, rlat; int i, nnx, nny, nres, nscan; unsigned int nnpnts; long long_i; gdt = code_table_3_1(sec); gds = sec[3]; /* only process certain grids */ if (gdt != 10 && gdt != 20 && gdt != 30 && gdt != 31) return 1; get_nxny(sec, &nnx, &nny, &nnpnts, &nres, &nscan); /* potentially staggered */ if (nnx < 1 || nny < 1) return 1; llat = *lat; llon = *lon; if (llat != NULL) { free(llat); free(llon); *lat = *lon = llat = llon = NULL; } inv_fn = NULL; dx = dy = 0.0; if (gdt == 10) { // mercator /* get earth axis */ axes_earth(sec, &r_maj, &r_min); dy = GDS_Mercator_dy(gds); dx = GDS_Mercator_dx(gds); /* central point */ c_lon = GDS_Mercator_ori_angle(gds) * (M_PI/180.0); c_lat = GDS_Mercator_latD(gds) * (M_PI/180.0); /* find the eastling and northing of of the 1st grid point */ false_east = false_north = 0.0; long_i = merforint(r_maj,r_min,c_lon,c_lat,false_east,false_north); rlon = GDS_Mercator_lon1(gds) * (M_PI/180.0); rlat = GDS_Mercator_lat1(gds) * (M_PI/180.0); long_i = merfor(rlon, rlat, &x0, &y0); /* initialize for 1st grid point */ x0 = -x0; y0 = -y0; long_i = merinvint(r_maj,r_min,c_lon,c_lat,x0,y0); inv_fn = &merinv; } else if (gdt == 20) { // polar stereographic /* get earth axis */ axes_earth(sec, &r_maj, &r_min); dy = GDS_Polar_dy(gds); dx = GDS_Polar_dx(gds); /* central point */ c_lon = GDS_Polar_lov(gds) * (M_PI/180.0); c_lat = GDS_Polar_lad(gds) * (M_PI/180.0); /* find the eastling and northing of of the 1st grid point */ false_east = false_north = 0.0; long_i = psforint(r_maj,r_min,c_lon,c_lat,false_east,false_north); rlon = GDS_Polar_lon1(gds) * (M_PI/180.0); rlat = GDS_Polar_lat1(gds) * (M_PI/180.0); long_i = psfor(rlon, rlat, &x0, &y0); /* initialize for 1st grid point */ x0 = -x0; y0 = -y0; long_i = psinvint(r_maj,r_min,c_lon,c_lat,x0,y0); inv_fn = &psinv; } else if (gdt == 30) { // lambert conformal conic /* get earth axis */ axes_earth(sec, &r_maj, &r_min); dy = GDS_Lambert_dy(gds); dx = GDS_Lambert_dx(gds); //printf(">>> gctpc dx %lf, dy %lf\n", dx, dy); /* latitudes of tangent/intersection */ lat1 = GDS_Lambert_Latin1(gds) * (M_PI/180.0); lat2 = GDS_Lambert_Latin2(gds) * (M_PI/180.0); /* central point */ c_lon = GDS_Lambert_Lov(gds) * (M_PI/180.0); c_lat = GDS_Lambert_LatD(gds) * (M_PI/180.0); /* find the eastling and northing of of the 1st grid point */ false_east = false_north = 0.0; long_i = lamccforint(r_maj,r_min,lat1,lat2,c_lon,c_lat,false_east,false_north); rlon = GDS_Lambert_Lo1(gds) * (M_PI/180.0); rlat = GDS_Lambert_La1(gds) * (M_PI/180.0); long_i = lamccfor(rlon, rlat, &x0, &y0); /* initialize for 1st grid point */ x0 = -x0; y0 = -y0; long_i = lamccinvint(r_maj,r_min,lat1,lat2,c_lon,c_lat,x0,y0); inv_fn = &lamccinv; } else if (gdt == 31) { // albers equal area /* get earth axis */ axes_earth(sec, &r_maj, &r_min); dy = GDS_Albers_dy(gds); dx = GDS_Albers_dx(gds); /* latitudes of tangent/intersection */ lat1 = GDS_Albers_Latin1(gds) * (M_PI/180.0); lat2 = GDS_Albers_Latin2(gds) * (M_PI/180.0); /* central point */ c_lon = GDS_Albers_Lov(gds) * (M_PI/180.0); c_lat = GDS_Albers_LatD(gds) * (M_PI/180.0); /* find the eastling and northing of of the 1st grid point */ false_east = false_north = 0.0; long_i = alberforint(r_maj,r_min,lat1,lat2,c_lon,c_lat,false_east,false_north); rlon = GDS_Albers_Lo1(gds) * (M_PI/180.0); rlat = GDS_Albers_La1(gds) * (M_PI/180.0); long_i = alberfor(rlon, rlat, &x0, &y0); /* initialize for 1st grid point */ x0 = -x0; y0 = -y0; long_i = alberinvint(r_maj,r_min,lat1,lat2,c_lon,c_lat,x0,y0); inv_fn = &alberinv; } if (inv_fn == NULL) return 1; if ((*lat = llat = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("gctpc_get_latlon memory allocation failed",""); } if ((*lon = llon = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("gctpc_get_latlon memory allocation failed",""); } /* put x[] and y[] values in lon and lat */ if (stagger(sec, nnpnts, llon, llat)) fatal_error("gctpc: stagger problem",""); printf(">> stagger gctpc x00 %lf y00 %lf\n",llon[0], llat[0]); #pragma omp parallel for schedule(static) private(i) for (i = 0; i < nnpnts; i++) { inv_fn(llon[i]*dx, llat[i]*dy, llon+i, llat+i); llat[i] *= (180.0 / M_PI); llon[i] *= (180.0 / M_PI); if (llon[i] < 0.0) llon[i] += 360.0; } return 0; }
int small_grib(unsigned char **sec, int mode, float *data, double *lon, double *lat, unsigned int ndata, int ix0, int ix1, int iy0, int iy1, FILE *out) { int can_subset, grid_template; int nx, ny, res, scan, new_nx, new_ny, i, j; unsigned int sec3_len, new_ndata, k, npnts; unsigned char *sec3, *new_sec[9]; double units; int basic_ang, sub_ang, cyclic_grid; float *new_data; get_nxny(sec, &nx, &ny, &npnts, &res, &scan); /* get nx, ny, and scan mode of grid */ grid_template = code_table_3_1(sec); // make a copy of the gds (sec3) sec3_len = GB2_Sec3_size(sec); sec3 = (unsigned char *) malloc(sec3_len); for (k = 0; k < sec3_len; k++) sec3[k] = sec[3][k]; // make a copy of the sec[] with new sec3 new_sec[0] = sec[0]; new_sec[1] = sec[1]; new_sec[2] = sec[2]; new_sec[3] = sec3; new_sec[4] = sec[4]; new_sec[5] = sec[5]; new_sec[6] = sec[6]; new_sec[7] = sec[7]; // new_sec[8] = sec[8]; not needed by writing routines can_subset = 1; if (lat == NULL || lon == NULL) can_subset = 0; new_nx = ix1-ix0+1; new_ny = iy1-iy0+1; if (new_nx <= 0) fatal_error("small_grib, new_nx is <= 0",""); if (new_ny <= 0) fatal_error("small_grib, new_ny is <= 0",""); new_ndata = new_nx * new_ny; cyclic_grid = 0; if (can_subset) { cyclic_grid = cyclic(sec); // lat-lon grid - no thinning if ((grid_template == 0 && sec3_len == 72) || (grid_template == 1 && sec3_len == 04)) { uint_char(new_nx,sec3+30); // nx uint_char(new_ny,sec3+34); // ny basic_ang = GDS_LatLon_basic_ang(sec3); sub_ang = GDS_LatLon_sub_ang(sec3); if (basic_ang != 0) { units = (double) basic_ang / (double) sub_ang; } else { units = 0.000001; } i = lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lat1 int_char(i,sec3+46); i = lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lon1 int_char(i,sec3+50); i = lat[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lat2 int_char(i,sec3+55); i = lon[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lon2 int_char(i,sec3+59); } else if ((grid_template == 40 && sec3_len == 72)) { // full Gaussian grid uint_char(new_nx,sec3+30); // nx uint_char(new_ny,sec3+34); // ny basic_ang = GDS_Gaussian_basic_ang(sec3); sub_ang = GDS_Gaussian_sub_ang(sec3); if (basic_ang != 0) { units = (double) basic_ang / (double) sub_ang; } else { units = 0.000001; } i = lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lat1 int_char(i,sec3+46); i = lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lon1 int_char(i,sec3+50); i = lat[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lat2 int_char(i,sec3+55); i = lon[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lon2 int_char(i,sec3+59); } // polar-stereo graphic, lambert conformal , no thinning else if ((grid_template == 20 && sec3_len == 65) || // polar stereographic (grid_template == 30 && sec3_len == 81)) { // lambert conformal uint_char(new_nx,sec3+30); // nx uint_char(new_ny,sec3+34); // ny i = (int) (lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] * 1000000.0); // lat1 int_char(i,sec3+38); i = (int) (lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] * 1000000.0); // lon1 int_char(i,sec3+42); } // mercator, no thinning else if (grid_template == 10 && sec3_len == 72) { // mercator uint_char(new_nx,sec3+30); // nx uint_char(new_ny,sec3+34); // ny units = 0.000001; i = lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lat1 int_char(i,sec3+38); i = lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lon1 int_char(i,sec3+42); i = lat[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lat2 int_char(i,sec3+51); i = lon[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lon2 int_char(i,sec3+55); } else { can_subset = 0; } } // copy data to a new array if (can_subset) { uint_char(new_ndata, sec3+6); new_data = (float *) malloc(new_ndata * sizeof(float)); #pragma omp parallel for private(i,j,k) for(j = iy0; j <= iy1; j++) { k = (j-iy0)*(ix1-ix0+1); for(i = ix0; i <= ix1; i++) { new_data[(i-ix0) + k ] = data[ idx(i,j,nx,ny,cyclic_grid) ]; } } } else { new_ndata = ndata; new_data = (float *) malloc(new_ndata * sizeof(float)); for (k = 0; k < ndata; k++) new_data[k] = data[k]; new_nx = nx; new_ny = ny; } set_order(new_sec, output_order); grib_wrt(new_sec, new_data, new_ndata, new_nx, new_ny, use_scale, dec_scale, bin_scale, wanted_bits, max_bits, grib_type, out); if (flush_mode) fflush(out); free(new_data); free(sec3); return 0; }
int main(int argc, char **argv) { FILE *in; unsigned char *msg, *sec[9]; long int last_pos; struct stat stat_buf; /* for type of grib input file */ int file_arg, i, j, num_submsgs; int n_arg; unsigned int k, ndata; float *data; double *ddata, ref; #ifdef USE_G2CLIB float missing_c_val_1, missing_c_val_2; g2int *bitmap, has_bitmap; g2float *g2_data; int ii; #endif struct ARGLIST arglist[N_ARGLIST]; int narglist = 0; const char *new_argv[N_ARGLIST]; void *local[N_ARGLIST]; int has_inv_option, last_submsg; int err, new_GDS, gdt, pdt, center; unsigned char dscale[2] = {0,0}; inv_file = stdout; // jas_init(); // gctpc initialiation init(-1,-1,"gctpc_1,txt", "gctpc_2.txt"); data = NULL; ndata = 0; /* no arguments .. help screen */ if (argc == 1) { // f_help(-1,NULL,NULL,0,inv_out,local,"most"); mode = -1; data = NULL; ndata = 0; *inv_out = 0; f_h(call_ARG0(inv_out,NULL)); fprintf(inv_file, "%s\n", inv_out); eof_bin(); eof_string(); exit(8); } setup_user_gribtable(); /* copy argv */ for (i = 0; i < argc; i++) { new_argv[i] = argv[i]; } /* scan for "inv" and input file */ has_inv_option = 0; file_arg = 0; for (i = 1; i < argc; i++) { if (new_argv[i][0] != '-') { /* must be filename */ file_arg = i; continue; } /* must be an option */ for (j = 0; j < nfunctions; j++) { if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) { if (functions[j].type == inv) has_inv_option = 1; i += functions[j].nargs; break; } } } /* if no inv option, use default inventory .. put it at end */ if (has_inv_option == 0) { for (i = 0; i < argc; i++) { new_argv[i] = new_argv[i]; } new_argv[argc++] = "-s"; } /* parse parameters */ file_arg = 0; for (i = 1; i < argc; i++) { if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0) ) { /* must be filename */ if (file_arg == 0) { file_arg = i; continue; } else { fatal_error("too many grib files .. 2nd=%s", new_argv[i]); } } /* must be an option */ for (j = 0; j < nfunctions; j++) { if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) { #ifdef DEBUG fprintf(stderr,"match .. -%s %d args\n", functions[j].name, functions[j].nargs); #endif /* add to function argument list */ arglist[narglist].fn = j; arglist[narglist].i_argc = i+1; if (functions[j].type == inv) has_inv_option = 1; i += functions[j].nargs; if (i >= argc) fatal_error("missing arguments option=%s",functions[j].name); narglist++; break; } } if (j == nfunctions) { fatal_error("unknown option %s", new_argv[i]); } } if (has_inv_option == 0) { fatal_error("missing arguments on last option",""); } /* initialize options mode = -1 */ #ifdef DEBUG fprintf(stderr,"init options narglist %d\n",narglist); #endif for (j = 0; j < narglist; j++) { inv_out[0] = 0; n_arg = functions[arglist[j].fn].nargs; err = 0; if (n_arg == 0) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j); else if (n_arg == 1) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); if(inv_out[0] != 0) fprintf(inv_file, "%s", inv_out); if (err) { err_bin(); err_string(); exit(8); } } if (file_arg == 0 && argc > 1) fatal_error("no input file", ""); if (latlon == 1 && output_order_wanted != wesn) fatal_error("latitude-longitude information is only available with -order we:sn",""); /* open input file */ seq_input = 0; if (strcmp(new_argv[file_arg],"-") == 0) { seq_input = 1; in = stdin; if (mode == 98) fprintf(stderr, "grib input is stdin\n"); } else { if (stat(new_argv[file_arg], &stat_buf) != -1) { if (S_ISREG(stat_buf.st_mode)) { if (mode == 98) fprintf(stderr, "grib input is a regular file\n"); } else if (S_ISDIR(stat_buf.st_mode)) { fatal_error("grib input is a directory: %s",new_argv[file_arg]); } else if (S_ISCHR(stat_buf.st_mode)) { seq_input = 1; if (mode == 98) fprintf(stderr, "grib input is a char device\n"); } else if (S_ISBLK(stat_buf.st_mode)) { seq_input = 1; if (mode == 98) fprintf(stderr, "grib input is a block device\n"); } else if (S_ISFIFO(stat_buf.st_mode)) { seq_input = 1; if (mode == 98) fprintf(stderr, "grib input is a fifo device\n"); } else { if (mode == 98) fprintf(stderr, "grib input has an unknown type\n"); } } if ((in = fopen(new_argv[file_arg],"rb")) == NULL) { fatal_error("could not open file: %s", new_argv[file_arg]); } } /* sequential input - can not do random access */ if (seq_input && input == inv_mode) fatal_error("wgrib2 cannot random access grib input file",""); ndata = 0; data = NULL; ddata = NULL; msg_no = 1; inv_no = 0; len = pos = 0; submsg = 0; msg = NULL; if ((old_gds = (unsigned char *) malloc(GDS_max_size * sizeof(char)) ) == NULL) { fatal_error("memory allocation problem old_gds in wgrib2.main",""); } last_pos = -1; last_submsg = -1; /* if dump mode .. position io stream */ if (input == dump_mode) { while (msg_no < dump_msg) { msg = seq_input ? rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) : rd_grib2_msg(in, &pos, &len, &num_submsgs); if (msg == NULL) fatal_error_i("record %d not found", dump_msg); last_pos = pos; pos += len; msg_no++; } #ifdef DEBUG printf("dump mode msg=%d\n", msg_no); #endif } /* * submsg = 0 .. beginning of unread record * submsg = i .. start at ith submsg * num_submsgs = number of submessages in grib message */ /* inventory loop */ for (;last_message == 0;) { /* need position and submessage number of message */ if (input == inv_mode || input == dump_mode) { if (input == inv_mode) { if (rd_inventory(&msg_no,&submsg, &pos)) break; } else if (input == dump_mode) { if (dump_msg == -1) break; submsg = dump_submsg; dump_msg = -1; } if (pos != last_pos) { msg = seq_input ? rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) : rd_grib2_msg(in, &pos, &len, &num_submsgs); if (msg == NULL) { fatal_error_i("grib message #%d not found", msg_no); break; } last_pos = pos; last_submsg = -1; } if (pos == last_pos && submsg == last_submsg + 1) { /* read previous submessage */ if (parse_next_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, submsg); break; } } else { /* need to get desired submessage into sec */ if (parse_1st_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.1 not found ***\n\n", msg_no); break; } for (i = 2; i <= submsg; i++) { if (parse_next_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, i); break; } } } last_submsg = submsg; } else if (input == all_mode) { if (submsg == 0) { msg = seq_input ? rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) : rd_grib2_msg(in, &pos, &len, &num_submsgs); if (msg == NULL) break; submsg = 1; } else if (submsg > num_submsgs) { pos += len; msg_no++; msg = seq_input ? rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) : rd_grib2_msg(in, &pos, &len, &num_submsgs); if (msg == NULL) break; submsg = 1; } if (submsg == 1) { if (parse_1st_msg(sec) != 0) { fprintf(stderr,"illegal format: parsing 1st submessage\n"); } } else { if (parse_next_msg(sec) != 0) { fprintf(stderr,"illegal format: parsing submessages\n"); } } } if (only_submsg > 0 && only_submsg != submsg) { submsg++; continue; } if (for_mode) { if (msg_no < for_start || msg_no > for_end || ((msg_no - for_start) % for_step) != 0) { if (msg_no > for_end && input != inv_mode) last_message = 1; submsg++; continue; } } #ifdef USE_REGEX /* move inv_no++ before match_inv is made */ inv_no++; if (match) { inv_out[0] = 0; if (num_submsgs > 1) { sprintf(inv_out,"%d.%d:", msg_no, submsg); } else { sprintf(inv_out,"%d:", msg_no); } // f_match_inv(0, sec, NULL, 0, inv_out+strlen(inv_out), NULL); f_match_inv(call_ARG0(inv_out+strlen(inv_out), NULL)); if (is_match(inv_out) != 0) { submsg++; inv_no--; continue; } } #endif match_flag = 0; if (for_n_mode) { if (inv_no < for_n_start || inv_no > for_n_end || ((inv_no - for_n_start) % for_n_step) != 0) { if (inv_no > for_n_end) last_message = 1; submsg++; continue; } } /* see if new GDS */ if ((i = GB2_Sec3_size(sec)) != old_GDS_size) { new_GDS = 1; } else { new_GDS = 0; for (j = 0; j < i; j++) { if (old_gds[j] != sec[3][j]) new_GDS = 1; } } if (new_GDS) { GDS_change_no++; if (i > GDS_max_size) { free(old_gds); GDS_max_size = i; if ((old_gds = (unsigned char *) malloc(GDS_max_size) ) == NULL) { fatal_error("memory allocation problem old_gds in wgrib2.main",""); } } for (j = 0; j < i; j++) { old_gds[j] = sec[3][j]; } old_GDS_size = i; /* update grid information */ get_nxny(sec, &nx, &ny, &npnts, &res, &scan); /* get nx, ny, and scan mode of grid */ output_order = (nx == -1 || ny == -1) ? raw : output_order_wanted; if (latlon) { i = 1; if (use_gctpc && output_order == wesn) { /* use gctpc to get lat lon values */ i = gctpc_get_latlon(sec, &lon, &lat); } if (i) get_latlon(sec, &lon, &lat); /* get lat lon of grid points */ } } /* Decode NDFD WxText */ if (WxText) mk_WxKeys(sec); // any fixes to raw grib message before decode need to be placed here if (fix_ncep_2_flag) fix_ncep_2(sec); if (fix_ncep_3_flag) fix_ncep_3(sec); if (fix_ncep_4_flag) fix_ncep_4(sec); #ifdef CHECK j = code_table_5_0(sec); // type of compression /* yes this can be simplified but want to split it up in case other decoders have problems */ if (j == 0 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib/grib-api simple decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); if ((j == 2 || j == 3) && int2(sec[5]+17) != 0 && int4(sec[5] + 31) == 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib complex decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); if (j == 40 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib jpeg deocde may differ from WMO standard, use use -g2clib 0 for WMO standard\n"); if (j == 41 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib/grib-api png decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); #endif #ifdef CHECK /* check the size of Section 7 */ /* code to check the other sizes needs to be placed in decode routines */ j = code_table_5_0(sec); // type of compression if (j == 0) { /* simple */ /* to avoid overflow on 32 bit machines */ /* old: k = (GB2_Sec5_nval(sec) * sec[5][19] + 7) / 8 + 5; */ k = 5 + (GB2_Sec5_nval(sec)/8) * sec[5][19] + (GB2_Sec5_nval(sec)%8) * (sec[5][19]/8) + ( (GB2_Sec5_nval(sec)%8) * (sec[5][19]%8) + 7) / 8; if (k != GB2_Sec7_size(sec)) { fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec)); if (decode) fatal_error("Section 7 size, mismatch, simple packing",""); } } else if (j == 4) { /* IEEE */ k = GB2_Sec5_nval(sec) * 4 + 5; if (k != GB2_Sec7_size(sec)) { fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec)); if (decode) fatal_error("Section 7 size, mismatch, IEEE packing",""); } } #endif if (decode) { #ifdef CHECK if (code_table_6_0(sec) == 0) { // has bitmap k = GB2_Sec3_npts(sec) - GB2_Sec5_nval(sec); if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec))) fatal_error_ii("inconsistent number of bitmap points sec3-sec5: %d sec6: %d", k, missing_points(sec[6]+6, GB2_Sec3_npts(sec))); } else if (code_table_6_0(sec) == 255) { // no bitmap if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec)) fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d", GB2_Sec3_npts(sec), GB2_Sec5_nval(sec)); } #endif /* allocate data */ if (GB2_Sec3_npts(sec) != ndata) { if (ndata) free(data); ndata = GB2_Sec3_npts(sec); if (ndata) { data = (float *) malloc(ndata * sizeof(float)); if (data == NULL) fatal_error("main: memory allocation failed data",""); } else { data = NULL; } } j = code_table_5_0(sec); // type of compression gdt = code_table_3_1(sec); // grid type pdt = GB2_ProdDefTemplateNo(sec); // product defintion template /* USE G2CLIB */ #ifdef USE_G2CLIB if (use_g2clib == 2) { err = g2_getfld(msg,submsg,1,1,&grib_data); if (err != 0) fatal_error_ii("Fatal g2clib decode err=%d msg=%d", err, msg_no); free_gribfield = 1; has_bitmap = grib_data->ibmap; g2_data = &(grib_data->fld[0]); if (has_bitmap == 0 || has_bitmap == 254) { bitmap = grib_data->bmap; for (i = 0; i < ndata; i++) { data[i] = (bitmap[i] == 0) ? UNDEFINED : g2_data[i]; } } else { for (i = 0; i < ndata; i++) { data[i] = g2_data[i]; } } /* complex packing uses special values for undefined */ ii = sub_missing_values(sec, &missing_c_val_1, &missing_c_val_2); if (ii == 1) { for (i = 0; i < ndata; i++) { if (data[i] == missing_c_val_1) data[i] = UNDEFINED; } } else if (ii == 2) { for (i = 0; i < ndata; i++) { if (data[i] == missing_c_val_1) data[i] = UNDEFINED; if (data[i] == missing_c_val_2) data[i] = UNDEFINED; } } } #endif /* USE INTERNAL DECODER */ if (use_g2clib != 2) { center = GB2_Center(sec); if (use_g2clib == 1) { // introduce g2clib constant field error /* g2clib ignores decimal scaling for constant fields make internal decoders look like g2clib*/ if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) || (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19] == 0) || (center == NCEP && j == 40000 && sec[5][19] == 0) || (center == NCEP && j == 40010 && sec[5][19] == 0) ) { dscale[0] = sec[5][17]; dscale[1] = sec[5][18]; sec[5][17] = sec[5][18] = 0; } } err = unpk_grib(sec, data); if (err != 0) fatal_error_i("Fatal decode packing type %d",err); if (use_g2clib == 1) { // fix up data /* restore decimal scaling */ if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) || (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19]) || (center == NCEP && j == 40000 && sec[5][19] == 0) || (center == NCEP && j == 40010 && sec[5][19] == 0) ) { sec[5][17] = dscale[0]; sec[5][18] = dscale[1]; } } } /* convert to standard output order we:sn */ if (output_order_wanted == wesn) to_we_sn_scan(data); else if (output_order_wanted == wens) to_we_ns_scan(data); } else { if (ndata) free(data); ndata = 0; data = NULL; } /* get scaling parameters */ use_scale = scaling(sec, &ref, &dec_scale, &bin_scale, &i) == 0; if (num_submsgs > 1) { fprintf(inv_file, "%d.%d%s%ld", msg_no, submsg, ":", pos); } else { fprintf(inv_file, "%d%s%ld", msg_no, ":", pos); } for (j = 0; j < narglist; j++) { /* skip execution if match_flag == 1 */ /* an output option acts as endif for match_flag */ if (match_flag == 1) { if (functions[arglist[j].fn].type == output) match_flag = 0; continue; } // if (functions[arglist[j].fn].type == inv) fprintf(inv_file, item_deliminator); if (functions[arglist[j].fn].type == inv) fprintf(inv_file, "%s", item_deliminator); if (functions[arglist[j].fn].type != setup) { inv_out[0] = 0; n_arg = functions[arglist[j].fn].nargs; if (n_arg == 0) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j); else if (n_arg == 1) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); if(inv_out[0] != 0) fprintf(inv_file, "%s", inv_out); } } #ifdef CHECK if (!decode) { if (code_table_6_0(sec) == 0) { // has bitmap k = GB2_Sec3_npts(sec) - GB2_Sec5_nval(sec); if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec))) fatal_error_ii("inconsistent number of bitmap points sec3-sec5: %d sec6: %d", k, missing_points(sec[6]+6, GB2_Sec3_npts(sec))); } else if (code_table_6_0(sec) == 255) { // no bitmap if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec)) fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d", GB2_Sec3_npts(sec), GB2_Sec5_nval(sec)); } } #endif submsg++; #ifdef USE_G2CLIB if (free_gribfield) { g2_free(grib_data); free_gribfield = 0;} #endif // fprintf(inv_file, "\n"); fprintf(inv_file, "%s",end_inv); if (flush_mode) fflush(inv_file); if (dump_msg > 0) break; } /* finalize all functions, call with mode = -2 */ for (j = 0; j < narglist; j++) { if (functions[arglist[j].fn].type != setup) { n_arg = functions[arglist[j].fn].nargs; inv_out[0] = 0; if (n_arg == 0) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j); else if (n_arg == 1) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); // if (inv_out[0]) fprintf(stderr, "%s\n", inv_out); if (inv_out[0]) fprintf(stderr, "%s%s", inv_out, end_inv); } } eof_bin(); eof_string(); exit(0); }
int space_view_init(unsigned char **sec) { double major, minor, orient_angle, angular_size; int x0, y0; int nres, nscan; unsigned int nnpnts; fprintf(stderr,"ALPHA: experimental space_view2ij\n"); if (sec == NULL || sec[3] == NULL) fatal_error("space_view_init: sec/sec[3] == NULL",""); if (code_table_3_1(sec) != 90) fatal_error("space_view_init: not space view grid",""); if (output_order != wesn) fatal_error("space_view_init: order must be we:sn",""); //printf("space_view_init >>>> table 3.1 %d\n", code_table_3_1(sec)); get_nxny(sec, &nnx, &nny, &nnpnts, &nres, &nscan); axes_earth(sec, &major, &minor); //fprintf(stderr,">> axes %lf minor %lf\n", major,minor); r_eq = major * 0.001; r_pol = minor * 0.001; r_pol_eq = (r_pol * r_pol) / (r_eq * r_eq); // factor_10 = (r_eq*r_eq - r_pol*r_pol) / (r_eq * r_eq); factor_10 = 1.0 - r_pol_eq; //fprintf(stderr,">> r_eq %lf r_pol %lf rad_factor %lf \n",r_eq, r_pol, factor_10); angular_size = 2.0 * asin(1e6/ uint4(sec[3]+68)); sat_height = uint4(sec[3]+68) * 1e-6 * r_eq; //fprintf(stderr,">> sat height %lf\n",sat_height); lap = int4(sec[3]+38); lop = int4(sec[3]+38); /* I am guessing that a scale factor has to be added */ lap *= 1e-6; lop *= 1e-6; // fprintf(stderr,">> lap %lf lop %lf degrees\n",lap, lop); if (lap != 0.0) return 0; // need to extend code /* convert to radians */ lap *= (180.0/M_PI); lop *= (180.0/M_PI); orient_angle = int4(sec[3]+64); /* I am guessing that a scale factor has to be added */ orient_angle *= 1e-6; // fprintf(stderr,">> orientation angle %lf\n", orient_angle); if (orient_angle != 0.0) return 0; // need to extend code xp = int4(sec[3]+55) * 0.001; yp = int4(sec[3]+59) * 0.001; //fprintf(stderr,">> xp %lf yp %lf pixels\n",xp, yp); x0 = int4(sec[3]+72); y0 = int4(sec[3]+76); //fprintf(stderr,">> origin x0 %d yo %d pixels\n",x0, y0); /* find center point in we:sn coordinate */ if (GDS_Scan_x(nscan)) { xp = xp - x0; } else { xp = (nnx-1) - (xp - x0); } if (GDS_Scan_y(nscan)) { yp = yp - y0; } else { yp = (nny-1) - (yp - y0); } //fprintf(stderr,">> new center point point x/y=%lf %lf nnx=%d nny=%d\n", xp,yp,nnx, nny); dx = int4(sec[3]+47); dy = int4(sec[3]+51); //fprintf(stderr,">> dia: dx %lf dy %lf pixels\n",dx, dy); inv_rx = dx / angular_size; inv_ry = (r_eq/r_pol) * dy / angular_size; // fprintf(stderr,">> factor %.18lf %.18lf, q: %.19lf %.18lf\n", 256*256.0/(-781648343.0), 256*256.0/(-781648343.0), 1/inv_rx, 1/inv_ry); return 0; }
int gauss2ll(unsigned char **sec, double **llat, double **llon) { int nlat; /* in grib, number of latitudes must be even! */ double dx, e, w, south, north, lat1, lon1, lat2, lon2, *ylat; int isouth, inorth; double units; double *lat, *lon; int basic_ang, sub_ang; int i,j, n; unsigned int k; unsigned char *gds; int nnx, nny, nres, nscan; unsigned int nnpnts; get_nxny(sec, &nnx, &nny, &nnpnts, &nres, &nscan); gds = sec[3]; nlat = 2 * GDS_Gaussian_nlat(gds); /* figure out angle units */ basic_ang = GDS_Gaussian_basic_ang(gds); sub_ang = GDS_Gaussian_sub_ang(gds); units = basic_ang == 0 ? 0.000001 : (double) basic_ang / (double) sub_ang; lat1 = GDS_Gaussian_lat1(gds) * units; lat2 = GDS_Gaussian_lat2(gds) * units; lon1 = GDS_Gaussian_lon1(gds) * units; lon2 = GDS_Gaussian_lon2(gds) * units; if (lon1 < 0.0 || lon2 < 0.0 || lon1 > 360.0 || lon2 > 360.0) fatal_error("BAD GDS lon",""); if (lat1 < -90.0 || lat2 < -90.0 || lat1 > 90.0 || lat2 > 90.0) fatal_error("BAD GDS lat",""); /* find S latitude and dy */ if (GDS_Scan_y(nscan)) { south = lat1; north = lat2; } else { south = lat2; north = lat1; } if (south > north) fatal_error("gaussian grid: lat1 and lat2 inconsistent with scan order",""); if (nny == -1) { fprintf(stderr,"Sorry code does not handle variable ny yet\n"); return 0; } if (nny > nlat || nny < 0) fatal_error_i("gauss2ll: bad ny %d",nny); if ((*llat = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("gauss2ll memory allocation failed",""); } if ((*llon = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("gauss2ll memory allocation failed",""); } lat = *llat; lon = *llon; /* do latitudes first */ ylat = (double *) malloc(sizeof(double) * nlat); /* calculate Gaussian latitudes */ gauss2lats(nlat, ylat); /* find index of south and north */ isouth = inorth = -1; for (i = 0; i < nlat; i++) { if (fabs(south - ylat[i]) < LATERR) { isouth = i; break; } } for (i = 0; i < nlat; i++) { if (fabs(north - ylat[i]) < LATERR) { inorth = i; break; } } if (isouth < 0 || inorth < 0) fatal_error("gauss2ll: lat1/lat2 not a Gaussian latitude",""); if (inorth - isouth + 1 != nny) fatal_error("gauss2ll: lat1/lat2 not consistent with ny",""); n = 0; if (nnx >= 0) { /* regular grid */ #pragma omp parallel for private(i,j) for (j = 0; j < nny; j++) { for (i = 0; i < nnx; i++) { lat[i+j*nnx] = ylat[j+isouth]; } } } else { /* quasi regular grid */ for (j = 0; j < nny; j++) { for (i = 0; i < variable_dim[j]; i++) { lat[n++] = ylat[j+isouth]; } } } free(ylat); /* now for the longitudes */ if (GDS_Scan_x(nscan)) { e = lon1; w = lon2; } else { e = lon2; w = lon1; } if (e > w) w += 360.0; if (e < 0.0) { e += 360.0; w += 360.0; } if (e >= 360.0) { e -= 360.0; w -= 360.0; } if (nnx >= 0) { dx = (w-e) / (nnx-1); #pragma omp parallel { #pragma omp for private(i) for (i = 0; i < nnx; i++) { lon[i] = e + (dx * i) >= 360.0 ? e + (dx * i) - 360.0 : e + (dx * i); } #pragma omp for private(i,j) for (j = 1; j < nny; j++) { for (i = 0; i < nnx; i++) { lon[i+j*nnx] = lon[i]; } } } } else { n = 0; for (j = 0; j < nny; j++) { dx = (w-e) / (variable_dim[j]-1); for (i = 0; i < variable_dim[j]; i++) { lon[n++] = e + (dx * i) >= 360.0 ? e + (dx * i) - 360.0 : e + (dx * i); } } } return 0; } /* end gauss2ll() */
int regular2ll(unsigned char **sec, double **lat, double **lon) { int basic_ang, sub_ang; double units, dlat, dlon, lat1, lat2, lon1, lon2; double e, w, n, s, dx, dy; int i, j; double *llat, *llon; unsigned char *gds; int nnx, nny, nres, nscan; unsigned int nnpnts; get_nxny(sec, &nnx, &nny, &nnpnts, &nres, &nscan); gds = sec[3]; if (nny == -1) { fprintf(stderr,"Sorry code does not handle variable ny yet\n"); return 0; } if ((*lat = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("regular2ll memory allocation failed",""); } if ((*lon = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("regular2ll memory allocation failed",""); } /* now figure out the grid coordinates mucho silly grib specification */ basic_ang = GDS_LatLon_basic_ang(gds); sub_ang = GDS_LatLon_sub_ang(gds); if (basic_ang != 0) { units = (double) basic_ang / (double) sub_ang; } else { units = 0.000001; } dlat = GDS_LatLon_dlat(gds) * units; dlon = GDS_LatLon_dlon(gds) * units; lat1 = GDS_LatLon_lat1(gds) * units; lat2 = GDS_LatLon_lat2(gds) * units; lon1 = GDS_LatLon_lon1(gds) * units; lon2 = GDS_LatLon_lon2(gds) * units; if (lon1 < 0.0 || lon2 < 0.0) fatal_error("BAD grid definition lon < zero",""); if (lon1 > 360.0 || lon2 > 360.0) fatal_error("BAD grid definition lon >= 360",""); if (lat1 < -90.0 || lat2 < -90.0 || lat1 > 90.0 || lat2 > 90.0) fatal_error("BAD grid definition lat",""); /* find S latitude and dy */ if (GDS_Scan_y(nscan)) { s = lat1; n = lat2; } else { s = lat2; n = lat1; } if (s > n) fatal_error("lat-lon grid: lat1 and lat2 inconsistent with scan order",""); if (nny != 1) { dy = (n - s) / (nny - 1); if (nres & 16) { /* lat increment is valid */ if (fabs(dy - dlat) > 0.001) fatal_error("lat-lon grid: dlat is inconsistent",""); } } else { dy = 0.0; } // fprintf(stderr,">>> geo: dy %lf dlat %lf nres %d has dy %d has dx %d\n", dy, dlat, nres, nres & 16, nres & 32); /* find W latitude and dx */ if ( GDS_Scan_row_rev(nscan) && (nny % 2 == 0) && ((nres & 32) == 0) ) { fatal_error("grib GDS ambiguity",""); } if (GDS_Scan_x(nscan)) { w = lon1; e = lon2; if (GDS_Scan_row_rev(nscan) && ((nres & 32) == 0)) { e = lon1 + (nnx-1) * dlon; } } else { w = lon2; e = lon1; if (GDS_Scan_row_rev(nscan) && ((nres & 32) == 0)) { w = lon1 - (nnx-1) * dlon; } } if (e <= w) e += 360.0; if (e-w > 360.0) e -= 360.0; if (w < 0) { w += 360.0; e += 360.0; } /* lat-lon should be in a WE:SN order */ if (nnx > 0 && nny > 0) { /* non-thinned, potentially staggered grid */ /* put x[] and y[] values in lon[] and lat[] */ llat = *lat; llon = *lon; if (stagger(sec, nnpnts,llon,llat)) fatal_error("geo: stagger problem",""); if (nnx != 1) { dx = (e-w) / (nnx - 1); dx = fabs(dx); if (nres & 32) { /* lon increment is valid */ if (fabs(dx - fabs(dlon)) > 0.001) fatal_error("lat-lon grid: dlon is inconsistent",""); } } else { dx = 0.0; } dy = fabs(dy); #pragma omp parallel for private(j) for (j = 0; j < nnpnts; j++) { llon[j] = lon1 + llon[j]*dx; llon[j] = llon[j] >= 360.0 ? llon[j] - 360.0 : llon[j]; llon[j] = llon[j] < 0.0 ? llon[j] + 360.0 : llon[j]; llat[j] = lat1 + llat[j]*dy; } return 0; } /* must be thinned grid */ llat = *lat; /* quasi-regular grid */ for (j = 0; j < nny; j++) { for (i = 0; i < variable_dim[j]; i++) { *llat++ = s + j*dy; } } llon = *lon; /* quasi-regular grid */ for (j = 0; j < nny; j++) { dx = (e-w) / (variable_dim[j]-1); for (i = 0; i < variable_dim[j]; i++) { *llon++ = w + i*dx >= 360.0 ? w + i*dx - 360.0: w + i*dx; } } return 0; } /* end regular2ll() */
int mercator2ll(unsigned char **sec, double **lat, double **lon) { double dx, dy, lat1, lat2, lon1, lon2; double *llat, *llon; int i, j; unsigned int k; double dlon, circum; double n,s,e,w,tmp,error; unsigned char *gds; int nnx, nny, nres, nscan; unsigned int nnpnts; get_nxny(sec, &nnx, &nny, &nnpnts, &nres, &nscan); gds = sec[3]; dy = GDS_Mercator_dy(gds); dx = GDS_Mercator_dx(gds); lat1 = GDS_Mercator_lat1(gds); lat2 = GDS_Mercator_lat2(gds); lon1 = GDS_Mercator_lon1(gds); lon2 = GDS_Mercator_lon2(gds); if (lon1 < 0.0 || lon2 < 0.0 || lon1 > 360.0 || lon2 > 360.0) fatal_error("BAD GDS lon",""); if (lat1 < -90.0 || lat2 < -90.0 || lat1 > 90.0 || lat2 > 90.0) fatal_error("BAD GDS lat",""); if (GDS_Mercator_ori_angle(gds) != 0.0) { fprintf(stderr,"cannot handle non-zero mercator orientation angle %f\n", GDS_Mercator_ori_angle(gds)); return 0; } if (nnx == -1 || nny == -1) { fprintf(stderr,"Sorry geo/mercator code does not handle variable nx/ny yet\n"); return 0; } if ((*lat = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("mercator2ll memory allocation failed",""); } if ((*lon = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("mercator2ll memory allocation failed",""); } /* now figure out the grid coordinates mucho silly grib specification */ /* find S and N latitude */ if (GDS_Scan_y(nscan)) { s = lat1; n = lat2; } else { s = lat2; n = lat1; } if (s > n) fatal_error("Mercator grid: lat1 and lat2",""); /* find W and E longitude */ if ( ((nscan & 16) == 16) && (nny % 2 == 0) && ((nres & 32) == 0) ) { fatal_error("grib GDS ambiguity",""); } if ( ((nscan & 16) == 16) && (nny % 2 == 0) ) { fatal_error("more code needed to decode GDS",""); } if (GDS_Scan_x(nscan)) { w = lon1; e = lon2; } else { w = lon2; e = lon1; } if (e <= w) e += 360.0; llat = *lat; llon = *lon; dlon = (e-w) / (nnx-1); circum = 2.0 * M_PI * radius_earth(sec) * cos(GDS_Mercator_latD(gds) * (M_PI/180.0)); dx = dx * 360.0 / circum; // dlon should be almost == to dx // replace dx by dlon to get end points to match if (dx != 0.0) { error = fabs(dx-dlon) / fabs(dx); if (error >= 0.001) { fprintf(stderr, "\n*** Mercator grid error: inconsistent d-longitude, radius and grid domain\n" "*** d-longitude from grid domain %lf (used), d-longitude from dx %lf (not used)\n", dlon, dx); } dx = dlon; } s = log(tan((45+s/2)*M_PI/180)); n = log(tan((45+n/2)*M_PI/180)); dy = (n - s) / (nny - 1); for (j = 0; j < nny; j++) { tmp = (atan(exp(s+j*dy))*180/M_PI-45)*2; for (i = 0; i < nnx; i++) { *llat++ = tmp; } } for (j = 0; j < nnx; j++) { llon[j] = w + j*dx >= 360.0 ? w + j*dx - 360.0 : w + j*dx; } for (k = nnx; k < nnpnts; k++) { llon[k] = llon[k-nnx]; } return 0; } /* end mercator2ll() */
int lambert2ll(unsigned char **sec, double **llat, double **llon) { double n; double *lat, *lon; double dx, dy, lat1r, lon1r, lon2d, lon2r, latin1r, latin2r; double lond, latd, d_lon; double f, rho, rhoref, theta, startx, starty; int j, nnx, nny, nres, nscan; double x, y, tmp; unsigned char *gds; double latDr; double earth_radius; unsigned int nnpnts; get_nxny(sec, &nnx, &nny, &nnpnts, &nres, &nscan); if (nnx <= 0 || nny <= 0) { fprintf(stderr,"Sorry code does not handle variable nx/ny yet\n"); return 0; } earth_radius = radius_earth(sec); gds = sec[3]; dy = GDS_Lambert_dy(gds); dx = GDS_Lambert_dx(gds); lat1r = GDS_Lambert_La1(gds) * (M_PI / 180.0); lon1r = GDS_Lambert_Lo1(gds) * (M_PI / 180.0); lon2d = GDS_Lambert_Lov(gds); lon2r = lon2d * (M_PI / 180.0); latin1r = GDS_Lambert_Latin1(gds) * (M_PI/180.0); latin2r = GDS_Lambert_Latin2(gds) * (M_PI/180.0); // fix for theta start value crossing 0 longitude // if ((lon1r - lon2r) > 0) lon2r = lon2r + 2*M_PI; // // Latitude of "false origin" where scales are defined. // It is used to estimate "reference_R", rhoref. // Often latDr == latin1r == latin2r and non-modified code is true and works fine. // But could be different if intersection latitudes latin1r and latin2r are different. // Usually latDr must be latin1r <= latDr <= latin2r, other could be strange. // latDr = GDS_Lambert_LatD(gds) * (M_PI/180.0); if (lon1r < 0) fatal_error("bad GDS, lon1r < 0.0",""); if ( fabs(latin1r - latin2r) < 1E-09 ) { n = sin(latin1r); } else { n = log(cos(latin1r)/cos(latin2r)) / log(tan(M_PI_4 + latin2r/2.0) / tan(M_PI_4 + latin1r/2.0)); } f = (cos(latin1r) * pow(tan(M_PI_4 + latin1r/2.0), n)) / n; rho = earth_radius * f * pow(tan(M_PI_4 + lat1r/2.0),-n); // old rhoref = earth_radius * f * pow(tan(M_PI_4 + latin1r/2.0),-n); rhoref = earth_radius * f * pow(tan(M_PI_4 + latDr/2.0),-n); // 2/2009 .. new code d_lon = lon1r - lon2r; if (d_lon > M_PI) d_lon -= 2*M_PI; if (d_lon < -M_PI) d_lon += 2*M_PI; theta = n * d_lon; // 2/2009 theta = n * (lon1r - lon2r); startx = rho * sin(theta); starty = rhoref - rho * cos(theta); if ((*llat = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("lambert2ll memory allocation failed",""); } if ((*llon = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("lambert2ll memory allocation failed",""); } lat = *llat; lon = *llon; /* put x[] and y[] values in lon[] and lat[] */ if (stagger(sec, nnpnts, lon, lat)) fatal_error("geo: stagger problem",""); dx = fabs(dx); dy = fabs(dy); #pragma omp parallel for private(j,x,y,tmp,theta,rho,lond,latd) for (j = 0; j < nnpnts; j++) { y = starty + lat[j]*dy; x = startx + lon[j]*dx; tmp = rhoref - y; theta = atan(x / tmp); rho = sqrt(x * x + tmp*tmp); rho = n > 0 ? rho : -rho; lond = lon2d + todegrees(theta/n); latd = todegrees(2.0 * atan(pow(earth_radius * f/rho,1.0/n)) - M_PI_2); lond = lond >= 360.0 ? lond - 360.0 : lond; lond = lond < 0.0 ? lond + 360.0 : lond; lon[j] = lond; lat[j] = latd; } return 0; } /* end lambert2ll() */
int polar2ll(unsigned char **sec, double **llat, double **llon) { double *lat, *lon; unsigned char *gds; double dx, dy, orient, de, de2, dr, tmp, xp, yp, h, lat1, lon1, dr2; double di, dj, LatD; int ix, iy; int nnx, nny, nres, nscan; unsigned int nnpnts; get_nxny(sec, &nnx, &nny, &nnpnts, &nres, &nscan); gds = sec[3]; if (nnx == -1 || nny == -1) { fprintf(stderr,"Sorry code does not handle variable nx/ny yet\n"); return 0; } if ((*llat = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("polar2ll memory allocation failed",""); } if ((*llon = (double *) malloc(nnpnts * sizeof(double))) == NULL) { fatal_error("polar2ll memory allocation failed",""); } lat = *llat; lon = *llon; /* based on iplib */ lat1 = GDS_Polar_lat1(gds) * (M_PI/180); lon1 = GDS_Polar_lon1(gds); orient = GDS_Polar_lov(gds); LatD = GDS_Polar_lad(gds); lon1 *= (M_PI/180.0); orient *= (M_PI/180.0); dy = GDS_Polar_dy(gds); dx = GDS_Polar_dx(gds); h = 1.0; if (GDS_Polar_sps(gds)) { h = -1.0; /* added 12/19/2008 WNE sps checkout */ orient -= M_PI; } // removed 12/11 if (! (GDS_Scan_x(nscan))) dx = -dx; // removed 12/11 if (! (GDS_Scan_y(nscan))) dy = -dy; /* 60 probably becomes something else in grib2 */ /* vsm: from comment to grib2 polar template: "Grid length is in units of 10-3 m at the latitude specified by LaD" do use GDS_Polar_lad(gds) instead of 60? Do use fabs for southern hemisphere? */ de = (1.0 + sin(fabs(LatD)*(M_PI/180.0))) * radius_earth(sec); dr = de * cos(lat1) / (1 + h*sin(lat1)); xp=-h*sin(lon1-orient)*dr/dx; yp= cos(lon1-orient)*dr/dy; // added 12/11 if (! (GDS_Scan_y(nscan))) { yp = yp - nny + 1; } if (! (GDS_Scan_x(nscan))) { xp = xp - nnx + 1; } de2 = de*de; #pragma omp parallel for private(iy,ix,di,dj,dr2,tmp) for (iy = 0; iy < nny; iy++) { for (ix = 0; ix < nnx; ix++) { di = (ix - xp) * dx; dj = (iy - yp) * dy; dr2 = di*di + dj*dj; if (dr2 < de2*1e-6) { lon[ix+iy*nx] = 0.0; lat[ix+iy*nx] = h*90.0; } else { tmp = (orient+h*atan2(di,-dj))*(180.0/M_PI); if (tmp < 0.0) tmp += 360.0; if (tmp > 360.0) tmp -= 360.0; lon[ix+iy*nx] = tmp; lat[ix+iy*nx] = h*asin((de2-dr2)/(de2+dr2))*(180.0/M_PI); } } } return 0; }
int main(int argc, char **argv) { #else int wgrib2(int argc, const char **argv) { #endif //WNE FILE *in; struct seq_file in_file; unsigned char *msg, *sec[10]; /* sec[9] = last valid bitmap */ long int last_pos; int file_arg, i, j, num_submsgs; int n_arg; unsigned int k, ndata; int err_4_3_count; float *data; double ref; // double *ddata, ref; #ifdef USE_G2CLIB float missing_c_val_1, missing_c_val_2; g2int *bitmap, has_bitmap; g2float *g2_data; int ii; #endif struct ARGLIST arglist[N_ARGLIST]; int narglist; const char *new_argv[N_ARGLIST]; void *local[N_ARGLIST]; int has_inv_option, last_submsg; int err, new_GDS, center; unsigned char dscale[2]; init_globals(); init_inv_out(); ndata = 0; err_4_3_count = 0; if (initial_call) { /* only done 1st time */ setup_user_gribtable(); // jas_init(); // gctpc initialiation init(-1,-1,"gctpc_error,txt", "gctpc_param.txt"); initial_call = 0; } narglist = 0; dscale[0] = dscale[1] = 0; mode = 0; if (fopen_file(&(rd_inventory_input), "-", "r")) fatal_error("opening stdin for rd_inventory",""); data = NULL; // ddata = NULL; #ifdef CALLABLE_WGRIB2 if (setjmp(fatal_err)) { fprintf(stderr,"*** arg list to wgrib2:"); for (i=0; i < argc; i++) { fprintf(stderr," %s", argv[i]); } fprintf(stderr,"\n\n"); if (ndata && data != NULL) free(data); ndata=0; return 1; } #endif /* no arguments .. help screen */ if (argc == 1) { mode = -1; inv_out[0] = 0; f_h(call_ARG0(inv_out,NULL)); // fprintf(inv_file, "%s\n", inv_out); i = strlen(inv_out); inv_out[i++] = '\n'; inv_out[i] = '\0'; fwrite_file(inv_out, 1, i, &inv_file); err_bin(1); err_string(1); return 8; } /* copy argv */ for (i = 0; i < argc; i++) { new_argv[i] = argv[i]; } /* scan for "inv" and input file */ has_inv_option = 0; file_arg = 0; for (i = 1; i < argc; i++) { if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0) ) { /* must be filename */ if (file_arg == 0) { file_arg = i; continue; } else { fatal_error_ss("too many grib files .. 1st=%s 2nd=%s", new_argv[file_arg], new_argv[i]); } } /* must be an option */ for (j = 0; j < nfunctions; j++) { if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) { if (functions[j].type == inv) has_inv_option = 1; i += functions[j].nargs; break; } } if (j == nfunctions) { fatal_error("undefined option: %s", new_argv[i]); } } /* if no inv option, use default inventory .. put it at end */ if (has_inv_option == 0) new_argv[argc++] = "-s"; /* try opening the input file */ in_file.file_type = NOT_OPEN; if (file_arg != 0) { fopen_file(&in_file, new_argv[file_arg],"rb"); } /* "compile" options */ #ifdef DEBUG fprintf(stderr,"going to compile phase\n"); #endif for (i = 1; i < argc; i++) { /* if filename skip */ if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0)) continue; /* must be an option */ for (j = 0; j < nfunctions; j++) { if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) break; } if (j == nfunctions) fatal_error("unknown option %s", new_argv[i]); /* add to function argument list */ arglist[narglist].fn = j; arglist[narglist].i_argc = i+1; if (functions[j].type == inv) has_inv_option = 1; i += functions[j].nargs; if (i >= argc) fatal_error("missing arguments option=%s",functions[j].name); narglist++; } if (has_inv_option == 0) fatal_error("missing arguments on last option",""); /* initialize options, mode = -1 */ #ifdef DEBUG fprintf(stderr,"going to init options, narglist %d\n",narglist); #endif for (j = 0; j < narglist; j++) { new_inv_out(); /* inv_out[0] = 0; */ n_arg = functions[arglist[j].fn].nargs; err = 0; #ifdef DEBUG fprintf(stderr,"going to init option %s\n", functions[arglist[j].fn].name); #endif if (n_arg == 0) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j); else if (n_arg == 1) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); // if(inv_out[0] != 0) fprintf(inv_file, "%s", inv_out); if(inv_out[0] != 0) fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file); if (err) { err_bin(1); err_string(1); // cleanup return 8; } } /* error and EOF handlers have been initialized */ #ifdef DEBUG fprintf(stderr,"initial error and EOF handlers\n"); #endif if (has_inv_option == 0) fatal_error("missing arguments on last option",""); if (in_file.file_type == NOT_OPEN) { if (file_arg == 0) fatal_error("no input file defined",""); else fatal_error("missing input file %s", new_argv[file_arg]); } if (latlon == 1 && output_order_wanted != wesn) fatal_error("latitude-longitude information is only available with -order we:sn",""); if (input == inv_mode && (in_file.file_type != DISK && in_file.file_type != MEM)) fatal_error("wgrib2 cannot random access grib input file",""); #ifdef DEBUG fprintf(stderr,"going to process data\n"); #endif msg_no = 1; inv_no = 0; len = pos = 0; submsg = 0; msg = NULL; last_pos = -1; last_submsg = -1; /* if dump mode .. position io stream */ if (input == dump_mode) { while (msg_no < dump_msg) { // // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs); // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); // else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs); msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); if (msg == NULL) fatal_error_i("record %d not found", dump_msg); last_pos = pos; pos += len; msg_no++; } #ifdef DEBUG printf("dump mode msg=%d\n", msg_no); #endif } /* * submsg = 0 .. beginning of unread record * submsg = i .. start at ith submsg * num_submsgs = number of submessages in grib message */ /* inventory loop */ for (;last_message == 0;) { /* need position and submessage number of message */ if (input == inv_mode || input == dump_mode) { if (input == inv_mode) { if (rd_inventory(&msg_no,&submsg, &pos, &rd_inventory_input)) break; if (fseek_file(&in_file, pos,SEEK_SET) != 0) fatal_error("fseek_file failed",""); } else if (input == dump_mode) { if (dump_msg == -1) break; submsg = dump_submsg; dump_msg = -1; } if (pos != last_pos) { // // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs); // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); // else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs); msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); if (msg == NULL) { fatal_error_i("grib message #%d not found", msg_no); break; } last_pos = pos; last_submsg = -1; } if (pos == last_pos && submsg == last_submsg + 1) { /* read previous submessage */ if (parse_next_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, submsg); break; } } else { /* need to get desired submessage into sec */ if (parse_1st_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.1 not found ***\n\n", msg_no); break; } for (i = 2; i <= submsg; i++) { if (parse_next_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, i); break; } } } last_submsg = submsg; } else if (input == all_mode) { if (submsg == 0) { // // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs); // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); // else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs); msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); if (msg == NULL) break; submsg = 1; } else if (submsg > num_submsgs) { pos += len; msg_no++; // // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs); // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); // else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs); msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); if (msg == NULL) break; submsg = 1; } if (submsg == 1) { if (parse_1st_msg(sec) != 0) { fprintf(stderr,"illegal format: parsing 1st submessage\n"); } } else { if (parse_next_msg(sec) != 0) { fprintf(stderr,"illegal format: parsing submessages\n"); } } } if (only_submsg > 0 && only_submsg != submsg) { submsg++; continue; } if (for_mode) { if (msg_no < for_start || msg_no > for_end || ((msg_no - for_start) % for_step) != 0) { if (msg_no > for_end && input != inv_mode) last_message = 1; submsg++; continue; } } /* move inv_no++ before match_inv is made */ inv_no++; if (match || match_fs) { inv_out[0] = 0; if (num_submsgs > 1) { sprintf(inv_out,"%d.%d:", msg_no, submsg); } else { sprintf(inv_out,"%d:", msg_no); } f_match_inv(call_ARG0(inv_out+strlen(inv_out), NULL)); if (is_match_fs(inv_out) != 0) { submsg++; inv_no--; continue; } #ifdef USE_REGEX if (is_match(inv_out) != 0) { submsg++; inv_no--; continue; } #endif } match_flag = 0; if (for_n_mode) { if (inv_no < for_n_start || inv_no > for_n_end || ((inv_no - for_n_start) % for_n_step) != 0) { if (inv_no > for_n_end) last_message = 1; submsg++; continue; } } /* see if new GDS */ if ((i = (int) GB2_Sec3_size(sec)) != old_GDS_size) { new_GDS = 1; } else { new_GDS = 0; for (j = 0; j < i; j++) { if (old_gds[j] != sec[3][j]) new_GDS = 1; } } if (new_GDS) { GDS_change_no++; if (i > GDS_max_size) { if (GDS_max_size) free(old_gds); GDS_max_size = i + 100; /* add 100 just to avoid excessive memory allocations */ if ((old_gds = (unsigned char *) malloc(GDS_max_size) ) == NULL) { fatal_error("memory allocation problem old_gds in wgrib2.main",""); } } for (j = 0; j < i; j++) { old_gds[j] = sec[3][j]; } old_GDS_size = i; /* update grid information */ get_nxny(sec, &nx, &ny, &npnts, &res, &scan); /* get nx, ny, and scan mode of grid */ get_nxny_(sec, &nx_, &ny_, &npnts, &res, &scan); /* get nx, ny, and scan mode of grid */ output_order = (nx_ < 1 || ny_ < 1) ? raw : output_order_wanted; if (latlon) { i = 1; #ifdef USE_PROJ4 if (use_proj4 && i != 0) { /* use Proj4 to get lat lon values */ i = proj4_get_latlon(sec, &lon, &lat); // if (i == 0) fprintf(stderr,"proj4_get_lat used\n"); } #endif if (use_gctpc && i != 0) { /* use gctpc to get lat lon values */ i = gctpc_get_latlon(sec, &lon, &lat); // if (i == 0) fprintf(stderr,"gctpc_get_lat used\n"); } if (i != 0) get_latlon(sec, &lon, &lat); /* get lat lon of grid points using built-in code */ } } /* Decode NDFD WxText */ if (WxText) mk_WxKeys(sec); // any fixes to raw grib message before decode need to be placed here if (fix_ncep_2_flag) fix_ncep_2(sec); if (fix_ncep_3_flag) fix_ncep_3(sec); if (fix_ncep_4_flag) fix_ncep_4(sec); #ifdef CHECK j = code_table_5_0(sec); // type of compression /* yes this can be simplified but want to split it up in case other decoders have problems */ if (j == 0 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib/grib-api simple encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); if ((j == 2 || j == 3) && int2(sec[5]+17) != 0 && int4(sec[5] + 31) == 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib complex encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); if (j == 40 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib jpeg encode/deocde may differ from WMO standard, use -g2clib 0 for WMO standard\n"); if (j == 41 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib/grib-api png encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); /* check the size of Section 7 */ /* code to check the other sizes needs to be placed in decode routines */ j = code_table_5_0(sec); // type of compression if (j == 0) { /* simple */ /* to avoid overflow on 32 bit machines */ /* old: k = (GB2_Sec5_nval(sec) * sec[5][19] + 7) / 8 + 5; */ k = 5 + (GB2_Sec5_nval(sec)/8) * sec[5][19] + (GB2_Sec5_nval(sec)%8) * (sec[5][19]/8) + ( (GB2_Sec5_nval(sec)%8) * (sec[5][19]%8) + 7) / 8; if (k != GB2_Sec7_size(sec)) { fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec)); if (decode) fatal_error("Section 7 size, mismatch, simple packing",""); } } else if (j == 4) { /* IEEE */ k = GB2_Sec5_nval(sec) * 4 + 5; if (k != GB2_Sec7_size(sec)) { fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec)); if (decode) fatal_error("Section 7 size, mismatch, IEEE packing",""); } } /* code table 4.3 can change units, warn if undefined */ if (err_4_3_count < 2) { if (code_table_4_3(sec) == 255) { fprintf(stderr,"** WARNING input Code Table 4.3 = 255 (undefined) **\n"); err_4_3_count++; } } #endif if (decode) { #ifdef CHECK if (code_table_6_0(sec) == 0) { // has bitmap k = GB2_Sec3_npts(sec) - GB2_Sec5_nval(sec); if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec))) fatal_error_uu("inconsistent number of bitmap points sec3-sec5: %u sec6: %u", k, missing_points(sec[6]+6, GB2_Sec3_npts(sec))); } else if (code_table_6_0(sec) == 255) { // no bitmap if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec)) fatal_error_uu("inconsistent number of data points sec3: %u sec5: %u", GB2_Sec3_npts(sec), GB2_Sec5_nval(sec)); } #endif /* allocate data */ if (GB2_Sec3_npts(sec) != ndata) { if (ndata) free(data); ndata = GB2_Sec3_npts(sec); if (ndata) { data = (float *) malloc(sizeof(float) * (size_t) ndata); if (data == NULL) { ndata = 0; fatal_error("main: memory allocation failed data",""); } } else { data = NULL; } } j = code_table_5_0(sec); // type of compression /* USE G2CLIB */ #ifdef USE_G2CLIB if (use_g2clib == 2) { err = g2_getfld(msg,submsg,1,1,&grib_data); if (err != 0) fatal_error_ii("Fatal g2clib decode err=%d msg=%d", err, msg_no); free_gribfield = 1; has_bitmap = grib_data->ibmap; g2_data = &(grib_data->fld[0]); if (has_bitmap == 0 || has_bitmap == 254) { bitmap = grib_data->bmap; for (k = 0; k < ndata; k++) { data[k] = (bitmap[k] == 0) ? UNDEFINED : g2_data[k]; } } else { for (k = 0; k < ndata; k++) { data[k] = g2_data[k]; } } /* complex packing uses special values for undefined */ ii = sub_missing_values(sec, &missing_c_val_1, &missing_c_val_2); if (ii == 1) { for (k = 0; k < ndata; k++) { if (data[k] == missing_c_val_1) data[k] = UNDEFINED; } } else if (ii == 2) { for (k = 0; k < ndata; k++) { if (data[k] == missing_c_val_1) data[k] = UNDEFINED; if (data[k] == missing_c_val_2) data[k] = UNDEFINED; } } } #endif /* USE INTERNAL DECODER */ if (use_g2clib != 2) { center = GB2_Center(sec); if (use_g2clib == 1) { // introduce g2clib constant field error /* g2clib ignores decimal scaling for constant fields make internal decoders look like g2clib*/ if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) || (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19] == 0) || (center == NCEP && j == 40000 && sec[5][19] == 0) || (center == NCEP && j == 40010 && sec[5][19] == 0) ) { dscale[0] = sec[5][17]; dscale[1] = sec[5][18]; sec[5][17] = sec[5][18] = 0; } } err = unpk_grib(sec, data); if (err != 0) fatal_error_i("Fatal decode packing type %d",err); if (use_g2clib == 1) { // fix up data /* restore decimal scaling */ if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) || (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19]) || (center == NCEP && j == 40000 && sec[5][19] == 0) || (center == NCEP && j == 40010 && sec[5][19] == 0) ) { sec[5][17] = dscale[0]; sec[5][18] = dscale[1]; } } } /* convert to standard output order we:sn */ if (output_order_wanted == wesn) to_we_sn_scan(data, scan, npnts, nx, ny, save_translation); else if (output_order_wanted == wens) to_we_ns_scan(data, scan, npnts, nx, ny, save_translation); } else { if (ndata) free(data); ndata = 0; data = NULL; } /* get scaling parameters */ use_scale = input_scale = scaling(sec, &ref, &dec_scale, &bin_scale, &i) == 0; /* make sure msg_no:pos is put in inv_out so that -last will work */ new_inv_out(); // inv_out[0] = 0; if (num_submsgs > 1) { sprintf(inv_out, "%d.%d%s%ld", msg_no, submsg, ":", pos); } else { sprintf(inv_out, "%d%s%ld", msg_no, ":", pos); } // fprintf(inv_file, "%s", inv_out); fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file); for (j = 0; j < narglist; j++) { /* skip execution if match_flag == 1 */ /* an output option acts as endif for match_flag */ if (match_flag == 1) { if (functions[arglist[j].fn].type == output) match_flag = 0; continue; } // if (functions[arglist[j].fn].type == inv) fprintf(inv_file, "%s", item_deliminator); if (functions[arglist[j].fn].type == inv) fwrite_file(item_deliminator, 1, strlen(item_deliminator), &inv_file); if (functions[arglist[j].fn].type != setup) { new_inv_out(); // inv_out[0] = 0; n_arg = functions[arglist[j].fn].nargs; if (n_arg == 0) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j); else if (n_arg == 1) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); // if(inv_out[0] != 0) fprintf(inv_file, "%s", inv_out); if(inv_out[0] != 0) fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file); } } #ifdef CHECK if (!decode) { if (code_table_6_0(sec) == 0) { // has bitmap k = GB2_Sec3_npts(sec) - GB2_Sec5_nval(sec); if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec))) fatal_error_uu("inconsistent number of bitmap points sec3-sec5: %u sec6: %u", k, missing_points(sec[6]+6, GB2_Sec3_npts(sec))); } else if (code_table_6_0(sec) == 255) { // no bitmap if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec)) fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d", (int) GB2_Sec3_npts(sec), (int) GB2_Sec5_nval(sec)); } } #endif submsg++; #ifdef USE_G2CLIB if (free_gribfield) { g2_free(grib_data); free_gribfield = 0;} #endif // fprintf(inv_file, "%s",end_inv); fwrite_file(end_inv, 1, strlen(end_inv), &inv_file); if (flush_mode) fflush_file(&inv_file); if (dump_msg > 0) break; } /* finalize all functions, call with mode = -2 */ err = 0; for (j = 0; j < narglist; j++) { // if (functions[arglist[j].fn].type != setup) { n_arg = functions[arglist[j].fn].nargs; new_inv_out(); // inv_out[0] = 0; if (n_arg == 0) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j); else if (n_arg == 1) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); // if (inv_out[0]) fprintf(stderr, "%s\n", inv_out); if (inv_out[0]) fprintf(stderr, "%s%s", inv_out, end_inv); // } } err_bin(0); err_string(0); fclose_file(&in_file); if (ndata) { ndata = 0; free(data); } // return 0; return err; } void set_mode(int new_mode) { mode = new_mode; }