#include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include "gribw.h" #include "mk_pds.h" /* necessary */ #define P_PARAM_TABLE(x) p_param_table,x #define P_CENTER(cntr,subcntr) p_center,cntr,p_subcenter,subcntr #define P_PROCESS(process) p_process,process /* optional */ #define P_GRID(grid) p_grid,grid #define P_GDS(has_gds) p_gds,has_gds #define P_BMS(has_bms) p_bms,has_bms /* either or */ #define P_PARAM(var) p_param,var #define P_KPDS5(var) p_param,var /* Either A, B or C */ /* A */ #define P_L_TYPE(x) p_l_type,x #define P_LEVEL(level) p_level,level /* B */ #define P_KPDS6(x) p_l_type,x #define P_KPDS7(x) p_level,x /* C */ #define P_MB(prs_level) p_l_type,100,p_level,prs_level #define P_SURFACE() p_l_type,1,p_level,0 #define P_TROPOPAUSE() p_l_type,7,p_level,0 #define P_TOA() p_l_type,8,p_level,0 #define P_MSL() p_l_type,102,p_level,0 #define P_COLUMN() p_l_type,200,p_level,0 /* this */ #define P_DATE(yymmddhh) p_date,yymmddhh /* or this */ #define P_YEAR(year) p_year,year #define P_MONTH(month) p_month,month #define P_DAY(day) p_day,day #define P_HOUR(hour) p_hour,hour #define P_MINUTE(minute) p_minute,minute /* time units */ #define MINUTE 0 #define HOUR 1 #define DAY 2 #define MONTH 3 #define YEAR 4 #define DECADE 5 #define NORMAL 6 #define CENTURY 7 #define SECOND 254 /* this */ #define P_ANALYSIS() p_t_range,0,p_t_p1,0,p_t_p2,0,p_t_unit,HOUR,p_n_ave,0,p_missing,0 #define P_FORECAST(n,unit) p_t_range,10,p_t_p1,((n)/256),p_t_p2,((n)%256),p_t_unit,unit #define P_AVERAGE(from,to,unit) #define P_ACCUM(from,to,unit) #define P_END() p_end enum f_pds {p_end, p_param_table, p_center, p_process, p_grid, p_GDS, p_BMS, p_param, p_l_type, p_level, p_year, p_month, p_day, p_hour, p_minute, p_date, p_t_unit, p_t_p1, p_t_p2, p_t_range, p_n_ave, p_missing, p_subcenter,p_bytes}; unsigned char *pds_tool(char *old_pds, ...) { unsigned char pds[MAX_LEN_PDS], *pds2; enum {undefined, defined, default_val, copied} pds_def[MAX_LEN_PDS]; va_list ap; enum f_pds type; int i, pds_len = 28, debug = 1; va_start(ap, old_pds); if (old_pds == NULL) { for (i = 0 ; i < MAX_LEN_PDS; i++) { pds[i] = 0; pds_def[i] = undefined; } pds[0] = pds[1] = 0; pds[2] = pds_len; pds_def[0] = pds_def[1] = pds_def[2] = default_val; } else { pds_len = (pds[0] << 16) + (pds[1] << 8) + pds[2]; for (i = 0 ; i < pds_len; i++) { pds[i] = old_pds[i]; pds_def[i] = copied; } } while ((type = va_arg(ap, enum f_pds)) != p_end) { i = va_arg(ap, int); switch(type) { case p_param_table: if (debug) printf("param table %d\n", i); pds[3] = i; pds_def[3] = defined; break; case p_center: if (debug) printf("center %d\n", i); pds[4] = i; pds_def[4] = defined; break; case p_process: if (debug) printf("process %d\n", i); pds[5] = i; pds_def[5] = defined; break; case p_grid: if (debug) printf("grid %d\n", i); pds[6] = i; pds_def[6] = defined; break; case p_GDS: if (debug) printf("gds %d\n", i); pds[7] = (pds[7] & 127) | (i ? 128 : 0); break; case p_BMS: if (debug) printf("gds %d\n", i); pds[7] = (pds[7] & 0xbf) | (i ? 64 : 0); break; case p_param: if (debug) printf("param %d\n", i); pds[8] = i; pds_def[8] = defined; break; case p_l_type: if (debug) printf("l_type %d\n", i); pds[9] = i; pds_def[9] = defined; break; case p_level: if (debug) printf("level %d\n", i); pds[10] = i / 256; pds[11] = i % 256; pds_def[10] = defined; pds_def[11] = defined; break; case p_year: if (debug) printf("year %d\n", i); pds[12] = i % 100; pds_def[12] = defined; pds[24] = (i - 1) / 100 + 1; pds_def[24] = defined; break; case p_month: if (debug) printf("month %d\n", i); pds[13] = i; pds_def[13] = defined; break; case p_day: if (debug) printf("day %d\n", i); pds[14] = i; pds_def[14] = defined; break; case p_hour: if (debug) printf("hour %d\n", i); pds[15] = i; pds_def[15] = defined; break; case p_minute: if (debug) printf("hour %d\n", i); pds[16] = i; pds_def[16] = defined; break; case p_date: if (debug) printf("date %d\n", i); /* minute */ pds[16] = 0; pds_def[16] = defined; /* hour */ pds[15] = i % 100; pds_def[15] = defined; i = i / 100; /* day */ pds[14] = i % 100; pds_def[14] = defined; /* month */ pds[13] = i % 100; pds_def[13] = defined; i = i / 100; /* year */ pds[12] = i % 100; pds_def[12] = defined; pds[24] = (i - 1) / 100 + 1; pds_def[24] = defined; break; case p_t_unit: if (debug) printf("forecast time units %d\n", i); pds[17] = i; pds_def[17] = defined; break; case p_t_p1: if (debug) printf("forecast p1 %d\n", i); pds[18] = i; pds_def[18] = defined; break; case p_t_p2: if (debug) printf("forecast p2 %d\n", i); pds[19] = i; pds_def[19] = defined; break; case p_t_range: if (debug) printf("forecast time range %d\n", i); pds[20] = i; pds_def[20] = defined; break; case p_n_ave: if (debug) printf("n ave %d\n", i); pds[21] = i / 256; pds[22] = i % 256; pds_def[21] = defined; pds_def[22] = defined; break; case p_missing: if (debug) printf("missing %d\n", i); pds[23] = i; pds_def[23] = defined; break; case p_subcenter: if (debug) printf("subcenter %d\n", i); pds[25] = i; pds_def[25] = defined; break; default: printf("undefined argument:mk_pds\n"); printf("%d %d\n", type, i); break; } } va_end(ap); /* set default values */ /* parameter table */ if (pds_def[3] == undefined) { pds[3] = DEFAULT_PARAMETER_TABLE; pds_def[3] = default_val; } /* center */ if (pds_def[4] == undefined) { pds[4] = DEFAULT_CENTER; pds_def[4] = default_val; } /* subcenter */ if (pds_def[25] == undefined) { pds[25] = DEFAULT_SUBCENTER; pds_def[25] = default_val; } /* process */ if (pds_def[5] == undefined) { pds[5] = DEFAULT_PROCESS; pds_def[5] = default_val; } /* kpds5, kpds6, kpds7 */ if (pds_def[8] == undefined) { pds[8] = DEFAULT_PARAM; pds_def[8] = default_val; } if (pds_def[9] == undefined) { pds[9] = DEFAULT_L_TYPE; pds_def[9] = default_val; } if (pds_def[10] == undefined) { pds[10] = DEFAULT_LEVEL1; pds_def[10] = default_val; } if (pds_def[11] == undefined) { pds[11] = DEFAULT_LEVEL2; pds_def[11] = default_val; } /* time range etc */ if (pds_def[17] == undefined) { pds[17] = DEFAULT_TIME_UNIT; pds_def[17] = default_val; } if (pds_def[18] == undefined) { pds[18] = DEFAULT_TIME_P1; pds_def[18] = default_val; } if (pds_def[19] == undefined) { pds[19] = DEFAULT_TIME_P2; pds_def[19] = default_val; } if (pds_def[20] == undefined) { pds[20] = DEFAULT_TIME_RANGE; pds_def[20] = default_val; } if (debug) { for (i = 3; i < pds_len; i++) { if (i != 7 && i != 22 && i != 26 && i != 27) { if (pds_def[i] == undefined) { fprintf(stderr,"PDS octet %d is undefined\n", i+1); } if (pds_def[i] == default_val) { fprintf(stderr,"PDS octet %d has default value\n", i+1); } } } } if (old_pds != NULL) { pds2 = old_pds; } else { if ((pds2 = (unsigned char *) malloc(pds_len)) == NULL) { fprintf(stderr,"memory allocation error: mk_pds\n"); exit(9); } } for (i = 0; i < pds_len; i++) { pds2[i] = pds[i]; } return pds2; } void main(void) { unsigned char *pds, *gds, *bms, *bds; int i, nxny; float array[144*73]; FILE *output; if ((output = fopen("output.grb","wb")) == NULL) { fprintf(stderr,"could not open file: output.grb\n"); exit(7); } for (i = 0; i < 144*73; i++) { array[i] = i; } pds = pds_tool(NULL,P_DATE(1996123106),P_CENTER(7,0),P_PARAM(7), P_PROCESS(62),P_MB(500), P_ANALYSIS(), p_end); gds = NCEP_GDS(pds,2); nxny = 144*73; bms = mk_BMS(pds, array, &nxny, 1.0, -1.0); bds = mk_BDS(pds, array, nxny); wrt_grib_msg(output, pds, gds, bms, bds); free(bds); if (bms) free(bms); free(gds); free(pds); }