#!/usr/bin/ksh

export PS4=' + extrkr.sh line $LINENO: '

loopnum=$1
cmodel=$2
ymdh=$3
pert=$4
init_flag=$5

trkrtype=tracker

# USE_OPER_VITALS=NO
# USE_OPER_VITALS=INIT_ONLY
USE_OPER_VITALS=YES

set +x
##############################################################################
echo " "
echo "------------------------------------------------"
echo "xxxx - Track vortices in model GRIB output"
echo "------------------------------------------------"
echo "History: Mar 1998 - Marchok - First implementation of this new script."
echo "         Apr 1999 - Marchok - Modified to allow radii output file and"
echo "                              to allow reading of 4-digit years from"
echo "                              TC vitals file."
echo "         Oct 2000 - Marchok - Fixed bugs: (1) copygb target grid scanning mode"
echo "                              flag had an incorrect value of 64 (this prevented"
echo "                              NAM, NGM and ECMWF from being processed correctly);" 
echo "                              Set it to 0.  (2) ECMWF option was using the "
echo "                              incorrect input date (today's date instead of "
echo "                              yesterday's)."
echo "         Jan 2001 - Marchok - Hours now listed in script for each model and "
echo "                              passed into program.  Script included to process"
echo "                              GFDL & Ensemble data.  Call to DBN included to "
echo "                              pass data to OSO and the Navy.  Forecast length"
echo "                              extended to 5 days for GFS & MRF."
echo " "
echo "                    In the event of a crash, you can contact Tim "
echo "                    Marchok at GFDL at (609) 452-6534 or tpm@gfdl.gov"
echo " "
echo "Current time is: `date`"
echo " "
##############################################################################
set -x

##############################################################################
#
#    FLOW OF CONTROL
#
# 1. Define data directories and file names for the input model 
# 2. Process input starting date/cycle information
# 3. Update TC Vitals file and select storms to be processed
# 4. Cut apart input GRIB files to select only the needed parms and hours
# 5. Execute the tracker
# 6. Copy the output track files to various locations
#
##############################################################################

########################################
msg="has begun for ${cmodel} at ${CYL}z"
postmsg "$jlogfile" "$msg"
########################################

# This script runs the hurricane tracker using operational GRIB model output.  
# This script makes sure that the data files exist, it then pulls all of the 
# needed data records out of the various GRIB forecast files and puts them 
# into one, consolidated GRIB file, and then runs a program that reads the TC 
# Vitals records for the input day and updates the TC Vitals (if necessary).
# It then runs gettrk, which actually does the tracking.
# 
# Environmental variable inputs needed for this scripts:
#  PDY   -- The date for data being processed, in YYYYMMDD format
#  CYL   -- The numbers for the cycle for data being processed (00, 06, 12, 18)
#  cmodel -- Model being processed (gfs, mrf, ukmet, ecmwf, nam, ngm, ngps,
#                                   gdas, gfdl, ens (ncep ensemble))
#  envir -- 'prod' or 'test'
#  SENDCOM -- 'YES' or 'NO'
#  stormenv -- This is only needed by the tracker run for the GFDL model.
#              'stormenv' contains the name/id that is used in the input
#              grib file names.
#  pert  -- This is only needed by the tracker run for the NCEP ensemble.
#           'pert' contains the ensemble member id (e.g., n2, p4, etc.)
#           which is used as part of the grib file names.
#
# For testing script interactively in non-production set following vars:
#     gfsvitdir  - Directory for GFS Error Checked Vitals
#     namvitdir  - Directory for NAM Error Checked Vitals
#     gltrkdir   - Directory for output tracks
#     homesyndir - Directory with syndir scripts/exec/fix 
#     archsyndir - Directory with syndir scripts/exec/fix 
#

qid=$$
#----------------------------------------------#
#   Get input date information                 #
#----------------------------------------------#

export PDY=` echo $ymdh | cut -c1-8`
export CYL=` echo $ymdh | cut -c9-10`

export PDY=${PDY:-$1}
export CYL=${cyc:-$2}
export CYCLE=t${CYL}z
export cmodel=${cmodel:-$3}
export jobid=${jobid:-testjob}
export envir=${envir:-prod}
export SENDCOM=${SENDCOM:-NO}
export PARAFLAG=${PARAFLAG:-NO}
export PHASEFLAG=y
export WCORE_DEPTH=1.0
#export PHASE_SCHEME=vtt
#export PHASE_SCHEME=cps
export PHASE_SCHEME=both
export STRUCTFLAG=n
export IKEFLAG=n

if [ ${PARAFLAG} = 'YES' ]; then
  export TRKDATA=/ptmp/wx20tm/trakouth/${PDY}${cyc}/${cmodel}
else
  export TRKDATA=${DATA}/trakout
fi

export DATA=${TRKDATA:-/ptmp/wx20tm/trakout}
if [ ! -d $DATA ]
then
   mkdir -p $DATA
   cd $DATA
   /nwprod/util/ush/setup.sh
fi
cd $DATA

if [ ${PARAFLAG} = 'YES' ]
then 
  /nwprod/util/ush/setup.sh
fi

