#!/bin/sh
#=======================================================================
# Create a time series file containing selected          --- tseries ---
# variables from history or diagnostic files
# $Id: tseries_jobdef 657 2012-02-22 23:48:49Z acrnrls $
#=======================================================================
#     keyword :: tseries
# description :: Create a time series from history or diagnostic files
#
# Larry Solheim  ...Apr,2008

 set -a
 . betapath2

 jobname=mm_tseries; time="7200" ; memory="1000mb"
 crawork=tseries_job

 nextjob=on
 noprint=on

 # lopgm=lopgm_o4xa or lopgm_o4xal may be required for ocean data
 # or high resolution atm files
 TS_lopgm=${TS_lopgm:=lopgm_o4xa}
 this_host=`hostname|cut -d'.' -f1`
 case $this_host in
   # This is pollux, use 64 bit binaries
   ib3-*) TS_lopgm=lopgm_o4xal ;;
 esac
 lopgm=${TS_lopgm:=lopgm_o4xa}

 # Note: Setting debug "on" will enable the "-x" option (ie write every
 # command to standard error) when tseries_x is executed below. Setting
 # debug "off" means no "-x" option, thus reducing cruft in the output.
 # This is in addition to the normal function of debug.
 # The "-x" option is also set when TS_verbose=1.
 debug=off

 # Alternate path to a directory where .queue/.crawork will be found
 JHOME=''

 if [ -n "$JHOME" -a x"$JHOME" != x"$HOME" ]; then
   # Allow optional reset of DATAPATH/RUNPATH
   JHOME_DATA=''
   DATAPATH=${JHOME_DATA:=$DATAPATH}
   RUNPATH=${JHOME_DATA:=$RUNPATH}
   # Allow optional reset of CCRNTMP
   JHOME_RUN=''
   CCRNTMP=${JHOME_RUN:=$CCRNTMP}
 fi

 . comjcl.cdk

