#!/bin/csh  
echo $0 started at `date`; echo " "

###### regulate how many instances of this script can run concurrently 
set maxinstances=3 # was 5
set instances=`ps -ef | grep "${0}" | grep "/bin/csh" | wc -l`
echo "For logging purposes the number of instances of this script $0 $1 $2 $3 $4 (including the 4 input arguments) presently running is $instances"; echo " "
if ($instances > $maxinstances) then
        if ("$4" == "") then # if a 4th arg is entered we are testing the script and it will work in its own subdir so it ok to exceed the max instances in this case
		echo "Including this, there are now ${instances} instances of '$0' running - (only a maximum of ${maxinstances} are allowed to run simultaneously).. script ending."
	        goto EXITING
	else
             	echo "Including this, there are now ${instances} instances of '$0' running - (only a maximum of ${maxinstances} are allowed to run simultaneously).. "
		echo "but a 4th command line argument was supplied so this is assumed to be running as a test and one more than the max instances will be allowed"
	endif	
endif
############# MODEL SPECIFIC SETTINGS YOU SHOULD CHANGE OR VERIFY #######################################################################################################################################

###### local settings
set MDL=wrf4nssl    		    					# what you want the model to be named, this is used for its grib and grid dir names


###### CYCLE availablility on remote server
set CYCLIST="00 06 12 18"							# change these to what you want to be retrieved 

###### file availability settings -- MUST match  how output files are provided on the remote server 
set fmin=1                      			       		# first fhr available - usually 0 (for testing could be set to a specific fhr)
set fmax=48								# max available lead time of the model (can be changed for testing)
set fres1=0            	       						# usually 0 (represents the fhr which tres1 is representative)
set tres1=1         	    						# the temporal resolution starting at fmin available on the remote server
set fres2=""                      					# fhr the temporal resolution changes on the server (if it changes), leave blank otherwise (double quote)
set tres2=""								# temporal resolution different than tres1 if it changes again, leave blank otherwise (double quote)
set fres3=""								# ditto if it changes again
set tres3=""								# ditto if it changes again
set fres4=""								# ditto if it changes again
set tres4=""								# ditto if it changes again
set tres=$tres1								# default start -- will be changed if a user enters a specific fhr to run the script
set runtotalfhrs=48                                                     # special line for when to launch additional post processing scripts

##### file nomenclature settings - must match how output files are provided on the remote serve
set URLFORM=cftp.nssl.noaa.gov/realtime                                 # anything in lower case is literal, anything in upper case will be modified in the core code of the script
set GRIBFORM=MMM_YMDCYCfFF.grib2                                        # gribfile nomenclature on remote server, lower case is literal, upper case will be modified in the script
									# WARNING - regardless of the number of chars of the fhr in the filename on remote server leave it here as FFF!
set MMM=mpasht2_nssl                                                    # what MMM will be on the remote server  WARNING - this is usually different than what MDL is set to
set GRIBDIRFORM=${MDL}.YMDCYC                                           # nomenclature of how retrieved grib files will be stored locally - YMDCYC will be replaced by real YMD CYC in the script core
set FHRCHARS=2                                                          # This specifies how many characters the fhr contains in the filename on the remote server - its either 2 or 3

#### user specific changes to model pull temporal frequency 
set tresmanualchange=""                                                 # leave as a null (double quote) if you wish to default to how output files available on server
									# otherwise specify using the format fH:N,fH:N where
									# The 3 characters   f  :  ,   are literal characters
									# H is the fhr to change pull frequency and N is the temporal frequency to change to
									# Comma separates each change
									# Example "f87:3,f168:6,f204:12" implies use default 1 hourly files then pull every three hours after f87, 
									# then pull every 6hrs after f168, then pull every 12 hrs after f204
set RESCHANGELIST=`echo $tresmanualchange | sed 's/,/ /g' | sed s/f//g` # this is here vs at the end inside the loop since we only need to determine this once

#### settings for wind cust calculations
set pmin=700 								# top limit in model of isobaric level to assess gusts 
set pmax=1000 								# lower limit in model of isobaric level to assess gusts
set resp1=50 # will have to skip 925					# vertical resolution from pmax and above  until it changes
set resp2=200 # next level above 700 is 500 				# vert resolution change from resp1 
set lvlresp2=700 							# model isobaric level at which vertical res changes
set percentage=70                                                       # threshold of std atm considered "stable" (70% of -6.5 degC/km = -4.6 degC/km) per NWS BUFKIT Ed Mahoney's momentum xfer method
set st=`echo $percentage|awk '{n= $0/100 * -6.5; printf "%.2f\n", n}'`  # stability threshold as calculated in example above
set flastgust=$fmax                                                     # Fhr to last conduct gust calcs (set to fmax if you wish all fhrs to be processed, sometimes data is not needed after certain fhrs)
set dtmax=300                                                           # max num secs to wait for a file to arrive - bail out after this

#### settings to trigger external scripts                               # set to -999 if you do not want script to be launched
set flastptype=$fmax  							# fhr get_${MDL}_ptype is launched (calcs ptype buckets -- f01-this fhr)
set VERIFWIND=-999        						# ditto for verif_${MDL}_wind script (calcs rolling window gusts and masked gusts)

# End settings section - typically you do not need to change anything below this line
#########################################################################################################################################################################################################
##### inputs and error checking
set CYC=$1          							# Cycle to be retrieved
set YMD=$2                      					# YMD of cycle to be retrieved
set FHR="$3"                    					# optional fhr to be retrieved - can be a range (ex 00-03)
set STN="$4"								# optional STN to be used for testing of wind output at a location

##### interpret inputs

if ($CYC == "") then
        echo " "
        echo "Need a cyc and ymd in a specific format.  Ex  6 `date +%Y%m%d`"
	echo " "
   	echo "If "'"'"sniffer"'"'" is supplied as a CYC then the script becomes a continuous sniffer.."
	echo "and grab/process the most recent cycles data as it becomes available until the cycle"
	echo "is completely retrieved"
	echo " "
	echo "If a cycle IS supplied that is not "'"'"sniffer"'"'"...."
	echo ".. but no 2nd arg (YMD) is supplied, the script assumes current z date in YMD"
	echo " "
        echo ".. an optional 3rd argument will be treated as an fhr to process.  Example 6 `date +%Y%m%d` 12"
        echo "   and treated as range if entered like 6-12.  Example 6 `date +%Y%m%d` 9-24"
	echo " "
        echo ".. an optional 4th argument will be treated as a test location to output wind gust calc info"
        echo "   and therefore serve as an indicator to reprocess only the input fhr(s). " 
	echo "   However the fhrs specified will not be re-retrieved or regridded unless they dont exist."
        echo "   Example BOS or "'"'"39.5;-79.5"'"'" (lat lons must be bounded in quotes)."
	echo "   WARNING - use the exact lat lon of a grid point vs an ID to avoid confusing results due to interpolation"
	echo "  " 
        goto EXITING
else
	if ($CYC != "sniffer") then
		set CYC=`echo $CYC | awk '{printf "%02d\n", $0}'`                       # ensure cycle supplied by user is transformed into a two character format with leading zeroes
		set CYCLIST=$CYC  							# override the default CYCLIST with the user input
		if ($YMD == "") set YMD=`date -u +%Y%m%d`				# default to current z date if no date provided and we are not in sniffer mode
	else
		#sniffer mode
		set YMD=`date -u +%Y%m%d`						# in sniffermode we are assuming to use latest z date
	       	set CYCLIST=`echo $CYCLIST | awk '{for (i=1; i<=NF; i++) {print $i}}' | sort -rn` 	# put CYCLIST in reverse order -- need to search from latest cyc possible avialable to oldets 
        endif
endif

