libsave_ic.sh 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. #================================================================================
  2. # save_ic functions - these are used to save EC-Earth states during a run,
  3. # which can be used as Initial Conditions (ICs) for other runs.
  4. #
  5. # save_ic_get_config : define the config to use based on the save_ic config parameter
  6. #
  7. # save_ic has two options available:
  8. # save_ic:end_leg (save ICs at the end of every leg)
  9. # save_ic:end_run (save ICs at the end of the run)
  10. #
  11. # By default, without an option, ICs are saved at given offsets from the leg
  12. # start, possibly if conditions are met. These offset(s) and condition(s) must
  13. # be coded in the "else" clause below. See commented example.
  14. #
  15. function save_ic_get_config ()
  16. {
  17. do_save_ic=false
  18. save_ic_custom=false
  19. if $(has_config save_ic)
  20. then
  21. tmp_leg_length_sec=${leg_length_sec}
  22. has_config nemo && ! has_config ifs && tmp_leg_length_sec=$(( tmp_leg_length_sec + $(leap_days "${leg_start_date}" "${leg_end_date}")*24*3600 ))
  23. if $(has_config save_ic:end_leg)
  24. then
  25. # save ICs at the end of every leg
  26. do_save_ic=true
  27. save_ic_date_offset=( "+ ${tmp_leg_length_sec} sec" )
  28. elif $(has_config save_ic:end_run)
  29. then
  30. # save ICs at the end of the run
  31. leg_end_date_yyyymmdd=$(date -u -d "${leg_end_date}" +%Y%m%d)
  32. run_end_date_yyyymmdd=$(date -u -d "${run_end_date}" +%Y%m%d)
  33. tmp_leg_end_date_yyyymmdd=${leg_end_date_yyyymmdd}
  34. has_config nemo && ! has_config ifs && tmp_leg_end_date_yyyymmdd=$(date -u --date="${leg_end_date_yyyymmdd} + $(leap_days "${leg_start_date_yyyymmdd}" "${run_end_date_yyyymmdd}") day" +%Y%m%d )
  35. if [ ${tmp_leg_end_date_yyyymmdd} -eq ${run_end_date_yyyymmdd} ]
  36. then
  37. do_save_ic=true && save_ic_date_offset=( "+ ${tmp_leg_length_sec} sec" )
  38. fi
  39. else
  40. echo "WARNING: save_ic requires to define condition and offset here or in the runscript"
  41. save_ic_custom=true
  42. do_save_ic=false
  43. save_ic_date_offset=( )
  44. # edit here or in the runscript the conditional statement to decide which legs to save ICs and the offset from leg start
  45. # e.g. to save at the end of every 10 legs:
  46. #EXAMPLE if (( leg_number%10 == 0 ))
  47. #EXAMPLE then
  48. #EXAMPLE do_save_ic=true
  49. #EXAMPLE save_ic_date_offset=( "+ ${leg_length_sec} sec" )
  50. #EXAMPLE fi
  51. fi
  52. fi
  53. }
  54. # save_ic_define_vars : define variables used in the save_ic functions
  55. #
  56. # The following variables must be defined in the runscript before calling this function
  57. #
  58. # 1) do_save_ic : set to true/false to enable save_ic feature
  59. #
  60. # 2) save_ic_date_offset : array of dates (offset from start of chunk, at 00:00h) to save ICs.
  61. # e.g. save_ic_date_offset=( "+1 month" "+2 month" )
  62. # The following restrictions apply, it is up to the user to ensure compliance
  63. # - first timestep of run is not supported
  64. # - if requesting first timestep of leg start, NEMO restarts from previous legs will
  65. # be used if present
  66. # - only one IC per month is supported (to simplify the IFS filter)
  67. # - maximum 9 ICs per leg (because of current restrictions in NEMO namelist)
  68. # - if requesting model-level output for IFS (e.g. for PRIMAVERA),
  69. # there will be no model-level variables in output on the timestep which
  70. # ICs are requested, unless requesting the last timestep of the leg
  71. #
  72. function save_ic_define_vars ()
  73. {
  74. if true
  75. then
  76. # save original value of ifs_lastout
  77. has_config ifs && [[ -z "${save_ic_ifs_lastout_orig:-}" ]] && save_ic_ifs_lastout_orig=${ifs_lastout}
  78. save_ic_ifs_lastout=false
  79. # sanity checks
  80. [ ${#save_ic_date_offset[@]} -gt 9 ] && error "Cannot create more than 9 ICs in a given leg"
  81. # sanity check for no more than one IC per month when ifs active
  82. if has_config ifs
  83. then
  84. ic_month=$(date -u -d"${leg_start_date} ${save_ic_date_offset[0]}" +%B)
  85. for (( i=1; i< ${#save_ic_date_offset[@]}; i++ ))
  86. do
  87. new_ic_month=$(date -u -d "${leg_start_date} ${save_ic_date_offset[$i]}" +%B)
  88. [[ "${ic_month}" == "${new_ic_month}" ]] && error "Error: no more than one IC is allowed in the same month when running with ifs" || ic_month=new_ic_month
  89. done
  90. fi
  91. # fill vars
  92. for (( i=0; i< ${#save_ic_date_offset[@]}; i++ ))
  93. do
  94. # sanity check for custom offsets
  95. # check leg_start_date + current save_ic_date_offset < leg_end_date
  96. end_current_save_ic_date=$(date -u -d "${leg_start_date} ${save_ic_date_offset}" +%Y%m%d)
  97. if has_config nemo && ! has_config ifs
  98. then
  99. # nemo works with no leap calendar in case to be needed this day must be removed.
  100. end_current_save_ic_date=$(date -u --date="${end_current_save_ic_date} - $(leap_days "${run_start_date}" "${save_ic_date_offset}") day" +%Y%m%d )
  101. fi
  102. tmp_leg_end_date=$(date -u -d "${leg_end_date}" +%Y%m%d)
  103. [[ ${tmp_leg_end_date} -lt ${end_current_save_ic_date} ]] && error "error requested IC date: ${end_current_save_ic_date} is out of leg boundaries: ${tmp_leg_end_date}"
  104. #save_ic_date1[$i]=${save_ic_date[$i]}
  105. save_ic_date1[$i]=$(date -u -d "${leg_start_date} ${save_ic_date_offset[$i]}" +%Y%m%d)
  106. save_ic_date[$i]=$(date -uR -d "${save_ic_date1[$i]}")
  107. save_ic_sec[$i]=$(( $(date -d "${save_ic_date[$i]}" +%s) - $(date -d "${run_start_date}" +%s) ))
  108. # Correct for leap days because NEMO standalone uses no-leap calendar
  109. has_config nemo && ! has_config ifs && save_ic_sec[$i]=$(( save_ic_sec[$i] - $(leap_days "${run_start_date}" "${save_ic_date[$i]}")*24*3600 ))
  110. save_ic_day[$i]=$(( ${save_ic_sec[$i]} / 86400 ))
  111. has_config ifs && save_ic_ppt_files[$i]="ppt"$(printf %06d ${save_ic_day[$i]})"0000"
  112. has_config nemo && save_ic_nemo_ts[$i]=$(( save_ic_sec[$i] / nem_time_step_sec ))
  113. # sanity checks
  114. if [ ${save_ic_sec[$i]} -eq 0 ]
  115. then
  116. info "Initial conditions cannot be created for first timestep of run"
  117. has_config ifs && save_ic_ppt_files[$i]=""
  118. has_config nemo && save_ic_nemo_ts[$i]=-1
  119. elif [ ${save_ic_sec[$i]} -eq $leg_start_sec ]
  120. then
  121. if has_config nemo
  122. then
  123. info "Cannot create NEMO ICs for first timestep of leg at save_ic_date1[$i], will use restarts from previous leg"
  124. save_ic_nemo_ts[$i]=-1
  125. fi
  126. fi
  127. # if saving ICs at the end of the leg, set ifs_lastout=true
  128. if [ ${save_ic_sec[$i]} -eq $leg_end_sec ]
  129. then
  130. if $(has_config ifs) && ! ${save_ic_ifs_lastout_orig}
  131. then
  132. ifs_lastout=true
  133. save_ic_ifs_lastout=true
  134. fi
  135. fi
  136. done
  137. fi
  138. }
  139. # prepare output configuration (NEMO namelist, IFS ppt file)
  140. function save_ic_prepare_output()
  141. {
  142. # For NEMO this is handled in the namelist variables ln_rst_list and nn_stocklist in namelist.nemo.ref.sh
  143. if has_config nemo
  144. then
  145. nemo_stocklist=""
  146. #for (( i=0; i< ${#save_ic_date[@]}; i++ )) ; do nemo_stocklist+=$(( save_ic_sec[$i] / nem_time_step_sec )), ; done
  147. for (( i=0; i< ${#save_ic_date[@]}; i++ ))
  148. do
  149. [ ${save_ic_nemo_ts[$i]} -ne -1 ] && nemo_stocklist+=${save_ic_nemo_ts[$i]},
  150. done
  151. nemo_stocklist+=$(( leg_end_sec / nem_time_step_sec )),
  152. for (( i=${#save_ic_date[@]}; i<9 ; i++ )) ; do nemo_stocklist+=0, ; done
  153. nemo_stocklist+=$'\n'
  154. fi
  155. # For IFS we need to create links to special ppt file
  156. if has_config ifs
  157. then
  158. # create the special ppt file
  159. save_ic_ppt_filename=pptdddddd0000_save_ic
  160. save_ic_ppt_ifile=pptdddddd0000 # change this for e.g. primavera
  161. # these are the codes which must be added to the special ppt file used for generating
  162. # required IFS model-level output at each requested timestep
  163. save_ic_MFP2DF_param_ids="129,152"
  164. save_ic_MFPPHY_param_ids="139,170,183,236,39,40,41,42,141,198,235,31,238,32,33,34,35,36,37,38,148,172,173,174,15,17,16,18,66,67,74,43,160,161,162,163,234,28,27,30,29" #all variables needed
  165. #save_ic_MFPPHY_param_ids="198,36,37,38,148,172,173,174,15,17,16,18,66,67,74,43,160,161,162,163,234,28,27,30,29" #all variables (old)
  166. #save_ic_MFPPHY_param_ids="198,36,37,38,148,172,173,174,15,17,16,18,74,43,160,161,162,163,234" #trunk
  167. #save_ic_MFPPHY_param_ids="173,174,15,17,16,18,66,67,74,43,160,161,162,163,234,28,27,30,29" #primavera
  168. save_ic_filter_param_ids=""
  169. # get requested output codes as a single line without space and without the last comma
  170. NFPPHY=`grep NFPPHY postins/$save_ic_ppt_ifile | sed -e 's/^\s*NFPPHY\s*=\s*//' -e 's/[,]$//'`
  171. MFPPHY=$(sed -e '1h;2,$H;$!d;g' -re 's/.*MFPPHY *=([0-9,\. \n]+).*/\1/' -e 's/[ \n]//g' -e 's/,$//' <postins/$save_ic_ppt_ifile)
  172. [[ $MFPPHY == "" ]] && error "IFS ppt file postins/$save_ic_ppt_ifile does not contain any entries in MFPPHY."
  173. NFP2DF=`grep NFP2DF postins/$save_ic_ppt_ifile | sed -e 's/^\s*NFP2DF\s*=\s*//' -e 's/[,]$//'`
  174. MFP2DF=$(sed -e '1h;2,$H;$!d;g' -re 's/.*MFP2DF *=([0-9,\. \n]+).*/\1/' -e 's/[ \n]//g' -e 's/,$//' <postins/$save_ic_ppt_ifile)
  175. [[ $MFP2DF == "" ]] && NFP2DF=0 && MFP2DF=","
  176. IFS=","
  177. old_MFPPHY_params=( ${MFPPHY} )
  178. old_MFP2DF_params=( ${MFP2DF} )
  179. new_MFPPHY_params=( ${save_ic_MFPPHY_param_ids} )
  180. new_MFP2DF_params=( ${save_ic_MFP2DF_param_ids} )
  181. unset IFS
  182. # update requested output codes by adding necessary variables
  183. for new_param_id in ${new_MFPPHY_params[@]}
  184. do
  185. new_param_id=`printf "%0*d" 3 $new_param_id`
  186. found=false
  187. for old_param_id in ${old_MFPPHY_params[@]}
  188. do
  189. old_param_id=`printf "%03g" $old_param_id`
  190. [ ${old_param_id} -eq ${new_param_id} ] && found=true && break
  191. done
  192. if ! $found
  193. then
  194. NFPPHY=$(( $NFPPHY + 1 ))
  195. MFPPHY="${MFPPHY},$new_param_id"
  196. save_ic_filter_param_ids="${save_ic_filter_param_ids}$new_param_id,"
  197. fi
  198. done
  199. for new_param_id in ${new_MFP2DF_params[@]}
  200. do
  201. new_param_id=`printf "%0*d" 3 $new_param_id`
  202. found=false
  203. for old_param_id in ${old_MFP2DF_params[@]}
  204. do
  205. old_param_id=`printf "%03g" $old_param_id`
  206. [ ${old_param_id} -eq ${new_param_id} ] && found=true && break
  207. done
  208. if ! $found
  209. then
  210. NFP2DF=$(( $NFP2DF + 1 ))
  211. MFP2DF="${MFP2DF},$new_param_id"
  212. fi
  213. done
  214. # create special ppt file with modified codes from original ppt file
  215. sed -r -e '1h;2,$H;$!d;g' \
  216. -e 's|(NFPPHY\s*=)[0-9 ]+|\1'${NFPPHY}'|' \
  217. -e 's|(MFPPHY\s*=)[0-9, \n]+\n|\1'${MFPPHY}',\n|' \
  218. -e 's|(NFP2DF\s*=)\s*[0-9]+|\1'${NFP2DF}'|' \
  219. -e 's|(MFP2DF\s*=)[0-9, \n]+\n|\1'${MFP2DF}',\n|' \
  220. -e 's|NFP3DFS\s*=\s*[0-9]+,||' \
  221. -e 's|MFP3DFS\s*=[0-9, \n]+\n|\n|' \
  222. -e 's|NRFP3S\s*=\s*\-?[0-9]+,||' \
  223. -e 's/&NAMFPC/\&NAMFPC\n NFP3DFS = 9,\n MFP3DFS = 133,75,76,246,247,248,138,155,130,\n NRFP3S = -99\n NFP2DF = 2,\n MFP2DF = 152,129,/' \
  224. <postins/$save_ic_ppt_ifile >postins/${save_ic_ppt_filename}
  225. # cleanup existing links from previous legs (required when save_ic_ifs_lastout=true)
  226. ls -ltr postins
  227. find -L postins/ -xtype l -samefile postins/${save_ic_ppt_filename} -exec rm {} \;
  228. # create links to ppt file for all requested timesteps
  229. for (( i=0; i< ${#save_ic_date[@]}; i++ ))
  230. do
  231. if [ ! -f postins/$save_ic_ppt_filename ]
  232. then
  233. error "IFS IC file $save_ic_ppt_filename does not exist."
  234. elif [ "${save_ic_ppt_files[$i]}" != "" ] ; then
  235. ln -sf $save_ic_ppt_filename postins/${save_ic_ppt_files[$i]}
  236. fi
  237. done
  238. /bin/ls -1 postins/* > dirlist
  239. ls -ltr postins
  240. fi
  241. }
  242. # post-process save_ic results
  243. function save_ic_postproc()
  244. {
  245. # cleanup existing links for subsequent legs (see issue #345)
  246. if has_config ifs
  247. then
  248. ls -ltr postins
  249. find -L postins/ -xtype l -samefile postins/${save_ic_ppt_filename} -exec rm {} \;
  250. /bin/ls -1 postins/* > dirlist
  251. ls -ltr postins
  252. fi
  253. for (( i=0; i< ${#save_ic_date[@]}; i++ ))
  254. do
  255. outdir="save_ic/"${save_ic_date1[$i]}
  256. # save IFS ICs
  257. if has_config ifs
  258. then
  259. [ "${save_ic_ppt_files[$i]}" != "" ] && save_ic_ifs_out2init $i
  260. fi
  261. # copy oasis restarts
  262. if has_config oasis
  263. then
  264. # copy oasis restarts if this is the last or first timestep of the leg
  265. # oasis files depend on the components and configuration
  266. # so they go in their own sub-directory, easier to separate from ifs and nemo files
  267. if [ ${save_ic_sec[$i]} -eq $leg_end_sec ]
  268. then
  269. mkdir -p ${outdir}/oasis
  270. for f in ${oas_rst_files} ; do test -f ${f} && cp ${f} ${outdir}/oasis ; done
  271. elif [ ${save_ic_sec[$i]} -eq $leg_start_sec ]
  272. then
  273. mkdir -p ${outdir}/oasis
  274. oas_rst_dir="restart/oasis/$(printf %03d $((leg_number)))"
  275. for f in ${oas_rst_files} ; do test -f ${oas_rst_dir}/${f} && cp ${oas_rst_dir}/${f} ${outdir}/oasis ; done
  276. fi
  277. fi
  278. # copy NEMO restarts
  279. if has_config nemo
  280. then
  281. nemo_ts=$(( save_ic_sec[$i] / nem_time_step_sec ))
  282. ns=$(printf %08d $(( nemo_ts - nem_restart_offset )))
  283. # copy each restart type seperately, depending on config
  284. extensions="oce"
  285. has_config lim3 && extensions+=" ice"
  286. has_config pisces && extensions+=" trc"
  287. for ext in $extensions
  288. do
  289. if ls ${exp_name}_${ns}_restart_${ext}_????.nc > /dev/null 2>&1
  290. then
  291. mkdir -p ${outdir}/nemo
  292. if [[ ${save_ic_sec[$i]} -eq $leg_start_sec ]] || [[ ${save_ic_sec[$i]} -eq $leg_end_sec ]]
  293. then
  294. cp -f ${exp_name}_${ns}_restart_${ext}_????.nc ${outdir}/nemo
  295. else
  296. mv -f ${exp_name}_${ns}_restart_${ext}_????.nc ${outdir}/nemo
  297. fi
  298. else
  299. error "Cannot find NEMO ($ext) initial conditions for date ${save_ic_date1[$i]}"
  300. fi
  301. done
  302. fi
  303. # copy TM5 restarts
  304. leg_end_date_yyyymmdd=$(date -u -d "${leg_end_date}" +%Y%m%d)
  305. if has_config tm5 && [[ $leg_end_date_yyyymmdd == ${save_ic_date1[$i]} ]]
  306. then
  307. found=false
  308. for f in TM5_restart_${leg_end_date_yyyymmdd}_0000_glb300x200.nc save_${leg_end_date_yyyymmdd}00_glb300x200.hdf
  309. do
  310. if [[ -f "$f" ]] ; then
  311. mkdir -p ${outdir}/tm5
  312. cp -f $f ${outdir}/tm5
  313. found=true
  314. fi
  315. done
  316. ! $found && error "Cannot find TM5 restarts for date ${save_ic_date1[$i]}" || true
  317. fi
  318. done
  319. }
  320. # Function to create IC files for IFS from special output based on a script from K. Wyser
  321. function save_ic_ifs_out2init()
  322. {
  323. icdate=${save_ic_date1[$1]}
  324. #srcdir=$2
  325. filter_output=true
  326. grib_filter=${GRIB_BIN_PATH}${GRIB_BIN_PATH:+/}grib_filter
  327. # temporary directory
  328. tmpdir=tmp_save_ic
  329. [ -d $tmpdir ] && rm -rf ${tmpdir}
  330. mkdir -p $tmpdir
  331. # first IFS timestep of a month is saved in last output file
  332. if [[ "$(date -d "${icdate}" +%d)" == "01" ]] ; then
  333. yyyymm=$(date -d "${icdate} - 6 hours" +%Y%m)
  334. else
  335. yyyymm=$(date -d "${icdate}" +%Y%m)
  336. fi
  337. # find the ICMSH/GG files containing the last timestep, which are in $srcdir/output/ifs/???
  338. #local ifile_sh=`find $srcdir -name ICMSH${exp_name}+$yyyymm -print -quit`
  339. #local ifile_gg=`find $srcdir -name ICMGG${exp_name}+$yyyymm -print -quit`
  340. ifile_sh=ICMSH${exp_name}+$yyyymm
  341. ifile_gg=ICMGG${exp_name}+$yyyymm
  342. if [[ ! -f "$ifile_sh" ]] ; then error "cannot find ICMSH file $ifile_sh to create initial conditions at $icdate!" ; return 0 ; fi
  343. if [[ ! -f "$ifile_gg" ]] ; then error "cannot find ICMGG file $ifile_gg to create initial conditions at $icdate!" ; return 0 ; fi
  344. if $filter_output
  345. then
  346. # define grib filters to separate data for IC from normal output
  347. # filter_time_init is to define which timestep contains the ICs, currently only one per month is supported
  348. filter_time_init="dataDate == ${icdate} && dataTime == 0"
  349. # filter_time_out is to filter any timesteps which might contain ICs
  350. filter_time_out="dataTime == 0 && ( 0 "
  351. for (( j=0; j< ${#save_ic_date[@]}; j++ )) ; do filter_time_out+=" || ( dataDate == ${save_ic_date1[$j]} )"; done
  352. filter_time_out+=" )"
  353. $save_ic_ifs_lastout && filter_last="( dataTime == 0 ) && ( dataDate == ${save_ic_date1[$((j-1))]} )" || filter_last="0"
  354. # build expression to filter the paramIDs which we have to filter out, set them in ini_filter_param_ids in the runscript
  355. #save_ic_filter_param_ids="198,36,37,38,148,172,173,174,15,17,16,18,74,43,160,161,162,163,234"
  356. filter_params="1"
  357. IFS=","
  358. for p in $save_ic_filter_param_ids ; do filter_params+=" && paramId != $p" ; done
  359. unset IFS
  360. # SH file
  361. ofile_sh_init=${tmpdir}/sh_init.grb
  362. ofile_sh_out=${tmpdir}/sh_out.grb
  363. ofile_sh_last=${tmpdir}/sh_last.grb
  364. filter_sh=${tmpdir}/filter_sh
  365. write_sh_init="if ( $filter_time_init ) { write \"${ofile_sh_init}\"; }"
  366. write_sh_out="if ( $filter_last ) { write \"${ofile_sh_last}\"; } else { write \"${ofile_sh_out}\"; }"
  367. cat > $filter_sh << EOT
  368. if ( ! ( $filter_time_out ) ) { write "${ofile_sh_out}"; }
  369. else {
  370. if ( typeOfLevel is "hybrid" ) { ${write_sh_init}; }
  371. else { ${write_sh_out}; }
  372. }
  373. EOT
  374. #GG file
  375. ofile_gg_init=${tmpdir}/gg_init.grb
  376. ofile_gg_out=${tmpdir}/gg_out.grb
  377. ofile_gg_last=${tmpdir}/gg_last.grb
  378. filter_gg=${tmpdir}/filter_gg
  379. write_gg_init="if ( $filter_time_init ) { write \"${ofile_gg_init}\"; }"
  380. write_gg_out="if ( $filter_last ) { write \"${ofile_gg_last}\"; } else { write \"${ofile_gg_out}\"; }"
  381. cat > $filter_gg << EOT
  382. if ( ! ( $filter_time_out ) ) { write "${ofile_gg_out}"; }
  383. else {
  384. if ( levelType is "ml" ) { ${write_gg_init}; }
  385. else {
  386. if ( levelType is "pl" ) { ${write_gg_out}; }
  387. else {
  388. if ( $filter_params ) {
  389. ${write_gg_init};
  390. ${write_gg_out};
  391. }
  392. else {
  393. ${write_gg_init};
  394. }
  395. }
  396. }
  397. }
  398. EOT
  399. #run grib_filter on SH and GG files
  400. $grib_filter $filter_sh $ifile_sh
  401. $grib_filter $filter_gg $ifile_gg
  402. if [[ ! -f "$ofile_sh_init" ]] ; then error "ICMSH file $ifile_sh does not contain data to create initial conditions at $icdate" ; return 0 ; fi
  403. if [[ ! -f "$ofile_gg_init" ]] ; then error "ICMGG file $ifile_gg does not contain data to create initial conditions at $icdate" ; return 0 ; fi
  404. #rename files
  405. ifile_sh=${tmpdir}/$(basename $ifile_sh)
  406. ifile_gg=${tmpdir}/$(basename $ifile_gg)
  407. mv ${ofile_sh_init} ${ifile_sh}
  408. mv ${ofile_gg_init} ${ifile_gg}
  409. #srcdir=${tmpdir}
  410. fi # $filter_output
  411. if [[ ! -f "$ifile_sh" ]] ; then error "cannot find ICMSH file $ifile_sh to create initial conditions at $icdate!" ; return 0 ; fi
  412. if [[ ! -f "$ifile_gg" ]] ; then error "cannot find ICMGG file $ifile_gg to create initial conditions at $icdate!" ; return 0 ; fi
  413. tgtdir=save_ic/$icdate/ifs
  414. ofile_sh=${tgtdir}/ICMSH${exp_name}INIT
  415. ofile_gg_init=${tgtdir}/ICMGG${exp_name}INIT
  416. ofile_gg_iniua=${tgtdir}/ICMGG${exp_name}INIUA
  417. # make sure the output folder is created and delete any existing files
  418. #[ -d $tgtdir ] && rm -rf ${tgtdir}/* || mkdir -p $tgtdir
  419. mkdir -p $tgtdir
  420. rm -f $ofile_sh $ofile_gg_init $ofile_gg_iniua
  421. cat > ${tmpdir}/gf1 << EOT
  422. if ( typeOfLevel is "hybrid" ) { write "${tmpdir}/shinit.[shortName].[level]"; }
  423. EOT
  424. $grib_filter ${tmpdir}/gf1 $ifile_sh
  425. cp -f ${tmpdir}/shinit.lnsp.1 $ofile_sh
  426. for lev in {1..91}
  427. do
  428. for var in vo d t
  429. do
  430. cat ${tmpdir}/shinit.$var.$lev >> $ofile_sh
  431. done
  432. done
  433. cat ${tmpdir}/shinit.z.1 >> $ofile_sh
  434. cat > ${tmpdir}/gf2 << EOT
  435. write "${tmpdir}/gginit.[shortName]";
  436. EOT
  437. $grib_filter ${tmpdir}/gf2 $ifile_gg
  438. for var in stl1 stl2 stl3 stl4 swvl1 swvl2 swvl3 swvl4 sd src skt ci tsn asn \
  439. rsn sst istl1 istl2 istl3 istl4 chnk lsm sr al aluvp alnip aluvd alnid \
  440. lai_lv lai_hv sdfor slt sdor isor anor slor lsrh cvh cvl tvh tvl
  441. do
  442. cat ${tmpdir}/gginit.$var >> $ofile_gg_init
  443. done
  444. cat > ${tmpdir}/gf3 << EOT
  445. write "${tmpdir}/gginiua.[shortName].[level]";
  446. EOT
  447. $grib_filter ${tmpdir}/gf3 $ifile_gg
  448. # ${tmpdir}/gginiua.o3 \ check this!
  449. for lev in {1..91}
  450. do
  451. for var in q
  452. do
  453. cat ${tmpdir}/gginiua.$var.$lev >> $ofile_gg_iniua
  454. done
  455. done
  456. for lev in {1..91}
  457. do
  458. for var in crwc cswc clwc ciwc cc
  459. do
  460. cat ${tmpdir}/gginiua.$var.$lev >> $ofile_gg_iniua
  461. done
  462. done
  463. # copy filtered files to the appropriate location
  464. if $filter_output
  465. then
  466. # move filter files to $tgtdir, in case something went wrong
  467. mv -f $filter_sh $filter_gg $tgtdir
  468. ifile_sh=$(basename $ifile_sh)
  469. ifile_gg=$(basename $ifile_gg)
  470. # keep the full output files as a backup
  471. mv -f $ifile_sh $tgtdir/${ifile_sh}-out+init
  472. mv -f $ifile_gg $tgtdir/${ifile_gg}-out+init
  473. # move the filtered output file to the runtime folder
  474. [ -f $ofile_sh_out ] && mv -f $ofile_sh_out $ifile_sh || error "save_ic_ifs_out2init - warning! SH file $ofile_sh_out missing!"
  475. [ -f $ofile_gg_out ] && mv -f $ofile_gg_out $ifile_gg || error "save_ic_ifs_out2init - warning! GG file $ofile_gg_out missing!"
  476. # keep a copy of the last timestep
  477. if $save_ic_ifs_lastout
  478. then
  479. [ -f $ofile_sh_last ] && mv -f $ofile_sh_last $tgtdir/${ifile_sh}-ifs_lastout
  480. [ -f $ofile_gg_last ] && mv -f $ofile_gg_last $tgtdir/${ifile_gg}-ifs_lastout
  481. fi
  482. fi #$filter_output
  483. # delete tmp folder
  484. rm -rf $tmpdir
  485. echo "save_ic_ifs_out2init ended successfully, results are in $tgtdir"
  486. }