if [ ${#PDY} -eq 0 -o ${#CYL} -eq 0 -o ${#cmodel} -eq 0 ]
then
  set +x
  echo
  echo "Something wrong with input data.  One or more input variables has length 0"
  echo "PDY= ${PDY}, CYL= ${CYL}, cmodel= ${cmodel}"
  echo "EXITING...."
  set -x
  err_exit " FAILED ${jobid} -- BAD INPUTS AT LINE $LINENO IN TRACKER SCRIPT - ABNORMAL EX
IT"
else
  set +x
  echo " "
  echo " #-----------------------------------------------------------------#"
  echo " At beginning of tracker script, the following imported variables "
  echo " are defined: "
  echo "   PDY ................................... $PDY"
  echo "   CYL ................................... $CYL"
  echo "   CYCLE ................................. $CYCLE"
  echo "   cmodel ................................ $cmodel"
  echo "   jobid ................................. $jobid"
  echo "   envir ................................. $envir"
  echo "   SENDCOM ............................... $SENDCOM"
  echo " "
  set -x
fi

scc=`echo ${PDY} | cut -c1-2`
syy=`echo ${PDY} | cut -c3-4`
smm=`echo ${PDY} | cut -c5-6`
sdd=`echo ${PDY} | cut -c7-8`
shh=${CYL}
symd=`echo ${PDY} | cut -c3-8`
syyyy=`echo ${PDY} | cut -c1-4`
symdh=${PDY}${CYL}

export gfsvitdir=${gfsvitdir:-/com/gfs/prod/gfs.$PDY}
export namvitdir=${namvitdir:-/com/nam/prod/nam.$PDY}
export gltrkdir=${gltrkdir:-/com/hur/${envir}/global}

export homesyndir=${homesyndir:-/nwprod/util}
export exectrkdir=${exectrkdir:-${homesyndir}/exec}
export ushtrkdir=${ushtrkdir:-${homesyndir}/ush}
export archsyndir=${archsyndir:-/com/arch/prod/syndat}

cp /com/date/t${CYL}z ncepdate
export CENT=` cut -c7-8 ncepdate `

export wgrib2=/nwprod/util/exec/wgrib2
export cnvgrib=/nwprod/util/exec/cnvgrib

if [ -s /nwprod/util/exec/wgrib ]
then
  wgrib=/nwprod/util/exec/wgrib
else
  set +x
  echo " "
  echo "!!! ERROR: wgrib is not available, script will crash.  Exiting...."
  echo " "
  set -x
  err_exit " FAILED ${jobid} -- line= $LINENO IN TRACKER SCRIPT - ABNORMAL EXIT"
fi

wgrib_parmlist=" HGT:925 HGT:850 HGT:700 UGRD:850 UGRD:700 UGRD:500 VGRD:850 VGRD:700 VGRD:500 SurfaceU SurfaceV ABSV:850 ABSV:700 PRMSL MSLET HGT:900 HGT:800 HGT:750 HGT:650 HGT:600 HGT:550 HGT:500 HGT:450 HGT:400 HGT:350 HGT:300 HGT:250 TMP:500 TMP:450 TMP:400 TMP:350 TMP:300 TMP:250"

export maxtime=65    # Max number of forecast time levels

#----------------------------------------------------------------#
#
#    --- Define data directories and data file names ---
#               
# Convert the input model to lowercase letters and check to see 
# if it's a valid model, and assign a model ID number to it.  
# This model ID number is passed into the Fortran program to 
# let the program know what set of forecast hours to use in the 
# ifhours array.  Also, set the directories for the operational 
# input GRIB data files and create templates for the file names.
# While only 1 of these sets of directories and file name 
# templates is used during a particular run of this script, 
# "gfsvitdir" is used every time, because that is the directory 
# that contains the error-checked TC vitals file that Steve Lord 
# produces, and so it is included after the case statement.
#
# NOTE: The varible PDY is now defined within the J-Jobs that
# call this script.  Therefore there is no reason to do this
# here.
#----------------------------------------------------------------#

cmodel=`echo ${cmodel} | tr "[A-Z]" "[a-z]"`

gfdldir=${gfdldir:-/com/hur/prod/hur.${PDY}${CYL}}  
COMIN=${gfdldir}                                 
gfdlgfile=${stormenv}.${PDY}${CYL}.grib6th.f    
gfdlifile=${stormenv}.${PDY}${CYL}.grib6th.if    
COM=/com/hur/${envir}/hur.${PDY}${CYL}           
fcstlen=126
fcsthrs=' 00 06 12 18 24 30 36 42 48 54 60 66 72 78
          84 90 96 102 108 114 120 126 99 99 99 99
          99 99 99 99 99 99 99 99 99 99 99 99 99 99
          99 99 99 99 99 99 99 99 99 99 99 99 99 99
          99 99 99 99 99 99 99 99 99 99 99'
stormid=${atcfid}                                
atcfnum=81                                       
atcfname="gfdt"                                  
atcfout="gfdt"                                   
atcffreq=600                                 
mslpthresh=0.0015                                
v850thresh=1.5000                                
modtyp='regional'                                
file_sequence="multi"                            
rundescr="12th_20x20"                            
atcfdescr=${stormenv}                            
lead_time_units='hours'                          
nest_type='moveable'                             
model=9                                         

if [ ${PHASEFLAG} = 'y' ]; then
  wgrib_parmlist=" HGT:850 HGT:700 UGRD:850 UGRD:700 UGRD:500 VGRD:850 VGRD:700 VGRD:500 SurfaceU SurfaceV ABSV:850 ABSV:700 PRMSL MSLET HGT:925 HGT:900 HGT:800 HGT:750 HGT:650 HGT:600 HGT:550 HGT:500 HGT:450 HGT:400 HGT:350 HGT:300 HGT:250 TMP:500 TMP:450 TMP:400 TMP:350 TMP:300 TMP:250"
else
  wgrib_parmlist=" HGT:850 HGT:700 UGRD:850 UGRD:700 UGRD:500 VGRD:850 VGRD:700 VGRD:500 SurfaceU SurfaceV ABSV:850 ABSV:700 PRMSL MSLET"
fi

# For doing the processing for the GFDL model, we want
# to further cut down on which vitals we allow into this run of the
# tracker.  The reason is that this program will be called from 
# each individual run for a storm, so the grib files will be 
# specific to each storm.  So if 4 storms are being run at a 
# particular cycle, then this script is run 4 separate times from
# within the GFDL_POST job.

grep -i ${stormid} ${COMIN}/${ATCFNAME}.vitals.${syy}${smm}${sdd}${shh} >${DATA}/tmpvit
mv ${DATA}/tmpvit ${DATA}/vitals.${atcfout}.${PDY}${CYL}

# - - - - - - - - - - - - -
# Before running the program to read, sort and update the vitals,
# first run the vitals through some awk logic, the purpose of 
# which is to convert all the 2-digit years into 4-digit years.
# Beginning 4/21/99, NHC and JTWC will begin sending the vitals
# with 4-digit years, however it is unknown when other global
# forecasting centers will begin using 4-digit years, thus we
# need the following logic to ensure that all the vitals going
# into supvit.f have uniform, 4-digit years in their records.
#
# 1/8/2000: sed code added by Tim Marchok due to the fact that 
#       some of the vitals were getting past the syndata/qctropcy
#       error-checking with a colon in them; the colon appeared
#       in the character immediately to the left of the date, which
#       was messing up the "(length($4) == 8)" statement logic.
# - - - - - - - - - - - - -

sed -e "s/\:/ /g"  ${DATA}/vitals.${atcfout}.${PDY}${CYL} > ${DATA}/tempvit
mv ${DATA}/tempvit ${DATA}/vitals.${atcfout}.${PDY}${CYL}

awk '
{
  yycheck = substr($0,20,2)
  if ((yycheck == 20 || yycheck == 19) && (length($4) == 8)) {
    printf ("%s\n",$0)
  }
  else {
    if (yycheck >= 0 && yycheck <= 50) {
      printf ("%s20%s\n",substr($0,1,19),substr($0,20))
    }
    else {
      printf ("%s19%s\n",substr($0,1,19),substr($0,20))
    }
  }
} ' ${DATA}/vitals.${atcfout}.${PDY}${CYL} >${DATA}/vitals.${atcfout}.${PDY}${CYL}.y4

mv ${DATA}/vitals.${atcfout}.${PDY}${CYL}.y4 ${DATA}/vitals.${atcfout}.${PDY}${CYL}

numvitrecs=` cat ${DATA}/vitals.${atcfout}.${PDY}${CYL} | wc -l`

if [ ${numvitrecs} -gt 0 ]
then
  mv ${DATA}/vitals.${atcfout}.${PDY}${CYL} ${DATA}/vitals.upd.${atcfout}.${PDY}${CYL}
else
  err_exit " FAILED ${jobid} - ERROR IN EXTRKR_GFDL - MISSING TC VITALS - ABNORMAL EXIT"
fi

#------------------------------------------------------------------#
# Now select all storms to be processed, that is, process every
# storm that's listed in the updated vitals file for the current
# forecast hour.  If there are no storms for the current time,
# then exit.
#------------------------------------------------------------------#

numvitrecs=`cat ${DATA}/vitals.upd.${atcfout}.${PDY}${CYL} | wc -l`
if [ ${numvitrecs} -eq 0 ]
then
  if [ ${trkrtype} = 'tracker' ]
  then
    set +x
    echo " "
    echo "!!! NOTE -- There are no vitals records for this time period "
    echo "!!! in the UPDATED vitals file."
    echo "!!! It could just be that there are no storms for the current"
    echo "!!! time.  Please check the dates and submit this job again...."
    echo " "
    set -x
    exit 1
  fi
fi

set +x
echo " "
echo " *--------------------------------*"
echo " |        STORM SELECTION         |"
echo " *--------------------------------*"
echo " "
set -x

ict=1
while [ $ict -le 15 ]
do
  stormflag[${ict}]=3
  let ict=ict+1
done

dtg_current="${symd} ${CYL}00"
stormmax=` grep "${dtg_current}" ${DATA}/vitals.upd.${atcfout}.${PDY}${CYL} | wc -l`

if [ ${stormmax} -gt 15 ]
then
  stormmax=15
fi

sct=1
while [ ${sct} -le ${stormmax} ]
do
  stormflag[${sct}]=1
  let sct=sct+1
done

# Simply create this zero-length genesis vitals file so that 
# the tracker code doesn't complain and fail due to it not
# being there....
genvitdir=${DATA}
genvitfile=${DATA}/genvitals.upd.${cmodel}.${atcfout}.${PDY}${CYL}
touch ${genvitfile}


#-----------------------------------------------------------------#
#
#         ------  CUT APART INPUT GRIB FILES  -------
#
# For the selected model, cut apart the GRIB input files in order
# to pull out only the variables that we need for the tracker.  
# Put these selected variables from all forecast hours into 1 big 
# GRIB file that we'll use as input for the tracker.
# 
# The wgrib utility (/nwprod/util/exec/wgrib) is used to cut out 
# the needed parms for the GFDL files.
# The utility /nwprod/util/exec/copygb is used to interpolate the 
# NGM (polar stereographic) and NAM (Lambert Conformal) data from 
# their grids onto lat/lon grids.  Note that while the lat/lon 
# grid that I specify overlaps into areas that don't have any data 
# on the original grid, Mark Iredell wrote the copygb software so 
# that it will mask such "no-data" points with a bitmap (just be 
# sure to check the lbms in your fortran program after getgb).
#-----------------------------------------------------------------#

set +x
echo " "
echo " -----------------------------------------"
echo "   NOW CUTTING APART INPUT GRIB FILES TO "
echo "   CREATE 1 BIG GRIB INPUT FILE "
echo " -----------------------------------------"
echo " "
set -x

gix=/nwprod/util/exec/grbindex
cgb=/nwprod/util/exec/copygb

regflag=`grep NHC ${DATA}/vitals.upd.${atcfout}.${PDY}${CYL} | wc -l`

# ----------------------------------
#   Process GFDL, if selected
# ----------------------------------

# The GFDL GRIB grid is already a lat/lon grid, however it uses a scanning 
# mode flag of 64, which means the data starts in the south and goes north.
# The tracker needs the data to start in the north and go south, so we will
# use copygb to flip the data in the grid.  The other thing that copygb 
# will do here is make the new file have wider boundaries around all 4 
# sides of the grid.  This is done because the GFDL grid is a regional grid,
# and we need to have that buffer of null, bitmapped data around a 
# regional grid.  The north-south extent of the domain is always the same,
# so we will hardwire the new latitude bounds in the "grid=" statement
# (adding an extra ~5.0 degrees both north and south), but we need to wgrib
# the 00h file to get the longitude bounds, and then modify them.  The 
# northern and southern boundaries are fixed in that "grid=" statement 
# because those boundaries do NOT change from run to run; the integration
# grid only changes in the east/west direction.

if [ ${model} -eq 9 ]
then

  dataflag='x'

  if [ $loopnum -eq 1 -a ${dataflag} = 'x' ]
  then

    if [ ${regflag} -eq 0 ]; then
      if [ ${trkrtype} = 'tracker' ]
      then
        set +x
        echo " "
        echo " !!! GFDL model has been selected, but there are no storms in the"
        echo " !!! TC Vitals file that can be processed.  That is, there are no"
        echo " !!! Vitals records from NHC.  The vitals records that are in the"
        echo " !!! updated vitals file must be from another cyclone forecast "
        echo " !!! center, and the GFDL domain does not extend to any "
        echo " !!! region other than that covered by NHC.  Exiting....."
        set -x
        exit 0
      fi
    fi
  
    if [ -s ${DATA}/gfdl.${stormenv}.pgrb.${PDY}${CYL} ]; then
      rm ${DATA}/gfdl.${stormenv}.pgrb.${PDY}${CYL}
    fi
  
    ict=1

    for fhour in ${fcsthrs}
    do
  
      if [ ${fhour} -eq 99 ]
      then
        continue
      fi

#     First do a wgrib to parse out only the variables we need.  This will make
#     the subsequent copygb procedure go much faster.  First we will parse out
#     using only the 1/6-degree, full-domain files.

      >${DATA}/g6th_orig_parsed.${stormenv}.${PDY}${CYL}.f${fhour}

      g6th_orig=${gfdldir}/${stormenv}.${PDY}${CYL}.grib6th.f${fhour}
      $wgrib -s ${g6th_orig} >g6th_orig.ix

      for parm in ${wgrib_parmlist}
      do
        case ${parm} in
          "SurfaceU")
            grep "UGRD:10 m " g6th_orig.ix | $wgrib -s ${g6th_orig} -i -grib -append \
                                    -o ${DATA}/g6th_orig_parsed.${stormenv}.${PDY}${CYL}.f${fhour} ;;
          "SurfaceV")
            grep "VGRD:10 m " g6th_orig.ix | $wgrib -s ${g6th_orig} -i -grib -append \
                                    -o ${DATA}/g6th_orig_parsed.${stormenv}.${PDY}${CYL}.f${fhour} ;;
                   *)
            grep "${parm}" g6th_orig.ix | $wgrib -s ${g6th_orig} -i -grib -append \
                                    -o ${DATA}/g6th_orig_parsed.${stormenv}.${PDY}${CYL}.f${fhour} ;;
        esac
      done