set ACTUALYMD=$YMD
foreach ACTUALCYC ($CYCLIST)
  # skip cycle if its too early
  set UTCNOW=`date -u +%s`; set UTCCYC=`date -ud "$ACTUALYMD +$ACTUALCYC Hours" +%s`
  if (`echo $UTCNOW $UTCCYC | awk '{if ( ($2 - $1)/60 >= -30 ) print "too early"}'` != "") then
        echo "`date` - too early to pull ${ACTUALCYC}z for $ACTUALYMD - have to wait until 30 min after cycle at least"
        goto NEXTCYC
  endif
  # end skip cycle check
  
  set REMOTEGRIBPATTERN=`echo $GRIBFORM | sed s/CYC/$ACTUALCYC/g | sed s/MMM/$MMM/g | sed s/YMD/$ACTUALYMD/g`                      # first sub the actual model name and cycle into the remote file  name pattern

  echo "instance $instances starting cycle $ACTUALCYC for ymd $ACTUALYMD"  
  set tres=$tres1

  set newfmin=$fmin
  set newfmax=$fmax
  if ("$FHR" != "") then                                                # if an fhr is supplied by the user, set newfmin and newfmax to this fhr, or treat input as a range if there is a dash in between
        set newfmin=`echo "$FHR" | cut -f 1 -d \- | bc -l`              # If there is a dash set the first as newfmin  btw if a negative fmin is entered it will be rendered as a null using this cut command
        set newfmax=`echo "$FHR" | cut -f 2 -d \- | bc -l`              # and the second as newfmax  the bc -l converts any fhrs with leading zeroe to integers
	if ( ($newfmin > $newfmax && $newfmax != "") || $newfmin < $fmin || $newfmax > $fmax || $newfmin == "") then 
		echo "check your range of fhrs and reissue command - be sure they in order of least to greatest and equal to or between $fmin and $fmax"
		goto EXITING
	endif

	# for a given fhr or range of fhrs entered we must check if the limits entered fall on the sequence of available fhrs and the appropriate tres to begin at a corrected newfmin
	# AND while we are at it need to determine for the starting fhr entered 
	if ($newfmax == "") set newfmax=$newfmin

	set testfhr=0; set testtres=$tres1
	set adjfmin=$newfmin; set adjfmax=$newfmax
	while ($testfhr <= $newfmax)
		if ($testfhr <= $newfmin) set adjfmin=$testfhr  
		set adjfmax=$testfhr

		# Change temporal resolution -- based on model availablility
                if ($fres2 != "" && $tres2 != "" && $testfhr >= $fres2) set testtres=$tres2
                if ($fres3 != "" && $tres3 != "" && $testfhr >= $fres3) set testtres=$tres3
                if ($fres4 != "" && $tres4 != "" && $testfhr >= $fres4) set testtres=$tres4
                # Override the default temporal resolution change with that the user specified in the manual settings section
		if ("$RESCHANGELIST" != "") then
	                foreach RESCHANGE ($RESCHANGELIST)
        	                set tempfhr=`echo $RESCHANGE | cut -f 1 -d :`
                	        set tempres=`echo $RESCHANGE | cut -f 2 -d :`
                        	if ($tempfhr != "" && $tempres != "" && $testfhr >= $tempfhr) set testtres=$tempres
	                end
		endif
		if ($testfhr <= $newfmin) set lasttres=$testtres # keep this here, do not put this with the other if testfhr statement above, this if/then specifically needs to be AFTER the for RESCHANGE loop
		@ testfhr = $testfhr + $testtres
	end	

        echo input fmin $newfmin adjusted to $adjfmin
        echo input fmax $newfmax adjusted to $adjfmax
	echo assume current tres at fhr $adjfmin is $lasttres

	set newfmin=$adjfmin
	set newfmax=$adjfmax
	set tres=$lasttres

  endif
  set showtestoutput=n
  set testflag=""
  if ("$STN" != "") then
	  set showtestoutput=y # if a STN is input then output the wind gust calc info at the STN location
          set testflag="test" # this string is used to prepend the workdirs so you can run this script and not interfere with the script should it be running in cron
  endif
  ##############other settings and prepwork

  #### start char of a cut command to obtain the proper num of characters for the fhr -- its based on always formatting the fhr to 3 char with leading zeros using awk
  # then cutting the result of the awk down to the proper characters based on the  above setting $FHRCHARS
  # if $FHRCHARS = 3, the start char will be 1 (cut -c 1-3 for three characters) and if $FHRCHARS = 2 the start char is 2 (cut -c 2-3 for a two char fhr format)
  # It is done this way so it makes sense to the user entering the FHRCHARS setting
  @ startchar = 4 - $FHRCHARS
  set LEADZERO=""; if ($FHRCHARS == 2) set LEADZERO="0"; if ($FHRCHARS == 1) set LEADZERO="00" # this is so the locally stored grid has the proper format for the fhr
  
  ##### directory settings, some based on command line inputs, and house cleaning
  set GRIBDIR="$MDL/"`echo $GRIBDIRFORM|sed s/YMD/$ACTUALYMD/g|sed s/CYC/$ACTUALCYC/g`# local gribdir nomenclature
  mkdir -p $MODEL/grib/$GRIBDIR $MODEL/grid/$MDL                          # ensure grib and grid dirs exist to place retrieved data

  set DIR=$SCRIPTS/model                                          # home directory for all get model scripts -- be sure the script runs from its own dir (see next line)
  #######################main loop########################################################################################
  set fhr=$newfmin
  while ($fhr <= $newfmax)
	set FFF=`echo $fhr | awk '{printf "%03d\n", $0}' | cut -c ${startchar}-3` # format of fhr with leading zeroes

        set WORKDIR=${testflag}workdir${ACTUALCYC}z/f${FFF}             # A separate working directory is required per cyc per fhr to support simultaneous instances of this script running,
        mkdir -p $DIR/$MDL/$WORKDIR                                     # so ensure they exist
        cd $DIR/$MDL/$WORKDIR                                           # and change to the working directory to begin processing
        set DEBUGLOG=$DIR/$MDL/$WORKDIR/debug${ACTUALCYC}zf${FFF}.log   # if needed we can use this to debug code
        echo " " >> $DEBUGLOG
        echo "`date` - i $instances - debuglog now set to $DEBUGLOG" >> $DEBUGLOG
        echo "`date` - i $instances - debuglog now set to $DEBUGLOG"
        echo "`date` - i $instances - starting f$fhr for CYC $ACTUALCYC YMD $ACTUALYMD" >> $DEBUGLOG
        echo "`date` - i $instances - starting f$fhr for CYC $ACTUALCYC YMD $ACTUALYMD"

        ### status file testing -- contains the currently or last processed cycle and fhr (also contains a status of processing or completed for debugging) 
        #   Rules - if status file doesnt exist create one and begin processing.  If it exists but doesnt contain present cycle and fhr, update it and begin processing.  
        #   Otherwise assume no processing for fhr needed
        #   The status.file default contents are present YMD CYC fhr as 'processing' and gets updated with the word 'complete' if successfully completed (both prevent another instance from trying)
        #   but gets entirely deleted if the grib retrieval fails so another intance can give it a try
        if (-e status.file) then
                set STATUS=`cat status.file`
                if (`cat status.file | grep ${ACTUALYMD}${ACTUALCYC}f$FFF` != "") then
                        echo "`date` - i $instances - status.file shows  $STATUS  which means another instance is working on or completed this very cycle's fhr -- moving onto next fhr" >> $DEBUGLOG
                        echo "`date` - i $instances - status.file shows  $STATUS  which means another instance is working on or completed this very cycle's fhr -- moving onto next fhr"
                        goto NEXTFHR                    
                endif
                echo "`date` - i $instances - status.file shows  $STATUS  which isnt current so it will be reset and processing will begin" >> $DEBUGLOG
                echo "`date` - i $instances - status.file shows  $STATUS  which isnt current so it will be reset and processing will begin"
        else
                echo "`date` - i $instances - status.file does not exist so assume we should begin processing this cycle's fhr" >> $DEBUGLOG
                echo "`date` - i $instances - status.file does not exist so assume we should begin processing this cycle's fhr"
        endif   

        echo "`date` - i $instances processing ${ACTUALYMD}${ACTUALCYC}f$FFF" > status.file 
        echo "`date` - i $instances - status.file for ${ACTUALYMD}${ACTUALCYC}f$FFF created with a status of processing" >> $DEBUGLOG
        echo "`date` - i $instances - status.file for ${ACTUALYMD}${ACTUALCYC}f$FFF created with a status of processing"
        ############################### end status file stuff

	set GEMDATE=`echo $ACTUALYMD | cut -c 3-8`/${ACTUALCYC}00F${LEADZERO}${FFF} # need to do this here
	echo "`date` - i $instances - Instance $instances for CYC $ACTUALCYC YMD $ACTUALYMD processing f${LEADZERO}$FFF ................." >> $DEBUGLOG
	echo "`date` - i $instances - Instance $instances for CYC $ACTUALCYC YMD $ACTUALYMD processing f${LEADZERO}$FFF ................."

	set      GRIBFILE=`echo $GRIBFORM | sed s/MMM/$MMM/g | sed s/CYC/$ACTUALCYC/g | sed s/FF/$FFF/g | sed s/YMD/$ACTUALYMD/g` # nomenclature on remote server
	set LOCALGRIBFILE=`echo $GRIBFORM | sed s/MMM/$MDL/g | sed s/CYC/$ACTUALCYC/g | sed s/FF/$FFF/g | sed s/YMD/$ACTUALYMD/g` #nomenclature for local grib file

        set LOCALGRIDFILE=${MDL}_${ACTUALYMD}${ACTUALCYC}f${LEADZERO}${FFF} # file will be degribbed locally in this workdir first
	set GRIDFILE=$MODEL/grid/$MDL/$LOCALGRIDFILE # then moved here - this is done so that mulitple instances working in their own directories dont simultaneisoly overwrite file at the final destination

	# 1. RETRIEVE GRIB FILE
	# retrieve remote grib into a local working directory then move it to the $MODEL/grib dir so multiple instances of this script dont smash into each other
        # however if grib file exists, even partially, in its final resting place or any possible working directory, move on skipping the dgrib (assume being processed and degribbed by another instance or is already completed) 

        set retrieveit=yes # assume we need to retrieve it
        if (-e $MODEL/grib/${GRIBDIR}/${LOCALGRIBFILE} || -e $DIR/$MDL/$WORKDIR/${LOCALGRIBFILE}) set retrieveit=no  # if it exists in the $MODEL/grib or $WORKDIR dir assume it has been or is being retrieved already and dont retrieve it

        echo "`date` - i $instances - retrieveit $retrieveit and stn $STN and maxinstances $maxinstances" >> $DEBUGLOG
        echo "`date` - i $instances - retrieveit $retrieveit and stn $STN and maxinstances $maxinstances"
        if ($retrieveit == "no") then
                if ("$STN" == "") then # if stn is defined dont go to next fhr even if its been processed previously because the user is specifing a STN to test data at this fhr
                        echo "`date` - i $instances - grib file is being or already has been processed" >> $DEBUGLOG
                        echo "`date` - i $instances - grib file is being or already has been processed"
                        goto NEXTFHR
                endif
                echo "`date` - i $instances - a test location was supplied so assume grib file already has been processed" >> $DEBUGLOG
                echo "`date` - i $instances - a test location was supplied so assume grib file already has been processed"
        else
                # commence retreival process
                echo "`date` - i $instances - retrieval commencing for $LOCALGRIBFILE" >> $DEBUGLOG
                echo "`date` - i $instances - retrieval commencing for $LOCALGRIBFILE"

		set GRIBMAXATTEMPTS=3; set GRIBGETATTEMPT=0
