1 | |
---|
2 | |
---|
3 | README for grib2nc4 v1.0 |
---|
4 | |
---|
5 | Contact: Don Morton, don.morton@borealscicomp.com |
---|
6 | Delia Arnold, deliona.arnold@gmail.com |
---|
7 | M. Harustak |
---|
8 | |
---|
9 | Last Update: 29 May 2016 |
---|
10 | |
---|
11 | ====================================================================== |
---|
12 | 1. Introduction |
---|
13 | ====================================================================== |
---|
14 | |
---|
15 | grib2nc4 comes from a request by users to make FLEXPART-preprocessed met data |
---|
16 | available in an easy-to-access way. In short, it uses preprocessing routines |
---|
17 | already developed for FLEXPART to open an ECMWF or NCEP met file and perform |
---|
18 | all the operations that FLEXPART normally does in order to prepare the met |
---|
19 | data for computations. It then takes the data which has been stored in |
---|
20 | FLEXPART global arrays and selectively writes it to a NetCDF4 file. |
---|
21 | |
---|
22 | This distribution is integrated into the FLEXPART source code, in a grib2nc4 |
---|
23 | subdirectory, but it doesn't necessarily have to reside there. The |
---|
24 | FLEXPART_SRC variable in the Makefile allows for an alternate FP source code |
---|
25 | location. The FLEXPART source code used by grib2nc4 must be FPv9.3, developed |
---|
26 | through CTBTO funding. FPv9.3 contains new routines that support the |
---|
27 | preprocessing of met data files - this capability does not exist in earlier |
---|
28 | versions. grib2nc4 is also dependent on the Vtable processing requirements |
---|
29 | of FPv9.3. |
---|
30 | |
---|
31 | grib2nc4 relies heavily on grib-api and NetCDF4 libraries, which have their |
---|
32 | own dependencies. Under the assumption that the libraries are installed |
---|
33 | correctly, the grib2nc4 binary can be produced by specifying the location |
---|
34 | of these libraries at the top of the Makefile and then making. |
---|
35 | |
---|
36 | A special "make test" option is available for an initial sanity check and |
---|
37 | to aid with future debugging, development and testing activities. Under |
---|
38 | this scenario, additional routines in the executable will be available, and |
---|
39 | they will be used to read in a small sample ECMWF GRIB file, preprocess it, |
---|
40 | write it to NC4 file, then read it back and compare with the preprocessed |
---|
41 | data still in the FLEXPART arrays. It does not test whether preprocessing |
---|
42 | is good, but only whether data was stored correctly in the NC4 files. |
---|
43 | |
---|
44 | ====================================================================== |
---|
45 | 2. Quick-Start |
---|
46 | ====================================================================== |
---|
47 | |
---|
48 | This section assumes that all library dependencies have been resolved, |
---|
49 | and someone wants to simply compile and run. If you are not this fortunate, |
---|
50 | you should go to the next section, Installation, then come back here to run. |
---|
51 | |
---|
52 | To compile, it should suffice to insure that the following Makefile variables |
---|
53 | are set correctly |
---|
54 | |
---|
55 | FLEXPART_SRC = .. |
---|
56 | |
---|
57 | GRIBAPI = /opt/grib-api |
---|
58 | NETCDFF = /opt/netcdf-fortran-4.4.3 |
---|
59 | NETCDF = /opt/netcdf-c-4.4.0 |
---|
60 | |
---|
61 | If you are compiling in the grib2nc4 subdirectory of the FLEXPART source code |
---|
62 | distribution, then there should be no need to change FLEXPART_SRC. |
---|
63 | |
---|
64 | Simply type "make" (noting that you may see some warnings related to |
---|
65 | variables for nests) to produce grib2nc4. |
---|
66 | |
---|
67 | Before trying to run, you might want to try "make test" to make sure that |
---|
68 | the simple test works as expected. |
---|
69 | |
---|
70 | grib2nc4 relies on Vtables to map GRIB variables to FLEXPART variables. |
---|
71 | Vtables for ECMWF and NCEP GRIB1 and GRIB2 data are availaible in the |
---|
72 | FLEXPART Vtables subdirectory. The Vtable needs to be present in your |
---|
73 | working directory. If you are not sure which one to use, you can simply |
---|
74 | copy in all of them from the FLEXPART Vtables subdirectory. |
---|
75 | |
---|
76 | Usage is simple - grib2nc4 requires two arguments - a path to the |
---|
77 | GRIB met file and a path to the NetCDF4 file to be created. |
---|
78 | |
---|
79 | WARNING - there is currently nothing to protect you if you get these out |
---|
80 | of order. It is possible for you to overwrite your met file if you use it |
---|
81 | as the second argument. |
---|
82 | |
---|
83 | Sample usage: |
---|
84 | |
---|
85 | ./grib2nc4 GD15051200 def9_nc1p0.nc4 |
---|
86 | |
---|
87 | By default, grib2nc4 will write the 3d u, v and t fields, as well as the |
---|
88 | terrain-following heights of the levels and geographic information. |
---|
89 | |
---|
90 | It is possible to write two more option variables, w and q, simply by adding |
---|
91 | them to the command. For example: |
---|
92 | |
---|
93 | ./grib2nc4 GD15051200 def9_nc1p0.nc4 q w |
---|
94 | |
---|
95 | ====================================================================== |
---|
96 | 3. Installation |
---|
97 | ====================================================================== |
---|
98 | |
---|
99 | Under the assumption that a satisfactory set of GRIB-API, HDF5, and NetCDF libs |
---|
100 | are available, as well as compatible FLEXPART source code, users should be able |
---|
101 | to define these locations in the Makefile and type "make" |
---|
102 | |
---|
103 | FLEXPART_SRC = .. |
---|
104 | GRIBAPI = /opt/grib-api |
---|
105 | NETCDFF = /opt/netcdf-fortran-4.4.3 |
---|
106 | NETCDF = /opt/netcdf-c-4.4.0 |
---|
107 | |
---|
108 | GRIBAPI installation is defined in other places. Because the installation of |
---|
109 | HDF5 and NETCDF can be confusing, a set of installation notes is presented |
---|
110 | here. They have worked for me on two different machines, and take some |
---|
111 | time to complete. Further, at this point in time they produce only dynamic |
---|
112 | libs, but this will hopefully change in the near future. |
---|
113 | |
---|
114 | Compression capabilities of NetCDF4 depend on HDF5, so that needs to be |
---|
115 | installed first. All examples are presented with a fictitious MYDIR directory, |
---|
116 | which may be in a user's directory if needed. |
---|
117 | |
---|
118 | mkdir MYDIR/usr |
---|
119 | |
---|
120 | (This may be different by the time you try) |
---|
121 | wget http://www.hdfgroup.org/ftp/HDF5/current/src/hdf5-1.8.16.tar.gz |
---|
122 | |
---|
123 | ./configure --prefix=MYDIR/usr/local/hdf5-1.8.16 \ |
---|
124 | --enable-fortran --enable-cxx |
---|
125 | make |
---|
126 | make check |
---|
127 | make install |
---|
128 | make check-install |
---|
129 | |
---|
130 | |
---|
131 | Then, NetCDF needs to be installed by first installing the C libs, then the |
---|
132 | Fortran libs |
---|
133 | |
---|
134 | wget https://github.com/Unidata/netcdf-c/archive/v4.4.0.tar.gz |
---|
135 | |
---|
136 | CPPFLAGS=-IMYDIR/usr/local/hdf5-1.8.16/include \ |
---|
137 | LDFLAGS=-LMYDIR/usr/local/hdf5-1.8.16/lib \ |
---|
138 | ./configure --prefix=MYDIR/usr/local/netcdf-c-4.4.0 |
---|
139 | |
---|
140 | make |
---|
141 | make check |
---|
142 | make install |
---|
143 | |
---|
144 | Then, for the Fortran libs |
---|
145 | |
---|
146 | wget https://github.com/Unidata/netcdf-fortran/archive/v4.4.3.tar.gz |
---|
147 | |
---|
148 | CPPFLAGS=-IMYDIR/usr/local/netcdf-c-4.4.0/include \ |
---|
149 | LDFLAGS=-LMYDIR/usr/local/netcdf-c-4.4.0/lib \ |
---|
150 | LD_LIBRARY_PATH=MYDIR/usr/local/netcdf-c-4.4.0/lib \ |
---|
151 | ./configure --prefix=MYDIR/usr/local/netcdf-fortran-4.4.3 |
---|
152 | |
---|
153 | make |
---|
154 | make check |
---|
155 | make install |
---|
156 | |
---|
157 | Good luck!! For your convenience, I am providing you with a Fortran |
---|
158 | program I created to test my installation of the libs. It may be |
---|
159 | overkill, but if you're having a problem compiling grib2nc4, you might |
---|
160 | want to back up and make sure that your libs are providing the core |
---|
161 | functionality needed by grib2nc4. |
---|
162 | |
---|
163 | This Fortran 90 test program generates its own data, writes it (compressed) |
---|
164 | to a NetCDF4 file, then opens the file for reading and reads the data back |
---|
165 | in. |
---|
166 | |
---|
167 | !!!!!!!!!!!!!!!!!! |
---|
168 | program simp1 |
---|
169 | |
---|
170 | !! Simple program to test system capabilities for writing/reading |
---|
171 | !! NetCDF-4 files. |
---|
172 | |
---|
173 | use netcdf |
---|
174 | |
---|
175 | character (len=*), parameter :: FILE_NAME="gen1.nc" |
---|
176 | integer, parameter :: NX=720, NY=360, NZ=200 |
---|
177 | integer, parameter :: DEFLATE_LEVEL = 2 |
---|
178 | |
---|
179 | double precision, dimension(NX, NY, NZ) :: U |
---|
180 | |
---|
181 | integer :: i, j, k |
---|
182 | integer :: ncid, retval |
---|
183 | integer :: x_dimid, y_dimid, z_dimid, dimids(3) |
---|
184 | integer :: u_varid |
---|
185 | |
---|
186 | ! Fill with arbitrary values |
---|
187 | do j=1,NY |
---|
188 | do i=1,NX |
---|
189 | do k=1,NZ |
---|
190 | U(i,j,k) = DBLE(i+j+k) |
---|
191 | enddo |
---|
192 | enddo |
---|
193 | enddo |
---|
194 | |
---|
195 | !print *, U |
---|
196 | |
---|
197 | print *, "Creating nc file for writing" |
---|
198 | !retval = nf90_create(FILE_NAME, NF90_CLOBBER, ncid) |
---|
199 | retval = nf90_create(FILE_NAME, OR(NF90_CLOBBER, NF90_HDF5), ncid) |
---|
200 | print *, 'Created file: ', retval |
---|
201 | |
---|
202 | !--------- Define the metadata |
---|
203 | ! Define the dimensions, and get dimension ids passed back |
---|
204 | retval = nf90_def_dim(ncid, "x", NX, x_dimid) |
---|
205 | retval = nf90_def_dim(ncid, "y", NY, y_dimid) |
---|
206 | retval = nf90_def_dim(ncid, "z", NZ, z_dimid) |
---|
207 | dimids = (/ x_dimid, y_dimid, z_dimid /) |
---|
208 | |
---|
209 | ! Define U metadata and save varids |
---|
210 | retval = nf90_def_var(ncid, "U", NF90_DOUBLE, dimids, u_varid) |
---|
211 | print *, "Defined U: ", retval |
---|
212 | ! Set deflate for each variable |
---|
213 | retval = nf90_def_var_deflate(ncid, u_varid, & |
---|
214 | & shuffle=0, & |
---|
215 | & deflate=1, & |
---|
216 | & deflate_level=DEFLATE_LEVEL) |
---|
217 | |
---|
218 | retval = nf90_enddef(ncid) |
---|
219 | print *, "Ended metadata definitions: ", retval |
---|
220 | |
---|
221 | ! Write the data arrays |
---|
222 | retval = nf90_put_var(ncid, u_varid, U) |
---|
223 | print *, "SUM(U): ", sum(U) |
---|
224 | print *, "Wrote U: ", retval |
---|
225 | print *, trim(nf90_strerror(retval)) |
---|
226 | |
---|
227 | print *, "Closing nc file" |
---|
228 | retval = nf90_close(ncid) |
---|
229 | |
---|
230 | !!!!!!!!!!!!!! Reading !!!!!!!!!!!!!!!!!!!! |
---|
231 | print *, "Opening nc file for reading" |
---|
232 | retval = nf90_open(FILE_NAME, NF90_NOWRITE, ncid) |
---|
233 | |
---|
234 | ! Get the varid of each |
---|
235 | retval = nf90_inq_varid(ncid, 'U', u_varid) |
---|
236 | |
---|
237 | ! Read each one |
---|
238 | retval = nf90_get_var(ncid, u_varid, U) |
---|
239 | |
---|
240 | print *, "SUM(U): ", sum(U) |
---|
241 | |
---|
242 | print *, "Closing nc file" |
---|
243 | retval = nf90_close(ncid) |
---|
244 | end program simp1 |
---|
245 | !!!!!!!!!!!!!!!!!! |
---|
246 | |
---|
247 | and, this is the Makefile, again using the fictitious MYDIR location of libs |
---|
248 | |
---|
249 | ########################################### |
---|
250 | FC=gfortran |
---|
251 | |
---|
252 | BINARY=simp1 |
---|
253 | |
---|
254 | ROOT=MYDIR |
---|
255 | INCLUDE = -I${ROOT}/netcdf-fortran-4.4.3/include |
---|
256 | |
---|
257 | FFLAGS = |
---|
258 | LDFLAGS = |
---|
259 | LIB=-L${ROOT}/netcdf-fortran-4.4.3/lib -lnetcdff -L${ROOT}/netcdf-c-4.4.0/lib -lnetcdf -lnetcdf |
---|
260 | |
---|
261 | all : ${BINARY} |
---|
262 | |
---|
263 | ${BINARY} : ${BINARY}.o |
---|
264 | ${FC} -o ${BINARY} ${LDFLAGS} ${BINARY}.o ${LIB} |
---|
265 | |
---|
266 | ${BINARY}.o : ${BINARY}.f90 makefile |
---|
267 | ${FC} -c ${FFLAGS} ${INCLUDE} ${BINARY}.f90 |
---|
268 | ########################################### |
---|
269 | |
---|
270 | |
---|
271 | This is set up to run with shared libs. I don't particularly like this, but |
---|
272 | creating static libs for HDF5 and NetCDF4 combinations is, apparently, |
---|
273 | discouraged by some, and I haven't had the time yet to explore all of this. |
---|
274 | So, in order to run this sample program (as well as grib2nc4), it's necessary |
---|
275 | to insure the libs are accessible, as follows |
---|
276 | |
---|
277 | export LD_LIBRARY_PATH='MYDIR/usr/local/netcdf-fortran-4.4.3/lib:MYDIR/usr/local/netcdf-c-4.4.0/lib' |
---|
278 | |
---|
279 | ====================================================================== |
---|
280 | 4. Performance / To-Do |
---|
281 | ====================================================================== |
---|
282 | |
---|
283 | In general, the code is mature, but could be modified based on user |
---|
284 | requests. However, the compression isn't as much as I had hoped for. |
---|
285 | In fact, it kind of stinks. But, I think that's the price we pay for using |
---|
286 | NetCDF as storage. |
---|
287 | |
---|
288 | Here are some examples. DEFLATE 0 is no compression, DEFLATE 2 is considered |
---|
289 | by some to be a good balance of time and compression, and DEFLATE 9 is |
---|
290 | maximum compression. In these cases, we are only stored u, v and t (plus |
---|
291 | some small, miscellaneous stuff) |
---|
292 | |
---|
293 | --------------------------------------------------- |
---|
294 | ECMWF 1.0deg NCEP 1.0 degr ECMWF 0.5 deg |
---|
295 | --------------------------------------------------- |
---|
296 | Orig GRIB Mbytes 112 19 553 |
---|
297 | ---------------- --------------------------------------------------- |
---|
298 | DEFLATE 2 |
---|
299 | Time 3 min 18 sec 3 min |
---|
300 | Mbytes 112 20 739 |
---|
301 | ---------------- --------------------------------------------------- |
---|
302 | DEFLATE 9 |
---|
303 | Time 9 min 75 sec 15 min |
---|
304 | Mbytes 106 19 415 |
---|
305 | ---------------- --------------------------------------------------- |
---|
306 | |
---|
307 | So, primary to-do items are |
---|
308 | |
---|
309 | 1) Build a simple interface for putting this out in a pure binary form and |
---|
310 | assess its performance. Keep in mind, however, that accessing subsets of |
---|
311 | data from NetCDF4 would be much simpler than with binary and, in fact, possibly |
---|
312 | more efficient. If people are OK with the time for compression and file sizes, |
---|
313 | then it may not make sense to change this. |
---|
314 | |
---|
315 | 2) Understand better how to make grib2nc4 static binaries that won't rely on |
---|
316 | local NetCDF, HDF5 and GRIB-API libraries |
---|
317 | |
---|
318 | |
---|