2 *****************************************************************************
3 * rg_write_grib - function which encapsulates parts of the MEL grib library
8 * tahutchinson@tasc.com
14 * pds - a pointer to a structure which stores information about the
15 * grib product definition section.
16 * gds - a pointer to a structure which stores information about the
17 * grib grid definition section.
18 * filename - This is the output grib file which will be created if
19 * it does not already exist. If this file already exists,
20 * grib records will be appended to it.
21 * data - a 2-d array holding the values at grid points for the grid
22 * that is to be output.
27 * Caveats: This function only supports a "latlon" grid
28 * currently, this is equivalent to a cylindrical equidistant
31 ***************************************************************************
37 #include "gribfuncs.h"
45 int rg_fwrite_grib(PDS_INPUT
*pds
, grid_desc_sec
*gds
, float **data
, FILE *fid
)
49 DATA_INPUT data_input
;
51 USER_INPUT user_input
;
57 if ((gds
->head
.usData_type
== LATLON_PRJ
) ||
58 (gds
->head
.usData_type
== GAUSS_PRJ
)) {
59 if (gds
->head
.usData_type
== GAUSS_PRJ
) {
60 strcpy(geom_in
.prjn_name
,"gaussian");
62 strcpy(geom_in
.prjn_name
,"spherical");
64 geom_in
.nx
= gds
->llg
.usNi
;
65 geom_in
.ny
= gds
->llg
.usNj
;
66 geom_in
.parm_1
= (gds
->llg
.iDj
)/1000.;
67 geom_in
.parm_2
= (gds
->llg
.iDi
)/1000.;
68 geom_in
.first_lat
= gds
->llg
.lLat1
/1000.;
69 geom_in
.first_lon
= gds
->llg
.lLon1
/1000.;
70 geom_in
.last_lat
= gds
->llg
.lLat2
/1000.;
71 geom_in
.last_lon
= gds
->llg
.lLon2
/1000.;
72 geom_in
.scan
= gds
->llg
.usScan_mode
;
73 geom_in
.usRes_flag
= gds
->llg
.usRes_flag
;
74 } else if (gds
->head
.usData_type
== LAMB_PRJ
) {
75 strcpy(geom_in
.prjn_name
,"lambert");
76 geom_in
.nx
= gds
->lam
.iNx
;
77 geom_in
.ny
= gds
->lam
.iNy
;
78 geom_in
.x_int_dis
= gds
->lam
.ulDx
/1000.;
79 geom_in
.y_int_dis
= gds
->lam
.ulDy
/1000.;
80 geom_in
.parm_1
= (gds
->lam
.lLat_cut2
)/1000.;
81 geom_in
.parm_2
= (gds
->lam
.lLat_cut1
)/1000.;
82 geom_in
.parm_3
= (gds
->lam
.lLon_orient
)/1000.;
83 geom_in
.first_lat
= gds
->lam
.lLat1
/1000.;
84 geom_in
.first_lon
= gds
->lam
.lLon1
/1000.;
85 geom_in
.scan
= gds
->lam
.usScan_mode
;
86 geom_in
.usRes_flag
= gds
->lam
.usRes_flag
;
88 fprintf(stderr
,"rg_fwrite_grib: invalid input projection %d\n",
89 gds
->head
.usData_type
);
93 data_input
.usProc_id
= pds
->usProc_id
;
94 data_input
.usGrid_id
= pds
->usGrid_id
;
95 data_input
.usParm_id
= pds
->usParm_id
;
96 data_input
.usParm_sub_id
= pds
->usCenter_sub
;
97 data_input
.usLevel_id
= pds
->usLevel_id
;
98 data_input
.nLvl_1
= pds
->usHeight1
;
99 data_input
.nLvl_2
= pds
->usHeight2
;
100 data_input
.nYear
= pds
->usYear
+ (pds
->usCentury
-1)*100;
101 data_input
.nMonth
= pds
->usMonth
;
102 data_input
.nDay
= pds
->usDay
;
103 data_input
.nHour
= pds
->usHour
;
104 data_input
.nMinute
= pds
->usMinute
;
105 data_input
.nSecond
= 0;
106 data_input
.usFcst_id
= pds
->usFcst_unit_id
;
107 data_input
.usFcst_per1
= pds
->usP1
;
108 data_input
.usFcst_per2
= pds
->usP2
;
109 data_input
.usTime_range_id
= pds
->usTime_range
;
110 data_input
.usTime_range_avg
= pds
->usTime_range_avg
;
111 data_input
.usTime_range_mis
= pds
->usTime_range_mis
;
112 /* We add an extra digit here, because the grib library seems to cut off
113 * one more than I would prefer.
115 data_input
.nDec_sc_fctr
= pds
->sDec_sc_fctr
+1;
117 user_input
.chCase_id
='0';
118 user_input
.usParm_tbl
=pds
->usParm_tbl
;
119 user_input
.usSub_tbl
=pds
->usSub_tbl
;
121 user_input.usCenter_id=190;
123 user_input
.usCenter_id
= pds
->usCenter_id
;
124 user_input
.usCenter_sub
=pds
->usCenter_sub
;
125 user_input
.usTrack_num
=0;
126 user_input
.usGds_bms_id
= 128;
127 user_input
.usBDS_flag
=0;
128 user_input
.usBit_pack_num
=0;
131 data_one_d
= (float *)calloc(geom_in
.nx
*geom_in
.ny
,sizeof(float));
132 if (data_one_d
== NULL
) {
133 fprintf(stderr
,"rg_fwrite_grib: could not allocate space for data_one_d\n");
137 for (i
=0; i
<geom_in
.nx
; i
++) {
138 for (j
=0; j
<geom_in
.ny
; j
++) {
139 data_one_d
[i
+j
*geom_in
.nx
] = data
[j
][i
];
143 status
= init_gribhdr(&gh
,errmsg
);
145 fprintf (stderr
,"rg_fwrite_grib: %s",errmsg
);
149 status
= grib_enc(data_input
,user_input
,geom_in
,data_one_d
,gh
,errmsg
);
151 fprintf (stderr
,"rg_fwrite_grib: %s",errmsg
);
155 status
= gribhdr2file(gh
,fid
,errmsg
);
157 fprintf (stderr
,"rg_fwrite_grib: %s",errmsg
);
167 int rg_write_grib(PDS_INPUT
*pds
, grid_desc_sec
*gds
, char filename
[],
175 sprintf(tmpfile
,"/tmp/tmpgribfile_%d",getpid());
176 fid
= fopen(tmpfile
,"wb");
178 fprintf(stderr
,"rg_write_grib: Could not open %s\n",tmpfile
);
182 status
= rg_fwrite_grib(pds
,gds
,data
,fid
);
185 fprintf(stderr
,"rg_write_grib: rg_fwrite_grib failed\n");
189 /* append tmpfile to filename */
190 sprintf(tmpstring
,"cat %s >> %s",tmpfile
,filename
);