GETGRIB:
	
		touch $GRIBFILE; /bin/rm $GRIBFILE
	        echo "`date` - i $instances - retrieval commencing of remote file $GRIBFILE to local file $LOCALGRIBFILE" >> $DEBUGLOG
                echo "`date` - i $instances - retrieval commencing of remote file $GRIBFILE to local file $LOCALGRIBFILE"
		sshpass -p "Wxltd4567;" sftp -P 2222 firstenergy@cftp.nssl.noaa.gov:/realtime/${GRIBFILE}
		# note with sftp and sshpass 
		# You need sshpass installed  the -p option allows the following command from sftp to accept the password in quotes
		# sftp needs -P 2222 to get through to the server cftp.nssl.noaa.gov (crush ftp server)
		# uname is ltdanon but they created firstenergy for just us 
		# If you get a hostkey error - just do the sftp -P 2222 ltdanon@cftp.nssl.noaa.gov:/realtime/   and enter the password after it prompts you, then it will write the fingerprint for you
		#  you will have to do this on all the machines

                touch $GRIBFILE
  		if (-z $GRIBFILE) then # if file is not on server or the server is unavailable, wget will still initially open a local file due to the -O argument (which will be zero bytes)
                	echo "`date` - i $instances - $GRIBFILE retrieved was zero bytes on try $GRIBGETATTEMPT of $GRIBMAXATTEMPTS" >> $DEBUGLOG
                        echo "`date` - i $instances - $GRIBFILE retrieved was zero bytes on try $GRIBGETATTEMPT of $GRIBMAXATTEMPTS"
                        @ GRIBGETATTEMPT += 1        
			if ($GRIBGETATTEMPT == $GRIBMAXATTEMPTS) then
	                       	echo "`date` - i $instances - $GRIBFILE retrieval attempts reached max number of tries (${GRIBMAXATTEMPTS}) so moving on" >> $DEBUGLOG
        	               	echo "`date` - i $instances - $GRIBFILE retrieved attempts reached max number of tries (${GRIBMAXATTEMPTS}) so moving on"
				if (-e status.file) /bin/rm -f status.file
				#goto NEXTFHR		
				goto NEXTCYC # we choose to go to next cycle just for this model to save nssl on the number of hits they get on their server 
			else
				goto GETGRIB
			endif
                else
			mv $GRIBFILE $LOCALGRIBFILE
		endif

                # if you get here a non-zero byte gribfile was retrieved so lets preserve the last round of the debug log which will get removed eventually by the scour routine in cron
                set DTE=`date +%Y%m%d"_"%H%M%S`
                mv $DEBUGLOG ${DEBUGLOG}.${DTE}
                echo "`date` - i $instances - moving debuglog to a prev version ${DEBUGLOG}.${DTE}" >> $DEBUGLOG
                echo "`date` - i $instances - moving debuglog to a prev version ${DEBUGLOG}.${DTE}"


                # now make sure the retrieved grib file is viable using the feature wgrib2 returns a "FATAL ERROR" message if the grib file is bad
                wgrib2 $LOCALGRIBFILE >& wgrib_f${fhr}.test; touch wgrib_f${fhr}.test
                if (`grep "FATAL" wgrib_f${fhr}.test` != "") then # the grib file is corrupt and we need to go re-retrieve it
	                /bin/rm wgrib_f${fhr}.test $LOCALGRIBFILE wget_f${fhr}.log
                        echo "`date` - i $instances - bad grib file detected for $LOCALGRIBFILE - it has been deleted and ending script to let next instance retry - moving on to next fhr"    >> $DEBUGLOG
                        echo "`date` - i $instances - bad grib file detected for $LOCALGRIBFILE - it has been deleted and ending script to let next instance retry - moving on to next fhr"
                        if (-e status.file) /bin/rm -f status.file
                        echo "`date` - i $instances - status.file for ${ACTUALYMD}${ACTUALCYC}f$FFF deleted to allow other instances a shot" >> $DEBUGLOG
                        echo "`date` - i $instances - status.file for ${ACTUALYMD}${ACTUALCYC}f$FFF deleted to allow other instances a shot"
                        goto NEXTFHR
                endif

                # if you get here you have a viable gribfile and can proceed with processing
                echo "`date` - i $instances - $LOCALGRIBFILE appears viable" >> $DEBUGLOG
                echo "`date` - i $instances - $LOCALGRIBFILE appears viable"

		echo "`date` - i $instances - proceeding with moving $LOCALGRIBFILE to $MODEL/grib/${GRIBDIR}" >> $DEBUGLOG
                echo "`date` - i $instances - proceeding with moving $LOCALGRIBFILE to $MODEL/grib/${GRIBDIR}"

                /bin/rm -rf wgrib_f${fhr}.test
		chmod 664 $LOCALGRIBFILE #### for some reason these are retreived as executables and that messes up our scour routine which ignores executables when purging
                mv $LOCALGRIBFILE $MODEL/grib/${GRIBDIR}
                if (-e $GRIDFILE) /bin/rm -rf $GRIDFILE # in case an old version of the GRID file exists blow it away
                goto GRIBAVAILABLE
	else
                #if you get here youve run out of retreval attempts and it means either the run for this fhr to fmax is not yet available on the server or there was a network or remote server problem
                # You either want to bail out of this cycle if the fhr in the loop is more than lastavailfhrsofar (the maxfhr avail so far on the remote server)
                # OR if the fhr in this  cycle is less than or equal to whats available on the remote server move onto the next FHR in the loop and let the next isntance of the script get this fhr
                # --- might want to delete this comment We do not want to move on to the next fhr because we need a contiguous run for ptype and wind scripts and will let subsequent launches of this script try again.

                if (-e status.file) /bin/rm -f status.file
                echo "`date` - i $instances - status.file for ${ACTUALYMD}${ACTUALCYC}f$FFF deleted to allow other instances a shot" >> $DEBUGLOG
                echo "`date` - i $instances - status.file for ${ACTUALYMD}${ACTUALCYC}f$FFF deleted to allow other instances a shot"                        
        endif

