NetCDF  4.9.2
sfc_pres_temp_wr.c
Go to the documentation of this file.
1 /* Copyright 2019 University Corporation for Atmospheric
2  Research/Unidata. See COPYRIGHT file for conditions of use. */
15 #include <stdio.h>
16 #include <string.h>
17 #include <netcdf.h>
18 
19 /* This is the name of the data file we will create. */
20 #define FILE_NAME "sfc_pres_temp.nc"
21 
22 /* We are writing 2D data, a 6 x 12 lat-lon grid. We will need two
23  * netCDF dimensions. */
24 #define NDIMS 2
25 #define NLAT 6
26 #define NLON 12
27 #define LAT_NAME "latitude"
28 #define LON_NAME "longitude"
29 
30 /* Names of things. */
31 #define PRES_NAME "pressure"
32 #define TEMP_NAME "temperature"
33 #define UNITS "units"
34 #define DEGREES_EAST "degrees_east"
35 #define DEGREES_NORTH "degrees_north"
36 
37 /* These are used to construct some example data. */
38 #define SAMPLE_PRESSURE 900
39 #define SAMPLE_TEMP 9.0
40 #define START_LAT 25.0
41 #define START_LON -125.0
42 
43 /* Handle errors by printing an error message and exiting with a
44  * non-zero status. */
45 #define ERR(e) {printf("Error: %s\n", nc_strerror(e)); return 2;}
46 
47 int
48 main()
49 {
50  int ncid, lon_dimid, lat_dimid, pres_varid, temp_varid;
51 
52 /* In addition to the latitude and longitude dimensions, we will also
53  create latitude and longitude netCDF variables which will hold the
54  actual latitudes and longitudes. Since they hold data about the
55  coordinate system, the netCDF term for these is: "coordinate
56  variables." */
57  int lat_varid, lon_varid;
58 
59  int dimids[NDIMS];
60 
61  /* We will write surface temperature and pressure fields. */
62  float pres_out[NLAT][NLON];
63  float temp_out[NLAT][NLON];
64  float lats[NLAT], lons[NLON];
65 
66  /* It's good practice for each netCDF variable to carry a "units"
67  * attribute. */
68  char pres_units[] = "hPa";
69  char temp_units[] = "celsius";
70 
71  /* Loop indexes. */
72  int lat, lon;
73 
74  /* Error handling. */
75  int retval;
76 
77  /* Create some pretend data. If this wasn't an example program, we
78  * would have some real data to write, for example, model
79  * output. */
80  for (lat = 0; lat < NLAT; lat++)
81  lats[lat] = START_LAT + 5.*lat;
82  for (lon = 0; lon < NLON; lon++)
83  lons[lon] = START_LON + 5.*lon;
84 
85  for (lat = 0; lat < NLAT; lat++)
86  for (lon = 0; lon < NLON; lon++)
87  {
88  pres_out[lat][lon] = SAMPLE_PRESSURE + (lon * NLAT + lat);
89  temp_out[lat][lon] = SAMPLE_TEMP + .25 * (lon * NLAT + lat);
90  }
91 
92  /* Create the file. */
93  if ((retval = nc_create(FILE_NAME, NC_CLOBBER, &ncid)))
94  ERR(retval);
95 
96  /* Define the dimensions. */
97  if ((retval = nc_def_dim(ncid, LAT_NAME, NLAT, &lat_dimid)))
98  ERR(retval);
99  if ((retval = nc_def_dim(ncid, LON_NAME, NLON, &lon_dimid)))
100  ERR(retval);
101 
102  /* Define coordinate netCDF variables. They will hold the
103  coordinate information, that is, the latitudes and longitudes. A
104  varid is returned for each.*/
105  if ((retval = nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, &lat_dimid,
106  &lat_varid)))
107  ERR(retval);
108  if ((retval = nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, &lon_dimid,
109  &lon_varid)))
110  ERR(retval);
111 
112  /* Define units attributes for coordinate vars. This attaches a
113  text attribute to each of the coordinate variables, containing
114  the units. Note that we are not writing a trailing NULL, just
115  "units", because the reading program may be fortran which does
116  not use null-terminated strings. In general it is up to the
117  reading C program to ensure that it puts null-terminators on
118  strings where necessary.*/
119  if ((retval = nc_put_att_text(ncid, lat_varid, UNITS,
120  strlen(DEGREES_NORTH), DEGREES_NORTH)))
121  ERR(retval);
122  if ((retval = nc_put_att_text(ncid, lon_varid, UNITS,
123  strlen(DEGREES_EAST), DEGREES_EAST)))
124  ERR(retval);
125 
126  /* Define the netCDF variables. The dimids array is used to pass
127  the dimids of the dimensions of the variables.*/
128  dimids[0] = lat_dimid;
129  dimids[1] = lon_dimid;
130  if ((retval = nc_def_var(ncid, PRES_NAME, NC_FLOAT, NDIMS,
131  dimids, &pres_varid)))
132  ERR(retval);
133  if ((retval = nc_def_var(ncid, TEMP_NAME, NC_FLOAT, NDIMS,
134  dimids, &temp_varid)))
135  ERR(retval);
136 
137  /* Define units attributes for vars. */
138  if ((retval = nc_put_att_text(ncid, pres_varid, UNITS,
139  strlen(pres_units), pres_units)))
140  ERR(retval);
141  if ((retval = nc_put_att_text(ncid, temp_varid, UNITS,
142  strlen(temp_units), temp_units)))
143  ERR(retval);
144 
145  /* End define mode. */
146  if ((retval = nc_enddef(ncid)))
147  ERR(retval);
148 
149  /* Write the coordinate variable data. This will put the latitudes
150  and longitudes of our data grid into the netCDF file. */
151  if ((retval = nc_put_var_float(ncid, lat_varid, &lats[0])))
152  ERR(retval);
153  if ((retval = nc_put_var_float(ncid, lon_varid, &lons[0])))
154  ERR(retval);
155 
156  /* Write the pretend data. This will write our surface pressure and
157  surface temperature data. The arrays of data are the same size
158  as the netCDF variables we have defined. */
159  if ((retval = nc_put_var_float(ncid, pres_varid, &pres_out[0][0])))
160  ERR(retval);
161  if ((retval = nc_put_var_float(ncid, temp_varid, &temp_out[0][0])))
162  ERR(retval);
163 
164  /* Close the file. */
165  if ((retval = nc_close(ncid)))
166  ERR(retval);
167 
168  printf("*** SUCCESS writing example file sfc_pres_temp.nc!\n");
169  return 0;
170 }
EXTERNL int nc_put_att_text(int ncid, int varid, const char *name, size_t len, const char *op)
Write a text attribute.
Definition: dattput.c:153
EXTERNL int nc_close(int ncid)
Close an open netCDF dataset.
Definition: dfile.c:1302
EXTERNL int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition: dfile.c:400
EXTERNL int nc_enddef(int ncid)
Leave define mode.
Definition: dfile.c:1029
EXTERNL int nc_def_dim(int ncid, const char *name, size_t len, int *idp)
Define a new dimension.
Definition: ddim.c:121
int nc_put_var_float(int ncid, int varid, const float *op)
Write an entire variable with one call.
Definition: dvarput.c:962
EXTERNL int nc_def_var(int ncid, const char *name, nc_type xtype, int ndims, const int *dimidsp, int *varidp)
Define a new variable.
Definition: dvar.c:214
Main header file for the C API.
#define NC_CLOBBER
Destroy existing file.
Definition: netcdf.h:129
#define NC_FLOAT
single precision floating point number
Definition: netcdf.h:40