**Introduction****Spectral coefficients ->****Regular latitude-longitude grids ->****Regular Gaussian grids ->****Reduced Gaussian grids ->****Generic ->****Diagnostics of ECMWF EMOSLIB error codes****Decoding GRIB records to get real field data****Makefile for Fortran 77 programs for performing ECMWF EMOSLIB standard transformations****Gaussian latitudes, weights, and points****Fixed regular latitude-longitude grids other than 2.5°****Download tarfile****Outstanding ECMWF software issues****References**

**spectral coefficients**(spherical harmonics) to:*spectral coefficients*,*rotated spectral coefficients*,*regular latitude-longitude grids*,*regular Gaussian grids*, and*reduced Gaussian grids*^{2}**regular latitude-longitude grids**to:*regular latitude-longitude grids*and*regular Gaussian grids***regular Gaussian grids**to:*regular Gaussian grids*and*regular latitude-longitude grids***reduced Gaussian grids**to:*regular latitude-longitude grids*and*regular Gaussian grids*

In the code examples, input GRIB
(GRIdded Binary) records are assumed, and the gridded output data are also encoded
in GRIB. A typical processing sequence begins with opening an input GRIB file with
pboben
which returns a unique integer identifier for the input file that is subsequently used for the rest of
the program. Similarly, an output GRIB file is opened and associated with its own unique integer
identifier. The GRIB records of the input file are read sequentially, one record at a time, with
pbgrib, which
packs the GRIB record, still encoded in GRIB, into an integer array. It is the integer array
returned by "pbgrib" that contains the bulk of the data and metadata necessary to
the proper functioning of the interpolation routines. The remaining metadata is generated by
invoking intout
with sets of parameters describing the desired output grid. Once "intout" has been called,
all the necessary preparations have been made to perform the transformation using
intf^{3}.
The subroutine "intf" evaluates all available metadata, and generates output data encoded
in GRIB which may be written to the output file using
pbwrite.
The input and output GRIB files are closed with
pbclose
after all records have been processed.

For the following programs, we have assumed a series of various input GRIB files containing 500 hPa temperature
at 6-hourly resolution spanning September 1957, hence 120 GRIB records. The output is also in GRIB. In addition,
generic 1 megabyte^{4} integer and real arrays are declared to handle all GRIB
input, processing, and output. The actual number of bytes that are read, processed, to be written, and
so on are signaled by integer counts returned and/or utilized by the EMOSLIB routines. We have found that
1 megabyte arrays are more than sufficient to handle all ERA-40 GRIB records, and alleviates potential
difficulties if the arrays are declared with insufficient lengths. Finally, the EMOSLIB library must
be installed on your system.

^{3}If one starts with spectral vorticity and divergence, and the desired output
is U and V (eastward and northward wind components), then
intuvp
is used instead of "intf".

^{4}1 megabyte, i.e., a length of 262,144 4-byte words

- Spectral coefficients -> spectral coefficients: prog_sphhar_trsphh.f
- Spectral coefficients -> regular latitude-longitude grids: prog_sphhar_2p5reg.f
- Spectral coefficients -> regular Gaussian grids: prog_sphhar_regn80.f
- Spectral coefficients -> reduced Gaussian grids: prog_sphhar_redn80.f

- Spectral vorticity and divergence -> regular latitude-longitude U and V: prog_sphvod_uv_2p5reg.f
- Spectral vorticity and divergence -> regular Gaussian U and V: prog_sphvod_uv_regn80.f
- Spectral vorticity and divergence -> reduced Gaussian U and V: prog_sphvod_uv_redn80.f

**Important Notes:**

As stated previously, we have found that EMOSLIB generates slightly erroneous U and V (eastward and northward wind components, necessarily a vector pair) starting from spectral vorticity and divergence.

In addition, according to the ERA-40 Archive Plan (2002, see "References" below),

"Basic T159 spherical-harmonic fields will be truncated to T63 before the 2.5° grid values are computed."To ensure this is achieved, we use "prog_sphhar_trsphh.f" to truncate spectral coefficients from T159 to T63, then "prog_sphhar_2p5reg.f" to transform truncated spectral coefficients to 2.5° grid values for scalars, or "prog_sphvod_uv_2p5reg.f" to transform truncated spectral vorticity and divergence to 2.5° grid values for U and V.

Please see the section "**Outstanding ECMWF software issues**" below for further details.

- 2.5° regular latitude-longitude grids -> fixed regular latitude-longitude grids: prog_2p5reg_fixreg.f
- 2.5° regular latitude-longitude grids -> regular Gaussian grids: prog_2p5reg_reggau.f

- Regular N80 Gaussian grids -> regular Gaussian grids: prog_regn80_reggau.f
- Regular N80 Gaussian grids -> 2.5° regular latitude-longitude grids: prog_regn80_2p5reg.f

- Reduced N80 Gaussian grids -> 2.5° regular latitude-longitude grids: prog_redn80_2p5reg.f
- Reduced N80 Gaussian grids -> regular N80 Gaussian grids: prog_redn80_regn80.f

We provide three programs for generating 2.5° regular latitude-longitude grids, regular N80 Gaussian grids, or reduced N80 Gaussian grids, from generic input GRIB records.

- Generic -> 2.5° regular latitude-longitude grids: prog_generic_2p5reg.f
- Generic -> regular N80 Gaussian grids: prog_generic_regn80.f
- Generic -> reduced N80 Gaussian grids: prog_generic_redn80.f