GRIBAVAILABLE:
        # 2. GRIB PROCESSING
        echo "`date` - i $instances - gribfile is available" >> $DEBUGLOG
        echo "`date` - i $instances - gribfile is available"

        # Create idx and pydx files
        echo "`date` - i $instances - creating wgrib idx and pygrib pydx files"
        echo "`date` - i $instances - creating wgrib idx and pygrib pydx files" >> $DEBUGLOG
        wgrib2 $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE > $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE.idx
        if (-e $UTILS/pydx) then
                pydx $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE > $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE.pydx
        else
                echo "`date` - i $instances - pydx script not found in $UTILS  so no pydx index file will be created" >> $DEBUGLOG
        endif

        # Process instantaneous gusts using python
        if ($fhr <= $flastgust && $retrieveit != "no") then
                echo "`date` - i $instances - creating gust grib pythonically" >> $DEBUGLOG
                echo "`date` - i $instances - creating gust grib pythonically"
                set GUSTINSTANT=$SCRIPTS/pycommon/gust_instant
                if (! -e $GUSTINSTANT) then
                        echo "`date` - i $instances - $GUSTINSTANT does not exist -- no processing of momentum xfer gusts will occur"  >> $DEBUGLOG
                        echo "`date` - i $instances - $GUSTINSTANT does not exist -- no processing of momentum xfer gusts will occur"
                else
                        echo "`date` - i $instances - running $GUSTINSTANT $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE" >> $DEBUGLOG
                        echo "`date` - i $instances - running $GUSTINSTANT $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE"
                        $GUSTINSTANT $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE >> $DEBUGLOG

                        set GUSTGRIB=$MODEL/grib/$GRIBDIR/${LOCALGRIBFILE}.momentumxfergusts
                        touch $GUSTGRIB; set gustmsg="created";  if (-z $GUSTGRIB) set gustmsg="failed to create"
                        echo "`date` - i $instances - $GUSTINSTANT $gustmsg $GUSTGRIB" >> $DEBUGLOG
                        echo "`date` - i $instances - $GUSTINSTANT $gustmsg $GUSTGRIB"

                        # make convective gusts too
                        set cnvmsg=""; if ("$gustmsg" != "created") set cnvmsg="not "
                        echo "`date` - i $instances - ${cnvmsg}running makecnvgusts $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE" >> $DEBUGLOG
                        echo "`date` - i $instances - ${cnvmsg}running makecnvgusts $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE"
                        if ("$cnvmsg" == "") then
                                makecnvgusts $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE >> $DEBUGLOG
                        endif
                        set CNVGUSTGRIB=$MODEL/grib/$GRIBDIR/${LOCALGRIBFILE}.convectivegusts
                        touch $CNVGUSTGRIB; set gustmsg="created"; if (-z $CNVGUSTGRIB) set gustmsg="failed to create"
                        echo "`date` - i $instances - makecnvgusts $gustmsg $CNVGUSTGRIB" >> $DEBUGLOG
                        echo "`date` - i $instances - makecnfgusts $gustmsg $CNVGUSTGRIB"

                endif
        else
                echo "`date` - i $instances - skipping creating gust grib pythonically since fhr $fhr is > fhr for last gust processing $flastgust or retrieveit=no implying already processed" >> $DEBUGLOG
                echo "`date` - i $instances - skipping creating gust grib pythonically since fhr $fhr is > fhr for last gust processing $flastgust or retreiveit=no implying already processed"
        endif

        # lets submit it to EDEX 
        if (! -e /awips2/edex) then
                echo "`date` - i $instances - /awips2/edex/ does not exist -- it appears AWIPS2 is not installed on this system so $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE will not be submitted to EDEX" >> $DEBUGLOG
                echo "`date` - i $instances - /awips2/edex/ does not exist -- it appears AWIPS2 is not installed on this system so $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE will not be submitted to EDEX"
        else
               if ($retrieveit != "no") then
                        if (`edex status | grep EDEXingest | awk -F "::" '{print $2}' | sed 's/ //g'` == "running") then
                                if (-e $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE) then
                                        if (-z $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE) then
                                                echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE is zero bytes -- not submitted to EDEX" >> $DEBUGLOG
                                                echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE is zero bytes -- not submitted to EDEX"
                                        else
                                                mdl2edex $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE >> $DEBUGLOG
                                                echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE submitted to EDEX" >> $DEBUGLOG
                                                echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE submitted to EDEX"
                                        endif
                                else
                                        echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE does not exist -- not submitted to EDEX" >> $DEBUGLOG
                                        echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE does not exist -- not submitted to EDEX"
                                endif
                        else
                                echo "`date` - i $instances - edex status shows EDEXingest isn't running - no submission to EDEX will occur" >> $DEBUGLOG
                                echo "`date` - i $instances - edex status shows EDEXingest isn't running - no submission to EDEX will occur"
                        endif
                else
                        echo "`date` - i $instances - assumed $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE previously submitted to EDEX - not resubmitting" >> $DEBUGLOG
                        echo "`date` - i $instances - assumed $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE previously submitted to EDEX - not resubmitting"
                endif
        endif

        # NAWIPS Processing
        if (! -e $GRIDFILE) then
                echo "`date` - i $instances - degribbing to gridfile" >> $DEBUGLOG
                echo "`date` - i $instances - degribbing to gridfile"
                set DEGRIBATTEMPT=0; set MAXDEGRIBATTEMPTS=3
