00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00020
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 #include <io.h>
00064
00066 int
00067 read_netcdf_var_3d(double **buf, info_field_struct *info_field, proj_struct *proj, char *filename, char *varname,
00068 char *dimxname, char *dimyname, char *timename, int *nlon, int *nlat, int *ntime, int outinfo) {
00086 int istat;
00087
00088 size_t dimval;
00089
00090 int ncinid;
00091 int varinid;
00092 int projinid;
00093 nc_type vartype_main;
00094 int varndims;
00095 int vardimids[NC_MAX_VAR_DIMS];
00096 int timediminid;
00097 int londiminid;
00098 int latdiminid;
00099
00100 size_t start[3];
00101 size_t count[3];
00102
00103 float valf;
00104 int vali;
00105 char *tmpstr = NULL;
00106 size_t t_len;
00107
00108 float *proj_latin = NULL;
00109 int npts = 0;
00110 char *grid_mapping = NULL;
00111
00112
00113 tmpstr = (char *) malloc(MAXPATH * sizeof(char));
00114 if (tmpstr == NULL) alloc_error(__FILE__, __LINE__);
00115
00116
00117
00118
00119 if (outinfo == TRUE)
00120 printf("%s: Opening for reading NetCDF input file %s\n", __FILE__, filename);
00121 istat = nc_open(filename, NC_NOWRITE, &ncinid);
00122 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00123
00124 if (outinfo == TRUE)
00125 printf("%s: READ %s %s\n", __FILE__, varname, filename);
00126
00127
00128 istat = nc_inq_dimid(ncinid, timename, &timediminid);
00129 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00130 istat = nc_inq_dimlen(ncinid, timediminid, &dimval);
00131 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00132 *ntime = (int) dimval;
00133
00134 istat = nc_inq_dimid(ncinid, dimyname, &latdiminid);
00135 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00136 istat = nc_inq_dimlen(ncinid, latdiminid, &dimval);
00137 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00138 *nlat = (int) dimval;
00139
00140 istat = nc_inq_dimid(ncinid, dimxname, &londiminid);
00141 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00142 istat = nc_inq_dimlen(ncinid, londiminid, &dimval);
00143 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00144 *nlon = (int) dimval;
00145
00146
00147 istat = nc_inq_varid(ncinid, varname, &varinid);
00148 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00149
00152
00153 istat = nc_inq_var(ncinid, varinid, (char *) NULL, &vartype_main, &varndims, vardimids, (int *) NULL);
00154 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00155
00156
00157 if (varndims != 3 && varndims != 2) {
00158 (void) fprintf(stderr, "%s: Error NetCDF type and/or dimensions nlon %d nlat %d.\n", __FILE__, *nlon, *nlat);
00159 (void) free(tmpstr);
00160 istat = ncclose(ncinid);
00161 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00162 return -1;
00163 }
00164
00165 if (varndims == 2) {
00166 if ((*nlat) != (*nlon)) {
00167 (void) fprintf(stderr, "%s: Error NetCDF type and/or dimensions nlon %d nlat %d.\n", __FILE__, *nlon, *nlat);
00168 (void) free(tmpstr);
00169 istat = ncclose(ncinid);
00170 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00171 return -1;
00172 }
00173 npts = *nlon;
00174 *nlat = 0;
00175 }
00176
00177
00178 if (info_field != NULL) {
00179
00180 if (vartype_main == NC_FLOAT) {
00181 istat = nc_get_att_float(ncinid, varinid, "missing_value", &valf);
00182 if (istat != NC_NOERR)
00183 info_field->fillvalue = -9999.0;
00184 else
00185 info_field->fillvalue = (double) valf;
00186 }
00187 else if (vartype_main == NC_DOUBLE) {
00188 istat = nc_get_att_double(ncinid, varinid, "missing_value", &(info_field->fillvalue));
00189 if (istat != NC_NOERR)
00190 info_field->fillvalue = -9999.0;
00191 }
00192
00193
00194 istat = nc_inq_attlen(ncinid, varinid, "coordinates", &t_len);
00195 if (istat == NC_NOERR) {
00196 istat = nc_get_att_text(ncinid, varinid, "coordinates", tmpstr);
00197 if (istat == NC_NOERR) {
00198 if (tmpstr[t_len-1] != '\0')
00199 tmpstr[t_len] = '\0';
00200 info_field->coordinates = strdup(tmpstr);
00201 }
00202 else
00203 info_field->coordinates = strdup("lon lat");
00204 }
00205 else
00206 info_field->coordinates = strdup("lon lat");
00207
00208
00209 istat = nc_inq_attlen(ncinid, varinid, "grid_mapping", &t_len);
00210 if (istat == NC_NOERR) {
00211 handle_netcdf_error(istat, __FILE__, __LINE__);
00212 istat = nc_get_att_text(ncinid, varinid, "grid_mapping", tmpstr);
00213 if (istat == NC_NOERR) {
00214 if (tmpstr[t_len-1] != '\0')
00215 tmpstr[t_len] = '\0';
00216 info_field->grid_mapping = strdup(tmpstr);
00217 }
00218 else
00219 info_field->grid_mapping = strdup("unknown");
00220 }
00221 else
00222 info_field->grid_mapping = strdup("unknown");
00223
00224
00225 istat = nc_inq_attlen(ncinid, varinid, "units", &t_len);
00226 if (istat == NC_NOERR) {
00227 handle_netcdf_error(istat, __FILE__, __LINE__);
00228 istat = nc_get_att_text(ncinid, varinid, "units", tmpstr);
00229 if (istat == NC_NOERR) {
00230 if (tmpstr[t_len-1] != '\0')
00231 tmpstr[t_len] = '\0';
00232 info_field->units = strdup(tmpstr);
00233 }
00234 else
00235 info_field->units = strdup("unknown");
00236 }
00237 else
00238 info_field->units = strdup("unknown");
00239
00240
00241 istat = nc_inq_attlen(ncinid, varinid, "height", &t_len);
00242 if (istat == NC_NOERR) {
00243 handle_netcdf_error(istat, __FILE__, __LINE__);
00244 istat = nc_get_att_text(ncinid, varinid, "height", tmpstr);
00245 if (istat == NC_NOERR) {
00246 if (tmpstr[t_len-1] != '\0')
00247 tmpstr[t_len] = '\0';
00248 info_field->height = strdup(tmpstr);
00249 }
00250 else
00251 info_field->height = strdup("unknown");
00252 }
00253 else
00254 info_field->height = strdup("unknown");
00255
00256
00257 istat = nc_inq_attlen(ncinid, varinid, "long_name", &t_len);
00258 if (istat == NC_NOERR) {
00259 handle_netcdf_error(istat, __FILE__, __LINE__);
00260 istat = nc_get_att_text(ncinid, varinid, "long_name", tmpstr);
00261 if (istat == NC_NOERR) {
00262 if (tmpstr[t_len-1] != '\0')
00263 tmpstr[t_len] = '\0';
00264 info_field->long_name = strdup(tmpstr);
00265 }
00266 else
00267 info_field->long_name = strdup(varname);
00268 }
00269 else
00270 info_field->long_name = strdup(varname);
00271 }
00272
00273
00274 if (proj != NULL) {
00275 if (info_field == NULL)
00276 grid_mapping = strdup("unknown");
00277 else
00278 grid_mapping = strdup(info_field->grid_mapping);
00279
00280 if ( !strcmp(grid_mapping, "Lambert_Conformal") ) {
00281 istat = nc_inq_varid(ncinid, grid_mapping, &projinid);
00282 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00283 }
00284 else if ( !strcmp(grid_mapping, "rotated_latitude_longitude") ) {
00285 istat = nc_inq_varid(ncinid, grid_mapping, &projinid);
00286 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00287 }
00288 if (proj->name != NULL) {
00289 if ( strcmp(grid_mapping, "Lambert_Conformal") && strcmp(grid_mapping, "Latitude_Longitude") &&
00290 ( !strcmp(proj->name, "Latitude_Longitude") || !strcmp(proj->name, "Lambert_Conformal") ) ) {
00291 (void) free(grid_mapping);
00292 grid_mapping = strdup(proj->name);
00293 }
00294 else if ( strcmp(grid_mapping, "rotated_latitude_longitude") && !strcmp(proj->name, "rotated_pole") ) {
00295 (void) free(grid_mapping);
00296 grid_mapping = strdup("rotated_latitude_longitude");
00297 }
00298 }
00299 if ( !strcmp(grid_mapping, "Lambert_Conformal") ) {
00300
00301
00302
00303
00304
00305
00306
00307
00308 istat = nc_get_var1_int(ncinid, projinid, 0, &vali);
00309 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00310 if (proj->name != NULL)
00311 (void) free(proj->name);
00312 proj->name = strdup(grid_mapping);
00313 if (proj->grid_mapping_name != NULL)
00314 (void) free(proj->grid_mapping_name);
00315 istat = get_attribute_str(&(proj->grid_mapping_name), ncinid, projinid, "grid_mapping_name");
00316
00317 proj_latin = (float *) malloc(2 * sizeof(float));
00318 if (proj_latin == NULL) alloc_error(__FILE__, __LINE__);
00319 istat = nc_get_att_float(ncinid, projinid, "standard_parallel", proj_latin);
00320 proj->latin1 = (double) proj_latin[0];
00321 proj->latin2 = (double) proj_latin[1];
00322 (void) free(proj_latin);
00323
00324 istat = nc_get_att_double(ncinid, projinid, "longitude_of_central_meridian", &(proj->lonc));
00325 istat = nc_get_att_double(ncinid, projinid, "latitude_of_projection_origin", &(proj->lat0));
00326 istat = nc_get_att_double(ncinid, projinid, "false_easting", &(proj->false_easting));
00327 istat = nc_get_att_double(ncinid, projinid, "false_northing", &(proj->false_northing));
00328
00329 }
00330 else if ( !strcmp(grid_mapping, "rotated_latitude_longitude") ) {
00331
00332
00333
00334
00335
00336 istat = nc_get_var1_int(ncinid, projinid, 0, &vali);
00337 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00338 if (proj->name != NULL)
00339 (void) free(proj->name);
00340 proj->name = strdup(grid_mapping);
00341 if (proj->grid_mapping_name != NULL)
00342 (void) free(proj->grid_mapping_name);
00343 istat = get_attribute_str(&(proj->grid_mapping_name), ncinid, projinid, "grid_mapping_name");
00344
00345 istat = nc_get_att_double(ncinid, projinid, "grid_north_pole_latitude", &(proj->latpole));
00346 istat = nc_get_att_double(ncinid, projinid, "grid_north_pole_longitude", &(proj->lonpole));
00347
00348 }
00349 else if ( !strcmp(grid_mapping, "Latitude_Longitude") ) {
00350 if (proj->name != NULL)
00351 (void) free(proj->name);
00352 proj->name = strdup(grid_mapping);
00353 if (proj->grid_mapping_name != NULL)
00354 (void) free(proj->grid_mapping_name);
00355 proj->grid_mapping_name = strdup("Latitude_Longitude");
00356 proj->latin1 = 0.0;
00357 proj->latin2 = 0.0;
00358 proj->lonc = 0.0;
00359 proj->lat0 = 0.0;
00360 proj->false_easting = 0.0;
00361 proj->false_northing = 0.0;
00362 }
00363 else if ( !strcmp(grid_mapping, "list") ) {
00364 if (proj->name != NULL)
00365 (void) free(proj->name);
00366 proj->name = strdup(grid_mapping);
00367 if (proj->grid_mapping_name != NULL)
00368 (void) free(proj->grid_mapping_name);
00369 proj->grid_mapping_name = strdup("list");
00370 proj->latin1 = 0.0;
00371 proj->latin2 = 0.0;
00372 proj->lonc = 0.0;
00373 proj->lat0 = 0.0;
00374 proj->false_easting = 0.0;
00375 proj->false_northing = 0.0;
00376 }
00377 else {
00378 (void) fprintf(stderr, "%s: WARNING: No projection parameter available for %s.\n", __FILE__, grid_mapping);
00379 (void) fprintf(stderr, "%s: WARNING: Assuming list of longitude and latitude points.\n", __FILE__);
00380 if (proj->name != NULL)
00381 (void) free(proj->name);
00382 proj->name = strdup("list");
00383 if (proj->grid_mapping_name != NULL)
00384 (void) free(proj->grid_mapping_name);
00385 proj->grid_mapping_name = strdup("list");
00386 proj->latin1 = 0.0;
00387 proj->latin2 = 0.0;
00388 proj->lonc = 0.0;
00389 proj->lat0 = 0.0;
00390 proj->false_easting = 0.0;
00391 proj->false_northing = 0.0;
00392 }
00393 (void) free(grid_mapping);
00394 }
00395
00396 if (varndims == 3) {
00397
00398 start[0] = 0;
00399 start[1] = 0;
00400 start[2] = 0;
00401 count[0] = (size_t) *ntime;
00402 count[1] = (size_t) *nlat;
00403 count[2] = (size_t) *nlon;
00404
00405 (*buf) = (double *) malloc((*nlat)*(*nlon)*(*ntime) * sizeof(double));
00406 if ((*buf) == NULL) alloc_error(__FILE__, __LINE__);
00407 }
00408 else if (varndims == 2) {
00409
00410 start[0] = 0;
00411 start[1] = 0;
00412 start[2] = 0;
00413 count[0] = (size_t) *ntime;
00414 count[1] = (size_t) npts;
00415 count[2] = 0;
00416
00417 (*buf) = (double *) malloc(npts*(*ntime) * sizeof(double));
00418 if ((*buf) == NULL) alloc_error(__FILE__, __LINE__);
00419 }
00420
00421
00422 istat = nc_get_vara_double(ncinid, varinid, start, count, *buf);
00423 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00424
00425
00426 istat = ncclose(ncinid);
00427 if (istat != NC_NOERR) handle_netcdf_error(istat, __FILE__, __LINE__);
00428
00429
00430 (void) free(tmpstr);
00431
00432
00433 return 0;
00434 }