cat > Execute_Script <<'end_of_script'

  # start wall clock
  echo "\nSTART tseries_job:  "`date`"\n"

  # bail is a simple error exit routine
  bail(){
    echo "tseries: "$1
    echo " " >> haltit
    exit 1
  }

  set -a

  # These variables are set when the job string is created
  run_start_year=NotSet
  run_start_month=NotSet
  run_stop_year=NotSet
  run_stop_month=NotSet
  current_year=NotSet
  current_month=NotSet
  previous_year=NotSet
  previous_month=NotSet
  next_year=NotSet
  next_month=NotSet
  [ $current_year = "NotSet" -o $current_month = "NotSet" ] && \
    bail "current_year or current_month is not set"

  # files transferred will be for months in the range from
  # TS_start_year,TS_start_mon to TS_end_year,TS_end_mon
  if [ $previous_year = "NotSet" -o $previous_month = "NotSet" ]; then
    if [ $next_year = "NotSet" -o $next_month = "NotSet" ]; then
      bail "Neither previous_(year|month) nor next_(year|month) are set"
    else
      TS_start_year=$current_year
      TS_start_mon=$current_month
      TS_end_year=$next_year
      TS_end_mon=$next_month
    fi
  else
    TS_start_year=$previous_year
    TS_start_mon=$previous_month
    TS_end_year=$current_year
    TS_end_mon=$current_month
  fi

  TS_start_year=`echo $TS_start_year|awk '{printf "%3.3d",$1}' -`
  TS_start_mon=`echo $TS_start_mon|awk '{printf "%2.2d",$1}' -`
  TS_end_year=`echo $TS_end_year|awk '{printf "%3.3d",$1}' -`
  TS_end_mon=`echo $TS_end_mon|awk '{printf "%2.2d",$1}' -`

  [ -z "$TS_start_year" ] && bail "TS_start_year is null"
  [ -z "$TS_end_year" ]   && bail "TS_end_year is null"
  [ -z "$TS_start_mon" ]  && bail "TS_start_mon is null"
  [ -z "$TS_end_mon" ]    && bail "TS_end_mon is null"
  [ $TS_start_mon -gt 12 -o $TS_start_mon -lt 1 ] &&\
    bail "TS_start_mon=$TS_start_mon is out of range"
  [ $TS_end_mon -gt 12 -o $TS_end_mon -lt 1 ] &&\
    bail "TS_end_mon=$TS_end_mon is out of range"
  [ $TS_start_year -gt $TS_end_year ] &&\
    bail "TS_start_year=$TS_start_year is out of range"

  TS_run_start_year=$run_start_year
  TS_run_start_month=$run_start_month
  TS_run_stop_year=$run_stop_year
  TS_run_stop_month=$run_stop_month

  # TS_verbose indicates the amount of output
  TS_verbose=0
  [ "$TS_verbose" = 'on' ]  && eval TS_verbose\=1
  [ "$TS_verbose" = 'off' ] && eval TS_verbose\=0
  [ "$TS_verbose" = 'yes' ] && eval TS_verbose\=1
  [ "$TS_verbose" = 'no' ]  && eval TS_verbose\=0

  # RUNPATH may be set if desired
  RUNPATH=$RUNPATH

  # It is often more efficient to set CCRNTMP = $RUNPATH
  CCRNTMP=$CCRNTMP

  #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
  # Define the set of time series that are to be written to the output file
  #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

  # A variable is specified by a colon separated list of fields.
  # Each field in this list determines something about the variable
  # (e.g. averaging, sampling, windowing, ...)
  # The format of this colon separated list is as follows.
  # VarName:VarDef:SpatialAvg:TimeSampling:TemporalAvg:CodedLevels:LevelCoord:Window
  #   VarName ...the NAME (ibuf3 value) as it appears in the file.
  #              In the case of a GP or XP file this is a super label.
  #   VarDef ...an expression that defines a new variable in terms of
  #             other variables that exist in the input file
  #       The desired variable may be something that does not exist
  #       in the input file but can be derived from other variables
  #       that are found in the input file. This field will tell this script
  #       how to create these derived types from existing variables.
  #       e.g. FLA+FLG would create a variable in the output file that is
  #       the sum of the variables FLA and FLG found in the input file.
  #       When this field is not empty the name of the variable that will appear in
  #       the output file is the name specified in the Variable Name field.
  #   SpatialAvg ...indicates the variable is to be a global average (g or G)
  #                 or a zonal average (z or Z)
  #       In multi level fields these spatial averages are applied on each level.
  #       The default is to not perform any explicit spatial averaging so that the
  #       variable will be spatially averaged, or not, depending on how it appears
  #       in the input file.
  #   TimeSampling ...a comma separated list of quantities (inc,orig,offset,max)
  #       inc is the sampling frequency, orig indicates the origin of the
  #       selection, either start of month (M) or start of run (R), offset is a time
  #       offset relative to the origin and max is the largest time step to extract.
  #       Any of inc, offset or max may be of the form (here N is an integer)
  #         N        - a number of time steps (kount values)
  #         Ns or NS - a number of save intervals
  #         Nd or ND - a number of days
  #   TemporalAvg ...indicates the variable is to be monthly averaged (m or M).
  #       The default is to not perform any explicit temporal averaging
  #       so that the variable will be temporally averaged, or not,
  #       depending on how it appears in the input file.
  #   CodedLevels ...a comma separted list of coded levels (ibuf4 values).
  #       If levels are supplied then only these levels will appear in the output
  #       time series file. The default is to extract every level found in the
  #       input file.
  #   LevelCoord ...a single (case insensitive) character to indicate that the
  #                 levels should be model eta (e or E) levels, pressure (p or P)
  #                 levels or ocean depths (d or D).
  #       If pressure levels are requested and the input file contains model levels
  #       then an attempt will be made to interpolate to pressure levels.
  #       This may not always be possible. If model levels are requested and the
  #       input file contains pressure levels then an error will occur.
  #       The default is to use the level coordinates found in the input file.
  #   Window ...a comma separated list of the four grid indicies that identify a
  #             window, optionally followed by a switch indicating whether the grid
  #             contains an extra cyclic longitude (cycle=0) or not (cycle .ne. 0).
  #       If cycle is not present then cycle=0 is used.
  #       window = "left,right,lower,upper,cycle"
  #       The letters "NH" and "SH" may be used in place of the list of integers
  #       as shorthand for the northern or southern hemispheres.
  #       The default is to use the entire grid found in the input file.

  # TS_gs is a space separated list of "gs" file variable specifications.
  # No white space is allowed within any field
  TS_gs=''

  # TS_ss is a space separated list of "ss" file variable specifications.
  # No white space is allowed within any field
  # Note, SPEC fields will be converted to GRID fields by default.
  TS_ss=''

  # TS_gp is a space separated list of "gp" file variable specifications.
  # No white space is allowed within any field
  # If defined via this variable the super labels identifying sets to
  # be extracted from the gp file may not contain spaces. For super
  # labels that do contain spaces use the TS_gpNN variables.
  TS_gp=''

  # TS_xp is a space separated list of "xp" file variable specifications.
  # No white space is allowed within any field
  # If defined via this variable the super labels identifying sets to
  # be extracted from the xp file may not contain spaces. For super
  # labels that do contain spaces use the TS_xpNN variables.
  TS_xp=''

  # TS_td is a space separated list of "td" file variable defs.
  # No white space is allowed within any field
  TS_td=''

  # TS_gz is a space separated list of "gz" file variable defs.
  # No white space is allowed within any field
  TS_gz=''

  # TS_cp is a space separated list of "cp" file variable defs.
  # No white space is allowed within any field
  TS_cp=''

  # TS_cm is a space separated list of "cm" file variable defs.
  # No white space is allowed within any field
  TS_cm=''

  # TS_gpNN each contain a single variable definition for "gp" fields
  # In these variables the super labels may contain spaces.
  # Note TS_gpNN variable definitions for NN > 10 may be added on the cccjob
  # command line by appending ":A" to the variable definition (e.g. TS_gpNN=val:A)
  # These definitions will be added below just prior to the main loop.
  TS_gp01=''
  TS_gp02=''
  TS_gp03=''
  TS_gp04=''
  TS_gp05=''
  TS_gp06=''
  TS_gp07=''
  TS_gp08=''
  TS_gp09=''
  TS_gp10=''

  # TS_xpNN each contain a single variable definition for "xp" fields
  # In these variables the super labels may contain spaces
  # Note TS_xpNN variable definitions for NN > 10 may be added on the cccjob
  # command line by appending ":A" to the variable definition (e.g. TS_xpNN=val:A)
  # These definitions will be added below just prior to the main loop.
  TS_xp01=''
  TS_xp02=''
  TS_xp03=''
  TS_xp04=''
  TS_xp05=''
  TS_xp06=''
  TS_xp07=''
  TS_xp08=''
  TS_xp09=''
  TS_xp10=''

  # TS_clean flags removal of temporary directories that contain
  # "gs", "ss" or "td" split files
  TS_clean=''

  # TS_config is the full pathname of a configuration file. If this is set
  # then all variable specification information is taken from this file
  # and any variable specifications set via TS_.. variables are ignored.
  TS_config=''

  # TS_plevs is a comma separated list of pressure levels to be used
  # as the default set of pressure levels if pressure levels are requested
  # for a field from an SS or GS file.
  TS_plevs=''

  # If either TS_date_offset or TS_date_format are set then all non TIME records
  # will have their ibuf2 values converted to TS_date_format (YYYYMMDDHH by default).
  # TS_date_offset must be an integer in YYYY or YYYYMMDDHH format
  # TS_date_format must be an string, one of:
  #                 YYYYMMDDHH
  #                   YYYYMMDD
  #                     YYYYMM
  #                       YYYY
  #                   YYMMDDHH
  #                     YYMMDD
  #                       YYMM
  #                      MODEL

  TS_date_offset=''
  TS_date_format=''

  # File type specific date_offset and date_format may be set to be used
  # for only a particular file type
  TS_date_offset_gs=''
  TS_date_format_gs=''
  TS_date_offset_ss=''
  TS_date_format_ss=''
  TS_date_offset_gp=''
  TS_date_format_gp=''
  TS_date_offset_xp=''
  TS_date_format_xp=''
  TS_date_offset_td=''
  TS_date_format_td=''
  TS_date_offset_gz=''
  TS_date_format_gz=''
  TS_date_offset_cm=''
  TS_date_format_cm=''
  TS_date_offset_cp=''
  TS_date_format_cp=''
  TS_date_offset_ie=''
  TS_date_format_ie=''
  TS_date_offset_cc=''
  TS_date_format_cc=''

  # TS_sp2gg flags conversion of spectral records to grid records. TS_sp2gg is
  # either "on" or "off". Tdefault is "on" if TS_sp2gg is not set or null.
  TS_sp2gg=''

  # TS_usr_decks is a space separated list of user supplied common decks
  # The user can supply a list of decks that will be sourced in the order
  # they appear in this list. These decks can be used to create arbitrary
  # time series that will then be appended to the local file "TSFILE" which
  # in turn is appended to the output file named in the variable TS_file.
  TS_usr_decks=''

  # The TS_require_XX variables are used to determine if a file with the
  # extension XX is to be read by the tseries script. This is only required
  # if the user has supplied comdecks via TS_usr_decks.
  TS_require_gs=''
  TS_require_ss=''
  TS_require_gz=''
  TS_require_gp=''
  TS_require_td=''
  TS_require_xp=''
  TS_require_cp=''
  TS_require_cm=''

  # The TS_XXfile variables are used to specify a non-default file name
  # for files with the extension XX
  TS_gsfile=''
  TS_ssfile=''
  TS_gpfile=''
  TS_xpfile=''
  TS_tdfile=''
  TS_gzfile=''
  TS_cpfile=''
  TS_cmfile=''

  # The delt_XX variables are used to specify a file specific time step
  # (in seconds) or to override the default.
  delt_gs=''
  delt_ss=''
  delt_gp=''
  delt_xp=''
  delt_td=''
  delt_gz=''
  delt_cp=''
  delt_cm=''

  # The plid_XX variables are used to specify a file specific lid pressure
  # or to override the default.
  plid_gs=''
  plid_ss=''
  plid_gp=''
  plid_xp=''
  plid_td=''
  plid_gz=''
  plid_cp=''
  plid_cm=''

  # TS_kinc and TS_koff are used to override the default time step increment
  # (TS_koff) and time step offset (TS_koff) used to time sample fields.
  TS_kinc=''
  TS_koff=''

  # Set specific parmsub parameters to null strings so that if one is set
  # by the user, its value will get passed on to the tseries deck.
  delt=''; plid=''; coord=''; moist=''; sref=''; spow='';

  # TS_ccmval flags CCMVal specific options
  TS_ccmval=0
  [ "$TS_ccmval" = 'on' ]  && eval TS_ccmval\=1
  [ "$TS_ccmval" = 'off' ] && eval TS_ccmval\=0
  [ "$TS_ccmval" = 'yes' ] && eval TS_ccmval\=1
  [ "$TS_ccmval" = 'no' ]  && eval TS_ccmval\=0