DEGRIB:
                @ DEGRIBATTEMPT ++
                touch $LOCALGRIDFILE $DIR/$MDL/$WORKDIR/dcgrib2_f${fhr}.log; /bin/rm $LOCALGRIDFILE $DIR/$MDL/$WORKDIR/dcgrib2_f${fhr}.log
                if (! -e $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE) then
                        echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE does not exist -- no degribbing will occur" >> $DEBUGLOG
                        echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE does not exist -- no degribbing will occur"
                else
                        if (-z $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE) then
                                echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE is zero bytes -- no degribbing will occur" >> $DEBUGLOG
                                echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE is zero bytes -- no degribbing will occur"
                        else
                                echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE degrib commencing" >> $DEBUGLOG
                                echo "`date` - i $instances - $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE degrib commencing"
                                dcgrib2 -d $DIR/$MDL/$WORKDIR/dcgrib2_f${fhr}.log $LOCALGRIDFILE < $MODEL/grib/$GRIBDIR/$LOCALGRIBFILE >& dcgrib2command_f${fhr}.out
                        endif
                endif

		touch $LOCALGRIDFILE
                if (-z $LOCALGRIDFILE) then
                        if ($DEGRIBATTEMPT < $MAXDEGRIBATTEMPTS) then
                                goto DEGRIB
                        else
                                # if you get here degrib failed (you somehow have a zero byte $LOCALGRIDFILE and your out of tries to attempt to degrib it)
                                # it may be you have to delete the $LOCALGRIBFILE and go to the next cycle so a subsequent instance of this script will reget it
                                echo "`date` - i $instances - failed to degrib $MODEL/grib/${GRIBDIR}/${LOCALGRIBFILE} - moving to next FHR which may impact ptype and wind scripts but allow rest of model to be processed" >> $DEBUGLOG
                                echo "`date` - i $instances - failed to degrib $MODEL/grib/${GRIBDIR}/${LOCALGRIBFILE} - moving to next FHR which may impact ptype and wind scripts but allow rest of model to be processed"
                                /bin/rm $LOCALGRIDFILE
                                goto NEXTFHR
                        endif
                else
                        # if you get here all is well
                        mv $LOCALGRIDFILE $GRIDFILE
                        # cant launch ptype scripts until all grid files in from start of run through $flastptype - no quick way to check this given a later fhr may arrive sooner than an earlier fhr
                        set testfhr=1; set testres=1; set allpresent=1
                        while ($testfhr <= $flastptype && $allpresent == 1)
                                set TESTFFF=`echo $testfhr | awk '{printf "%03d\n", $0}'`
                                set TESTGRIDFILE=$MODEL/grid/$MDL/${MDL}_${ACTUALYMD}${ACTUALCYC}f${TESTFFF}
                                if ($testfhr == "$fres1" && "$fres1" != "") set testres=$tres1
                                if ($testfhr == "$fres2" && "$fres2" != "") set testres=$tres2
                                if ($testfhr == "$fres3" && "$fres3" != "") set testres=$tres3
                                if ($testfhr == "$fres4" && "$fres4" != "") set testres=$tres4
                                # Override the default temporal resolution change with that the user specified in the manual settings section
                                if ("$RESCHANGELIST" != "") then
                                       foreach RESCHANGE ($RESCHANGELIST)
                                                set temptestfhr=`echo $RESCHANGE | cut -f 1 -d :`
                                                set temptestres=`echo $RESCHANGE | cut -f 2 -d :`
                                                if ($temptestfhr != "" && $temptestres != "" && $testfhr >= $temptestfhr) set testres=$temptestres
                                        end
                                endif

                                if (! -e $TESTGRIDFILE) set allpresent=0
                                echo $testfhr $testres $flastptype $TESTGRIDFILE presentflag $allpresent >> $DEBUGLOG
                                echo $testfhr $testres $flastptype $TESTGRIDFILE presentflag $allpresent
                                @ testfhr = $testfhr + $testres
                        end
                        if ($allpresent == 1) then # we can run ptype scripts
                                if (-e $DIR/$MDL/ptype_${MDL} && `ps -ef | grep "ptype_${MDL} $ACTUALCYC $ACTUALYMD" | grep -v grep` == "") then
                                        $DIR/$MDL/ptype_${MDL} $ACTUALCYC $ACTUALYMD >& $DIR/$MDL/ptype_launch_${ACTUALCYC}z.log &
                                        echo "`date` - i $instances - $DIR/$MDL/ptype_${MDL} $ACTUALCYC $ACTUALYMD launched by instance $instances into the background" >> $DEBUGLOG
                                        echo "`date` - i $instances - $DIR/$MDL/ptype_${MDL} $ACTUALCYC $ACTUALYMD launched by instance $instances into the background"
                                else
                                        echo "`date` - i $instances - ptype not launched $DIR/$MDL/ptype_${MDL} either script doesnt exist or another instance of ptype_${MDL} $ACTUALCYC $ACTUALYMD still running" >> $DEBUGLOG
                                        echo "`date` - i $instances - ptype not launched $DIR/$MDL/ptype_${MDL} either script doesnt exist or another instance of ptype_${MDL} $ACTUALCYC $ACTUALYMD still running"
                                        ps -ef | grep ptype_${MDL} | grep -v grep >> $DEBUGLOG
                                endif
                        else
                                        echo "`date` - i $instances - $DIR/$MDL/ptype_${MDL} $ACTUALCYC $ACTUALYMD not launched - needed grid files through fhr $flastptype not in yet" >> $DEBUGLOG
                                        echo "`date` - i $instances - $DIR/$MDL/ptype_${MDL} $ACTUALCYC $ACTUALYMD not launched - needed grid files through fhr $flastptype not in yet"
                        endif
                
		endif
        endif

        echo "`date` - i $instances - gridfile is available" >> $DEBUGLOG
        echo "`date` - i $instances - gridfile is available"
       
	goto SKIPGUST 
	if ($fhr > $flastgust) then
                echo "`date` - i $instances - skipping wind gust calcs because fhr $fhr is past the f$flastgust limit set in the script" >> $DEBUGLOG
                echo "`date` - i $instances - skipping wind gust calcs because fhr $fhr is past the f$flastgust limit set in the script"
                goto SKIPGUST
        endif

	#3. #############################################################################################
	# post process wind
	# Approach - from the ground up to 700 find level where lapserate first meets "stable" criteria
	# The pressure at that level is called pgst (pressure gust level).
	# Maxwind from pgst to ground is your raw max gust potential (maxw)
	# Average wind from pgst to ground is your average wind gust (avgw)
	# The maxw and avgw are then further modified based on the offset between sfc wind angle
	# So that gstf is now the frequent gusts and gstx is the max gust possible
	# Note when the stablity first meets the criteria as stable, pgst is set to the level serving as
	# the lowest layer in the stability analysis when the stability exceeds the stability percentage threshold
	# CAUTION - the true pressue at the ground is your starting pressure level -- all model levels HIGHER than this are ignored becuase they are below ground
	# and likewise the stability at the first model pressure level above the surface has to be calculated using the dhght and dtemp between the ground and that first plvl abv ground
	# The gfunc hght holds the height off the ground above sea level for any level in the model - even at the surface.  This is handy to help calc stability
	# of the surface-to-first-model-level-above-ground layer as the deltaZ is simply sub(hght@<level>%pres,hght@0%none)  and detlta T is sub (tmpc@<level>%pres,tmpc@0%none)
	# The quotient of these two is the stability --   gfunc=(sub(tmpc@<level>%pres,tmpc@0%none),sub(hght@<level>%pres,hght@0%none)  where <level> is the first model level above the true surface

                
     	# initialize grid fields
	#	set pgst (presure gust level) to the true pressure at ground (pres@0%none)
     	# 	set nlvls to 1 number of levels from and inclduing both pressure at ground (pres@0%none) to pgst for calc of avgs
     	# 	set flag to 0  indicates if stability threshold has been met
	# 	set maxw to surface wind speed 
	#	set sumw to surface wind speed (holds the sum of the wind speeds in the levels from and including the ground to and including pgst)
	# 	set dirmax to the direction of the surface wind (this will hold the direction of the maxw)
	#	set dirsum to the direction of the surface wind (this will sum the directions through the layer incluidng sfc wind and up to and including pgst)
	#	set sf speedflag to 0 for when the speed at a model pressure level is greater than the max so far in the layer we are assessing -- used because GEMAK has char limits in input and this is a space saver
	#	set pf pflag to 0 indicates when the model pressure level we are looping through is greater than the surface pressure- instances when psfc = say 986 mb and lowest model level is 1000mb, we want to ignore 1000mb

        echo "`date` - i $instances - starting gust calcs" >> $DEBUGLOG
        echo "`date` - i $instances - starting gust calcs"
     	gddiag << ENDGD0 > gdinit.out
     	  gdfile=${GRIDFILE}
          gdoutf=${GRIDFILE}
          gdattim=f$FFF
          grdtyp=s
          gpack=
          grdhdr=
          proj=
          grdarea=
          kxky=
          maxgrd=5000
          cpyfil=
          anlyss=
	  glevel = 0
	  gvcord = none
          gfunc=pres@0%none^${GEMDATE}
          grdnam=pgst@0%none^${GEMDATE}
	  l

          r
          
          gfunc=1
	  grdnam=nlvls@0%none^${GEMDATE}
	  l

          r
			
	  gfunc=0
	  grdnam=flag@0%none^${GEMDATE}
	  l

          r


          grdnam=pf@0%none^${GEMDATE}
          l
		    
          r

          grdnam=sf@0%none^${GEMDATE}
	  l

	  r

	  gfunc=sped@10%hght
	  grdnam=maxw@0%none^${GEMDATE}
	  l

	  r

	  grdnam=sumw@0%none^${GEMDATE}
	  l

	  r

	  gfunc=dirn(wind@10%hght)
	  grdnam=dirmax@0%none^${GEMDATE}
	  l

	  r

	  grdnam=dirsum@0%none^${GEMDATE}
	  l

	  r

	  gfunc=sin(mul(dtr,dirn(wind@10%hght)))
	  grdnam=sindirsum@0%none^${GEMDATE}
	  l

	  r

	  gfunc=cos(mul(dtr,dirn(wind@10%hght)))
	  grdnam=cosdirsum@0%none^${GEMDATE}
	  l

	  r

	  gfunc=0
	  glevel=0
	  gvcord=none
	  grdnam=dtmp@0%none^${GEMDATE}
	  l

	  r

	  grdnam=dhgt@0%none^${GEMDATE}
	  l

	  r

	  grdnam=sfcstab@0%none^${GEMDATE}
	  grdnam=invsfcstab@0%none^${GEMDATE}
	  l

	  r

          exit