#     Now we will parse out the necessary variables from the original ~1/12 deg
#     files, which cover only the innermost mesh.

      >${DATA}/g12th_orig_parsed.${stormenv}.${PDY}${CYL}.f${fhour}

      g12th_orig=${gfdldir}/${stormenv}.${PDY}${CYL}.gribn3.f${fhour}
      $wgrib -s ${g12th_orig} >g12th_orig.ix

      for parm in ${wgrib_parmlist}
      do
        case ${parm} in
          "SurfaceU")
            grep "UGRD:10 m " g12th_orig.ix | $wgrib -s ${g12th_orig} -i -grib -append \
                                    -o ${DATA}/g12th_orig_parsed.${stormenv}.${PDY}${CYL}.f${fhour} ;;
          "SurfaceV")
            grep "VGRD:10 m " g12th_orig.ix | $wgrib -s ${g12th_orig} -i -grib -append \
                                    -o ${DATA}/g12th_orig_parsed.${stormenv}.${PDY}${CYL}.f${fhour} ;;
                   *)
            grep "${parm}" g12th_orig.ix | $wgrib -s ${g12th_orig} -i -grib -append \
                                    -o ${DATA}/g12th_orig_parsed.${stormenv}.${PDY}${CYL}.f${fhour} ;;
        esac
      done

