#!/bin/csh
#
# Data Assimilation Research Testbed -- DART
# Copyright 2004, Data Assimilation Initiative, University Corporation for Atmospheric Research
# Licensed under the GPL -- www.gpl.org/licenses/gpl.html
#
# $Id: MakeICs,v 1.16 2004/09/15 19:56:38 thoar Exp $
#
# script to create initial conditions for any low-order experiment
#======================================================================

set SNAME = $0
set clobber
set DART_HOME = ~/DART

switch ( $#argv )
   case 1:
      # supplying one argument -- assumed to be the model
      set Model = $1
      breaksw
   case 2:
      # supplying two arguments
      set Model = $1
      set DART_HOME = $2
      breaksw
   default:
      echo " "
      echo "usage: $SNAME:t MODEL [DART_HOME]"
      echo " "
      echo "This script is used to generate a set of initial conditions for some of the"
      echo "models supported by the Data Assimilation Research Testbed (DART) software."
      echo "MODEL        must be one of: 9var lorenz_63 lorenz_84 lorenz_96 pe2lyr"
      echo "DART_HOME    must point to your DART directory."
      echo " "
      echo "To generate a set of initial conditions, one has to advance the"
      echo "filter for some amount of time. The only way to do this is to create an"
      echo "observation sequence that spans the required amount of time -- since"
      echo "'filter' runs for the time period covered in the observation sequence." 
      echo "The normal procedure is to create a bogus observation sequence using"
      echo "'perfect_model_obs' and then run 'filter'. If the 'perfect' observations have"
      echo "enormous observational errors -- the 'observations' don't have any impact."
      echo " "
      @ MYSTATUS = 1
      exit
      breaksw
endsw

#======================================================================
# This block just tries to guess where you have your DARTHOME and sets
# the defaults appropriately.
#======================================================================

setenv DARTDIR ${DART_HOME}/models/${Model}/work
if ( ! -d ${DARTDIR} ) then
   echo "${DARTDIR} does not exist ... "
   exit 2
endif

echo "DART project directory is $DART_HOME"
echo "Building Initial Conditions for $Model"
echo "in directory $DARTDIR"
echo "You have 4 seconds to stop this ..."
sleep 1
echo "3"
sleep 1
echo "2"
sleep 1
echo "1"
sleep 1
echo

cd ${DARTDIR}

#======================================================================
# Save any existing namelist ...
# Creating a null namelist just to avoid moving nothing.
#======================================================================

touch nullnamelist$$.nml
touch nullnamelist$$.nml_default

set SAVEME = .NamelistStorage.$$
if ( ! -d $SAVEME ) then
   mkdir ${SAVEME}
endif
mv -f *.nml         ${SAVEME}
mv -f *.nml_default ${SAVEME}

echo 'Saved all existing *.nml into directory '"$SAVEME"
echo 'Will restore and remove the directory at the end.'

#======================================================================
# Building the executables and storing the namelists.
# Each mkmf_* builds a namelist file containing all the namelists
# for the executable. These show ALL the namelist variables -- this
# script just sets some of them and takes the defaults on the rest.
#======================================================================

if !( -e create_obs_sequence ) then
   csh mkmf_create_obs_sequence
   make || exit 1
   \rm -f input.nml.create_obs_sequence_default
endif
if !( -e create_fixed_network_seq ) then
   csh mkmf_create_fixed_network_seq
   make || exit 2
   \rm -f input.nml.create_fixed_network_seq_default
endif
if !( -e perfect_model_obs ) then
   csh mkmf_perfect_model_obs
   make || exit 3
   \rm -f input.nml.perfect_model_obs_default
endif
if !( -e filter ) then
   csh mkmf_filter
   make || exit 4
   \rm -f input.nml.filter_default
endif
\rm -f *.o *.mod Makefile

#======================================================================
# Define input files based on model
#======================================================================

set BINARY_RESTART_FILES = .false.

set COS = create_obs_sequence.in
set CFN = create_fixed_network_seq.in

switch ( ${Model} )

   case 9var:

      echo "10"            > $COS  ;# upper bound on number of observations in sequence
      echo "0"            >> $COS  ;# number of copies of data (0 for just a definition)
      echo "0"            >> $COS  ;# number of quality control values per field
      echo "1"            >> $COS  ;# anything (but -1) to continue
      echo "-1"           >> $COS  ;# -1 == state variable 1     ------------
      echo "1 0"          >> $COS  ;# first obs time (days, seconds)        |
      echo "1000000.0"    >> $COS  ;# error variance for this observation   |
      echo "-1"           >> $COS  ;# -1 == no more observations ------------
      echo "set_def.out"  >> $COS  ;# output file name

      echo "set_def.out"   > $CFN  ;# same filename as 'output' above
      echo "1"            >> $CFN  ;# make a "regular" sequence
      echo "10000"        >> $CFN  ;# number of observations in first set
      echo "1 0"          >> $CFN  ;# time of first obs (days, seconds)
      echo "1 0"          >> $CFN  ;# observation interval (days, seconds)
      echo "obs_seq.in"   >> $CFN  ;# output file -- destined for perfect_model_obs 

      echo "&model_nml"                         > model.nml
      echo "   g = 8.0,"                       >> model.nml
      echo "   deltat = 0.0833333333333333  /" >> model.nml

      set num_ens_members = 1000

   breaksw

   case lorenz_96:

      echo "10"            > $COS  ;# upper bound on number of observations in sequence
      echo "0"            >> $COS  ;# number of copies of data (0 for just a definition)
      echo "0"            >> $COS  ;# number of quality control values per field
      echo "1"            >> $COS  ;# anything (but -1) to continue
      echo "-1"           >> $COS  ;# -1 == state variable 1     ------------
      echo "1 0"          >> $COS  ;# first obs time (days, seconds)        |
      echo "1000000.0"    >> $COS  ;# error variance for this observation   |
      echo "-1"           >> $COS  ;# -1 == no more observations ------------
      echo "set_def.out"  >> $COS  ;# output file name

      echo "set_def.out"   > $CFN  ;# same filename as 'output' above
      echo "1"            >> $CFN  ;# make a "regular" sequence
      echo "1000"         >> $CFN  ;# number of observations in first set
      echo "1 0"          >> $CFN  ;# time of first obs (days, seconds)
      echo "1 0"          >> $CFN  ;# observation interval (days, seconds)
      echo "obs_seq.in"   >> $CFN  ;# output file -- destined for perfect_model_obs

      echo "&model_nml"              > model.nml
      echo "   model_size = 40,"    >> model.nml
      echo "   forcing = 8.00,"     >> model.nml
      echo "   deltat = 0.005  /"   >> model.nml

      set num_ens_members = 200

   breaksw

   case lorenz_96_2scale:

      echo "10"            > $COS  ;# upper bound on number of observations in sequence
      echo "0"            >> $COS  ;# number of copies of data (0 for just a definition)
      echo "0"            >> $COS  ;# number of quality control values per field
      echo "1"            >> $COS  ;# anything (but -1) to continue
      echo "-1"           >> $COS  ;# -1 == state variable 1     ------------
      echo "1 0"          >> $COS  ;# first obs time (days, seconds)        |
      echo "1000000.0"    >> $COS  ;# error variance for this observation   |
      echo "-1"           >> $COS  ;# -1 == no more observations ------------
      echo "set_def.out"  >> $COS  ;# output file name

      echo "set_def.out"   > $CFN  ;# same filename as 'output' above
      echo "1"            >> $CFN  ;# make a "regular" sequence
      echo "1000"         >> $CFN  ;# number of observations in first set
      echo "1 0"          >> $CFN  ;# time of first obs (days, seconds)
      echo "1 0"          >> $CFN  ;# observation interval (days, seconds)
      echo "obs_seq.in"   >> $CFN  ;# output file -- destined for perfect_model_obs

      echo "&model_nml"                           > model.nml
      echo "   model_size_x = 36,"               >> model.nml
      echo "   y_per_x = 10,"                    >> model.nml
      echo "   forcing = 10.00,"                 >> model.nml
      echo "   delta_t = 0.005,"                 >> model.nml
      echo "   coupling_b = 10.0,"               >> model.nml
      echo "   coupling_c = 10.0,"               >> model.nml
      echo "   coupling_h =  1.0,"               >> model.nml
      echo "   output_state_vector = .false.,"   >> model.nml
      echo "   local_y = .false.  /"             >> model.nml

      set num_ens_members = 200

   breaksw

   case lorenz_04:

      echo "10"            > $COS  ;# upper bound on number of observations in sequence
      echo "0"            >> $COS  ;# number of copies of data (0 for just a definition)
      echo "0"            >> $COS  ;# number of quality control values per field
      echo "1"            >> $COS  ;# anything (but -1) to continue
      echo "-1"           >> $COS  ;# -1 == state variable 1     ------------
      echo "1 0"          >> $COS  ;# first obs time (days, seconds)        |
      echo "1000000.0"    >> $COS  ;# error variance for this observation   |
      echo "-1"           >> $COS  ;# -1 == no more observations ------------
      echo "set_def.out"  >> $COS  ;# output file name

      echo "set_def.out"   > $CFN  ;# same filename as 'output' above
      echo "1"            >> $CFN  ;# make a "regular" sequence
      echo "1000"         >> $CFN  ;# number of observations in first set
      echo "1 0"          >> $CFN  ;# time of first obs (days, seconds)
      echo "1 0"          >> $CFN  ;# observation interval (days, seconds)
      echo "obs_seq.in"   >> $CFN  ;# output file -- destined for perfect_model_obs

      echo "&model_nml"                            > model.nml
      echo "   model_size = 960,"                 >> model.nml
      echo "   forcing = 15.00,"                  >> model.nml
      echo "   delta_t = 0.001,"                  >> model.nml
      echo "   space_time_scale = 10.0,"          >> model.nml
      echo "   coupling = 3.0,"                   >> model.nml
      echo "   K =  32,"                          >> model.nml
      echo "   smooth_steps = 12,"                >> model.nml
      echo "   time_step_days = 0,"               >> model.nml
      echo "   time_step_seconds = 3600   / "     >> model.nml

      set num_ens_members = 500

   breaksw

   case pe2lyr:

      set BINARY_RESTART_FILES = .true.

      echo "10"            > $COS  ;# upper bound on number of observations in sequence
      echo "0"            >> $COS  ;# number of copies of data (0 for just a definition)
      echo "0"            >> $COS  ;# number of quality control values per field
      echo "1"            >> $COS  ;# anything (but -1) to continue
      echo "-1"           >> $COS  ;# -1 == state variable 1     ------------
      echo "1 0"          >> $COS  ;# first obs time (days, seconds)        |
      echo "1000000.0"    >> $COS  ;# error variance for this observation   |
      echo "-1"           >> $COS  ;# -1 == no more observations ------------
      echo "set_def.out"  >> $COS  ;# output file name

      echo "set_def.out"   > $CFN  ;# same filename as 'output' above
      echo "1"            >> $CFN  ;# make a "regular" sequence
      echo "100"          >> $CFN  ;# # of observations
      echo "1 0"          >> $CFN  ;# first obs time (days, seconds)
      echo "1 0"          >> $CFN  ;# observation interval (d, s)
      echo "obs_seq.in"   >> $CFN  ;# output file -- destined for perfect_model_obs

      echo " " > model.nml

      set num_ens_members = 50

   breaksw

   default:     # lorenz_63, lorenz_84

      echo "10"            > $COS  ;# upper bound on number of observations in sequence
      echo "0"            >> $COS  ;# number of copies of data (0 for just a definition)
      echo "0"            >> $COS  ;# number of quality control values per field
      echo "1"            >> $COS  ;# anything (but -1) to continue
      echo "-1"           >> $COS  ;# -1 == state variable 1     ------------
      echo "1 0"          >> $COS  ;# first obs time (days, seconds)        |
      echo "1000000.0"    >> $COS  ;# error variance for this observation   |
      echo "-1"           >> $COS  ;# -1 == no more observations ------------
      echo "set_def.out"  >> $COS  ;# output file name

      echo "set_def.out"   > $CFN  ;# same filename as 'output' above
      echo "1"            >> $CFN  ;# make a "regular" sequence
      echo "1000"         >> $CFN  ;# # of observations
      echo "1 0"          >> $CFN  ;# first obs time (days, seconds)
      echo "1 0"          >> $CFN  ;# observation interval (d, s)
      echo "obs_seq.in"   >> $CFN  ;# output name -- destined for perfect_model_obs

      echo "&model_nml"          > model.nml
      echo "   deltat = 0.01 /" >> model.nml

      set num_ens_members = 200

   breaksw

endsw

#======================================================================
# Create namelists and run ...
#======================================================================

echo "&assim_model_nml"                                         > assim_mod.nml
echo "    read_binary_restart_files = $BINARY_RESTART_FILES ," >> assim_mod.nml
echo "   write_binary_restart_files = $BINARY_RESTART_FILES /" >> assim_mod.nml

echo "#----------------------------------------------------------------------"
echo "Step 1.1: Create an observation definition."
echo "#----------------------------------------------------------------------"

echo '&utilities_nml'                                 > utilities.nml
echo '   logfilename = "create_obs_sequence.out",'   >> utilities.nml
echo '   TERMLEVEL = 1 /'                            >> utilities.nml

echo '&obs_sequence_nml'                         > obs_sequence.nml
echo '   read_binary_obs_sequence = .true.,'    >> obs_sequence.nml
echo '   write_binary_obs_sequence = .true. /'  >> obs_sequence.nml

cat utilities.nml assim_mod.nml > input.nml

./create_obs_sequence < $COS

if ( $status > 0 ) then
   echo "ERROR: running create_obs_sequence bombed ..."
   exit
else
   echo " "
   echo "create_obs_sequence terminated normally"
   echo " "
endif

echo "#----------------------------------------------------------------------"
echo "# Step 1.2: Create a fixed network definition (with nothing in them)"
echo "#----------------------------------------------------------------------"

echo '&utilities_nml'                                    > utilities.nml
echo '   logfilename = "create_fixed_network_seq.out",' >> utilities.nml
echo '   TERMLEVEL = 1 /'                               >> utilities.nml

cat utilities.nml assim_mod.nml > input.nml

./create_fixed_network_seq < $CFN

if ( $status > 0 ) then
   echo "ERROR: create_fixed_network_seq bombed ..."
   exit
else
   echo " "
   echo "create_fixed_network_seq terminated normally"
   echo " "
endif

echo "#----------------------------------------------------------------------"
echo "# Step 1.3: Initialize the model"
echo "#    creates files True_State.nc, obs_seq.out"
echo "#----------------------------------------------------------------------"

#----------------------------------------------------------------------
# input.nml is needed by perfect_model_obs and filter
# Initially, we need to spin up for a while and then we can put
# out a restart file. First run is start_from_restart FALSE, then
# second run is start_from_restart TRUE ... 
# Copy the "perfect_restart"  to "perfect_ics" and "filter_ics"
# THEN, we can run the filter
# with restart = FALSE!  "counterintuitive" as they say.
#----------------------------------------------------------------------

echo '&utilities_nml'                                > utilities.nml
echo '   logfilename = "perfect_model_obs.out",'    >> utilities.nml
echo '   TERMLEVEL = 1   /'                         >> utilities.nml

cat << ENDofTask02 > perfect.nml
&perfect_model_obs_nml
   async = 0,
   obs_seq_in_file_name = "obs_seq.in",
   obs_seq_out_file_name = "obs_seq.out",
   start_from_restart = .false.,
   output_restart = .true.,
   restart_in_file_name = "perfect_ics",
   restart_out_file_name = "perfect_restart",
   init_time_days = 0,
   init_time_seconds = 0,
   output_interval = 1  /
ENDofTask02

cat utilities.nml assim_mod.nml perfect.nml model.nml > input.nml

./perfect_model_obs
 
if ( $status > 0 ) then
   echo "ERROR: perfect_model_obs (spinup) bombed ..."
   exit
else
   echo " "
   echo "perfect_model_obs (spinup) terminated normally"
   echo " "
endif

echo "#----------------------------------------------------------------------"
echo "# Step 2: Generate a set of ensemble initial conditions"
echo "#         This is a multi-step procedure."
echo "#----------------------------------------------------------------------"

cp -f perfect_restart perfect_ics

echo "#----------------------------------------------------------------------"
echo "# Step 2.1: Generate a 'perfect' observation sequence for the filter"
echo "#----------------------------------------------------------------------"

echo '&utilities_nml'                                > utilities.nml
echo '   logfilename = "perfect_model_obs.out",'    >> utilities.nml
echo '   TERMLEVEL = 1  /'                          >> utilities.nml

cat << ENDofTask02 > perfect.nml
&perfect_model_obs_nml
   async = 0,
   obs_seq_in_file_name = "obs_seq.in",
   obs_seq_out_file_name = "obs_seq.out",
   start_from_restart = .true.,
   output_restart = .true.,
   restart_in_file_name = "perfect_ics",
   restart_out_file_name = "perfect_restart",
   init_time_days = 0,
   init_time_seconds = 0,
   output_interval = 1  /
ENDofTask02

cat utilities.nml assim_mod.nml perfect.nml model.nml > input.nml

./perfect_model_obs
 
if ( $status > 0 ) then
   echo "ERROR: perfect_model_obs (ensemble) bombed ..."
   exit
else
   echo " "
   echo "perfect_model_obs (ensemble) terminated normally"
   echo " "
endif

echo "#----------------------------------------------------------------------"
echo "# Step 2.2: Generate a set of ensemble initial conditions"
echo "#----------------------------------------------------------------------"

echo '&utilities_nml'                      > utilities.nml
echo '   logfilename = "dart_log.out",'   >> utilities.nml
echo '   TERMLEVEL = 1  /'                >> utilities.nml

cat << ENDofTask03 > filter.nml
&filter_nml
   async = 0,
   ens_size = xxxxxxxx,
   cutoff = 0.0,
   cov_inflate = 1.00,
   start_from_restart = .false.,
   output_restart = .true.
   obs_sequence_in_name = "obs_seq.out",
   obs_sequence_out_name = "obs_seq.final",
   restart_in_file_name = "perfect_ics",
   restart_out_file_name = "filter_restart",
   init_time_days = 0,
   init_time_seconds = 0, 
   output_state_ens_mean = .true.,
   output_state_ens_spread = .true.,
   output_obs_ens_mean = .true.,
   output_obs_ens_spread = .true.,
   num_output_ens_members = 0,
   output_interval = 1       /
ENDofTask03

# use some unix trickery to replace the string

set STRING = "1,$ s#xxxxxxxx#$num_ens_members#"
sed -e "$STRING" filter.nml > input.nml

cat utilities.nml assim_mod.nml model.nml >> input.nml

#----------------------------------------------------------------------
# Step 4: filter
# We can use the same logfile -- things just get appended -- can be
# surprising if you keep using the same one over and over ...
#----------------------------------------------------------------------

./filter

if ( $status > 0 ) then
   echo "ERROR: filter bombed ..."
   exit
else
   echo " "
   echo "filter terminated normally"
   echo " "
   \rm -f utilities.nml perfect.nml model.nml assim_mod.nml filter.nml 
   \rm -f set_def.out obs_seq.in ${COS} ${CFN}
endif

mv perfect_restart perfect_ics
mv  filter_restart  filter_ics

#======================================================================
# Restore the existing namelists ...
#======================================================================

\mv -f ${SAVEME}/*.nml .
\mv -f ${SAVEME}/*default .
\rmdir ${SAVEME}
\rm -f nullnamelist$$.nml nullnamelist$$.nml_default

exit