ENDGD0
	# End initializing grid fields

	# output initialized values just initialized at a STN (input by user), skip output if no STN supplied
        if ($showtestoutput == n) goto SKIPTEST0
        touch gpinit.out; /bin/rm gpinit.out
	gdpoint << ENDGP1 > gpinit.out
	        GDATTIM  = f${fhr}
                GDFILE   = ${GRIDFILE}
                GLEVEL   = 0
                GPOINT   = $STN
                GVCORD   = none
                SCALE    = 0
                gfunc    = pres
                r

		glevel  = 10
		gvcord  = hght
                gfunc   = dirn(wnd)
                r

                gfunc   =sped
                r

	        glevel  =0
                gvcord  =none
                gfunc   =pgst
          	r

		gfunc  =hght
		r

		gfunc =tmpc
		r

          	gfunc=nlvls
	        r

          	gfunc=flag
          	r

          	gfunc=maxw
		r

	        gfunc=sumw
          	r

	        gfunc=dirmax
          	r

                gfunc=dirsum
          	r

		gfunc=pf
		r

		gfunc=sf
                r

		gfunc=sindirsum
		r

		gfunc=cosdirsum
		r

                gfunc=dtmp
		r

		gfunc=dhgt
		r

		gfunc=sfcstab
		gfunc=invsfcstab
		r


                exit

ENDGP1
        set  PSFC=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 1p`
        set DDSFC=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 2p`
        set  WSFC=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 3p`
	set  PGST=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 4p`
	set SFHGT=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 5p`
        set SFTMP=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 6p`
	set  NLVL=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 7p`
	set  FLAG=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 8p`
	set  MAXW=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 9p`
	set  SUMW=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 10p`
	set  DMAX=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 11p`
	set  DSUM=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 12p`
	set    PF=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 13p`
	set    SF=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 14p`
	set SDSUM=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 15p`
	set CDSUM=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 16p`
	set  DTMP=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 17p`
	set  DHGT=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 18p`
	set SSTAB=`cat gpinit.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 19p`

        echo " "
	echo "Test of $MDL $YMD ${CYC}z f${FHR} at $STN with stability flag set to ${percentage}% of -6.5 deg C/km or $st deg C/km (stbv >= $st for flag to be set to 1 ==> inversion exists).    Speeds in m/s"
	echo "Note - stbv is gempak stab fn for plo to pup EXCEPT for first mdl level abv (less than) sfc p in where it is manually calcd using deltatmpC deltahghtm btwn sfc and that first mdl lvl"
	echo "       and when this is first encountered going up from the ground (where model p is first less than sfc p) the invsfcstab (inverted sfc stability.. that is.. just 1 div by the sfc stab)"
	echo "       is reinverted and will be what you see in the stbv column.  See comments above gddiag sections of code that explain why we needed to use the inverted form of stab -- calc error in gempak"
	echo "       Also the inverted method runs into problems when dt is close to zero -- when this is the case the invsfcstab approaches infinity and is rendered as a missing value.  "
	echo "       All missing values in the stbv calc are then assumed to be a cause of this and thus forced with a value of about 2 hundredths less than the threshold needed to pass the test ($st - .02)"
	echo "      "
	echo "p    plo  pup    hgt      tmpc     stbv   flag     nlvls    pgst         dir     sped    dirmax   spedmax   sumdir   sumsped  pf(p<psfc) sf(sped>max) sindirsum cosdirsum  dtmp(C)   dhgt(m)  invsfcstabkm/C"
	echo "sfc  $PSFC $SFHGT $SFTMP  na      $FLAG $NLVL $PGST $DDSFC $WSFC $DMAX $SUMW $DSUM $SUMW   $PF     $SF    $SDSUM   $CDSUM   $DTMP   $DHGT  $SSTAB"

SKIPTEST0:
        # Stablity interrogation
        # At each model's isobaric level calc the stability between that level and the layer immediately above it.
        # If the stability is greather than the threshold, the bottom of the layer being evaluted is considered
        # where the inversion begins and becomes the level from there to the ground where gusts will be evaluated
        # The first layer's (the layer from the ground to first model level that has a p less than sfc p)
        # stability is not just a standard calculation via stbv GEMPAK function.  It must be
        # calculated manually because the sfc pressure rarely sits at a model level. And sometimes is above standard
        # model levels (example sfc p 922 is above 1000 950 and 925 mb.  The next model level that should be used
	# in the stab calc is 900 mb -- but the hght and tmpc at the sfc (922 mb) must be obtained from hght@0%none 
	# tmpc@0%none.  These can be used with the same from 900 mb -- the next model layer above the sfc --
	# to calc stability of the first layer.
	# See the comments int he GEMPAK code for what we are doing

        echo "`date` - i $instances - begin stability interrogation" >> $DEBUGLOG
        echo "`date` - i $instances - begin stability interrogation"
	set resp=$resp1 # initially our vertical resolution will be resp1, when we hit lvlresp2 we will use resp2
	set p=$pmax
	while ($p >= $pmin)
		@ plwr = $p
		@ pupr = $p - $resp1; if ($p <= $lvlresp2) @ pupr = $p - $resp2
                if ($STN == "") then
                        echo "`date` - i $instances - $p $pmin" >> $DEBUGLOG
                        echo "`date` - i $instances - $p $pmin"
                endif
	        gddiag << ENDGD1 > gdpass1.out
			GDFILE   = ${GRIDFILE}
			GDOUTF   = ${GRIDFILE}
			gfunc    = stab
			GDATTIM  = f$FFF
			GLEVEL   = ${pupr}:${plwr}
			GVCORD   = PRES
			GRDNAM   = stbv@${p}%pres^${GEMDATE}
			GRDTYP   = S
			GPACK    =  
			GRDHDR   =  
			PROJ     =  
			GRDAREA  =  
			KXKY     =  
			MAXGRD   = 5000
			CPYFIL   = 
			ANLYSS   =  
			l

			r

                        ! WARNING - order of these grid calcs are extremely important as subsequent grids rely on the previous
		        !
			! stab of sfc to present plevel - warning for whatever reason the gempak gddiag is not calculating stab (dTemp/dHeight) properly using the following
			! gfunc=quo(sub(tmpc@$p%pres,tmpc),quo(sub(hght@$p%pres,hght),1000))   it gives bad results -- even without the quo(,1000).  Not sure why but it seems 
			! the smaller the denominator the less accurate the results of the gfunc.  
			! Workaround was to store the numerator and denominator separately then combine them inverted in a different gridname.  then put this inverted form under one in the final gfunc.
			! Its hokey but it gave the most accurate result by far.   
			glevel=0
			gvcord=none
			grdnam=dtmp@0%none^${GEMDATE}
			gfunc=sub(tmpc@${p}%pres,tmpc@0%none)
			l
			
			r

                        grdnam=dhgt@0%none^${GEMDATE}
			gfunc=sub(hght@${p}%pres,hght@0%none)
			l

			r

			! calling this the inverted surface stability - see comments above as to why we did it this way.  Also guard against situations when abs val of dtmp is small or zero
			! because the invstab will be infinity -- this seems to only be happening when the sfc p is very close to the model level p. Like Psfc=1000.3mb and pmdl=1000mb.  In essense wed
			! like to just ignore this situation and keep assessing.  So in this situation sset the inv sfc stab to  1/(-.02+theshold) so when its inverted it will barely pass the flag test
			! you will recognize the this occurred when stbv = is about 2 hundredths less than the threshold needed to pass the test
			grdnam=sfcstab@0%none^${GEMDATE}
			gfunc=quo(dtmp@0%none,quo(dhgt@0%none,1000))
                        grdnam=invsfcstab@0%none^${GEMDATE}
			gfunc=miss(quo(quo(dhgt,dtmp),1000),quo(1,add(-.02,$st)))
			l

			r

			! only once replace the stability at the present mdl lyr (and the lyr abv) with that calcd btwn the sfc and this mdl lyr when the p of the present mdl lyr first becomes < sfc p
			! so this will be done only when pmodel layer is < psfc and pflag is still zero  
			grdnam=stbv@${p}%pres^${GEMDATE}
                        gfunc=add(mul(stbv@${p}%pres,or(ge($p,pres),ge(pf,1))),mul(and(lt($p,pres),lt(pf,1)),sfcstab))
			gfunc=add(mul(stbv@${p}%pres,or(ge($p,pres),ge(pf,1))),mul(and(lt($p,pres),lt(pf,1)),quo(1,invsfcstab)))
			l

			r
			
			! set pf -- p-flag.. set to 1 when  model level p <= surface pressure; 0 otherwise (used as a shortcut otrwise gfuncs exceed GEMPAK char limit)
			glevel=0
			gvcord=none
			gfunc=le($p,pres@0%none)
			grdnam=pf@0%none^${GEMDATE}
			l

			r

			! set sf - speed flag  1 if sped at a given level is > than max in the layer, 0 otherwise (needed as a shortcut otrwise gfuncs exceed GEMPAK char limit)
			gfunc=gt(sped@$p%pres,maxw@0%none)
			grdnam=sf@0%none^${GEMDATE}
			l

			r

			! set pgust - remains its initialized value but will change to the present value of p level in the loop only if both flag =0 and p level of the model < = sfc pressure  
			gfunc    = add(mul(pgst,not(mul($p,and(pf,lt(flag,1))))),mul($p,and(pf,lt(flag,1))))
			grdnam   = pgst@0%none^${GEMDATE}
			l

			r

			! set nlvls - increase by one only if both flag is 0 and pressure level in loop <= surface pressure
			gfunc    = add(nlvls,and(lt(flag,1),pf))
			grdnam   = nlvls@0%none^${GEMDATE}
			l

			r

			! set dirmax -- dir at the the level the speed is at a maximum between sfc and gust level.  MUST do this before setting maxw
			! THIS IS NOT THE MAXIMUM OF THE COMPASS POINTS - Rather it is the direction where the SPEED is a maximum in the layer.
			! remains at its initialized value.  updated only to the dir at the present p level if  flag =0, p lvl <= sfc pres, speed is a max
			! remember sf = a binary flag where 1 means sped at curr pres level is gt max tracked so far and pf = binary where 1 means p is <= surface pressure
                        gfunc= add(mul(dirmax,not(mul(dirn(wind@$p%pres),and(sf,and(lt(flag,1),pf)))),mul(dirn(wind@$p%pres),and(sf,and(lt(flag,1),pf)))))
			grdnam = dirmax@0%none^${GEMDATE}
			l

			r

			! set max wind - if flag still 0 set max to current levels speed if speed > max, otherwise keep old max
			gfunc = add(mul(maxw,not(and(pf,and(sf,lt(flag,1))))),mul(sped@$p%pres,and(pf,and(sf,lt(flag,1)))))
			grdnam = maxw@0%none^${GEMDATE}
			l

			r

			! until flag is set to 1, add to sum of speeds if pgst> p (pf =1)
			gfunc= add(sumw,mul(sped@$p%pres,and(lt(flag,1),pf)))
			grdnam=sumw@0%none^${GEMDATE}
			l

			r

			! ditto of sum dirs
			gfunc=add(dirsum,mul(dirn(wind@$p%pres),and(lt(flag,1),pf)))
			grdnam=dirsum@0%none^${GEMDATE}
			l

			r

			! sum of the sin dirs
			gfunc=add(sindirsum,mul(   sin(mul(dtr,dirn(wind@$p%pres)))  ,and(lt(flag,1),pf)))
			grdnam=sindirsum@0%none^${GEMDATE}
			l

			r

			! sum of the cos dirs
			gfunc=add(cosdirsum,mul(   cos(mul(dtr,dirn(wind@$p%pres)))  ,and(lt(flag,1),pf)))
			grdnam=cosdirsum@0%none^${GEMDATE}
			l

			r

			! set flag -- do this last. if flag already 1 keep it at 1 or set flag to 1 when it is zero and the stab threshold met 
			gfunc    = or(ge(flag,1),and(pf,ge(stbv@$p%pres,$st)))
			grdnam   = flag@0%none^${GEMDATE}
			l

			r

			exit