#     Check to see if the original initial grib files exist. If not, we will exit.
#     For later lead times, the grib files may not be present if the gfdl model
#     stopped prematurely.

      if [ ${ict} -eq 1 ]; then
        if [ ! -s ${g6th_orig} -o ! -s ${g12th_orig} ]; then
          set +x
          echo " "
          echo " "
          echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
          echo " !!! ERROR: AT LEAST ONE OF THESE 2 GFDL FILES IS MISSING AT "
          echo " !!! THE **INITIAL** HOUR fhour= ${fhour}"
          echo " !!!    ${g6th_orig}"
          echo " !!!    ${g12th_orig}"
          echo " !!! WE CANNOT PROCESS ANY INITIAL DATA, SO WE WILL EXIT THE SCRIPT."
          echo " !!! CHECK TO BE SURE THAT THE FILE AND DIRECTORY NAMES ARE"
          echo " !!! SPECIFIED CORRECTLY."
          echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
          set -x
          err_exit " FAILED ${jobid} -- INITIAL GRIB FILES MISSING FOR GFDL IN TRACKER SCRIPT - ABNORMAL EXIT"
          exit 95
        fi
      fi

      gfdl_6th=${DATA}/g6th_orig_parsed.${stormenv}.${PDY}${CYL}.f${fhour}
      gfdl_12th=${DATA}/g12th_orig_parsed.${stormenv}.${PDY}${CYL}.f${fhour}

      origwestlon=`${wgrib} -V ${gfdl_12th} | grep long | head -1 | awk '{printf ("%d",$2*1000)}'`
      origeastlon=`${wgrib} -V ${gfdl_12th} | grep long | head -1 | awk '{printf ("%d",$4*1000)}'`
      let newwestlon=origwestlon-7500
      let neweastlon=origeastlon+7500

      origsolat=`${wgrib} -V ${gfdl_12th} | grep latlon | head -1 | awk '{printf ("%d",$3*1000)}'`
      orignolat=`${wgrib} -V ${gfdl_12th} | grep latlon | head -1 | awk '{printf ("%d",$5*1000)}'`
      let newsolat=origsolat-7500
      let newnolat=orignolat+7500

      gfdl_merge_basic=${DATA}/gfdl.merge_basic.${stormenv}.${PDY}${CYL}.f${fhour}

      grid="255 0 240 240 ${newnolat} ${newwestlon} 128 ${newsolat} ${neweastlon} 083  083 0"

      if [ ! -s ${gfdl_6th} -o ! -s ${gfdl_12th} ]
      then
        set +x
        echo " "
        echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        echo " !!! AT LEAST ONE OF THESE 2 GFDL FILES IS MISSING AT HOUR fhour= ${fhour}"
        echo " !!!    ${gfdl_6th}"
        echo " !!!    ${gfdl_12th}"
        echo " !!! THIS COULD BE AN ERROR, OR IT COULD BE THAT THE MODEL ITSELF STOPPED"
        echo " !!! PRIOR TO 126h DUE TO THE STORM REACHING THE GRID BOUNDARY."
        echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 
        set -x 
        continue
      fi

      timex $cgb -xg"$grid" -M ${gfdl_6th} ${gfdl_12th} ${gfdl_merge_basic}

      if [ -s ${gfdl_merge_basic}.i ]; then rm ${gfdl_merge_basic}.i; fi

      $gix ${gfdl_merge_basic} ${gfdl_merge_basic}.i
      x1=${gfdl_merge_basic}.i

      set +x
      echo " "
      echo "TIMING: Date in interpolation for fhour= $fhour before = `date`"
      echo " "
      set -x