# Define a default set of pressure levels to be used by the tseries deck
  if [ $TS_ccmval -eq 1 ]; then
    # This is the set of pressure levels used in CCMVal diagnostics
    p01="-4700"; p02="-3100"; p03="-3150"; p04="-3200"; p05="-3300";
    p06="-3400"; p07="-3500"; p08="-3700"; p09="-2100"; p10="-2150";
    p11="-2200"; p12="-2300"; p13="-2400"; p14="-2500"; p15="-2700";
    p16="-1100"; p17="-1150"; p18="-1200"; p19="-1300"; p20="-1400";
    p21="-1500"; p22="-1700"; p23="-0100"; p24="-0150"; p25="-0200";
    p26="-0300"; p27="-0400"; p28="-0500"; p29="-0700"; p30="   10";
    p31="   15"; p32="   20"; p33="   25"; p34="   30"; p35="   35";
    p36="   40"; p37="   50"; p38="   60"; p39="   70"; p40="   80";
    p41="   90"; p42="  100"; p43="  115"; p44="  130"; p45="  150";
    p46="  170"; p47="  200"; p48="  250"; p49="  285"; p50="  300";
    p51="  350"; p52="  400"; p53="  450"; p54="  500"; p55="  600";
    p56="  650"; p57="  700"; p58="  750"; p59="  780"; p60="  800";
    p61="  850"; p62="  925"; p63=" 1000"; p64=''
  else
    # This is the "standard" set of pressure levels used in cccma diagnostics
    p01="   10"; p02="   20"; p03="   30"; p04="   50"; p05="   70";
    p06="  100"; p07="  150"; p08="  200"; p09="  250"; p10="  300";
    p11="  400"; p12="  500"; p13="  600"; p14="  700"; p15="  850";
    p16="  925"; p17=" 1000"; p18=''; p19=''; p20='';
    p21=''; p22=''; p23=''; p24=''; p25='';
    p26=''; p27=''; p28=''; p29=''; p30='';
    p31=''; p32=''; p33=''; p34=''; p35='';
    p36=''; p37=''; p38=''; p39=''; p40='';
    p41=''; p42=''; p43=''; p44=''; p45='';
    p46=''; p47=''; p48=''; p49=''; p50='';
    p61=''; p62=''; p63=''; p64=''; p65='';
    p66=''; p67=''; p68=''; p69=''; p70='';
    p71=''; p72=''; p73=''; p74=''; p75='';
    p76=''; p77=''; p78=''; p79=''; p80='';
    p81=''; p82=''; p83=''; p84=''; p85='';
    p86=''; p87=''; p88=''; p89=''; p90='';
    p91=''; p92=''; p93=''; p94=''; p95='';
    p96=''; p97=''; p98=''; p99=''; p100='';
  fi

  #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
  #
  #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

  # These variables are set when the job string is created

  year=yyy; mon=mm   # memory99=1

  runid="job000"; uxxx='uxxx'; tseries_uxxx=$uxxx;
  tseries_prefix="${tseries_uxxx}_${runid}"   # memory99=1
  tseries_prefix_=${tseries_prefix}_          # memory99=1
  crawork="${runid}_job"; username="acrnxxx"; user="XXX";

  # Time series files used will be for months in the range from
  # tseries_start_year,tseries_start_mon to tseries_end_year,tseries_end_mon
  [ $current_year = "NotSet" -o $current_month = "NotSet" ] && \
    bail "current_year or current_month is not set"
  if [ $previous_year = "NotSet" -o $previous_month = "NotSet" ]; then
    [ $next_year = "NotSet" -o $next_month = "NotSet" ] && \
      bail "tseries: Neither previous_(year|month) nor next_(year|month) are set"
    tseries_start_year=$current_year
    tseries_start_mon=$current_month
    tseries_end_year=$next_year
    tseries_end_mon=$next_month
  else
    tseries_start_year=$previous_year
    tseries_start_mon=$previous_month
    tseries_end_year=$current_year
    tseries_end_mon=$current_month
  fi
  tseries_start_year=`echo $tseries_start_year|awk '{printf "%3.3d",$1}' -`
  tseries_start_mon=`echo $tseries_start_mon|awk '{printf "%2.2d",$1}' -`
  tseries_end_year=`echo $tseries_end_year|awk '{printf "%3.3d",$1}' -`
  tseries_end_mon=`echo $tseries_end_mon|awk '{printf "%2.2d",$1}' -`

  # Perform checks on variables that are set dynamically
  [ -z "$tseries_start_year" ] && bail "tseries_start_year is null"
  [ -z "$tseries_end_year" ]   && bail "tseries_end_year is null"
  [ -z "$tseries_start_mon" ]  && bail "tseries_start_mon is null"
  [ -z "$tseries_end_mon" ]    && bail "tseries_end_mon is null"
  [ $tseries_start_mon -gt 12 -o $tseries_start_mon -lt 1 ] &&\
    bail "tseries_start_mon=$tseries_start_mon is out of range"
  [ $tseries_end_mon -gt 12 -o $tseries_end_mon -lt 1 ] &&\
    bail "tseries_end_mon=$tseries_end_mon is out of range"
  [ $tseries_start_year -gt $tseries_end_year ] &&\
    bail "tseries_start_year=$tseries_start_year is out of range"

  # range is a string used as part of the default output file name
  # This extra step of defining start_stop_equal is required to get around
  # a bug in submit3 (the same bug that causes problems in the while loop below)
  start_stop_equal=0
  [ $tseries_start_year -eq $tseries_end_year -a \
    $tseries_start_mon  -eq $tseries_end_mon ] && start_stop_equal=1
  if [ $start_stop_equal -eq 1 ]; then
    # When start and stop times are equal, range is of the form YYY_mMM
    range="${tseries_start_year}_m${tseries_start_mon}"
  else
    # range is a string of the form YYYmMM_YYYmMM
    range="${tseries_start_year}m${tseries_start_mon}"
    range="${range}_${tseries_end_year}m$tseries_end_mon"
  fi

  # These may be used to form part of the output file names when splitting
  # variables into individual files via directions in the config file
  ymrange=''
  yrange=''

  # TS_file is the name under which the output file containing the time series
  # will be saved. If TS_file already exists it will be appended to,
  # if it does not exist it will be created (except see TS_file_clobber)
  TS_file=${tseries_prefix_}${range}_ts

  # If TS_file_clobber is set to on then the file named in TS_file
  # will always be overwritten
  TS_file_clobber=off

  # TS_file_split flags writing multiple output files with one variable
  # per output file. Each individual file will be created if it does not
  # exist or appended to if it exists and TS_file_clobber is false.
  TS_file_split=''

  # determine a full pathname for tseries.dk
  tseries_path=''
  for p in `echo $PATH|sed 's/:/ /g'`; do
    if [ -s ${p}/tseries.dk ]; then
      tseries_path=${p}/tseries.dk
      break
    fi
  done
  [ -z "$tseries_path" ] && bail "The file tseries.dk must be on your path."

  # If model1 is set non null then it will be used to determine file names
  # of gs, ss, td and gz files. In particular, it will look for files with
  # the names ${model1}gs, ${model1}ss, ${model1}td and ${model1}gz.
  # These names will, in turn, be overidden by the corresponding TS_XXfile
  # variable; one of TS_gsfile, TS_ssfile, TS_tdfile or TS_gzfile.
  model1=''

  # If model1_prefix is set non null then it will be used in the loop
  # below to as the prefix of a new model1 definition each loop iteration.
  model1_prefix=''

  # If flabel is set non null then it will be used to determine file names
  # of gp and xp files. In particular, it will look for files with the
  # names ${flabel}gp and ${flabel}xp.
  # These names will, in turn, be overidden by the corresponding TS_XXfile
  # variable; one of TS_gpfile or TS_xpfile.
  flabel=''

  # If flabel_prefix is set non null then it will be used in the loop
  # below to as the prefix of a new flabel definition each loop iteration.
  flabel_prefix=''

  # <<INSERT>> any user supplied variable definitions here.

  # ---Start_submit_ignore_code----

  # Create a local file containing the "Execute_Script" here document
  # found in tseries.dk
  awk 'BEGIN {delim="";indoc=0}
       /^ *cat .*Execute_Script/ && indoc == 0 {
         if (match($0,/<< *.[a-zA-Z_]*/) > 0) {
           delim = substr($0,RSTART,RLENGTH)
           sub(/^.*<< */    ,"",delim)
           sub(/^[^a-zA-Z_]/,"",delim)
           sub(/[^a-zA-Z_]$/,"",delim)
         }
         indoc=1
         next}
       {if (length(delim)>0) {if (index($0,delim) == 1) {exit}}}
       indoc == 1 {print}
      ' $tseries_path > XXX

  [ ! -s XXX ] && bail "Unable to extract Execute_Script from tseries.dk"

  # Prepend a shebang line and make executable
  setopts='-ae'
  [ x"$debug" = 'xon' -o $TS_verbose -gt 0 ] && setopts='-aex'
  cat > TTT << EOF
