National Weather Service United States Department of Commerce

The MDL website has been migrated to the NOAA Virtual Lab (VLab). This page can now be found at: Your browser will automatically be redirected to this page in 15 seconds. Please update any bookmarks that you might have.


Standard Hydrological Exchange Format (SHEF)

This information does not come from MDL. The following originated from a website of the National Weather Service Office of Climate, Water, and Weather Services: Hydrologic Services Division. ( )


SHEF Software Instructions

Download Source Code

Download source code (.gz)


How to install the software


          File Structure for the Shefpars Code Transfer (Linux)

A compressed tar file "ShefCode_tar.gz" is used to transfer the
shefpars code, test programs, and data.  Download this file and
uncompress it using the gunzip utility; then untar the file as follows:

      tar  -xvf  ShefCode_tar
      rm  ShefCode_tar

Seven directories and three text files are created as follows:

      README_shef_general .. readme text file with general information
      README_shef_install .. readme text file for installing the
      README_shef_updates... readme text file describing updates		     
      shef_src ............. directory for all parsing subroutines
      shef_sheftest ........ directory for test mainline
      shef_data ............ directory for SHEFPARM file and example
      shef_lib ............. directory for parsing subroutines
                             archive library
      shef_scripts ......... directory for scripts to make makefiles
      shef_workspace ....... directory for running the test shefpars
      shef_shefit .......... directory for source to make program

All that is required to make a program using the shefpars decoder
is the source modules in directory "shef_src", and one data file
"SHEFPARM" in directory "shef_data".  Subroutine "shdriv" is the
driver for the parser.  The rest of the files are for support of
compiling and testing the parser.

A test program "shmain" and its called display routine "shpout" in
directory "shef_sheftest" can be used as an example of how to run the
shefpars decoder; or as an example of how to create a user developed
program calling routine "shdriv".  Its function is to open the input
message file and the "SHEFPARM" file, create and open the output
files, run the decoder, and display the results with a decoded text
file and a status/error file.

    Four scripts are included in directory "shef_scripts":

      make_lib_makefile ...... creates a makefile in directory
                               "shef_src" that will compile and make
                               an archived library for the shef
                               decoder.  The library is placed in
                               directory "shef_lib".

      make_sheftest_makefile . creates a makefile in directory
                               "shef_sheftest" that will compile the
                               "test" source modules and create an
                               executable called "shefpars" in
                               directory "shef_sheftest".

      make_shefit_makefile ... creates a makefile in directory
                               "shef_shefit" that will compile the
                               "shefit" source modules and create an
                               executable called "shefit" in
                               directory "shef_shefit".

      run_sheftest ........... makes a test run using the created
                               "sheftest" executable and test data
                               from directory "shef_data".  The
                               input data "shefin1", file "SHEFPARM",
                               and all the output files are placed
                               in directory "shef_workspace".

Note, the makefiles are created to work on our LINUX platform.  They
are about as generic as can be.  A "sed" function in the scripts that
make the makefiles attempts to create the needed environment.  Of
course, once the makefiles are created, they can be manually adjusted
to suit the user's needs before they are run.

The example test program "shefpars" requires one input line on the
standard input unit which contains the filename (128 char max) of
the input shef message to be decoded.  Also required is the shefpars
resource file "SHEFPARM" in the same directory where the test
program is run.  Three output files are created in the current
      shefout .... a binary output file for the edited input shef
      display .... a text file that displays the data in the binary
                   file (subroutine "shpout" creates this file)
      error ...... a status file with messages and errors (if any)
The following ksh script can be used independently to run "sheftest":
      [[ -f ./SHEFPARM ]] || exit 1
      [[ -f $Input ]] || exit 1
      sheftest << EoF 2 > log

The following example output files are given with this program in
directory "shef_data":

      shefin1 .... a long example of shef input messages including
                   messages with errors
      SHEFdis .... the output from the "shpout" subroutine that
                   displays in text mode what the resulting "shefout"
                   file would contain
      SHEFerr .... the shef error messages from the given input file
                   (including a list of all input)