#      catfile=${DATA}/${cmodel}_cat.${PDY}${CYL}.f${fhour}
#      >${catfile}

      gfile=${gfdl_merge_basic}
      ifile=${x1}

      gparm=7
      namelist=${DATA}/vint_input.${PDY}${CYL}.z
      echo "&timein ifcsthour=${fhour}, iparm=${gparm}/"  >${namelist}

      ln -s -f ${gfile}                                   fort.11
      ln -s -f ${FIXhur}/gfdl_tracker_hgt_levs.txt        fort.16
      ln -s -f ${ifile}                                   fort.31
      ln -s -f ${DATA}/${cmodel}.${PDY}${CYL}.z.f${fhour} fort.51

      timex ${exechwrfdir}/hwrf_vint <${namelist}

      gparm=11
      namelist=${DATA}/vint_input.${PDY}${CYL}
      echo "&timein ifcsthour=${fhour}, iparm=${gparm}/"  >${namelist}

      ln -s -f ${gfile}                                   fort.11
      ln -s -f ${FIXhur}/gfdl_tracker_tmp_levs.txt        fort.16
      ln -s -f ${ifile}                                   fort.31
      ln -s -f ${DATA}/${cmodel}.${PDY}${CYL}.t.f${fhour} fort.51

      timex ${exechwrfdir}/hwrf_vint <${namelist}

      namelist=${DATA}/tave_input.${PDY}${CYL}
      echo "&timein ifcsthour=${fhour}, iparm=${gparm}/"   >${namelist}
#      echo "        lt_units='${lead_time_units}'/"       >>${namelist}

      ffile=${DATA}/${cmodel}.${PDY}${CYL}.t.f${fhour}
      ifile=${DATA}/${cmodel}.${PDY}${CYL}.t.f${fhour}.i
      $gix ${ffile} ${ifile}

      ln -s -f ${ffile}                                      fort.11
      ln -s -f ${ifile}                                      fort.31
      ln -s -f ${DATA}/${cmodel}_tave.${PDY}${CYL}.f${fhour} fort.51

      timex ${exechwrfdir}/hwrf_tave <${namelist}

      tavefile=${DATA}/${cmodel}_tave.${PDY}${CYL}.f${fhour}
      zfile=${DATA}/${cmodel}.${PDY}${CYL}.z.f${fhour}
#      cat ${zfile} ${tavefile} >>${catfile}

#      g2=${catfile}
#      x2=${catfile}.i
#      $gix $g2 $x2

      g2=${zfile}
      x2=${zfile}.i
      $gix $g2 $x2

      g3=${tavefile}
      x3=${tavefile}.i
      $gix $g3 $x3
  
      set +x
      echo " "
      echo " Extracting GFDL GRIB data for forecast hour = $fhour"
      echo " "
      set -x
  
      g1=${gfdl_merge_basic}
  
      $cgb -g"$grid" -k'4*-1 33 100 850' $g1 $x1 ${DATA}/gfdlu850.grb.f${fhour};   rcc1=$?
      $cgb -g"$grid" -k'4*-1 33 100 700' $g1 $x1 ${DATA}/gfdlu700.grb.f${fhour};   rcc2=$?
      $cgb -g"$grid" -k'4*-1 33 100 500' $g1 $x1 ${DATA}/gfdlu500.grb.f${fhour};   rcc3=$?
      $cgb -g"$grid" -k'4*-1 33 105  10' $g1 $x1 ${DATA}/gfdlu10m.grb.f${fhour};   rcc4=$?
      $cgb -g"$grid" -k'4*-1  7 100 850' $g1 $x1 ${DATA}/gfdlz850.grb.f${fhour};   rcc7=$?
      $cgb -g"$grid" -k'4*-1  7 100 700' $g1 $x1 ${DATA}/gfdlz700.grb.f${fhour};   rcc8=$?
      $cgb -g"$grid" -k'4*-1  2 102   0' $g1 $x1 ${DATA}/gfdlmslp.grb.f${fhour};   rcc9=$?
      $cgb -g"$grid"                     $g2 $x2 ${DATA}/gfdlphase.grb.f${fhour};  rcc10=$?
      $cgb -g"$grid"                     $g3 $x3 ${DATA}/gfdltave.grb.f${fhour};  rcc11=$?
     
  
      if [ $rcc1 -eq 134 -o $rcc2 -eq 134 -o $rcc3 -eq 134 -o $rcc4 -eq 134 -o \
           $rcc7 -eq 134 -o $rcc8 -eq 134 -o $rcc9 -eq 134 -o $rcc10 -eq 134 -o \
           $rcc11 -eq 134 ]
      then
        set +x
        echo " "
        echo "!!! ERROR using $cgb to interpolate gfdl data.  We will stop execution because"
        echo "!!! some variables may have been copied okay, while some obviously have not, "
        echo "!!! and that could lead to unreliable results from the tracker.  Check to make"
        echo "!!! sure you've allocated enough memory for this job.  Exiting...."
        echo " "
        set -x
        err_exit " FAILED ${jobid} - ERROR INTERPOLATING GFDL DATA IN TRACKER SCRIPT - ABNORMAL EXIT"
      fi
  
      let fmin=fhour*60
      minstr=` echo $fmin | awk '{printf ("%5.5d",$0)}'`
      gfdl_12th_20x20=${DATA}/gfdt.12th_20x20.${stormenv}.${PDY}${CYL}.f${minstr}

      cat ${DATA}/gfdlu850.grb.f${fhour} ${DATA}/gfdlu700.grb.f${fhour} \
          ${DATA}/gfdlu500.grb.f${fhour} ${DATA}/gfdlz850.grb.f${fhour} \
          ${DATA}/gfdlz700.grb.f${fhour} ${DATA}/gfdlmslp.grb.f${fhour} \
          ${DATA}/gfdlu10m.grb.f${fhour} ${DATA}/gfdlphase.grb.f${fhour} \
          ${DATA}/gfdltave.grb.f${fhour} >${gfdl_12th_20x20}
  
      $gix ${gfdl_12th_20x20} ${gfdl_12th_20x20}.ix

      cp ${gfdl_12th_20x20}    ${COMIN}/.
      cp ${gfdl_12th_20x20}.ix ${COMIN}/.

      let ict=ict+1
   
    done

  fi

  gribfile=NULL_USING_MULTI_OPTION
  ixfile=NULL_USING_MULTI_OPTION