Thus far, "check_error_status" handles any errors returned by the EMOSLIB routines "pbopen", "pbwrite", "pbclose", "pbgrib", "intf", "intuvp", "intin", and "intout".

- Diagnosing error codes: subr_check_error_status.f

- Example program: prog_get_field_data_2p5reg.f
- Invokes (dependency):
- Subroutine to decode GRIB records to get real field data: subr_get_field_data.f

integer length_array integer nlon integer nlat c parameter(length_array=262144) parameter(nlon=73) parameter(nlon=144) c integer iarray_in(length_array) integer iarray_out(length_array) integer rarray_in(length_array) integer rarray_out(length_array) c real latlon_array(nlat,nlon) c integer intout, intf external intout, intf c integer ierror integer words_read_into_iarray_out integer ilat integer jlon integer k integer ival(80) real rval(80) c c ... c ierror = intout( 'form', ival, rval, 'unpacked' ) call check_error_status('intout',ierror) ierror = intf( iarray_in, length_array, rarray_in + iarray_out, words_read_into_iarray_out, rarray_out ) call check_error_status('intf', ierror) k = 0 do 200 ilat = 1, nlat do 300 jlon = 1, nlon k = k + 1 latlon_array(ilat,jlon) = rarray_out(k) 300 continue 200 continueSimilarly, the same technique can be applied to the real arrays returned by "intuvp".

Note also that the dependency "subr_check_error_status.f" is required for checking the status of error codes returned by EMOSLIB routines. See above.

In the makefile notice that we have used the Portland Group Fortran 90 compiler (pgf90) and have linked the EMOS library available in /usr/local/emos-240/lib. Please modify these to identify the compiler and EMOSLIB library path that you are using. (The best practice in the case of EMOSLIB is to use the same compiler that was used to build the EMOSLIB library on your machine.)

*Please note that if you cut and paste the makefile, then a tab must be inserted at the beginning
of each command line*, that is, prior to each instance of "${FORTRAN_COMPILER} ...".
This is a cardinal convention of all makefiles.

- makefile: makefile

integer ngau integer stp c parameter( ngau = 24 ) parameter( stp = 31 ) c integer intv(ngau) real realv(ngau) character*30 charv(ngau) c real lats(ngau) real area(4) c data lats / + 87.1591, 83.4789, 79.7770, 76.0702, 72.3616, 68.6520, + 64.9419, 61.2316, 57.5210, 53.8103, 50.0995, 46.3886, + 42.6776, 38.9666, 35.2556, 31.5445, 27.8334, 24.1223, + 20.4112, 16.7001, 12.9890, 9.2778, 5.5667, 1.8556 / c data area / 4*0.0 / c c ... c ierror = intout('area', intv, area, charv ) call check_error_status('intout', ierror) c ierror = intout('user_regular_gaussian', ngau, realv, charv ) call check_error_status('intout', ierror) c ierror = intout('g_lats', intv, lats, charv ) call check_error_status('intout', ierror) c ierror = intout('truncation', stp, realv, charv ) call check_error_status('intout', ierror)

- Gaussian latitudes, weights, and points: Gaussian latitudes, weights, and points

data grid / 2.5, 2.5 /may be changed to

data grid / 5.0, 5.0 /to generate a 37x72 5.0° regular latitude-longitude output grid. Some common fixed regular latitude-longitude grids are (and the conventions adhered to in ECMWF EMOSLIB output):

------------------------------------------------------------------------------------------------ latitude spacing longitude spacing latitudes longitudes first latitude first longitude ------------------------------------------------------------------------------------------------ 1.0° 1.0° 181 360 90°N 0°E 1.125° 1.125° 161 320 90°N 0°E 2.5° 2.5° 73 144 90°N 0°E 5.0° 5.0° 37 72 90°N 0°E ------------------------------------------------------------------------------------------------

- Download tarfile (shift-middle-click): era-40-std-transformations.tar

- The subroutine "intuvp" has been found to generate slightly erroneous U and V (necessarily a vector pair) starting from spectral vorticity and divergence. The errors are described and quantified in a separate DSS web document, "Diagnostics of ECMWF Interpolation Software and ERA-40 2.5° Scalar and Vector Fields". Users are encouraged to assess for themselves whether or not such errors play a significant role in their data processing and research.
- According to ECMWF on-line documentation,
("Transformations"),
"Spectral fields are automatically truncated before interpolation to grid fields to reduce data volumes and spurious 'aliased' values."

The ECMWF EMOSLIB default truncations are as follows:**Grid increment****Truncation**2.5 and greater T63 1.5 to 2.5 T106 0.6 to 1.5 T213 0.4 to 0.6 T319 0 to 0.4 T639 - The building and installation of EMOSLIB on a Linux system using g77
^{5}and ECMWF source code and makefiles has proven problematical due to the use of a "POINTER" intrinsic by ECMWF that is an extension to the Fortran 77 and 90 standards. The "POINTER" extension is supported by most commercial vendors^{6},*but not by g77*. Our experience with installing EMOSLIB on a Linux system^{7}underscores the precondition of having a Fortran compiler, capable of supporting the "POINTER" extension, available on the system. The Portland Group Fortran 90 compiler for Linux has been used by the DSS in this capacity, as well as to compile and test the source code described in the present web document.

^{6}See for example the Sun Fortran 77 Language Reference.

^{7}Specifically, a Dell Precision 360 with Pentium IV processor running Red Hat Enterprise Linux WS Version 3.