ENDGD1

		# output calculated values at a STN (input by user), skip if no STN supplied
		if ($showtestoutput == n) goto SKIPTEST1
		touch gppass1.out; /bin/rm gppass1.out
		gdpoint << ENDGP2 > gppass1.out
			GDATTIM  = f${fhr}
			GDFILE   = ${GRIDFILE}
			GLEVEL   = $p
			GPOINT   = $STN
			GVCORD   = pres
			SCALE    = 0
			gfunc    = hght
			r				
				
			gfunc    = tmpc
			r

			GFUNC    = stbv
			SCALE    = 0
			r

			gfunc    = flag@0%none
			r
                    
			gfunc    = nlvls@0%none
			r

			gfunc    = pgst@0%none
			r

			gfunc   = dirn(wnd)
			r

			gfunc   =sped
			r
                                
			gfunc   = dirmax@0%none
			r

			gfunc   = maxw@0%none
			r

			gfunc   = dirsum@0%none
			r

			gfunc   = sumw@0%none
			r

			gfunc   = pf@0%none
			r

			gfunc   = sf@0%none
			r

			gfunc   = sindirsum@0%none
			r

			gfunc   = cosdirsum@0%none
			r
                        
			gfunc   = dtmp@0%none
			r

                        gfunc   = dhgt@0%none
			r

			gfunc   = sfcstab@0%none
			gfunc   = invsfcstab@0%none
			r

			exit

ENDGP2
		set HGHT=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 1p`
		set TMPC=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 2p`
		set STBV=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 3p`
		set FLAG=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 4p`
		set NLVL=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 5p`
		set pgst=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 6p`
		set DIRN=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 7p`
		set SPED=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 8p`
		set DMAX=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 9p`
		set WMAX=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 10p`
		set DSUM=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 11p`
		set WSUM=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 12p`
		set   PF=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 13p`
		set   SF=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 14p`
                set SIND=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 15p`
                set COSD=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 16p`
	        set DTMP=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 17p`
        	set DHGT=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 18p`
	        set SSTB=`cat gppass1.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 19p`
		
                
		if ($p == 1000) echo  "$p $plwr $pupr $HGHT  $TMPC $STBV $FLAG $NLVL $pgst $DIRN $SPED $DMAX $WMAX $DSUM $WSUM   $PF     $SF    $SIND   $COSD   $DTMP   $DHGT  $SSTB"
		if ($p != 1000) echo " $p  $plwr $pupr $HGHT $TMPC $STBV $FLAG $NLVL $pgst $DIRN $SPED $DMAX $WMAX $DSUM $WSUM   $PF     $SF    $SIND   $COSD   $DTMP   $DHGT  $SSTB"
SKIPTEST1:


NEXTP:
                set resp=$resp1; if ($p <= $lvlresp2) set resp=$resp2
                @ p = $p - $resp
        end

	# finally fine tune the speed of the max gust and average based on the offset of the wind angle of each relative to the 10m wind
        echo "`date` - i $instances - finalizing gusts" >> $DEBUGLOG
        echo "`date` - i $instances - finalizing gusts"
	gddiag << ENDGD2 > gdfinalize.out
		GDFILE   = ${GRIDFILE}
		GDOUTF   = ${GRIDFILE}
		GDATTIM  = f$FFF
		GRDTYP   = S
		GPACK    =  
		GRDHDR   =  
		PROJ     =  
		GRDAREA  =  
	        KXKY     =  
		MAXGRD   = 5000
		CPYFIL   = 
		ANLYSS   =  

		! calc averages then further adjust by offset of wind angle between sfc and layermax or avg

		! first call the direction of the max speed in the level "dmxg" 
		glevel   = 0
		gvcord   = none
		gfunc    = dirmax 
		grdnam   = dmxg@0%none^${GEMDATE}
		l

		r

		! calc avg direction (davg) -- cant do it using compass points because an average of directions 330 and 30 is not 180, but is 0 or 360
		! The atn2 function in GEMPAK has a bug - with small S1 and S2 values it just gives the value of atan instead of the atan2 calculation
		! For proof In gdpoint try gfunc=atn2(.01192,.78305) and instead of 1.555 you will get .012 or the same value of gfunc=atan(quo(.01192,.78305))
		! So we must use atan.  To convert the results of atan to met degrees you need to look at the sign of a given sindirsum and cosdirsum pair
		!
		! A +,+ pair indicates the first quadrant on the meteorological compass (0-90 degrees).  The results of ATAN(quo(quo(sindirsum,nlvls),quo(cosdirsum,nlvls)))*PI/180 are positive and can be used "as is"
		! A +,- pair indicates the second quadrant on the meteorological compass (90-180 degrees).  The results of ATAN(quo(quo(sindirsum,nlvls),quo(cosdirsum,nlvls)))*PI/180 are negative and need to be added by 180 for use.
		! A -,- pair indicates the third quadrant on the meteorological compass (180-270 degrees).  The results of ATAN(quo(quo(sindirsum,nlvls),quo(cosdirsum,nlvls)))*PI/180 are positive and need to be added by 180 for use.
		! A -,+ pair indicates the fourth quadrant on the meteorological compass (270-360 degrees).  The results of ATAN(quo(quo(sindirsum,nlvls),quo(cosdirsum,nlvls)))*PI/180 are negative and need to be added by 360 for use.
		! 
		! Bottom line is  add at least 180 when sindirsum and cosdirsum are both not +.   Then tack on an additional 180 when sindirsum is neg and cosdirsum is pos
		! 
		! Calc the average direction using atan -- note RTD is the radians-to-degrees constant in GEMPAK.  Also note that we need to use the average the sines an cosines which is why you see quo(sindirsum,nlvls) and its cos pair
		gfunc    = mul(rtd,atan(quo(quo(sindirsum,nlvls),quo(cosdirsum,nlvls))))
		grdnam   = davg@0%none^${GEMDATE}   
		l

		r

		! add 180 to davg only if sindirsum and condirsum are both not positive 
		gfunc    = add(davg,mul(180,not(and(ge(sindirsum,0),ge(cosdirsum,0)))))
		grdnam   = davg@0%none^${GEMDATE}
		l

		r

		! now tack on another 180 only if sinddirsum is - and cosdirsum is +
                gfunc    = add(davg,mul(180,and(lt(sindirsum,0),ge(cosdirsum,0))))
		grdnam   = davg@0%none^${GEMDATE}
		l

		r
	
                ! use the abs val of the difference between the angles of the layr avg dir and sfc dir to further modulate the max gust magnitude.  The difference between the angles will be no more than 180 deg.
		! This means if you have a difference that is greater than 180 subtract it from 360. Example 330 and 10  difference is 320.  Subtract 360 and abs value is 40
		! The delta bewtween the mag of the sfc wind and the max wind will be multipled by (1 - anglediff/180).  Such that if the angle diff is 180 you get no gust contribution at the surface.
		! Because the method for finding the max wind works from ground up - if the sfc happens to have the highest wind, this method just sets it to the surface wind too.
		! NOTE we are using the layr avg dir because it seems a more meaningful modulator vs say the dir at the max wind speed.  Its the CYS principle - best gusts when all winds aloft algin with sfc
		!
		! Step 1 calc the abs value of the difference in the angle between the layer avg dir and the surface and set it to a value between 0 and 180
		gfunc = abs(sub(davg,dirn(wnd@10%hght)))
		grdnam = angle@0%none^${GEMDATE}
		l

		r


		! if that angle is more than 180 subtract it from 360
		gfunc = add(mul(le(angle,180),angle),mul(gt(angle,180),sub(360,angle)))
		grdnam = angle@0%none^${GEMDATE}
		l

		r

		! use that angle ratio relative to 180 to modulate max gust
		gfunc    = add(mul(abs(sub(maxw,sped@10%hght)),sub(1,quo(angle,180))),sped@10%hght)
		!gfunc    = abs(sub(gstx,sped@10%hght))
		grdnam   = gstx@0%none^${GEMDATE}
		l

		r

                ! convert any missing gstx data to sfc wind
                gfunc = miss(gstx@0%none^${GEMDATE},sped@10%hght)
                grdnam = gstx@0%none^${GEMDATE}
                l

                r

                ! use that angle ratio relative to 180 to modulate frequent gust -- but in this case need to add the result to the smaller of the two (sfc wind or lyr avg) as sometimes sfc wind is the max in the lyr
                gfunc    = add(mul(abs(sub(quo(sumw,nlvls),sped@10%hght)),sub(1,quo(angle,180))),sped@10%hght)
		gfunc    = add(mul(abs(sub(quo(sumw,nlvls),sped@10%hght)),sub(1,quo(angle,180))),smin(sped@10%hght,quo(sumw,nlvls)))
                grdnam   = gstf@0%none^${GEMDATE}
                l

                r

                ! convert any missing gstf data to sfc wind
                gfunc = miss(gstf@0%none^${GEMDATE},sped@10%hght)
                grdnam = gstf@0%none^${GEMDATE}
                l

                r

                ! man due to GEMPAK goofiness sometimes gstx < gstf, make sure they are at least equal in this situation
                gfunc = smax(gstf@0%none^${GEMDATE},gstx@0%none^${GEMDATE})
                grdnam = gstx@0%none^${GEMDATE}
                l

                r

		!create masks of gstf when sfc wind >= 16 mph (7.143 m/s)
		gfunc    =mul(gstf@0%none^$GEMDATE,ge(sped@10%hght^$GEMDATE,7.143))
                grdnam   =gstfm16@0%none^${GEMDATE}
		l
			
		r

                ! create masks of gstx when sfc wind >= 16 mph (7.143 m/s)
                gfunc    =mul(gstx@0%none^$GEMDATE,ge(sped@10%hght^$GEMDATE,7.143))
                grdnam   =gstxm16@0%none^${GEMDATE}
                l

                r

                ! create masks of gstf when sfc wind >= 20 mph (8.929 m/s)
                gfunc    =mul(gstf@0%none^$GEMDATE,ge(sped@10%hght^$GEMDATE,8.929))
                grdnam   =gstfm20@0%none^${GEMDATE}
                l

                r

                ! create masks of gstx when sfc wind >= 20 mph (8.929 m/s)
                gfunc    =mul(gstx@0%none^$GEMDATE,ge(sped@10%hght^$GEMDATE,8.929))
                grdnam   =gstxm20@0%none^${GEMDATE}
                l

                r

		exit

ENDGD2

	# output finalized values at a STN (input by user), skip if no STN supplied
        if ($showtestoutput == n) goto SKIPTEST2
        touch gpfinalize.out; /bin/rm gpfinalize.out
        gdpoint << ENDGP3 > gpfinalize.out
		GDATTIM  = f${fhr}
                GDFILE   = ${GRIDFILE}
                GLEVEL   = 0
                GPOINT   = $STN
                GVCORD   = none
                SCALE    = 0
                gfunc    = dmxg
                r

                gfunc    = maxw
                r

                gfunc    = davg
                r

                gfunc    = quo(sumw,nlvls)
                r

		gfunc   = angle
		r

                GFUNC    = gstx
                r

                gfunc   =  gstf
                r

                exit

ENDGP3
        set  DMXG=`cat gpfinalize.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 1p`
        set  MAXW=`cat gpfinalize.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 2p`
        set  DAVG=`cat gpfinalize.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 3p`
        set  WAVG=`cat gpfinalize.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 4p`
        set  ANGL=`cat gpfinalize.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 5p`
        set  GSTX=`cat gpfinalize.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 6p`
        set  GSTF=`cat gpfinalize.out | grep "$GEMDATE :" | cut -f 2 -d : | sed -n 7p`
	echo "Dir at max speed/max speed $DMXG $MAXW  avg layer dir/speed $DAVG $WAVG  angle (abs diff between sfc dir and avg lyr dir) $ANGL   Refined Speed using angle diff Max/Avg $GSTX $GSTF"
	echo " "
SKIPTEST2:

SKIPGUST:
        echo "`date` - i $instances - f${LEADZERO}$FFF completed" >> $DEBUGLOG
        echo "`date` - i $instances - f${LEADZERO}$FFF completed"

        ## update status file to completed
        echo "`date` - i $instances completed ${ACTUALYMD}${ACTUALCYC}f$FFF" > status.file
        echo "`date` - i $instances - status.file for ${ACTUALYMD}${ACTUALCYC}f$FFF created with a status of completed" >> $DEBUGLOG
        echo "`date` - i $instances - status.file for ${ACTUALYMD}${ACTUALCYC}f$FFF created with a status of completed"

NEXTFHR:
	# Change temporal resolution based on model availablility 
	if ($fres2 != "" && $tres2 != "" && $fhr >= $fres2) set tres=$tres2
	if ($fres3 != "" && $tres3 != "" && $fhr >= $fres3) set tres=$tres3
	if ($fres4 != "" && $tres4 != "" && $fhr >= $fres4) set tres=$tres4
	# Override the default temporal resolution change with that the user specified in the manual settings section at the top of the script
	if ("$RESCHANGELIST" != "") then
		foreach RESCHANGE ($RESCHANGELIST)
			set tempfhr=`echo $RESCHANGE | cut -f 1 -d :`
			set tempres=`echo $RESCHANGE | cut -f 2 -d :`
			if ($tempfhr != "" && $tempres != "" && $fhr >= $tempfhr) set tres=$tempres
		end
	endif
	@ fhr = $fhr + $tres
	
  end #fhr loop

NEXTCYC:
end # ACTUALCYC LOOP
echo "`date` - i $instances - $0 script ending" >> $DEBUGLOG
echo "`date` - i $instances - $0 script ending"

#############################################################################################################
EXITING:
echo "`date` - i $instances - $0 script exit"
exit(0)