fi

#------------------------------------------------------------------------#
#                         Now run the tracker                            #
#------------------------------------------------------------------------#

ist=1
while [ $ist -le 15 ]
do
  if [ ${stormflag[${ist}]} -ne 1 ]
  then
    set +x; echo "Storm number $ist NOT selected for processing"; set -x
  else
    set +x; echo "Storm number $ist IS selected for processing...."; set -x
  fi
  let ist=ist+1
done

# Load the forecast hours for this particular model into an array 
# that will be passed into the executable via a namelist....

last_fcst_hour=0
ifh=1
while [ $ifh -le ${maxtime} ]
do
  fh[${ifh}]=` echo ${fcsthrs} | awk '{print $n}' n=$ifh`
  fhr=`        echo ${fcsthrs} | awk '{print $n}' n=$ifh`
  if [ ${fhr} -ne 99 ]
  then
    last_fcst_hour=${fhr}
  fi
  let ifh=ifh+1
done

if [ ! -s ${DATA}/last_fcst_hour.${atcfout}.${PDY}${CYL} ]
then
  echo ${last_fcst_hour} >${DATA}/last_fcst_hour.${atcfout}.${PDY}${CYL}
fi

namelist=${DATA}/input.${atcfout}.${PDY}${CYL}
ATCFNAME=` echo "${atcfname}" | tr '[a-z]' '[A-Z]'`

export atcfymdh=${scc}${syy}${smm}${sdd}${shh}

contour_interval=100.0
write_vit=n

echo "&datein inp%bcc=${scc},inp%byy=${syy},inp%bmm=${smm},"      >${namelist}
echo "        inp%bdd=${sdd},inp%bhh=${shh},inp%model=${model}," >>${namelist}
echo "        inp%modtyp='${modtyp}',"                           >>${namelist}
echo "        inp%lt_units='${lead_time_units}',"                >>${namelist}
echo "        inp%file_seq='${file_sequence}',"                  >>${namelist}
echo "        inp%nesttyp='${nest_type}'/"                       >>${namelist}
echo "&atcfinfo atcfnum=${atcfnum},atcfname='${ATCFNAME}',"      >>${namelist}
echo "          atcfymdh=${atcfymdh},"                           >>${namelist}
echo "          atcffreq=${atcffreq}/"                           >>${namelist}
echo "&trackerinfo trkrinfo%westbd=${trkrwbd},"                  >>${namelist}
echo "      trkrinfo%eastbd=${trkrebd},"                         >>${namelist}
echo "      trkrinfo%northbd=${trkrnbd},"                        >>${namelist}
echo "      trkrinfo%southbd=${trkrsbd},"                        >>${namelist}
echo "      trkrinfo%type='${trkrtype}',"                        >>${namelist}
echo "      trkrinfo%mslpthresh=${mslpthresh},"                  >>${namelist}
echo "      trkrinfo%v850thresh=${v850thresh},"                  >>${namelist}
echo "      trkrinfo%gridtype='${modtyp}',"                      >>${namelist}
echo "      trkrinfo%contint=${contour_interval},"               >>${namelist}
echo "      trkrinfo%out_vit='${write_vit}'/"                    >>${namelist}
echo "&phaseinfo phaseflag='${PHASEFLAG}',"                      >>${namelist}
echo "           phasescheme='${PHASE_SCHEME}',"                 >>${namelist}
echo "           wcore_depth=${WCORE_DEPTH}/"                    >>${namelist}
echo "&structinfo structflag='${STRUCTFLAG}',"                   >>${namelist}
echo "            ikeflag='${IKEFLAG}'/"                         >>${namelist}
echo "&fnameinfo  gmodname='${atcfname}',"                       >>${namelist}
echo "            rundescr='${rundescr}',"                       >>${namelist}
echo "            atcfdescr='${atcfdescr}'/"                     >>${namelist}
echo "&verbose verb=3/"                                          >>${namelist}
echo "&waitinfo use_waitfor='n',"                                >>${namelist}
echo "          wait_min_age=10,"                                >>${namelist}
echo "          wait_min_size=100,"                              >>${namelist}
echo "          wait_max_wait=1800,"                             >>${namelist}
echo "          wait_sleeptime=5,"                               >>${namelist}
echo "          per_fcst_command=''/"                            >>${namelist}

export pgm=gfdl_gettrk
. prep_step

