unsigned char *sec3_polar_stereo(double lov, double lad, int proj, int nx, double x0, double dx, int ny, double y0, double dy, unsigned char **old_sec) { static unsigned char gds[65]; int i; unsigned char *p; if (x0 < 0) x0 += 360.0; uint_char(65, gds); /* 1-4 length of section */ gds[4] = 3; /* section 3 */ gds[5] = 0; /* source of grid */ uint_char(nx*ny, gds+6); /* number of data points */ gds[10] = 0; /* number of octets for optional list of number */ gds[11] = 0; /* list */ gds[12] = 0; /* gdt=20 polar stereographic */ gds[13]= 20; /* shape of the earth */ if (old_sec == NULL) { /* use NCEP default */ gds[14] = 6; /* shape of earth */ gds[15] = 0; /* scale factor of radius of spherical earth */ uint_char(0, gds+16); /* scaled value of radius of spherical earth */ gds[20] = 0; /* scale factor of major radious of oblate earth */ uint_char(0, gds+21); /* scaled value of major axis */ gds[25] = 0; /* scale factor of minor axis */ uint_char(0, gds+26); /* scaled value of minor axis */ } else { p = code_table_3_2_location(old_sec); for (i = 0; i < 16; i++) gds[14+i] = p[i]; } uint_char(nx, gds+30); uint_char(ny, gds+34); int_char((int) floor(y0*ANGLE_FACTOR+0.5), gds+38); /* lat1 */ uint_char((int) floor(x0*ANGLE_FACTOR+0.5), gds+42); /* lon1 */ gds[46] = 32+16; /* flag table 3.3 */ int_char((int) floor(lad*ANGLE_FACTOR+0.5), gds+47); uint_char((int) floor(lov*ANGLE_FACTOR+0.5), gds+51); int_char((int) floor(fabs(dx)*1000+0.5), gds+55); /* Di 1/1000 of a meter */ int_char((int) floor(fabs(dy)*1000+0.5), gds+59); /* Dj 1/1000 of a meter */ gds[63] = proj; gds[64] = 0; /* scanning mode */ if (dx < 0.0) gds[64] |= 128; if (dy > 0.0) gds[64] |= 64; return gds; }
unsigned char *sec3_mercator(double lad, int nx, double x0, double dx, double xn, int ny, double y0, double dy, double yn, unsigned char **old_sec) { static unsigned char gds[100]; unsigned char *p; int i; if (x0 < 0) x0 += 360.0; uint_char(72, gds); /* 1-4 length of section */ gds[4] = 3; /* section 3 */ gds[5] = 0; /* source of grid */ uint_char(nx*ny, gds+6); /* number of data points */ gds[10] = 0; /* number of octets for optional list of number */ gds[11] = 0; /* list */ gds[12] = 0; gds[13] = 10; /* template 3.0 mercator grid */ /* shape of the earth */ if (old_sec == NULL) { /* use NCEP default */ gds[14] = 6; /* shape of earth */ gds[15] = 0; /* scale factor of radius of spherical earth */ uint_char(0, gds+16); /* scaled value of radius of spherical earth */ gds[20] = 0; /* scale factor of major radious of oblate earth */ uint_char(0, gds+21); /* scaled value of major axis */ gds[25] = 0; /* scale factor of minor axis */ uint_char(0, gds+26); /* scaled value of minor axis */ } else { p = code_table_3_2_location(old_sec); for (i = 0; i < 16; i++) gds[14+i] = p[i]; } uint_char(nx, gds+30); uint_char(ny, gds+34); int_char((int) floor(y0*ANGLE_FACTOR+0.5), gds+38); /* lat1 */ uint_char((int) floor(x0*ANGLE_FACTOR+0.5), gds+42); /* lon1 */ int_char((int) floor(lad*ANGLE_FACTOR+0.5), gds+47); int_char((int) floor(yn*ANGLE_FACTOR+0.5), gds+51); /* lat2 */ if (xn > 360.0) xn -= 360.0; if (xn < 0.0) xn += 360.0; uint_char( (int) floor(xn*ANGLE_FACTOR+0.5), gds+55); /* lon2 */ int_char(0, gds+60); /* only handle 0 orient */ int_char((int) floor(fabs(dx) * 1000.0 + 0.5), gds+64); /* Di i direction increment */ int_char((int) floor(fabs(dy) * 1000.0 + 0.5), gds+68); /* Dj i direction increment */ gds[46] = 32+16; /* flag table 3.3 */ gds[59] = 0; /* scanning mode */ if (dx < 0.0) gds[59] |= 128; if (dy > 0.0) gds[59] |= 64; return gds; }
void s_printf(char *format,...) { va_list opt; char out[2]=" "; int val; char *s; va_start(opt, format); while(format[0]) { if(format[0]!='%') {out[0]=*format++;os_puts(out);} else { format++; switch(format[0]) { case 'd': case 'i': val=va_arg(opt,int); int_char(val); os_puts(mem_cad); break; case 'u': val=va_arg(opt, unsigned); uint_char(val); os_puts(mem_cad); break; case 'x': val=va_arg(opt,int); hex_char((u32) val); os_puts(mem_cad); break; case 's': s=va_arg(opt,char *); os_puts(s); break; } format++; } } va_end(opt); }
int f_set_prob(ARG5) { int pdt, val, scale; double value; unsigned char *p; if (mode < 0) return 0; pdt = code_table_4_0(sec); switch(pdt) { case 0: case 1: case 2: case 4: case 6: f_set_pdt(call_ARG1(inv_out, NULL, "+5")); break; case 8: case 10: case 11: case 12: case 13: case 14: case 15: f_set_pdt(call_ARG1(inv_out, NULL, "+9")); break; } p = code_table_4_9_location(sec); p[-2] = (unsigned char) atoi(arg1); p[-1] = (unsigned char) atoi(arg2); p[0] = (unsigned char) atoi(arg3); // encode lower limit value = atof(arg4); best_scaled_value(value, &scale,&val); p[1] = scale & 255; uint_char(val, p+2); // encode upper limit value = atof(arg5); best_scaled_value(value, &scale,&val); p[6] = scale & 255; uint_char(val, p+7); return 0; }
int f_grib_out_irr(ARG2) { float *data_tmp; int all, i, j; unsigned int n; unsigned char *gds, *old_gds, *p; if (mode == -1) { latlon = decode = 1; if (strcmp(arg1,"defined") && strcmp(arg1,"all")) fatal_error("grib_out_irr: %s should be all or defined", arg1); *local = (void *) ffopen(arg2, file_append? "ab" : "wb" ); if (*local == NULL) fatal_error("Could not open %s", arg2); return 0; } if (mode == -2) { ffclose((FILE *) *local); return 0; } if (lat == NULL || lon == NULL) fatal_error("grid_out_irr: failed, no lat-lon information",""); all = strcmp(arg1,"all") == 0; if (all) { n = ndata; } else { for (i = n = 0; i < ndata; i++) { if (DEFINED_VAL(data[i])) n++; } } if (n == 0) { fprintf(stderr,"grib_out_irr: no grid points to write out, no write\n"); return 0; } if ((gds = (unsigned char *) malloc(n * 8 + 30)) == NULL) fatal_error("grib_out_irr: memory allocation",""); if ((data_tmp = (float *) malloc(n* sizeof(float))) == NULL) fatal_error("grib_out_irr: memory allocation",""); /* sec3 = grid defintion */ uint_char(30+n*8, gds); gds[4] = 3; // sec3 gds[5] = 0; // use table 3.1 uint_char(n, gds+6); gds[10] = 0; // no optional list octets gds[11] = 0; uint2_char(130, gds+12); p = code_table_3_2_location(sec); if (p == NULL) { // no earth descripition for (i = 14; i < 30; i++) { gds[i] = 255; } } else { for (i = 14; i < 30; i++) { gds[i] = p[i-14]; } } if (all) { for (i = 0; i < ndata; i++) { int_char( (int) (lat[i] * 1000000.0), gds + 30 + i*8); int_char( (int) (lon[i] * 1000000.0), gds + 34 + i*8); data_tmp[i] = data[i]; } } else { for (j = i = 0; i < ndata; i++) { if (DEFINED_VAL(data[i])) { int_char( (int) (lat[i] * 1000000.0), gds + 30 + j*8); int_char( (int) (lon[i] * 1000000.0), gds + 34 + j*8); data_tmp[j++] = data[i]; } } } old_gds = sec[3]; sec[3] = gds; grib_wrt(sec, data_tmp, n, n, 1, use_scale, dec_scale, bin_scale, wanted_bits, max_bits, grib_type, (FILE *) *local); sec[3] = old_gds; if (flush_mode) fflush((FILE *) *local); free(data_tmp); free(gds); return 0; }
int grib_ieee(unsigned char **sec, float *data, unsigned int ndata, FILE *out, FILE *head, FILE *tail, FILE *c) { int i; unsigned int n_defined, j; // int flag; unsigned long int size; unsigned char *p, *sec0, *sec1, *sec2, *sec3, *sec4, *sec5, *sec6, *sec7; unsigned char s[8]; float *new_data; /* required passed sections */ sec0 = sec[0]; sec1 = sec[1]; sec2 = sec[2]; sec3 = sec[3]; sec4 = sec[4]; /* change scan mode */ // flag = flag_table_3_4(sec); // set_order(sec, output_order); /* make a new section 6 */ n_defined = ndata; sec6 = (unsigned char *) malloc(6); if (sec6 == NULL) fatal_error("grib_out ieee memory allocation sec6",""); uint_char(6 * sizeof (unsigned char), sec6); sec6[4] = 6; // section 5 sec6[5] = 255; // no bitmap /* data representation section */ sec5 = (unsigned char *) malloc(12 * sizeof(unsigned char)); if (sec5 == NULL) fatal_error("grib_out ieee memory allocation sec5",""); uint_char(12 * sizeof (unsigned char), sec5); sec5[4] = 5; // section 5 uint_char(ndata, sec5+5); // number of points uint2_char(4,sec5+9); // data template 4 sec5[11] = 1; // precision: ieee 32-bit /* data section */ new_data = (float *) malloc(n_defined * sizeof(float)); if (new_data == NULL) fatal_error("grib_out ieee memory allocation data",""); undo_output_order(data, new_data, n_defined); sec7 = (unsigned char *) malloc(5 + n_defined * 4); if (sec7 == NULL) fatal_error("grib_out ieee memory allocation sec7",""); uint_char(5+n_defined*4, sec7); sec7[4] = 7; p = sec7 + 5; for (j = 0; j < n_defined; j++) { flt2ieee_nan(new_data[j], p); p += 4; } free(new_data); size = (unsigned long int) GB2_Sec0_size + GB2_Sec8_size + (sec1 ? uint4(sec1) : 0) + (sec2 ? uint4(sec2) : 0) + (sec3 ? uint4(sec3) : 0) + (sec4 ? uint4(sec4) : 0) + (sec5 ? uint4(sec5) : 0) + (sec6 ? uint4(sec6) : 0) + (sec7 ? uint4(sec7) : 0); fprintf(c,"unsigned char head[] = {"); /* section 0 */ fwrite((void *) sec0, sizeof(char), 8, out); fwrite((void *) sec0, sizeof(char), 8, head); output_c(c, sec0, 8); uint8_char(size, s); fwrite((void *) s, sizeof(char), 8, out); fwrite((void *) s, sizeof(char), 8, head); output_c(c, s, 8); fwrite((void *)sec1, sizeof(char), uint4(sec1), out); fwrite((void *)sec1, sizeof(char), uint4(sec1), head); output_c(c, sec1, uint4(sec1)); if (sec2) fwrite((void *)sec2, sizeof(char), uint4(sec2), out); if (sec2) fwrite((void *)sec2, sizeof(char), uint4(sec2), head); if (sec2) output_c(c, sec2, uint4(sec2)); if (sec3) fwrite((void *)sec3, sizeof(char), uint4(sec3), out); if (sec3) fwrite((void *)sec3, sizeof(char), uint4(sec3), head); if (sec3) output_c(c, sec3, uint4(sec3)); if (sec4) fwrite((void *)sec4, sizeof(char), uint4(sec4), out); if (sec4) fwrite((void *)sec4, sizeof(char), uint4(sec4), head); if (sec4) output_c(c, sec4, uint4(sec4)); if (sec5) fwrite((void *)sec5, sizeof(char), uint4(sec5), out); if (sec5) fwrite((void *)sec5, sizeof(char), uint4(sec5), head); if (sec5) output_c(c, sec5, uint4(sec5)); if (sec6) fwrite((void *)sec6, sizeof(char), uint4(sec6), out); if (sec6) fwrite((void *)sec6, sizeof(char), uint4(sec6), head); if (sec6) output_c(c, sec6, uint4(sec6)); if (sec7) fwrite((void *)sec7, sizeof(char), uint4(sec7), out); if (sec7) fwrite((void *)sec7, sizeof(char), 5, head); if (sec7) output_c(c, sec7, 5); fprintf(c,"};\n\n"); s[0] = s[1] = s[2] = s[3] = 55; /* s = "7777" */ fprintf(c,"unsigned char tail[4] = {55, 55, 55, 55};\n\n"); fwrite((void *) s, sizeof(char), 4, out); fwrite((void *) s, sizeof(char), 4, tail); fprintf(c,"#define NDATA %u\n", ndata); i = 0; fprintf(c,"#define SEC0 0\n"); fprintf(c,"#define DISCIPLINE %d\n",6); fprintf(c,"#define EDITION %d\n",7); i = 16; fprintf(c,"#define SEC1 %d\n",i); fprintf(c,"#define CENTER %d\n",i+5); fprintf(c,"#define SUBCENTER %d\n",i+7); fprintf(c,"#define MASTERTABLE %d\n",i+9); fprintf(c,"#define LOCALTABLE %d\n",i+9); fprintf(c,"#define YEAR %d\n",i+12); fprintf(c,"#define MONTH %d\n",i+14); fprintf(c,"#define DAY %d\n",i+15); fprintf(c,"#define HOUR %d\n",i+16); fprintf(c,"#define MINUTE %d\n",i+17); fprintf(c,"#define SECOND %d\n",i+18); i = i + uint4(sec1); if (sec2) { fprintf(c,"#define SEC2 %d\n",i); i = i + uint4(sec2); } if (sec3) { fprintf(c,"#define SEC3 %d\n",i); i = i + uint4(sec3); } if (sec4) { fprintf(c,"#define SEC4 %d\n",i); fprintf(c,"#define PRODUCTDEFTEMPLATENUM %d\n",i+7); fprintf(c,"#define PRODUCTDEFTEMPLATE %d\n",i+9); fprintf(c,"#define PRODUCTCATEGORY %d\n",i+9); fprintf(c,"#define PRODUCTNUMBER %d\n",i+9); i = i + uint4(sec4); } if (sec5) { fprintf(c,"#define SEC5 %d\n",i); i = i + uint4(sec5); } if (sec6) { fprintf(c,"#define SEC6 %d\n",i); i = i + uint4(sec6); } if (sec7) { fprintf(c,"#define SEC7 %d\n",i); i = i + uint4(sec4); } free(sec5); free(sec6); free(sec7); // /* set scan mode to original order */ // set_flag_table_3_4(sec, flag); 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 ieee_grib_out(unsigned char **sec, float *data, unsigned int ndata, FILE *out) { unsigned int n_defined, i; int j; unsigned char *p, *sec0, *sec1, *sec2, *sec3, *sec4, *sec5, *sec6, *sec7; #ifdef IEEE_BITMAP float *data_tmp; #endif /* required passed sections */ sec0 = sec[0]; sec1 = sec[1]; sec2 = sec[2]; sec3 = sec[3]; sec4 = sec[4]; /* make a new section 6 */ #ifdef IEEE_BITMAP data_tmp = (float *) malloc(ndata * sizeof(float)); for (i = 0; i < ndata; i++) { data_tmp[i] = data[i]; } n_defined = ndata; sec6 = mk_bms(data_tmp, &n_defined); // make bitmap section if (sec6 == NULL) fatal_error("grib_out ieee memory allocation sec6",""); #else n_defined = ndata; sec6 = (unsigned char *) malloc(6); if (sec6 == NULL) fatal_error("grib_out ieee memory allocation sec6",""); uint_char(6 * sizeof (unsigned char), sec6); sec6[4] = 6; // section 5 sec6[5] = 255; // no bitmap #endif /* data representation section */ sec5 = (unsigned char *) malloc(12 * sizeof(unsigned char)); if (sec5 == NULL) fatal_error("grib_out ieee memory allocation sec5",""); uint_char(12 * sizeof (unsigned char), sec5); sec5[4] = 5; // section 5 uint_char(ndata, sec5+5); // number of points uint2_char(4,sec5+9); // data template 4 sec5[11] = 1; // precision: ieee 32-bit /* data section */ sec7 = (unsigned char *) malloc(5 + n_defined * 4); if (sec7 == NULL) fatal_error("grib_out ieee memory allocation sec7",""); uint_char(5+n_defined*4, sec7); sec7[4] = 7; p = sec7 + 5; j = 0; for (i = 0; i < n_defined; i++) { #ifdef IEEE_BITMAP flt2ieee_nan(data_tmp[i], p); #else flt2ieee_nan(data[i], p); #endif p += 4; } #ifdef IEEE_BITMAP free(data_tmp); #endif j = wrt_sec(sec0, sec1, sec2, sec3, sec4, sec5, sec6, sec7, out); free(sec5); free(sec6); free(sec7); return j; }
void debug_printf(char *format,...) { #if 1 va_list opt; static char out[32] ATTRIBUTE_ALIGN(32)=" "; int val; char *s; va_start(opt, format); int fd; int message; static int one=1; static u32 buffer[8]; static u32 queuehandle2=-1; if(one) { queuehandle2 = os_message_queue_create(buffer, 8); one=0; } else os_message_queue_receive(queuehandle2, (void *)&message, 0); internal=internal_debug_printf; if(internal & 2) goto salir; if(index_dev & 1) { if(internal) fd = FAT_Open("usb:/ffs_log.txt" ,O_WRONLY | O_APPEND); else fd=os_open("usb:/ffs_log.txt" ,O_WRONLY | O_APPEND); } else { if(internal) fd = FAT_Open("sd:/ffs_log.txt" ,O_WRONLY | O_APPEND); else fd=os_open("sd:/ffs_log.txt" ,O_WRONLY | O_APPEND); } if(fd<0) goto salir; while(format[0]) { if(format[0]!='%') {out[0]=*format++; printf_write(fd, out, strlen(out));} else { format++; switch(format[0]) { case 'd': case 'i': val=va_arg(opt,int); int_char(val); printf_write(fd, mem_cad, strlen(mem_cad)); break; case 'u': val=va_arg(opt, unsigned); uint_char(val); //printf_write(fd, mem_cad, strlen(mem_cad)); printf_write(fd, mem_cad, strlen(mem_cad)); break; case 'x': val=va_arg(opt,int); hex_char((u32) val); printf_write(fd, mem_cad, strlen(mem_cad)); break; case 's': s=va_arg(opt,char *); printf_write(fd, s, strlen(s)); break; } format++; } } va_end(opt); if(internal) FAT_Close(fd); else os_close(fd); salir: os_message_queue_send(queuehandle2, 0, 0); #endif }
unsigned char *sec3_gaussian(int nx, double x0, double dx, int ny, double y0, unsigned char **old_sec) { static unsigned char gds[72]; unsigned char *p; double r; int i; if (x0 < 0) x0 += 360.0; uint_char(72, gds); /* 1-4 length of section */ gds[4] = 3; /* section 3 */ gds[5] = 0; /* source of grid */ uint_char(nx*ny, gds+6); /* number of data points */ gds[10] = 0; /* number of octets for optional list of number */ gds[11] = 0; /* list */ gds[12] = 0; gds[13] = 40; /* template 3.0 gaussian grid*/ /* shape of the earth */ if (old_sec == NULL) { /* use NCEP default */ gds[14] = 6; /* shape of earth */ gds[15] = 0; /* scale factor of radius of spherical earth */ uint_char(0, gds+16); /* scaled value of radius of spherical earth */ gds[20] = 0; /* scale factor of major radious of oblate earth */ uint_char(0, gds+21); /* scaled value of major axis */ gds[25] = 0; /* scale factor of minor axis */ uint_char(0, gds+26); /* scaled value of minor axis */ } else { p = code_table_3_2_location(old_sec); for (i = 0; i < 16; i++) gds[14+i] = p[i]; } uint_char(nx, gds+30); uint_char(ny, gds+34); uint_char(0, gds+38); /* 0 */ uint_char(0xffffffff, gds+42); /* undefined */ int_char((int) floor(y0*ANGLE_FACTOR+0.5), gds+46); /* lat1 */ uint_char((int) floor(x0*ANGLE_FACTOR+0.5), gds+50); /* lon1 */ gds[54] = 32+16; /* flag table 3.3 */ r = -y0; int_char((int) floor(r*ANGLE_FACTOR+0.5), gds+55); /* lat2 */ r = x0 + (nx-1)*dx; if (r >= 360.0) r -= 360.0; if (r < 0.0) r += 360.0; uint_char((int) floor(r*ANGLE_FACTOR+0.5), gds+59); /* lon2 */ int_char((int) floor(fabs(dx) * ANGLE_FACTOR + 0.5), gds+63); /* Di i direction increment */ uint_char(ny/2, gds+67); gds[71] = 0; /* scanning mode */ if (dx < 0.0) gds[71] |= 128; if (y0 < 0.0) gds[71] |= 64; return gds; }
/* * HEADER:100:fix_CFSv2_fcst:misc:3:fixes CFSv2 monthly fcst X=daily or 00/06/12/18 Y=pert no. Z=number ens fcsts v1.0 */ int f_fix_CFSv2_fcst(ARG3) { int subcenter, n_time_ranges, fcst_time_0, fcst_time_1, i; int dtime, unit, id; int ref_year, ref_month, ref_day, ref_hour, ref_minute, ref_second; int fcst0_year, fcst0_month, fcst0_day, fcst0_hour, fcst0_minute, fcst0_second; int fcst1_year, fcst1_month, fcst1_day, fcst1_hour, fcst1_minute, fcst1_second; static unsigned char new_sec4[61]; struct local_struct { int fixed; // number of fields processed int dt; // dt either 6 or 24 int hour0; // initial hour int pert; // perturbation no, 0 = ctl int num_ensemble_members; }; struct local_struct *save; if (mode == -1) { *local = save = (struct local_struct *)malloc( sizeof(struct local_struct)); save->fixed = 0; save->dt = 24; if (strcmp(arg1,"daily") == 0) { save->dt = 6; save->hour0 = 0; } else if (strcmp(arg1,"00") == 0) { save->hour0 = 0; } else if (strcmp(arg1,"06") == 0) { save->hour0 = 6; } else if (strcmp(arg1,"12") == 0) { save->hour0 = 12; } else if (strcmp(arg1,"18") == 0) { save->hour0 = 1; } else fatal_error("fix_CFSv2_fcst: bad arg %s, wanted daily,00,06,12 or 18",arg1); save->pert = atoi(arg2); save->num_ensemble_members = atoi(arg2); } save = *local; if (mode == -2) sprintf(inv_out,"fix_CFSRv2_fcst %d fields fixed" , save->fixed); if (mode < 0) return 0; // only process NCEP CFSv2 monthly forecasts // must be NCEP generated if (GB2_Center(sec) != NCEP) return 0; // subcenter should be 0, 1 (reanalysis), 3 (EMC) or 4 (NCO) subcenter = GB2_Subcenter(sec); if (subcenter != 0 && subcenter != 1 && subcenter != 3 && subcenter != 4) return 0; // must have process id = 82 or 98 id = analysis_or_forecast_generating_process_identifier(sec); if (id != 82 && id != 98) return 0; // product defn table must be 8 (fcst average) if ( code_table_4_0(sec) != 8) return 0; // n_time_ranges should be 1 if ( (n_time_ranges = sec[4][41]) != 1) { fprintf(stderr,"unexected CFSv2 type forecast field .. pdt=8, n=%d\n", n_time_ranges); return 0; } // forecast time units should be months if (sec[4][17] != 3 || sec[4][48] != 3) return 0; fcst_time_0 = int4(sec[4]+18); fcst_time_1 = int4(sec[4]+49) + fcst_time_0; // get reference time reftime(sec, &ref_year, &ref_month, &ref_day, &ref_hour, &ref_minute, &ref_second); if (ref_minute != 0 || ref_second != 0) { fprintf(stderr,"unexected CFSv2 minute/second value != 0\n"); return 0; } if (fcst_time_0 != 0) { // start at day=1 hour=save->hour0 of proper month fcst0_year = ref_year; fcst0_month = ref_month + fcst_time_0; if (fcst0_month > 12) { i = (fcst0_month - 1) / 12; fcst0_year += i; fcst0_month -= (i*12); } fcst0_day = 1; fcst0_hour = save->hour0; fcst0_minute = 0; fcst0_second= 0; } else { // start at current month fcst0_year = ref_year; fcst0_month = ref_month; fcst0_day = ref_day; fcst0_hour = ref_hour; fcst0_minute = ref_minute; fcst0_second= ref_second; if (save->dt == 24) { i = save->hour0 - fcst0_hour; if (i < 0) i += 24; add_time(&fcst0_year, &fcst0_month, &fcst0_day, &fcst0_hour, &fcst0_minute, &fcst0_second, i, HOUR); } } sub_time(fcst0_year, fcst0_month, fcst0_day, fcst0_hour, fcst0_minute, fcst0_second, ref_year, ref_month, ref_day, ref_hour, ref_minute, ref_second, &dtime, &unit); // set forecast time. if (dtime == 0) unit = MONTH; sec[4][17] = unit; int_char(dtime, sec[4]+18); if (fcst_time_1 == 0) fatal_error("fix-CFSv2_fcst: unexpected end_ft",""); if (save->dt == 6) { // ends at 18Z of last day of month fcst1_year = ref_year; fcst1_month = ref_month + fcst_time_1-1; if (fcst1_month > 12) { i = (fcst1_month - 1) / 12; fcst1_year += i; fcst1_month -= (i*12); } fcst1_day = num_days_in_month(fcst1_year, fcst1_month); fcst1_hour = 18; fcst1_minute = 0; fcst1_second= 0; // time increment = 6 hours sec[4][53] = (unsigned char) HOUR; int_char(6, sec[4]+54); } else { fcst1_year = ref_year; fcst1_month = ref_month + fcst_time_1-1; if (fcst1_month > 12) { i = (fcst1_month - 1) / 12; fcst1_year += i; fcst1_month -= (i*12); } fcst1_day = num_days_in_month(fcst1_year, fcst1_month); fcst1_hour = save->hour0; fcst1_minute = 0; fcst1_second= 0; // time increment = 24 hours sec[4][53] = (unsigned char) HOUR; int_char(24, sec[4]+54); } // find stat processing time sub_time(fcst1_year, fcst1_month, fcst1_day, fcst1_hour, fcst1_minute, fcst1_second, fcst0_year, fcst0_month, fcst0_day, fcst0_hour, fcst0_minute, fcst0_second, &dtime, &unit); // change length of processing sec[4][48] = (unsigned char) unit; int_char(dtime, sec[4]+49); // fprintf(stderr,"length of processing %d unit (%d)\n", dtime, unit); // save end-of-processing time save_time(fcst1_year, fcst1_month, fcst1_day, fcst1_hour, fcst1_minute, fcst1_second, sec[4]+34); // make sure that some basic info is correct sec[4][47] = 2; // fcst_time++ // now to add ensemble information for (i = 0; i < 34; i++) new_sec4[i] = sec[4][i]; for (i = 34; i <= 57; i++) new_sec4[i+3] = sec[4][i]; uint_char(61, new_sec4); // length of new sec[4[ new_sec4[7] = 0; // pdt = 11 new_sec4[8] = 11; // add perturbation info if (save->pert == 0) { // pert == 0 means control forecast new_sec4[34] = 0; new_sec4[35] = 0; } else { new_sec4[34] = 3; new_sec4[35] = save->pert; } new_sec4[35] = save->num_ensemble_members; sec[4] = new_sec4; save->fixed = save->fixed + 1; return 0; }
unsigned char *gds_lola(int nx, float x0, float dx, int ny, float y0, float dy) { static unsigned char gds[100]; double r; uint_char(72, gds); /* 1-4 length of section */ gds[4] = 3; /* number of section */ gds[5] = 0; uint_char(nx*ny, gds+6); /* number of data points */ gds[10] = 0; /* number of octtets for optional list of number */ gds[11] = 0; /* code 3.11 */ gds[12] = gds[13] = 0; /* template 3.0 */ /* template 3.0 values */ gds[14] = 0; /* shape of earth */ gds[15] = 0; /* scale factor of radius of spherical earth */ uint_char(0, gds+16); /* scaled value of radius of spherical earth */ gds[20] = 0; /* scale factor of major radious of oblate earth */ uint_char(0, gds+21); /* scaled value of major axis */ gds[25] = 0; /* scale factor of minor axis */ uint_char(0, gds+26); /* scaled value of minor axis */ uint_char(nx, gds+30); uint_char(ny, gds+34); uint_char(0, gds+38); uint_char(0, gds+42); uint_char((int) (y0*1000000.0), gds+46); /* lat1 */ uint_char((int) (x0*1000000.0), gds+50); /* lon1 */ gds[54] = 0; /* flag table 3.3 */ r = y0 + (ny-1)*dy; uint_char((int) (r*1000000.0), gds+55); /* lat1 */ r = x0 + (nx-1)*dx; if (r >= 360.0) r -= 360.0; uint_char((int) (r*1000000.0), gds+59); /* lat1 */ int_char((int) (dx*1000000.0), gds+63); /* Di i direction increment */ int_char((int) (dy*1000000.0), gds+67); /* Dj i direction increment */ gds[71] = 0x40; /* scanning mode */ return gds; }
/* * HEADER:100:irr_grid:output:3:make irregular grid, nearest neighbor, X=lon-lat list Y=radius (km) Z=output grib file */ int f_irr_grid(ARG3) { int i, k, m; struct local_struct { int ngrid; double *lon_lat_list, radius; FILE *out; int *iptr; int last_GDS_change_no; }; struct local_struct *save; const char *t; unsigned char *p; double tmp; float *array; unsigned char *new_sec[8], *new_sec3; /* initialization phase */ if (mode == -1) { decode = latlon = 1; *local = save = (struct local_struct *)malloc( sizeof(struct local_struct)); if (save == NULL) fatal_error("irr_grid: memory allocation",""); /* count number of colons */ t = arg1; i = 0; while (*t) { if (*t++ == ':') i++; } if (i % 2 != 1) fatal_error("irr_grid: need lon0:lat0:lon1:lat1:..:lonN:latN",""); save->ngrid = (i + 1)/2; save->lon_lat_list = (double *) malloc(save->ngrid * 2 * sizeof(double)); save->iptr = (int *) malloc(save->ngrid * sizeof(int)); if (save->lon_lat_list == NULL || save->iptr == NULL ) fatal_error("irr_grid: memory allocation",""); t = arg1; k = sscanf(t, "%lf%n", &tmp, &m); if (k != 1) fatal_error("irr_grid: lat-lon list, %s",t); save->lon_lat_list[0] = tmp; t += m; for (i = 1; i < 2*save->ngrid; i++) { k = sscanf(t, ":%lf%n", &tmp, &m); if (k != 1) fatal_error("irr_grid: lat-lon list, %s",t); save->lon_lat_list[i] = tmp; t += m; } for (i = 0 ; i < save->ngrid; i++) { tmp = save->lon_lat_list[i*2]; if (tmp < 0.0) save->lon_lat_list[i*2] = tmp + 360.0; if (tmp > 360.0) save->lon_lat_list[i*2] = tmp - 360.0; if (fabs(save->lon_lat_list[i*2+1]) > 90.0) fatal_error("irr_grid: bad latitude",""); } if (sscanf(arg2,"%lf",&(save->radius)) != 1) fatal_error("irr_grid: radius %s", arg2); if ((save->out = ffopen(arg3, file_append ? "ab" : "wb" )) == NULL) fatal_error("irr_grid could not open file %s", arg3); } if (mode < 0) return 0; save = (struct local_struct *) *local; if (save->last_GDS_change_no != GDS_change_no) { save->last_GDS_change_no = GDS_change_no; if (lat == NULL || lon == NULL || data == NULL) fatal_error("irr_grid: no val",""); /* find the nearest points for the grid */ closest_init(sec); for (i = 0; i < save->ngrid; i++) { save->iptr[i] = closest(sec, save->lon_lat_list[i*2+1], save->lon_lat_list[i*2]); } } array = (float *) malloc(save->ngrid * sizeof(float)); new_sec3 = (unsigned char *) malloc((30+8*save->ngrid) * sizeof(unsigned char)); if (array == NULL || new_sec3 == NULL) fatal_error("irr_grid: memory allocation",""); /* sec3 = grid defintion */ uint_char(30+save->ngrid*8, new_sec3); new_sec3[4] = 3; // sec3 new_sec3[5] = 0; // use table 3.1 uint_char(save->ngrid, new_sec3+6); new_sec3[10] = 0; // no optional list octets new_sec3[11] = 0; uint2_char(130, new_sec3+12); p = code_table_3_2_location(sec); if (p == NULL) { // no earth descripition for (i = 14; i < 30; i++) { new_sec3[i] = 255; } } else { for (i = 14; i < 30; i++) { new_sec3[i] = p[i-14]; } } /* make new_sec[] with new grid definition */ for (i = 0; i < 8; i++) new_sec[i] = sec[i]; new_sec[3] = new_sec3; for (i = 0; i < save->ngrid; i++) { array[i] = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED; int_char( (int) (save->lon_lat_list[i*2+1] * 1000000.0), new_sec3 + 30 + i*8); uint_char( (int) (save->lon_lat_list[i*2] * 1000000.0), new_sec3 + 34 + i*8); } grib_wrt(new_sec, array, save->ngrid, save->ngrid, 1, use_scale, dec_scale, bin_scale, wanted_bits, max_bits, grib_type, save->out); free(array); free(new_sec3); return 0; }
static int do_ave(struct ave_struct *save) { int i, j, n, ndata, pdt; float *data; unsigned char *p, *sec4; double factor; sec4 = NULL; if (save->has_val == 0) return 0; #ifdef DEBUG printf(" ave nfields=%d missing=%d\n",save->n_fields,save->n_missing); #endif ndata = save->n_sum; if ((data = (float *) malloc(sizeof(float) * ndata)) == NULL) fatal_error("ave: memory allocation",""); factor = 1.0 / save->n_fields; for (i = 0; i < ndata; i++) { if (save->n[i] != save->n_fields) data[i] = UNDEFINED; else data[i] = factor * save->sum[i]; #ifdef DEBUG if (i < 10) printf("data[%d]=%lf n[%d]=%d, sum[%d]=%lf\n", i,data[i],i,save->n[i],i,save->sum[i]); #endif } pdt = GB2_ProdDefTemplateNo(save->first_sec); // average of a forecast if (pdt == 0) { sec4 = (unsigned char *) malloc(58 * sizeof(unsigned char)); if (sec4 == NULL) fatal_error("fcst_ave: memory allocation",""); for (i = 0; i < 34; i++) { sec4[i] = save->first_sec[4][i]; } uint_char((unsigned int) 58, sec4); // length sec4[8] = 8; // pdt // verification time save_time(save->year2,save->month2,save->day2,save->hour2,save->minute2,save->second2, sec4+34); sec4[41] = 1; // 1 time range uint_char(save->n_missing, sec4+42); sec4[46] = 0; // average sec4[47] = 2; // rt=constant, ft++ sec4[48] = save->dt_unit; // total length of stat processing uint_char(save->dt*(save->n_fields+save->n_missing-1), sec4+49); sec4[53] = save->dt_unit; // time step uint_char(save->dt, sec4+54); } // average of an ensemble forecast, use pdt 4.11 else if (pdt == 1) { sec4 = (unsigned char *) malloc(61 * sizeof(unsigned char)); if (sec4 == NULL) fatal_error("fcst_ave: memory allocation",""); for (i = 0; i < 37; i++) { sec4[i] = save->first_sec[4][i]; } uint_char((unsigned int) 61, sec4); // length sec4[8] = 11; // pdt // verification time save_time(save->year2,save->month2,save->day2,save->hour2,save->minute2,save->second2, sec4+37); sec4[44] = 1; // 1 time range uint_char(save->n_missing, sec4+45); sec4[49] = 0; // average sec4[50] = 2; // rt=constant, ft++ sec4[51] = save->dt_unit; // total length of stat processing uint_char(save->dt*(save->n_fields+save->n_missing-1), sec4+52); sec4[56] = save->dt_unit; // time step uint_char(save->dt, sec4+57); } // average of an average or accumulation else if (pdt == 8) { i = GB2_Sec4_size(save->first_sec); n = save->first_sec[4][41]; if (i != 46 + 12*n) fatal_error("ave: invalid sec4 size for pdt=8",""); // keep pdt == 8 but make it 12 bytes bigger sec4 = (unsigned char *) malloc( (i+12) * sizeof(unsigned char)); if (sec4 == NULL) fatal_error("fcst_ave: memory allocation",""); uint_char((unsigned int) i+12, sec4); // new length for (i = 4; i < 34; i++) { // keep base of pdt sec4[i] = save->first_sec[4][i]; } // new verification time save_time(save->year2,save->month2,save->day2,save->hour2,save->minute2,save->second2, sec4+34); // number of stat-proc loops is increased by 1 sec4[41] = n + 1; // copy old stat-proc loops // for (j = n*12-1; j >= 0; j--) sec4[58+j] = save->first_sec[4][46+j]; for (j = 0; j < n*12; j++) sec4[46+12+j] = save->first_sec[4][46+j]; #ifdef DEBUG printf("save->n_missing =%d save->n_fields=%d\n",save->n_missing,save->n_fields); #endif uint_char(save->n_missing, sec4+42); sec4[46] = 0; // average sec4[47] = 2; // fcst++ sec4[48] = save->dt_unit; // total length of stat processing uint_char(save->dt*(save->n_fields+save->n_missing-1), sec4+49); // missing sec4[53] = save->dt_unit; // time step uint_char(save->dt, sec4+54); } else { fatal_error_i("ave with pdt %d is not supported",pdt); } // write grib file p = save->first_sec[4]; save->first_sec[4] = sec4; grib_wrt(save->first_sec, data, ndata, save->nx, save->ny, save->use_scale, save->dec_scale, save->bin_scale, save->wanted_bits, save->max_bits, save->grib_type, save->output); if (flush_mode) fflush(save->output); save->first_sec[4] = p; free(data); free(sec4); return 0; }