#!/bin/sh
  set $setopts
EOF
  cat TTT XXX > tseries_x
  chmod u+x tseries_x
  rm TTT XXX

  # Create a temporary working directory in which tseries_x will run
  CWD=`pwd`
  stamp=`date "+%j"$$`
  tmpd_ts=tmpd_ts$stamp
  mkdir -p $tmpd_ts

  #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
  # Generate a list of file name prefixes and assign them to the variable
  # "model" then execute tseries_x after each new definition of model.
  # model is used by tseries_x to define variable names. Depending on which
  # variables have been selected, one or more of the files ${model}gs,
  # ${model}ss, ${model}gp, ${model}xp, ${model}td or ${model}gz must be
  # present on disk (ie DATAPATH/RUNPATH).
  #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

  # Loop over year/month of the requested range and run tseries_x for each month
  tseries_curr_year=`echo $tseries_start_year|awk '{y=$1-1;printf "%3.3d", y}' -`
  nnts=0
  while [ $tseries_curr_year -lt $tseries_end_year ]; do
    tseries_curr_year=`echo $tseries_curr_year|awk '{y=1+$1;printf "%3.3d", y}' -`
    eval year\=$tseries_curr_year
    if [ $tseries_curr_year -eq $tseries_start_year ]; then
      mm=`echo $tseries_start_mon|awk '{m=$1-1;printf "%2.2d", m}' -`
    else
      mm=0
    fi
    if [ $tseries_curr_year -eq $tseries_end_year ]; then
      mm_end=$tseries_end_mon
    else
      mm_end=12
    fi
    while [ $mm -lt $mm_end ]; do
      mm=`echo $mm|awk '{m=1+$1;printf "%2.2d", m}' -`
      eval mon\=$mm
      # model will determine default file names
      model=${tseries_prefix_}${tseries_curr_year}_m${mm}_
      # flabel will determine gp and xp file names
      if [ -n "$flabel_prefix" ]; then
        flabel=${flabel_prefix}_${tseries_curr_year}_m${mm}_
      fi
      # model1 will determine gs, ss, td and gz file names
      if [ -n "$model1_prefix" ]; then
        model1=${model1_prefix}_${tseries_curr_year}_m${mm}_
      fi
      # Execute tseries_x in the temporary working directory
      cd $tmpd_ts
      rm -fr *
      $CWD/tseries_x
      cd $CWD
      # After the first iteration reset TS_file_clobber to "off" so that subsequent
      # iterations do not clobber the file generate by the previous iteration
      # This is done with the eval to hide it from cccjob variable substitution
      eval TS_file_clobber\=off
    done
  done

  # By default, always call tscat after processing the loop above.
  # The user may set TS_call_tscat=off to change this default behavior.
  TS_call_tscat=${TS_call_tscat:=1}
  [ "$TS_call_tscat" = 'on' ]  && eval TS_call_tscat\=1
  [ "$TS_call_tscat" = 'off' ] && eval TS_call_tscat\=0
  [ "$TS_call_tscat" = 'yes' ] && eval TS_call_tscat\=1
  [ "$TS_call_tscat" = 'no' ]  && eval TS_call_tscat\=0

  if [ $start_stop_equal -eq 1 ]; then
    # Do not call tscat when start and stop times are equal
    eval TS_call_tscat\=0
  fi

  if [ $TS_call_tscat -eq 1 ]; then
    #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
    # Call tscat with the single file named in TS_file as input.
    # This will concatenate similar sets, but for different months, that were
    # written to TS_file by tseries_x during execution of the above loop.
    #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#

    # determine a full pathname for tscat.dk
    tscat_path=''
    for p in `echo $PATH|sed 's/:/ /g'`; do
      if [ -s ${p}/tscat.dk ]; then
        tscat_path=${p}/tscat.dk
        break
      fi
    done
    [ ! -s $tscat_path ] && bail "The file tscat.dk must be on your path."

    # Create a local file containing the "Execute_Script" here document
    # found in tscat.dk
    rm -f XXX
    awk 'BEGIN {delim="";indoc=0}
         /^ *cat .*Execute_Script/ && indoc == 0 {
           if (match($0,/<< *.[a-zA-Z_]*/) > 0) {
             delim = substr($0,RSTART,RLENGTH)
             sub(/^.*<< */    ,"",delim)
             sub(/^[^a-zA-Z_]/,"",delim)
             sub(/[^a-zA-Z_]$/,"",delim)
           }
           indoc=1
           next}
         {if (length(delim)>0) {if (index($0,delim) == 1) {exit}}}
         indoc == 1 {print}
        ' $tscat_path > XXX

    [ ! -s XXX ] && bail "Unable to extract Execute_Script from tscat.dk"

    # Prepend a shebang line and make executable
    setopts='-ae'
    [ x"$debug" = 'xon' -o $TS_verbose -gt 0 ] && setopts='-aex'
    cat > TTT << EOF