ln -s -f ${gribfile}                                               fort.11
ln -s -f ${DATA}/vitals.upd.${atcfout}.${PDY}${shh}                fort.12
ln -s -f ${DATA}/genvitals.upd.${atcfout}.${PDY}${shh}             fort.13
ln -s -f ${FIXhur}/${cmodel}_tracker_leadtimes.txt                 fort.15
ln -s -f ${ixfile}                                                 fort.31

ln -s -f ${DATA}/trak.${atcfout}.all.${stormenv}.${PDY}${CYL}       fort.61
ln -s -f ${DATA}/trak.${atcfout}.atcf.${stormenv}.${PDY}${CYL}      fort.62
ln -s -f ${DATA}/trak.${atcfout}.radii.${stormenv}.${PDY}${CYL}     fort.63
ln -s -f ${DATA}/trak.${atcfout}.atcfunix.${stormenv}.${PDY}${CYL}  fort.64
ln -s -f ${DATA}/trak.${atcfout}.atcf_gen.${stormenv}.${PDY}${CYL}  fort.66
ln -s -f ${DATA}/trak.${atcfout}.atcf_sink.${stormenv}.${PDY}${CYL} fort.68
ln -s -f ${DATA}/trak.${atcfout}.atcf_hfip.${stormenv}.${PDY}${CYL} fort.69

if [ ${atcfname} = 'aear' ]
then
  ln -s -f ${DATA}/trak.${atcfout}.initvitl.${PDY}${CYL}           fort.65
fi

if [ ${write_vit} = 'y' ]
then
  ln -s -f ${DATA}/output_genvitals.${atcfout}.${PDY}${shh}        fort.67
fi

if [ ${PHASEFLAG} = 'y' ]; then
  ln -s -f ${DATA}/trak.${atcfout}.cps_parms.${stormenv}.${PDY}${CYL}    fort.71
fi

if [ ${STRUCTFLAG} = 'y' ]; then
  ln -s -f ${DATA}/trak.${atcfout}.structure.${stormenv}.${PDY}${CYL}    fort.72
  ln -s -f ${DATA}/trak.${atcfout}.fractwind.${stormenv}.${PDY}${CYL}    fort.73
  ln -s -f ${DATA}/trak.${atcfout}.pdfwind.${stormenv}.${PDY}${CYL}      fort.76
fi

if [ ${IKEFLAG} = 'y' ]; then
  ln -s -f ${DATA}/trak.${atcfout}.ike.${stormenv}.${PDY}${CYL}          fort.74
fi


set +x
echo " "
echo " -----------------------------------------------"
echo "           NOW EXECUTING TRACKER......"
echo " -----------------------------------------------"
echo " "
set -x

msg="$pgm start for $atcfout at ${CYL}z"
postmsg "$jlogfile" "$msg"

set +x
echo "+++ TIMING: BEFORE gfdl_gettrk  ---> `date`"
set -x

ulimit -c unlimited

${exectrkdir}/gfdl_gettrk <${namelist}
gettrk_rcc=$?

set +x
echo "+++ TIMING: AFTER  gfdl_gettrk  ---> `date`"
set -x

#--------------------------------------------------------------#
# Now copy the output track files to different directories
#--------------------------------------------------------------#

set +x
echo " "
echo " -----------------------------------------------"
echo "    NOW COPYING OUTPUT TRACK FILES TO COM  "
echo " -----------------------------------------------"
echo " "
set -x

if [ ${gettrk_rcc} -eq 0 ]; then

  if [ -s ${DATA}/output_genvitals.${atcfout}.${PDY}${shh} ]; then
    cat ${DATA}/output_genvitals.${atcfout}.${PDY}${shh} >>${genvitfile}
  fi

  if [ ${PARAFLAG} = 'YES' ]
  then
    cp ${DATA}/trak.${atcfout}.atcfunix.${PDY}${CYL} ../.
    cat ${DATA}/trak.${atcfout}.atcfunix.${PDY}${CYL} >> \
           ${rundir}/${cmodel}.atcfunix.${syyyy}
#    cp ${DATA}/trak.${atcfout}.atcf_sink.${PDY}${CYL} ../.
#    cp ${DATA}/trak.${atcfout}.atcf_gen.${PDY}${CYL} ../.
  fi

  msg="$pgm end for $atcfout at ${CYL}z completed normally"
  postmsg "$jlogfile" "$msg"

# Copy atcf files to NHC archives. We'll use Steve Lord's original script,
# distatcf.sh, to do this, and that script requires the input atcf file to
# have the name "attk126", so first copy the file to that name, then call
# the distatcf.sh script.  After that's done, then copy the full 0-72h
# track into the /com/hur/prod/global track archive file.

  if [ ${SENDCOM} = 'YES' ]
  then

    gltrakarch=${gltrakarch:-${gltrkdir}/tracks.${syy}}
    tmtrakarch=${tmtrakarch:-/global/save/wx20tm/trak/prod/tracks.all.${syy}}

    glatcfarch=${glatcfarch:-${gltrkdir}/tracks.atcf.${syy}}
    tmatcfarch=${tmatcfarch:-/global/save/wx20tm/trak/prod/tracks.atcf.${syy}}

    glatuxarch=${glatuxarch:-${gltrkdir}/tracks.atcfunix.${syy}}
    tmatuxarch=${tmatuxarch:-/global/save/wx20tm/trak/prod/tracks.atcfunix.${syy}}

    glradarch=${glradarch:-${gltrkdir}/tracks.radii.${syy}}
    tmradarch=${tmradarch:-/global/save/wx20tm/trak/prod/tracks.radii.${syy}}

#    cat ${DATA}/trak.${atcfout}.all.${PDY}${CYL}   >>${gltrakarch}
#    cat ${DATA}/trak.${atcfout}.all.${PDY}${CYL}   >>${tmtrakarch}

#    cat ${DATA}/trak.${atcfout}.atcf.${PDY}${CYL}  >>${glatcfarch}
#    cat ${DATA}/trak.${atcfout}.atcf.${PDY}${CYL}  >>${tmatcfarch}

