00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #include <io.h>
00065
00067 int
00068 write_netcdf_dims_3d(double *lon, double *lat, double *x, double *y, double *alt, double *timein, char *cal_type, char *time_units,
00069 int nlon, int nlat, int ntime, char *timestep, char *gridname, char *coords,
00070 char *grid_mapping_name, double latin1, double latin2,
00071 double lonc, double lat0, double false_easting, double false_northing,
00072 double lonpole, double latpole,
00073 char *lonname, char *latname, char *timename,
00074 char *filename, int outinfo) {
00106 int istat;
00107
00108 int ncoutid;
00109 int timedimoutid, xdimoutid, ydimoutid;
00110 int timeoutid, latoutid, lonoutid, xoutid, youtid, projoutid, altoutid;
00111 int vardimids[NC_MAX_VAR_DIMS];
00112
00113 short int *alts = NULL;
00114
00115 size_t start[3];
00116 size_t count[3];
00117
00118 int vali;
00119 int i;
00120
00121 float *proj_latin = NULL;
00122
00123 char *tmpstr = NULL;
00124 double *tmpd = NULL;
00125 int *tmpi = NULL;
00126
00127 double minlat;
00128 double maxlat;
00129 double minlon;
00130 double maxlon;
00131
00132 short int fillvalue = -99;
00133
00134
00135 tmpstr = strdup(filename);
00136 istat = chdir(dirname(tmpstr));
00137 (void) free(tmpstr);
00138
00139 tmpstr = (char *) malloc(MAXPATH * sizeof(char));
00140 if (tmpstr == NULL) alloc_error(__FILE__, __LINE__);
00141
00142
00143 if (outinfo == TRUE)
00144 printf("%s: Writing info from NetCDF output file %s\n", __FILE__, filename);
00145 istat = nc_open(filename, NC_WRITE, &ncoutid);
00146 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00147
00148 istat = nc_redef(ncoutid);
00149 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00150
00151
00152 istat = nc_def_dim(ncoutid, timename, NC_UNLIMITED, &timedimoutid);
00153 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00154 if ( !strcmp(gridname, "Latitude_Longitude")) {
00155 istat = nc_def_dim(ncoutid, lonname, nlon, &xdimoutid);
00156 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00157 istat = nc_def_dim(ncoutid, latname, nlat, &ydimoutid);
00158 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00159 }
00160 else if ( !strcmp(gridname, "list")) {
00161 istat = nc_def_dim(ncoutid, lonname, nlon, &xdimoutid);
00162 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00163 istat = nc_def_dim(ncoutid, latname, nlon, &ydimoutid);
00164 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00165 }
00166 else {
00167 istat = nc_def_dim(ncoutid, "x", nlon, &xdimoutid);
00168 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00169 istat = nc_def_dim(ncoutid, "y", nlat, &ydimoutid);
00170 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00171 }
00172
00173
00174 vardimids[0] = timedimoutid;
00175 vardimids[1] = 0;
00176 istat = nc_def_var(ncoutid, timename, NC_INT, 1, vardimids, &timeoutid);
00177 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00178
00179 if ( !strcmp(coords, "1D") ) {
00180 vardimids[0] = xdimoutid;
00181 vardimids[1] = 0;
00182 istat = nc_def_var(ncoutid, lonname, NC_DOUBLE, 1, vardimids, &lonoutid);
00183 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00184 vardimids[0] = ydimoutid;
00185 vardimids[1] = 0;
00186 istat = nc_def_var(ncoutid, latname, NC_DOUBLE, 1, vardimids, &latoutid);
00187 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00188 }
00189 else if ( !strcmp(gridname, "Latitude_Longitude") && !strcmp(coords, "2D") ) {
00190 vardimids[0] = ydimoutid;
00191 vardimids[1] = xdimoutid;
00192 istat = nc_def_var(ncoutid, lonname, NC_DOUBLE, 2, vardimids, &lonoutid);
00193 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00194 vardimids[0] = ydimoutid;
00195 vardimids[1] = xdimoutid;
00196 istat = nc_def_var(ncoutid, latname, NC_DOUBLE, 2, vardimids, &latoutid);
00197 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00198 }
00199 else {
00200 vardimids[0] = ydimoutid;
00201 vardimids[1] = xdimoutid;
00202 istat = nc_def_var(ncoutid, lonname, NC_DOUBLE, 2, vardimids, &lonoutid);
00203 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00204 vardimids[0] = xdimoutid;
00205 vardimids[1] = 0;
00206 istat = nc_def_var(ncoutid, "x", NC_INT, 1, vardimids, &xoutid);
00207 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00208 vardimids[0] = ydimoutid;
00209 vardimids[1] = xdimoutid;
00210 istat = nc_def_var(ncoutid, latname, NC_DOUBLE, 2, vardimids, &latoutid);
00211 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00212 vardimids[0] = ydimoutid;
00213 vardimids[1] = 0;
00214 istat = nc_def_var(ncoutid, "y", NC_INT, 1, vardimids, &youtid);
00215 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00216 }
00217
00218
00219 if ( !strcmp(gridname, "Lambert_Conformal")) {
00220 istat = nc_def_var(ncoutid, gridname, NC_INT, 0, 0, &projoutid);
00221 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00222 }
00223 else if ( !strcmp(gridname, "rotated_pole")) {
00224 istat = nc_def_var(ncoutid, gridname, NC_INT, 0, 0, &projoutid);
00225 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00226 }
00227
00228 if (alt != NULL) {
00229
00230 vardimids[0] = ydimoutid;
00231 vardimids[1] = xdimoutid;
00232 istat = nc_def_var(ncoutid, "Altitude", NC_SHORT, 2, vardimids, &altoutid);
00233 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00234 }
00235
00236
00237 istat = nc_put_att_text(ncoutid, timeoutid, "units", strlen(time_units), time_units);
00238 istat = nc_put_att_text(ncoutid, timeoutid, "calendar", strlen(cal_type), cal_type);
00239 (void) sprintf(tmpstr, "time in %s", time_units);
00240 istat = nc_put_att_text(ncoutid, timeoutid, "long_name", strlen(tmpstr), tmpstr);
00241
00242 istat = nc_put_att_text(ncoutid, NC_GLOBAL, "timestep", strlen(timestep), timestep);
00243
00244
00245 (void) strcpy(tmpstr, "degrees_east");
00246 istat = nc_put_att_text(ncoutid, lonoutid, "units", strlen(tmpstr), tmpstr);
00247 (void) strcpy(tmpstr, "longitude coordinate");
00248 istat = nc_put_att_text(ncoutid, lonoutid, "long_name", strlen(tmpstr), tmpstr);
00249 (void) strcpy(tmpstr, "longitude");
00250 istat = nc_put_att_text(ncoutid, lonoutid, "standard_name", strlen(tmpstr), tmpstr);
00251
00252
00253 (void) strcpy(tmpstr, "degrees_north");
00254 istat = nc_put_att_text(ncoutid, latoutid, "units", strlen(tmpstr), tmpstr);
00255 (void) strcpy(tmpstr, "latitude coordinate");
00256 istat = nc_put_att_text(ncoutid, latoutid, "long_name", strlen(tmpstr), tmpstr);
00257 (void) strcpy(tmpstr, "latitude");
00258 istat = nc_put_att_text(ncoutid, latoutid, "standard_name", strlen(tmpstr), tmpstr);
00259
00260 if (alt != NULL) {
00261
00262 (void) strcpy(tmpstr, "meters");
00263 istat = nc_put_att_text(ncoutid, altoutid, "units", strlen(tmpstr), tmpstr);
00264 (void) strcpy(tmpstr, "Altitude");
00265 istat = nc_put_att_text(ncoutid, altoutid, "long_name", strlen(tmpstr), tmpstr);
00266 (void) strcpy(tmpstr, "Altitude");
00267 istat = nc_put_att_text(ncoutid, altoutid, "standard_name", strlen(tmpstr), tmpstr);
00268 (void) strcpy(tmpstr, "lon lat");
00269 istat = nc_put_att_text(ncoutid, altoutid, "coordinates", strlen(tmpstr), tmpstr);
00270 fillvalue = -99;
00271 istat = nc_put_att_short(ncoutid, altoutid, "_FillValue", NC_SHORT, 1, &fillvalue);
00272 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00273 istat = nc_put_att_short(ncoutid, altoutid, "missing_value", NC_SHORT, 1, &fillvalue);
00274 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00275 }
00276
00277 if ( strcmp(gridname, "Latitude_Longitude") && strcmp(gridname, "list")) {
00278
00279
00280
00281
00282
00283 (void) strcpy(tmpstr, "m");
00284 istat = nc_put_att_text(ncoutid, xoutid, "units", strlen(tmpstr), tmpstr);
00285 (void) strcpy(tmpstr, "x coordinate of projection");
00286 istat = nc_put_att_text(ncoutid, xoutid, "long_name", strlen(tmpstr), tmpstr);
00287 (void) strcpy(tmpstr, "projection_x_coordinate");
00288 istat = nc_put_att_text(ncoutid, xoutid, "standard_name", strlen(tmpstr), tmpstr);
00289
00290
00291
00292
00293
00294
00295 (void) strcpy(tmpstr, "m");
00296 istat = nc_put_att_text(ncoutid, youtid, "units", strlen(tmpstr), tmpstr);
00297 (void) strcpy(tmpstr, "y coordinate of projection");
00298 istat = nc_put_att_text(ncoutid, youtid, "long_name", strlen(tmpstr), tmpstr);
00299 (void) strcpy(tmpstr, "projection_y_coordinate");
00300 istat = nc_put_att_text(ncoutid, youtid, "standard_name", strlen(tmpstr), tmpstr);
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 }
00318
00319 if ( !strcmp(gridname, "Lambert_Conformal")) {
00320
00321 istat = nc_put_att_text(ncoutid, projoutid, "grid_mapping_name", strlen(grid_mapping_name), grid_mapping_name);
00322 if (alt != NULL)
00323 istat = nc_put_att_text(ncoutid, altoutid, "grid_mapping_name", strlen(grid_mapping_name), grid_mapping_name);
00324
00325 proj_latin = (float *) malloc(2 * sizeof(float));
00326 if (proj_latin == NULL) alloc_error(__FILE__, __LINE__);
00327 proj_latin[0] = (float) latin1;
00328 proj_latin[1] = (float) latin2;
00329 istat = nc_put_att_float(ncoutid, projoutid, "standard_parallel", NC_FLOAT, 2, proj_latin);
00330 (void) free(proj_latin);
00331
00332 istat = nc_put_att_double(ncoutid, projoutid, "longitude_of_central_meridian", NC_FLOAT, 1, &lonc);
00333 istat = nc_put_att_double(ncoutid, projoutid, "latitude_of_projection_origin", NC_FLOAT, 1, &lat0);
00334 istat = nc_put_att_double(ncoutid, projoutid, "false_easting", NC_FLOAT, 1, &false_easting);
00335 istat = nc_put_att_double(ncoutid, projoutid, "false_northing", NC_FLOAT, 1, &false_northing);
00336 }
00337 else if ( !strcmp(gridname, "rotated_pole")) {
00338
00339 istat = nc_put_att_text(ncoutid, projoutid, "grid_mapping_name", strlen(grid_mapping_name), grid_mapping_name);
00340 if (alt != NULL)
00341 istat = nc_put_att_text(ncoutid, altoutid, "grid_mapping_name", strlen(grid_mapping_name), grid_mapping_name);
00342
00343 istat = nc_put_att_double(ncoutid, projoutid, "grid_north_pole_latitude", NC_FLOAT, 1, &latpole);
00344 istat = nc_put_att_double(ncoutid, projoutid, "grid_north_pole_longitude", NC_FLOAT, 1, &lonpole);
00345 }
00346
00347 (void) strcpy(tmpstr, "Grid");
00348 istat = nc_put_att_text(ncoutid, NC_GLOBAL, "cdm_datatype", strlen(tmpstr), tmpstr);
00349
00350
00351 maxlat = -9999.9;
00352 minlat = 9999.9;
00353 maxlon = -9999.9;
00354 minlon = 9999.9;
00355 if ( !strcmp(gridname, "list") ) {
00356 for (i=0; i<(nlon); i++) {
00357 if (lat[i] > maxlat) maxlat = lat[i];
00358 if (lat[i] < minlat) minlat = lat[i];
00359 }
00360 for (i=0; i<(nlon); i++) {
00361 if (lon[i] > maxlon) maxlon = lon[i];
00362 if (lon[i] < minlon) minlon = lon[i];
00363 }
00364 }
00365 else {
00366 for (i=0; i<(nlat*nlon); i++) {
00367 if (lat[i] > maxlat) maxlat = lat[i];
00368 if (lat[i] < minlat) minlat = lat[i];
00369 }
00370 for (i=0; i<(nlat*nlon); i++) {
00371 if (lon[i] > maxlon) maxlon = lon[i];
00372 if (lon[i] < minlon) minlon = lon[i];
00373 }
00374 }
00375 istat = nc_put_att_double(ncoutid, NC_GLOBAL, "geospatial_lat_max", NC_DOUBLE, 1, &maxlat);
00376 istat = nc_put_att_double(ncoutid, NC_GLOBAL, "geospatial_lat_min", NC_DOUBLE, 1, &minlat);
00377 istat = nc_put_att_double(ncoutid, NC_GLOBAL, "geospatial_lon_max", NC_DOUBLE, 1, &maxlon);
00378 istat = nc_put_att_double(ncoutid, NC_GLOBAL, "geospatial_lon_min", NC_DOUBLE, 1, &minlon);
00379
00380
00381 istat = nc_enddef(ncoutid);
00382 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00383
00384 if ( !strcmp(gridname, "Lambert_Conformal") || !strcmp(gridname, "rotated_pole") ) {
00385
00386 vali = 1;
00387 istat = nc_put_var1_int(ncoutid, projoutid, 0, &vali);
00388 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00389 }
00390
00391
00392 if (ntime > 0) {
00393 start[0] = 0;
00394 count[0] = (size_t) ntime;
00395 count[1] = 0;
00396 count[2] = 0;
00397 istat = nc_put_vara_double(ncoutid, timeoutid, start, count, timein);
00398 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00399 }
00400
00401 if ( !strcmp(gridname, "list") ) {
00402 start[0] = 0;
00403 start[1] = 0;
00404 start[2] = 0;
00405 count[0] = (size_t) nlon;
00406 count[1] = 0;
00407 count[2] = 0;
00408 istat = nc_put_vara_double(ncoutid, latoutid, start, count, lat);
00409 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00410
00411 start[0] = 0;
00412 start[1] = 0;
00413 start[2] = 0;
00414 count[0] = (size_t) nlon;
00415 count[1] = 0;
00416 count[2] = 0;
00417 istat = nc_put_vara_double(ncoutid, lonoutid, start, count, lon);
00418 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00419 }
00420 else if ( !strcmp(coords, "1D") ) {
00421 start[0] = 0;
00422 start[1] = 0;
00423 start[2] = 0;
00424 count[0] = (size_t) nlat;
00425 count[1] = 0;
00426 count[2] = 0;
00427 tmpd = (double *) malloc(nlat * sizeof(double));
00428 if (tmpd == NULL) alloc_error(__FILE__, __LINE__);
00429 for (i=0; i<nlat; i++)
00430 tmpd[i] = lat[i*nlon];
00431 istat = nc_put_vara_double(ncoutid, latoutid, start, count, tmpd);
00432 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00433
00434 start[0] = 0;
00435 start[1] = 0;
00436 start[2] = 0;
00437 count[0] = (size_t) nlon;
00438 count[1] = 0;
00439 count[2] = 0;
00440 tmpd = (double *) realloc(tmpd, nlon * sizeof(double));
00441 if (tmpd == NULL) alloc_error(__FILE__, __LINE__);
00442 for (i=0; i<nlon; i++)
00443 tmpd[i] = lon[i];
00444 istat = nc_put_vara_double(ncoutid, lonoutid, start, count, tmpd);
00445 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00446 (void) free(tmpd);
00447 }
00448 else {
00449 start[0] = 0;
00450 start[1] = 0;
00451 start[2] = 0;
00452 count[0] = (size_t) nlat;
00453 count[1] = (size_t) nlon;
00454 count[2] = 0;
00455 istat = nc_put_vara_double(ncoutid, latoutid, start, count, lat);
00456 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00457
00458 start[0] = 0;
00459 start[1] = 0;
00460 start[2] = 0;
00461 count[0] = (size_t) nlat;
00462 count[1] = (size_t) nlon;
00463 count[2] = 0;
00464 istat = nc_put_vara_double(ncoutid, lonoutid, start, count, lon);
00465 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00466 }
00467
00468 if ( (!strcmp(gridname, "Lambert_Conformal")||!strcmp(gridname, "rotated_pole")) && x != NULL && y != NULL) {
00469 start[0] = 0;
00470 start[1] = 0;
00471 start[2] = 0;
00472 count[0] = (size_t) nlon;
00473 count[1] = 0;
00474 count[2] = 0;
00475 tmpi = (int *) realloc(tmpi, nlon * sizeof(int));
00476 if (tmpi == NULL) alloc_error(__FILE__, __LINE__);
00477 for (i=0; i<nlon; i++)
00478 tmpi[i] = x[i];
00479
00480 istat = nc_put_vara_int(ncoutid, xoutid, start, count, tmpi);
00481 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00482 start[0] = 0;
00483 start[1] = 0;
00484 start[2] = 0;
00485 count[0] = (size_t) nlat;
00486 count[1] = 0;
00487 count[2] = 0;
00488 tmpi = (int *) realloc(tmpi, nlat * sizeof(int));
00489 if (tmpi == NULL) alloc_error(__FILE__, __LINE__);
00490 for (i=0; i<nlat; i++)
00491 tmpi[i] = y[i];
00492 istat = nc_put_vara_int(ncoutid, youtid, start, count, tmpi);
00493 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00494 (void) free(tmpi);
00495 }
00496
00497 if (alt != NULL) {
00498 alts = (short int *) malloc(nlat*nlon * sizeof(short int));
00499 if (alts == NULL) alloc_error(__FILE__, __LINE__);
00500 for (i=0; i<(nlat*nlon); i++)
00501 alts[i] = (short int) alt[i];
00502 start[0] = 0;
00503 start[1] = 0;
00504 start[2] = 0;
00505 count[0] = (size_t) nlat;
00506 count[1] = (size_t) nlon;
00507 count[2] = 0;
00508 istat = nc_put_vara_short(ncoutid, altoutid, start, count, alts);
00509 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00510 (void) free(alts);
00511 }
00512
00513
00514 istat = ncclose(ncoutid);
00515 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00516
00517 (void) free(tmpstr);
00518
00519 return 0;
00520 }