#!/bin/sh
  set $setopts
EOF
    cat TTT XXX > tscat_x
    chmod u+x tscat_x
    rm TTT XXX

    # Define the tscat input file name
    tscat01=$TS_file
    tscat02=''

    # TS_plot flags output of a plot from tscat_x and
    TS_plot=off
    # TS_yoff is a year offset used in those plots
    TS_yoff=0
    # TS_ptitle will form part of the plot title of every plot
    TS_ptitle=''
    # plunit is only used when TS_plot is set 'on'
    plunit="VIC"

    # tscat_save is the name of the output file saved by tscat_x.
    # If this is null then tscat_x will not save any output file.
    tscat_save=''

    # TS_del_after_cat flags the deletion of all input tscatNN files after
    # they have been concatenated into a single file. This will never happpen
    # unless the output file is saved (ie: tscat_save is set non null).
    # The default is to delete the input files when the output file is saved.
    TS_del_after_cat=on

    # Execute tscat_x in a sub directory
    tmpd_cat=tmpd_cat$stamp
    mkdir -p $tmpd_cat
    cd $tmpd_cat
      $CWD/tscat_x
      # tscat will create a file named NEW_TSFILE
      mv NEW_TSFILE $CWD
    cd $CWD

    # Overwrite the TS_file that was created by tseries_x with
    # the NEW_TSFILE that was created by tscat_x
    access oldTSFILE $TS_file na
    save NEW_TSFILE $TS_file
    delete oldTSFILE na
  fi

  # stop wall clock
  echo "\nSTOP tscat_job:  "`date`"\n"

  # ---Stop_submit_ignore_code----

end_of_script

 . endjcl.cdk

#end_of_job