#    cat ${DATA}/trak.${atcfout}.atcfunix.${PDY}${CYL}  >>${glatuxarch}
#    cat ${DATA}/trak.${atcfout}.atcfunix.${PDY}${CYL}  >>${tmatuxarch}

#    cat ${DATA}/trak.${atcfout}.atcfunix.${stormenv}.${PDY}${CYL}  >>${glatuxarch}
#    cat ${DATA}/trak.${atcfout}.atcfunix.${stormenv}.${PDY}${CYL}  >>${tmatuxarch}

#    cat ${DATA}/trak.${atcfout}.radii.${PDY}${CYL} >>${glradarch}
#    cat ${DATA}/trak.${atcfout}.radii.${PDY}${CYL} >>${tmradarch}


    if [ ${PARAFLAG} = 'YES' -a ${SENDCOM} = 'NO' ]
    then
      echo " "
    else
#      cp ${DATA}/trak.${atcfout}.atcf.${PDY}${CYL} attk126
#      ${ushtrkdir}/extrkr_distatcf.sh

#      cp ${DATA}/trak.${atcfout}.all.${PDY}${CYL}      ${COM}/${stormenv}.${PDY}${CYL}.trackerall
#      cp ${DATA}/trak.${atcfout}.atcf.${PDY}${CYL}     ${COM}/${stormenv}.${PDY}${CYL}.trackeratcf

#     "fulltrackeratcfunix" contains the thermal parms at the end....
      cp ${DATA}/trak.${atcfout}.atcfunix.${stormenv}.${PDY}${CYL} \
         ${COMIN}/${stormenv}.${PDY}${CYL}.fulltrackeratcfunix

#     Create a shortened version that does not include the thermal parms....
      cat ${DATA}/trak.${atcfout}.atcfunix.${stormenv}.${PDY}${CYL} | \
          cut -c1-113 >${DATA}/${stormenv}.${PDY}${CYL}.trackeratcfunix

      cp ${DATA}/${stormenv}.${PDY}${CYL}.trackeratcfunix ${COMIN}/.

      tmscrdir=/global/save/wx20tm/trak/prod

      tmtrakstat=${tmscrdir}/tracker.prod.status
      echo "${atcfout} tracker completed okay for ${PDY}${CYL}" >>${tmtrakstat}

      export SENDDBN=${SENDDBN:-YES}
      if [ ${SENDDBN} = 'YES' ]
      then
        $DBNROOT/bin/dbn_alert ATCFUNIX GFS_NAVY $job ${COMIN}/${stormenv}.${PDY}${CYL}.trackeratcfunix
      fi

      # We need to parse apart the atcfunix file and distribute the forecasts to 
      # the necessary directories.  To do this, first sort the atcfunix records 
      # by forecast hour (k6), then sort again by ocean basin (k1), storm number (k2)
      # and then quadrant radii wind threshold (k12).  Once you've got that organized 
      # file, break the file up by putting all the forecast records for each storm 
      # into a separate file.  Then, for each file, find the corresponding atcfunix 
      # file in the tpc directory and dump the atcfunix records for that storm 
      # in there.  NOTE: Only do this if the model run is NOT for the ensemble.
      # the reason is that we do NOT want to write out the individual member tracks
      # to the atcfunix file.  We only want to write out the ensemble mean track
      # to the atcfunix file, and the mean track is calculated in a separate script.

      if [ $cmodel != 'ens' ]; then

        auxfile=${COMIN}/${stormenv}.${PDY}${CYL}.trackeratcfunix

        sort -k6 ${auxfile} | sort -k1 -k2 -k12  >atcfunix.sorted

        old_string="XX, XX"

        ict=0
        while read unixrec
        do
          storm_string=` echo "${unixrec}" | cut -c1-6`
          if [ "${storm_string}" = "${old_string}" ]
          then
            echo "${unixrec}" >>atcfunix_file.${ict}
          else
            let ict=ict+1
            echo "${unixrec}"  >atcfunix_file.${ict}
            old_string="${storm_string}"
          fi
        done <atcfunix.sorted

        if [ $ict -gt 0 ]
        then
          mct=0
          while [ $mct -lt $ict ]
          do
            let mct=mct+1
            at=` head -1 atcfunix_file.$mct | cut -c1-2 | tr '[A-Z]' '[a-z]'`
            NO=` head -1 atcfunix_file.$mct | cut -c5-6`
            if [ -d ${ATCFdir}/${at}${NO}${syyyy} ]
            then
              cat atcfunix_file.$mct >>${ATCFdir}/${at}${NO}${syyyy}/ncep_a${at}${NO}${syyyy}.dat
              set +x
              echo " "
              echo "+++ Adding records to  TPC ATCFUNIX directory: ${ATCFdir}/${at}${NO}${syyyy}"
              echo " "
              set -x
            else
              set +x
              echo " "
              echo "There is no TPC ATCFUNIX directory for: ${ATCFdir}/${at}${NO}${syyyy}"
              set -x
            fi
          done
        fi

      fi

#      /nwprod/util/ush/prodllsubmit wx20tm ${tmscrdir}/tracker_prod_post.sh
    fi

  fi

else

  if [ ${PARAFLAG} = 'YES' ]
  then
    echo " "
  else
    tmtrakstat=/global/save/wx20tm/trak/prod/tracker.prod.status
    echo "ERROR: ${atcfout} tracker FAILED for ${PDY}${CYL}" >>${tmtrakstat}
  fi

  set +x
  echo " "
  echo "!!! ERROR -- An error occurred while running gfdl_gettrk, "
  echo "!!! which is the program that actually gets the track."
  echo "!!! Return code from gfdl_gettrk = ${gettrk_rcc}"
  echo "!!! model= ${atcfout}, forecast initial time = ${PDY}${CYL}"
  echo "!!! Exiting...."
  echo " "
  set -x
  err_exit " FAILED ${jobid} - ERROR RUNNING GFDL_GETTRK IN TRACKER SCRIPT- ABNORMAL EXIT"

fi
