NetCDF 4.9.3
Loading...
Searching...
No Matches
pres_temp_4D_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
16#include <stdio.h>
17#include <string.h>
18#include <netcdf.h>
19
20/* This is the name of the data file we will create. */
21#define FILE_NAME "pres_temp_4D.nc"
22
23/* We are writing 4D data, a 2 x 6 x 12 lvl-lat-lon grid, with 2
24 timesteps of data. */
25#define NDIMS 4
26#define NLAT 6
27#define NLON 12
28#define LAT_NAME "latitude"
29#define LON_NAME "longitude"
30#define NREC 2
31#define REC_NAME "time"
32#define LVL_NAME "level"
33#define NLVL 2
34
35/* Names of things. */
36#define PRES_NAME "pressure"
37#define TEMP_NAME "temperature"
38#define UNITS "units"
39#define DEGREES_EAST "degrees_east"
40#define DEGREES_NORTH "degrees_north"
41
42/* These are used to construct some example data. */
43#define SAMPLE_PRESSURE 900.0f
44#define SAMPLE_TEMP 9.0f
45#define START_LAT 25.0f
46#define START_LON -125.0f
47
48/* For the units attributes. */
49#define UNITS "units"
50#define PRES_UNITS "hPa"
51#define TEMP_UNITS "celsius"
52#define LAT_UNITS "degrees_north"
53#define LON_UNITS "degrees_east"
54#define MAX_ATT_LEN 80
55
56/* Handle errors by printing an error message and exiting with a
57 * non-zero status. */
58#define ERR(e) {printf("Error: %s\n", nc_strerror(e)); return 2;}
59
60int
61main()
62{
63 /* IDs for the netCDF file, dimensions, and variables. */
64 int ncid, lon_dimid, lat_dimid, lvl_dimid, rec_dimid;
65 int lat_varid, lon_varid, pres_varid, temp_varid;
66 int dimids[NDIMS];
67
68 /* The start and count arrays will tell the netCDF library where to
69 write our data. */
70 size_t start[NDIMS], count[NDIMS];
71
72 /* Program variables to hold the data we will write out. We will only
73 need enough space to hold one timestep of data; one record. */
74 float pres_out[NLVL][NLAT][NLON];
75 float temp_out[NLVL][NLAT][NLON];
76
77 /* These program variables hold the latitudes and longitudes. */
78 float lats[NLAT], lons[NLON];
79
80 /* Loop indexes. */
81 int lvl, lat, lon, i = 0;
82
83 /* Error handling. */
84 int retval;
85
86 /* Create some pretend data. If this wasn't an example program, we
87 * would have some real data to write, for example, model
88 * output. */
89 for (lat = 0; lat < NLAT; lat++)
90 lats[lat] = START_LAT + 5.F*(float)lat;
91 for (lon = 0; lon < NLON; lon++)
92 lons[lon] = START_LON + 5.F*(float)lon;
93
94 for (lvl = 0; lvl < NLVL; lvl++)
95 for (lat = 0; lat < NLAT; lat++)
96 for (lon = 0; lon < NLON; lon++)
97 {
98 pres_out[lvl][lat][lon] = SAMPLE_PRESSURE + (float)i;
99 temp_out[lvl][lat][lon] = SAMPLE_TEMP + (float)i++;
100 }
101
102 /* Create the file. */
103 if ((retval = nc_create(FILE_NAME, NC_CLOBBER, &ncid)))
104 ERR(retval);
105
106 /* Define the dimensions. The record dimension is defined to have
107 * unlimited length - it can grow as needed. In this example it is
108 * the time dimension.*/
109 if ((retval = nc_def_dim(ncid, LVL_NAME, NLVL, &lvl_dimid)))
110 ERR(retval);
111 if ((retval = nc_def_dim(ncid, LAT_NAME, NLAT, &lat_dimid)))
112 ERR(retval);
113 if ((retval = nc_def_dim(ncid, LON_NAME, NLON, &lon_dimid)))
114 ERR(retval);
115 if ((retval = nc_def_dim(ncid, REC_NAME, NC_UNLIMITED, &rec_dimid)))
116 ERR(retval);
117
118 /* Define the coordinate variables. We will only define coordinate
119 variables for lat and lon. Ordinarily we would need to provide
120 an array of dimension IDs for each variable's dimensions, but
121 since coordinate variables only have one dimension, we can
122 simply provide the address of that dimension ID (&lat_dimid) and
123 similarly for (&lon_dimid). */
124 if ((retval = nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, &lat_dimid,
125 &lat_varid)))
126 ERR(retval);
127 if ((retval = nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, &lon_dimid,
128 &lon_varid)))
129 ERR(retval);
130
131 /* Assign units attributes to coordinate variables. */
132 if ((retval = nc_put_att_text(ncid, lat_varid, UNITS,
133 strlen(DEGREES_NORTH), DEGREES_NORTH)))
134 ERR(retval);
135 if ((retval = nc_put_att_text(ncid, lon_varid, UNITS,
136 strlen(DEGREES_EAST), DEGREES_EAST)))
137 ERR(retval);
138
139 /* The dimids array is used to pass the dimids of the dimensions of
140 the netCDF variables. Both of the netCDF variables we are
141 creating share the same four dimensions. In C, the
142 unlimited dimension must come first on the list of dimids. */
143 dimids[0] = rec_dimid;
144 dimids[1] = lvl_dimid;
145 dimids[2] = lat_dimid;
146 dimids[3] = lon_dimid;
147
148 /* Define the netCDF variables for the pressure and temperature
149 * data. */
150 if ((retval = nc_def_var(ncid, PRES_NAME, NC_FLOAT, NDIMS,
151 dimids, &pres_varid)))
152 ERR(retval);
153 if ((retval = nc_def_var(ncid, TEMP_NAME, NC_FLOAT, NDIMS,
154 dimids, &temp_varid)))
155 ERR(retval);
156
157 /* Assign units attributes to the netCDF variables. */
158 if ((retval = nc_put_att_text(ncid, pres_varid, UNITS,
159 strlen(PRES_UNITS), PRES_UNITS)))
160 ERR(retval);
161 if ((retval = nc_put_att_text(ncid, temp_varid, UNITS,
162 strlen(TEMP_UNITS), TEMP_UNITS)))
163 ERR(retval);
164
165 /* End define mode. */
166 if ((retval = nc_enddef(ncid)))
167 ERR(retval);
168
169 /* Write the coordinate variable data. This will put the latitudes
170 and longitudes of our data grid into the netCDF file. */
171 if ((retval = nc_put_var_float(ncid, lat_varid, &lats[0])))
172 ERR(retval);
173 if ((retval = nc_put_var_float(ncid, lon_varid, &lons[0])))
174 ERR(retval);
175
176 /* These settings tell netcdf to write one timestep of data. (The
177 setting of start[0] inside the loop below tells netCDF which
178 timestep to write.) */
179 count[0] = 1;
180 count[1] = NLVL;
181 count[2] = NLAT;
182 count[3] = NLON;
183 start[1] = 0;
184 start[2] = 0;
185 start[3] = 0;
186
187 /* Write the pretend data. This will write our surface pressure and
188 surface temperature data. The arrays only hold one timestep worth
189 of data. We will just rewrite the same data for each timestep. In
190 a real application, the data would change between timesteps. */
191 for (size_t rec = 0; rec < NREC; rec++)
192 {
193 start[0] = rec;
194 if ((retval = nc_put_vara_float(ncid, pres_varid, start, count,
195 &pres_out[0][0][0])))
196 ERR(retval);
197 if ((retval = nc_put_vara_float(ncid, temp_varid, start, count,
198 &temp_out[0][0][0])))
199 ERR(retval);
200 }
201
202 /* Close the file. */
203 if ((retval = nc_close(ncid)))
204 ERR(retval);
205
206 printf("*** SUCCESS writing example file %s!\n", FILE_NAME);
207 return 0;
208}
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:1300
EXTERNL int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
Definition dfile.c:398
EXTERNL int nc_enddef(int ncid)
Leave define mode.
Definition dfile.c:1027
EXTERNL int nc_def_dim(int ncid, const char *name, size_t len, int *idp)
Define a new dimension.
Definition ddim.c:121
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_UNLIMITED
Size argument to nc_def_dim() for an unlimited dimension.
Definition netcdf.h:261
#define NC_CLOBBER
Destroy existing file.
Definition netcdf.h:138
#define NC_FLOAT
single precision floating point number
Definition netcdf.h:40