They can be compared with the output from the test run; but note that
some of the output dates are determined by when the program is run
since defaults to the current month or year are involved.

About program "shefit"; it is made using source code in directories
"./shef_shefit" and "./shef_src".  It is a filter version of the
shefpars program (output is ascii text).  For instructions on its
use, run the command "shefit -help" after making the program.

          Summary of Commands to Download and Run Shefpars

 1) Create a directory to contain the shefpars code (need about
    2 MB):

                cd  < parent-dir >
                mkdir  shefpars
                cd  shefpars

 2) Download the compressed tar file for the shefpars code
    (i.e. after ftp):

                cp  ShefCode_tar.gz  .

 3) Uncompress and untar to create a file structure:

                gunzip  ShefCode_tar.gz
                tar  -xvf  ShefCode_tar
                rm  ShefCode_tar

 4) Source code for the shefpars driver is in directory "shef_src".
    Now run some scripts to make makefiles; then run the makefiles
    to create a program; and finally run a script to test the

    Special Note1:  The "FFLAGS" and "CFLAGS" variables in the
                    makefiles are created below will probably need
                    editing for the local compilers.

                cd  ./shef_scripts

                cd  ../shef_src
                  < may need to edit file "Makefile" for compiler
                    options >
                  < may need to edit "shcurd.c" for underscore >
                make  -f  Makefile
                cd  ../shef_sheftest
                  < may need to edit file "Makefile" for compiler
                    options >
                make  -f  Makefile

                cd  ../shef_scripts

    Special Note2:  Source module "shcurd.c" may not compile with
                    some "Fortran-call-c" compilers ... so it may
                    be necessary to put a underscore "_" after the
                    name "shcurd" in the module "shcurd.c and
                    recompile it.

                 may need to change line:
                       void shcurd(int *yr,int *mo,int *da
                       void shcurd_(int *yr,int *mo,int *da)
                 in routine "shcurd.c" and rerun the makefile.

 5) The output can be compared to the expected output in directory
    "shef_data" but note that some dates may differ because missing
    dates will default to a current date (later that when the
    example output was made):

                cd  ../shef_workspace
                diff  display  ../shef_data/SHEFdis
                diff  error  ../shef_data/SHEFerr

 6) Source code for the shefpars filter program "shefit" is in
    directory "shef_shefit".  It also uses the shefpars driver code.
    Run the following to make "shefit":

    Special Note3:  Source module "get_apps_defaults.c" may need a
                    underscore "_" at the end of the routine name
                    similar to module "shcurd.c" in Special Note2
                    above for some compilers.  For one compiler, two
                    underscores were needed; example:
                       "int get_apps_defaults__(..."

                cd  ../shef_scripts

                cd  ../shef_shefit
                  < may need to edit file "Makefile" for compiler
                    options >
                  < may need to edit "get_apps_defaults.c" for
                    underscore >
                make  -f  Makefile
                shefit -help

Date:   01 April 2008


How to use the software



Standard Hydrologic Exchange Format (SHEF) was developed as a
prerequisite for automated hydrologic data exchange.  This paper
describes how to use the software to parse shef messages and output
them to the desired database system.

                         TABLE OF CONTENTS

    1.  Introduction
    2.  Parsing and Posting
    3.  The Output File, SHEFOUT
    4.  Using Shefpars Source Code
    5.  Error Handling
    6.  Source Module Information


    A.  Error Messages
    B.  Downloading Software


Standard Hydrologic Exchange Format (SHEF) (1) is the standard
format used by the National Weather Service for encoding
hydrologic data.  SHEF is sufficiently flexible to handle most
hydro-meteorological data and as a result, is used by many programs
within the National Weather Service (NWS) as well as elements of
other government and private agencies.

SHEF has been designed to allow for the automation of data
handling techniques at the same time as maintaining a format which
is visually readable.

NWS handbook "Standard Hydrologic Exchange Format" documents the
syntax for SHEF messages.  Documentation and source code are available
from the NWS Office of Hydrology web page:

The following describes how to use the parsing subroutines in a
program to decode SHEF messages; how to obtain the output data
values; and how to download the source code.


The process of taking data in SHEF and putting it in a database
can be described as a two step process; parsing and posting.  The
parsing step takes SHEF text messages and reduces them to a simplified,
machine readable format.  If a SHEF message contains several data
values, each is parsed into an separate output record ready for the
posting process.  The posting process takes the reduced data
and interacts with the target database in such a way that the data is
integrated into the database.

This conceptualization of the process allows software to be
developed for the parsing step which is essentially standard and is
not database specific thus allowing for a high degree of portability.
The software for the posting process is database specific and is not
presented here.

The software used by the National Weather Service reads SHEF
messages from a text file; passes each single decoded data value
and its attributes into an output subroutine, "shout", which writes
the value to a binary file with a set format that can be easily read
by a posting program.  All decoded values are passed to this one
subroutine, thus the form of the output from the shef parsing
routines can be changed by reprogramming this one subroutine.

Other files used by the parsing routines are a text resource file,
"SHEFPARM", and optionally one or two text output files to display
errors and a copy of the input messages.


This file is the "pipe" for passing the reduced data from the
parsing step to the posting step.  It is a Fortran sequential
unformatted file with each record being a self sufficient and complete
description of an item of data and its attributes.  All times on the
file have been converted to Universal Standard Time (i.e. GMT) and
all data is in English units as prescribed in SHEF.

Each record of the shefout file is written with the following
statement in subroutine, "shout":

     $        PARCOD(1:1),BLNK3,PARCOD(2:2),BLNK3,IDUR,
     $        PARCOD(4:4),BLNK3,PARCOD(5:5),BLNK3,PARCOD(6:6),BLNK3,
     $        CODP,VALU,IQUAL,BLNK3,
     $        QUO


    LUOUT ..... is the Fortran output file unit number
    BLNK3 ..... is three blank characters as CHARACTER*3
    BLNK4 ..... is four blank characters as CHARACTER*4

and data variables are:


    ID           CHARACTER*8    Station id
    IYR          INTEGER        Year of observation date (4 digits)
    IMO          INTEGER        Month of observation date
    IDA          INTEGER        Day of observation date
    IHR          INTEGER        Hour of observation date
    IMN          INTEGER        Minute of observation date
    ISE          INTEGER        Second of observation date
    KYR          INTEGER        Year of creation date (4 digits)
    KMO          INTEGER        Month of creation date
    KDA          INTEGER        Day of creation date
    KHR          INTEGER        Hour of creation date
    KMN          INTEGER        Minute of creation date
    KSE          INTEGER        Second of creation date
    PARCOD(1:1)  CHARACTER*1    First character of physical element
    PARCOD(2:2)  CHARACTER*1    Second character of physical element
    IDUR         INTEGER        Encoded duration code
    PARCOD(4:4)  CHARACTER*1    Type code
    PARCOD(5:5)  CHARACTER*1    Source code
    PARCOD(6:6)  CHARACTER*1    Extremum code
    CODP         REAL           Probability code
    VALU         DOUBLE PREC'N  Data value
    IQUAL        CHARACTER*1    Data qualifier
    IREV         INTEGER        Revision code (0=not a rev,1=rev)
    JID          CHARACTER*8    Data source
    ITIME        INTEGER        Time series indicator
                                (0=no ts,1=first elem,2=othr elem)
    PARCOD(1:8)  CHARACTER*8    Full parameter code
    QUO          CHARACTER*80   Internal comment (quote for data value)

Each output record contains 208 bytes; 128 bytes for the normal data
value variables and 80 bytes for the output internal comment or quote,
QUO.  The size of QUO is set in subroutine "shdcod" and can be changed
in that routine without any side effects in any other code.
For further description of the output variables check with the NWS
handbook, "Standard Hydrologic Exchange Format".


The parsing of SHEF messages is done by calling subroutine "shdriv".
The only arguments passed to "shdriv" are five Fortran unit numbers for
the input and output files used by the parser.  Only the first three
unit numbers are required, the last two output files are optional (a
"-1" will cause their output to be skipped).  Programs using the SHEF
parser routines assume the tasks of opening the files using Fortran
open statements, passing the unit numbers to "shdriv", and eventually
closing the files upon returning from "shdriv".  Inside "shdriv",
subroutine "shout" is eventually called which writes the decoded
data in binary format the the SHEFOUT file.  Subroutine "shout"
could be changed to accommodate the user's desired database system.

Following is a simplified example of how to use the shefpars routines
in a Fortran program (a C program would need to call a Fortran
subroutine to open the files and obtain Fortran unit numbers):


      OPEN (LUINP,FILE='shef_input_message',STATUS='OLD')

      OPEN (LUERR,FILE='shef_errors',STATUS='NEW')



where the following variables are needed for "shdriv":

    LUINP ... unit number of the text file to be decoded (the SHEF
              message "input" file),
    LUOUT ... unit number of the output binary file containing decoded
              data in a fixed format (the "shefout" file),
    LUPAR ... unit number of a text resource file containing shefpars
              decode parameters defining allowable codes (the
              "SHEFPARM" file),
    LUERR ... unit number of a file to contain error messages that may
              occur during the decoding,
    LUCPY ... unit number of a file to contain a copy of the input
              lines that are passed to the decoder.

Note that unit numbers LUERR and LUCPY can be set to -1 if those
output files are not needed, though it is recommended that the error
file should be used.  Also, if the output error file and display file
are to be combined into one file, just set LUCPY = LUERR instead of
opening a separate display file (as used in this example).  It is the
responsibility of the calling program to check that the input files
exist and that all files are opened correctly.

The currently used subroutine, "shout", outputs the decoded data to
the binary file ready for posting, using unit number LUOUT.  If the
user wants to look at the output, a new program or a subroutine would
be needed to read the binary file and display the data.

An alternate method of looking at the decoded message would be to
change subroutine "shout" to output the decoded data as text.  In this
case unit number LUOUT could be set to the standard output number for
Fortran, or it could be used to open a text output file if the write
statement in "shout" is modified to accompany it.

Subroutines shdura, shexcd, shfact, shmaxe, shpabg, shprob, shqual,
shsend, shtscd, and shyear each read the parameter file "SHEFPARM"
once each time the shef decode program is run; thus repetitively
executing the mainline to decode short messages will cause many reads
from the SHEFPARM file.  However, if the "shdriv" subroutine is
called many times from a continuously running mainline, the reading
of this resource file can be kept to a minimum.

The only other subroutine that reads data is "shline" in module shline.
It reads a single shef message line.  The following declaration line
in shline defines the length of an acceptable shef message line:

      CHARACTER*1004   LINE

The dimension is 4 more than the number of characters allowed in a 
single message line.  Thus "CHARACTER*124" for example would be used
for a maximum message line length of 120 characters.

There is one "C" routine that calls C library routines "time" and
"localtime".  It is named "shcurd" and is called in routine "shyear"
that gets the current date.


All errors or warnings encountered during parsing are sent to an error
file through subroutine "sherr".  Most errors stop parsing the current
message while warnings are likely to output something.  All error and
warning messages are contained in subroutine "sherrm" and are output
to the error file through that routine.  Two other subroutines send
text output to the error file;  1) "sherrs" can be used to output a
summary of the number of errors and warnings;  2) "shvern" can be
used to output the version number of the parsing routines.  A copy of
each shef input line can be output through subroutine "shline" to a
separate file or the error file.

There are no provisions for handling signal interruptions.


All but one routine, "shcurd", is written in standard Fortran 77.
The C routine is in standard ANSI C.  All the routines come from RCS
files and have RCS keyword statements in them for tracking purposes
only, and could give warnings alluding to unused variables or
statements that cannot be reached.  They have never given any runtime


This is a list of error and warning messages that comes directly
from subroutine "sherrm".

  002   Two digits are required in date or time group
  003   An expected parameter code is missing
  004   File read error while accessing data file
  005   No dot in column 1 when looking for new message
  006   Dot found but not in column 1 of new message
  007   Unknown message type, looking for .A, .B, or .E
  008   Bad char in message type format (or missing blank delimiter)
  009   Last message format was different from this continuation messg
  010   Last message was NOT a revision unlike this continuation messg
  011   Last message had an error so cannot continue
  012   No positional data or no blank before it
  013   Bad character in station id
  014   Station id has more than 8 characters
  015   Bad number in positional data date group
  016   Incorrect number in date group
  017   Incorrect number in time group
  018   Missing blank char in positional data
  019   Bad creation date
  020   Bad date code letter after the character "D"
  021   Unknown data qualifier, data value is lost
  022   Unknown data units code (need S or E)
  023   Unknown duration code
  024   Bad 2-digit number following duration code
  025   Unknown time interval code (need Y,M,D,H,N,S,E)
  026   Bad 2-digit number following time interval code
  027   Bad character after "DR" (relative date code)
  028   Bad 1- or 2-digit number in relative date code
  029   Bad character in parameter code
  030   Bad parameter code calls for send code
  031   Trace for code other than PP, PC, PY, SD, SF, SW
  032   Variable duration not defined
  033   Bad character where delimiter is expected
  034   Non-existent value for given type and source parameter code
  035   ZULU, DR, or DI has send code QY, PY, or HY
  036   Forecast data given without creation date
  037   No value given after parameter code and before slash or eol
  038   Explicit date for codes DRE or DIE is not the end-of-month
  039   Year not in good range (1753-2199)
  040   Exceeded limit of data items
  041   Too many data items for given .B format
  042   Not enough data items for given .B format
  043   Cannot adjust forecast date to Zulu time
  044   Time between 0201 & 0259 on day changing from stnd to daylight
  045   No time increment specified (use DI code)
  046   No ".END" message for previous ".B" format
  047   ID requires 3 to 8 characters
  048   For DST, check Apr/Mar or Oct/Nov for 1976 thru 2040 only
  049   Bad character in the message
  050   Missing parameter code
  051   Bad value chars (or missing delimiter), data may be lost
  052   Bad character in data field
  053   "?" not accepted for missing, use "M" or "+"
  054   Parameter code is too long or too short
  055   Missing delimiter between data type fields
  056   Missing delimiter after data type field
  057   Should use "/" after date, time, or other D-code; before data
  058   Parm codes PP and PC require decimal value
  059   Abort, cannot read "shefparm" file correctly
  060   Non-existent value for given duration parameter code
  061   Non-existent value for given extremum parameter code
  062   Non-existent value for given conversion factor parameter code
  063   Non-existent value for given probability parameter code
  064   Parameter code too short or field misinterpreted as param-code
  065   Comma not allowed in data field, data value is lost
  066   Date check for yr-mo-da shows bad date
  067   No data on line identified with a message type format
  068   An unexpected ".END" message was encountered
  069    BUMMER!!!  Maximum number of errors reached, abort message
  070   Cannot output to binary shefpars file
  071   Cannot access "PE conversion factors" from the "shefparm" file
  072   Cannot access "send codes" from the "shefparm" file
  073   Cannot access "duration codes" from the "shefparm" file
  074   Cannot access "type/source codes" from the "shefparm" file
  075   Cannot access "extremum codes" from the "shefparm" file
  076   Cannot access "probability codes" from the "shefparm" file
  077   Cannot read "SHEFPARM" file!!!!!
  078   Bad character in data value, data value is lost
  079   Julian day should be written with 3 digits
  080   Too many digits in date group!
  081   Too many characters in quotes
  082   Data line found before completing .B format line(s)
  083   Missing slash delimiter or bad time zone code
  084   Too many chars in qualifier code, data value is lost
  085   Bad data qualifier, rest of format is lost
  086   Retained comment found without a data value, comment is lost
  087   Unexpected slash found after parameter code, before data value
  088   Cannot access "qualifier codes" from the "shefparm" file
  090   Unknown error number given

Date:   14 July 2004