From ba05105d921358921c221d5a39be17156f37ea3a Mon Sep 17 00:00:00 2001 From: flexpart <> Date: Mon, 2 Mar 2015 13:29:40 +0100 Subject: [PATCH] add preprocessing routines flex_extract_ecgate_V6.0 --- .../CONTROL_ERA_TEMPLATE | 38 + .../flex_extract_ecgate_V6.0/CONTROL_ERA__CV | 38 + .../flex_extract_ecgate_V6.0/CONTROL_ERA__EI | 38 + .../CONTROL_ERA__GLOBALETA | 38 + .../CONTROL_ERA__GLOBALGAUSS | 38 + .../CONTROL_ERA__HAIYAN | 38 + .../CONTROL_ERA__HIRES | 38 + .../CONTROL_OPS_TEMPLATE | 28 + .../flex_extract_ecgate_V6.0/CONTROL_OPS_V6.0 | 28 + .../CONTROL_OPS_V6.0_4V | 28 + .../ecmwf_idc_ops_body | 863 +++++++++++++++ .../ecmwf_idc_ops_ecgate | 904 ++++++++++++++++ .../ecmwf_idc_ops_header | 41 + .../ecmwf_idc_ops_header_template | 41 + .../ecmwf_idc_ops_multi_ecgate | 979 ++++++++++++++++++ .../ecmwf_idc_ops_multi_footer | 33 + .../ecmwf_idc_ops_multi_header | 83 ++ .../ecmwf_idc_ops_multi_header_template | 83 ++ .../flex_extract_ecgate_V6.0/flex_ecmwf_CV | 873 ++++++++++++++++ .../flex_extract_ecgate_V6.0/flex_ecmwf_EI | 873 ++++++++++++++++ .../flex_ecmwf_GLOBALETA | 873 ++++++++++++++++ .../flex_ecmwf_GLOBALGAUSS | 873 ++++++++++++++++ .../flex_ecmwf_HAIYAN | 873 ++++++++++++++++ .../flex_extract_ecgate_V6.0/flex_ecmwf_HIRES | 873 ++++++++++++++++ .../flex_extract_ecgate_V6.0/flex_ecmwf_body | 768 ++++++++++++++ .../flex_ecmwf_header | 67 ++ .../flex_ecmwf_header_template | 67 ++ .../flex_extract_ecgate_V6.0/source.tar | Bin 0 -> 348160 bytes .../submit_examples.ksh | 43 + .../update_script.ksh | 106 ++ .../flex_extract_ecgate_V6.0/upload_source | 8 + 31 files changed, 9674 insertions(+) create mode 100644 preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA_TEMPLATE create mode 100644 preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__CV create mode 100644 preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__EI create mode 100644 preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__GLOBALETA create mode 100644 preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__GLOBALGAUSS create mode 100644 preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__HAIYAN create mode 100644 preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__HIRES create mode 100644 preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_TEMPLATE create mode 100644 preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_V6.0 create mode 100644 preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_V6.0_4V create mode 100644 preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_body create mode 100644 preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_ecgate create mode 100644 preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_header create mode 100644 preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_header_template create mode 100644 preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_ecgate create mode 100644 preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_footer create mode 100644 preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_header create mode 100644 preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_header_template create mode 100644 preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_CV create mode 100644 preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_EI create mode 100644 preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_GLOBALETA create mode 100644 preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_GLOBALGAUSS create mode 100644 preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_HAIYAN create mode 100644 preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_HIRES create mode 100644 preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_body create mode 100644 preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_header create mode 100644 preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_header_template create mode 100644 preprocessing/flex_extract_ecgate_V6.0/source.tar create mode 100755 preprocessing/flex_extract_ecgate_V6.0/submit_examples.ksh create mode 100644 preprocessing/flex_extract_ecgate_V6.0/update_script.ksh create mode 100644 preprocessing/flex_extract_ecgate_V6.0/upload_source diff --git a/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA_TEMPLATE b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA_TEMPLATE new file mode 100644 index 00000000..1227e9bf --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA_TEMPLATE @@ -0,0 +1,38 @@ +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 1000 +M_LEFT -179000 +M_LOWER -90000 +M_UPPER 90000 +M_RIGHT 180000 +M_LEVEL 137 +M_RESOL 159 +M_GAUSS 1 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 0 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EN +GATEWAY xxx.xxx.xxx.xxx +DESTINATION xxx@xxx +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_Vv.v +EOF diff --git a/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__CV b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__CV new file mode 100644 index 00000000..4b4aa161 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__CV @@ -0,0 +1,38 @@ +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV +M_TIME 00 00 00 00 00 00 00 00 00 00 00 00 12 12 12 12 12 12 12 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 06 07 08 09 10 11 00 01 02 03 04 05 06 07 08 09 10 11 +M_CLASS OD +M_STREAM ENFO +M_NUMBER 1 +M_EXPVER 1 +M_GRID 1000 +M_LEFT -179000 +M_LOWER -90000 +M_UPPER 90000 +M_RIGHT 180000 +M_LEVEL 62 +M_RESOL 159 +M_GAUSS 1 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 0 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EG +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF diff --git a/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__EI b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__EI new file mode 100644 index 00000000..c2acbb71 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__EI @@ -0,0 +1,38 @@ +DAY1 20121107 +DAY2 20121108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS EI +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 1000 +M_LEFT -179000 +M_LOWER -90000 +M_UPPER 90000 +M_RIGHT 180000 +M_LEVEL 60 +M_RESOL 159 +M_GAUSS 1 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 0 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EI +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF diff --git a/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__GLOBALETA b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__GLOBALETA new file mode 100644 index 00000000..50d9a585 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__GLOBALETA @@ -0,0 +1,38 @@ +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 1000 +M_LEFT -179000 +M_LOWER -90000 +M_UPPER 90000 +M_RIGHT 180000 +M_LEVEL 137 +M_RESOL 159 +M_GAUSS 0 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 1 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EE +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF diff --git a/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__GLOBALGAUSS b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__GLOBALGAUSS new file mode 100644 index 00000000..e250d255 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__GLOBALGAUSS @@ -0,0 +1,38 @@ +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 1000 +M_LEFT -179000 +M_LOWER -90000 +M_UPPER 90000 +M_RIGHT 180000 +M_LEVEL 137 +M_RESOL 159 +M_GAUSS 1 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 0 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EG +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF diff --git a/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__HAIYAN b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__HAIYAN new file mode 100644 index 00000000..8e5cfbdb --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__HAIYAN @@ -0,0 +1,38 @@ +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 200 +M_LEFT 113000 +M_LOWER 00000 +M_UPPER 30000 +M_RIGHT 190000 +M_LEVEL 137 +M_RESOL 799 +M_GAUSS 0 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 1 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EH +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF diff --git a/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__HIRES b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__HIRES new file mode 100644 index 00000000..a76207b1 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_ERA__HIRES @@ -0,0 +1,38 @@ +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 200 +M_LEFT -10000 +M_LOWER 30000 +M_UPPER 60000 +M_RIGHT 30000 +M_LEVEL 137 +M_RESOL 799 +M_GAUSS 0 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 1 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EH +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF diff --git a/preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_TEMPLATE b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_TEMPLATE new file mode 100644 index 00000000..b216923b --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_TEMPLATE @@ -0,0 +1,28 @@ +M_TYPE AN FC FC FC FC FC FC FC FC FC FC FC AN FC FC FC FC FC FC FC FC FC FC FC FC +M_TIME 00 00 00 00 00 00 00 00 00 00 00 00 12 12 12 12 12 12 12 12 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 06 07 08 09 10 11 00 01 02 03 04 05 06 07 08 09 10 11 12 +DTIME 1 +PREFIX EN +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_GRID 1000 +M_RESOL 255 +M_SMOOTH 0 +M_GAUSS 0 +M_ETA 1 +M_ETAPAR 77 +M_DPDETA 1 +M_LEVEL 137 +M_LEVELIST 1/to/137 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +M_FORMAT GRIB1 +GATEWAY xxx.xxx.xxx.xxx +DESTINATION xxx@xxx +ECSTORAGE 1 +ECTRANS 1 +ECFSDIR ectmp:/xxx/ecops +MAILOPS xxx +MAILFAIL xxx +EXEDIR . +SOURCECODE /home/ms/ggg/xxx/flex_extract_ecgate_Vv.v diff --git a/preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_V6.0 b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_V6.0 new file mode 100644 index 00000000..d082d52e --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_V6.0 @@ -0,0 +1,28 @@ +M_TYPE AN FC FC FC FC FC FC FC FC FC FC FC AN FC FC FC FC FC FC FC FC FC FC FC FC +M_TIME 00 00 00 00 00 00 00 00 00 00 00 00 12 12 12 12 12 12 12 12 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 06 07 08 09 10 11 00 01 02 03 04 05 06 07 08 09 10 11 12 +DTIME 1 +PREFIX EN +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_GRID 1000 +M_RESOL 255 +M_SMOOTH 0 +M_GAUSS 0 +M_ETA 1 +M_ETAPAR 77 +M_DPDETA 1 +M_LEVEL 137 +M_LEVELIST 1/to/137 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +M_FORMAT GRIB1 +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 1 +ECFSDIR ectmp:/lh0/ecops +MAILOPS lh0 +MAILFAIL lh0 +EXEDIR . +SOURCECODE /home/ms/spatlh00/lh0/flex_extract_ecgate_V6.0 diff --git a/preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_V6.0_4V b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_V6.0_4V new file mode 100644 index 00000000..4951f0d8 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/CONTROL_OPS_V6.0_4V @@ -0,0 +1,28 @@ +M_TYPE AN FC FC FC FC FC FC FC FC FC FC FC AN FC FC FC FC FC FC FC FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 09 00 00 09 12 12 12 12 12 18 12 12 21 12 12 21 +M_STEP 00 01 02 03 04 05 00 07 08 00 10 11 03 01 02 03 04 05 00 07 08 00 10 11 03 +DTIME 3 +PREFIX EN +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_GRID 1000 +M_RESOL 255 +M_SMOOTH 179 +M_GAUSS 1 +M_ETA 0 +M_ETAPAR 77 +M_DPDETA 1 +M_LEVEL 137 +M_LEVELIST 1/to/137 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +M_FORMAT GRIB1 +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 1 +ECFSDIR ectmp:/lh0/ecops +MAILOPS lh0 +MAILFAIL lh0 +EXEDIR . +SOURCECODE /home/ms/spatlh00/lh0/flex_extract_ecgate_V6.0 diff --git a/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_body b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_body new file mode 100644 index 00000000..4ecdc4c3 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_body @@ -0,0 +1,863 @@ +# no changes below + +NRW=0 + +#ksh scripts for date manipulation +juldate2() + { + let jc=$1 + if (( ${#jc} < 8 )) + then + print "illegal date!" + exit 1 + fi + let y=`echo $jc | cut -c1-4` + let m1=`echo $jc | cut -c5` + let m2=`echo $jc | cut -c6` + m=$m1$m2 + let d1=`echo $jc | cut -c7` + let d2=`echo $jc | cut -c8` + d=$d1$d2 + let jd=367*y-7*(y+(m+9)/12)/4+275*m/9+d+1721014 + let jd=jd+15-3*((y+(m-9)/7)/100+1)/4 + print $jd + } + +civildate2() + { + let jd=$1 + if (( jd < 1721060 )) + then + print "Julian date not in AD." + exit 1 + fi + let k=jd+68569 + let n=4*k/146097 + let k=k-\(146097*n+3\)/4 + let y=4000*(k+1)/1461001 + let k=k-1461*y/4+31 + let m=80*k/2447 + let d=k-\(2447*m\)/80 + let k=m/11 + let m=m+2-12*k + let y=100*(n-49)+y+k + [ $m -le 9 ] && m=0$m + [ $d -le 9 ] && d=0$d + print $y$m$d + } + +date2m1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-1 + civildate2 $j0 + } + +date2p1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1+1 + civildate2 $j0 + } + +date2m14() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-14 + civildate2 $j0 + } + +marsinst() +{ +MTYPE="${1}" +MDAY="${2}" +MTIME="${3}" +MSTEP="${4}" +MPAR="${5}" +MFN=$6 +MLTY=$7 +MGRID="${8}" +MLEV="${9}" + +#if [[ ${MPAR} == 'LNSP' ]] ; then +# MLEV=1 +#else +# if [[ ${MLTY} == 'SFC' ]] ; then +# MLEV=OFF +# else +# MLEV=${M_LEVELIST} +# fi +#fi + +RED=0 +#if [[ ${MTYPE} != 'AN' ]] ; then + MPAR2=`echo ${MPAR} | sed s,160/,,` + MPAR2=`echo ${MPAR2} | sed s,27/,,` + MPAR2=`echo ${MPAR2} | sed s,28/,,` + MPAR2=`echo ${MPAR2} | sed s,173/,,` + if [[ ${MPAR2} != ${MPAR} ]] ; then + MPAR=${MPAR2} + RED=1 + fi +#fi + +MAREA=${M_AREA} +if [[ ${10} == 'GAUSSIAN=REDUCED,' ]] ; then + MAREA=G +fi + +if [[ -f ${MFN} ]] ; then + rm ${MFN} +fi + +cat <<EOF >> marsjob +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=${MPAR}, +RESOL=${M_RESOL}, +AREA=${MAREA}, +GRID=${MGRID}, +LEVTYPE=${MLTY}, +LEVELIST=${MLEV}, +ACCURACY=${M_ACCURACY}, +DATE=${MDAY}, +TIME=${MTIME}, +STEP=${MSTEP},${10} +TARGET="${MFN}" +EOF + +if [[ ! -f 'OROLSM' && $RED -eq 1 ]] ; then + +cat <<EOF >> marsjob +RETRIEVE,TYPE=AN,TIME=0,STEP=0,CLASS=OD, + PARAM=160/27/28/173, + TARGET="OROLSM" +EOF +fi + +} + +marsflux() +{ +MTYPE="${1}" +MSTEP="${2}" + +#if [[ ! -f "surf_${M_STEP}_ub" ]] ; then +cat <<EOF >>mars_flux +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=LSP/CP/SSHF/EWSS/NSSS/SSR, +AREA=${M_AREA}, +GRID=${D_GRID}, +LEVTYPE=SFC, +LEVELIST=OFF, +ACCURACY=${M_ACCURACY}, REPRES=GG, +DATE=${DAY1M1}/TO/${DAY2P1}, +TIME=00/12, +AC=N, +STEP=${MSTEP}, +TARGET="surf_${MSTEP}_ub" +EOF + +if [[ $MSJ_BASETIME == 00 ]] ; then + DAY2P2=`date2p1 ${DAY2P1}` + cat <<EOF >>mars_flux +RETRIEVE, +DATE=${DAY2P2}, +TIME=00, +TARGET="surf_${MSTEP}_ub" +EOF +fi +#fi +} + + +myerror() + { + + echo $1 + echo $2 + echo $3 + echo ABORT! + + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + + exit 1 + } + +# +# MAIN SCRIPT CONTINUES HERE +# +#read CONTROL file, process specifications +while read NAME PARA +do + +if [[ $NAME == 'M_TYPE' || $NAME == 'M_TIME' || $NAME == 'M_STEP' ]] ; then + eval "set -A $NAME $PARA" +else + eval "export $NAME='$PARA'" +fi +echo `echo $NAME`=$PARA + +done <${CONTROLFILE} + + +#defaults +[ -z "$M_EXPVER" ] && M_EXPVER=1 +[ -z "$M_CLASS" ] && M_CLASS=OD +[ -z "$M_STREAM" ] && M_STREAM=OPER +[ -z "$M_NUMBER" ] && M_NUMBER=OFF +[ -z "$M_TYPE" ] && set -A M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +[ -z "$M_TIME" ] && set -A M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +[ -z "$M_STEP" ] && set -A M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +[ -z "$DTIME" ] && DTIME=6 +[ -z "$M_GRID" ] && M_GRID=1000 +[ -z "$M_LOWER" ] && M_LOWER=-90000 +[ -z "$M_LEFT" ] && M_LEFT=-179000 +[ -z "$M_UPPER" ] && M_UPPER=90000 +[ -z "$M_RIGHT" ] && M_RIGHT=180000 +[ -z "$M_LEVEL" ] && M_LEVEL=91 +[ -z "$M_LEVELIST" ] && M_LEVELIST=1/TO/$M_LEVEL +[ -z "$M_ADDPAR" ] && M_ADDPAR='' +[ -z "$M_RESOL" ] && M_RESOL=799 +[ -z "$M_GAUSS" ] && M_GAUSS=0 +[ -z "$M_SMOOTH" ] && M_SMOOTH=0 +[ -z "$M_OMEGA" ] && M_OMEGA=0 +[ -z "$M_OMEGADIFF" ] && M_OMEGADIFF=0 +[ -z "$M_ETA" ] && M_ETA=0 +[ -z "$M_ETADIFF" ] && M_ETADIFF=0 +[ -z "$M_ETAPAR" ] && M_ETAPAR=77 +[ -z "$M_DPDETA" ] && M_DPDETA=1 +[ -z "$M_ACCURACY" ] && M_ACCURACY=24 +[ -z "$EXEDIR" ] && EXEDIR=. +[ -z "$SOURCECODE" ] && SOURCECODE=ecgate:flex_extract_ecgate +[ -z "$GATEWAY" ] && GATEWAY='' +[ -z "$DESTINATION" ] && DESTINATION='' +[ -z "$PREFIX" ] && PREFIX=EN +[ -z "$COMPRESSION" ] && COMPRESSION=grid_simple +[ -z "$ECTRANS" ] && ECTRANS=0 +[ -z "$ECSTORAGE" ] && ECSTORAGE=1 +[ -z "$ECFSDIR" ] && ECFSDIR=ectmp: +[ -z "$MAILOPS" ] && MAILOPS=${USER} +[ -z "$MAILFAIL" ] && MAILFAIL=${USER} + + +export MARS_MULTITARGET_STRICT_FORMAT=1 + +if [ $M_GAUSS -eq 1 ] ; then + export SCRATCHDIR=${SCRATCH}/ctbto_run_ecgate-${DTIME}hrs-G_V${VERSION} + mkdir $SCRATCHDIR >/dev/null +else + export SCRATCHDIR=${SCRATCH}/ctbto_run_ecgate-${DTIME}hrs-L_V${VERSION} + mkdir $SCRATCHDIR >/dev/null +fi + +# +# cleanup +# +#\rm -f $SCRATCHDIR/* +\rm -f $SCRATCHDIR/fort* + +[ ! -d $SCRATCHDIR ] && mkdir $SCRATCHDIR +cd $SCRATCHDIR + + +DAY1=${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY} +if [ $MSJ_BASETIME -eq 00 ] ; then + DAY2=DAY1 +else + DAY2=`date2p1 ${DAY1}` +fi + +#additional dates for flux retrievals (polynomial interpolation) +DAY1M1=`date2m1 ${DAY1}` +DAY2P1=`date2m1 ${DAY2}` + +#julian dates for time loops +JULDAY1=`juldate2 ${DAY1}` +JULDAY2=`juldate2 ${DAY1}` + + +#echo 'field date :' $M_DATE_S, $M_TIME_S +#echo 'flux dates :' $FLXDT1, $FLXT1, $FLXDT2, $FLXT2 + +#take care of nameing convention +#M_DATEX=`echo ${M_DATE_S} | cut -c3-8` +#DATEREFX=`echo ${DATEREF} | cut -c3-8` + +# determine number of gridpoints and whether grid is cyclic +ZYK=`expr \( $M_RIGHT + 360000 \) % 360000 - \( $M_LEFT + 360000 \) % 360000 + $M_GRID` + +if [ $M_RIGHT -le $M_LEFT ] ; then + if [ $M_RIGHT -le 0 ] ; then + M_RIGHT=$(($M_RIGHT+360000)) + else + M_LEFT=$(($M_LEFT-360000)) + fi +fi + +if [[ $ZYK -ne 0 ]] ; then + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED NON-CYCLIC" + exit 1 + fi +else + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED CYCLIC" + exit 1 + fi +fi + +if [ $((180000/$M_GRID-$M_RESOL)) -lt 0 ] ; then + + if [ ${M_SMOOTH} -eq 0 ] ; then + echo "WARNING: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SPECTRAL RESOLUTION ${M_RESOL} " "USE M_SMOOTH FOR SMOOTHING OR FINER OUTPUT GRID" +# exit 1 + else + if [ $((180000/$M_GRID-$M_SMOOTH)) -lt 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SMOOTHED SPECTRAL RESOLUTION ${M_SMOOTH} " + fi + fi + +fi + + +# convert lat/lon to MARS format (degrees) +if [[ $M_LEFT -lt 0 ]] ; then + LLLO=$(($M_LEFT / 1000)).$((($M_LEFT)*(-1) % 1000)) +else + LLLO=$(($M_LEFT / 1000)).$(($M_LEFT % 1000)) +fi +if [[ $M_LOWER -lt 0 ]] ; then + LLLA=$(($M_LOWER / 1000)).$(($M_LOWER*(-1) % 1000)) +else + LLLA=$(($M_LOWER / 1000)).$((($M_LOWER) % 1000)) +fi +if [[ $M_RIGHT -lt 0 ]] ; then + URLO=$(($M_RIGHT / 1000)).$((($M_RIGHT)*(-1) % 1000)) +else + URLO=$(($M_RIGHT / 1000)).$(($M_RIGHT % 1000)) +fi +if [[ $M_UPPER -lt 0 ]] ; then + URLA=$(($M_UPPER / 1000)).$((($M_UPPER)*(-1) % 1000)) +else + URLA=$(($M_UPPER / 1000)).$(($M_UPPER % 1000)) +fi + +M_AREA=${URLA}/${LLLO}/${LLLA}/${URLO} + +if [ $M_GAUSS -eq 1 ] ; then +# Gaussian grid detected + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=OFF + QG_GRID=OFF + if [ $M_RESOL -le 799 ] ; then + QG_GRID=$((($M_RESOL+1)/2)) + fi + D_GRID=${D_GRID}/${D_GRID} + +else + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=${G_GRID}/${G_GRID} + D_GRID=${D_GRID}/${D_GRID} +fi + +G_LEVELIST=1/to/${M_LEVEL} + + +#namelist +cat <<EOF >fort.4 +&NAMGEN + MAXL=${MAXL}, MAXB=${MAXB}, + MLEVEL=${M_LEVEL}, MLEVELIST="${M_LEVELIST}", + MNAUF=${M_RESOL},METAPAR=${M_ETAPAR}, + RLO0=${LLLO}, RLO1=${URLO}, RLA0=${LLLA}, RLA1=${URLA}, + MOMEGA=${M_OMEGA},MOMEGADIFF=${M_OMEGADIFF},MGAUSS=${M_GAUSS}, + MSMOOTH=${M_SMOOTH},META=${M_ETA},METADIFF=${M_ETADIFF}, + MDPDETA=${M_DPDETA} +/ +&NAMFX2 + NX=${MAXL}, NY=${MAXB}, + MAXTIME=400,JPOLY=4, + JHRF=${DTIME}, + RLO0=${LLLO}, RLA0=${LLLA}, DX=${D_GRID}, DY=${D_GRID} +/ +EOF + + +cp ${SOURCECODE}/source.tar . +tar -xvf source.tar +if [[ $OS_VERSION == aix ]] ; then + make -f Makefile.IBM FLXACC2 CONVERT2 CHECK +else + make -f Makefile.ecgb FLXACC2 CONVERT2 CHECK +fi + +if [ $? -ne 0 ]; then + ls + echo 'ERROR: FLXACC2 and CONVERT2 could not be compiled:' ${INFILE} + echo ABORT! + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + exit 1 +else + echo 'compile worked' +fi + + +# +#MARS requests (field) +# +imax=6 +set -A PARLIST U/V T Q LNSP SD/MSL/TCC/10U/10V/2T/2D 129/172/160${M_ADDPAR} +set -A PARNAME 131/132 130 133 152 SURF OROLSM +set -A REPR SH SH GG SH GG GG +set -A UNIT 10 11 17 12 14 20 +set -A LTY ML ML ML ML SFC SFC +set -A GRID ${G_GRID} ${D_GRID} ${D_GRID} OFF ${D_GRID} ${D_GRID} +set -A LEVELIST ${M_LEVELIST} ${M_LEVELIST} ${M_LEVELIST} 1 1 1 + +set -A FIELD 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 + + +if [[ $M_OMEGA -eq 1 || $M_OMEGADIFF -eq 1 ]] ; then + M_OMEGA=1 + PARLIST[imax]=W + PARNAME[imax]=135 + REPR[imax]=SH + UNIT[imax]=19 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 1 || $M_ETADIFF -eq 1 ]] ; then + M_ETA=1 + PARLIST[imax]=77 + PARNAME[imax]=77 + REPR[imax]=SH + UNIT[imax]=21 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi + +if [[ $M_GAUSS -eq 2 ]] ; then + PARLIST[imax]=VO + PARNAME[imax]=138 + REPR[imax]=SH + UNIT[imax]=30 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 0 || $M_GAUSS -eq 1 || $M_ETADIFF -eq 1 ]] ; then + PARLIST[imax]=D + PARNAME[imax]=155 + REPR[imax]=SH + UNIT[imax]=13 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + LEVELIST[1]=${G_LEVELIST} # U/V needed on all levels for calculating ETA + imax=$(($imax+1)) +fi + +jmax=$(( ${#M_TYPE[*]})) + +# M_TIME needs leading zeros while M_STEP must have leading zeros +# to be consistent with MARS file naming convention +# The following loop ensures this +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TIME[$j]} -lt 10 ]] ; then + M_TIME[$j]=0$((${M_TIME[$j]})) + fi + if [[ ${M_STEP[$j]} -lt 10 ]] ; then + M_STEP[$j]=$((${M_STEP[$j]})) + fi + + j=$(($j+1)) +done + +echo ${M_TIME[*]} +echo ${M_STEP[*]} + + +rm mars_flux 2>/dev/null +j=0 +while [[ $j -lt 24 ]] ; do + marsflux ${M_TYPE[2]} ${FIELD[$j]} + j=$(($j+$DTIME)) +done +mars mars_flux +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + + +# +# FLXACC job +# + + +${EXEDIR}/FLXACC2 +if [ -f OROLSM ] ; then + rm OROLSM + + +fi + +# +# CONVERT job +# + +#loop over DATE and TIME for CONVERT/CHECK/ECtrans job + +iter=0 +IJULDAY=${JULDAY1} +while [ $IJULDAY -le $JULDAY2 ]; +do + +MDATE=`civildate2 ${IJULDAY}` +if [ $MSJ_BASETIME -eq 00 ] ; then + MDATE=`date2m1 ${MDATE}` +fi + +MDATEX=`echo ${MDATE} | cut -c3-8` + + +i=0 +rm marsjob 2>/dev/null + +#humidity on reduced Gaussian grid for initialization +#of spectral transformations +if [ ${M_GAUSS} -eq 1 ] ; then + NGRID=$(( ( ${M_RESOL} + 1 ) / 2 )) + + marsinst ${M_TYPE[0]} ${DAY1} 00 00 Q fort.18 ML ${QG_GRID} 1 'GAUSSIAN=REDUCED,' + +set -e +mars marsjob +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +rm marsjob + +fi + +set -e + +if [ $MSJ_BASETIME -eq 12 ] ; then + j=$(($DTIME)) + jmax=$(($DTIME+12)) +else + j=$(($DTIME+12)) +fi +if [ $iter -eq 1 ] ; then + j=0 + jmax=1 +fi +set -A TYPEKEY ${M_TYPE[$j]} +kmax=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[j]} != ${TYPEKEY[0]} ]] ; then + if [[ $kmax == 1 ]] ; then + if [[ ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${TYPEKEY[1]} ${M_TYPE[j]} + kmax=2 + fi + else + if [[ $kmax == 0 ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${M_TYPE[j]} + kmax=1 + else + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[2]} ]] ; then + + echo ${TYPEKEY[0]} ${TYPEKEY[1]} ${TYPEKEY[2]} ${M_TYPE[j]} + myerror 'More than three different MARS TYPES not supported' + + exit 1 + fi + fi + fi + fi + fi + j=$(($j+$DTIME)) +done + +set -A GRIDKEY $D_GRID +mmax=1 +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${GRID[$i]} == 'OFF' && ${PARLIST[$i]} != LNSP ]] ; then + set -A GRIDKEY $D_GRID OFF + mmax=2 + fi + i=$(($i+1)) +done + +k=0 +kmax=$(($kmax+1)) +while [[ $k -lt $kmax ]] ; do +MMTIME='' +MMSTEP='' +TSUFF='' +SSUFF='' +j=0 +if [ $MSJ_BASETIME -eq 12 ] ; then + j=$(($DTIME)) + jmax=$(($DTIME+12)) +else + j=$(($DTIME+12)) +fi +if [ $iter -eq 1 ] ; then + j=0 + jmax=1 +fi +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[$j]} == ${TYPEKEY[$k]} ]] ; then + if [[ `echo $MMTIME | grep ${M_TIME[$j]}` == '' ]] ; then + MMTIME=${MMTIME}$TSUFF${M_TIME[$j]} + TSUFF='/' + fi + if [[ `echo $MMSTEP | grep ${M_STEP[$j]}` == '' ]] ; then + MMSTEP=${MMSTEP}$SSUFF${M_STEP[$j]} + SSUFF='/' + fi + fi +j=$(($j+$DTIME)) +done + +m=0 +while [[ $m -lt $mmax ]] ; do +MMPAR='' +PSUFF='' +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${LTY[$i]} == ML && ${GRID[$i]} == ${GRIDKEY[m]} && ${PARLIST[$i]} != LNSP ]] ; then + if [[ `echo $MMPAR | grep ${PARLIST[$i]}` == '' ]] ; then + MMPAR=${MMPAR}$PSUFF${PARLIST[$i]} + PSUFF='/' + fi + fi +i=$(($i+1)) +done + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} $MMPAR "[param].[date].[time].[step]" ML ${GRIDKEY[$m]} ${LEVELIST[$m]} + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +m=$(($m+1)) +done +# LNSP treated separately since it exists only on 1 level + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} LNSP "[param].[date].[time].[step]" ML OFF 1 + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# For some data classes, MARS adds GRIB table number to parameter number, +# e.g. for Temperature it is 130.128 instead of just 130 +# + set +e + TNR=`ls 131*${MDATE}.${M_TIME[00]}00.${M_STEP[00]} | awk -F . '{print $2}' - | grep -v ${MDATE}`. + set -e + if [[ $TNR != '.' ]] ; then + TNR=.$TNR + fi + +# SURF treated separately since it exists only on 1 level + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[4]} "SURF${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob +# OROLSM treated separately since it exists only on 1 level + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[5]} "OROLSM${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +# if [ -f OROLSM ] ; then +# for oro in `ls +# cat OROLSM >> OROLSM${TNR}${MDATE}.${MMTIME}00.${MMSTEP} +# rm OROLSM +# echo 'found' +# exit 0 +# fi + rm marsjob + +k=$(($k+1)) +done + + + + +j=0 +if [ $MSJ_BASETIME -eq 12 ] ; then + j=$(($DTIME)) + jmax=$(($DTIME+12)) +else + j=$(($DTIME+12)) +fi +if [ $iter -eq 1 ] ; then + j=0 + jmax=1 +fi +while [[ $j -lt $jmax ]] ; do + + +TIME=${FIELD[$j]} +XTIME=${TIME}00 + +set +e +i=0 +while [[ $i -lt $imax ]] ; do + \rm fort.${UNIT[$i]} 2>/dev/null + if [[ ${PARLIST[$i]} == U/V ]] ; then + cat 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} > fort.${UNIT[$i]} + rm 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} + else + mv ${PARNAME[$i]}${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} fort.${UNIT[$i]} + fi + i=$(($i+1)) +done + +# flux data need special GRIB conversion +#if [ ${M_FORMAT} == GRIB2 ] ; then +# grib_set -w shortName!=lsp,shortName!=cp,shortName!=ewss,shortName!=nsss -s edition=2,productDefinitionTemplateNumber=8 flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +# +#else +# mv flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +#fi + +${EXEDIR}/CONVERT2 + +if [ $TIME -eq 00 ]; then + MDATE=`date2p1 ${MDATE}` + MDATEX=`echo ${MDATE} | cut -c 3-8` +fi + +INFILE=${PREFIX}${MDATEX}${TIME} + +if [ -s fort.15 ]; then + cp fort.15 ${INFILE} + cat fort.14 >> ${INFILE} + cat flux${MDATE}${TIME} >> ${INFILE} + cat OROLSM >> ${INFILE} + cat fort.20 >> ${INFILE} + +# +# Convert to GRIB2 if needed +# +# to enable additional compression try +# set packingType="grid_jpeg"; +# this is rather time consuming. + +if [ ${M_FORMAT} == GRIB2 ] ; then + grib_set -s edition=2,productDefinitionTemplateNumber=8 $INFILE ${INFILE}_2 + mv ${INFILE}_2 ${INFILE} + + if [ ${COMPRESSION} != grid_simple ] ; then + +cat >rule.filter<<EOF +set packingType="${COMPRESSION}"; +write "[file]_2"; +EOF + grib_filter rule.filter ${INFILE} + mv ${INFILE}_2 ${INFILE} + fi +fi +ls -l ${INFILE} + +else + echo ERROR: ENfile ${INFILE} missing! + echo ABORT! + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + exit 1 +fi + +#check ENxxx file & ECtrans to local gateway + + +\rm fort.15 2>/dev/null +ln -s ${INFILE} fort.15 + +[ -s CHECK.SUCCESS ] && rm CHECK.SUCCESS + +${EXEDIR}/CHECK + +#check fields +if [ -s CHECK.SUCCESS ]; then + SUCCESS=1 +else + echo 'ERROR: check on ENfile failed:' ${INFILE} + echo ABORT! + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + exit 1 +fi + + + +#ECtrans +if [ $SUCCESS -eq 1 -a $ECTRANS -eq 1 ] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source $INFILE +fi + +#ECFS +if [ $SUCCESS -eq 1 -a $ECSTORAGE -eq 1 ] ; then + ecp -o $INFILE $ECFSDIR +fi + +rm ${INFILE}_2 ${INFILE} fort.15 flux${MDATE}${TIME}* + +j=$(($j+$DTIME)) + +#done TIME +done + +(( IJULDAY = IJULDAY + 1 )) +(( iter = iter + 1 )) + +#done JULDAY +done + +#any warnings ? +[ $NRW -gt 0 ] && echo There were $NRW warnings ! + +#mail logfile (list MAILOPS) +for MUSER in $MAILOPS +do + +mailx -s ${JOBNAME} ${MUSER} <${LOG_FILE} +done + +# +# cleanup +# +cd ${SCRATCH} +echo $SCRATCHDIR not removed! +#\rm -fR $SCRATCHDIR + + diff --git a/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_ecgate b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_ecgate new file mode 100644 index 00000000..6437f391 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_ecgate @@ -0,0 +1,904 @@ +#!/bin/ksh + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf_oper +#SBATCH --output=ms_sms_output_V6.0/CTBTO_ops.out +#SBATCH --error=ms_sms_output_V6.0/CTBTO_ops.out +#SBATCH --mail-type=ALL +#SBATCH --time=12:00:00 + + +set -x + +alias ecp='set noglob; $ECFS_SYS_PATH/ecp.p' + +export OMP_NUM_THREADS=1 + +export VERSION=6.0 +JOBNAME=ecmwf_idc_ops_ecgate_V${VERSION} +CONTROLFILE=${HOME}/flex_extract_ecgate_V${VERSION}/CONTROL_OPS_V${VERSION} + +[ -z "$WSHOME" ] && export WSHOME=$HOME + +# # +# #testing purposes +# # +MSJ_YEAR=2013 +MSJ_MONTH=11 +MSJ_DAY=07 +MSJ_BASETIME=00 + +echo 'MSJ_ENVIRONMENT:' $MSJ_YEAR, $MSJ_MONTH, $MSJ_DAY, $MSJ_BASETIME + +DATEREF=${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY} + + +WDAY=$(date +%A) +[ ! -d $SCRATCH/ms_sms_output_V${VERSION} ] && mkdir $SCRATCH/ms_sms_output_V${VERSION} + +LOG_FILE=$SCRATCH/ms_sms_output_V${VERSION}/${JOBNAME}_${WDAY}_${MSJ_BASETIME} +exec 1>${LOG_FILE} +# no changes below + +NRW=0 + +#ksh scripts for date manipulation +juldate2() + { + let jc=$1 + if (( ${#jc} < 8 )) + then + print "illegal date!" + exit 1 + fi + let y=`echo $jc | cut -c1-4` + let m1=`echo $jc | cut -c5` + let m2=`echo $jc | cut -c6` + m=$m1$m2 + let d1=`echo $jc | cut -c7` + let d2=`echo $jc | cut -c8` + d=$d1$d2 + let jd=367*y-7*(y+(m+9)/12)/4+275*m/9+d+1721014 + let jd=jd+15-3*((y+(m-9)/7)/100+1)/4 + print $jd + } + +civildate2() + { + let jd=$1 + if (( jd < 1721060 )) + then + print "Julian date not in AD." + exit 1 + fi + let k=jd+68569 + let n=4*k/146097 + let k=k-\(146097*n+3\)/4 + let y=4000*(k+1)/1461001 + let k=k-1461*y/4+31 + let m=80*k/2447 + let d=k-\(2447*m\)/80 + let k=m/11 + let m=m+2-12*k + let y=100*(n-49)+y+k + [ $m -le 9 ] && m=0$m + [ $d -le 9 ] && d=0$d + print $y$m$d + } + +date2m1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-1 + civildate2 $j0 + } + +date2p1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1+1 + civildate2 $j0 + } + +date2m14() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-14 + civildate2 $j0 + } + +marsinst() +{ +MTYPE="${1}" +MDAY="${2}" +MTIME="${3}" +MSTEP="${4}" +MPAR="${5}" +MFN=$6 +MLTY=$7 +MGRID="${8}" +MLEV="${9}" + +#if [[ ${MPAR} == 'LNSP' ]] ; then +# MLEV=1 +#else +# if [[ ${MLTY} == 'SFC' ]] ; then +# MLEV=OFF +# else +# MLEV=${M_LEVELIST} +# fi +#fi + +RED=0 +#if [[ ${MTYPE} != 'AN' ]] ; then + MPAR2=`echo ${MPAR} | sed s,160/,,` + MPAR2=`echo ${MPAR2} | sed s,27/,,` + MPAR2=`echo ${MPAR2} | sed s,28/,,` + MPAR2=`echo ${MPAR2} | sed s,173/,,` + if [[ ${MPAR2} != ${MPAR} ]] ; then + MPAR=${MPAR2} + RED=1 + fi +#fi + +MAREA=${M_AREA} +if [[ ${10} == 'GAUSSIAN=REDUCED,' ]] ; then + MAREA=G +fi + +if [[ -f ${MFN} ]] ; then + rm ${MFN} +fi + +cat <<EOF >> marsjob +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=${MPAR}, +RESOL=${M_RESOL}, +AREA=${MAREA}, +GRID=${MGRID}, +LEVTYPE=${MLTY}, +LEVELIST=${MLEV}, +ACCURACY=${M_ACCURACY}, +DATE=${MDAY}, +TIME=${MTIME}, +STEP=${MSTEP},${10} +TARGET="${MFN}" +EOF + +if [[ ! -f 'OROLSM' && $RED -eq 1 ]] ; then + +cat <<EOF >> marsjob +RETRIEVE,TYPE=AN,TIME=0,STEP=0,CLASS=OD, + PARAM=160/27/28/173, + TARGET="OROLSM" +EOF +fi + +} + +marsflux() +{ +MTYPE="${1}" +MSTEP="${2}" + +#if [[ ! -f "surf_${M_STEP}_ub" ]] ; then +cat <<EOF >>mars_flux +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=LSP/CP/SSHF/EWSS/NSSS/SSR, +AREA=${M_AREA}, +GRID=${D_GRID}, +LEVTYPE=SFC, +LEVELIST=OFF, +ACCURACY=${M_ACCURACY}, REPRES=GG, +DATE=${DAY1M1}/TO/${DAY2P1}, +TIME=00/12, +AC=N, +STEP=${MSTEP}, +TARGET="surf_${MSTEP}_ub" +EOF + +if [[ $MSJ_BASETIME == 00 ]] ; then + DAY2P2=`date2p1 ${DAY2P1}` + cat <<EOF >>mars_flux +RETRIEVE, +DATE=${DAY2P2}, +TIME=00, +TARGET="surf_${MSTEP}_ub" +EOF +fi +#fi +} + + +myerror() + { + + echo $1 + echo $2 + echo $3 + echo ABORT! + + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + + exit 1 + } + +# +# MAIN SCRIPT CONTINUES HERE +# +#read CONTROL file, process specifications +while read NAME PARA +do + +if [[ $NAME == 'M_TYPE' || $NAME == 'M_TIME' || $NAME == 'M_STEP' ]] ; then + eval "set -A $NAME $PARA" +else + eval "export $NAME='$PARA'" +fi +echo `echo $NAME`=$PARA + +done <${CONTROLFILE} + + +#defaults +[ -z "$M_EXPVER" ] && M_EXPVER=1 +[ -z "$M_CLASS" ] && M_CLASS=OD +[ -z "$M_STREAM" ] && M_STREAM=OPER +[ -z "$M_NUMBER" ] && M_NUMBER=OFF +[ -z "$M_TYPE" ] && set -A M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +[ -z "$M_TIME" ] && set -A M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +[ -z "$M_STEP" ] && set -A M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +[ -z "$DTIME" ] && DTIME=6 +[ -z "$M_GRID" ] && M_GRID=1000 +[ -z "$M_LOWER" ] && M_LOWER=-90000 +[ -z "$M_LEFT" ] && M_LEFT=-179000 +[ -z "$M_UPPER" ] && M_UPPER=90000 +[ -z "$M_RIGHT" ] && M_RIGHT=180000 +[ -z "$M_LEVEL" ] && M_LEVEL=91 +[ -z "$M_LEVELIST" ] && M_LEVELIST=1/TO/$M_LEVEL +[ -z "$M_ADDPAR" ] && M_ADDPAR='' +[ -z "$M_RESOL" ] && M_RESOL=799 +[ -z "$M_GAUSS" ] && M_GAUSS=0 +[ -z "$M_SMOOTH" ] && M_SMOOTH=0 +[ -z "$M_OMEGA" ] && M_OMEGA=0 +[ -z "$M_OMEGADIFF" ] && M_OMEGADIFF=0 +[ -z "$M_ETA" ] && M_ETA=0 +[ -z "$M_ETADIFF" ] && M_ETADIFF=0 +[ -z "$M_ETAPAR" ] && M_ETAPAR=77 +[ -z "$M_DPDETA" ] && M_DPDETA=1 +[ -z "$M_ACCURACY" ] && M_ACCURACY=24 +[ -z "$EXEDIR" ] && EXEDIR=. +[ -z "$SOURCECODE" ] && SOURCECODE=ecgate:flex_extract_ecgate +[ -z "$GATEWAY" ] && GATEWAY='' +[ -z "$DESTINATION" ] && DESTINATION='' +[ -z "$PREFIX" ] && PREFIX=EN +[ -z "$COMPRESSION" ] && COMPRESSION=grid_simple +[ -z "$ECTRANS" ] && ECTRANS=0 +[ -z "$ECSTORAGE" ] && ECSTORAGE=1 +[ -z "$ECFSDIR" ] && ECFSDIR=ectmp: +[ -z "$MAILOPS" ] && MAILOPS=${USER} +[ -z "$MAILFAIL" ] && MAILFAIL=${USER} + + +export MARS_MULTITARGET_STRICT_FORMAT=1 + +if [ $M_GAUSS -eq 1 ] ; then + export SCRATCHDIR=${SCRATCH}/ctbto_run_ecgate-${DTIME}hrs-G_V${VERSION} + mkdir $SCRATCHDIR >/dev/null +else + export SCRATCHDIR=${SCRATCH}/ctbto_run_ecgate-${DTIME}hrs-L_V${VERSION} + mkdir $SCRATCHDIR >/dev/null +fi + +# +# cleanup +# +#\rm -f $SCRATCHDIR/* +\rm -f $SCRATCHDIR/fort* + +[ ! -d $SCRATCHDIR ] && mkdir $SCRATCHDIR +cd $SCRATCHDIR + + +DAY1=${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY} +if [ $MSJ_BASETIME -eq 00 ] ; then + DAY2=DAY1 +else + DAY2=`date2p1 ${DAY1}` +fi + +#additional dates for flux retrievals (polynomial interpolation) +DAY1M1=`date2m1 ${DAY1}` +DAY2P1=`date2m1 ${DAY2}` + +#julian dates for time loops +JULDAY1=`juldate2 ${DAY1}` +JULDAY2=`juldate2 ${DAY1}` + + +#echo 'field date :' $M_DATE_S, $M_TIME_S +#echo 'flux dates :' $FLXDT1, $FLXT1, $FLXDT2, $FLXT2 + +#take care of nameing convention +#M_DATEX=`echo ${M_DATE_S} | cut -c3-8` +#DATEREFX=`echo ${DATEREF} | cut -c3-8` + +# determine number of gridpoints and whether grid is cyclic +ZYK=`expr \( $M_RIGHT + 360000 \) % 360000 - \( $M_LEFT + 360000 \) % 360000 + $M_GRID` + +if [ $M_RIGHT -le $M_LEFT ] ; then + if [ $M_RIGHT -le 0 ] ; then + M_RIGHT=$(($M_RIGHT+360000)) + else + M_LEFT=$(($M_LEFT-360000)) + fi +fi + +if [[ $ZYK -ne 0 ]] ; then + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED NON-CYCLIC" + exit 1 + fi +else + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED CYCLIC" + exit 1 + fi +fi + +if [ $((180000/$M_GRID-$M_RESOL)) -lt 0 ] ; then + + if [ ${M_SMOOTH} -eq 0 ] ; then + echo "WARNING: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SPECTRAL RESOLUTION ${M_RESOL} " "USE M_SMOOTH FOR SMOOTHING OR FINER OUTPUT GRID" +# exit 1 + else + if [ $((180000/$M_GRID-$M_SMOOTH)) -lt 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SMOOTHED SPECTRAL RESOLUTION ${M_SMOOTH} " + fi + fi + +fi + + +# convert lat/lon to MARS format (degrees) +if [[ $M_LEFT -lt 0 ]] ; then + LLLO=$(($M_LEFT / 1000)).$((($M_LEFT)*(-1) % 1000)) +else + LLLO=$(($M_LEFT / 1000)).$(($M_LEFT % 1000)) +fi +if [[ $M_LOWER -lt 0 ]] ; then + LLLA=$(($M_LOWER / 1000)).$(($M_LOWER*(-1) % 1000)) +else + LLLA=$(($M_LOWER / 1000)).$((($M_LOWER) % 1000)) +fi +if [[ $M_RIGHT -lt 0 ]] ; then + URLO=$(($M_RIGHT / 1000)).$((($M_RIGHT)*(-1) % 1000)) +else + URLO=$(($M_RIGHT / 1000)).$(($M_RIGHT % 1000)) +fi +if [[ $M_UPPER -lt 0 ]] ; then + URLA=$(($M_UPPER / 1000)).$((($M_UPPER)*(-1) % 1000)) +else + URLA=$(($M_UPPER / 1000)).$(($M_UPPER % 1000)) +fi + +M_AREA=${URLA}/${LLLO}/${LLLA}/${URLO} + +if [ $M_GAUSS -eq 1 ] ; then +# Gaussian grid detected + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=OFF + QG_GRID=OFF + if [ $M_RESOL -le 799 ] ; then + QG_GRID=$((($M_RESOL+1)/2)) + fi + D_GRID=${D_GRID}/${D_GRID} + +else + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=${G_GRID}/${G_GRID} + D_GRID=${D_GRID}/${D_GRID} +fi + +G_LEVELIST=1/to/${M_LEVEL} + + +#namelist +cat <<EOF >fort.4 +&NAMGEN + MAXL=${MAXL}, MAXB=${MAXB}, + MLEVEL=${M_LEVEL}, MLEVELIST="${M_LEVELIST}", + MNAUF=${M_RESOL},METAPAR=${M_ETAPAR}, + RLO0=${LLLO}, RLO1=${URLO}, RLA0=${LLLA}, RLA1=${URLA}, + MOMEGA=${M_OMEGA},MOMEGADIFF=${M_OMEGADIFF},MGAUSS=${M_GAUSS}, + MSMOOTH=${M_SMOOTH},META=${M_ETA},METADIFF=${M_ETADIFF}, + MDPDETA=${M_DPDETA} +/ +&NAMFX2 + NX=${MAXL}, NY=${MAXB}, + MAXTIME=400,JPOLY=4, + JHRF=${DTIME}, + RLO0=${LLLO}, RLA0=${LLLA}, DX=${D_GRID}, DY=${D_GRID} +/ +EOF + + +cp ${SOURCECODE}/source.tar . +tar -xvf source.tar +if [[ $OS_VERSION == aix ]] ; then + make -f Makefile.IBM FLXACC2 CONVERT2 CHECK +else + make -f Makefile.ecgb FLXACC2 CONVERT2 CHECK +fi + +if [ $? -ne 0 ]; then + ls + echo 'ERROR: FLXACC2 and CONVERT2 could not be compiled:' ${INFILE} + echo ABORT! + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + exit 1 +else + echo 'compile worked' +fi + + +# +#MARS requests (field) +# +imax=6 +set -A PARLIST U/V T Q LNSP SD/MSL/TCC/10U/10V/2T/2D 129/172/160${M_ADDPAR} +set -A PARNAME 131/132 130 133 152 SURF OROLSM +set -A REPR SH SH GG SH GG GG +set -A UNIT 10 11 17 12 14 20 +set -A LTY ML ML ML ML SFC SFC +set -A GRID ${G_GRID} ${D_GRID} ${D_GRID} OFF ${D_GRID} ${D_GRID} +set -A LEVELIST ${M_LEVELIST} ${M_LEVELIST} ${M_LEVELIST} 1 1 1 + +set -A FIELD 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 + + +if [[ $M_OMEGA -eq 1 || $M_OMEGADIFF -eq 1 ]] ; then + M_OMEGA=1 + PARLIST[imax]=W + PARNAME[imax]=135 + REPR[imax]=SH + UNIT[imax]=19 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 1 || $M_ETADIFF -eq 1 ]] ; then + M_ETA=1 + PARLIST[imax]=77 + PARNAME[imax]=77 + REPR[imax]=SH + UNIT[imax]=21 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi + +if [[ $M_GAUSS -eq 2 ]] ; then + PARLIST[imax]=VO + PARNAME[imax]=138 + REPR[imax]=SH + UNIT[imax]=30 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 0 || $M_GAUSS -eq 1 || $M_ETADIFF -eq 1 ]] ; then + PARLIST[imax]=D + PARNAME[imax]=155 + REPR[imax]=SH + UNIT[imax]=13 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + LEVELIST[1]=${G_LEVELIST} # U/V needed on all levels for calculating ETA + imax=$(($imax+1)) +fi + +jmax=$(( ${#M_TYPE[*]})) + +# M_TIME needs leading zeros while M_STEP must have leading zeros +# to be consistent with MARS file naming convention +# The following loop ensures this +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TIME[$j]} -lt 10 ]] ; then + M_TIME[$j]=0$((${M_TIME[$j]})) + fi + if [[ ${M_STEP[$j]} -lt 10 ]] ; then + M_STEP[$j]=$((${M_STEP[$j]})) + fi + + j=$(($j+1)) +done + +echo ${M_TIME[*]} +echo ${M_STEP[*]} + + +rm mars_flux 2>/dev/null +j=0 +while [[ $j -lt 24 ]] ; do + marsflux ${M_TYPE[2]} ${FIELD[$j]} + j=$(($j+$DTIME)) +done +mars mars_flux +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + + +# +# FLXACC job +# + + +${EXEDIR}/FLXACC2 +if [ -f OROLSM ] ; then + rm OROLSM + + +fi + +# +# CONVERT job +# + +#loop over DATE and TIME for CONVERT/CHECK/ECtrans job + +iter=0 +IJULDAY=${JULDAY1} +while [ $IJULDAY -le $JULDAY2 ]; +do + +MDATE=`civildate2 ${IJULDAY}` +if [ $MSJ_BASETIME -eq 00 ] ; then + MDATE=`date2m1 ${MDATE}` +fi + +MDATEX=`echo ${MDATE} | cut -c3-8` + + +i=0 +rm marsjob 2>/dev/null + +#humidity on reduced Gaussian grid for initialization +#of spectral transformations +if [ ${M_GAUSS} -eq 1 ] ; then + NGRID=$(( ( ${M_RESOL} + 1 ) / 2 )) + + marsinst ${M_TYPE[0]} ${DAY1} 00 00 Q fort.18 ML ${QG_GRID} 1 'GAUSSIAN=REDUCED,' + +set -e +mars marsjob +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +rm marsjob + +fi + +set -e + +if [ $MSJ_BASETIME -eq 12 ] ; then + j=$(($DTIME)) + jmax=$(($DTIME+12)) +else + j=$(($DTIME+12)) +fi +if [ $iter -eq 1 ] ; then + j=0 + jmax=1 +fi +set -A TYPEKEY ${M_TYPE[$j]} +kmax=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[j]} != ${TYPEKEY[0]} ]] ; then + if [[ $kmax == 1 ]] ; then + if [[ ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${TYPEKEY[1]} ${M_TYPE[j]} + kmax=2 + fi + else + if [[ $kmax == 0 ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${M_TYPE[j]} + kmax=1 + else + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[2]} ]] ; then + + echo ${TYPEKEY[0]} ${TYPEKEY[1]} ${TYPEKEY[2]} ${M_TYPE[j]} + myerror 'More than three different MARS TYPES not supported' + + exit 1 + fi + fi + fi + fi + fi + j=$(($j+$DTIME)) +done + +set -A GRIDKEY $D_GRID +mmax=1 +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${GRID[$i]} == 'OFF' && ${PARLIST[$i]} != LNSP ]] ; then + set -A GRIDKEY $D_GRID OFF + mmax=2 + fi + i=$(($i+1)) +done + +k=0 +kmax=$(($kmax+1)) +while [[ $k -lt $kmax ]] ; do +MMTIME='' +MMSTEP='' +TSUFF='' +SSUFF='' +j=0 +if [ $MSJ_BASETIME -eq 12 ] ; then + j=$(($DTIME)) + jmax=$(($DTIME+12)) +else + j=$(($DTIME+12)) +fi +if [ $iter -eq 1 ] ; then + j=0 + jmax=1 +fi +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[$j]} == ${TYPEKEY[$k]} ]] ; then + if [[ `echo $MMTIME | grep ${M_TIME[$j]}` == '' ]] ; then + MMTIME=${MMTIME}$TSUFF${M_TIME[$j]} + TSUFF='/' + fi + if [[ `echo $MMSTEP | grep ${M_STEP[$j]}` == '' ]] ; then + MMSTEP=${MMSTEP}$SSUFF${M_STEP[$j]} + SSUFF='/' + fi + fi +j=$(($j+$DTIME)) +done + +m=0 +while [[ $m -lt $mmax ]] ; do +MMPAR='' +PSUFF='' +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${LTY[$i]} == ML && ${GRID[$i]} == ${GRIDKEY[m]} && ${PARLIST[$i]} != LNSP ]] ; then + if [[ `echo $MMPAR | grep ${PARLIST[$i]}` == '' ]] ; then + MMPAR=${MMPAR}$PSUFF${PARLIST[$i]} + PSUFF='/' + fi + fi +i=$(($i+1)) +done + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} $MMPAR "[param].[date].[time].[step]" ML ${GRIDKEY[$m]} ${LEVELIST[$m]} + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +m=$(($m+1)) +done +# LNSP treated separately since it exists only on 1 level + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} LNSP "[param].[date].[time].[step]" ML OFF 1 + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# For some data classes, MARS adds GRIB table number to parameter number, +# e.g. for Temperature it is 130.128 instead of just 130 +# + set +e + TNR=`ls 131*${MDATE}.${M_TIME[00]}00.${M_STEP[00]} | awk -F . '{print $2}' - | grep -v ${MDATE}`. + set -e + if [[ $TNR != '.' ]] ; then + TNR=.$TNR + fi + +# SURF treated separately since it exists only on 1 level + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[4]} "SURF${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob +# OROLSM treated separately since it exists only on 1 level + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[5]} "OROLSM${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +# if [ -f OROLSM ] ; then +# for oro in `ls +# cat OROLSM >> OROLSM${TNR}${MDATE}.${MMTIME}00.${MMSTEP} +# rm OROLSM +# echo 'found' +# exit 0 +# fi + rm marsjob + +k=$(($k+1)) +done + + + + +j=0 +if [ $MSJ_BASETIME -eq 12 ] ; then + j=$(($DTIME)) + jmax=$(($DTIME+12)) +else + j=$(($DTIME+12)) +fi +if [ $iter -eq 1 ] ; then + j=0 + jmax=1 +fi +while [[ $j -lt $jmax ]] ; do + + +TIME=${FIELD[$j]} +XTIME=${TIME}00 + +set +e +i=0 +while [[ $i -lt $imax ]] ; do + \rm fort.${UNIT[$i]} 2>/dev/null + if [[ ${PARLIST[$i]} == U/V ]] ; then + cat 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} > fort.${UNIT[$i]} + rm 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} + else + mv ${PARNAME[$i]}${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} fort.${UNIT[$i]} + fi + i=$(($i+1)) +done + +# flux data need special GRIB conversion +#if [ ${M_FORMAT} == GRIB2 ] ; then +# grib_set -w shortName!=lsp,shortName!=cp,shortName!=ewss,shortName!=nsss -s edition=2,productDefinitionTemplateNumber=8 flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +# +#else +# mv flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +#fi + +${EXEDIR}/CONVERT2 + +if [ $TIME -eq 00 ]; then + MDATE=`date2p1 ${MDATE}` + MDATEX=`echo ${MDATE} | cut -c 3-8` +fi + +INFILE=${PREFIX}${MDATEX}${TIME} + +if [ -s fort.15 ]; then + cp fort.15 ${INFILE} + cat fort.14 >> ${INFILE} + cat flux${MDATE}${TIME} >> ${INFILE} + cat OROLSM >> ${INFILE} + cat fort.20 >> ${INFILE} + +# +# Convert to GRIB2 if needed +# +# to enable additional compression try +# set packingType="grid_jpeg"; +# this is rather time consuming. + +if [ ${M_FORMAT} == GRIB2 ] ; then + grib_set -s edition=2,productDefinitionTemplateNumber=8 $INFILE ${INFILE}_2 + mv ${INFILE}_2 ${INFILE} + + if [ ${COMPRESSION} != grid_simple ] ; then + +cat >rule.filter<<EOF +set packingType="${COMPRESSION}"; +write "[file]_2"; +EOF + grib_filter rule.filter ${INFILE} + mv ${INFILE}_2 ${INFILE} + fi +fi +ls -l ${INFILE} + +else + echo ERROR: ENfile ${INFILE} missing! + echo ABORT! + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + exit 1 +fi + +#check ENxxx file & ECtrans to local gateway + + +\rm fort.15 2>/dev/null +ln -s ${INFILE} fort.15 + +[ -s CHECK.SUCCESS ] && rm CHECK.SUCCESS + +${EXEDIR}/CHECK + +#check fields +if [ -s CHECK.SUCCESS ]; then + SUCCESS=1 +else + echo 'ERROR: check on ENfile failed:' ${INFILE} + echo ABORT! + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + exit 1 +fi + + + +#ECtrans +if [ $SUCCESS -eq 1 -a $ECTRANS -eq 1 ] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source $INFILE +fi + +#ECFS +if [ $SUCCESS -eq 1 -a $ECSTORAGE -eq 1 ] ; then + ecp -o $INFILE $ECFSDIR +fi + +rm ${INFILE}_2 ${INFILE} fort.15 flux${MDATE}${TIME}* + +j=$(($j+$DTIME)) + +#done TIME +done + +(( IJULDAY = IJULDAY + 1 )) +(( iter = iter + 1 )) + +#done JULDAY +done + +#any warnings ? +[ $NRW -gt 0 ] && echo There were $NRW warnings ! + +#mail logfile (list MAILOPS) +for MUSER in $MAILOPS +do + +mailx -s ${JOBNAME} ${MUSER} <${LOG_FILE} +done + +# +# cleanup +# +cd ${SCRATCH} +echo $SCRATCHDIR not removed! +#\rm -fR $SCRATCHDIR + + diff --git a/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_header b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_header new file mode 100644 index 00000000..6f8aad00 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_header @@ -0,0 +1,41 @@ +#!/bin/ksh + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf_oper +#SBATCH --output=ms_sms_output_V6.0/CTBTO_ops.out +#SBATCH --error=ms_sms_output_V6.0/CTBTO_ops.out +#SBATCH --mail-type=ALL +#SBATCH --time=12:00:00 + + +set -x + +alias ecp='set noglob; $ECFS_SYS_PATH/ecp.p' + +export OMP_NUM_THREADS=1 + +export VERSION=6.0 +JOBNAME=ecmwf_idc_ops_ecgate_V${VERSION} +CONTROLFILE=${HOME}/flex_extract_ecgate_V${VERSION}/CONTROL_OPS_V${VERSION} + +[ -z "$WSHOME" ] && export WSHOME=$HOME + +# # +# #testing purposes +# # +MSJ_YEAR=2013 +MSJ_MONTH=11 +MSJ_DAY=07 +MSJ_BASETIME=12 + +echo 'MSJ_ENVIRONMENT:' $MSJ_YEAR, $MSJ_MONTH, $MSJ_DAY, $MSJ_BASETIME + +DATEREF=${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY} + + +WDAY=$(date +%A) +[ ! -d $SCRATCH/ms_sms_output_V${VERSION} ] && mkdir $SCRATCH/ms_sms_output_V${VERSION} + +LOG_FILE=$SCRATCH/ms_sms_output_V${VERSION}/${JOBNAME}_${WDAY}_${MSJ_BASETIME} +exec 1>${LOG_FILE} diff --git a/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_header_template b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_header_template new file mode 100644 index 00000000..f31b155c --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_header_template @@ -0,0 +1,41 @@ +#!/bin/ksh + +#SBATCH --workdir=/scratch/ms/ggg/xxx +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf_oper +#SBATCH --output=ms_sms_output_Vv.v/CTBTO_ops.out +#SBATCH --error=ms_sms_output_Vv.v/CTBTO_ops.out +#SBATCH --mail-type=ALL +#SBATCH --time=12:00:00 + + +set -x + +alias ecp='set noglob; $ECFS_SYS_PATH/ecp.p' + +export OMP_NUM_THREADS=1 + +export VERSION=v.v +JOBNAME=ecmwf_idc_ops_ecgate_V${VERSION} +CONTROLFILE=${HOME}/flex_extract_ecgate_V${VERSION}/CONTROL_OPS_V${VERSION} + +[ -z "$WSHOME" ] && export WSHOME=$HOME + +# # +# #testing purposes +# # +MSJ_YEAR=2013 +MSJ_MONTH=11 +MSJ_DAY=07 +MSJ_BASETIME=12 + +echo 'MSJ_ENVIRONMENT:' $MSJ_YEAR, $MSJ_MONTH, $MSJ_DAY, $MSJ_BASETIME + +DATEREF=${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY} + + +WDAY=$(date +%A) +[ ! -d $SCRATCH/ms_sms_output_V${VERSION} ] && mkdir $SCRATCH/ms_sms_output_V${VERSION} + +LOG_FILE=$SCRATCH/ms_sms_output_V${VERSION}/${JOBNAME}_${WDAY}_${MSJ_BASETIME} +exec 1>${LOG_FILE} diff --git a/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_ecgate b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_ecgate new file mode 100644 index 00000000..01f5470c --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_ecgate @@ -0,0 +1,979 @@ +#!/bin/ksh + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf_oper +#SBATCH --output=ms_sms_output_V6.0/CTBTO_ops.out +#SBATCH --error=ms_sms_output_V6.0/CTBTO_ops.out +#SBATCH --mail-type=ALL +#SBATCH --time=12:00:00 + + +set -x + +alias ecp='set noglob; $ECFS_SYS_PATH/ecp.p' + +export OMP_NUM_HREADS=1 + + + +########################### + +# ADD BEGIN AND END HERE # + +########################### + + MSJ_START=2013110700 + MSJ_END=2013110812 + + +########################### + +# NO CHANGES BELOW # + +########################### + +VERSION=6.0 +JOBNAME=ecmwf_idc_ops_ecgate_V${VERSION} +CONTROLFILE=${HOME}/flex_extract_ecgate_V${VERSION}/CONTROL_OPS_V${VERSION} + +WDAY=$(date +%A) +[ ! -d $SCRATCH/ms_sms_output_V${VERSION} ] && mkdir $SCRATCH/ms_sms_output_V${VERSION} + +LOG_FILE=$SCRATCH/ms_sms_output_V${VERSION}/${JOBNAME}_${WDAY} +exec 1>${LOG_FILE} + +[ -z "$WSHOME" ] && export WSHOME=$HOME + + DAY1=$(($MSJ_START/100)) + DAY2=$(($MSJ_END/100)) + TDIFF=$(( (`date +%s -d $DAY2` - `date +%s -d $DAY1` )/86400 )) + if [[ $TDIFF -lt 0 || $TDIFF -gt 31 ]] ; then + echo invalid difference $TDIFF between dates $1, $2 + echo difference must be positive and smaller than 32 + exit + fi + + + MSJ=$MSJ_START + MSJ_YEAR=$(( ($MSJ/1000000))) + while [ $MSJ -le $MSJ_END ] + do + + MSJ_MONTH=$(( ($MSJ%1000000)/10000)) + MSJ_DAY=$(( ($MSJ%10000)/100)) + MSJ_BASETIME=$(($MSJ%100)) + + if [ $MSJ_MONTH -lt 10 ] ; then + MSJ_MONTH='0'$MSJ_MONTH + fi + if [ $MSJ_DAY -lt 10 ] ; then + MSJ_DAY='0'$MSJ_DAY + fi + if [ $MSJ_BASETIME -lt 10 ] ; then + MSJ_BASETIME='0'$MSJ_BASETIME + fi + + MSJ=$MSJ_YEAR$MSJ_MONTH$MSJ_DAY$MSJ_BASETIME + + echo 'MSJ_ENVIRONMENT:' $MSJ + + DATEREF=${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY} + + +# no changes below + +NRW=0 + +#ksh scripts for date manipulation +juldate2() + { + let jc=$1 + if (( ${#jc} < 8 )) + then + print "illegal date!" + exit 1 + fi + let y=`echo $jc | cut -c1-4` + let m1=`echo $jc | cut -c5` + let m2=`echo $jc | cut -c6` + m=$m1$m2 + let d1=`echo $jc | cut -c7` + let d2=`echo $jc | cut -c8` + d=$d1$d2 + let jd=367*y-7*(y+(m+9)/12)/4+275*m/9+d+1721014 + let jd=jd+15-3*((y+(m-9)/7)/100+1)/4 + print $jd + } + +civildate2() + { + let jd=$1 + if (( jd < 1721060 )) + then + print "Julian date not in AD." + exit 1 + fi + let k=jd+68569 + let n=4*k/146097 + let k=k-\(146097*n+3\)/4 + let y=4000*(k+1)/1461001 + let k=k-1461*y/4+31 + let m=80*k/2447 + let d=k-\(2447*m\)/80 + let k=m/11 + let m=m+2-12*k + let y=100*(n-49)+y+k + [ $m -le 9 ] && m=0$m + [ $d -le 9 ] && d=0$d + print $y$m$d + } + +date2m1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-1 + civildate2 $j0 + } + +date2p1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1+1 + civildate2 $j0 + } + +date2m14() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-14 + civildate2 $j0 + } + +marsinst() +{ +MTYPE="${1}" +MDAY="${2}" +MTIME="${3}" +MSTEP="${4}" +MPAR="${5}" +MFN=$6 +MLTY=$7 +MGRID="${8}" +MLEV="${9}" + +#if [[ ${MPAR} == 'LNSP' ]] ; then +# MLEV=1 +#else +# if [[ ${MLTY} == 'SFC' ]] ; then +# MLEV=OFF +# else +# MLEV=${M_LEVELIST} +# fi +#fi + +RED=0 +#if [[ ${MTYPE} != 'AN' ]] ; then + MPAR2=`echo ${MPAR} | sed s,160/,,` + MPAR2=`echo ${MPAR2} | sed s,27/,,` + MPAR2=`echo ${MPAR2} | sed s,28/,,` + MPAR2=`echo ${MPAR2} | sed s,173/,,` + if [[ ${MPAR2} != ${MPAR} ]] ; then + MPAR=${MPAR2} + RED=1 + fi +#fi + +MAREA=${M_AREA} +if [[ ${10} == 'GAUSSIAN=REDUCED,' ]] ; then + MAREA=G +fi + +if [[ -f ${MFN} ]] ; then + rm ${MFN} +fi + +cat <<EOF >> marsjob +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=${MPAR}, +RESOL=${M_RESOL}, +AREA=${MAREA}, +GRID=${MGRID}, +LEVTYPE=${MLTY}, +LEVELIST=${MLEV}, +ACCURACY=${M_ACCURACY}, +DATE=${MDAY}, +TIME=${MTIME}, +STEP=${MSTEP},${10} +TARGET="${MFN}" +EOF + +if [[ ! -f 'OROLSM' && $RED -eq 1 ]] ; then + +cat <<EOF >> marsjob +RETRIEVE,TYPE=AN,TIME=0,STEP=0,CLASS=OD, + PARAM=160/27/28/173, + TARGET="OROLSM" +EOF +fi + +} + +marsflux() +{ +MTYPE="${1}" +MSTEP="${2}" + +#if [[ ! -f "surf_${M_STEP}_ub" ]] ; then +cat <<EOF >>mars_flux +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=LSP/CP/SSHF/EWSS/NSSS/SSR, +AREA=${M_AREA}, +GRID=${D_GRID}, +LEVTYPE=SFC, +LEVELIST=OFF, +ACCURACY=${M_ACCURACY}, REPRES=GG, +DATE=${DAY1M1}/TO/${DAY2P1}, +TIME=00/12, +AC=N, +STEP=${MSTEP}, +TARGET="surf_${MSTEP}_ub" +EOF + +if [[ $MSJ_BASETIME == 00 ]] ; then + DAY2P2=`date2p1 ${DAY2P1}` + cat <<EOF >>mars_flux +RETRIEVE, +DATE=${DAY2P2}, +TIME=00, +TARGET="surf_${MSTEP}_ub" +EOF +fi +#fi +} + + +myerror() + { + + echo $1 + echo $2 + echo $3 + echo ABORT! + + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + + exit 1 + } + +# +# MAIN SCRIPT CONTINUES HERE +# +#read CONTROL file, process specifications +while read NAME PARA +do + +if [[ $NAME == 'M_TYPE' || $NAME == 'M_TIME' || $NAME == 'M_STEP' ]] ; then + eval "set -A $NAME $PARA" +else + eval "export $NAME='$PARA'" +fi +echo `echo $NAME`=$PARA + +done <${CONTROLFILE} + + +#defaults +[ -z "$M_EXPVER" ] && M_EXPVER=1 +[ -z "$M_CLASS" ] && M_CLASS=OD +[ -z "$M_STREAM" ] && M_STREAM=OPER +[ -z "$M_NUMBER" ] && M_NUMBER=OFF +[ -z "$M_TYPE" ] && set -A M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +[ -z "$M_TIME" ] && set -A M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +[ -z "$M_STEP" ] && set -A M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +[ -z "$DTIME" ] && DTIME=6 +[ -z "$M_GRID" ] && M_GRID=1000 +[ -z "$M_LOWER" ] && M_LOWER=-90000 +[ -z "$M_LEFT" ] && M_LEFT=-179000 +[ -z "$M_UPPER" ] && M_UPPER=90000 +[ -z "$M_RIGHT" ] && M_RIGHT=180000 +[ -z "$M_LEVEL" ] && M_LEVEL=91 +[ -z "$M_LEVELIST" ] && M_LEVELIST=1/TO/$M_LEVEL +[ -z "$M_ADDPAR" ] && M_ADDPAR='' +[ -z "$M_RESOL" ] && M_RESOL=799 +[ -z "$M_GAUSS" ] && M_GAUSS=0 +[ -z "$M_SMOOTH" ] && M_SMOOTH=0 +[ -z "$M_OMEGA" ] && M_OMEGA=0 +[ -z "$M_OMEGADIFF" ] && M_OMEGADIFF=0 +[ -z "$M_ETA" ] && M_ETA=0 +[ -z "$M_ETADIFF" ] && M_ETADIFF=0 +[ -z "$M_ETAPAR" ] && M_ETAPAR=77 +[ -z "$M_DPDETA" ] && M_DPDETA=1 +[ -z "$M_ACCURACY" ] && M_ACCURACY=24 +[ -z "$EXEDIR" ] && EXEDIR=. +[ -z "$SOURCECODE" ] && SOURCECODE=ecgate:flex_extract_ecgate +[ -z "$GATEWAY" ] && GATEWAY='' +[ -z "$DESTINATION" ] && DESTINATION='' +[ -z "$PREFIX" ] && PREFIX=EN +[ -z "$COMPRESSION" ] && COMPRESSION=grid_simple +[ -z "$ECTRANS" ] && ECTRANS=0 +[ -z "$ECSTORAGE" ] && ECSTORAGE=1 +[ -z "$ECFSDIR" ] && ECFSDIR=ectmp: +[ -z "$MAILOPS" ] && MAILOPS=${USER} +[ -z "$MAILFAIL" ] && MAILFAIL=${USER} + + +export MARS_MULTITARGET_STRICT_FORMAT=1 + +if [ $M_GAUSS -eq 1 ] ; then + export SCRATCHDIR=${SCRATCH}/ctbto_run_ecgate-${DTIME}hrs-G_V${VERSION} + mkdir $SCRATCHDIR >/dev/null +else + export SCRATCHDIR=${SCRATCH}/ctbto_run_ecgate-${DTIME}hrs-L_V${VERSION} + mkdir $SCRATCHDIR >/dev/null +fi + +# +# cleanup +# +#\rm -f $SCRATCHDIR/* +\rm -f $SCRATCHDIR/fort* + +[ ! -d $SCRATCHDIR ] && mkdir $SCRATCHDIR +cd $SCRATCHDIR + + +DAY1=${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY} +if [ $MSJ_BASETIME -eq 00 ] ; then + DAY2=DAY1 +else + DAY2=`date2p1 ${DAY1}` +fi + +#additional dates for flux retrievals (polynomial interpolation) +DAY1M1=`date2m1 ${DAY1}` +DAY2P1=`date2m1 ${DAY2}` + +#julian dates for time loops +JULDAY1=`juldate2 ${DAY1}` +JULDAY2=`juldate2 ${DAY1}` + + +#echo 'field date :' $M_DATE_S, $M_TIME_S +#echo 'flux dates :' $FLXDT1, $FLXT1, $FLXDT2, $FLXT2 + +#take care of nameing convention +#M_DATEX=`echo ${M_DATE_S} | cut -c3-8` +#DATEREFX=`echo ${DATEREF} | cut -c3-8` + +# determine number of gridpoints and whether grid is cyclic +ZYK=`expr \( $M_RIGHT + 360000 \) % 360000 - \( $M_LEFT + 360000 \) % 360000 + $M_GRID` + +if [ $M_RIGHT -le $M_LEFT ] ; then + if [ $M_RIGHT -le 0 ] ; then + M_RIGHT=$(($M_RIGHT+360000)) + else + M_LEFT=$(($M_LEFT-360000)) + fi +fi + +if [[ $ZYK -ne 0 ]] ; then + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED NON-CYCLIC" + exit 1 + fi +else + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED CYCLIC" + exit 1 + fi +fi + +if [ $((180000/$M_GRID-$M_RESOL)) -lt 0 ] ; then + + if [ ${M_SMOOTH} -eq 0 ] ; then + echo "WARNING: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SPECTRAL RESOLUTION ${M_RESOL} " "USE M_SMOOTH FOR SMOOTHING OR FINER OUTPUT GRID" +# exit 1 + else + if [ $((180000/$M_GRID-$M_SMOOTH)) -lt 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SMOOTHED SPECTRAL RESOLUTION ${M_SMOOTH} " + fi + fi + +fi + + +# convert lat/lon to MARS format (degrees) +if [[ $M_LEFT -lt 0 ]] ; then + LLLO=$(($M_LEFT / 1000)).$((($M_LEFT)*(-1) % 1000)) +else + LLLO=$(($M_LEFT / 1000)).$(($M_LEFT % 1000)) +fi +if [[ $M_LOWER -lt 0 ]] ; then + LLLA=$(($M_LOWER / 1000)).$(($M_LOWER*(-1) % 1000)) +else + LLLA=$(($M_LOWER / 1000)).$((($M_LOWER) % 1000)) +fi +if [[ $M_RIGHT -lt 0 ]] ; then + URLO=$(($M_RIGHT / 1000)).$((($M_RIGHT)*(-1) % 1000)) +else + URLO=$(($M_RIGHT / 1000)).$(($M_RIGHT % 1000)) +fi +if [[ $M_UPPER -lt 0 ]] ; then + URLA=$(($M_UPPER / 1000)).$((($M_UPPER)*(-1) % 1000)) +else + URLA=$(($M_UPPER / 1000)).$(($M_UPPER % 1000)) +fi + +M_AREA=${URLA}/${LLLO}/${LLLA}/${URLO} + +if [ $M_GAUSS -eq 1 ] ; then +# Gaussian grid detected + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=OFF + QG_GRID=OFF + if [ $M_RESOL -le 799 ] ; then + QG_GRID=$((($M_RESOL+1)/2)) + fi + D_GRID=${D_GRID}/${D_GRID} + +else + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=${G_GRID}/${G_GRID} + D_GRID=${D_GRID}/${D_GRID} +fi + +G_LEVELIST=1/to/${M_LEVEL} + + +#namelist +cat <<EOF >fort.4 +&NAMGEN + MAXL=${MAXL}, MAXB=${MAXB}, + MLEVEL=${M_LEVEL}, MLEVELIST="${M_LEVELIST}", + MNAUF=${M_RESOL},METAPAR=${M_ETAPAR}, + RLO0=${LLLO}, RLO1=${URLO}, RLA0=${LLLA}, RLA1=${URLA}, + MOMEGA=${M_OMEGA},MOMEGADIFF=${M_OMEGADIFF},MGAUSS=${M_GAUSS}, + MSMOOTH=${M_SMOOTH},META=${M_ETA},METADIFF=${M_ETADIFF}, + MDPDETA=${M_DPDETA} +/ +&NAMFX2 + NX=${MAXL}, NY=${MAXB}, + MAXTIME=400,JPOLY=4, + JHRF=${DTIME}, + RLO0=${LLLO}, RLA0=${LLLA}, DX=${D_GRID}, DY=${D_GRID} +/ +EOF + + +cp ${SOURCECODE}/source.tar . +tar -xvf source.tar +if [[ $OS_VERSION == aix ]] ; then + make -f Makefile.IBM FLXACC2 CONVERT2 CHECK +else + make -f Makefile.ecgb FLXACC2 CONVERT2 CHECK +fi + +if [ $? -ne 0 ]; then + ls + echo 'ERROR: FLXACC2 and CONVERT2 could not be compiled:' ${INFILE} + echo ABORT! + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + exit 1 +else + echo 'compile worked' +fi + + +# +#MARS requests (field) +# +imax=6 +set -A PARLIST U/V T Q LNSP SD/MSL/TCC/10U/10V/2T/2D 129/172/160${M_ADDPAR} +set -A PARNAME 131/132 130 133 152 SURF OROLSM +set -A REPR SH SH GG SH GG GG +set -A UNIT 10 11 17 12 14 20 +set -A LTY ML ML ML ML SFC SFC +set -A GRID ${G_GRID} ${D_GRID} ${D_GRID} OFF ${D_GRID} ${D_GRID} +set -A LEVELIST ${M_LEVELIST} ${M_LEVELIST} ${M_LEVELIST} 1 1 1 + +set -A FIELD 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 + + +if [[ $M_OMEGA -eq 1 || $M_OMEGADIFF -eq 1 ]] ; then + M_OMEGA=1 + PARLIST[imax]=W + PARNAME[imax]=135 + REPR[imax]=SH + UNIT[imax]=19 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 1 || $M_ETADIFF -eq 1 ]] ; then + M_ETA=1 + PARLIST[imax]=77 + PARNAME[imax]=77 + REPR[imax]=SH + UNIT[imax]=21 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi + +if [[ $M_GAUSS -eq 2 ]] ; then + PARLIST[imax]=VO + PARNAME[imax]=138 + REPR[imax]=SH + UNIT[imax]=30 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 0 || $M_GAUSS -eq 1 || $M_ETADIFF -eq 1 ]] ; then + PARLIST[imax]=D + PARNAME[imax]=155 + REPR[imax]=SH + UNIT[imax]=13 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + LEVELIST[1]=${G_LEVELIST} # U/V needed on all levels for calculating ETA + imax=$(($imax+1)) +fi + +jmax=$(( ${#M_TYPE[*]})) + +# M_TIME needs leading zeros while M_STEP must have leading zeros +# to be consistent with MARS file naming convention +# The following loop ensures this +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TIME[$j]} -lt 10 ]] ; then + M_TIME[$j]=0$((${M_TIME[$j]})) + fi + if [[ ${M_STEP[$j]} -lt 10 ]] ; then + M_STEP[$j]=$((${M_STEP[$j]})) + fi + + j=$(($j+1)) +done + +echo ${M_TIME[*]} +echo ${M_STEP[*]} + + +rm mars_flux 2>/dev/null +j=0 +while [[ $j -lt 24 ]] ; do + marsflux ${M_TYPE[2]} ${FIELD[$j]} + j=$(($j+$DTIME)) +done +mars mars_flux +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + + +# +# FLXACC job +# + + +${EXEDIR}/FLXACC2 +if [ -f OROLSM ] ; then + rm OROLSM + + +fi + +# +# CONVERT job +# + +#loop over DATE and TIME for CONVERT/CHECK/ECtrans job + +iter=0 +IJULDAY=${JULDAY1} +while [ $IJULDAY -le $JULDAY2 ]; +do + +MDATE=`civildate2 ${IJULDAY}` +if [ $MSJ_BASETIME -eq 00 ] ; then + MDATE=`date2m1 ${MDATE}` +fi + +MDATEX=`echo ${MDATE} | cut -c3-8` + + +i=0 +rm marsjob 2>/dev/null + +#humidity on reduced Gaussian grid for initialization +#of spectral transformations +if [ ${M_GAUSS} -eq 1 ] ; then + NGRID=$(( ( ${M_RESOL} + 1 ) / 2 )) + + marsinst ${M_TYPE[0]} ${DAY1} 00 00 Q fort.18 ML ${QG_GRID} 1 'GAUSSIAN=REDUCED,' + +set -e +mars marsjob +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +rm marsjob + +fi + +set -e + +if [ $MSJ_BASETIME -eq 12 ] ; then + j=$(($DTIME)) + jmax=$(($DTIME+12)) +else + j=$(($DTIME+12)) +fi +if [ $iter -eq 1 ] ; then + j=0 + jmax=1 +fi +set -A TYPEKEY ${M_TYPE[$j]} +kmax=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[j]} != ${TYPEKEY[0]} ]] ; then + if [[ $kmax == 1 ]] ; then + if [[ ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${TYPEKEY[1]} ${M_TYPE[j]} + kmax=2 + fi + else + if [[ $kmax == 0 ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${M_TYPE[j]} + kmax=1 + else + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[2]} ]] ; then + + echo ${TYPEKEY[0]} ${TYPEKEY[1]} ${TYPEKEY[2]} ${M_TYPE[j]} + myerror 'More than three different MARS TYPES not supported' + + exit 1 + fi + fi + fi + fi + fi + j=$(($j+$DTIME)) +done + +set -A GRIDKEY $D_GRID +mmax=1 +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${GRID[$i]} == 'OFF' && ${PARLIST[$i]} != LNSP ]] ; then + set -A GRIDKEY $D_GRID OFF + mmax=2 + fi + i=$(($i+1)) +done + +k=0 +kmax=$(($kmax+1)) +while [[ $k -lt $kmax ]] ; do +MMTIME='' +MMSTEP='' +TSUFF='' +SSUFF='' +j=0 +if [ $MSJ_BASETIME -eq 12 ] ; then + j=$(($DTIME)) + jmax=$(($DTIME+12)) +else + j=$(($DTIME+12)) +fi +if [ $iter -eq 1 ] ; then + j=0 + jmax=1 +fi +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[$j]} == ${TYPEKEY[$k]} ]] ; then + if [[ `echo $MMTIME | grep ${M_TIME[$j]}` == '' ]] ; then + MMTIME=${MMTIME}$TSUFF${M_TIME[$j]} + TSUFF='/' + fi + if [[ `echo $MMSTEP | grep ${M_STEP[$j]}` == '' ]] ; then + MMSTEP=${MMSTEP}$SSUFF${M_STEP[$j]} + SSUFF='/' + fi + fi +j=$(($j+$DTIME)) +done + +m=0 +while [[ $m -lt $mmax ]] ; do +MMPAR='' +PSUFF='' +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${LTY[$i]} == ML && ${GRID[$i]} == ${GRIDKEY[m]} && ${PARLIST[$i]} != LNSP ]] ; then + if [[ `echo $MMPAR | grep ${PARLIST[$i]}` == '' ]] ; then + MMPAR=${MMPAR}$PSUFF${PARLIST[$i]} + PSUFF='/' + fi + fi +i=$(($i+1)) +done + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} $MMPAR "[param].[date].[time].[step]" ML ${GRIDKEY[$m]} ${LEVELIST[$m]} + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +m=$(($m+1)) +done +# LNSP treated separately since it exists only on 1 level + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} LNSP "[param].[date].[time].[step]" ML OFF 1 + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# For some data classes, MARS adds GRIB table number to parameter number, +# e.g. for Temperature it is 130.128 instead of just 130 +# + set +e + TNR=`ls 131*${MDATE}.${M_TIME[00]}00.${M_STEP[00]} | awk -F . '{print $2}' - | grep -v ${MDATE}`. + set -e + if [[ $TNR != '.' ]] ; then + TNR=.$TNR + fi + +# SURF treated separately since it exists only on 1 level + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[4]} "SURF${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob +# OROLSM treated separately since it exists only on 1 level + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[5]} "OROLSM${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +# if [ -f OROLSM ] ; then +# for oro in `ls +# cat OROLSM >> OROLSM${TNR}${MDATE}.${MMTIME}00.${MMSTEP} +# rm OROLSM +# echo 'found' +# exit 0 +# fi + rm marsjob + +k=$(($k+1)) +done + + + + +j=0 +if [ $MSJ_BASETIME -eq 12 ] ; then + j=$(($DTIME)) + jmax=$(($DTIME+12)) +else + j=$(($DTIME+12)) +fi +if [ $iter -eq 1 ] ; then + j=0 + jmax=1 +fi +while [[ $j -lt $jmax ]] ; do + + +TIME=${FIELD[$j]} +XTIME=${TIME}00 + +set +e +i=0 +while [[ $i -lt $imax ]] ; do + \rm fort.${UNIT[$i]} 2>/dev/null + if [[ ${PARLIST[$i]} == U/V ]] ; then + cat 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} > fort.${UNIT[$i]} + rm 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} + else + mv ${PARNAME[$i]}${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} fort.${UNIT[$i]} + fi + i=$(($i+1)) +done + +# flux data need special GRIB conversion +#if [ ${M_FORMAT} == GRIB2 ] ; then +# grib_set -w shortName!=lsp,shortName!=cp,shortName!=ewss,shortName!=nsss -s edition=2,productDefinitionTemplateNumber=8 flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +# +#else +# mv flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +#fi + +${EXEDIR}/CONVERT2 + +if [ $TIME -eq 00 ]; then + MDATE=`date2p1 ${MDATE}` + MDATEX=`echo ${MDATE} | cut -c 3-8` +fi + +INFILE=${PREFIX}${MDATEX}${TIME} + +if [ -s fort.15 ]; then + cp fort.15 ${INFILE} + cat fort.14 >> ${INFILE} + cat flux${MDATE}${TIME} >> ${INFILE} + cat OROLSM >> ${INFILE} + cat fort.20 >> ${INFILE} + +# +# Convert to GRIB2 if needed +# +# to enable additional compression try +# set packingType="grid_jpeg"; +# this is rather time consuming. + +if [ ${M_FORMAT} == GRIB2 ] ; then + grib_set -s edition=2,productDefinitionTemplateNumber=8 $INFILE ${INFILE}_2 + mv ${INFILE}_2 ${INFILE} + + if [ ${COMPRESSION} != grid_simple ] ; then + +cat >rule.filter<<EOF +set packingType="${COMPRESSION}"; +write "[file]_2"; +EOF + grib_filter rule.filter ${INFILE} + mv ${INFILE}_2 ${INFILE} + fi +fi +ls -l ${INFILE} + +else + echo ERROR: ENfile ${INFILE} missing! + echo ABORT! + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + exit 1 +fi + +#check ENxxx file & ECtrans to local gateway + + +\rm fort.15 2>/dev/null +ln -s ${INFILE} fort.15 + +[ -s CHECK.SUCCESS ] && rm CHECK.SUCCESS + +${EXEDIR}/CHECK + +#check fields +if [ -s CHECK.SUCCESS ]; then + SUCCESS=1 +else + echo 'ERROR: check on ENfile failed:' ${INFILE} + echo ABORT! + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + exit 1 +fi + + + +#ECtrans +if [ $SUCCESS -eq 1 -a $ECTRANS -eq 1 ] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source $INFILE +fi + +#ECFS +if [ $SUCCESS -eq 1 -a $ECSTORAGE -eq 1 ] ; then + ecp -o $INFILE $ECFSDIR +fi + +rm ${INFILE}_2 ${INFILE} fort.15 flux${MDATE}${TIME}* + +j=$(($j+$DTIME)) + +#done TIME +done + +(( IJULDAY = IJULDAY + 1 )) +(( iter = iter + 1 )) + +#done JULDAY +done + +#any warnings ? +[ $NRW -gt 0 ] && echo There were $NRW warnings ! + +#mail logfile (list MAILOPS) +for MUSER in $MAILOPS +do + +mailx -s ${JOBNAME} ${MUSER} <${LOG_FILE} +done + +# +# cleanup +# +cd ${SCRATCH} +echo $SCRATCHDIR not removed! +#\rm -fR $SCRATCHDIR + + +# go to next date 12 hours later + + if [ $(($MSJ%100)) -eq 0 ] ; then + MSJ=$(($MSJ+12)) + else + MSJ=$(($MSJ+88)) + fi + + + if [ $MSJ_MONTH -eq 2 ] + then + DDD=28 + [ `expr \$YYY \% 4` -eq 0 ] && DDD=29 + elif [ $MSJ_MONTH -eq 4 -o $MSJ_MONTH -eq 6 -o $MSJ_MONTH -eq 9 -o $MSJ_MONTH -eq 11 ] + then + DDD=30 + else + DDD=31 + fi + + if [ $MSJ_DAY -gt $DDD ] ; then + MSJ_DAY=1 + MSJ_MONTH=$(($MSJ_MONTH+1)) + fi + if [ $MSJ_MONTH -gt 12 ] ; then + MSJ_MONTH=1 + MSJ_YEAR=$(($MSJ_YEAR+1)) + fi + + + +# close +done diff --git a/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_footer b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_footer new file mode 100644 index 00000000..cd67637b --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_footer @@ -0,0 +1,33 @@ +# go to next date 12 hours later + + if [ $(($MSJ%100)) -eq 0 ] ; then + MSJ=$(($MSJ+12)) + else + MSJ=$(($MSJ+88)) + fi + + + if [ $MSJ_MONTH -eq 2 ] + then + DDD=28 + [ `expr \$YYY \% 4` -eq 0 ] && DDD=29 + elif [ $MSJ_MONTH -eq 4 -o $MSJ_MONTH -eq 6 -o $MSJ_MONTH -eq 9 -o $MSJ_MONTH -eq 11 ] + then + DDD=30 + else + DDD=31 + fi + + if [ $MSJ_DAY -gt $DDD ] ; then + MSJ_DAY=1 + MSJ_MONTH=$(($MSJ_MONTH+1)) + fi + if [ $MSJ_MONTH -gt 12 ] ; then + MSJ_MONTH=1 + MSJ_YEAR=$(($MSJ_YEAR+1)) + fi + + + +# close +done diff --git a/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_header b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_header new file mode 100644 index 00000000..ca1c56c0 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_header @@ -0,0 +1,83 @@ +#!/bin/ksh + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf_oper +#SBATCH --output=ms_sms_output_V6.0/CTBTO_ops.out +#SBATCH --error=ms_sms_output_V6.0/CTBTO_ops.out +#SBATCH --mail-type=ALL +#SBATCH --time=12:00:00 + + +set -x + +alias ecp='set noglob; $ECFS_SYS_PATH/ecp.p' + +export OMP_NUM_HREADS=1 + + + +########################### + +# ADD BEGIN AND END HERE # + +########################### + + MSJ_START=2013110700 + MSJ_END=2013110812 + + +########################### + +# NO CHANGES BELOW # + +########################### + +VERSION=6.0 +JOBNAME=ecmwf_idc_ops_ecgate_V${VERSION} +CONTROLFILE=${HOME}/flex_extract_ecgate_V${VERSION}/CONTROL_OPS_V${VERSION} + +WDAY=$(date +%A) +[ ! -d $SCRATCH/ms_sms_output_V${VERSION} ] && mkdir $SCRATCH/ms_sms_output_V${VERSION} + +LOG_FILE=$SCRATCH/ms_sms_output_V${VERSION}/${JOBNAME}_${WDAY} +exec 1>${LOG_FILE} + +[ -z "$WSHOME" ] && export WSHOME=$HOME + + DAY1=$(($MSJ_START/100)) + DAY2=$(($MSJ_END/100)) + TDIFF=$(( (`date +%s -d $DAY2` - `date +%s -d $DAY1` )/86400 )) + if [[ $TDIFF -lt 0 || $TDIFF -gt 31 ]] ; then + echo invalid difference $TDIFF between dates $1, $2 + echo difference must be positive and smaller than 32 + exit + fi + + + MSJ=$MSJ_START + MSJ_YEAR=$(( ($MSJ/1000000))) + while [ $MSJ -le $MSJ_END ] + do + + MSJ_MONTH=$(( ($MSJ%1000000)/10000)) + MSJ_DAY=$(( ($MSJ%10000)/100)) + MSJ_BASETIME=$(($MSJ%100)) + + if [ $MSJ_MONTH -lt 10 ] ; then + MSJ_MONTH='0'$MSJ_MONTH + fi + if [ $MSJ_DAY -lt 10 ] ; then + MSJ_DAY='0'$MSJ_DAY + fi + if [ $MSJ_BASETIME -lt 10 ] ; then + MSJ_BASETIME='0'$MSJ_BASETIME + fi + + MSJ=$MSJ_YEAR$MSJ_MONTH$MSJ_DAY$MSJ_BASETIME + + echo 'MSJ_ENVIRONMENT:' $MSJ + + DATEREF=${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY} + + diff --git a/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_header_template b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_header_template new file mode 100644 index 00000000..188c8b2d --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/ecmwf_idc_ops_multi_header_template @@ -0,0 +1,83 @@ +#!/bin/ksh + +#SBATCH --workdir=/scratch/ms/ggg/xxx +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf_oper +#SBATCH --output=ms_sms_output_Vv.v/CTBTO_ops.out +#SBATCH --error=ms_sms_output_Vv.v/CTBTO_ops.out +#SBATCH --mail-type=ALL +#SBATCH --time=12:00:00 + + +set -x + +alias ecp='set noglob; $ECFS_SYS_PATH/ecp.p' + +export OMP_NUM_HREADS=1 + + + +########################### + +# ADD BEGIN AND END HERE # + +########################### + + MSJ_START=2013110700 + MSJ_END=2013110812 + + +########################### + +# NO CHANGES BELOW # + +########################### + +VERSION=v.v +JOBNAME=ecmwf_idc_ops_ecgate_V${VERSION} +CONTROLFILE=${HOME}/flex_extract_ecgate_V${VERSION}/CONTROL_OPS_V${VERSION} + +WDAY=$(date +%A) +[ ! -d $SCRATCH/ms_sms_output_V${VERSION} ] && mkdir $SCRATCH/ms_sms_output_V${VERSION} + +LOG_FILE=$SCRATCH/ms_sms_output_V${VERSION}/${JOBNAME}_${WDAY} +exec 1>${LOG_FILE} + +[ -z "$WSHOME" ] && export WSHOME=$HOME + + DAY1=$(($MSJ_START/100)) + DAY2=$(($MSJ_END/100)) + TDIFF=$(( (`date +%s -d $DAY2` - `date +%s -d $DAY1` )/86400 )) + if [[ $TDIFF -lt 0 || $TDIFF -gt 31 ]] ; then + echo invalid difference $TDIFF between dates $1, $2 + echo difference must be positive and smaller than 32 + exit + fi + + + MSJ=$MSJ_START + MSJ_YEAR=$(( ($MSJ/1000000))) + while [ $MSJ -le $MSJ_END ] + do + + MSJ_MONTH=$(( ($MSJ%1000000)/10000)) + MSJ_DAY=$(( ($MSJ%10000)/100)) + MSJ_BASETIME=$(($MSJ%100)) + + if [ $MSJ_MONTH -lt 10 ] ; then + MSJ_MONTH='0'$MSJ_MONTH + fi + if [ $MSJ_DAY -lt 10 ] ; then + MSJ_DAY='0'$MSJ_DAY + fi + if [ $MSJ_BASETIME -lt 10 ] ; then + MSJ_BASETIME='0'$MSJ_BASETIME + fi + + MSJ=$MSJ_YEAR$MSJ_MONTH$MSJ_DAY$MSJ_BASETIME + + echo 'MSJ_ENVIRONMENT:' $MSJ + + DATEREF=${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY} + + diff --git a/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_CV b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_CV new file mode 100644 index 00000000..a870879a --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_CV @@ -0,0 +1,873 @@ +#!/bin/ksh + +# On demand script for retrieving input for FLEXPART trajectory model +# Version 6.0, September 2013 +# Maintainer Leopold Haimberger leopold.haimberger@univie.ac.at +# +#@ shell = /usr/bin/ksh + +# NOTE: If calculation on Gaussian grid are required below, it is +# recommended to send the job to the ECMWF HPC facility +# NOTE: On hpce the class should be ns or np +# NOTE: On ecgb it should be normal + + +#ON HPC (with loadleveler) +# start with ecaccess-job-submit -queueName c1a NAME_OF_THIS_FILE on gateway server +# start with llsubmit NAME_OF_THIS_FILE directly on machine + +#@ shell = /usr/bin/ksh +#@ class = ns +#@ resources = ConsumableCpus(1) ConsumableMemory(32000MB) +#@ job_name = flex_ecmwf +#@ output = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ error = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ environment = COPY_ALL +#@ queue + + +# ON ECGB: +# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE on gateway server +# start with sbatch NAME_OF_THIS_FILE directly on machine + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf +#SBATCH --output=flex_ecmwf.%j.out +#SBATCH --error=flex_ecmwf.%j.out +#SBATCH --mail-type=FAIL +#SBATCH --time=12:00:00 + +set -x + +JOBNAME=flex_ecmwf_${HOST} + +env +ulimit -a +export OMP_NUM_THREADS=1 +export MARS_MULTITARGET_STRICT_FORMAT=1 + +#export SCRATCH=$TEMP +export SCRATCHDIR=${SCRATCH}/${JOBNAME}_$$ +[ -z "$WSHOME" ] && WSHOME=$HOME + + +mkdir $SCRATCHDIR +cd $SCRATCHDIR + +LOG_FILE=$SCRATCHDIR/${JOBNAME}_$$ +exec 1>${LOG_FILE} + +CONTROLFILE=./CONTROL_ERA + +################################### +#BEGIN: modification of config file +################################### + +cat <<EOF >CONTROL_ERA +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV +M_TIME 00 00 00 00 00 00 00 00 00 00 00 00 12 12 12 12 12 12 12 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 06 07 08 09 10 11 00 01 02 03 04 05 06 07 08 09 10 11 +M_CLASS OD +M_STREAM ENFO +M_NUMBER 1 +M_EXPVER 1 +M_GRID 1000 +M_LEFT -179000 +M_LOWER -90000 +M_UPPER 90000 +M_RIGHT 180000 +M_LEVEL 62 +M_RESOL 159 +M_GAUSS 1 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 0 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EG +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF +# no changes below + +NRW=0 + +#ksh scripts for date manipulation +juldate2() + { + let jc=$1 + if (( ${#jc} < 8 )) + then + print "illegal date!" + exit 1 + fi + let y=`echo $jc | cut -c1-4` + let m1=`echo $jc | cut -c5` + let m2=`echo $jc | cut -c6` + m=$m1$m2 + let d1=`echo $jc | cut -c7` + let d2=`echo $jc | cut -c8` + d=$d1$d2 + let jd=367*y-7*(y+(m+9)/12)/4+275*m/9+d+1721014 + let jd=jd+15-3*((y+(m-9)/7)/100+1)/4 + print $jd + } + +civildate2() + { + let jd=$1 + if (( jd < 1721060 )) + then + print "Julian date not in AD." + exit 1 + fi + let k=jd+68569 + let n=4*k/146097 + let k=k-\(146097*n+3\)/4 + let y=4000*(k+1)/1461001 + let k=k-1461*y/4+31 + let m=80*k/2447 + let d=k-\(2447*m\)/80 + let k=m/11 + let m=m+2-12*k + let y=100*(n-49)+y+k + [ $m -le 9 ] && m=0$m + [ $d -le 9 ] && d=0$d + print $y$m$d + } + +date2m1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-1 + civildate2 $j0 + } + +date2p1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1+1 + civildate2 $j0 + } + + +marsinst() +{ +MTYPE="${1}" +MDAY="${2}" +MTIME="${3}" +MSTEP="${4}" +MPAR="${5}" +MFN=$6 +MLTY=$7 +MGRID="${8}" +MLEV="${9}" + +RED=0 +#if [[ ${MTYPE} != 'AN' ]] ; then + MPAR2=`echo ${MPAR} | sed s,160/,,` + MPAR2=`echo ${MPAR2} | sed s,27/,,` + MPAR2=`echo ${MPAR2} | sed s,28/,,` + MPAR2=`echo ${MPAR2} | sed s,173/,,` + if [[ ${MPAR2} != ${MPAR} ]] ; then + MPAR=${MPAR2} + RED=1 + fi +#fi + +MAREA=${M_AREA} +if [[ ${10} == 'GAUSSIAN=REDUCED,' ]] ; then + MAREA=G +fi + +if [[ -f ${MFN} ]] ; then + rm ${MFN} +fi + +cat <<EOF >> marsjob +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=${MPAR}, +RESOL=${M_RESOL}, +AREA=${MAREA}, +GRID=${MGRID}, +LEVTYPE=${MLTY}, +LEVELIST=${MLEV}, +ACCURACY=${M_ACCURACY}, +DATE=${MDAY}, +TIME=${MTIME}, +STEP=${MSTEP},${10} +TARGET="${MFN}" +EOF + +if [[ ! -f 'OROLSM' && $RED -eq 1 ]] ; then + +cat <<EOF >> marsjob +RETRIEVE,TYPE=AN,TIME=0,STEP=0,CLASS=OD, + PARAM=160/27/28/173, + TARGET="OROLSM" +EOF +fi + +} + +marsflux() +{ +MTYPE="${1}" +MSTEP="${2}" + +cat <<EOF >>mars_flux +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=LSP/CP/SSHF/EWSS/NSSS/SSR, +AREA=${M_AREA}, +GRID=${D_GRID}, +LEVTYPE=SFC, +LEVELIST=OFF, +ACCURACY=${M_ACCURACY}, REPRES=GG, +DATE=${DAY1M1}/TO/${DAY2P1}, +TIME=00/12, +AC=N, +STEP=${MSTEP}, +TARGET="surf_${MSTEP}_ub" +EOF +} + + +myerror() + { + + echo $1 + echo $2 + echo $3 + echo ABORT! + + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + } + +# +# MAIN SCRIPT CONTINUES HERE +# +#read CONTROL file, process specifications +while read NAME PARA +do + +if [[ $NAME == 'M_TYPE' || $NAME == 'M_TIME' || $NAME == 'M_STEP' ]] ; then + eval "set -A $NAME $PARA" +else + eval "export $NAME='$PARA'" +fi +echo `echo $NAME`=$PARA + +done <${CONTROLFILE} + + +if [ -z "$DAY1" -o -z "$DAY2" ]; then + myerror 'DAY specification missing !' + exit 1 +fi + +#defaults +[ -z "$M_EXPVER" ] && M_EXPVER=1 +[ -z "$M_CLASS" ] && M_CLASS=OD +[ -z "$M_STREAM" ] && M_STREAM=OPER +[ -z "$M_NUMBER" ] && M_NUMBER=OFF +[ -z "$M_TYPE" ] && set -A M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +[ -z "$M_TIME" ] && set -A M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +[ -z "$M_STEP" ] && set -A M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +[ -z "$DTIME" ] && DTIME=6 +[ -z "$M_GRID" ] && M_GRID=1000 +[ -z "$M_LOWER" ] && M_LOWER=-90000 +[ -z "$M_LEFT" ] && M_LEFT=-179000 +[ -z "$M_UPPER" ] && M_UPPER=90000 +[ -z "$M_RIGHT" ] && M_RIGHT=180000 +[ -z "$M_LEVEL" ] && M_LEVEL=91 +[ -z "$M_LEVELIST" ] && M_LEVELIST=1/TO/$M_LEVEL +[ -z "$M_ADDPAR" ] && M_ADDPAR='' +[ -z "$M_RESOL" ] && M_RESOL=799 +[ -z "$M_GAUSS" ] && M_GAUSS=0 +[ -z "$M_SMOOTH" ] && M_SMOOTH=0 +[ -z "$M_OMEGA" ] && M_OMEGA=0 +[ -z "$M_OMEGADIFF" ] && M_OMEGADIFF=0 +[ -z "$M_ETA" ] && M_ETA=0 +[ -z "$M_ETADIFF" ] && M_ETADIFF=0 +[ -z "$M_ETAPAR" ] && M_ETAPAR=77 +[ -z "$M_DPDETA" ] && M_DPDETA=1 +[ -z "$M_ACCURACY" ] && M_ACCURACY=24 +[ -z "$EXEDIR" ] && EXEDIR=. +[ -z "$SOURCECODE" ] && SOURCECODE=ecgate:flex_extract_ecgate +[ -z "$GATEWAY" ] && GATEWAY='' +[ -z "$DESTINATION" ] && DESTINATION='' +[ -z "$PREFIX" ] && PREFIX=EN +[ -z "$COMPRESSION" ] && COMPRESSION=grid_simple +[ -z "$ECTRANS" ] && ECTRANS=0 +[ -z "$ECSTORAGE" ] && ECSTORAGE=1 +[ -z "$ECFSDIR" ] && ECFSDIR=ectmp: +[ -z "$MAILOPS" ] && MAILOPS=${USER} +[ -z "$MAILFAIL" ] && MAILFAIL=${USER} + + +#additional dates for flux retrievals (polynomial interpolation) +DAY1M1=`date2m1 ${DAY1}` +DAY2P1=`date2p1 ${DAY2}` + +#julian dates for time loops +JULDAY1=`juldate2 ${DAY1}` +JULDAY2=`juldate2 ${DAY2}` + +echo JULDATES $JULDAY1 $JULDAY2 + +#check consistency +if [ ${DAY1} -gt ${DAY2} ]; then + `myerror "ERROR: DAY1 > DAY2: ${DAY1}, ${DAY2}"` + exit 1 +fi + + +# determine number of gridpoints and whether grid is cyclic +ZYK=`expr \( $M_RIGHT + 360000 \) % 360000 - \( $M_LEFT + 360000 \) % 360000 + $M_GRID` + +if [ $M_RIGHT -le $M_LEFT ] ; then + if [ $M_RIGHT -le 0 ] ; then + M_RIGHT=$(($M_RIGHT+360000)) + else + M_LEFT=$(($M_LEFT-360000)) + fi +fi + +if [[ $ZYK -ne 0 ]] ; then + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED NON-CYCLIC" + exit 1 + fi +else + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED CYCLIC" + exit 1 + fi +fi + +if [ $((180000/$M_GRID-$M_RESOL)) -lt 0 ] ; then + + if [ ${M_SMOOTH} -eq 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SPECTRAL RESOLUTION ${M_RESOL} " "USE M_SMOOTH FOR SMOOTHING OR FINER OUTPUT GRID" +# exit 1 + else + if [ $((180000/$M_GRID-$M_SMOOTH)) -lt 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SMOOTHED SPECTRAL RESOLUTION ${M_SMOOTH} " + fi + fi + +fi + + +# convert lat/lon to MARS format (degrees) +if [[ $M_LEFT -lt 0 ]] ; then + LLLO=$(($M_LEFT / 1000)).$((($M_LEFT)*(-1) % 1000)) +else + LLLO=$(($M_LEFT / 1000)).$(($M_LEFT % 1000)) +fi +if [[ $M_LOWER -lt 0 ]] ; then + LLLA=$(($M_LOWER / 1000)).$(($M_LOWER*(-1) % 1000)) +else + LLLA=$(($M_LOWER / 1000)).$((($M_LOWER) % 1000)) +fi +if [[ $M_RIGHT -lt 0 ]] ; then + URLO=$(($M_RIGHT / 1000)).$((($M_RIGHT)*(-1) % 1000)) +else + URLO=$(($M_RIGHT / 1000)).$(($M_RIGHT % 1000)) +fi +if [[ $M_UPPER -lt 0 ]] ; then + URLA=$(($M_UPPER / 1000)).$((($M_UPPER)*(-1) % 1000)) +else + URLA=$(($M_UPPER / 1000)).$(($M_UPPER % 1000)) +fi + +M_AREA=${URLA}/${LLLO}/${LLLA}/${URLO} + +if [ $M_GAUSS -eq 1 ] ; then +# Gaussian grid detected + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=OFF + QG_GRID=OFF + if [ $M_RESOL -le 799 ] ; then + QG_GRID=$((($M_RESOL+1)/2)) + fi + D_GRID=${D_GRID}/${D_GRID} + +else + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=${G_GRID}/${G_GRID} + D_GRID=${D_GRID}/${D_GRID} +fi + +G_LEVELIST=1/to/${M_LEVEL} + + +#namelist +cat <<EOF >fort.4 +&NAMGEN + MAXL=${MAXL}, MAXB=${MAXB}, + MLEVEL=${M_LEVEL}, MLEVELIST="${M_LEVELIST}", + MNAUF=${M_RESOL},METAPAR=${M_ETAPAR}, + RLO0=${LLLO}, RLO1=${URLO}, RLA0=${LLLA}, RLA1=${URLA}, + MOMEGA=${M_OMEGA},MOMEGADIFF=${M_OMEGADIFF},MGAUSS=${M_GAUSS}, + MSMOOTH=${M_SMOOTH},META=${M_ETA},METADIFF=${M_ETADIFF}, + MDPDETA=${M_DPDETA} +/ +&NAMFX2 + NX=${MAXL}, NY=${MAXB}, + MAXTIME=400,JPOLY=4, + JHRF=${DTIME}, + RLO0=${LLLO}, RLA0=${LLLA}, DX=${D_GRID}, DY=${D_GRID} +/ +EOF + + +if [[ $OS_VERSION == aix ]] ; then + scp ecgb:${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.IBM FLXACC2 CONVERT2 CHECK +else + cp ${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.ecgb FLXACC2 CONVERT2 CHECK +fi + +if [ $? -ne 0 ]; then + + ls + myerror 'ERROR: FLXACC2 and CONVERT2 could not be compiled:' 'ABORT!' + exit 1 +else + echo 'compile worked' +fi + + +# +#MARS requests (field) +# +imax=6 +set -A PARLIST U/V T Q LNSP SD/MSL/TCC/10U/10V/2T/2D 129/172/160${M_ADDPAR} +set -A PARNAME 131/132 130 133 152 SURF OROLSM +set -A REPR SH SH GG SH GG GG +set -A UNIT 10 11 17 12 14 20 +set -A LTY ML ML ML ML SFC SFC +set -A GRID ${G_GRID} ${D_GRID} ${D_GRID} OFF ${D_GRID} ${D_GRID} +set -A LEVELIST ${M_LEVELIST} ${M_LEVELIST} ${M_LEVELIST} 1 1 1 + +set -A FIELD 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 + + +if [[ $M_OMEGA -eq 1 || $M_OMEGADIFF -eq 1 ]] ; then + M_OMEGA=1 + PARLIST[imax]=W + PARNAME[imax]=135 + REPR[imax]=SH + UNIT[imax]=19 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 1 || $M_ETADIFF -eq 1 ]] ; then + M_ETA=1 + PARLIST[imax]=77 + PARNAME[imax]=77 + REPR[imax]=SH + UNIT[imax]=21 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi + +if [[ $M_GAUSS -eq 2 ]] ; then + PARLIST[imax]=VO + PARNAME[imax]=138 + REPR[imax]=SH + UNIT[imax]=30 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 0 || $M_GAUSS -eq 1 || $M_ETADIFF -eq 1 ]] ; then + PARLIST[imax]=D + PARNAME[imax]=155 + REPR[imax]=SH + UNIT[imax]=13 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + LEVELIST[1]=${G_LEVELIST} # U/V needed on all levels for calculating ETA + imax=$(($imax+1)) +fi + +jmax=${#M_TYPE[*]} + +# M_TIME needs leading zeros while M_STEP must have leading zeros +# to be consistent with MARS file naming convention +# The following loop ensures this +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TIME[$j]} -lt 10 ]] ; then + M_TIME[$j]=0$((${M_TIME[$j]})) + fi + if [[ ${M_STEP[$j]} -lt 10 ]] ; then + M_STEP[$j]=$((${M_STEP[$j]})) + fi + + j=$(($j+1)) +done + +echo ${M_TIME[*]} +echo ${M_STEP[*]} + + +rm mars_flux 2>/dev/null +j=$DTIME +while [[ $j -lt 13 ]] ; do + marsflux ${M_TYPE[2]} ${FIELD[$j]} + j=$(($j+$DTIME)) +done +mars mars_flux | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + + +# +# FLXACC job +# + + +${EXEDIR}/FLXACC2 +if [ -f OROLSM ] ; then + rm OROLSM +fi + +# +# CONVERT job +# + +#loop over DATE and TIME for CONVERT/CHECK/ECtrans job + +IJULDAY=${JULDAY1} +while [ $IJULDAY -le $JULDAY2 ]; +do + +MDATE=`civildate2 ${IJULDAY}` +MDATEX=`echo ${MDATE} | cut -c3-8` + + +i=0 +rm marsjob 2>/dev/null + +#humidity on reduced Gaussian grid for initialization +#of spectral transformations +if [ ${M_GAUSS} -eq 1 ] ; then + NGRID=$(( ( ${M_RESOL} + 1 ) / 2 )) + + marsinst ${M_TYPE[0]} ${DAY1} 00 00 Q fort.18 ML ${QG_GRID} 1 'GAUSSIAN=REDUCED,' + +set -e +mars marsjob | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +rm marsjob + +fi + +set -e + +set -A TYPEKEY ${M_TYPE[0]} +j=$DTIME +kmax=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[j]} != ${TYPEKEY[0]} ]] ; then + if [[ $kmax == 1 ]] ; then + if [[ ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${TYPEKEY[1]} ${M_TYPE[j]} + kmax=2 + fi + else + if [[ $kmax == 0 ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${M_TYPE[j]} + kmax=1 + else + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[2]} ]] ; then + + echo ${TYPEKEY[0]} ${TYPEKEY[1]} ${TYPEKEY[2]} ${M_TYPE[j]} + myerror 'More than three different MARS TYPES not supported' + + exit 1 + fi + fi + fi + fi + fi + j=$(($j+$DTIME)) +done + +set -A GRIDKEY $D_GRID +mmax=1 +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${GRID[$i]} == 'OFF' && ${PARLIST[$i]} != LNSP ]] ; then + set -A GRIDKEY $D_GRID OFF + mmax=2 + fi + i=$(($i+1)) +done + +k=0 +kmax=$(($kmax+1)) +while [[ $k -lt $kmax ]] ; do +MMTIME='' +MMSTEP='' +TSUFF='' +SSUFF='' +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[$j]} == ${TYPEKEY[$k]} ]] ; then + if [[ `echo $MMTIME | grep ${M_TIME[$j]}` == '' ]] ; then + MMTIME=${MMTIME}$TSUFF${M_TIME[$j]} + TSUFF='/' + fi + if [[ `echo $MMSTEP | grep ${M_STEP[$j]}` == '' ]] ; then + MMSTEP=${MMSTEP}$SSUFF${M_STEP[$j]} + SSUFF='/' + fi + fi +j=$(($j+$DTIME)) +done + +m=0 +while [[ $m -lt $mmax ]] ; do +MMPAR='' +PSUFF='' +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${LTY[$i]} == ML && ${GRID[$i]} == ${GRIDKEY[m]} && ${PARLIST[$i]} != LNSP ]] ; then + if [[ `echo $MMPAR | grep ${PARLIST[$i]}` == '' ]] ; then + MMPAR=${MMPAR}$PSUFF${PARLIST[$i]} + PSUFF='/' + fi + fi +i=$(($i+1)) +done + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} $MMPAR "[param].[date].[time].[step]" ML ${GRIDKEY[$m]} ${LEVELIST[$m]} + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +m=$(($m+1)) +done + +# LNSP treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} LNSP "[param].[date].[time].[step]" ML OFF 1 + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# For some data classes, MARS adds GRIB table number to parameter number, +# e.g. for Temperature it is 130.128 instead of just 130 +# + set +e + TNR=`ls 131*${MDATE}.${M_TIME[00]}00.${M_STEP[00]} | awk -F . '{print $2}' - | grep -v ${MDATE}`. + set -e + if [[ $TNR != '.' ]] ; then + TNR=.$TNR + fi + +# SURF treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[4]} "SURF${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# OROLSM treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[5]} "OROLSM${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +k=$(($k+1)) +done + + + +j=0 +while [[ $j -lt $jmax ]] ; do + + +TIME=${FIELD[j]} +XTIME=${TIME}00 + +set +e +i=0 +while [[ $i -lt $imax ]] ; do + \rm fort.${UNIT[$i]} 2>/dev/null + if [[ ${PARLIST[$i]} == U/V ]] ; then + cat 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} > fort.${UNIT[$i]} + rm 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} + else + mv ${PARNAME[$i]}${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} fort.${UNIT[$i]} + fi + i=$(($i+1)) +done + +# flux data need special GRIB conversion +#if [ ${M_FORMAT} == GRIB2 ] ; then +# grib_set -w shortName!=lsp,shortName!=cp,shortName!=ewss,shortName!=nsss -s edition=2,productDefinitionTemplateNumber=8 flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 + +#else +# mv flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +#fi + +${EXEDIR}/CONVERT2 + +INFILE=${PREFIX}${MDATEX}${TIME} + +if [ -s fort.15 ]; then + cp fort.15 ${INFILE} + cat fort.14 >> ${INFILE} + cat flux${MDATE}${TIME} >> ${INFILE} + cat OROLSM >> ${INFILE} + cat fort.20 >> ${INFILE} +# +# Convert also surface fields to GRIB2 if needed +# +# Note: GRIB2 surface fields are incompatible with FLEXPART versions < 9.2 +# +# To enable additional compression +# set packingType="grid_jpeg"; +# this is rather time consuming. + +if [ ${M_FORMAT} == GRIB2 ] ; then + grib_set -s edition=2,productDefinitionTemplateNumber=8 $INFILE ${INFILE}_2 + mv ${INFILE}_2 ${INFILE} + + if [ ${COMPRESSION} != grid_simple ] ; then + +cat >rule.filter<<EOF +set packingType="${COMPRESSION}"; +write "[file]_2"; +EOF + grib_filter rule.filter ${INFILE} + mv ${INFILE}_2 ${INFILE} + fi +fi +ls -l ${INFILE} + + +else + myerror "ERROR: ENfile ${INFILE} missing!" "ABORT!" + exit 1 +fi + +#check ENxxx file & ECtrans to local gateway +if [ -s fort.25 ]; then + mv fort.25 OMEGA${MDATEX}${TIME} + ln -s OMEGA${MDATEX}${TIME} fort.25 +fi + + +\rm fort.15 2>/dev/null +ln -s ${INFILE} fort.15 + +[ -s CHECK.SUCCESS ] && rm CHECK.SUCCESS + +${EXEDIR}/CHECK + +#check fields +if [ -s CHECK.SUCCESS ]; then + SUCCESS=1 +else + myerror 'ERROR: check on ENfile failed:' ${INFILE} "ABORT!" + exit 1 +fi + + +#ECtrans +if [ $SUCCESS -eq 1 -a $ECTRANS -eq 1 ] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source $INFILE +fi + +if [[ $M_OMEGA -eq 1 && $SUCCESS -eq 1 && $ECTRANS -eq 1 ]] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source OMEGA${MDATEX}${TIME} +fi + +#ECFS +if [ $SUCCESS -eq 1 -a $ECSTORAGE -eq 1 ] ; then + ecp -o $INFILE $ECFSDIR +fi + +if [[ $SUCCESS -eq 1 && $ECSTORAGE -eq 1 && $M_OMEGA -eq 1 ]] ; then + ecp -o OMEGA${MDATEX}${TIME} $ECFSDIR +fi + +rm ${INFILE}_2 ${INFILE} fort.15 flux${MDATE}${TIME}* OMEGA${MDATEX}${TIME} fort.25 + +j=$(($j+$DTIME)) + +#done TIME +done + +(( IJULDAY = IJULDAY + 1 )) + +#done JULDAY +done + +#any warnings ? +[ $NRW -gt 0 ] && echo There were $NRW warnings ! + +#mail logfile (list MAILOPS) +for MUSER in $MAILOPS +do + +mailx -s ${JOBNAME} ${MUSER} <${LOG_FILE} +done + +# +# cleanup +# +cd ${SCRATCH} +echo $SCRATCHDIR not removed! +#\rm -fR $SCRATCHDIR + +exit 0 + diff --git a/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_EI b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_EI new file mode 100644 index 00000000..b6f57c44 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_EI @@ -0,0 +1,873 @@ +#!/bin/ksh + +# On demand script for retrieving input for FLEXPART trajectory model +# Version 6.0, September 2013 +# Maintainer Leopold Haimberger leopold.haimberger@univie.ac.at +# +#@ shell = /usr/bin/ksh + +# NOTE: If calculation on Gaussian grid are required below, it is +# recommended to send the job to the ECMWF HPC facility +# NOTE: On hpce the class should be ns or np +# NOTE: On ecgb it should be normal + + +#ON HPC (with loadleveler) +# start with ecaccess-job-submit -queueName c1a NAME_OF_THIS_FILE on gateway server +# start with llsubmit NAME_OF_THIS_FILE directly on machine + +#@ shell = /usr/bin/ksh +#@ class = ns +#@ resources = ConsumableCpus(1) ConsumableMemory(32000MB) +#@ job_name = flex_ecmwf +#@ output = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ error = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ environment = COPY_ALL +#@ queue + + +# ON ECGB: +# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE on gateway server +# start with sbatch NAME_OF_THIS_FILE directly on machine + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf +#SBATCH --output=flex_ecmwf.%j.out +#SBATCH --error=flex_ecmwf.%j.out +#SBATCH --mail-type=FAIL +#SBATCH --time=12:00:00 + +set -x + +JOBNAME=flex_ecmwf_${HOST} + +env +ulimit -a +export OMP_NUM_THREADS=1 +export MARS_MULTITARGET_STRICT_FORMAT=1 + +#export SCRATCH=$TEMP +export SCRATCHDIR=${SCRATCH}/${JOBNAME}_$$ +[ -z "$WSHOME" ] && WSHOME=$HOME + + +mkdir $SCRATCHDIR +cd $SCRATCHDIR + +LOG_FILE=$SCRATCHDIR/${JOBNAME}_$$ +exec 1>${LOG_FILE} + +CONTROLFILE=./CONTROL_ERA + +################################### +#BEGIN: modification of config file +################################### + +cat <<EOF >CONTROL_ERA +DAY1 20121107 +DAY2 20121108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS EI +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 1000 +M_LEFT -179000 +M_LOWER -90000 +M_UPPER 90000 +M_RIGHT 180000 +M_LEVEL 60 +M_RESOL 159 +M_GAUSS 1 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 0 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EI +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF +# no changes below + +NRW=0 + +#ksh scripts for date manipulation +juldate2() + { + let jc=$1 + if (( ${#jc} < 8 )) + then + print "illegal date!" + exit 1 + fi + let y=`echo $jc | cut -c1-4` + let m1=`echo $jc | cut -c5` + let m2=`echo $jc | cut -c6` + m=$m1$m2 + let d1=`echo $jc | cut -c7` + let d2=`echo $jc | cut -c8` + d=$d1$d2 + let jd=367*y-7*(y+(m+9)/12)/4+275*m/9+d+1721014 + let jd=jd+15-3*((y+(m-9)/7)/100+1)/4 + print $jd + } + +civildate2() + { + let jd=$1 + if (( jd < 1721060 )) + then + print "Julian date not in AD." + exit 1 + fi + let k=jd+68569 + let n=4*k/146097 + let k=k-\(146097*n+3\)/4 + let y=4000*(k+1)/1461001 + let k=k-1461*y/4+31 + let m=80*k/2447 + let d=k-\(2447*m\)/80 + let k=m/11 + let m=m+2-12*k + let y=100*(n-49)+y+k + [ $m -le 9 ] && m=0$m + [ $d -le 9 ] && d=0$d + print $y$m$d + } + +date2m1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-1 + civildate2 $j0 + } + +date2p1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1+1 + civildate2 $j0 + } + + +marsinst() +{ +MTYPE="${1}" +MDAY="${2}" +MTIME="${3}" +MSTEP="${4}" +MPAR="${5}" +MFN=$6 +MLTY=$7 +MGRID="${8}" +MLEV="${9}" + +RED=0 +#if [[ ${MTYPE} != 'AN' ]] ; then + MPAR2=`echo ${MPAR} | sed s,160/,,` + MPAR2=`echo ${MPAR2} | sed s,27/,,` + MPAR2=`echo ${MPAR2} | sed s,28/,,` + MPAR2=`echo ${MPAR2} | sed s,173/,,` + if [[ ${MPAR2} != ${MPAR} ]] ; then + MPAR=${MPAR2} + RED=1 + fi +#fi + +MAREA=${M_AREA} +if [[ ${10} == 'GAUSSIAN=REDUCED,' ]] ; then + MAREA=G +fi + +if [[ -f ${MFN} ]] ; then + rm ${MFN} +fi + +cat <<EOF >> marsjob +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=${MPAR}, +RESOL=${M_RESOL}, +AREA=${MAREA}, +GRID=${MGRID}, +LEVTYPE=${MLTY}, +LEVELIST=${MLEV}, +ACCURACY=${M_ACCURACY}, +DATE=${MDAY}, +TIME=${MTIME}, +STEP=${MSTEP},${10} +TARGET="${MFN}" +EOF + +if [[ ! -f 'OROLSM' && $RED -eq 1 ]] ; then + +cat <<EOF >> marsjob +RETRIEVE,TYPE=AN,TIME=0,STEP=0,CLASS=OD, + PARAM=160/27/28/173, + TARGET="OROLSM" +EOF +fi + +} + +marsflux() +{ +MTYPE="${1}" +MSTEP="${2}" + +cat <<EOF >>mars_flux +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=LSP/CP/SSHF/EWSS/NSSS/SSR, +AREA=${M_AREA}, +GRID=${D_GRID}, +LEVTYPE=SFC, +LEVELIST=OFF, +ACCURACY=${M_ACCURACY}, REPRES=GG, +DATE=${DAY1M1}/TO/${DAY2P1}, +TIME=00/12, +AC=N, +STEP=${MSTEP}, +TARGET="surf_${MSTEP}_ub" +EOF +} + + +myerror() + { + + echo $1 + echo $2 + echo $3 + echo ABORT! + + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + } + +# +# MAIN SCRIPT CONTINUES HERE +# +#read CONTROL file, process specifications +while read NAME PARA +do + +if [[ $NAME == 'M_TYPE' || $NAME == 'M_TIME' || $NAME == 'M_STEP' ]] ; then + eval "set -A $NAME $PARA" +else + eval "export $NAME='$PARA'" +fi +echo `echo $NAME`=$PARA + +done <${CONTROLFILE} + + +if [ -z "$DAY1" -o -z "$DAY2" ]; then + myerror 'DAY specification missing !' + exit 1 +fi + +#defaults +[ -z "$M_EXPVER" ] && M_EXPVER=1 +[ -z "$M_CLASS" ] && M_CLASS=OD +[ -z "$M_STREAM" ] && M_STREAM=OPER +[ -z "$M_NUMBER" ] && M_NUMBER=OFF +[ -z "$M_TYPE" ] && set -A M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +[ -z "$M_TIME" ] && set -A M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +[ -z "$M_STEP" ] && set -A M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +[ -z "$DTIME" ] && DTIME=6 +[ -z "$M_GRID" ] && M_GRID=1000 +[ -z "$M_LOWER" ] && M_LOWER=-90000 +[ -z "$M_LEFT" ] && M_LEFT=-179000 +[ -z "$M_UPPER" ] && M_UPPER=90000 +[ -z "$M_RIGHT" ] && M_RIGHT=180000 +[ -z "$M_LEVEL" ] && M_LEVEL=91 +[ -z "$M_LEVELIST" ] && M_LEVELIST=1/TO/$M_LEVEL +[ -z "$M_ADDPAR" ] && M_ADDPAR='' +[ -z "$M_RESOL" ] && M_RESOL=799 +[ -z "$M_GAUSS" ] && M_GAUSS=0 +[ -z "$M_SMOOTH" ] && M_SMOOTH=0 +[ -z "$M_OMEGA" ] && M_OMEGA=0 +[ -z "$M_OMEGADIFF" ] && M_OMEGADIFF=0 +[ -z "$M_ETA" ] && M_ETA=0 +[ -z "$M_ETADIFF" ] && M_ETADIFF=0 +[ -z "$M_ETAPAR" ] && M_ETAPAR=77 +[ -z "$M_DPDETA" ] && M_DPDETA=1 +[ -z "$M_ACCURACY" ] && M_ACCURACY=24 +[ -z "$EXEDIR" ] && EXEDIR=. +[ -z "$SOURCECODE" ] && SOURCECODE=ecgate:flex_extract_ecgate +[ -z "$GATEWAY" ] && GATEWAY='' +[ -z "$DESTINATION" ] && DESTINATION='' +[ -z "$PREFIX" ] && PREFIX=EN +[ -z "$COMPRESSION" ] && COMPRESSION=grid_simple +[ -z "$ECTRANS" ] && ECTRANS=0 +[ -z "$ECSTORAGE" ] && ECSTORAGE=1 +[ -z "$ECFSDIR" ] && ECFSDIR=ectmp: +[ -z "$MAILOPS" ] && MAILOPS=${USER} +[ -z "$MAILFAIL" ] && MAILFAIL=${USER} + + +#additional dates for flux retrievals (polynomial interpolation) +DAY1M1=`date2m1 ${DAY1}` +DAY2P1=`date2p1 ${DAY2}` + +#julian dates for time loops +JULDAY1=`juldate2 ${DAY1}` +JULDAY2=`juldate2 ${DAY2}` + +echo JULDATES $JULDAY1 $JULDAY2 + +#check consistency +if [ ${DAY1} -gt ${DAY2} ]; then + `myerror "ERROR: DAY1 > DAY2: ${DAY1}, ${DAY2}"` + exit 1 +fi + + +# determine number of gridpoints and whether grid is cyclic +ZYK=`expr \( $M_RIGHT + 360000 \) % 360000 - \( $M_LEFT + 360000 \) % 360000 + $M_GRID` + +if [ $M_RIGHT -le $M_LEFT ] ; then + if [ $M_RIGHT -le 0 ] ; then + M_RIGHT=$(($M_RIGHT+360000)) + else + M_LEFT=$(($M_LEFT-360000)) + fi +fi + +if [[ $ZYK -ne 0 ]] ; then + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED NON-CYCLIC" + exit 1 + fi +else + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED CYCLIC" + exit 1 + fi +fi + +if [ $((180000/$M_GRID-$M_RESOL)) -lt 0 ] ; then + + if [ ${M_SMOOTH} -eq 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SPECTRAL RESOLUTION ${M_RESOL} " "USE M_SMOOTH FOR SMOOTHING OR FINER OUTPUT GRID" +# exit 1 + else + if [ $((180000/$M_GRID-$M_SMOOTH)) -lt 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SMOOTHED SPECTRAL RESOLUTION ${M_SMOOTH} " + fi + fi + +fi + + +# convert lat/lon to MARS format (degrees) +if [[ $M_LEFT -lt 0 ]] ; then + LLLO=$(($M_LEFT / 1000)).$((($M_LEFT)*(-1) % 1000)) +else + LLLO=$(($M_LEFT / 1000)).$(($M_LEFT % 1000)) +fi +if [[ $M_LOWER -lt 0 ]] ; then + LLLA=$(($M_LOWER / 1000)).$(($M_LOWER*(-1) % 1000)) +else + LLLA=$(($M_LOWER / 1000)).$((($M_LOWER) % 1000)) +fi +if [[ $M_RIGHT -lt 0 ]] ; then + URLO=$(($M_RIGHT / 1000)).$((($M_RIGHT)*(-1) % 1000)) +else + URLO=$(($M_RIGHT / 1000)).$(($M_RIGHT % 1000)) +fi +if [[ $M_UPPER -lt 0 ]] ; then + URLA=$(($M_UPPER / 1000)).$((($M_UPPER)*(-1) % 1000)) +else + URLA=$(($M_UPPER / 1000)).$(($M_UPPER % 1000)) +fi + +M_AREA=${URLA}/${LLLO}/${LLLA}/${URLO} + +if [ $M_GAUSS -eq 1 ] ; then +# Gaussian grid detected + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=OFF + QG_GRID=OFF + if [ $M_RESOL -le 799 ] ; then + QG_GRID=$((($M_RESOL+1)/2)) + fi + D_GRID=${D_GRID}/${D_GRID} + +else + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=${G_GRID}/${G_GRID} + D_GRID=${D_GRID}/${D_GRID} +fi + +G_LEVELIST=1/to/${M_LEVEL} + + +#namelist +cat <<EOF >fort.4 +&NAMGEN + MAXL=${MAXL}, MAXB=${MAXB}, + MLEVEL=${M_LEVEL}, MLEVELIST="${M_LEVELIST}", + MNAUF=${M_RESOL},METAPAR=${M_ETAPAR}, + RLO0=${LLLO}, RLO1=${URLO}, RLA0=${LLLA}, RLA1=${URLA}, + MOMEGA=${M_OMEGA},MOMEGADIFF=${M_OMEGADIFF},MGAUSS=${M_GAUSS}, + MSMOOTH=${M_SMOOTH},META=${M_ETA},METADIFF=${M_ETADIFF}, + MDPDETA=${M_DPDETA} +/ +&NAMFX2 + NX=${MAXL}, NY=${MAXB}, + MAXTIME=400,JPOLY=4, + JHRF=${DTIME}, + RLO0=${LLLO}, RLA0=${LLLA}, DX=${D_GRID}, DY=${D_GRID} +/ +EOF + + +if [[ $OS_VERSION == aix ]] ; then + scp ecgb:${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.IBM FLXACC2 CONVERT2 CHECK +else + cp ${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.ecgb FLXACC2 CONVERT2 CHECK +fi + +if [ $? -ne 0 ]; then + + ls + myerror 'ERROR: FLXACC2 and CONVERT2 could not be compiled:' 'ABORT!' + exit 1 +else + echo 'compile worked' +fi + + +# +#MARS requests (field) +# +imax=6 +set -A PARLIST U/V T Q LNSP SD/MSL/TCC/10U/10V/2T/2D 129/172/160${M_ADDPAR} +set -A PARNAME 131/132 130 133 152 SURF OROLSM +set -A REPR SH SH GG SH GG GG +set -A UNIT 10 11 17 12 14 20 +set -A LTY ML ML ML ML SFC SFC +set -A GRID ${G_GRID} ${D_GRID} ${D_GRID} OFF ${D_GRID} ${D_GRID} +set -A LEVELIST ${M_LEVELIST} ${M_LEVELIST} ${M_LEVELIST} 1 1 1 + +set -A FIELD 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 + + +if [[ $M_OMEGA -eq 1 || $M_OMEGADIFF -eq 1 ]] ; then + M_OMEGA=1 + PARLIST[imax]=W + PARNAME[imax]=135 + REPR[imax]=SH + UNIT[imax]=19 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 1 || $M_ETADIFF -eq 1 ]] ; then + M_ETA=1 + PARLIST[imax]=77 + PARNAME[imax]=77 + REPR[imax]=SH + UNIT[imax]=21 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi + +if [[ $M_GAUSS -eq 2 ]] ; then + PARLIST[imax]=VO + PARNAME[imax]=138 + REPR[imax]=SH + UNIT[imax]=30 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 0 || $M_GAUSS -eq 1 || $M_ETADIFF -eq 1 ]] ; then + PARLIST[imax]=D + PARNAME[imax]=155 + REPR[imax]=SH + UNIT[imax]=13 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + LEVELIST[1]=${G_LEVELIST} # U/V needed on all levels for calculating ETA + imax=$(($imax+1)) +fi + +jmax=${#M_TYPE[*]} + +# M_TIME needs leading zeros while M_STEP must have leading zeros +# to be consistent with MARS file naming convention +# The following loop ensures this +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TIME[$j]} -lt 10 ]] ; then + M_TIME[$j]=0$((${M_TIME[$j]})) + fi + if [[ ${M_STEP[$j]} -lt 10 ]] ; then + M_STEP[$j]=$((${M_STEP[$j]})) + fi + + j=$(($j+1)) +done + +echo ${M_TIME[*]} +echo ${M_STEP[*]} + + +rm mars_flux 2>/dev/null +j=$DTIME +while [[ $j -lt 13 ]] ; do + marsflux ${M_TYPE[2]} ${FIELD[$j]} + j=$(($j+$DTIME)) +done +mars mars_flux | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + + +# +# FLXACC job +# + + +${EXEDIR}/FLXACC2 +if [ -f OROLSM ] ; then + rm OROLSM +fi + +# +# CONVERT job +# + +#loop over DATE and TIME for CONVERT/CHECK/ECtrans job + +IJULDAY=${JULDAY1} +while [ $IJULDAY -le $JULDAY2 ]; +do + +MDATE=`civildate2 ${IJULDAY}` +MDATEX=`echo ${MDATE} | cut -c3-8` + + +i=0 +rm marsjob 2>/dev/null + +#humidity on reduced Gaussian grid for initialization +#of spectral transformations +if [ ${M_GAUSS} -eq 1 ] ; then + NGRID=$(( ( ${M_RESOL} + 1 ) / 2 )) + + marsinst ${M_TYPE[0]} ${DAY1} 00 00 Q fort.18 ML ${QG_GRID} 1 'GAUSSIAN=REDUCED,' + +set -e +mars marsjob | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +rm marsjob + +fi + +set -e + +set -A TYPEKEY ${M_TYPE[0]} +j=$DTIME +kmax=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[j]} != ${TYPEKEY[0]} ]] ; then + if [[ $kmax == 1 ]] ; then + if [[ ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${TYPEKEY[1]} ${M_TYPE[j]} + kmax=2 + fi + else + if [[ $kmax == 0 ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${M_TYPE[j]} + kmax=1 + else + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[2]} ]] ; then + + echo ${TYPEKEY[0]} ${TYPEKEY[1]} ${TYPEKEY[2]} ${M_TYPE[j]} + myerror 'More than three different MARS TYPES not supported' + + exit 1 + fi + fi + fi + fi + fi + j=$(($j+$DTIME)) +done + +set -A GRIDKEY $D_GRID +mmax=1 +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${GRID[$i]} == 'OFF' && ${PARLIST[$i]} != LNSP ]] ; then + set -A GRIDKEY $D_GRID OFF + mmax=2 + fi + i=$(($i+1)) +done + +k=0 +kmax=$(($kmax+1)) +while [[ $k -lt $kmax ]] ; do +MMTIME='' +MMSTEP='' +TSUFF='' +SSUFF='' +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[$j]} == ${TYPEKEY[$k]} ]] ; then + if [[ `echo $MMTIME | grep ${M_TIME[$j]}` == '' ]] ; then + MMTIME=${MMTIME}$TSUFF${M_TIME[$j]} + TSUFF='/' + fi + if [[ `echo $MMSTEP | grep ${M_STEP[$j]}` == '' ]] ; then + MMSTEP=${MMSTEP}$SSUFF${M_STEP[$j]} + SSUFF='/' + fi + fi +j=$(($j+$DTIME)) +done + +m=0 +while [[ $m -lt $mmax ]] ; do +MMPAR='' +PSUFF='' +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${LTY[$i]} == ML && ${GRID[$i]} == ${GRIDKEY[m]} && ${PARLIST[$i]} != LNSP ]] ; then + if [[ `echo $MMPAR | grep ${PARLIST[$i]}` == '' ]] ; then + MMPAR=${MMPAR}$PSUFF${PARLIST[$i]} + PSUFF='/' + fi + fi +i=$(($i+1)) +done + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} $MMPAR "[param].[date].[time].[step]" ML ${GRIDKEY[$m]} ${LEVELIST[$m]} + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +m=$(($m+1)) +done + +# LNSP treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} LNSP "[param].[date].[time].[step]" ML OFF 1 + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# For some data classes, MARS adds GRIB table number to parameter number, +# e.g. for Temperature it is 130.128 instead of just 130 +# + set +e + TNR=`ls 131*${MDATE}.${M_TIME[00]}00.${M_STEP[00]} | awk -F . '{print $2}' - | grep -v ${MDATE}`. + set -e + if [[ $TNR != '.' ]] ; then + TNR=.$TNR + fi + +# SURF treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[4]} "SURF${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# OROLSM treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[5]} "OROLSM${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +k=$(($k+1)) +done + + + +j=0 +while [[ $j -lt $jmax ]] ; do + + +TIME=${FIELD[j]} +XTIME=${TIME}00 + +set +e +i=0 +while [[ $i -lt $imax ]] ; do + \rm fort.${UNIT[$i]} 2>/dev/null + if [[ ${PARLIST[$i]} == U/V ]] ; then + cat 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} > fort.${UNIT[$i]} + rm 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} + else + mv ${PARNAME[$i]}${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} fort.${UNIT[$i]} + fi + i=$(($i+1)) +done + +# flux data need special GRIB conversion +#if [ ${M_FORMAT} == GRIB2 ] ; then +# grib_set -w shortName!=lsp,shortName!=cp,shortName!=ewss,shortName!=nsss -s edition=2,productDefinitionTemplateNumber=8 flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 + +#else +# mv flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +#fi + +${EXEDIR}/CONVERT2 + +INFILE=${PREFIX}${MDATEX}${TIME} + +if [ -s fort.15 ]; then + cp fort.15 ${INFILE} + cat fort.14 >> ${INFILE} + cat flux${MDATE}${TIME} >> ${INFILE} + cat OROLSM >> ${INFILE} + cat fort.20 >> ${INFILE} +# +# Convert also surface fields to GRIB2 if needed +# +# Note: GRIB2 surface fields are incompatible with FLEXPART versions < 9.2 +# +# To enable additional compression +# set packingType="grid_jpeg"; +# this is rather time consuming. + +if [ ${M_FORMAT} == GRIB2 ] ; then + grib_set -s edition=2,productDefinitionTemplateNumber=8 $INFILE ${INFILE}_2 + mv ${INFILE}_2 ${INFILE} + + if [ ${COMPRESSION} != grid_simple ] ; then + +cat >rule.filter<<EOF +set packingType="${COMPRESSION}"; +write "[file]_2"; +EOF + grib_filter rule.filter ${INFILE} + mv ${INFILE}_2 ${INFILE} + fi +fi +ls -l ${INFILE} + + +else + myerror "ERROR: ENfile ${INFILE} missing!" "ABORT!" + exit 1 +fi + +#check ENxxx file & ECtrans to local gateway +if [ -s fort.25 ]; then + mv fort.25 OMEGA${MDATEX}${TIME} + ln -s OMEGA${MDATEX}${TIME} fort.25 +fi + + +\rm fort.15 2>/dev/null +ln -s ${INFILE} fort.15 + +[ -s CHECK.SUCCESS ] && rm CHECK.SUCCESS + +${EXEDIR}/CHECK + +#check fields +if [ -s CHECK.SUCCESS ]; then + SUCCESS=1 +else + myerror 'ERROR: check on ENfile failed:' ${INFILE} "ABORT!" + exit 1 +fi + + +#ECtrans +if [ $SUCCESS -eq 1 -a $ECTRANS -eq 1 ] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source $INFILE +fi + +if [[ $M_OMEGA -eq 1 && $SUCCESS -eq 1 && $ECTRANS -eq 1 ]] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source OMEGA${MDATEX}${TIME} +fi + +#ECFS +if [ $SUCCESS -eq 1 -a $ECSTORAGE -eq 1 ] ; then + ecp -o $INFILE $ECFSDIR +fi + +if [[ $SUCCESS -eq 1 && $ECSTORAGE -eq 1 && $M_OMEGA -eq 1 ]] ; then + ecp -o OMEGA${MDATEX}${TIME} $ECFSDIR +fi + +rm ${INFILE}_2 ${INFILE} fort.15 flux${MDATE}${TIME}* OMEGA${MDATEX}${TIME} fort.25 + +j=$(($j+$DTIME)) + +#done TIME +done + +(( IJULDAY = IJULDAY + 1 )) + +#done JULDAY +done + +#any warnings ? +[ $NRW -gt 0 ] && echo There were $NRW warnings ! + +#mail logfile (list MAILOPS) +for MUSER in $MAILOPS +do + +mailx -s ${JOBNAME} ${MUSER} <${LOG_FILE} +done + +# +# cleanup +# +cd ${SCRATCH} +echo $SCRATCHDIR not removed! +#\rm -fR $SCRATCHDIR + +exit 0 + diff --git a/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_GLOBALETA b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_GLOBALETA new file mode 100644 index 00000000..25201074 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_GLOBALETA @@ -0,0 +1,873 @@ +#!/bin/ksh + +# On demand script for retrieving input for FLEXPART trajectory model +# Version 6.0, September 2013 +# Maintainer Leopold Haimberger leopold.haimberger@univie.ac.at +# +#@ shell = /usr/bin/ksh + +# NOTE: If calculation on Gaussian grid are required below, it is +# recommended to send the job to the ECMWF HPC facility +# NOTE: On hpce the class should be ns or np +# NOTE: On ecgb it should be normal + + +#ON HPC (with loadleveler) +# start with ecaccess-job-submit -queueName c1a NAME_OF_THIS_FILE on gateway server +# start with llsubmit NAME_OF_THIS_FILE directly on machine + +#@ shell = /usr/bin/ksh +#@ class = ns +#@ resources = ConsumableCpus(1) ConsumableMemory(32000MB) +#@ job_name = flex_ecmwf +#@ output = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ error = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ environment = COPY_ALL +#@ queue + + +# ON ECGB: +# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE on gateway server +# start with sbatch NAME_OF_THIS_FILE directly on machine + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf +#SBATCH --output=flex_ecmwf.%j.out +#SBATCH --error=flex_ecmwf.%j.out +#SBATCH --mail-type=FAIL +#SBATCH --time=12:00:00 + +set -x + +JOBNAME=flex_ecmwf_${HOST} + +env +ulimit -a +export OMP_NUM_THREADS=1 +export MARS_MULTITARGET_STRICT_FORMAT=1 + +#export SCRATCH=$TEMP +export SCRATCHDIR=${SCRATCH}/${JOBNAME}_$$ +[ -z "$WSHOME" ] && WSHOME=$HOME + + +mkdir $SCRATCHDIR +cd $SCRATCHDIR + +LOG_FILE=$SCRATCHDIR/${JOBNAME}_$$ +exec 1>${LOG_FILE} + +CONTROLFILE=./CONTROL_ERA + +################################### +#BEGIN: modification of config file +################################### + +cat <<EOF >CONTROL_ERA +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 1000 +M_LEFT -179000 +M_LOWER -90000 +M_UPPER 90000 +M_RIGHT 180000 +M_LEVEL 137 +M_RESOL 159 +M_GAUSS 0 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 1 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EE +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF +# no changes below + +NRW=0 + +#ksh scripts for date manipulation +juldate2() + { + let jc=$1 + if (( ${#jc} < 8 )) + then + print "illegal date!" + exit 1 + fi + let y=`echo $jc | cut -c1-4` + let m1=`echo $jc | cut -c5` + let m2=`echo $jc | cut -c6` + m=$m1$m2 + let d1=`echo $jc | cut -c7` + let d2=`echo $jc | cut -c8` + d=$d1$d2 + let jd=367*y-7*(y+(m+9)/12)/4+275*m/9+d+1721014 + let jd=jd+15-3*((y+(m-9)/7)/100+1)/4 + print $jd + } + +civildate2() + { + let jd=$1 + if (( jd < 1721060 )) + then + print "Julian date not in AD." + exit 1 + fi + let k=jd+68569 + let n=4*k/146097 + let k=k-\(146097*n+3\)/4 + let y=4000*(k+1)/1461001 + let k=k-1461*y/4+31 + let m=80*k/2447 + let d=k-\(2447*m\)/80 + let k=m/11 + let m=m+2-12*k + let y=100*(n-49)+y+k + [ $m -le 9 ] && m=0$m + [ $d -le 9 ] && d=0$d + print $y$m$d + } + +date2m1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-1 + civildate2 $j0 + } + +date2p1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1+1 + civildate2 $j0 + } + + +marsinst() +{ +MTYPE="${1}" +MDAY="${2}" +MTIME="${3}" +MSTEP="${4}" +MPAR="${5}" +MFN=$6 +MLTY=$7 +MGRID="${8}" +MLEV="${9}" + +RED=0 +#if [[ ${MTYPE} != 'AN' ]] ; then + MPAR2=`echo ${MPAR} | sed s,160/,,` + MPAR2=`echo ${MPAR2} | sed s,27/,,` + MPAR2=`echo ${MPAR2} | sed s,28/,,` + MPAR2=`echo ${MPAR2} | sed s,173/,,` + if [[ ${MPAR2} != ${MPAR} ]] ; then + MPAR=${MPAR2} + RED=1 + fi +#fi + +MAREA=${M_AREA} +if [[ ${10} == 'GAUSSIAN=REDUCED,' ]] ; then + MAREA=G +fi + +if [[ -f ${MFN} ]] ; then + rm ${MFN} +fi + +cat <<EOF >> marsjob +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=${MPAR}, +RESOL=${M_RESOL}, +AREA=${MAREA}, +GRID=${MGRID}, +LEVTYPE=${MLTY}, +LEVELIST=${MLEV}, +ACCURACY=${M_ACCURACY}, +DATE=${MDAY}, +TIME=${MTIME}, +STEP=${MSTEP},${10} +TARGET="${MFN}" +EOF + +if [[ ! -f 'OROLSM' && $RED -eq 1 ]] ; then + +cat <<EOF >> marsjob +RETRIEVE,TYPE=AN,TIME=0,STEP=0,CLASS=OD, + PARAM=160/27/28/173, + TARGET="OROLSM" +EOF +fi + +} + +marsflux() +{ +MTYPE="${1}" +MSTEP="${2}" + +cat <<EOF >>mars_flux +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=LSP/CP/SSHF/EWSS/NSSS/SSR, +AREA=${M_AREA}, +GRID=${D_GRID}, +LEVTYPE=SFC, +LEVELIST=OFF, +ACCURACY=${M_ACCURACY}, REPRES=GG, +DATE=${DAY1M1}/TO/${DAY2P1}, +TIME=00/12, +AC=N, +STEP=${MSTEP}, +TARGET="surf_${MSTEP}_ub" +EOF +} + + +myerror() + { + + echo $1 + echo $2 + echo $3 + echo ABORT! + + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + } + +# +# MAIN SCRIPT CONTINUES HERE +# +#read CONTROL file, process specifications +while read NAME PARA +do + +if [[ $NAME == 'M_TYPE' || $NAME == 'M_TIME' || $NAME == 'M_STEP' ]] ; then + eval "set -A $NAME $PARA" +else + eval "export $NAME='$PARA'" +fi +echo `echo $NAME`=$PARA + +done <${CONTROLFILE} + + +if [ -z "$DAY1" -o -z "$DAY2" ]; then + myerror 'DAY specification missing !' + exit 1 +fi + +#defaults +[ -z "$M_EXPVER" ] && M_EXPVER=1 +[ -z "$M_CLASS" ] && M_CLASS=OD +[ -z "$M_STREAM" ] && M_STREAM=OPER +[ -z "$M_NUMBER" ] && M_NUMBER=OFF +[ -z "$M_TYPE" ] && set -A M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +[ -z "$M_TIME" ] && set -A M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +[ -z "$M_STEP" ] && set -A M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +[ -z "$DTIME" ] && DTIME=6 +[ -z "$M_GRID" ] && M_GRID=1000 +[ -z "$M_LOWER" ] && M_LOWER=-90000 +[ -z "$M_LEFT" ] && M_LEFT=-179000 +[ -z "$M_UPPER" ] && M_UPPER=90000 +[ -z "$M_RIGHT" ] && M_RIGHT=180000 +[ -z "$M_LEVEL" ] && M_LEVEL=91 +[ -z "$M_LEVELIST" ] && M_LEVELIST=1/TO/$M_LEVEL +[ -z "$M_ADDPAR" ] && M_ADDPAR='' +[ -z "$M_RESOL" ] && M_RESOL=799 +[ -z "$M_GAUSS" ] && M_GAUSS=0 +[ -z "$M_SMOOTH" ] && M_SMOOTH=0 +[ -z "$M_OMEGA" ] && M_OMEGA=0 +[ -z "$M_OMEGADIFF" ] && M_OMEGADIFF=0 +[ -z "$M_ETA" ] && M_ETA=0 +[ -z "$M_ETADIFF" ] && M_ETADIFF=0 +[ -z "$M_ETAPAR" ] && M_ETAPAR=77 +[ -z "$M_DPDETA" ] && M_DPDETA=1 +[ -z "$M_ACCURACY" ] && M_ACCURACY=24 +[ -z "$EXEDIR" ] && EXEDIR=. +[ -z "$SOURCECODE" ] && SOURCECODE=ecgate:flex_extract_ecgate +[ -z "$GATEWAY" ] && GATEWAY='' +[ -z "$DESTINATION" ] && DESTINATION='' +[ -z "$PREFIX" ] && PREFIX=EN +[ -z "$COMPRESSION" ] && COMPRESSION=grid_simple +[ -z "$ECTRANS" ] && ECTRANS=0 +[ -z "$ECSTORAGE" ] && ECSTORAGE=1 +[ -z "$ECFSDIR" ] && ECFSDIR=ectmp: +[ -z "$MAILOPS" ] && MAILOPS=${USER} +[ -z "$MAILFAIL" ] && MAILFAIL=${USER} + + +#additional dates for flux retrievals (polynomial interpolation) +DAY1M1=`date2m1 ${DAY1}` +DAY2P1=`date2p1 ${DAY2}` + +#julian dates for time loops +JULDAY1=`juldate2 ${DAY1}` +JULDAY2=`juldate2 ${DAY2}` + +echo JULDATES $JULDAY1 $JULDAY2 + +#check consistency +if [ ${DAY1} -gt ${DAY2} ]; then + `myerror "ERROR: DAY1 > DAY2: ${DAY1}, ${DAY2}"` + exit 1 +fi + + +# determine number of gridpoints and whether grid is cyclic +ZYK=`expr \( $M_RIGHT + 360000 \) % 360000 - \( $M_LEFT + 360000 \) % 360000 + $M_GRID` + +if [ $M_RIGHT -le $M_LEFT ] ; then + if [ $M_RIGHT -le 0 ] ; then + M_RIGHT=$(($M_RIGHT+360000)) + else + M_LEFT=$(($M_LEFT-360000)) + fi +fi + +if [[ $ZYK -ne 0 ]] ; then + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED NON-CYCLIC" + exit 1 + fi +else + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED CYCLIC" + exit 1 + fi +fi + +if [ $((180000/$M_GRID-$M_RESOL)) -lt 0 ] ; then + + if [ ${M_SMOOTH} -eq 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SPECTRAL RESOLUTION ${M_RESOL} " "USE M_SMOOTH FOR SMOOTHING OR FINER OUTPUT GRID" +# exit 1 + else + if [ $((180000/$M_GRID-$M_SMOOTH)) -lt 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SMOOTHED SPECTRAL RESOLUTION ${M_SMOOTH} " + fi + fi + +fi + + +# convert lat/lon to MARS format (degrees) +if [[ $M_LEFT -lt 0 ]] ; then + LLLO=$(($M_LEFT / 1000)).$((($M_LEFT)*(-1) % 1000)) +else + LLLO=$(($M_LEFT / 1000)).$(($M_LEFT % 1000)) +fi +if [[ $M_LOWER -lt 0 ]] ; then + LLLA=$(($M_LOWER / 1000)).$(($M_LOWER*(-1) % 1000)) +else + LLLA=$(($M_LOWER / 1000)).$((($M_LOWER) % 1000)) +fi +if [[ $M_RIGHT -lt 0 ]] ; then + URLO=$(($M_RIGHT / 1000)).$((($M_RIGHT)*(-1) % 1000)) +else + URLO=$(($M_RIGHT / 1000)).$(($M_RIGHT % 1000)) +fi +if [[ $M_UPPER -lt 0 ]] ; then + URLA=$(($M_UPPER / 1000)).$((($M_UPPER)*(-1) % 1000)) +else + URLA=$(($M_UPPER / 1000)).$(($M_UPPER % 1000)) +fi + +M_AREA=${URLA}/${LLLO}/${LLLA}/${URLO} + +if [ $M_GAUSS -eq 1 ] ; then +# Gaussian grid detected + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=OFF + QG_GRID=OFF + if [ $M_RESOL -le 799 ] ; then + QG_GRID=$((($M_RESOL+1)/2)) + fi + D_GRID=${D_GRID}/${D_GRID} + +else + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=${G_GRID}/${G_GRID} + D_GRID=${D_GRID}/${D_GRID} +fi + +G_LEVELIST=1/to/${M_LEVEL} + + +#namelist +cat <<EOF >fort.4 +&NAMGEN + MAXL=${MAXL}, MAXB=${MAXB}, + MLEVEL=${M_LEVEL}, MLEVELIST="${M_LEVELIST}", + MNAUF=${M_RESOL},METAPAR=${M_ETAPAR}, + RLO0=${LLLO}, RLO1=${URLO}, RLA0=${LLLA}, RLA1=${URLA}, + MOMEGA=${M_OMEGA},MOMEGADIFF=${M_OMEGADIFF},MGAUSS=${M_GAUSS}, + MSMOOTH=${M_SMOOTH},META=${M_ETA},METADIFF=${M_ETADIFF}, + MDPDETA=${M_DPDETA} +/ +&NAMFX2 + NX=${MAXL}, NY=${MAXB}, + MAXTIME=400,JPOLY=4, + JHRF=${DTIME}, + RLO0=${LLLO}, RLA0=${LLLA}, DX=${D_GRID}, DY=${D_GRID} +/ +EOF + + +if [[ $OS_VERSION == aix ]] ; then + scp ecgb:${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.IBM FLXACC2 CONVERT2 CHECK +else + cp ${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.ecgb FLXACC2 CONVERT2 CHECK +fi + +if [ $? -ne 0 ]; then + + ls + myerror 'ERROR: FLXACC2 and CONVERT2 could not be compiled:' 'ABORT!' + exit 1 +else + echo 'compile worked' +fi + + +# +#MARS requests (field) +# +imax=6 +set -A PARLIST U/V T Q LNSP SD/MSL/TCC/10U/10V/2T/2D 129/172/160${M_ADDPAR} +set -A PARNAME 131/132 130 133 152 SURF OROLSM +set -A REPR SH SH GG SH GG GG +set -A UNIT 10 11 17 12 14 20 +set -A LTY ML ML ML ML SFC SFC +set -A GRID ${G_GRID} ${D_GRID} ${D_GRID} OFF ${D_GRID} ${D_GRID} +set -A LEVELIST ${M_LEVELIST} ${M_LEVELIST} ${M_LEVELIST} 1 1 1 + +set -A FIELD 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 + + +if [[ $M_OMEGA -eq 1 || $M_OMEGADIFF -eq 1 ]] ; then + M_OMEGA=1 + PARLIST[imax]=W + PARNAME[imax]=135 + REPR[imax]=SH + UNIT[imax]=19 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 1 || $M_ETADIFF -eq 1 ]] ; then + M_ETA=1 + PARLIST[imax]=77 + PARNAME[imax]=77 + REPR[imax]=SH + UNIT[imax]=21 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi + +if [[ $M_GAUSS -eq 2 ]] ; then + PARLIST[imax]=VO + PARNAME[imax]=138 + REPR[imax]=SH + UNIT[imax]=30 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 0 || $M_GAUSS -eq 1 || $M_ETADIFF -eq 1 ]] ; then + PARLIST[imax]=D + PARNAME[imax]=155 + REPR[imax]=SH + UNIT[imax]=13 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + LEVELIST[1]=${G_LEVELIST} # U/V needed on all levels for calculating ETA + imax=$(($imax+1)) +fi + +jmax=${#M_TYPE[*]} + +# M_TIME needs leading zeros while M_STEP must have leading zeros +# to be consistent with MARS file naming convention +# The following loop ensures this +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TIME[$j]} -lt 10 ]] ; then + M_TIME[$j]=0$((${M_TIME[$j]})) + fi + if [[ ${M_STEP[$j]} -lt 10 ]] ; then + M_STEP[$j]=$((${M_STEP[$j]})) + fi + + j=$(($j+1)) +done + +echo ${M_TIME[*]} +echo ${M_STEP[*]} + + +rm mars_flux 2>/dev/null +j=$DTIME +while [[ $j -lt 13 ]] ; do + marsflux ${M_TYPE[2]} ${FIELD[$j]} + j=$(($j+$DTIME)) +done +mars mars_flux | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + + +# +# FLXACC job +# + + +${EXEDIR}/FLXACC2 +if [ -f OROLSM ] ; then + rm OROLSM +fi + +# +# CONVERT job +# + +#loop over DATE and TIME for CONVERT/CHECK/ECtrans job + +IJULDAY=${JULDAY1} +while [ $IJULDAY -le $JULDAY2 ]; +do + +MDATE=`civildate2 ${IJULDAY}` +MDATEX=`echo ${MDATE} | cut -c3-8` + + +i=0 +rm marsjob 2>/dev/null + +#humidity on reduced Gaussian grid for initialization +#of spectral transformations +if [ ${M_GAUSS} -eq 1 ] ; then + NGRID=$(( ( ${M_RESOL} + 1 ) / 2 )) + + marsinst ${M_TYPE[0]} ${DAY1} 00 00 Q fort.18 ML ${QG_GRID} 1 'GAUSSIAN=REDUCED,' + +set -e +mars marsjob | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +rm marsjob + +fi + +set -e + +set -A TYPEKEY ${M_TYPE[0]} +j=$DTIME +kmax=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[j]} != ${TYPEKEY[0]} ]] ; then + if [[ $kmax == 1 ]] ; then + if [[ ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${TYPEKEY[1]} ${M_TYPE[j]} + kmax=2 + fi + else + if [[ $kmax == 0 ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${M_TYPE[j]} + kmax=1 + else + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[2]} ]] ; then + + echo ${TYPEKEY[0]} ${TYPEKEY[1]} ${TYPEKEY[2]} ${M_TYPE[j]} + myerror 'More than three different MARS TYPES not supported' + + exit 1 + fi + fi + fi + fi + fi + j=$(($j+$DTIME)) +done + +set -A GRIDKEY $D_GRID +mmax=1 +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${GRID[$i]} == 'OFF' && ${PARLIST[$i]} != LNSP ]] ; then + set -A GRIDKEY $D_GRID OFF + mmax=2 + fi + i=$(($i+1)) +done + +k=0 +kmax=$(($kmax+1)) +while [[ $k -lt $kmax ]] ; do +MMTIME='' +MMSTEP='' +TSUFF='' +SSUFF='' +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[$j]} == ${TYPEKEY[$k]} ]] ; then + if [[ `echo $MMTIME | grep ${M_TIME[$j]}` == '' ]] ; then + MMTIME=${MMTIME}$TSUFF${M_TIME[$j]} + TSUFF='/' + fi + if [[ `echo $MMSTEP | grep ${M_STEP[$j]}` == '' ]] ; then + MMSTEP=${MMSTEP}$SSUFF${M_STEP[$j]} + SSUFF='/' + fi + fi +j=$(($j+$DTIME)) +done + +m=0 +while [[ $m -lt $mmax ]] ; do +MMPAR='' +PSUFF='' +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${LTY[$i]} == ML && ${GRID[$i]} == ${GRIDKEY[m]} && ${PARLIST[$i]} != LNSP ]] ; then + if [[ `echo $MMPAR | grep ${PARLIST[$i]}` == '' ]] ; then + MMPAR=${MMPAR}$PSUFF${PARLIST[$i]} + PSUFF='/' + fi + fi +i=$(($i+1)) +done + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} $MMPAR "[param].[date].[time].[step]" ML ${GRIDKEY[$m]} ${LEVELIST[$m]} + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +m=$(($m+1)) +done + +# LNSP treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} LNSP "[param].[date].[time].[step]" ML OFF 1 + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# For some data classes, MARS adds GRIB table number to parameter number, +# e.g. for Temperature it is 130.128 instead of just 130 +# + set +e + TNR=`ls 131*${MDATE}.${M_TIME[00]}00.${M_STEP[00]} | awk -F . '{print $2}' - | grep -v ${MDATE}`. + set -e + if [[ $TNR != '.' ]] ; then + TNR=.$TNR + fi + +# SURF treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[4]} "SURF${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# OROLSM treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[5]} "OROLSM${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +k=$(($k+1)) +done + + + +j=0 +while [[ $j -lt $jmax ]] ; do + + +TIME=${FIELD[j]} +XTIME=${TIME}00 + +set +e +i=0 +while [[ $i -lt $imax ]] ; do + \rm fort.${UNIT[$i]} 2>/dev/null + if [[ ${PARLIST[$i]} == U/V ]] ; then + cat 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} > fort.${UNIT[$i]} + rm 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} + else + mv ${PARNAME[$i]}${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} fort.${UNIT[$i]} + fi + i=$(($i+1)) +done + +# flux data need special GRIB conversion +#if [ ${M_FORMAT} == GRIB2 ] ; then +# grib_set -w shortName!=lsp,shortName!=cp,shortName!=ewss,shortName!=nsss -s edition=2,productDefinitionTemplateNumber=8 flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 + +#else +# mv flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +#fi + +${EXEDIR}/CONVERT2 + +INFILE=${PREFIX}${MDATEX}${TIME} + +if [ -s fort.15 ]; then + cp fort.15 ${INFILE} + cat fort.14 >> ${INFILE} + cat flux${MDATE}${TIME} >> ${INFILE} + cat OROLSM >> ${INFILE} + cat fort.20 >> ${INFILE} +# +# Convert also surface fields to GRIB2 if needed +# +# Note: GRIB2 surface fields are incompatible with FLEXPART versions < 9.2 +# +# To enable additional compression +# set packingType="grid_jpeg"; +# this is rather time consuming. + +if [ ${M_FORMAT} == GRIB2 ] ; then + grib_set -s edition=2,productDefinitionTemplateNumber=8 $INFILE ${INFILE}_2 + mv ${INFILE}_2 ${INFILE} + + if [ ${COMPRESSION} != grid_simple ] ; then + +cat >rule.filter<<EOF +set packingType="${COMPRESSION}"; +write "[file]_2"; +EOF + grib_filter rule.filter ${INFILE} + mv ${INFILE}_2 ${INFILE} + fi +fi +ls -l ${INFILE} + + +else + myerror "ERROR: ENfile ${INFILE} missing!" "ABORT!" + exit 1 +fi + +#check ENxxx file & ECtrans to local gateway +if [ -s fort.25 ]; then + mv fort.25 OMEGA${MDATEX}${TIME} + ln -s OMEGA${MDATEX}${TIME} fort.25 +fi + + +\rm fort.15 2>/dev/null +ln -s ${INFILE} fort.15 + +[ -s CHECK.SUCCESS ] && rm CHECK.SUCCESS + +${EXEDIR}/CHECK + +#check fields +if [ -s CHECK.SUCCESS ]; then + SUCCESS=1 +else + myerror 'ERROR: check on ENfile failed:' ${INFILE} "ABORT!" + exit 1 +fi + + +#ECtrans +if [ $SUCCESS -eq 1 -a $ECTRANS -eq 1 ] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source $INFILE +fi + +if [[ $M_OMEGA -eq 1 && $SUCCESS -eq 1 && $ECTRANS -eq 1 ]] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source OMEGA${MDATEX}${TIME} +fi + +#ECFS +if [ $SUCCESS -eq 1 -a $ECSTORAGE -eq 1 ] ; then + ecp -o $INFILE $ECFSDIR +fi + +if [[ $SUCCESS -eq 1 && $ECSTORAGE -eq 1 && $M_OMEGA -eq 1 ]] ; then + ecp -o OMEGA${MDATEX}${TIME} $ECFSDIR +fi + +rm ${INFILE}_2 ${INFILE} fort.15 flux${MDATE}${TIME}* OMEGA${MDATEX}${TIME} fort.25 + +j=$(($j+$DTIME)) + +#done TIME +done + +(( IJULDAY = IJULDAY + 1 )) + +#done JULDAY +done + +#any warnings ? +[ $NRW -gt 0 ] && echo There were $NRW warnings ! + +#mail logfile (list MAILOPS) +for MUSER in $MAILOPS +do + +mailx -s ${JOBNAME} ${MUSER} <${LOG_FILE} +done + +# +# cleanup +# +cd ${SCRATCH} +echo $SCRATCHDIR not removed! +#\rm -fR $SCRATCHDIR + +exit 0 + diff --git a/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_GLOBALGAUSS b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_GLOBALGAUSS new file mode 100644 index 00000000..016c25c2 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_GLOBALGAUSS @@ -0,0 +1,873 @@ +#!/bin/ksh + +# On demand script for retrieving input for FLEXPART trajectory model +# Version 6.0, September 2013 +# Maintainer Leopold Haimberger leopold.haimberger@univie.ac.at +# +#@ shell = /usr/bin/ksh + +# NOTE: If calculation on Gaussian grid are required below, it is +# recommended to send the job to the ECMWF HPC facility +# NOTE: On hpce the class should be ns or np +# NOTE: On ecgb it should be normal + + +#ON HPC (with loadleveler) +# start with ecaccess-job-submit -queueName c1a NAME_OF_THIS_FILE on gateway server +# start with llsubmit NAME_OF_THIS_FILE directly on machine + +#@ shell = /usr/bin/ksh +#@ class = ns +#@ resources = ConsumableCpus(1) ConsumableMemory(32000MB) +#@ job_name = flex_ecmwf +#@ output = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ error = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ environment = COPY_ALL +#@ queue + + +# ON ECGB: +# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE on gateway server +# start with sbatch NAME_OF_THIS_FILE directly on machine + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf +#SBATCH --output=flex_ecmwf.%j.out +#SBATCH --error=flex_ecmwf.%j.out +#SBATCH --mail-type=FAIL +#SBATCH --time=12:00:00 + +set -x + +JOBNAME=flex_ecmwf_${HOST} + +env +ulimit -a +export OMP_NUM_THREADS=1 +export MARS_MULTITARGET_STRICT_FORMAT=1 + +#export SCRATCH=$TEMP +export SCRATCHDIR=${SCRATCH}/${JOBNAME}_$$ +[ -z "$WSHOME" ] && WSHOME=$HOME + + +mkdir $SCRATCHDIR +cd $SCRATCHDIR + +LOG_FILE=$SCRATCHDIR/${JOBNAME}_$$ +exec 1>${LOG_FILE} + +CONTROLFILE=./CONTROL_ERA + +################################### +#BEGIN: modification of config file +################################### + +cat <<EOF >CONTROL_ERA +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 1000 +M_LEFT -179000 +M_LOWER -90000 +M_UPPER 90000 +M_RIGHT 180000 +M_LEVEL 137 +M_RESOL 159 +M_GAUSS 1 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 0 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EG +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF +# no changes below + +NRW=0 + +#ksh scripts for date manipulation +juldate2() + { + let jc=$1 + if (( ${#jc} < 8 )) + then + print "illegal date!" + exit 1 + fi + let y=`echo $jc | cut -c1-4` + let m1=`echo $jc | cut -c5` + let m2=`echo $jc | cut -c6` + m=$m1$m2 + let d1=`echo $jc | cut -c7` + let d2=`echo $jc | cut -c8` + d=$d1$d2 + let jd=367*y-7*(y+(m+9)/12)/4+275*m/9+d+1721014 + let jd=jd+15-3*((y+(m-9)/7)/100+1)/4 + print $jd + } + +civildate2() + { + let jd=$1 + if (( jd < 1721060 )) + then + print "Julian date not in AD." + exit 1 + fi + let k=jd+68569 + let n=4*k/146097 + let k=k-\(146097*n+3\)/4 + let y=4000*(k+1)/1461001 + let k=k-1461*y/4+31 + let m=80*k/2447 + let d=k-\(2447*m\)/80 + let k=m/11 + let m=m+2-12*k + let y=100*(n-49)+y+k + [ $m -le 9 ] && m=0$m + [ $d -le 9 ] && d=0$d + print $y$m$d + } + +date2m1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-1 + civildate2 $j0 + } + +date2p1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1+1 + civildate2 $j0 + } + + +marsinst() +{ +MTYPE="${1}" +MDAY="${2}" +MTIME="${3}" +MSTEP="${4}" +MPAR="${5}" +MFN=$6 +MLTY=$7 +MGRID="${8}" +MLEV="${9}" + +RED=0 +#if [[ ${MTYPE} != 'AN' ]] ; then + MPAR2=`echo ${MPAR} | sed s,160/,,` + MPAR2=`echo ${MPAR2} | sed s,27/,,` + MPAR2=`echo ${MPAR2} | sed s,28/,,` + MPAR2=`echo ${MPAR2} | sed s,173/,,` + if [[ ${MPAR2} != ${MPAR} ]] ; then + MPAR=${MPAR2} + RED=1 + fi +#fi + +MAREA=${M_AREA} +if [[ ${10} == 'GAUSSIAN=REDUCED,' ]] ; then + MAREA=G +fi + +if [[ -f ${MFN} ]] ; then + rm ${MFN} +fi + +cat <<EOF >> marsjob +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=${MPAR}, +RESOL=${M_RESOL}, +AREA=${MAREA}, +GRID=${MGRID}, +LEVTYPE=${MLTY}, +LEVELIST=${MLEV}, +ACCURACY=${M_ACCURACY}, +DATE=${MDAY}, +TIME=${MTIME}, +STEP=${MSTEP},${10} +TARGET="${MFN}" +EOF + +if [[ ! -f 'OROLSM' && $RED -eq 1 ]] ; then + +cat <<EOF >> marsjob +RETRIEVE,TYPE=AN,TIME=0,STEP=0,CLASS=OD, + PARAM=160/27/28/173, + TARGET="OROLSM" +EOF +fi + +} + +marsflux() +{ +MTYPE="${1}" +MSTEP="${2}" + +cat <<EOF >>mars_flux +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=LSP/CP/SSHF/EWSS/NSSS/SSR, +AREA=${M_AREA}, +GRID=${D_GRID}, +LEVTYPE=SFC, +LEVELIST=OFF, +ACCURACY=${M_ACCURACY}, REPRES=GG, +DATE=${DAY1M1}/TO/${DAY2P1}, +TIME=00/12, +AC=N, +STEP=${MSTEP}, +TARGET="surf_${MSTEP}_ub" +EOF +} + + +myerror() + { + + echo $1 + echo $2 + echo $3 + echo ABORT! + + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + } + +# +# MAIN SCRIPT CONTINUES HERE +# +#read CONTROL file, process specifications +while read NAME PARA +do + +if [[ $NAME == 'M_TYPE' || $NAME == 'M_TIME' || $NAME == 'M_STEP' ]] ; then + eval "set -A $NAME $PARA" +else + eval "export $NAME='$PARA'" +fi +echo `echo $NAME`=$PARA + +done <${CONTROLFILE} + + +if [ -z "$DAY1" -o -z "$DAY2" ]; then + myerror 'DAY specification missing !' + exit 1 +fi + +#defaults +[ -z "$M_EXPVER" ] && M_EXPVER=1 +[ -z "$M_CLASS" ] && M_CLASS=OD +[ -z "$M_STREAM" ] && M_STREAM=OPER +[ -z "$M_NUMBER" ] && M_NUMBER=OFF +[ -z "$M_TYPE" ] && set -A M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +[ -z "$M_TIME" ] && set -A M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +[ -z "$M_STEP" ] && set -A M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +[ -z "$DTIME" ] && DTIME=6 +[ -z "$M_GRID" ] && M_GRID=1000 +[ -z "$M_LOWER" ] && M_LOWER=-90000 +[ -z "$M_LEFT" ] && M_LEFT=-179000 +[ -z "$M_UPPER" ] && M_UPPER=90000 +[ -z "$M_RIGHT" ] && M_RIGHT=180000 +[ -z "$M_LEVEL" ] && M_LEVEL=91 +[ -z "$M_LEVELIST" ] && M_LEVELIST=1/TO/$M_LEVEL +[ -z "$M_ADDPAR" ] && M_ADDPAR='' +[ -z "$M_RESOL" ] && M_RESOL=799 +[ -z "$M_GAUSS" ] && M_GAUSS=0 +[ -z "$M_SMOOTH" ] && M_SMOOTH=0 +[ -z "$M_OMEGA" ] && M_OMEGA=0 +[ -z "$M_OMEGADIFF" ] && M_OMEGADIFF=0 +[ -z "$M_ETA" ] && M_ETA=0 +[ -z "$M_ETADIFF" ] && M_ETADIFF=0 +[ -z "$M_ETAPAR" ] && M_ETAPAR=77 +[ -z "$M_DPDETA" ] && M_DPDETA=1 +[ -z "$M_ACCURACY" ] && M_ACCURACY=24 +[ -z "$EXEDIR" ] && EXEDIR=. +[ -z "$SOURCECODE" ] && SOURCECODE=ecgate:flex_extract_ecgate +[ -z "$GATEWAY" ] && GATEWAY='' +[ -z "$DESTINATION" ] && DESTINATION='' +[ -z "$PREFIX" ] && PREFIX=EN +[ -z "$COMPRESSION" ] && COMPRESSION=grid_simple +[ -z "$ECTRANS" ] && ECTRANS=0 +[ -z "$ECSTORAGE" ] && ECSTORAGE=1 +[ -z "$ECFSDIR" ] && ECFSDIR=ectmp: +[ -z "$MAILOPS" ] && MAILOPS=${USER} +[ -z "$MAILFAIL" ] && MAILFAIL=${USER} + + +#additional dates for flux retrievals (polynomial interpolation) +DAY1M1=`date2m1 ${DAY1}` +DAY2P1=`date2p1 ${DAY2}` + +#julian dates for time loops +JULDAY1=`juldate2 ${DAY1}` +JULDAY2=`juldate2 ${DAY2}` + +echo JULDATES $JULDAY1 $JULDAY2 + +#check consistency +if [ ${DAY1} -gt ${DAY2} ]; then + `myerror "ERROR: DAY1 > DAY2: ${DAY1}, ${DAY2}"` + exit 1 +fi + + +# determine number of gridpoints and whether grid is cyclic +ZYK=`expr \( $M_RIGHT + 360000 \) % 360000 - \( $M_LEFT + 360000 \) % 360000 + $M_GRID` + +if [ $M_RIGHT -le $M_LEFT ] ; then + if [ $M_RIGHT -le 0 ] ; then + M_RIGHT=$(($M_RIGHT+360000)) + else + M_LEFT=$(($M_LEFT-360000)) + fi +fi + +if [[ $ZYK -ne 0 ]] ; then + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED NON-CYCLIC" + exit 1 + fi +else + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED CYCLIC" + exit 1 + fi +fi + +if [ $((180000/$M_GRID-$M_RESOL)) -lt 0 ] ; then + + if [ ${M_SMOOTH} -eq 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SPECTRAL RESOLUTION ${M_RESOL} " "USE M_SMOOTH FOR SMOOTHING OR FINER OUTPUT GRID" +# exit 1 + else + if [ $((180000/$M_GRID-$M_SMOOTH)) -lt 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SMOOTHED SPECTRAL RESOLUTION ${M_SMOOTH} " + fi + fi + +fi + + +# convert lat/lon to MARS format (degrees) +if [[ $M_LEFT -lt 0 ]] ; then + LLLO=$(($M_LEFT / 1000)).$((($M_LEFT)*(-1) % 1000)) +else + LLLO=$(($M_LEFT / 1000)).$(($M_LEFT % 1000)) +fi +if [[ $M_LOWER -lt 0 ]] ; then + LLLA=$(($M_LOWER / 1000)).$(($M_LOWER*(-1) % 1000)) +else + LLLA=$(($M_LOWER / 1000)).$((($M_LOWER) % 1000)) +fi +if [[ $M_RIGHT -lt 0 ]] ; then + URLO=$(($M_RIGHT / 1000)).$((($M_RIGHT)*(-1) % 1000)) +else + URLO=$(($M_RIGHT / 1000)).$(($M_RIGHT % 1000)) +fi +if [[ $M_UPPER -lt 0 ]] ; then + URLA=$(($M_UPPER / 1000)).$((($M_UPPER)*(-1) % 1000)) +else + URLA=$(($M_UPPER / 1000)).$(($M_UPPER % 1000)) +fi + +M_AREA=${URLA}/${LLLO}/${LLLA}/${URLO} + +if [ $M_GAUSS -eq 1 ] ; then +# Gaussian grid detected + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=OFF + QG_GRID=OFF + if [ $M_RESOL -le 799 ] ; then + QG_GRID=$((($M_RESOL+1)/2)) + fi + D_GRID=${D_GRID}/${D_GRID} + +else + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=${G_GRID}/${G_GRID} + D_GRID=${D_GRID}/${D_GRID} +fi + +G_LEVELIST=1/to/${M_LEVEL} + + +#namelist +cat <<EOF >fort.4 +&NAMGEN + MAXL=${MAXL}, MAXB=${MAXB}, + MLEVEL=${M_LEVEL}, MLEVELIST="${M_LEVELIST}", + MNAUF=${M_RESOL},METAPAR=${M_ETAPAR}, + RLO0=${LLLO}, RLO1=${URLO}, RLA0=${LLLA}, RLA1=${URLA}, + MOMEGA=${M_OMEGA},MOMEGADIFF=${M_OMEGADIFF},MGAUSS=${M_GAUSS}, + MSMOOTH=${M_SMOOTH},META=${M_ETA},METADIFF=${M_ETADIFF}, + MDPDETA=${M_DPDETA} +/ +&NAMFX2 + NX=${MAXL}, NY=${MAXB}, + MAXTIME=400,JPOLY=4, + JHRF=${DTIME}, + RLO0=${LLLO}, RLA0=${LLLA}, DX=${D_GRID}, DY=${D_GRID} +/ +EOF + + +if [[ $OS_VERSION == aix ]] ; then + scp ecgb:${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.IBM FLXACC2 CONVERT2 CHECK +else + cp ${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.ecgb FLXACC2 CONVERT2 CHECK +fi + +if [ $? -ne 0 ]; then + + ls + myerror 'ERROR: FLXACC2 and CONVERT2 could not be compiled:' 'ABORT!' + exit 1 +else + echo 'compile worked' +fi + + +# +#MARS requests (field) +# +imax=6 +set -A PARLIST U/V T Q LNSP SD/MSL/TCC/10U/10V/2T/2D 129/172/160${M_ADDPAR} +set -A PARNAME 131/132 130 133 152 SURF OROLSM +set -A REPR SH SH GG SH GG GG +set -A UNIT 10 11 17 12 14 20 +set -A LTY ML ML ML ML SFC SFC +set -A GRID ${G_GRID} ${D_GRID} ${D_GRID} OFF ${D_GRID} ${D_GRID} +set -A LEVELIST ${M_LEVELIST} ${M_LEVELIST} ${M_LEVELIST} 1 1 1 + +set -A FIELD 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 + + +if [[ $M_OMEGA -eq 1 || $M_OMEGADIFF -eq 1 ]] ; then + M_OMEGA=1 + PARLIST[imax]=W + PARNAME[imax]=135 + REPR[imax]=SH + UNIT[imax]=19 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 1 || $M_ETADIFF -eq 1 ]] ; then + M_ETA=1 + PARLIST[imax]=77 + PARNAME[imax]=77 + REPR[imax]=SH + UNIT[imax]=21 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi + +if [[ $M_GAUSS -eq 2 ]] ; then + PARLIST[imax]=VO + PARNAME[imax]=138 + REPR[imax]=SH + UNIT[imax]=30 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 0 || $M_GAUSS -eq 1 || $M_ETADIFF -eq 1 ]] ; then + PARLIST[imax]=D + PARNAME[imax]=155 + REPR[imax]=SH + UNIT[imax]=13 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + LEVELIST[1]=${G_LEVELIST} # U/V needed on all levels for calculating ETA + imax=$(($imax+1)) +fi + +jmax=${#M_TYPE[*]} + +# M_TIME needs leading zeros while M_STEP must have leading zeros +# to be consistent with MARS file naming convention +# The following loop ensures this +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TIME[$j]} -lt 10 ]] ; then + M_TIME[$j]=0$((${M_TIME[$j]})) + fi + if [[ ${M_STEP[$j]} -lt 10 ]] ; then + M_STEP[$j]=$((${M_STEP[$j]})) + fi + + j=$(($j+1)) +done + +echo ${M_TIME[*]} +echo ${M_STEP[*]} + + +rm mars_flux 2>/dev/null +j=$DTIME +while [[ $j -lt 13 ]] ; do + marsflux ${M_TYPE[2]} ${FIELD[$j]} + j=$(($j+$DTIME)) +done +mars mars_flux | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + + +# +# FLXACC job +# + + +${EXEDIR}/FLXACC2 +if [ -f OROLSM ] ; then + rm OROLSM +fi + +# +# CONVERT job +# + +#loop over DATE and TIME for CONVERT/CHECK/ECtrans job + +IJULDAY=${JULDAY1} +while [ $IJULDAY -le $JULDAY2 ]; +do + +MDATE=`civildate2 ${IJULDAY}` +MDATEX=`echo ${MDATE} | cut -c3-8` + + +i=0 +rm marsjob 2>/dev/null + +#humidity on reduced Gaussian grid for initialization +#of spectral transformations +if [ ${M_GAUSS} -eq 1 ] ; then + NGRID=$(( ( ${M_RESOL} + 1 ) / 2 )) + + marsinst ${M_TYPE[0]} ${DAY1} 00 00 Q fort.18 ML ${QG_GRID} 1 'GAUSSIAN=REDUCED,' + +set -e +mars marsjob | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +rm marsjob + +fi + +set -e + +set -A TYPEKEY ${M_TYPE[0]} +j=$DTIME +kmax=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[j]} != ${TYPEKEY[0]} ]] ; then + if [[ $kmax == 1 ]] ; then + if [[ ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${TYPEKEY[1]} ${M_TYPE[j]} + kmax=2 + fi + else + if [[ $kmax == 0 ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${M_TYPE[j]} + kmax=1 + else + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[2]} ]] ; then + + echo ${TYPEKEY[0]} ${TYPEKEY[1]} ${TYPEKEY[2]} ${M_TYPE[j]} + myerror 'More than three different MARS TYPES not supported' + + exit 1 + fi + fi + fi + fi + fi + j=$(($j+$DTIME)) +done + +set -A GRIDKEY $D_GRID +mmax=1 +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${GRID[$i]} == 'OFF' && ${PARLIST[$i]} != LNSP ]] ; then + set -A GRIDKEY $D_GRID OFF + mmax=2 + fi + i=$(($i+1)) +done + +k=0 +kmax=$(($kmax+1)) +while [[ $k -lt $kmax ]] ; do +MMTIME='' +MMSTEP='' +TSUFF='' +SSUFF='' +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[$j]} == ${TYPEKEY[$k]} ]] ; then + if [[ `echo $MMTIME | grep ${M_TIME[$j]}` == '' ]] ; then + MMTIME=${MMTIME}$TSUFF${M_TIME[$j]} + TSUFF='/' + fi + if [[ `echo $MMSTEP | grep ${M_STEP[$j]}` == '' ]] ; then + MMSTEP=${MMSTEP}$SSUFF${M_STEP[$j]} + SSUFF='/' + fi + fi +j=$(($j+$DTIME)) +done + +m=0 +while [[ $m -lt $mmax ]] ; do +MMPAR='' +PSUFF='' +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${LTY[$i]} == ML && ${GRID[$i]} == ${GRIDKEY[m]} && ${PARLIST[$i]} != LNSP ]] ; then + if [[ `echo $MMPAR | grep ${PARLIST[$i]}` == '' ]] ; then + MMPAR=${MMPAR}$PSUFF${PARLIST[$i]} + PSUFF='/' + fi + fi +i=$(($i+1)) +done + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} $MMPAR "[param].[date].[time].[step]" ML ${GRIDKEY[$m]} ${LEVELIST[$m]} + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +m=$(($m+1)) +done + +# LNSP treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} LNSP "[param].[date].[time].[step]" ML OFF 1 + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# For some data classes, MARS adds GRIB table number to parameter number, +# e.g. for Temperature it is 130.128 instead of just 130 +# + set +e + TNR=`ls 131*${MDATE}.${M_TIME[00]}00.${M_STEP[00]} | awk -F . '{print $2}' - | grep -v ${MDATE}`. + set -e + if [[ $TNR != '.' ]] ; then + TNR=.$TNR + fi + +# SURF treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[4]} "SURF${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# OROLSM treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[5]} "OROLSM${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +k=$(($k+1)) +done + + + +j=0 +while [[ $j -lt $jmax ]] ; do + + +TIME=${FIELD[j]} +XTIME=${TIME}00 + +set +e +i=0 +while [[ $i -lt $imax ]] ; do + \rm fort.${UNIT[$i]} 2>/dev/null + if [[ ${PARLIST[$i]} == U/V ]] ; then + cat 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} > fort.${UNIT[$i]} + rm 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} + else + mv ${PARNAME[$i]}${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} fort.${UNIT[$i]} + fi + i=$(($i+1)) +done + +# flux data need special GRIB conversion +#if [ ${M_FORMAT} == GRIB2 ] ; then +# grib_set -w shortName!=lsp,shortName!=cp,shortName!=ewss,shortName!=nsss -s edition=2,productDefinitionTemplateNumber=8 flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 + +#else +# mv flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +#fi + +${EXEDIR}/CONVERT2 + +INFILE=${PREFIX}${MDATEX}${TIME} + +if [ -s fort.15 ]; then + cp fort.15 ${INFILE} + cat fort.14 >> ${INFILE} + cat flux${MDATE}${TIME} >> ${INFILE} + cat OROLSM >> ${INFILE} + cat fort.20 >> ${INFILE} +# +# Convert also surface fields to GRIB2 if needed +# +# Note: GRIB2 surface fields are incompatible with FLEXPART versions < 9.2 +# +# To enable additional compression +# set packingType="grid_jpeg"; +# this is rather time consuming. + +if [ ${M_FORMAT} == GRIB2 ] ; then + grib_set -s edition=2,productDefinitionTemplateNumber=8 $INFILE ${INFILE}_2 + mv ${INFILE}_2 ${INFILE} + + if [ ${COMPRESSION} != grid_simple ] ; then + +cat >rule.filter<<EOF +set packingType="${COMPRESSION}"; +write "[file]_2"; +EOF + grib_filter rule.filter ${INFILE} + mv ${INFILE}_2 ${INFILE} + fi +fi +ls -l ${INFILE} + + +else + myerror "ERROR: ENfile ${INFILE} missing!" "ABORT!" + exit 1 +fi + +#check ENxxx file & ECtrans to local gateway +if [ -s fort.25 ]; then + mv fort.25 OMEGA${MDATEX}${TIME} + ln -s OMEGA${MDATEX}${TIME} fort.25 +fi + + +\rm fort.15 2>/dev/null +ln -s ${INFILE} fort.15 + +[ -s CHECK.SUCCESS ] && rm CHECK.SUCCESS + +${EXEDIR}/CHECK + +#check fields +if [ -s CHECK.SUCCESS ]; then + SUCCESS=1 +else + myerror 'ERROR: check on ENfile failed:' ${INFILE} "ABORT!" + exit 1 +fi + + +#ECtrans +if [ $SUCCESS -eq 1 -a $ECTRANS -eq 1 ] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source $INFILE +fi + +if [[ $M_OMEGA -eq 1 && $SUCCESS -eq 1 && $ECTRANS -eq 1 ]] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source OMEGA${MDATEX}${TIME} +fi + +#ECFS +if [ $SUCCESS -eq 1 -a $ECSTORAGE -eq 1 ] ; then + ecp -o $INFILE $ECFSDIR +fi + +if [[ $SUCCESS -eq 1 && $ECSTORAGE -eq 1 && $M_OMEGA -eq 1 ]] ; then + ecp -o OMEGA${MDATEX}${TIME} $ECFSDIR +fi + +rm ${INFILE}_2 ${INFILE} fort.15 flux${MDATE}${TIME}* OMEGA${MDATEX}${TIME} fort.25 + +j=$(($j+$DTIME)) + +#done TIME +done + +(( IJULDAY = IJULDAY + 1 )) + +#done JULDAY +done + +#any warnings ? +[ $NRW -gt 0 ] && echo There were $NRW warnings ! + +#mail logfile (list MAILOPS) +for MUSER in $MAILOPS +do + +mailx -s ${JOBNAME} ${MUSER} <${LOG_FILE} +done + +# +# cleanup +# +cd ${SCRATCH} +echo $SCRATCHDIR not removed! +#\rm -fR $SCRATCHDIR + +exit 0 + diff --git a/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_HAIYAN b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_HAIYAN new file mode 100644 index 00000000..b6aacf28 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_HAIYAN @@ -0,0 +1,873 @@ +#!/bin/ksh + +# On demand script for retrieving input for FLEXPART trajectory model +# Version 6.0, September 2013 +# Maintainer Leopold Haimberger leopold.haimberger@univie.ac.at +# +#@ shell = /usr/bin/ksh + +# NOTE: If calculation on Gaussian grid are required below, it is +# recommended to send the job to the ECMWF HPC facility +# NOTE: On hpce the class should be ns or np +# NOTE: On ecgb it should be normal + + +#ON HPC (with loadleveler) +# start with ecaccess-job-submit -queueName c1a NAME_OF_THIS_FILE on gateway server +# start with llsubmit NAME_OF_THIS_FILE directly on machine + +#@ shell = /usr/bin/ksh +#@ class = ns +#@ resources = ConsumableCpus(1) ConsumableMemory(32000MB) +#@ job_name = flex_ecmwf +#@ output = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ error = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ environment = COPY_ALL +#@ queue + + +# ON ECGB: +# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE on gateway server +# start with sbatch NAME_OF_THIS_FILE directly on machine + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf +#SBATCH --output=flex_ecmwf.%j.out +#SBATCH --error=flex_ecmwf.%j.out +#SBATCH --mail-type=FAIL +#SBATCH --time=12:00:00 + +set -x + +JOBNAME=flex_ecmwf_${HOST} + +env +ulimit -a +export OMP_NUM_THREADS=1 +export MARS_MULTITARGET_STRICT_FORMAT=1 + +#export SCRATCH=$TEMP +export SCRATCHDIR=${SCRATCH}/${JOBNAME}_$$ +[ -z "$WSHOME" ] && WSHOME=$HOME + + +mkdir $SCRATCHDIR +cd $SCRATCHDIR + +LOG_FILE=$SCRATCHDIR/${JOBNAME}_$$ +exec 1>${LOG_FILE} + +CONTROLFILE=./CONTROL_ERA + +################################### +#BEGIN: modification of config file +################################### + +cat <<EOF >CONTROL_ERA +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 200 +M_LEFT 113000 +M_LOWER 00000 +M_UPPER 30000 +M_RIGHT 190000 +M_LEVEL 137 +M_RESOL 799 +M_GAUSS 0 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 1 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EH +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF +# no changes below + +NRW=0 + +#ksh scripts for date manipulation +juldate2() + { + let jc=$1 + if (( ${#jc} < 8 )) + then + print "illegal date!" + exit 1 + fi + let y=`echo $jc | cut -c1-4` + let m1=`echo $jc | cut -c5` + let m2=`echo $jc | cut -c6` + m=$m1$m2 + let d1=`echo $jc | cut -c7` + let d2=`echo $jc | cut -c8` + d=$d1$d2 + let jd=367*y-7*(y+(m+9)/12)/4+275*m/9+d+1721014 + let jd=jd+15-3*((y+(m-9)/7)/100+1)/4 + print $jd + } + +civildate2() + { + let jd=$1 + if (( jd < 1721060 )) + then + print "Julian date not in AD." + exit 1 + fi + let k=jd+68569 + let n=4*k/146097 + let k=k-\(146097*n+3\)/4 + let y=4000*(k+1)/1461001 + let k=k-1461*y/4+31 + let m=80*k/2447 + let d=k-\(2447*m\)/80 + let k=m/11 + let m=m+2-12*k + let y=100*(n-49)+y+k + [ $m -le 9 ] && m=0$m + [ $d -le 9 ] && d=0$d + print $y$m$d + } + +date2m1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-1 + civildate2 $j0 + } + +date2p1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1+1 + civildate2 $j0 + } + + +marsinst() +{ +MTYPE="${1}" +MDAY="${2}" +MTIME="${3}" +MSTEP="${4}" +MPAR="${5}" +MFN=$6 +MLTY=$7 +MGRID="${8}" +MLEV="${9}" + +RED=0 +#if [[ ${MTYPE} != 'AN' ]] ; then + MPAR2=`echo ${MPAR} | sed s,160/,,` + MPAR2=`echo ${MPAR2} | sed s,27/,,` + MPAR2=`echo ${MPAR2} | sed s,28/,,` + MPAR2=`echo ${MPAR2} | sed s,173/,,` + if [[ ${MPAR2} != ${MPAR} ]] ; then + MPAR=${MPAR2} + RED=1 + fi +#fi + +MAREA=${M_AREA} +if [[ ${10} == 'GAUSSIAN=REDUCED,' ]] ; then + MAREA=G +fi + +if [[ -f ${MFN} ]] ; then + rm ${MFN} +fi + +cat <<EOF >> marsjob +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=${MPAR}, +RESOL=${M_RESOL}, +AREA=${MAREA}, +GRID=${MGRID}, +LEVTYPE=${MLTY}, +LEVELIST=${MLEV}, +ACCURACY=${M_ACCURACY}, +DATE=${MDAY}, +TIME=${MTIME}, +STEP=${MSTEP},${10} +TARGET="${MFN}" +EOF + +if [[ ! -f 'OROLSM' && $RED -eq 1 ]] ; then + +cat <<EOF >> marsjob +RETRIEVE,TYPE=AN,TIME=0,STEP=0,CLASS=OD, + PARAM=160/27/28/173, + TARGET="OROLSM" +EOF +fi + +} + +marsflux() +{ +MTYPE="${1}" +MSTEP="${2}" + +cat <<EOF >>mars_flux +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=LSP/CP/SSHF/EWSS/NSSS/SSR, +AREA=${M_AREA}, +GRID=${D_GRID}, +LEVTYPE=SFC, +LEVELIST=OFF, +ACCURACY=${M_ACCURACY}, REPRES=GG, +DATE=${DAY1M1}/TO/${DAY2P1}, +TIME=00/12, +AC=N, +STEP=${MSTEP}, +TARGET="surf_${MSTEP}_ub" +EOF +} + + +myerror() + { + + echo $1 + echo $2 + echo $3 + echo ABORT! + + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + } + +# +# MAIN SCRIPT CONTINUES HERE +# +#read CONTROL file, process specifications +while read NAME PARA +do + +if [[ $NAME == 'M_TYPE' || $NAME == 'M_TIME' || $NAME == 'M_STEP' ]] ; then + eval "set -A $NAME $PARA" +else + eval "export $NAME='$PARA'" +fi +echo `echo $NAME`=$PARA + +done <${CONTROLFILE} + + +if [ -z "$DAY1" -o -z "$DAY2" ]; then + myerror 'DAY specification missing !' + exit 1 +fi + +#defaults +[ -z "$M_EXPVER" ] && M_EXPVER=1 +[ -z "$M_CLASS" ] && M_CLASS=OD +[ -z "$M_STREAM" ] && M_STREAM=OPER +[ -z "$M_NUMBER" ] && M_NUMBER=OFF +[ -z "$M_TYPE" ] && set -A M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +[ -z "$M_TIME" ] && set -A M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +[ -z "$M_STEP" ] && set -A M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +[ -z "$DTIME" ] && DTIME=6 +[ -z "$M_GRID" ] && M_GRID=1000 +[ -z "$M_LOWER" ] && M_LOWER=-90000 +[ -z "$M_LEFT" ] && M_LEFT=-179000 +[ -z "$M_UPPER" ] && M_UPPER=90000 +[ -z "$M_RIGHT" ] && M_RIGHT=180000 +[ -z "$M_LEVEL" ] && M_LEVEL=91 +[ -z "$M_LEVELIST" ] && M_LEVELIST=1/TO/$M_LEVEL +[ -z "$M_ADDPAR" ] && M_ADDPAR='' +[ -z "$M_RESOL" ] && M_RESOL=799 +[ -z "$M_GAUSS" ] && M_GAUSS=0 +[ -z "$M_SMOOTH" ] && M_SMOOTH=0 +[ -z "$M_OMEGA" ] && M_OMEGA=0 +[ -z "$M_OMEGADIFF" ] && M_OMEGADIFF=0 +[ -z "$M_ETA" ] && M_ETA=0 +[ -z "$M_ETADIFF" ] && M_ETADIFF=0 +[ -z "$M_ETAPAR" ] && M_ETAPAR=77 +[ -z "$M_DPDETA" ] && M_DPDETA=1 +[ -z "$M_ACCURACY" ] && M_ACCURACY=24 +[ -z "$EXEDIR" ] && EXEDIR=. +[ -z "$SOURCECODE" ] && SOURCECODE=ecgate:flex_extract_ecgate +[ -z "$GATEWAY" ] && GATEWAY='' +[ -z "$DESTINATION" ] && DESTINATION='' +[ -z "$PREFIX" ] && PREFIX=EN +[ -z "$COMPRESSION" ] && COMPRESSION=grid_simple +[ -z "$ECTRANS" ] && ECTRANS=0 +[ -z "$ECSTORAGE" ] && ECSTORAGE=1 +[ -z "$ECFSDIR" ] && ECFSDIR=ectmp: +[ -z "$MAILOPS" ] && MAILOPS=${USER} +[ -z "$MAILFAIL" ] && MAILFAIL=${USER} + + +#additional dates for flux retrievals (polynomial interpolation) +DAY1M1=`date2m1 ${DAY1}` +DAY2P1=`date2p1 ${DAY2}` + +#julian dates for time loops +JULDAY1=`juldate2 ${DAY1}` +JULDAY2=`juldate2 ${DAY2}` + +echo JULDATES $JULDAY1 $JULDAY2 + +#check consistency +if [ ${DAY1} -gt ${DAY2} ]; then + `myerror "ERROR: DAY1 > DAY2: ${DAY1}, ${DAY2}"` + exit 1 +fi + + +# determine number of gridpoints and whether grid is cyclic +ZYK=`expr \( $M_RIGHT + 360000 \) % 360000 - \( $M_LEFT + 360000 \) % 360000 + $M_GRID` + +if [ $M_RIGHT -le $M_LEFT ] ; then + if [ $M_RIGHT -le 0 ] ; then + M_RIGHT=$(($M_RIGHT+360000)) + else + M_LEFT=$(($M_LEFT-360000)) + fi +fi + +if [[ $ZYK -ne 0 ]] ; then + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED NON-CYCLIC" + exit 1 + fi +else + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED CYCLIC" + exit 1 + fi +fi + +if [ $((180000/$M_GRID-$M_RESOL)) -lt 0 ] ; then + + if [ ${M_SMOOTH} -eq 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SPECTRAL RESOLUTION ${M_RESOL} " "USE M_SMOOTH FOR SMOOTHING OR FINER OUTPUT GRID" +# exit 1 + else + if [ $((180000/$M_GRID-$M_SMOOTH)) -lt 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SMOOTHED SPECTRAL RESOLUTION ${M_SMOOTH} " + fi + fi + +fi + + +# convert lat/lon to MARS format (degrees) +if [[ $M_LEFT -lt 0 ]] ; then + LLLO=$(($M_LEFT / 1000)).$((($M_LEFT)*(-1) % 1000)) +else + LLLO=$(($M_LEFT / 1000)).$(($M_LEFT % 1000)) +fi +if [[ $M_LOWER -lt 0 ]] ; then + LLLA=$(($M_LOWER / 1000)).$(($M_LOWER*(-1) % 1000)) +else + LLLA=$(($M_LOWER / 1000)).$((($M_LOWER) % 1000)) +fi +if [[ $M_RIGHT -lt 0 ]] ; then + URLO=$(($M_RIGHT / 1000)).$((($M_RIGHT)*(-1) % 1000)) +else + URLO=$(($M_RIGHT / 1000)).$(($M_RIGHT % 1000)) +fi +if [[ $M_UPPER -lt 0 ]] ; then + URLA=$(($M_UPPER / 1000)).$((($M_UPPER)*(-1) % 1000)) +else + URLA=$(($M_UPPER / 1000)).$(($M_UPPER % 1000)) +fi + +M_AREA=${URLA}/${LLLO}/${LLLA}/${URLO} + +if [ $M_GAUSS -eq 1 ] ; then +# Gaussian grid detected + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=OFF + QG_GRID=OFF + if [ $M_RESOL -le 799 ] ; then + QG_GRID=$((($M_RESOL+1)/2)) + fi + D_GRID=${D_GRID}/${D_GRID} + +else + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=${G_GRID}/${G_GRID} + D_GRID=${D_GRID}/${D_GRID} +fi + +G_LEVELIST=1/to/${M_LEVEL} + + +#namelist +cat <<EOF >fort.4 +&NAMGEN + MAXL=${MAXL}, MAXB=${MAXB}, + MLEVEL=${M_LEVEL}, MLEVELIST="${M_LEVELIST}", + MNAUF=${M_RESOL},METAPAR=${M_ETAPAR}, + RLO0=${LLLO}, RLO1=${URLO}, RLA0=${LLLA}, RLA1=${URLA}, + MOMEGA=${M_OMEGA},MOMEGADIFF=${M_OMEGADIFF},MGAUSS=${M_GAUSS}, + MSMOOTH=${M_SMOOTH},META=${M_ETA},METADIFF=${M_ETADIFF}, + MDPDETA=${M_DPDETA} +/ +&NAMFX2 + NX=${MAXL}, NY=${MAXB}, + MAXTIME=400,JPOLY=4, + JHRF=${DTIME}, + RLO0=${LLLO}, RLA0=${LLLA}, DX=${D_GRID}, DY=${D_GRID} +/ +EOF + + +if [[ $OS_VERSION == aix ]] ; then + scp ecgb:${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.IBM FLXACC2 CONVERT2 CHECK +else + cp ${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.ecgb FLXACC2 CONVERT2 CHECK +fi + +if [ $? -ne 0 ]; then + + ls + myerror 'ERROR: FLXACC2 and CONVERT2 could not be compiled:' 'ABORT!' + exit 1 +else + echo 'compile worked' +fi + + +# +#MARS requests (field) +# +imax=6 +set -A PARLIST U/V T Q LNSP SD/MSL/TCC/10U/10V/2T/2D 129/172/160${M_ADDPAR} +set -A PARNAME 131/132 130 133 152 SURF OROLSM +set -A REPR SH SH GG SH GG GG +set -A UNIT 10 11 17 12 14 20 +set -A LTY ML ML ML ML SFC SFC +set -A GRID ${G_GRID} ${D_GRID} ${D_GRID} OFF ${D_GRID} ${D_GRID} +set -A LEVELIST ${M_LEVELIST} ${M_LEVELIST} ${M_LEVELIST} 1 1 1 + +set -A FIELD 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 + + +if [[ $M_OMEGA -eq 1 || $M_OMEGADIFF -eq 1 ]] ; then + M_OMEGA=1 + PARLIST[imax]=W + PARNAME[imax]=135 + REPR[imax]=SH + UNIT[imax]=19 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 1 || $M_ETADIFF -eq 1 ]] ; then + M_ETA=1 + PARLIST[imax]=77 + PARNAME[imax]=77 + REPR[imax]=SH + UNIT[imax]=21 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi + +if [[ $M_GAUSS -eq 2 ]] ; then + PARLIST[imax]=VO + PARNAME[imax]=138 + REPR[imax]=SH + UNIT[imax]=30 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 0 || $M_GAUSS -eq 1 || $M_ETADIFF -eq 1 ]] ; then + PARLIST[imax]=D + PARNAME[imax]=155 + REPR[imax]=SH + UNIT[imax]=13 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + LEVELIST[1]=${G_LEVELIST} # U/V needed on all levels for calculating ETA + imax=$(($imax+1)) +fi + +jmax=${#M_TYPE[*]} + +# M_TIME needs leading zeros while M_STEP must have leading zeros +# to be consistent with MARS file naming convention +# The following loop ensures this +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TIME[$j]} -lt 10 ]] ; then + M_TIME[$j]=0$((${M_TIME[$j]})) + fi + if [[ ${M_STEP[$j]} -lt 10 ]] ; then + M_STEP[$j]=$((${M_STEP[$j]})) + fi + + j=$(($j+1)) +done + +echo ${M_TIME[*]} +echo ${M_STEP[*]} + + +rm mars_flux 2>/dev/null +j=$DTIME +while [[ $j -lt 13 ]] ; do + marsflux ${M_TYPE[2]} ${FIELD[$j]} + j=$(($j+$DTIME)) +done +mars mars_flux | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + + +# +# FLXACC job +# + + +${EXEDIR}/FLXACC2 +if [ -f OROLSM ] ; then + rm OROLSM +fi + +# +# CONVERT job +# + +#loop over DATE and TIME for CONVERT/CHECK/ECtrans job + +IJULDAY=${JULDAY1} +while [ $IJULDAY -le $JULDAY2 ]; +do + +MDATE=`civildate2 ${IJULDAY}` +MDATEX=`echo ${MDATE} | cut -c3-8` + + +i=0 +rm marsjob 2>/dev/null + +#humidity on reduced Gaussian grid for initialization +#of spectral transformations +if [ ${M_GAUSS} -eq 1 ] ; then + NGRID=$(( ( ${M_RESOL} + 1 ) / 2 )) + + marsinst ${M_TYPE[0]} ${DAY1} 00 00 Q fort.18 ML ${QG_GRID} 1 'GAUSSIAN=REDUCED,' + +set -e +mars marsjob | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +rm marsjob + +fi + +set -e + +set -A TYPEKEY ${M_TYPE[0]} +j=$DTIME +kmax=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[j]} != ${TYPEKEY[0]} ]] ; then + if [[ $kmax == 1 ]] ; then + if [[ ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${TYPEKEY[1]} ${M_TYPE[j]} + kmax=2 + fi + else + if [[ $kmax == 0 ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${M_TYPE[j]} + kmax=1 + else + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[2]} ]] ; then + + echo ${TYPEKEY[0]} ${TYPEKEY[1]} ${TYPEKEY[2]} ${M_TYPE[j]} + myerror 'More than three different MARS TYPES not supported' + + exit 1 + fi + fi + fi + fi + fi + j=$(($j+$DTIME)) +done + +set -A GRIDKEY $D_GRID +mmax=1 +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${GRID[$i]} == 'OFF' && ${PARLIST[$i]} != LNSP ]] ; then + set -A GRIDKEY $D_GRID OFF + mmax=2 + fi + i=$(($i+1)) +done + +k=0 +kmax=$(($kmax+1)) +while [[ $k -lt $kmax ]] ; do +MMTIME='' +MMSTEP='' +TSUFF='' +SSUFF='' +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[$j]} == ${TYPEKEY[$k]} ]] ; then + if [[ `echo $MMTIME | grep ${M_TIME[$j]}` == '' ]] ; then + MMTIME=${MMTIME}$TSUFF${M_TIME[$j]} + TSUFF='/' + fi + if [[ `echo $MMSTEP | grep ${M_STEP[$j]}` == '' ]] ; then + MMSTEP=${MMSTEP}$SSUFF${M_STEP[$j]} + SSUFF='/' + fi + fi +j=$(($j+$DTIME)) +done + +m=0 +while [[ $m -lt $mmax ]] ; do +MMPAR='' +PSUFF='' +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${LTY[$i]} == ML && ${GRID[$i]} == ${GRIDKEY[m]} && ${PARLIST[$i]} != LNSP ]] ; then + if [[ `echo $MMPAR | grep ${PARLIST[$i]}` == '' ]] ; then + MMPAR=${MMPAR}$PSUFF${PARLIST[$i]} + PSUFF='/' + fi + fi +i=$(($i+1)) +done + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} $MMPAR "[param].[date].[time].[step]" ML ${GRIDKEY[$m]} ${LEVELIST[$m]} + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +m=$(($m+1)) +done + +# LNSP treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} LNSP "[param].[date].[time].[step]" ML OFF 1 + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# For some data classes, MARS adds GRIB table number to parameter number, +# e.g. for Temperature it is 130.128 instead of just 130 +# + set +e + TNR=`ls 131*${MDATE}.${M_TIME[00]}00.${M_STEP[00]} | awk -F . '{print $2}' - | grep -v ${MDATE}`. + set -e + if [[ $TNR != '.' ]] ; then + TNR=.$TNR + fi + +# SURF treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[4]} "SURF${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# OROLSM treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[5]} "OROLSM${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +k=$(($k+1)) +done + + + +j=0 +while [[ $j -lt $jmax ]] ; do + + +TIME=${FIELD[j]} +XTIME=${TIME}00 + +set +e +i=0 +while [[ $i -lt $imax ]] ; do + \rm fort.${UNIT[$i]} 2>/dev/null + if [[ ${PARLIST[$i]} == U/V ]] ; then + cat 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} > fort.${UNIT[$i]} + rm 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} + else + mv ${PARNAME[$i]}${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} fort.${UNIT[$i]} + fi + i=$(($i+1)) +done + +# flux data need special GRIB conversion +#if [ ${M_FORMAT} == GRIB2 ] ; then +# grib_set -w shortName!=lsp,shortName!=cp,shortName!=ewss,shortName!=nsss -s edition=2,productDefinitionTemplateNumber=8 flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 + +#else +# mv flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +#fi + +${EXEDIR}/CONVERT2 + +INFILE=${PREFIX}${MDATEX}${TIME} + +if [ -s fort.15 ]; then + cp fort.15 ${INFILE} + cat fort.14 >> ${INFILE} + cat flux${MDATE}${TIME} >> ${INFILE} + cat OROLSM >> ${INFILE} + cat fort.20 >> ${INFILE} +# +# Convert also surface fields to GRIB2 if needed +# +# Note: GRIB2 surface fields are incompatible with FLEXPART versions < 9.2 +# +# To enable additional compression +# set packingType="grid_jpeg"; +# this is rather time consuming. + +if [ ${M_FORMAT} == GRIB2 ] ; then + grib_set -s edition=2,productDefinitionTemplateNumber=8 $INFILE ${INFILE}_2 + mv ${INFILE}_2 ${INFILE} + + if [ ${COMPRESSION} != grid_simple ] ; then + +cat >rule.filter<<EOF +set packingType="${COMPRESSION}"; +write "[file]_2"; +EOF + grib_filter rule.filter ${INFILE} + mv ${INFILE}_2 ${INFILE} + fi +fi +ls -l ${INFILE} + + +else + myerror "ERROR: ENfile ${INFILE} missing!" "ABORT!" + exit 1 +fi + +#check ENxxx file & ECtrans to local gateway +if [ -s fort.25 ]; then + mv fort.25 OMEGA${MDATEX}${TIME} + ln -s OMEGA${MDATEX}${TIME} fort.25 +fi + + +\rm fort.15 2>/dev/null +ln -s ${INFILE} fort.15 + +[ -s CHECK.SUCCESS ] && rm CHECK.SUCCESS + +${EXEDIR}/CHECK + +#check fields +if [ -s CHECK.SUCCESS ]; then + SUCCESS=1 +else + myerror 'ERROR: check on ENfile failed:' ${INFILE} "ABORT!" + exit 1 +fi + + +#ECtrans +if [ $SUCCESS -eq 1 -a $ECTRANS -eq 1 ] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source $INFILE +fi + +if [[ $M_OMEGA -eq 1 && $SUCCESS -eq 1 && $ECTRANS -eq 1 ]] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source OMEGA${MDATEX}${TIME} +fi + +#ECFS +if [ $SUCCESS -eq 1 -a $ECSTORAGE -eq 1 ] ; then + ecp -o $INFILE $ECFSDIR +fi + +if [[ $SUCCESS -eq 1 && $ECSTORAGE -eq 1 && $M_OMEGA -eq 1 ]] ; then + ecp -o OMEGA${MDATEX}${TIME} $ECFSDIR +fi + +rm ${INFILE}_2 ${INFILE} fort.15 flux${MDATE}${TIME}* OMEGA${MDATEX}${TIME} fort.25 + +j=$(($j+$DTIME)) + +#done TIME +done + +(( IJULDAY = IJULDAY + 1 )) + +#done JULDAY +done + +#any warnings ? +[ $NRW -gt 0 ] && echo There were $NRW warnings ! + +#mail logfile (list MAILOPS) +for MUSER in $MAILOPS +do + +mailx -s ${JOBNAME} ${MUSER} <${LOG_FILE} +done + +# +# cleanup +# +cd ${SCRATCH} +echo $SCRATCHDIR not removed! +#\rm -fR $SCRATCHDIR + +exit 0 + diff --git a/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_HIRES b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_HIRES new file mode 100644 index 00000000..ba18d501 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_HIRES @@ -0,0 +1,873 @@ +#!/bin/ksh + +# On demand script for retrieving input for FLEXPART trajectory model +# Version 6.0, September 2013 +# Maintainer Leopold Haimberger leopold.haimberger@univie.ac.at +# +#@ shell = /usr/bin/ksh + +# NOTE: If calculation on Gaussian grid are required below, it is +# recommended to send the job to the ECMWF HPC facility +# NOTE: On hpce the class should be ns or np +# NOTE: On ecgb it should be normal + + +#ON HPC (with loadleveler) +# start with ecaccess-job-submit -queueName c1a NAME_OF_THIS_FILE on gateway server +# start with llsubmit NAME_OF_THIS_FILE directly on machine + +#@ shell = /usr/bin/ksh +#@ class = ns +#@ resources = ConsumableCpus(1) ConsumableMemory(32000MB) +#@ job_name = flex_ecmwf +#@ output = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ error = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ environment = COPY_ALL +#@ queue + + +# ON ECGB: +# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE on gateway server +# start with sbatch NAME_OF_THIS_FILE directly on machine + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf +#SBATCH --output=flex_ecmwf.%j.out +#SBATCH --error=flex_ecmwf.%j.out +#SBATCH --mail-type=FAIL +#SBATCH --time=12:00:00 + +set -x + +JOBNAME=flex_ecmwf_${HOST} + +env +ulimit -a +export OMP_NUM_THREADS=1 +export MARS_MULTITARGET_STRICT_FORMAT=1 + +#export SCRATCH=$TEMP +export SCRATCHDIR=${SCRATCH}/${JOBNAME}_$$ +[ -z "$WSHOME" ] && WSHOME=$HOME + + +mkdir $SCRATCHDIR +cd $SCRATCHDIR + +LOG_FILE=$SCRATCHDIR/${JOBNAME}_$$ +exec 1>${LOG_FILE} + +CONTROLFILE=./CONTROL_ERA + +################################### +#BEGIN: modification of config file +################################### + +cat <<EOF >CONTROL_ERA +DAY1 20131107 +DAY2 20131108 +DTIME 3 +M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +M_CLASS OD +M_STREAM OPER +M_NUMBER OFF +M_EXPVER 1 +M_GRID 200 +M_LEFT -10000 +M_LOWER 30000 +M_UPPER 60000 +M_RIGHT 30000 +M_LEVEL 137 +M_RESOL 799 +M_GAUSS 0 +M_ACCURACY 24 +M_OMEGA 0 +M_OMEGADIFF 0 +M_ETA 1 +M_ETADIFF 0 +M_DPDETA 1 +M_SMOOTH 0 +M_FORMAT GRIB1 +M_ADDPAR /27/28/173/186/187/188/235/139/39 +PREFIX EH +GATEWAY srvx7.img.univie.ac.at +DESTINATION leo@genericSftp +ECSTORAGE 1 +ECTRANS 0 +ECFSDIR ectmp:/${USER}/econdemand/ +MAILOPS ${USER} +MAILFAIL ${USER} +EXEDIR . +SOURCECODE ${WSHOME}/flex_extract_ecgate_V6.0 +EOF +# no changes below + +NRW=0 + +#ksh scripts for date manipulation +juldate2() + { + let jc=$1 + if (( ${#jc} < 8 )) + then + print "illegal date!" + exit 1 + fi + let y=`echo $jc | cut -c1-4` + let m1=`echo $jc | cut -c5` + let m2=`echo $jc | cut -c6` + m=$m1$m2 + let d1=`echo $jc | cut -c7` + let d2=`echo $jc | cut -c8` + d=$d1$d2 + let jd=367*y-7*(y+(m+9)/12)/4+275*m/9+d+1721014 + let jd=jd+15-3*((y+(m-9)/7)/100+1)/4 + print $jd + } + +civildate2() + { + let jd=$1 + if (( jd < 1721060 )) + then + print "Julian date not in AD." + exit 1 + fi + let k=jd+68569 + let n=4*k/146097 + let k=k-\(146097*n+3\)/4 + let y=4000*(k+1)/1461001 + let k=k-1461*y/4+31 + let m=80*k/2447 + let d=k-\(2447*m\)/80 + let k=m/11 + let m=m+2-12*k + let y=100*(n-49)+y+k + [ $m -le 9 ] && m=0$m + [ $d -le 9 ] && d=0$d + print $y$m$d + } + +date2m1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-1 + civildate2 $j0 + } + +date2p1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1+1 + civildate2 $j0 + } + + +marsinst() +{ +MTYPE="${1}" +MDAY="${2}" +MTIME="${3}" +MSTEP="${4}" +MPAR="${5}" +MFN=$6 +MLTY=$7 +MGRID="${8}" +MLEV="${9}" + +RED=0 +#if [[ ${MTYPE} != 'AN' ]] ; then + MPAR2=`echo ${MPAR} | sed s,160/,,` + MPAR2=`echo ${MPAR2} | sed s,27/,,` + MPAR2=`echo ${MPAR2} | sed s,28/,,` + MPAR2=`echo ${MPAR2} | sed s,173/,,` + if [[ ${MPAR2} != ${MPAR} ]] ; then + MPAR=${MPAR2} + RED=1 + fi +#fi + +MAREA=${M_AREA} +if [[ ${10} == 'GAUSSIAN=REDUCED,' ]] ; then + MAREA=G +fi + +if [[ -f ${MFN} ]] ; then + rm ${MFN} +fi + +cat <<EOF >> marsjob +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=${MPAR}, +RESOL=${M_RESOL}, +AREA=${MAREA}, +GRID=${MGRID}, +LEVTYPE=${MLTY}, +LEVELIST=${MLEV}, +ACCURACY=${M_ACCURACY}, +DATE=${MDAY}, +TIME=${MTIME}, +STEP=${MSTEP},${10} +TARGET="${MFN}" +EOF + +if [[ ! -f 'OROLSM' && $RED -eq 1 ]] ; then + +cat <<EOF >> marsjob +RETRIEVE,TYPE=AN,TIME=0,STEP=0,CLASS=OD, + PARAM=160/27/28/173, + TARGET="OROLSM" +EOF +fi + +} + +marsflux() +{ +MTYPE="${1}" +MSTEP="${2}" + +cat <<EOF >>mars_flux +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=LSP/CP/SSHF/EWSS/NSSS/SSR, +AREA=${M_AREA}, +GRID=${D_GRID}, +LEVTYPE=SFC, +LEVELIST=OFF, +ACCURACY=${M_ACCURACY}, REPRES=GG, +DATE=${DAY1M1}/TO/${DAY2P1}, +TIME=00/12, +AC=N, +STEP=${MSTEP}, +TARGET="surf_${MSTEP}_ub" +EOF +} + + +myerror() + { + + echo $1 + echo $2 + echo $3 + echo ABORT! + + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + } + +# +# MAIN SCRIPT CONTINUES HERE +# +#read CONTROL file, process specifications +while read NAME PARA +do + +if [[ $NAME == 'M_TYPE' || $NAME == 'M_TIME' || $NAME == 'M_STEP' ]] ; then + eval "set -A $NAME $PARA" +else + eval "export $NAME='$PARA'" +fi +echo `echo $NAME`=$PARA + +done <${CONTROLFILE} + + +if [ -z "$DAY1" -o -z "$DAY2" ]; then + myerror 'DAY specification missing !' + exit 1 +fi + +#defaults +[ -z "$M_EXPVER" ] && M_EXPVER=1 +[ -z "$M_CLASS" ] && M_CLASS=OD +[ -z "$M_STREAM" ] && M_STREAM=OPER +[ -z "$M_NUMBER" ] && M_NUMBER=OFF +[ -z "$M_TYPE" ] && set -A M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +[ -z "$M_TIME" ] && set -A M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +[ -z "$M_STEP" ] && set -A M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +[ -z "$DTIME" ] && DTIME=6 +[ -z "$M_GRID" ] && M_GRID=1000 +[ -z "$M_LOWER" ] && M_LOWER=-90000 +[ -z "$M_LEFT" ] && M_LEFT=-179000 +[ -z "$M_UPPER" ] && M_UPPER=90000 +[ -z "$M_RIGHT" ] && M_RIGHT=180000 +[ -z "$M_LEVEL" ] && M_LEVEL=91 +[ -z "$M_LEVELIST" ] && M_LEVELIST=1/TO/$M_LEVEL +[ -z "$M_ADDPAR" ] && M_ADDPAR='' +[ -z "$M_RESOL" ] && M_RESOL=799 +[ -z "$M_GAUSS" ] && M_GAUSS=0 +[ -z "$M_SMOOTH" ] && M_SMOOTH=0 +[ -z "$M_OMEGA" ] && M_OMEGA=0 +[ -z "$M_OMEGADIFF" ] && M_OMEGADIFF=0 +[ -z "$M_ETA" ] && M_ETA=0 +[ -z "$M_ETADIFF" ] && M_ETADIFF=0 +[ -z "$M_ETAPAR" ] && M_ETAPAR=77 +[ -z "$M_DPDETA" ] && M_DPDETA=1 +[ -z "$M_ACCURACY" ] && M_ACCURACY=24 +[ -z "$EXEDIR" ] && EXEDIR=. +[ -z "$SOURCECODE" ] && SOURCECODE=ecgate:flex_extract_ecgate +[ -z "$GATEWAY" ] && GATEWAY='' +[ -z "$DESTINATION" ] && DESTINATION='' +[ -z "$PREFIX" ] && PREFIX=EN +[ -z "$COMPRESSION" ] && COMPRESSION=grid_simple +[ -z "$ECTRANS" ] && ECTRANS=0 +[ -z "$ECSTORAGE" ] && ECSTORAGE=1 +[ -z "$ECFSDIR" ] && ECFSDIR=ectmp: +[ -z "$MAILOPS" ] && MAILOPS=${USER} +[ -z "$MAILFAIL" ] && MAILFAIL=${USER} + + +#additional dates for flux retrievals (polynomial interpolation) +DAY1M1=`date2m1 ${DAY1}` +DAY2P1=`date2p1 ${DAY2}` + +#julian dates for time loops +JULDAY1=`juldate2 ${DAY1}` +JULDAY2=`juldate2 ${DAY2}` + +echo JULDATES $JULDAY1 $JULDAY2 + +#check consistency +if [ ${DAY1} -gt ${DAY2} ]; then + `myerror "ERROR: DAY1 > DAY2: ${DAY1}, ${DAY2}"` + exit 1 +fi + + +# determine number of gridpoints and whether grid is cyclic +ZYK=`expr \( $M_RIGHT + 360000 \) % 360000 - \( $M_LEFT + 360000 \) % 360000 + $M_GRID` + +if [ $M_RIGHT -le $M_LEFT ] ; then + if [ $M_RIGHT -le 0 ] ; then + M_RIGHT=$(($M_RIGHT+360000)) + else + M_LEFT=$(($M_LEFT-360000)) + fi +fi + +if [[ $ZYK -ne 0 ]] ; then + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED NON-CYCLIC" + exit 1 + fi +else + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED CYCLIC" + exit 1 + fi +fi + +if [ $((180000/$M_GRID-$M_RESOL)) -lt 0 ] ; then + + if [ ${M_SMOOTH} -eq 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SPECTRAL RESOLUTION ${M_RESOL} " "USE M_SMOOTH FOR SMOOTHING OR FINER OUTPUT GRID" +# exit 1 + else + if [ $((180000/$M_GRID-$M_SMOOTH)) -lt 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SMOOTHED SPECTRAL RESOLUTION ${M_SMOOTH} " + fi + fi + +fi + + +# convert lat/lon to MARS format (degrees) +if [[ $M_LEFT -lt 0 ]] ; then + LLLO=$(($M_LEFT / 1000)).$((($M_LEFT)*(-1) % 1000)) +else + LLLO=$(($M_LEFT / 1000)).$(($M_LEFT % 1000)) +fi +if [[ $M_LOWER -lt 0 ]] ; then + LLLA=$(($M_LOWER / 1000)).$(($M_LOWER*(-1) % 1000)) +else + LLLA=$(($M_LOWER / 1000)).$((($M_LOWER) % 1000)) +fi +if [[ $M_RIGHT -lt 0 ]] ; then + URLO=$(($M_RIGHT / 1000)).$((($M_RIGHT)*(-1) % 1000)) +else + URLO=$(($M_RIGHT / 1000)).$(($M_RIGHT % 1000)) +fi +if [[ $M_UPPER -lt 0 ]] ; then + URLA=$(($M_UPPER / 1000)).$((($M_UPPER)*(-1) % 1000)) +else + URLA=$(($M_UPPER / 1000)).$(($M_UPPER % 1000)) +fi + +M_AREA=${URLA}/${LLLO}/${LLLA}/${URLO} + +if [ $M_GAUSS -eq 1 ] ; then +# Gaussian grid detected + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=OFF + QG_GRID=OFF + if [ $M_RESOL -le 799 ] ; then + QG_GRID=$((($M_RESOL+1)/2)) + fi + D_GRID=${D_GRID}/${D_GRID} + +else + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=${G_GRID}/${G_GRID} + D_GRID=${D_GRID}/${D_GRID} +fi + +G_LEVELIST=1/to/${M_LEVEL} + + +#namelist +cat <<EOF >fort.4 +&NAMGEN + MAXL=${MAXL}, MAXB=${MAXB}, + MLEVEL=${M_LEVEL}, MLEVELIST="${M_LEVELIST}", + MNAUF=${M_RESOL},METAPAR=${M_ETAPAR}, + RLO0=${LLLO}, RLO1=${URLO}, RLA0=${LLLA}, RLA1=${URLA}, + MOMEGA=${M_OMEGA},MOMEGADIFF=${M_OMEGADIFF},MGAUSS=${M_GAUSS}, + MSMOOTH=${M_SMOOTH},META=${M_ETA},METADIFF=${M_ETADIFF}, + MDPDETA=${M_DPDETA} +/ +&NAMFX2 + NX=${MAXL}, NY=${MAXB}, + MAXTIME=400,JPOLY=4, + JHRF=${DTIME}, + RLO0=${LLLO}, RLA0=${LLLA}, DX=${D_GRID}, DY=${D_GRID} +/ +EOF + + +if [[ $OS_VERSION == aix ]] ; then + scp ecgb:${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.IBM FLXACC2 CONVERT2 CHECK +else + cp ${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.ecgb FLXACC2 CONVERT2 CHECK +fi + +if [ $? -ne 0 ]; then + + ls + myerror 'ERROR: FLXACC2 and CONVERT2 could not be compiled:' 'ABORT!' + exit 1 +else + echo 'compile worked' +fi + + +# +#MARS requests (field) +# +imax=6 +set -A PARLIST U/V T Q LNSP SD/MSL/TCC/10U/10V/2T/2D 129/172/160${M_ADDPAR} +set -A PARNAME 131/132 130 133 152 SURF OROLSM +set -A REPR SH SH GG SH GG GG +set -A UNIT 10 11 17 12 14 20 +set -A LTY ML ML ML ML SFC SFC +set -A GRID ${G_GRID} ${D_GRID} ${D_GRID} OFF ${D_GRID} ${D_GRID} +set -A LEVELIST ${M_LEVELIST} ${M_LEVELIST} ${M_LEVELIST} 1 1 1 + +set -A FIELD 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 + + +if [[ $M_OMEGA -eq 1 || $M_OMEGADIFF -eq 1 ]] ; then + M_OMEGA=1 + PARLIST[imax]=W + PARNAME[imax]=135 + REPR[imax]=SH + UNIT[imax]=19 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 1 || $M_ETADIFF -eq 1 ]] ; then + M_ETA=1 + PARLIST[imax]=77 + PARNAME[imax]=77 + REPR[imax]=SH + UNIT[imax]=21 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi + +if [[ $M_GAUSS -eq 2 ]] ; then + PARLIST[imax]=VO + PARNAME[imax]=138 + REPR[imax]=SH + UNIT[imax]=30 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 0 || $M_GAUSS -eq 1 || $M_ETADIFF -eq 1 ]] ; then + PARLIST[imax]=D + PARNAME[imax]=155 + REPR[imax]=SH + UNIT[imax]=13 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + LEVELIST[1]=${G_LEVELIST} # U/V needed on all levels for calculating ETA + imax=$(($imax+1)) +fi + +jmax=${#M_TYPE[*]} + +# M_TIME needs leading zeros while M_STEP must have leading zeros +# to be consistent with MARS file naming convention +# The following loop ensures this +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TIME[$j]} -lt 10 ]] ; then + M_TIME[$j]=0$((${M_TIME[$j]})) + fi + if [[ ${M_STEP[$j]} -lt 10 ]] ; then + M_STEP[$j]=$((${M_STEP[$j]})) + fi + + j=$(($j+1)) +done + +echo ${M_TIME[*]} +echo ${M_STEP[*]} + + +rm mars_flux 2>/dev/null +j=$DTIME +while [[ $j -lt 13 ]] ; do + marsflux ${M_TYPE[2]} ${FIELD[$j]} + j=$(($j+$DTIME)) +done +mars mars_flux | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + + +# +# FLXACC job +# + + +${EXEDIR}/FLXACC2 +if [ -f OROLSM ] ; then + rm OROLSM +fi + +# +# CONVERT job +# + +#loop over DATE and TIME for CONVERT/CHECK/ECtrans job + +IJULDAY=${JULDAY1} +while [ $IJULDAY -le $JULDAY2 ]; +do + +MDATE=`civildate2 ${IJULDAY}` +MDATEX=`echo ${MDATE} | cut -c3-8` + + +i=0 +rm marsjob 2>/dev/null + +#humidity on reduced Gaussian grid for initialization +#of spectral transformations +if [ ${M_GAUSS} -eq 1 ] ; then + NGRID=$(( ( ${M_RESOL} + 1 ) / 2 )) + + marsinst ${M_TYPE[0]} ${DAY1} 00 00 Q fort.18 ML ${QG_GRID} 1 'GAUSSIAN=REDUCED,' + +set -e +mars marsjob | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +rm marsjob + +fi + +set -e + +set -A TYPEKEY ${M_TYPE[0]} +j=$DTIME +kmax=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[j]} != ${TYPEKEY[0]} ]] ; then + if [[ $kmax == 1 ]] ; then + if [[ ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${TYPEKEY[1]} ${M_TYPE[j]} + kmax=2 + fi + else + if [[ $kmax == 0 ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${M_TYPE[j]} + kmax=1 + else + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[2]} ]] ; then + + echo ${TYPEKEY[0]} ${TYPEKEY[1]} ${TYPEKEY[2]} ${M_TYPE[j]} + myerror 'More than three different MARS TYPES not supported' + + exit 1 + fi + fi + fi + fi + fi + j=$(($j+$DTIME)) +done + +set -A GRIDKEY $D_GRID +mmax=1 +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${GRID[$i]} == 'OFF' && ${PARLIST[$i]} != LNSP ]] ; then + set -A GRIDKEY $D_GRID OFF + mmax=2 + fi + i=$(($i+1)) +done + +k=0 +kmax=$(($kmax+1)) +while [[ $k -lt $kmax ]] ; do +MMTIME='' +MMSTEP='' +TSUFF='' +SSUFF='' +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[$j]} == ${TYPEKEY[$k]} ]] ; then + if [[ `echo $MMTIME | grep ${M_TIME[$j]}` == '' ]] ; then + MMTIME=${MMTIME}$TSUFF${M_TIME[$j]} + TSUFF='/' + fi + if [[ `echo $MMSTEP | grep ${M_STEP[$j]}` == '' ]] ; then + MMSTEP=${MMSTEP}$SSUFF${M_STEP[$j]} + SSUFF='/' + fi + fi +j=$(($j+$DTIME)) +done + +m=0 +while [[ $m -lt $mmax ]] ; do +MMPAR='' +PSUFF='' +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${LTY[$i]} == ML && ${GRID[$i]} == ${GRIDKEY[m]} && ${PARLIST[$i]} != LNSP ]] ; then + if [[ `echo $MMPAR | grep ${PARLIST[$i]}` == '' ]] ; then + MMPAR=${MMPAR}$PSUFF${PARLIST[$i]} + PSUFF='/' + fi + fi +i=$(($i+1)) +done + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} $MMPAR "[param].[date].[time].[step]" ML ${GRIDKEY[$m]} ${LEVELIST[$m]} + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +m=$(($m+1)) +done + +# LNSP treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} LNSP "[param].[date].[time].[step]" ML OFF 1 + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# For some data classes, MARS adds GRIB table number to parameter number, +# e.g. for Temperature it is 130.128 instead of just 130 +# + set +e + TNR=`ls 131*${MDATE}.${M_TIME[00]}00.${M_STEP[00]} | awk -F . '{print $2}' - | grep -v ${MDATE}`. + set -e + if [[ $TNR != '.' ]] ; then + TNR=.$TNR + fi + +# SURF treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[4]} "SURF${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# OROLSM treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[5]} "OROLSM${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +k=$(($k+1)) +done + + + +j=0 +while [[ $j -lt $jmax ]] ; do + + +TIME=${FIELD[j]} +XTIME=${TIME}00 + +set +e +i=0 +while [[ $i -lt $imax ]] ; do + \rm fort.${UNIT[$i]} 2>/dev/null + if [[ ${PARLIST[$i]} == U/V ]] ; then + cat 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} > fort.${UNIT[$i]} + rm 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} + else + mv ${PARNAME[$i]}${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} fort.${UNIT[$i]} + fi + i=$(($i+1)) +done + +# flux data need special GRIB conversion +#if [ ${M_FORMAT} == GRIB2 ] ; then +# grib_set -w shortName!=lsp,shortName!=cp,shortName!=ewss,shortName!=nsss -s edition=2,productDefinitionTemplateNumber=8 flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 + +#else +# mv flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +#fi + +${EXEDIR}/CONVERT2 + +INFILE=${PREFIX}${MDATEX}${TIME} + +if [ -s fort.15 ]; then + cp fort.15 ${INFILE} + cat fort.14 >> ${INFILE} + cat flux${MDATE}${TIME} >> ${INFILE} + cat OROLSM >> ${INFILE} + cat fort.20 >> ${INFILE} +# +# Convert also surface fields to GRIB2 if needed +# +# Note: GRIB2 surface fields are incompatible with FLEXPART versions < 9.2 +# +# To enable additional compression +# set packingType="grid_jpeg"; +# this is rather time consuming. + +if [ ${M_FORMAT} == GRIB2 ] ; then + grib_set -s edition=2,productDefinitionTemplateNumber=8 $INFILE ${INFILE}_2 + mv ${INFILE}_2 ${INFILE} + + if [ ${COMPRESSION} != grid_simple ] ; then + +cat >rule.filter<<EOF +set packingType="${COMPRESSION}"; +write "[file]_2"; +EOF + grib_filter rule.filter ${INFILE} + mv ${INFILE}_2 ${INFILE} + fi +fi +ls -l ${INFILE} + + +else + myerror "ERROR: ENfile ${INFILE} missing!" "ABORT!" + exit 1 +fi + +#check ENxxx file & ECtrans to local gateway +if [ -s fort.25 ]; then + mv fort.25 OMEGA${MDATEX}${TIME} + ln -s OMEGA${MDATEX}${TIME} fort.25 +fi + + +\rm fort.15 2>/dev/null +ln -s ${INFILE} fort.15 + +[ -s CHECK.SUCCESS ] && rm CHECK.SUCCESS + +${EXEDIR}/CHECK + +#check fields +if [ -s CHECK.SUCCESS ]; then + SUCCESS=1 +else + myerror 'ERROR: check on ENfile failed:' ${INFILE} "ABORT!" + exit 1 +fi + + +#ECtrans +if [ $SUCCESS -eq 1 -a $ECTRANS -eq 1 ] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source $INFILE +fi + +if [[ $M_OMEGA -eq 1 && $SUCCESS -eq 1 && $ECTRANS -eq 1 ]] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source OMEGA${MDATEX}${TIME} +fi + +#ECFS +if [ $SUCCESS -eq 1 -a $ECSTORAGE -eq 1 ] ; then + ecp -o $INFILE $ECFSDIR +fi + +if [[ $SUCCESS -eq 1 && $ECSTORAGE -eq 1 && $M_OMEGA -eq 1 ]] ; then + ecp -o OMEGA${MDATEX}${TIME} $ECFSDIR +fi + +rm ${INFILE}_2 ${INFILE} fort.15 flux${MDATE}${TIME}* OMEGA${MDATEX}${TIME} fort.25 + +j=$(($j+$DTIME)) + +#done TIME +done + +(( IJULDAY = IJULDAY + 1 )) + +#done JULDAY +done + +#any warnings ? +[ $NRW -gt 0 ] && echo There were $NRW warnings ! + +#mail logfile (list MAILOPS) +for MUSER in $MAILOPS +do + +mailx -s ${JOBNAME} ${MUSER} <${LOG_FILE} +done + +# +# cleanup +# +cd ${SCRATCH} +echo $SCRATCHDIR not removed! +#\rm -fR $SCRATCHDIR + +exit 0 + diff --git a/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_body b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_body new file mode 100644 index 00000000..4e864429 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_body @@ -0,0 +1,768 @@ +# no changes below + +NRW=0 + +#ksh scripts for date manipulation +juldate2() + { + let jc=$1 + if (( ${#jc} < 8 )) + then + print "illegal date!" + exit 1 + fi + let y=`echo $jc | cut -c1-4` + let m1=`echo $jc | cut -c5` + let m2=`echo $jc | cut -c6` + m=$m1$m2 + let d1=`echo $jc | cut -c7` + let d2=`echo $jc | cut -c8` + d=$d1$d2 + let jd=367*y-7*(y+(m+9)/12)/4+275*m/9+d+1721014 + let jd=jd+15-3*((y+(m-9)/7)/100+1)/4 + print $jd + } + +civildate2() + { + let jd=$1 + if (( jd < 1721060 )) + then + print "Julian date not in AD." + exit 1 + fi + let k=jd+68569 + let n=4*k/146097 + let k=k-\(146097*n+3\)/4 + let y=4000*(k+1)/1461001 + let k=k-1461*y/4+31 + let m=80*k/2447 + let d=k-\(2447*m\)/80 + let k=m/11 + let m=m+2-12*k + let y=100*(n-49)+y+k + [ $m -le 9 ] && m=0$m + [ $d -le 9 ] && d=0$d + print $y$m$d + } + +date2m1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1-1 + civildate2 $j0 + } + +date2p1() + { + let ymd=$1 + let j1=`juldate2 $ymd` + let j0=j1+1 + civildate2 $j0 + } + + +marsinst() +{ +MTYPE="${1}" +MDAY="${2}" +MTIME="${3}" +MSTEP="${4}" +MPAR="${5}" +MFN=$6 +MLTY=$7 +MGRID="${8}" +MLEV="${9}" + +RED=0 +#if [[ ${MTYPE} != 'AN' ]] ; then + MPAR2=`echo ${MPAR} | sed s,160/,,` + MPAR2=`echo ${MPAR2} | sed s,27/,,` + MPAR2=`echo ${MPAR2} | sed s,28/,,` + MPAR2=`echo ${MPAR2} | sed s,173/,,` + if [[ ${MPAR2} != ${MPAR} ]] ; then + MPAR=${MPAR2} + RED=1 + fi +#fi + +MAREA=${M_AREA} +if [[ ${10} == 'GAUSSIAN=REDUCED,' ]] ; then + MAREA=G +fi + +if [[ -f ${MFN} ]] ; then + rm ${MFN} +fi + +cat <<EOF >> marsjob +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=${MPAR}, +RESOL=${M_RESOL}, +AREA=${MAREA}, +GRID=${MGRID}, +LEVTYPE=${MLTY}, +LEVELIST=${MLEV}, +ACCURACY=${M_ACCURACY}, +DATE=${MDAY}, +TIME=${MTIME}, +STEP=${MSTEP},${10} +TARGET="${MFN}" +EOF + +if [[ ! -f 'OROLSM' && $RED -eq 1 ]] ; then + +cat <<EOF >> marsjob +RETRIEVE,TYPE=AN,TIME=0,STEP=0,CLASS=OD, + PARAM=160/27/28/173, + TARGET="OROLSM" +EOF +fi + +} + +marsflux() +{ +MTYPE="${1}" +MSTEP="${2}" + +cat <<EOF >>mars_flux +RETRIEVE, +TYPE=${MTYPE}, +CLASS=${M_CLASS},NUMBER=${M_NUMBER}, +EXPVER=${M_EXPVER},STREAM=${M_STREAM}, +PARAM=LSP/CP/SSHF/EWSS/NSSS/SSR, +AREA=${M_AREA}, +GRID=${D_GRID}, +LEVTYPE=SFC, +LEVELIST=OFF, +ACCURACY=${M_ACCURACY}, REPRES=GG, +DATE=${DAY1M1}/TO/${DAY2P1}, +TIME=00/12, +AC=N, +STEP=${MSTEP}, +TARGET="surf_${MSTEP}_ub" +EOF +} + + +myerror() + { + + echo $1 + echo $2 + echo $3 + echo ABORT! + + for MUSER in $MAILFAIL + do + mailx -s ERROR:${JOBNAME} ${MUSER} <${LOG_FILE} + done + } + +# +# MAIN SCRIPT CONTINUES HERE +# +#read CONTROL file, process specifications +while read NAME PARA +do + +if [[ $NAME == 'M_TYPE' || $NAME == 'M_TIME' || $NAME == 'M_STEP' ]] ; then + eval "set -A $NAME $PARA" +else + eval "export $NAME='$PARA'" +fi +echo `echo $NAME`=$PARA + +done <${CONTROLFILE} + + +if [ -z "$DAY1" -o -z "$DAY2" ]; then + myerror 'DAY specification missing !' + exit 1 +fi + +#defaults +[ -z "$M_EXPVER" ] && M_EXPVER=1 +[ -z "$M_CLASS" ] && M_CLASS=OD +[ -z "$M_STREAM" ] && M_STREAM=OPER +[ -z "$M_NUMBER" ] && M_NUMBER=OFF +[ -z "$M_TYPE" ] && set -A M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC +[ -z "$M_TIME" ] && set -A M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12 +[ -z "$M_STEP" ] && set -A M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11 +[ -z "$DTIME" ] && DTIME=6 +[ -z "$M_GRID" ] && M_GRID=1000 +[ -z "$M_LOWER" ] && M_LOWER=-90000 +[ -z "$M_LEFT" ] && M_LEFT=-179000 +[ -z "$M_UPPER" ] && M_UPPER=90000 +[ -z "$M_RIGHT" ] && M_RIGHT=180000 +[ -z "$M_LEVEL" ] && M_LEVEL=91 +[ -z "$M_LEVELIST" ] && M_LEVELIST=1/TO/$M_LEVEL +[ -z "$M_ADDPAR" ] && M_ADDPAR='' +[ -z "$M_RESOL" ] && M_RESOL=799 +[ -z "$M_GAUSS" ] && M_GAUSS=0 +[ -z "$M_SMOOTH" ] && M_SMOOTH=0 +[ -z "$M_OMEGA" ] && M_OMEGA=0 +[ -z "$M_OMEGADIFF" ] && M_OMEGADIFF=0 +[ -z "$M_ETA" ] && M_ETA=0 +[ -z "$M_ETADIFF" ] && M_ETADIFF=0 +[ -z "$M_ETAPAR" ] && M_ETAPAR=77 +[ -z "$M_DPDETA" ] && M_DPDETA=1 +[ -z "$M_ACCURACY" ] && M_ACCURACY=24 +[ -z "$EXEDIR" ] && EXEDIR=. +[ -z "$SOURCECODE" ] && SOURCECODE=ecgate:flex_extract_ecgate +[ -z "$GATEWAY" ] && GATEWAY='' +[ -z "$DESTINATION" ] && DESTINATION='' +[ -z "$PREFIX" ] && PREFIX=EN +[ -z "$COMPRESSION" ] && COMPRESSION=grid_simple +[ -z "$ECTRANS" ] && ECTRANS=0 +[ -z "$ECSTORAGE" ] && ECSTORAGE=1 +[ -z "$ECFSDIR" ] && ECFSDIR=ectmp: +[ -z "$MAILOPS" ] && MAILOPS=${USER} +[ -z "$MAILFAIL" ] && MAILFAIL=${USER} + + +#additional dates for flux retrievals (polynomial interpolation) +DAY1M1=`date2m1 ${DAY1}` +DAY2P1=`date2p1 ${DAY2}` + +#julian dates for time loops +JULDAY1=`juldate2 ${DAY1}` +JULDAY2=`juldate2 ${DAY2}` + +echo JULDATES $JULDAY1 $JULDAY2 + +#check consistency +if [ ${DAY1} -gt ${DAY2} ]; then + `myerror "ERROR: DAY1 > DAY2: ${DAY1}, ${DAY2}"` + exit 1 +fi + + +# determine number of gridpoints and whether grid is cyclic +ZYK=`expr \( $M_RIGHT + 360000 \) % 360000 - \( $M_LEFT + 360000 \) % 360000 + $M_GRID` + +if [ $M_RIGHT -le $M_LEFT ] ; then + if [ $M_RIGHT -le 0 ] ; then + M_RIGHT=$(($M_RIGHT+360000)) + else + M_LEFT=$(($M_LEFT-360000)) + fi +fi + +if [[ $ZYK -ne 0 ]] ; then + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED NON-CYCLIC" + exit 1 + fi +else + MAXL=$((($M_RIGHT-($M_LEFT))/$M_GRID+1)) + MAXB=$((($M_UPPER-($M_LOWER))/$M_GRID+1)) + if [[ $((($M_RIGHT-($M_LEFT))%$M_GRID)) -ne 0 || $((($M_UPPER-($M_LOWER))%$M_GRID)) -ne 0 ]] ; then + myerror "ERROR: LAT/LON RANGE MUST BE INTEGER MULTIPLES OF GRID SIZE" "URLO: $M_UPPER $M_RIGHT $M_LOWER $M_LEFT GRID: $M_GRID" "GRID ASSUMED CYCLIC" + exit 1 + fi +fi + +if [ $((180000/$M_GRID-$M_RESOL)) -lt 0 ] ; then + + if [ ${M_SMOOTH} -eq 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SPECTRAL RESOLUTION ${M_RESOL} " "USE M_SMOOTH FOR SMOOTHING OR FINER OUTPUT GRID" +# exit 1 + else + if [ $((180000/$M_GRID-$M_SMOOTH)) -lt 0 ] ; then + myerror "ERROR: OUTPUT GRID SPACING OF $((${M_GRID}/1000)).$((${M_GRID}%1000)) DEGREE IS TOO COARSE FOR GIVEN SMOOTHED SPECTRAL RESOLUTION ${M_SMOOTH} " + fi + fi + +fi + + +# convert lat/lon to MARS format (degrees) +if [[ $M_LEFT -lt 0 ]] ; then + LLLO=$(($M_LEFT / 1000)).$((($M_LEFT)*(-1) % 1000)) +else + LLLO=$(($M_LEFT / 1000)).$(($M_LEFT % 1000)) +fi +if [[ $M_LOWER -lt 0 ]] ; then + LLLA=$(($M_LOWER / 1000)).$(($M_LOWER*(-1) % 1000)) +else + LLLA=$(($M_LOWER / 1000)).$((($M_LOWER) % 1000)) +fi +if [[ $M_RIGHT -lt 0 ]] ; then + URLO=$(($M_RIGHT / 1000)).$((($M_RIGHT)*(-1) % 1000)) +else + URLO=$(($M_RIGHT / 1000)).$(($M_RIGHT % 1000)) +fi +if [[ $M_UPPER -lt 0 ]] ; then + URLA=$(($M_UPPER / 1000)).$((($M_UPPER)*(-1) % 1000)) +else + URLA=$(($M_UPPER / 1000)).$(($M_UPPER % 1000)) +fi + +M_AREA=${URLA}/${LLLO}/${LLLA}/${URLO} + +if [ $M_GAUSS -eq 1 ] ; then +# Gaussian grid detected + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=OFF + QG_GRID=OFF + if [ $M_RESOL -le 799 ] ; then + QG_GRID=$((($M_RESOL+1)/2)) + fi + D_GRID=${D_GRID}/${D_GRID} + +else + D_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=$(($M_GRID / 1000)).$(($M_GRID % 1000)) + G_GRID=${G_GRID}/${G_GRID} + D_GRID=${D_GRID}/${D_GRID} +fi + +G_LEVELIST=1/to/${M_LEVEL} + + +#namelist +cat <<EOF >fort.4 +&NAMGEN + MAXL=${MAXL}, MAXB=${MAXB}, + MLEVEL=${M_LEVEL}, MLEVELIST="${M_LEVELIST}", + MNAUF=${M_RESOL},METAPAR=${M_ETAPAR}, + RLO0=${LLLO}, RLO1=${URLO}, RLA0=${LLLA}, RLA1=${URLA}, + MOMEGA=${M_OMEGA},MOMEGADIFF=${M_OMEGADIFF},MGAUSS=${M_GAUSS}, + MSMOOTH=${M_SMOOTH},META=${M_ETA},METADIFF=${M_ETADIFF}, + MDPDETA=${M_DPDETA} +/ +&NAMFX2 + NX=${MAXL}, NY=${MAXB}, + MAXTIME=400,JPOLY=4, + JHRF=${DTIME}, + RLO0=${LLLO}, RLA0=${LLLA}, DX=${D_GRID}, DY=${D_GRID} +/ +EOF + + +if [[ $OS_VERSION == aix ]] ; then + scp ecgb:${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.IBM FLXACC2 CONVERT2 CHECK +else + cp ${SOURCECODE}/source.tar . + tar -xvf source.tar + make -f Makefile.ecgb FLXACC2 CONVERT2 CHECK +fi + +if [ $? -ne 0 ]; then + + ls + myerror 'ERROR: FLXACC2 and CONVERT2 could not be compiled:' 'ABORT!' + exit 1 +else + echo 'compile worked' +fi + + +# +#MARS requests (field) +# +imax=6 +set -A PARLIST U/V T Q LNSP SD/MSL/TCC/10U/10V/2T/2D 129/172/160${M_ADDPAR} +set -A PARNAME 131/132 130 133 152 SURF OROLSM +set -A REPR SH SH GG SH GG GG +set -A UNIT 10 11 17 12 14 20 +set -A LTY ML ML ML ML SFC SFC +set -A GRID ${G_GRID} ${D_GRID} ${D_GRID} OFF ${D_GRID} ${D_GRID} +set -A LEVELIST ${M_LEVELIST} ${M_LEVELIST} ${M_LEVELIST} 1 1 1 + +set -A FIELD 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 + + +if [[ $M_OMEGA -eq 1 || $M_OMEGADIFF -eq 1 ]] ; then + M_OMEGA=1 + PARLIST[imax]=W + PARNAME[imax]=135 + REPR[imax]=SH + UNIT[imax]=19 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 1 || $M_ETADIFF -eq 1 ]] ; then + M_ETA=1 + PARLIST[imax]=77 + PARNAME[imax]=77 + REPR[imax]=SH + UNIT[imax]=21 + LTY[imax]=ML + GRID[imax]=${D_GRID} + LEVELIST[imax]=${M_LEVELIST} + imax=$(($imax+1)) +fi + +if [[ $M_GAUSS -eq 2 ]] ; then + PARLIST[imax]=VO + PARNAME[imax]=138 + REPR[imax]=SH + UNIT[imax]=30 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + imax=$(($imax+1)) +fi +if [[ $M_ETA -eq 0 || $M_GAUSS -eq 1 || $M_ETADIFF -eq 1 ]] ; then + PARLIST[imax]=D + PARNAME[imax]=155 + REPR[imax]=SH + UNIT[imax]=13 + LTY[imax]=ML + GRID[imax]=${G_GRID} + LEVELIST[imax]=${G_LEVELIST} + LEVELIST[1]=${G_LEVELIST} # U/V needed on all levels for calculating ETA + imax=$(($imax+1)) +fi + +jmax=${#M_TYPE[*]} + +# M_TIME needs leading zeros while M_STEP must have leading zeros +# to be consistent with MARS file naming convention +# The following loop ensures this +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TIME[$j]} -lt 10 ]] ; then + M_TIME[$j]=0$((${M_TIME[$j]})) + fi + if [[ ${M_STEP[$j]} -lt 10 ]] ; then + M_STEP[$j]=$((${M_STEP[$j]})) + fi + + j=$(($j+1)) +done + +echo ${M_TIME[*]} +echo ${M_STEP[*]} + + +rm mars_flux 2>/dev/null +j=$DTIME +while [[ $j -lt 13 ]] ; do + marsflux ${M_TYPE[2]} ${FIELD[$j]} + j=$(($j+$DTIME)) +done +mars mars_flux | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + + +# +# FLXACC job +# + + +${EXEDIR}/FLXACC2 +if [ -f OROLSM ] ; then + rm OROLSM +fi + +# +# CONVERT job +# + +#loop over DATE and TIME for CONVERT/CHECK/ECtrans job + +IJULDAY=${JULDAY1} +while [ $IJULDAY -le $JULDAY2 ]; +do + +MDATE=`civildate2 ${IJULDAY}` +MDATEX=`echo ${MDATE} | cut -c3-8` + + +i=0 +rm marsjob 2>/dev/null + +#humidity on reduced Gaussian grid for initialization +#of spectral transformations +if [ ${M_GAUSS} -eq 1 ] ; then + NGRID=$(( ( ${M_RESOL} + 1 ) / 2 )) + + marsinst ${M_TYPE[0]} ${DAY1} 00 00 Q fort.18 ML ${QG_GRID} 1 'GAUSSIAN=REDUCED,' + +set -e +mars marsjob | grep -i -v 'MARS - INFO' +[ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" +rm marsjob + +fi + +set -e + +set -A TYPEKEY ${M_TYPE[0]} +j=$DTIME +kmax=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[j]} != ${TYPEKEY[0]} ]] ; then + if [[ $kmax == 1 ]] ; then + if [[ ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${TYPEKEY[1]} ${M_TYPE[j]} + kmax=2 + fi + else + if [[ $kmax == 0 ]] ; then + set -A TYPEKEY ${TYPEKEY[0]} ${M_TYPE[j]} + kmax=1 + else + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[1]} ]] ; then + if [[ $kmax == 2 && ${M_TYPE[j]} != ${TYPEKEY[2]} ]] ; then + + echo ${TYPEKEY[0]} ${TYPEKEY[1]} ${TYPEKEY[2]} ${M_TYPE[j]} + myerror 'More than three different MARS TYPES not supported' + + exit 1 + fi + fi + fi + fi + fi + j=$(($j+$DTIME)) +done + +set -A GRIDKEY $D_GRID +mmax=1 +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${GRID[$i]} == 'OFF' && ${PARLIST[$i]} != LNSP ]] ; then + set -A GRIDKEY $D_GRID OFF + mmax=2 + fi + i=$(($i+1)) +done + +k=0 +kmax=$(($kmax+1)) +while [[ $k -lt $kmax ]] ; do +MMTIME='' +MMSTEP='' +TSUFF='' +SSUFF='' +j=0 +while [[ $j -lt $jmax ]] ; do + if [[ ${M_TYPE[$j]} == ${TYPEKEY[$k]} ]] ; then + if [[ `echo $MMTIME | grep ${M_TIME[$j]}` == '' ]] ; then + MMTIME=${MMTIME}$TSUFF${M_TIME[$j]} + TSUFF='/' + fi + if [[ `echo $MMSTEP | grep ${M_STEP[$j]}` == '' ]] ; then + MMSTEP=${MMSTEP}$SSUFF${M_STEP[$j]} + SSUFF='/' + fi + fi +j=$(($j+$DTIME)) +done + +m=0 +while [[ $m -lt $mmax ]] ; do +MMPAR='' +PSUFF='' +i=0 +while [[ $i -lt $imax ]] ; do + if [[ ${LTY[$i]} == ML && ${GRID[$i]} == ${GRIDKEY[m]} && ${PARLIST[$i]} != LNSP ]] ; then + if [[ `echo $MMPAR | grep ${PARLIST[$i]}` == '' ]] ; then + MMPAR=${MMPAR}$PSUFF${PARLIST[$i]} + PSUFF='/' + fi + fi +i=$(($i+1)) +done + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} $MMPAR "[param].[date].[time].[step]" ML ${GRIDKEY[$m]} ${LEVELIST[$m]} + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +m=$(($m+1)) +done + +# LNSP treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} LNSP "[param].[date].[time].[step]" ML OFF 1 + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# For some data classes, MARS adds GRIB table number to parameter number, +# e.g. for Temperature it is 130.128 instead of just 130 +# + set +e + TNR=`ls 131*${MDATE}.${M_TIME[00]}00.${M_STEP[00]} | awk -F . '{print $2}' - | grep -v ${MDATE}`. + set -e + if [[ $TNR != '.' ]] ; then + TNR=.$TNR + fi + +# SURF treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[4]} "SURF${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +# OROLSM treated separately since it exists only on 1 level + + marsinst ${TYPEKEY[$k]} ${MDATE} ${MMTIME} ${MMSTEP} ${PARLIST[5]} "OROLSM${TNR}[date].[time].[step]" SFC $D_GRID OFF + mars marsjob | grep -i -v 'MARS - INFO' + [ $? -ne 0 ] && myerror "Job stopped because of failing MARS request" + rm marsjob + +k=$(($k+1)) +done + + + +j=0 +while [[ $j -lt $jmax ]] ; do + + +TIME=${FIELD[j]} +XTIME=${TIME}00 + +set +e +i=0 +while [[ $i -lt $imax ]] ; do + \rm fort.${UNIT[$i]} 2>/dev/null + if [[ ${PARLIST[$i]} == U/V ]] ; then + cat 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} > fort.${UNIT[$i]} + rm 131${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} 132${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} + else + mv ${PARNAME[$i]}${TNR}${MDATE}.${M_TIME[$j]}00.${M_STEP[$j]} fort.${UNIT[$i]} + fi + i=$(($i+1)) +done + +# flux data need special GRIB conversion +#if [ ${M_FORMAT} == GRIB2 ] ; then +# grib_set -w shortName!=lsp,shortName!=cp,shortName!=ewss,shortName!=nsss -s edition=2,productDefinitionTemplateNumber=8 flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 + +#else +# mv flux${MDATE}${TIME} flux${MDATE}${TIME}.grib2 +#fi + +${EXEDIR}/CONVERT2 + +INFILE=${PREFIX}${MDATEX}${TIME} + +if [ -s fort.15 ]; then + cp fort.15 ${INFILE} + cat fort.14 >> ${INFILE} + cat flux${MDATE}${TIME} >> ${INFILE} + cat OROLSM >> ${INFILE} + cat fort.20 >> ${INFILE} +# +# Convert also surface fields to GRIB2 if needed +# +# Note: GRIB2 surface fields are incompatible with FLEXPART versions < 9.2 +# +# To enable additional compression +# set packingType="grid_jpeg"; +# this is rather time consuming. + +if [ ${M_FORMAT} == GRIB2 ] ; then + grib_set -s edition=2,productDefinitionTemplateNumber=8 $INFILE ${INFILE}_2 + mv ${INFILE}_2 ${INFILE} + + if [ ${COMPRESSION} != grid_simple ] ; then + +cat >rule.filter<<EOF +set packingType="${COMPRESSION}"; +write "[file]_2"; +EOF + grib_filter rule.filter ${INFILE} + mv ${INFILE}_2 ${INFILE} + fi +fi +ls -l ${INFILE} + + +else + myerror "ERROR: ENfile ${INFILE} missing!" "ABORT!" + exit 1 +fi + +#check ENxxx file & ECtrans to local gateway +if [ -s fort.25 ]; then + mv fort.25 OMEGA${MDATEX}${TIME} + ln -s OMEGA${MDATEX}${TIME} fort.25 +fi + + +\rm fort.15 2>/dev/null +ln -s ${INFILE} fort.15 + +[ -s CHECK.SUCCESS ] && rm CHECK.SUCCESS + +${EXEDIR}/CHECK + +#check fields +if [ -s CHECK.SUCCESS ]; then + SUCCESS=1 +else + myerror 'ERROR: check on ENfile failed:' ${INFILE} "ABORT!" + exit 1 +fi + + +#ECtrans +if [ $SUCCESS -eq 1 -a $ECTRANS -eq 1 ] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source $INFILE +fi + +if [[ $M_OMEGA -eq 1 && $SUCCESS -eq 1 && $ECTRANS -eq 1 ]] ; then + ectrans -overwrite -gateway ${GATEWAY} -remote ${DESTINATION} -source OMEGA${MDATEX}${TIME} +fi + +#ECFS +if [ $SUCCESS -eq 1 -a $ECSTORAGE -eq 1 ] ; then + ecp -o $INFILE $ECFSDIR +fi + +if [[ $SUCCESS -eq 1 && $ECSTORAGE -eq 1 && $M_OMEGA -eq 1 ]] ; then + ecp -o OMEGA${MDATEX}${TIME} $ECFSDIR +fi + +rm ${INFILE}_2 ${INFILE} fort.15 flux${MDATE}${TIME}* OMEGA${MDATEX}${TIME} fort.25 + +j=$(($j+$DTIME)) + +#done TIME +done + +(( IJULDAY = IJULDAY + 1 )) + +#done JULDAY +done + +#any warnings ? +[ $NRW -gt 0 ] && echo There were $NRW warnings ! + +#mail logfile (list MAILOPS) +for MUSER in $MAILOPS +do + +mailx -s ${JOBNAME} ${MUSER} <${LOG_FILE} +done + +# +# cleanup +# +cd ${SCRATCH} +echo $SCRATCHDIR not removed! +#\rm -fR $SCRATCHDIR + +exit 0 + diff --git a/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_header b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_header new file mode 100644 index 00000000..071340fa --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_header @@ -0,0 +1,67 @@ +#!/bin/ksh + +# On demand script for retrieving input for FLEXPART trajectory model +# Version 6.0, September 2013 +# Maintainer Leopold Haimberger leopold.haimberger@univie.ac.at +# +#@ shell = /usr/bin/ksh + +# NOTE: If calculation on Gaussian grid are required below, it is +# recommended to send the job to the ECMWF HPC facility +# NOTE: On hpce the class should be ns or np +# NOTE: On ecgb it should be normal + + +#ON HPC (with loadleveler) +# start with ecaccess-job-submit -queueName c1a NAME_OF_THIS_FILE on gateway server +# start with llsubmit NAME_OF_THIS_FILE directly on machine + +#@ shell = /usr/bin/ksh +#@ class = ns +#@ resources = ConsumableCpus(1) ConsumableMemory(32000MB) +#@ job_name = flex_ecmwf +#@ output = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ error = /scratch/ms/spatlh00/lh0/$(job_name).$(host).$(jobid).out +#@ environment = COPY_ALL +#@ queue + + +# ON ECGB: +# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE on gateway server +# start with sbatch NAME_OF_THIS_FILE directly on machine + +#SBATCH --workdir=/scratch/ms/spatlh00/lh0 +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf +#SBATCH --output=flex_ecmwf.%j.out +#SBATCH --error=flex_ecmwf.%j.out +#SBATCH --mail-type=FAIL +#SBATCH --time=12:00:00 + +set -x + +JOBNAME=flex_ecmwf_${HOST} + +env +ulimit -a +export OMP_NUM_THREADS=1 +export MARS_MULTITARGET_STRICT_FORMAT=1 + +#export SCRATCH=$TEMP +export SCRATCHDIR=${SCRATCH}/${JOBNAME}_$$ +[ -z "$WSHOME" ] && WSHOME=$HOME + + +mkdir $SCRATCHDIR +cd $SCRATCHDIR + +LOG_FILE=$SCRATCHDIR/${JOBNAME}_$$ +exec 1>${LOG_FILE} + +CONTROLFILE=./CONTROL_ERA + +################################### +#BEGIN: modification of config file +################################### + +cat <<EOF >CONTROL_ERA diff --git a/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_header_template b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_header_template new file mode 100644 index 00000000..7f07b677 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/flex_ecmwf_header_template @@ -0,0 +1,67 @@ +#!/bin/ksh + +# On demand script for retrieving input for FLEXPART trajectory model +# Version 6.0, September 2013 +# Maintainer Leopold Haimberger leopold.haimberger@univie.ac.at +# +#@ shell = /usr/bin/ksh + +# NOTE: If calculation on Gaussian grid are required below, it is +# recommended to send the job to the ECMWF HPC facility +# NOTE: On hpce the class should be ns or np +# NOTE: On ecgb it should be normal + + +#ON HPC (with loadleveler) +# start with ecaccess-job-submit -queueName c1a NAME_OF_THIS_FILE on gateway server +# start with llsubmit NAME_OF_THIS_FILE directly on machine + +#@ shell = /usr/bin/ksh +#@ class = ns +#@ resources = ConsumableCpus(1) ConsumableMemory(32000MB) +#@ job_name = flex_ecmwf +#@ output = /scratch/ms/ggg/xxx/$(job_name).$(host).$(jobid).out +#@ error = /scratch/ms/ggg/xxx/$(job_name).$(host).$(jobid).out +#@ environment = COPY_ALL +#@ queue + + +# ON ECGB: +# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE on gateway server +# start with sbatch NAME_OF_THIS_FILE directly on machine + +#SBATCH --workdir=/scratch/ms/ggg/xxx +#SBATCH --qos=normal +#SBATCH --job-name=flex_ecmwf +#SBATCH --output=flex_ecmwf.%j.out +#SBATCH --error=flex_ecmwf.%j.out +#SBATCH --mail-type=FAIL +#SBATCH --time=12:00:00 + +set -x + +JOBNAME=flex_ecmwf_${HOST} + +env +ulimit -a +export OMP_NUM_THREADS=1 +export MARS_MULTITARGET_STRICT_FORMAT=1 + +#export SCRATCH=$TEMP +export SCRATCHDIR=${SCRATCH}/${JOBNAME}_$$ +[ -z "$WSHOME" ] && WSHOME=$HOME + + +mkdir $SCRATCHDIR +cd $SCRATCHDIR + +LOG_FILE=$SCRATCHDIR/${JOBNAME}_$$ +exec 1>${LOG_FILE} + +CONTROLFILE=./CONTROL_ERA + +################################### +#BEGIN: modification of config file +################################### + +cat <<EOF >CONTROL_ERA diff --git a/preprocessing/flex_extract_ecgate_V6.0/source.tar b/preprocessing/flex_extract_ecgate_V6.0/source.tar new file mode 100644 index 0000000000000000000000000000000000000000..11292f0d2b72dab936ae123edbe3cb8a88b32e2b GIT binary patch literal 348160 zcmYdJ%t=WsN!3eZpdBzUFfcGPF<>w-G&M9fGhhJm4NXkIG)T(8#GJv<$jHptz|hdt z7^Ke7*wCCo!GLy7LYQ1yT#{I%pumumnvW2~!YVCJEh@$$KE#C-z#ur(Dab!G#M94J z0h%B*yh43k979}nA|oRseSKYAbUZwKJ%fWaxst&;uoIb3;d~g)rKLb!$fX4}nmUvg z)I8_JoaEA+#FErvg_4X^1^1%V^!%dC#5@I1=1@p0%FhLhdzI$E1+h8+W*$~aG6Z4f zIfjOK_y<`jIOe4kr6v|D1efGz<S1wu87g=s=9MNERVo--TAFC;C?uvN7L=r>K%DGX znwwgbnVguT5R{snS&&++05gvar(o3rGcPQ$C^IoBC$-oLt1_YmVdlBGplESPtVH1x z&4HQc;en#XBfqo=MSxfi!aPuBfa?O8r=#GTnO9nps-qB`nw+1P0++<cfSKpzsN?0N z<K?X5<)Y)|s*sVIQ=m`=3sZaspvfW3^9k^9giE5B2NxxR0XGj)8o+cw^MOlZNh(Z; zI2y&gNVpz~-RJ8GHw(mo!~}>%B8Iuo*B3>jZ+>1$28sxg9GH2*!6+IaDWn)hj3^Gw zJW#2Oq#-gDREHr65X(e14^+xS^?}UOQ2_f|M}d^g2Qv?94#gDAJm>tp;*!L?5^9w% zp6)@e?g-a`(_b>w4umja7R-HwRT8HHWFD0(OfHDcp1uJ-p3a^j3V!~6u3RudzYte< z*B}K@asov^xVG2v_0@sb_c|UPI=-Gd!NF)cz|Dh59n^A52OO+AUXGx`2dcrvKh(*` zRUshA)!8%H)89`4tTV(FDjnb$<ml@f;u@r&0oH75WMpY+XlAGhb0S!Iq^+l42&_q> z3DxT91`&zWb9dDPYt{_$aP@=ADkwml0oJJjRjF%eVP<Y*Xr`%apl4*Nsc&p%YGeXp zA!)LO*r;u&4KY9$WHm^+7K9J8-qj}<<_VBpP;F3yT>V@;-JonQCtEK^Z9`Kd6PSQA z*imL?76y9S8X8_sx<)3(mKNp)n!1KYMtX)|cOkjT%f;5%%v8(ESsURLXP7g*T)~Ec zO!0Ej)HgQJGczzSgvq+N*m^nXdbxl-0hQD8a)n9z`r3NA>Ka1b<>{uN;p?mC9-?Px zq^aQRYwPQ)YiI<O1SJt$FK1m7b3;?85JJ6?CO8S%f)t?`2NKZpan&<GRRA>rBnwJ* zwuYcCffk6XZD?Si<?E~M;sRCU;Q{uak%^ubBoaehb=`dY9ihn~Qd1M|8BefELlYAN zoN9H=4D_@h+C4nrI)j64{Xju$VP;~0N3XFNNEThUHj<gXo-oIN!X`La&oxlb%s^8C zlr9w%6cx-26pF!(gJK0+1w(~gaDxHrQ3ZwIU|Rz?$Jf)=*Har7HOT1+WVEj*veC$z z5GHtd*m`(iH38C;hlV;x4Jgb#wS$9UnJ&mRBs2(?lU)5=xQ2KyXVm$)LLfOUtt5%2 zy?+L9KOcAh-^AS9+=Ri<(A>z(*vQ1x*p$J*(9podaJ2uAE6%7X&gBd(JdlO}oZZ|) zJQXzjbi#uj!(27FoD~!lv?vB#&R~Pk?Lo2zEKjjLS~x6H@bvQx@pSa@jB*VI703#X zK|zj@3Sd7fgnM{8dnkAYD})BSx+r-1ft}*yAL5|^3Jf;|M?V)Z%SjKcH6X~-*HyvI z(K*CF$TP|@1k|qacT@0F2=RA!4e@XdQV919@c<j*s1V}l6zT(46XM~j5EA6+?(gUC z>lzZ|>8#)u>gNnHAy~mN$W_7F-!~vM#MK34CD?%A5dR>sn;=frgL==?FCa8T0p5Iq ziuyqsdtgWUxca$=cqsV0fqB8MfuXK`&aMg}{t8YYCph{AyZHzCy1GEM`iF*KGZ7L# z3JQ)2;r>D1us{O`mv3lr2*@lKPhVF*P}>gV>JSAVSI6KG1rselZ9`MA51?*>IK$D` z71<<bM?a7e;9z(24^qGu<|u|Z1}pgZ`?)JP1}pd}1iAV;din(`g!(yqIQqG}y67pm zc)Gc{2D$o$K!OY6;9yiEf?O4XTmwTrLE#Fr6rm@~(I?b37!+oHkeGJ%_X~0L3jqnC zm;nhEa0vMMgF^x80tF}6kZ@O5KLuw;A0Lo5aJq3*@DBnroM7=sg>()HSJZ|*R1Dg# z_Y61G@eDW8fmP)}u8uxh7LbsE=6iVLL3BdoG_;W0F@6f5#)g8SrUFX4z%$%X!B)Xf z+YjEx@C-LnuvPF3H`MmihFJ*;2C&aP4dF$KhG)2;CZu%H@C-MCx5H432Q@n&Zi2cL zz2tzH=cwc9=I9LXF2F+r>QxO#T@M|9-6*&M4F5W6XlX+10h<Kn>G*{NMS5tMz{0`B zF~m^;B4(%wl{A7ejA0BDO?_h>6CEQRQ+=qT{d_=S1mn0V*ebvpXkJjZp@E?Si0y?4 zMmGfwFI^K&1w#WP9SAn&QULM5E&v$_cAOW?aqj-0Ty1Co>R=ce7$d9F2DRS}4NMgL z0zvwG^g(`rIVT7#qze+#@(YBDf|{3pK_JTwbqozmbqoy*!IqmU_<@}7=Z54?M`sN` zH*F(LkU1eikx&yLenv4bBq&lr&(Bp)!AMg9=2~;8a<GMN@HB=l?c%RsXkez`X=|k8 z2kTNPC@6S3fh={?^#uD65`hY!q@dyH1aT3J1MUogi~!|jPrp!DuMI43tf^qD00|>= z1+YteAPzM|I207DAPc}63_%)Ti5n~e@jlFHApxEWwhCr?Mi$0~7N*7q=7#2$rj{<S zSa%F^_fW7^2nq1ihjb+TV37#Y2670<CLd7F0tGvW0}22`0|jqGTSL?k2moa^H%Dg; zZ$oV(m@x_p3O+8-qy^Fq;)8OfkD-=l05rrE6cjvN{6XQT?*p?EA{GKN(#2of)5RYp zTmyVT5&`hOoq~b_$XN!K3SPE`I-UW(2$Mkuft>G&A{6eZ;i(G_J3~DKcxXTz2$ItT zIT=F+>=PdsZ68=zKs304!pZ<cwPTPwSOX+reOxrPK%tG|46vgu6g)j`O>{h6{6ln* zybm!OWHd^ef(V1Hbo124biIOtf@6@of~|s^C&)e@SjQEjPeDNe<UNSjU7Y=cH5`N7 zk>U!X3Zw)S0xrRxelP`w1{M%W1+;Vv5e21H&j1Bb=UTxOkyb5HybChd5MnoosSC~u z5d9z$BnFNX5Ch~WLjy~YIHrZ*1PM+nhK2^{4#Ft5p>9Acu$@5VzcZxRr){IsNyASE zVG+3Arb2a#wf*V@Yp_AulunM$-r<fxE?`j~*9Zj{&tT^u*AQ0)H~-KePuC!@V?u(U zjV}caP;(F}r4StH7vkX>>=~@7rvPf6ggN@S`i1yJD(HYKP=r-rLmc6D1h@uy`nz~K zE5O@$ZbAOO3Z5asFk2Oz{axMMJe@s3O&L9~c96vgcX$RXxVXA``nkF&IJx@xhbuUS zD4;h86`Wyh7e{d82GmM|w2s~UeSG}GL3$$<Q01Hy!aaR_6nsN{LOcU}B0)_+u<dY{ zIz=k@!Hfkt33sF1DN+F=L4n&}POe}h5zTuS1*b@`3qAeZ(e-%3`x`J@(Hhdhpyn{x zKxkVU<SNvrG^mLVid(oRoFQ#RU)K;1e-{N$l-8!Ne~_yJJn$95JzV`1{6IYokhuXt z{w|@;A)t^9_I32}Q2=)=f?-Yrb-X~u3p}PFq2uqS0CkWbwBrKGu;7L;$WWNGKpp`V zKcG$=*c4Ec2)XSI>GVLuPyyaBLTSZgG~zw|K#`~r5ajP3<mjsq;^7zq4(nh@8ij-e zq;(8&E!2E)kb(*q5GFOQK%F54M-(FvZFVe{LAr6EroF49vxfp)Es6=?wmvB6!A*V7 zU_=KI(phuycMVnmHSRqe!=T+J6#YT20j`dqo?5U!zAlMEh(~BJC>cWHB?QF`cn%C! zfcAv^okASJ`OwWV7&I&%;^7DhaW~JP;1EdO1qC4pgJT=qp#sM-B)p;KfO}L<k>FTC z?!Q7)1$yQNCwm121!$531s$kn*VEI}@q=ms*$BnX8eW>VVB14|6~Kj!x2>TLSh0e? z8>V`QHfIfQO)b}m01Zzq4KH0oO)U*?5NV_p;HmGYiAxtmZ@7nRkgI~HZE#>vhz6)0 zgOtXQxK{wzNZ<?rPg#&SbawP{hIYP#p?L+I9zoFxEjJ+MD=4_Q28RUsM}kT*^d1~q zxr6A;f#Z@2RSU!oxce>;d3X+ma21@PeH8@-1xT$*i*B0}xSIv7O`+CMqx%Lk*V#iS z9M*?}_>1IV@PLPd4oZ+<_Uxby6L3cc+IEKtIf5FXP!71Y18Z`6hJ(iHp)#QMqoElo zZE;ZB+cQ85xdltO?G3d}0n|<hI|kHNMK!}sK?BtM1NEs)5Y0bOKM@j&3Z4;QtHVKU z`4A)nBaA^!`3NI)aW@4GKSxO4#{gj<EEGUR1Gs{63=VcOQP2Q6NXN%e$5{s)ff}CS znmV9XWP}lvHiq}=6%^oIK2U2L)ZfKvng^)e=7`HQLjxm_=lno%WvJ`ti0~D((+HlL z0`-7FA%_$~NWD%ogeFiE8jF`<-8~dX8e#P^sLc#=5t0`{lVhO%Hcs6LFM@O%8km9% zAm}ACkSdUaVUcc(h$EynKdwl}9=Wg{IEq`1vHBDixga-#oPy+I3-IuOIY<;d*b@Ls zBFLs7e2i=gw0}d;=inX*vd<B{9r)xVD7r~Z?hz*7Y+y`OHZX*B-%&!!6mLjD{Avu% z4klQ#gCQt$f%;Q8O~nj3Y^E9-8iE3!P)HhrGY=>vF%!KZQo(_UL{N#~4CyC(27q$A zrwb&@L$W<Q=VK-cLr^9%G&Baei=cTPpfbc6<X2~~_rk$pWoT#u(hYI1GrV9z_NAdA zIP-u@NO0#Aqydx`Kt;A^xVDC80H}chDyu+g)X)svPCyv~0(lWK^kjfGyy*ujJ`v-X z;F8~5!4otH11iR#Ryk{UYAV<&ID2S-r+y6$&C%_^=p93JLW?1!rUf|PfZPKPavkIl zch+$>)NwX~gp-j@xFamY$*3zmUHrjO82}yi1UW~?*%?%#L+nHrhqw})yg=$;*x3-Q z+y^xDgRDFpsmgUW(f}tH&j3vwh%w;w2QvahJ9{A1K$L*SrJ!R_`mj*;0}BLbflPy` z3J3tjj%NUTkjgV405q<q;TfQ9s0r8V=>i@j1L^gL&vb!O6sQW;^9j*Y@Ie~qgH;Wn zs5UTG@Uk`10T~OmQ$az&%NbN=1OyoAdLabCs*Myt4PfL-9yUT|2u?DdF8&A|Ag?Qc zlZ=kHju$xjIBR(7c<Fd+YJ(yIv<}c47Q+z5pc2AE!xN<58AXFGiUw%i3R3Ow7XnS_ z&{`AJM}&(Qqo-1^FHA9f0TwpF>IG1e*YVZ?j~{^@VW<OkG_3MNc7Q3mb+Gyx6vv>U zS+G5z!9?PN+ybkszy_IP_yZD(P$yG4$iX!qdXR(1?ofi<5<Lt+PBp}mJiy`x*t`IB zKW2~{8h|{AY@MMYvUP@rMhc!Tps5HWT|`p!^aG`5Sk(r$)=a?%Bh~wWRC$6@y$>P{ zLrn8@@d4GJ2w|`x#tNRG+<=r{L9SC!0F?;dIzHg^3(EPR#G?&rG`jeJifM3Z;H`r^ zk_`$~BMnb)9UpM2hp5%mf~xck0A&(bErUpJ5Zgc=2F<H@x*$6n>}5|sXDrS(Rq(Pk zM$7TIGQ9%0WezpoOWV^AHjNIk8&bshcqxDuQz>}51ZX0;#!J`J1!*K6G(_VFnu&q< z4%9J5geO=MG$aj`1bG-@1&9QPwh4~VMueRvsDgq7qo#JaV-PI-;PXcyv%nY{L*T%M zv$ew=J>gow>&~E6Gsp%+s6#7blthS8;euUkfu(2#OPJ&E3N*eU=^mbPprT-3fa+az z=U5=;0Fd`Ub{H98u^eZ)ZfFT|k&zB4DWgplKy24FgcjhS;01GZA>rl)4k(bV5R6cc z2wbpwZG7sH4A=3}geV2+!fLpV7s6;AFHML;;HnJ`!3}BT=rO_=$@g;v<#kZA6y$11 zD)xsokBrcpM_{GMg@=(LD6kB{frUuH5bvQz9jGy8gi=6(tOG|6tlC8w02antzd9Rg z7=mg<aQgOuvJo0V>A_IL2uTHm4YnQJ7C{LNj4Bc8{SZhdMrtS+!TL>}E}ozw03{I2 zpy><Y4yY;+1#hlETL(s_3ecG-wA2Ms3~Fn*czPl0foU_rRy#oa>!}M56L6W~2`W&u zKs5(cLKi9wDn=nK3e-XcY78vcpsFDSG*msL(Dw9#7y&gG9IW6bJIDm2a={4PNJj~4 zjB)|qNH#PwSMYQJg(`AQ1xf?Pu$+q=vLJ<?E?$_WxsfHdAc6-gQu_@Srl9r&cv288 zDilCPJvg30y3t|-<W)n^%qEWDf`$!E!yMey067FX%rP>%F-B&GhdC(o;ahD1?wCLZ zKtMeQXXuy@d@_;bP6(v4VWb1fQy|MBSO=6yA)ON=q)vqbwD*9~2?=*JL>=%1H|pI( zP!<`08kivCK`F?<5F<@ELy8SZ@#L&wr~_)mf*Rq5I!2J@EJ!mba3Ko8bN$XRg`mba z7KNZ<24<oW+(aWx6F~}LCPEZ~OoS^0wdRqs4ag<%I0H56!G6Ll3c$j~-~|()z8)+D zK-wX_4sfD`IS^D{z&s6Nqk3CGK_Mgv)YSsD@O2@<19Br)m7w^;=n;Sd(-Y0>AX7bI zrh)?qY$m2EsEOb(0!24y34vCKr;#?8qp1}Vgu{1eI)aRJVLCiPI-o;@NP!FLwIFdp zfdvn15Qkv?fDCw{<PV*2M|fkF%sgU@JC7I>pGQC*Pyo3Gkzc^;nL->xgLFb1Lp>Gr zb@fbL40QA?%*+goOic`o%`Hq!j4fRZVC$Hml_6vp25C4I6q+F8!HEttf58(EB%6Q| zgQ1QwYR-bCFG%Xr2002fVzFmZl(-LpB_~Mc0oh}OZVy5UIK4yc0VfBL2OxPIlp|p| z1Ck@PLr|0ifkw|kL8hevE(So^1(bLpzCx-=ojp-hLfi#X32_&)O5~y?$Vk`O6L~NW zA_-om<Q!zAjV=jtFgUS0dm3pw2chZ&NkVjb8tFnLX;G%YBN<jIfPx>yMvZ7t2*ctU zB#RUaxUw-UDiF%iRKnvOQpA8QMvHflwXmr71Q#~YB!(QXAVrYz6}Xj9rRb_q69C9z zup|ItgM5q>wIE|r(*eYtpmg8~b|<Q07fAS^Cjw9t1#B-y3INGKJcl0rU>Q&nbcV-0 zG?{}O1@S95;eZQ9Q1i|OQLeh61v97|2G<&BIuPZm3wk&~YyhXea7QCh6G>Cc#nV_D z%+b_xK~Abr7lCa+(-CB>3)2D47BnciA+uQ+CAUtvqcJRY$Sl20aF^aD<dxpwC<M6- zQIeBeGJAp+={Y-VK#Dm~iiDI*h~_msb3v4VG8cxDAkZ`l*c1~TZ%v3PpbUX*3OE&l zECNYDOaUoIQW6Ap3#1AFnF1+Kk(EH(3lJqBQ!tcxLfrzXYapheTLg6rL<z(cR3*rj zO-PWDb_jApg-U|cXh@KeF1jSBzy%i|pf*YfIKhHr4BYMlNkVjb8tI}-f;w&B%oP%3 zs2vgnnm$431WB4`f|iX28S0`-f{cae^fc5C@kG@Ll7#5=G}MJi(xe7}B_>D#3krHj z@rH;%%r+k=^s%af#u22bgs4J|Bam6Jgy*RPl7rX?N?)ip!V(s!YzEagV0F6aDF<vG zG=0HTg6+ks5|+$BDnT~F%mldu&32eibP?$dqzgkOynKZu9`s}fDj&h+KSr7Z$v{e4 zh)z!<ZIqM+l8014=xGil1Fmf_5*%0tl$AozQyWMIT-$`8CpEAPSPwj%L6a{?#sgIR z>wt!K6>JsY^^G&4_Hf2tdw`QQLOr5>a>i9Zf%6x*!T{B1&WPFrrQHN|la99zntDY2 z1Zgc{@dG$Fg*zI9yrik+9Au&k=4fg;BWFE?4QT2;O|)U^!I_)}^%-PZ8f$%~6YdD# z(LiRMW{SH`Go`#v0|z+Bm5BNc(o+dCG}H<41Q9`oMj)1vg1(-yfu(_=nWd$PvAKz* zi8-hPV`*w=U}|P+Xl7(-YG`WWVgMUG(ABfRRBdWuZf;>}WNKt&X=Gw<OnG<5(-bt; z4y)@xC4-TUDN1(-sZs?M9-v|dQwb<1fh$!|dlF&_YMBuN&eU)v5L3{U1VP;bDSJSs z7^1rcTmZoPF(6Ygl|bDBDKjCapj!kj<{(NSrl2Z;)|=om3Tz#yEY`+Wy@Dz%m@;Uy z1G6qgI2&q?p&_Wps2vhyXrzT&CxeSCa5y0;1(lLur6@HtxP(P^9oR5X3jl09a@PtG z`Y=<Cz{3(DK_I25rh;MtlybE~f=snTJi&${SJL1l15w}!Q-EBQID>0Cs76y=h)QtT z0nRK63eMmP38KIgrU1nRNFNehnt}>lXHU=~C75oAq$#L*0qI_#N`fK;q7&T1z?1|R zq0XMh+RiABf*1>t3^LY5DIKB70bDdX2N`RlOM>i#NO~IUq8kg6gt!*mu>m=VHcc8( z#DRvrz{66Ygzt%#eL&3ySo%V4te|FiuqtRKf;4v^W})T~uqtRif~W%JBS_;0tx*AU z7qn3UHcb~j--678WfM@716J06*qH7ECozy;p$#6GnV4>bWfG7%pu!34N?k*6BMilz zs7)HE+0fhq%2P<$2~k<Xaz3OP2^xCAY|bG23ThrG(}CMe;LL?)G9reMRAVgxK<+^H zA51-{OaVC=Yz?~U@Hj(K4KdwN3!^CpE|Q@+7?#(Oa}CG^gvtYu8gP6;a(oah$77fS zN^=l3SW5-a00G3e=-Cr21JaF=H$gIxvJXAKgJr;a(6cN^2JCN)(giF7ZgztQJU}@a zS}1{Jz~KNHyg-)$>p?G$K;eSDq3MEXXyO>A02grZh9)rsA>e`y-q3VGG&Eh1OMj@F zFdCY~41|CSKyX_T)Rc8WG&Eh1%XWkfXzCFSO&9c(0ShH?DH`r*0%^*+1exlBIiPVG z)DQ>dWgTxFH1(dQ+A#G&AobL3%6j_whlVI<C@8qO`nc#QDEN8mDEN7S7~VPx3T~c0 zu6{ZSu0F25VA|8q!_^bo)YC#FA_xm~j-j89f={rHf~R`~h=|lt@C=U7@eGcH?+eD= z9OmK#ZJg1v0J}uP&r`?GOUKV!Q^%c)6D}3x8?56St`qDD7IgM-403c1aShTkRB+UB zG}Q44=Hf&M8Yws$A@fZYqI80NT^;>&f<fj4hdBlzOIs*}xCZ%p`XP%M8bN{pMa)zo zIK(joS;*W#!4(`d$buFIuy6wh3>T-5zq_ZiqmP1X1Q!<<XLyijh^vN{j+Q3O3NB7h zHw_=~VK(Z)>YAYaKYk#;D=7E}xcX@r>VRUy7DV`Ia&amsfN+$px}kxVmWDcr<7lg1 z0bv;0sw+TPMz-pj5GKgcw(20#GdRT4IoJxU030B;>Y!k;g$M-s2HUDDfJu;{pkT69 zR|s<qg2+Px3E~V5Q!7L8)C)+VyRD_ArKKK-=^1S6>8JrtQLuQ_0q@2HNrKm@LYx7Q zWgW0uP^>^=7qm--)6LO4#MaP2&p=DdGZ+*QLB7EXwjh^jfuy)NeZv(LY!!UN6`=fJ zPtg9*U{7}_A6ijDLfTMAUBl7BKvP{48ZDTzraGR+I*vv<j^<!xQ98Pw!5}^~ZXu~0 z*)))0knq4T%+pxMNW;-k$J1C-$0!19Fo=W9)>Ma%dunlV`g!U&f)c!=j-R&<DEBz( zc)CaGfO3x`DF0xX5A_NpX(72xK?CejLsK0`Qyn)8JtI)Qz+{444vGV4hJYBa#mVU# z4pI-!AE4N9G}HmbKRCmoSfT|AO<G$5@d?POj)tI=192s2N3;=S3e3+NDg@pp4PJ9( zsN;vc=l~I0h6bR}02u~On9zlw;FO{RUTy5D$z=py-v`;|1YX0*si1%`!O;+;+tHBA z2s}rQHjN2&3Fx>oL^k$;Wn)O-adCS3fzQLx0Oevx9@24*@C**Ib&UY$X-_u|JwN{t zJ=X|W{#Q^yE-KVRQj2mk^Az$^Qi~MaGILV%5_3}((h_rulQY2CmlHaj$_a7^D9|v= z4o)skSMa%MAn71iM;B<CLCGAP3JM@8NNPgM7z$B3C>aADO5jvMSTVw23s8tca}ctP zB<3DpQ10>d(s9)B#g}`Ky#(<rIQwuyqYfes4Gfy4ZD@*8&;SP(4Xpu%GR!leV20!& zPd5!nc!Q3K0Hs1d4R9e&X>wCgfTSr-1qDwx4GmvU(2`6~_Xtfr{~$dLUoQwZ63X=k zas9kCaoFkxPS2?dZmBsbDVe#cdBvIed8v7*2^?l4C>4XI#f>40*L=M}0^kC{(AZD` zw7b&J3nB!GU~rPgUK+p)0+3EfmPKFO2oeQ_EZ7uyiC}09Ug(BYa)4|E)lx_m7^KDq zIn@NR>=@apCZJ_k;KGZO6RHGKDsdT_KuaZ%)sS`?wD7V8)tXQ?xFCa_D+kW|5arP1 z25D%hE4VrO1UrKcPJ*9kq~I3n8l>P8te~h4%?FT(gmRpH{DWOJ5a&cfix-IDpw${& zl<&)gm;klV6MCi&?6@WcPe%m}H&0g|7egK7#so|`%6Xd*XTgksD+e$7hiZT|GQlRo z8z9h{7*yu@Xjv$@qbde93w45g9V2uiKm@q0>1YHCZIFa5#D(CMP4ER<AZ=JBpr(W3 z*#MFh;58Xk44P~q{(&TB0|W3%d_Uv^KR}a`P@BPi)CA=#kb5*i1k7%T6x33Xk(k<i zLi9kc)dUe}+6)aq=?`ApL5%?!;ph~s0nz}s6_nQzg06vjAXh;1ILKZF1yK0e!j(YH zLQ1Y+d5|uc6u6>-=!FV_Yz8R<9hL+=^ARQk+OP;)C5oO<;pc=x6+0T*y7>6J8yYBR zXt?Ve8tA1MXzGK^g(U??Be((ucd(2CT*}tP*D=CS0o1@ltUZDn404|%C>{(n6+9im zXJsPx5xFU7ID$6BAj#<(>KVWch8ltHcBn9vLfXp&YQlL2E5MVnPJoA}4yfS<YesY8 z>2E<o6`CIcJUrp1XoA{%pnev}qyR1jsJ(u+ex6!>URt2E3KatN5)AY}Epb}|J-9+} z8b(d55Fu=-8oXA}4_as|C<NGoT!N8eK^6u125Sds1#l^VnyI$F;o1RQXd5z+Tm|01 z9^@Mg+VRfm8*b|xt`F`^dAex?`37qR`3CFyhHLqTgCj!^l18C@s$frdTLV1<E_f3P zBmgrHp;HsqjDm#^u2=(|BM3VGF=ar{e>5{QGcd<E|Iv8#{s&O>&>X||tsv!H7to<D z^f><!Vvz>ooJndOrvNz{0?A7dAHmOt7(D=T^Z>}=a{wgzu^`|xQ4sUzplYA;6C5FV z6?_&5#C%H606{ho_52SE{~&ED1|Ql1Ij>O%bZp`135}yCG%7$2z67-z!N~(Wi8y*f zBeZh{+EfkNrayW@BQYm55;~x9xSr1lE{*APKqJH|`kc@Ru?u{BUT6rk)i-)X<LD8M zqenDC&iRI%j;;Vc5)bV-JVa-SxZ^ZOk7#sN7(JqKxF6Ao-Zw!xZxD0{Cr$cYu(J}u zJufPq!3e1u!5up2es1vb_pkw943CZ;vZw$(w8#Ky2_UZX_9#DO(FL+CEd;!dA9U~+ z=pY8N4_QPp4Rq2PZqq<J%M}z9kk45Ib*&Hw{?Y7^MHk2!1L$6cB}s$}3?R$Rz=utM zSM7jKC_vGT@FGa}pgUyI1+rTl-KXHw?;;TQVIcV!+aZf6rXYNbY|4;7WYGn(n*~=$ zLHtVcA&V%cVul<xQ)zX`q6_@QzYxgrd*JhPKnE;>F!*RhNL~dcWVDP3+C~67{t9+D zD=zcECXF7l2ren$L5>pQI1gFGQWt^_*1$OZ5VXkM#UElO(pD(wvQ+TeENBFRsnJ6e zq0^$E)!v{>ULfmaMh{U0oup&{soao`^f4GcL=kj734FZ=I1ho=T!Knw(2^v?!G_QT z1-dlH)=&p6K|vR@gGY%$ITn1*11QMR=Ij*|Kn5dOH+qO7B*+yY=SGemq6j+kPX~Pb zAT(eg6y(G^$cdG3_UIvskai91ydY>$d4R$YbVea~`yreIIlB;apdq4)0Pl2xsX&}` z2-XZa84-v2(L)p=Q$a>p>(|jk6j72GD3uw4Hbf2JfqvksALJ0E+JE#AMa`jqh$3`| z0z9Mx9dv`Q$;Ieoj2@B*$^stX16;xTGvT}VLA#S7=c$33Z3Y+z$->t=f`+od3p_^; zNrcq5U=q{-1|PKr4psQBSJ2rqV2&o}C<AcFLauK>DuoP8(6=4H!y05XXxTl8R)DQM zMOuOf?s!9ny-?CW=vYG7&<2h?FnS0gBqxB5fr52gpvPd19)bwEM*(ys1UNB|9)bwJ zLjrU-14_%r8T}vx$Iu{XPKV@K5D6+9FpqFWIRX=u7QyERz)!&hodp3pUjkGvgV-Re zVObhvDCme1&@l-J4M<07U@CTjobUiX698$d1=Ohr+Y32I08IwsIZw1RFhP2t=M}&X zz=SvmL_+-vPB`F#54_JFamdt2Is_3qKZH>-gN_=6MJ0~XdGwG&&{->xR0ccv33Muo z5!#t3A+WRPAVoJQvp^0^LgZ5TL8=fXAX6}ufDij|2Ax0+%W~+4uY^Ey2}}vZ6x5Sk zpa<}PD-&#|Fo9|s@Cg^7Mgi)9N{|K_L?`H+6XfGAoFS4Bo#+S7LG1)*H;gmqppxJ- zEHI9pgBlCbiGK1NR1%^Se)t@1P6UFUQVBVo1{8silX?&l2u=y$(@8)V`hZV_0S_^P z3OO`YpaKyr2Z}~e9AQ1{2YjLm$ShF&L2Lx6M>PwUus~%m$WE|2=t(|kDq(Je9_0<T z7pqEGG6R_jvJqw`$Q@{A!h8Zfj|gTahDuO*3vPEp5)b&m9@J9Y8Ju!4(j2J989n3> z)X)LN2F9U<h_h!#&LM};30$o873lat0(I8tA%>s^5V&g$Ij{nGjwA$f@)E2r1Lb_o z6AGaP38Whi%JP^>pk){2$Y6*msAa<FA%+UziX2pCgU&7-J;V^tab?gJ0=N+{dWa#S z3I=ClT(^C|v$7{rj|=noKS<{Z)XV@?^`P90^{7K=hK4kHKp7falLgighNyy=g_`X_ zjU>o{aL(X?c95N5(?$<51h<Js4>1H)PGC&%Xj4!JAKYjJ9rcWIj3`(JoMO=r7zN2d zQt9X+hT!wKVYf3N8j_=j7?L&U4K0<CM!mtStU;G=gYGp4tq;f9FooY?uK-=(tp!s` z#SOe}(DmL_Uq}u!7<?u4=t6QA{}3(YCN(GuVHdZXATDl4>iyDgA$bH<7m}lxhI{2K zDD8q~-v(wOc?3lZ$x(D8ya@3U_%1_&Yvav8wHI=v8zUm!5?V?qC@A2HbWnle2)Sy@ z0HG0f>m+D61h(2Y0y3k9Yk4%t%^;@`SV)dy3c|;bWzdl2=tF)Xc?3-slB1Z48FG*i zL|vW^T2)9ywlD-A+y+WRei%u?5UJpR?|+DZuWF{wLULT@jV>e)@$_?50L^D3f(Wwc z8?wX=bU&t{j<XSH(~h%;kxn@Llr4-I6c3Hjh2(Aupg>Rnop+@Gx)2n$%gPK|PC`4l zUKsb1<Gi)m0P8|GusK++TZfd7puuU_k}vSEycc{X)yo;>0uNO6kcEh#t}{pjxErej z(*T-;fT~7rPJ%Nw^15OJjH`#iZZ!p;K!)6m01KOd4=_Vn><p?AkOs)X?gtGjffsRr zSCgSwH@c8~bRoHd0(5DzCg{Q%574?=9YfIV@EV>jKA?$k$c5!P;8V0Ai5NseHGxw- zWIdjbChTr_&j3(!1GXOtk>Wx66hN0K`#^4M_JL+>keDCnzVXqO<lx{ZawWNLxT7a5 z$RW4P8ybT1IH(jrgu0<2xT%Vq@eMJq-3ApXh8EBp%L6<R5d)Sm$9A7P$QD>~K}kB$ z1OxVkp`ke_)=@0CKwmlrvIBfHwvmo!0J7yc3wA?Gkc*5U)$Hg>a@Ua1AlNxaevY7= z1Uq9C9JGd@z%m2}79wIH85leR3ym=F3RFWQj8&9iGmN2W17QGI7;6PPx{@3bN}$xQ zpa9z82cGfv(gY8*X@G8!hZL^hk#BDuFKChL=>;lAH9Wyh5NyVPB`^&E3quNGm=RD5 zL3O_owsK)~B{^-w+yWB!$fcd3ktIkFxi~a7Kvn>fC21usbc_OJ{u@;Lf(*jwWsI&Q z2Ul97E6L#<14uswH1UQ~)<8Q!;5k<KipUU8BV8~@6LiNOhI(*ugQg?MNE@aDe6c5W zZw3PQydmRWDCvKYtt8jc)w3`&GcYnWF)%i_FflQ<)Q1KhXi&$~#a{t*(}98!Vt^0U zq5)O023Xc*K-R^guIocxS>}vT0_y)kFFHrQEEPJ94ru^@jDn~`R)Y10N;G?5Gsdth z8Zp)qLzm^j?18BRCkId=1<H}&i97hBVB~8mLAJq)GmuK~bRAqJWYGyI4MWzJAghF2 zI|xpXkW~W6LuC+2@bW~AMZ{1CLv*6ABZf*sbb_xP1Q`qJ-y@ajAaB77anRs5I37vd zdIDbp3R>y~%AnvGbZkrX;BgI735i8;EFecEDC}UjeZisvp&U&mJl-LT1;7@A@2H0+ zTaf=iOSz#-e;}(Mp-BumUZIwb^kw9*LX-Gq<gh{$$0c>()Q7lo&eK>I%+b_xLB66K z8v5X38BIr!u{KNxc-1Zqie<=L6GpK-x{MsW=moqS0d-v+>e3jb6>+e<PxEEuAQynj zQb_rW$m^ra$Q2Z5Qo?%<;4*Shsscqewv}77UPcZ}XrKxR<PJnq180uWW#pg=7Ssd> zm)+oo2)Gpu9xy;OshzRcwP@-Qjdo|WY94L_YV82J>lIo%5W9>VR{uETs(-+nGT>L3 zItQ6(gE^X7=qt5AZqo7AK~wK(q6<?GzQU9S^%Z1N7;Aksw3m_V=;~RT8XB0InHriI zS(+M}n!t{s($%vturx3<v$QlZHaD>}G1t-6Gqo@`w=gv_H8Qd^GBG!%w4*Y*fLs&Q zdPd)vg|qLajdP0?e9t@PUD)vUKXkJg<nDQ_D@fs6KVjW4$TjugJFP(%*MmAUpuz{# zb_93IoRNBl;N_@brJ(ic$V$PzG9(uUfs}&wgh7l)RtjG4i|68NXK<2%DDZ^cjE#KH zu`{77ubsg=mPQwl`-Oln2!%u^<=s(mynx4zKvg!R=`gy09F|EyO&QQw1t_<J*q|m3 zO0x!3v4N{|Y`t&PY!AwO*e3BYb3RBVY@i2ZE2Q%e&U9F_KS(`nzy{W92djqURkRWS zq#D_OFw>1d!+)@CDoA-7q#jlhAWR1t3M(|golQuB1d+~!3Ini-rV6$Sc*+Bi8bU<^ zNDZM<0kjw#;@co&UG!#&3)luw%LqdT;^QH<fSkYp18Nh}1<{1WIfQ}Qgmgh4U;xE7 z1cUN{4*JeT7b1o*P@9A<h$f^9a_s<$X-M8dQ;%pux`3OI5Z8c6kc+@M6YW;}AjGZq zo}gofL24lwq(jGB2Ti@FscyKViH0X=7zU)CyhbX`?|H*z0qFie8ejj%U|?WiU}j># zU|?u!Xl!Nx<{O%rfN28*Gc$7&<oo~37z_*z%nb|~6bx`VnwsLJ#U+VF3JMH4srh(~ zEiFzhD#oi~NJ?V4{||Cm9@4dZ3JMC4n{X*1xv*c#hh)v@?SDb8u&ZiZK-X!210*=a zKgiWZ!P5_NV}~9z96kL4LPHebmnB0*{U9ZkLWqZ}f{&}8dx(dEzZ;kr>>3#A>gVjL z5aO@kG<y5r=<R<B3ZCJhfk;1XKW#&3o7FQMG`Hg!Zm8|24O>_QUSAF_62N<hz&nRD zD82j-$-L3K{|pUG6#N1eY!&=`^g(wTLL<X32rQ%v64LSugo=XZj{Sl(K_k;ThNE}? zjo$sIprGIx;HzM(;2EF`%g3Nj4d_7i(YyaZ^`T>syTa(*f1r>6ozDm@N09cYf(m2$ zT>S^Oi9R>~fvtkIrh>supwWx}Mlb#wz4#B(jTpW7&(Y7_)kPu1BQ#hcIMfN!JqiK$ zxIiT(2!{kY`USiB2l)moI6L}*dQJXLA&#DYt}Y60j=>?WK?)%rj(*^xW%S~|(To46 zd|m^%0t0usoFNB7KuD@|y<qnVj-J*4>H&KWrqddnAS>u_ZRm$>C`VfI3fnIWT0IO} zuLK$khaC@qVjAx4=^)cU3s#BPmTmw(6CBhFg`H=Cw1645Wf#;Z!G4AT=*BWo*^1&w zicV{ALe`D&BE(DJEpUV9v<4^0s&!nE3vx3waA1*&?b<&SQxHCeB#mKmT7wg0VGgd4 zg7_8nTm{sSGX(X84WU;$!LtLhshA;$%~V>Q)&S~oIXdfr${v)n13;JlK@JW8yCz%{ zGf^0VG7)T>E!=B3PJb9ZtpR>o10u*#LVWbvKhW-51zQCT&j4*hO?^;30?JFCE&<?C zB`wfV1F&f#aKR7Sy5bX}H+otFbSwqD&tvqo22i3wVCZbQ7x<_E@B$)i2V{V^iGvyg zNE_D;z&j|BHr9-u)<A{R8bFuGx{Myy08gNxOlxR@ZHqia31p+Zk0$7h1Mu+-KA>&G zLGY6okm_X=4UqH>(cuizGJ05pkD(5%Qh^4Q2Pk~NH}}DU7t9&G_RrG=`Me)U8iXtz z1P7VU=wS`u6a>n=My3j$wkDt!G+OEc9kKvwxwv?GX``k)ur|yMnP4M{I;;Wpqy_Nd z3(z(I#0*ePW(YmS0moqt+TenC^sokSfDv;*22H~p+|&TY8dCd%>W4KzhbT~XnZT-# z(Zd=*Yo{SQx)E6ky5AbSAQisB0JQiVt`IcRh15g@r6!6OyMvmn;3c7u5*KnhIe7Uq zsQn7P-UQ)D@UAt`f*GhRNF~UPpe5O$#quaBL1ts_hz98dpUjS;7HK0k+)PYWP!qvn z1m7nXg1Ej4<!U%k5{GRBN7E66INkxgvy8k2te^<Mb?qN?zzQY(59DDDA&#Lzwz_(z zF0kX0Kqm{>qMz0PmxcFv{ap1%k85xY_0-aE2JH_5rEySthg?wwE6_kG4ZJuW6sTa8 zkUR@gIeJ_JD8s|<UIHaU(4GpEybsFN*vlaF{ESpefMNnvj6&{QKs672;|KVR2yjM+ zWLXdivJ|s$8ol)o7B=7rK`l025XC03$2GtYU%<6p7GpOBY=bT2IDQ%w%#g_@jDmUe zxCU_D4nM8|w5<zLet~itB7Y6UaSb3BfZT$<xpefnhGBSI11#Y|PUJx(JaF;^&0Qna zC!j<DYI=h9BciE9Yovm!3T#ITg@AX<LCu6EG?1Afcc7U$dRzmZ+5vR*6u3<eI_dy* z3<6r$qShv$dy8S}i9W6YRyz=TTm!8BA^x}q`0)$G?6q_DL>%t`-fKsL`U*0Ci?zNQ zjK?*Aw&dID8KWMz0Pk0TcDLH1pVEMk4Kg&c#W<@0A?;~sWQ%@o16-EeE(>h8H*%95 zb+<RX)d^7oDoRFg{sWZ+pnebJ`dirO0qn2^&@OA_EzqL}H-v!82Uw_qE1l7U8%7Uq zKpH{-H*k=eEuh8-sH_1sMo<eRuu5o49V82C{=k|-_?s;tl`u0gRD!B$aJLVZn?YuS zM&q<G?#qVce9+O&aJ4!RmFPJiq;mA&1_gp=xq!lnP^kdg<1}IpZh)U9iGAP(wK3^} z7y~B$;09P@5;D{PEt)~`06A6xZD_(1agrpi!3?y67=qwuc@cYX1MI9Y;ty_sAH+c9 z!429}IJf~4Qe4o^5!$XQ&>GkQzxWTdkQ{bBA9(jJ6&I4j%pF}w4(g197IO}oYyaFJ zV|#>F&?42jur<e^{wipC4V3#~%S%yA!@Y7AWZJ+jBzHqz3JzLC3z}-jwu06Ga!?ES zb_DSLcF>XHD7q0|gm`I?EhKlN%0hA!QxHA|FFcMICJV{kAVUU(vH`@;CfHV6V_Qg$ zVk&0HK}<tko=&TU<e)l+nhVKsnK!zS9KMho5k#X4$wB81z*kv~E+mK47KV^kA@U6` z&{`2`$qHzA6p0Jc0$QJDFuIT&6ch*y>WPC^+Cdi9;<{;ZbRjvk3j*pF`zwI92YGti zqTl`nYSMw0-s(WsHG6>Bqu2gH5?i<<=)@gRo6*I`OBcM-79s&6!yP?g3p#zkSKNUF zAsCcvX}^+u^x8l0O?GH&eIa+)fftXDt|V6gr9`9AYyT7sjm$9aEyS@Z92{f=u#y~g z891nZ12r8W1qze|Esh3DzzQBuP^qK^s}D6%7e<2ztHC9c;pnx0;6fY`T+pzgX_(Vx zB{_7A0%ZammTpE@l7l95Ak)%_w$SKGa$E4CQ}B!wcwUV7mE^El2lSPvpb`k2rBLS` zKoeuoMJ$k|qo5uRsKtr2x5B^#xl;rx=-{jNK^)KlWgr^YN^<Ck6-xRa$d%;KbOu_< zi@Bg2<NiO2muJA{4k1@Hfs#99?KRXHps+?LflNVym-`|wDZ+UP1;P-lYdk=+r3fV$ zH%fr*L7tt0W<1!GC}J@Lk|E&vJNP<rh_66t6yhsb!3Ofy=!$YIH}S#Z8Zk8ujs@h{ z28A7L-v=xz5X#Y1!s8vX+z^z$Mpu+WiX#OD7jP1EhF|^&6IW0G6^A<BI;e#qF{kIF z=|EiZMC^)k_@phaNm#ULTlDk!X;45zW}Pq!=+PDB$m>)fjTBHxhjF_fB$dJL2n1z8 z3?;C8+93D-fJ}jumxzKDeu*eV3CI)-CE)cH&Y*ofptUa$Q$VY1kWGQE@r4x35K};k z5lWCN6HxV!evgqM?9PXfAR}FLNh8>n6VRr$5R?^ikcD*M)C;<P7+n%%EI9Lo1Q}|h zE+&Iq@d{pi5E5jli!KSW6Qa}8P&)*9Su3=@g6Q-#)P+cb=0VX0Y2ghP(2y>u`)Gi< zqZlk~tl(*Dgk^tn$mj)tkQ9YTN8ro>O>Lm+36u~)=?%n2O>r0%8b-1Msem*r(9;}9 z2C|$5Toqy@JCHm$|6!y#kPNuC#Yk{q8PM`GjMN5_0dKwvK~HL68L%FBIzz2Zur#hg z_Z34M*P|BzQn5n;nI6VkUk%X}<ro+L!MhzHL@X)CxC_w5fJ;$9AAJ!!w(A8I!HL)q zW6k>L{esYitdLR<RIVB7pe|w!fm}2Ns*OSYEJ$sPTJRz5?*b`-n1ZSVxi$vZ?2s-X z_)ajS3%j5-9k>jHZ?4C@Wo&erI%?wq++Z4Ararn%9cf$w+-`y9ZctkVx!r=A!@(*+ zbv|@=9VicjvN=c>YAyz=L~09xRDyClR+XT>C%Cl$%grEF*t0#T)q&Ld0l5P_D2SQ! zK`Ozm9grIMZgudDf#9+Pbj>Gvj}zR|0jY<Y304hS{|>nn6sh<Dn~vl^sB6K7!fp)2 zFde2IZu;o`g1XMgyJ$eu{@{BRK@CM`v<1*Ekk|||(#4R0?DztYYJe6+f~#;a;R1<K zPa|#TAXFK6nge&Fz>QMS71b^T$1l*-kKQkc8Lo7{Ul4TvUrB0l2`%pcBy|6usktG8 zp`p2vnX!?HsWIsOKSNV<lhOPC=y9PS>|od6P^TdOQ1B8*(1rm|1*D7lM(_V~^m9=F z1&fm&__~LHAWvUc1vf|M5dR?0D8~>_e?QPYdwvQb{_d_J9<D(O;hrHL;L9W&6+#@H zLVe(BLOej1?|HiW`}zC2h6H&!E4YRFIfG0HR&X4>|If)k!~-1CZlDVg!7L|mID+dW z1qB7iU<Dt4KX(xArx4`o>*(nhtPtww>;b;dLr=lQ)6LB_$ki_d`JR(tR3n016-Mv> z8&>!KK}Ql@977xxK=<W&Xc$_VXzCm5nCKYknCe5N{d_<->cKc}3bqQc1HinXY|wBo zi0y^A646aT!%No$bm5+nj-devgW9s7v0soyAOk~!B0V&~D{nxF6t;^7d`P>2G1xg! zRp52fqqqGj7#f(NuLAINb9B}KkM~1%ADJtFjxg}^QP2Y&x@M@UfE=u#U<PXdcY0tK zRf0vpO-w&GXdH(GfEI0<=^0rV8(Nqe8<-oKTbf$J$HN?h+&w_Ij0bq?yZQJ#hG_V~ zx^^IKAcuf#@&Rq_GK8848rU~9Q1CXiHPnGyqX4>s4|L)v$P?a%+D0&A6ciMET%bt{ zWE6-G>Mi;hYIz1gO$2Fn@du?4eIJ;W5U~)DkuLt)o-Y32lmj(k^tL}YQ1rNYY8&bq zz~d4cI0_1*xBbB~1ZXi0G?AgT?m#yoAois?)3AN#G<w^gzpsL4NU(yNe`t`WYmkDo zzpI;@r?aQ4Ur4YXxLpEi5<>49Q}7H{aB+15-!kUp>f;}-;25Id9~y#k+p~f*>>6m) z8~xlA-28of{KH*c6r3UzQ01Hy!aaR_6nsN{LOcU}B0=p~u<ekW&zxOBI{aY9f}G?S z6yz8QZAFE9cshH4oE91kF&iU6`Gy9EC^)%-jr8>M4DodI@r;6~1?{l(^m7MYvxd^e zfcG$9wxZo>9SpkE8f+l+T5FK2P;a$%_V*3&ag9)bd%_vgK=*YG@$h$17`^Qe8h?<u zM2;g^c}Z$qft%%y;8=kffwjr40JTg3oMPPkgA`mHojnlEa}*Q89DPDv!96HY^mzs= zz+DCDH@Wz`1}pgahbVYBhCy#IN6{bT8sO>};_9Lh?2oT^FnZe`EXtfUyfw94BLXx$ zwKTws$~C+}LwH770iODPnxK3KQ;A83d$<OT-u5?o+aEY(_<?#+(3Ur}tpUDn4c4(j zX*_#|E7&Taw4}{QX-R`x&Yl6N2P_b5IYS)<Zc&3BGpG(}K)Ig}abf{v|G1GRgf_;q zE8PIpRRHx?L9;2aLmE&_!@VmV)H?z7Uq^5IgY+(q5xq-Gq~sC-PH*9$?pFwsFnIGf zM56&hqd7tasJWv6I#2?7>^ZKZ2SCvP&O-|D&h6-Je}<s@?>xZiJ{+3-5!nDN96|IU z4JdaA;?54prqb$=22h8Knuj#tGH>*dh7eCbS4i%IUx+w*NW<tM4LaVM;MEp7Ud}q+ zppq9_cY>-<<kf^mpb{Br!7pfqJQ5cq3mO6(J){8?5=a=dCIGZob@Y%11<!y0BV8Xv zd%)8LH0|K&;sa_)AcR55$j}(a{d16uzbH7Q0lWcr^tL~E3I&Ju=xu*o3JQjX;G<HI z3N=GR3-sw2P;eO;K=;rGcpy@(mosQm0+hnN5P~4phL)hD4BGB6dfT6-0(_4MC;|F8 zf&vZJBL)T5=ot<EL*a}D)B_ek)f=eg0E$vLCUiyv>X8HBm73t0;?Xl26u?y!#u*JX z4RgAj(J*@3A2fGh-)8{caR6E;ji^7M3c+*tU}?~jU{G@%vQH9JX&D%zS5fdH7BrLv zDpX0`h6if0f-@v|6#;1JGHj_cl#S|0@Um>skPuWB=0?zhYYdejvthd%LFysPmcc9x zwMe_J;bszlMuRqZ{jDbMd&Iz@3RVOf;Ro%*1amaCXmv&dbl3}HOBJl_#BolEv5t?S zCN$-MC>>B3y7+^PF-8%Gq#M`~dmyD?4Dyv0L?P%z2o3lEJ@&&HMsNG`)`2Db(X$yK zX$q8%z$FRJox4Fu1pp``!}eu>_Glo?01YZ2s|00hZBR1Aol9X+0V+)(%16&;K)=@r zc}D_h4IU`EAei*C8DPaG&I9sMi_Ov7{%{t~CXg~05)nF(Oh8283|0?16#`LEgI4@` zy7)upR*VpHE1;<^kaBR=G*kecYKeSFI($1lq!@#=8&ESOyo!Y=0p(iARiqH-f((c6 zz=RyP05JuW#gUYN_lAQTC?E-lDX4q5La2Q<1IQwfTSjmD)A80B?q@TA(h?}LJu#bq z@Pq}cAi(Od-r<K)^MIP2SXF{|v_fTJ2@PaE$Q_7e4{rFv_TND-!3L#$tSUi`HbkR( z<ebd_J1ULXvl(FZk26{|4-Y@^TIg^`BMnbbv)wt!7<SeVdaVf30Xt;{p&oHT%jj)? zpyFLYK>?{lVM=+O1vV6PLIk4zqWHEy%%c<F%bP*_&PT8NgSNg$&rwiNa0VZ7gM7*Z z&JEPgh;|FKYXMRU*_&;sg?hFUcndM;VoI%$AX9Bns?$O{1;G@wW5UxAq!Fe7<rpRK zNfuCzrn*q0K$~H}IYvRj8C>f?6nMfEpqKzT!U@~}2i>EJvSk^1#D%FQ=(Oh`BW-j^ z`1wwt8&y#@E<*>Iz~!p5r?EE5?rEs85Xm58U1ux~0=GV#gN(J&B|&yVBt4B$H)TWZ zgt!*I#~L*Cj5PfM3Kxn8vqB*IxIw4m!)tQ1Ge$u5IAl*ZOcl5m$EFH)P67DLL2ye$ z2eVB8OI45~0wHE$ssbk{ENu)drz1dfH>h0!@&njJUG$SuK)wJcF{qiKhCbMZy68=0 zuu7zM3rHo*ObmB|YEeYH1!^`lw}1{MK<#gWRAUbBVLeX@qcsMqB|zf<+Mv^Tv{24O z1C1LXVhCzGIH!S}0M4{%?tm2npfH1}H-edNh{beRct8duAx^+r5`f$Sjyq@$hUIm% zGY6c(=?<dC6Q%|^^MK6(r6)*^4}#@*408}_u$Bto^9{hRN6(&M8IW#_ya|$lq*C<! z4weDyLC>-v8L+<x@*D+NYZAvfkl>;bG~Nkr8;)N0hj!WpG<SkaUGNQmpcb@?r|IZ* zfAE|CAeVcg)I1;#XvY|c#&-NNX#4x<b${T{@pKt{E6GtV=%aWgIf`kxm(GHwbU@Q@ z1GADGdKf<X`f8A)z|n+QR}DI61+?!PR2jh*%cJN<coC%A&|vhsKU)PuT|Y;}C=hi2 zwIL)ZEkOYc9<L364A+{%hieUC!?g+u3Z6LD&_{qOa?c1O(26+Zwe=C8D%mr_7+oCe zntMaoiW-zyg`DSzo+cn`yvbfkK6>4sC*&GULqqVLnV^^lt!e^q&Nt9h0B`w$rWZp) zaOMG*kSH74L7RU(!?iU$13>jLXd4b_V&4$UQ2?No+X{NFfqDuC=u4?UeFQ&k*bZmV zjDVrJf+uJ*K2oxC*6`E>^$$HXJi*!7&>ZLD0Z=-|SL=cHaez~wGx#81&j8STG^qU7 zady^mHq>!80+qGS9!5Ihjv%{0=3z{5duVt<CbB&PkOrP~K)nnXf5_@|WN}EQ!<a(> zEj7YsOt_;4blzJ*2efX~#m7*`Ge8qM6$4(-4006=gKtcNs)5*~0E!FHvOX7oeOM^^ zfe#-D&;ofCrYax+6#AY4@WTj3uloZ<IjB1i30$O3J+xLt5iv$jg`ng+x{@3cc5o8f zdiNS#Nj^AMl0z2cjV>jJCs0tX9lh=kT=I=BCHK~W7F6JyG`%!+K{c>9=srScNC<&j z%E;A#kpX%&0BT7g_C<r*R^U|-p!Saudi!T|DY*jlB0pH`ACw(Ouloa+PAJI?+zLk# z!DwkCW*v;o6+B%)2cH?~db;>S8+@RUHHK{hfr=?8Koxqrc!7Fp2w{+FBTJ0cIbaQ* zAfr89khY9~hFL*-04x+dZB4*UYgo$@>=O_Hjb{)AZ*hXe!5GvS29MW!X=2`v2$eux zdr#K#eMsf!>7@z2brEVVsM}&hm!;&;F$z$h1JvCB?TdzAON-IVa0d4>jBqcbHA3oS zC_uXh7`+V8urhq<EW9jo57AQ~enl2^HVw9>(GW7(0G_J^P3$1j3{)X_JR2+xn!^Ci z=0Ik6Q51q^*<dCjFXO^65u^}iB19p`#L=bX;Curjpe<~07=fZ2Jc|Ij@&wEwWhpsq z6$`DFk`K1){y=MZLHGPY6DH{9I$H&dYyK3#!{<;n@GJy6$B_6egmi-wD1n3KEzxgq z!nmIS<MKCX_JZXaXg)-_%@Jv3B+MT4m64-Y{edQ3LA`vW+7y(J5Y?xF5%}t5Qg@)h zBN;S(3k!Y_8#Gl7O+O%uK&w4KLoc8KBiJ4lP*Ma<^r9*oz3LBrd7KMmiX6OD1Qd^u z@C1?6Tuu(3u*J2U54Er*d{jPoB?^2wpNl7a`JW5=)d;XCN7FHS)gQSfFYI<U<hBE9 zhD0hfK@ApA;f!8rA}uEeWo$?b1a;L(2xMu(=v9B91{*l_g4!Uc%h8aQf??de2Cdz| zE3YsvUxTi^0%tpn``4h75S{QV*l1G1!xEDxxD5<S29V`aD8)8BJwa4~(i2uypjk6e z9ROY)4pD`gq`*s_KyzqtRS+Aor~(~o3{nNHPr&N1E)vIBzy#HWnk7IsgBSKeWkEK= z%mifsRR2QCWM|OYW`tj`E#Lw*Rl&V3a2saiEGLIGtchJt4y%8NUrw$Ku3R*=(CbT3 zh+|t$4qtwbtNsD!rf^4NP^4;VIR}|&gE=4@kXC<!=4v6A5TU8}G|`2r2QLi+9lQfl zjC?o`g?EQTriM{E)1aNApiM}ih1{U=I!L>~*VQi=bfp7`rvSb^-Nj$W6nDp(+RMqI znFX{`&=&pTJ(!%Qp`k6tO@A;+&^>>ci^*ZKo`y!CPK<@QxrM2bsgaSTk%>91X+(CV z30f8m-x>wV`9^39OW}naq$dt4zA%+Q%PvT53NZy#l0aP!E@YsEAVdko6f`A}<$IvJ z^gtyK$Q1NNr0|9}WSjwH3Z@dMTOi#oh$-k6LEQpT0x<<u3ABy^mtODz4sDEb3|b+< zltEe^nD=sF^!UJ+Y+=2U3!~EpRtj0^3A#E97T=&O1}lx>{X@`7Q;4Z(OGrmol7or_ zXl#L-ETb#Q5fwOEh6m?XXeNR*XF!?Ab95y+C=J0dw7P}md}sr3bR{`->&fU!a#%tE zO_)IT28`aw2MrTw-a&0hx*!^oF5reFR57TcgAJ9Stqc!BtPCe|CAltmS-GZ`3;1S4 z@|vpjxZI5hJCZX}le1}g`5yxV1OEH}42{hU%oz-gjLb}pObiT6jTj6J4Gj!N@Bbqr z_9#~Z$sPeg{_a7Jz6#DBuFl?ETv}8BTv`yLDIv9R7~)u3l969zrQoQi;N<G;jo%7f zh8P(b80#9C>Kd8h*AJG(We8Z3SVD_B0SoO7g$BDSxCePU#XAOgazVvBeFJ<vojpSo z{QUh~;evi4uI{cu3Z6P%I^H_4lSw^cqJA!}IzFL(o*_D*yHz|uRG5yBYnZR6ADD8C z;Nnt%n(yr4806?2;u@r7s1WHN;2H!K&&(@HO;0US$V@FNf>{d_%T27v(NV}vtVq&P z$jwPDOU=<y$Vn~BFD=ng$jwVEO@o?Il$w~MP?VEzpaUWeL1ZGBooEO%66R)K$51yN z1z$%$H=W$nl0-0(l9>iG32GqB0eJ<9MLL;aBE2Xx2`XEVSd^HXT9R6%0g|^hG==s5 zVcIf_QVYRynmU=qrMWO>QEG`!9@Gq&QeS^xS9eDp2<77G=BDH8?id;ztmEq%;uzo< zq~jax>+c`pq2uck;NlwM2=h;JMq*K7a!G2DmWe_#xFm+yf@XXsl9Y~*k1K5XGa@#O z4Ga`~eO$v_eLRC<3+kbPrQ_)1<L~Sk;^^e#s$gZMpx_Bsr(vb3<Ll$;=i(ZnVWkOj zkfKMhzk&iNgcK4BG8Iybit>vTa#M?o6Vp?R(OhI@1y&fATBK8uSmc~o0;2p%b9G88 z3xZ3FU=acLpGHn<o~@CICddIG8(cw#`xd7w*ea-l*$PFei7A<R>0o0O(lT>W)uC3R znPC7o!>u$gxg;|`4`fDqQDzD_kkmmw0p-V(#F9j4m@4Qig(&GLg(~SNg(>MM1uE$% z`S=9~DCsDH;sV42bDTjU!NDGGN+@e1l!AkUlysC_!-IpBbd>yp!4xRIm2{N+eO;7v zlmbFr{gm`UmMSQ~3M{bopcJH_Z)j|wV`yxsV`yxoV`yxwV`yxmV{WcvXkw&eXkx5m zXkw;gXl|xsXknmZXkn-WH9^bJ*i^^Bz);7~)B<WYWL_C$55)B1(p&|71qDML6s!y7 zgJ^6Rq#hEqT826bx`t50K|-*w^K<kCCnN=ZKSy78S3l_ei70DDd>tcvKv^)t2^v}` z3(bAOX-o$~c?O3-)fj^u55vBGpj-^gAt3t|6u`R+U<!hK{0(#zf_(f9L8K#??Pv%! z3cS1trV^6zu;o8kzH<$61ZPHY=7iXVQtYE=%*31=g@XLzyu@4u4HF%8NI0m&iU?3* z1&Kq1!MO+I6i~5b>**JwVQglgr==0(>gb~Z3MWlnLp@D>4UkWCL7vh?(&6U@)&W%; z>ZYj=(F`KB!HTsF_2B9=(=?ziRnW^z)l)Fk1l{8WD-RSDz$wmFgXA;^a=ijdl7o5G z)hE~$5?%`UjfY000`7#3#}YpmPdBhMh=3)-#GIV`<iwIx4QPo4Nll1i3&Phn1O+Gc z8Z4kHRUtSe)XhzSD)luN%sbFh+zPZ{&47yw)S~bYaP<S-jOOpA5bEdT<L~V4>H@CQ z72G_1T)DL10iO&?kD!7xKEEI}FCJ7rYC!62^|bt=5<NpxbshC0b)C$j)Dl?CDJURx zCFhssmBeSF=*)wsDg}j<e1%L~LwLOgiUow`ywvjew4(f6WNR})j?n?7HzfOzZA?!E z*;k?gQK+7pk_jrS{YrC_Qj64eK)OMd2daCK^(TY+B^n@kuwqzY59WYt4Bz5(gipaM zZa}UEVT8-mQ(+EJf>-wtCn&)xERYSz=HS=toLG{Yo?lc6)()!nh}Z6!q6BV)5VWkM zvLMwz%?H#_Qi9c|n(!7FC>N$_K*LW#FSSrl!AL<bF)u|=0o25Sh!`7~87pWilw_pl zDJUu=CKn_ZC`4zc>*pH9DkSIUm8BMyC}if9<SXRDQy3`VKnB<vnjno0r{<+(!YXs3 zY&Jkxt5BSmU#^gnT2PWfgyorO3K|-awgkvihMHhMfkgaDbHO4oA!ri=ET#$fWUvd0 zR}{dZVQXlDsI(LnGV@Y0lM_qwi~Q39V68tyr3wlG1vC$Xxv<7Bs?wBvg)C5(DM&0r zu{kphlxhn#vNRQJZNaY4RDfpvEKOTDOB>v#%tB5Lsd*_W`EavPd5C10oReRiij);K zNh(S_-83MTC8#2VY~3_a(DM({Q-BCVh0v-MgzeaiAEUuo{6LEyNX|#feee(l7kh&w z4#9~}!4*^wa&ajb8yYAmc)A7!f$t7RuPR(a99{fFP^$<~yn@6%-Q1v2sG#TQ=c1<o zs+OT5q(-XQAgohJj8sKPxI#!`b0+MDI*=~ZT!_j;<O<9@3DT<ok53cS_*7IVNGvK& z1@(ecb25udpeYj6v$M@f&C@6;%FNY(v~E0uL*Tc+f!v>$l3Ia~(orwTSJ#9z1q~GR z@{9C9WgM!C5P!G|v;>f8n~83mKD>#m0Pc|?tkN*F%G5Q~)X~yZfQ$`59j%~%)fgSU zlA_X7Jw)*aYBD34mZ@!M1@bT4K*tEUfjPFYy&d2jnrREM5H=VA30e@DW19oNryazH zwi9zSZ8PD9AxBwiPH`$+BFEN{ixbuZHq=D7(-66%4Kf_m^al58JcC0tGOaQ-Ayuuq zzB)8mIYFu*P69JwW`mu>sQ|57I3W&#+nl3qsA&rd32j3zPG~bMhl>*<_+h4HYHAx= z!8zK7n$Spr`aM&V3u*(%HBd_xU`^11qRhM!EgjH+hfZ#OZfbfWXw(GCgoX^r4WMfp zbre9#bd9t$40R!O1E|W-)P-{qajO8TyrDH4EL?OAAyqTfRETR7%8N2fQWZ3`bSy0m zOf{kXbB#<*9ficCVhy+vNJfL=49)m-P{#+-=7E^51*>3Tmgiux8`)|D6szIZ>L}zu z3<S9rWHExLpn&XlLt+e2fEVH5l3W{p^Q8hbTA-#w5(Jb3@+w$4sClDcfbI`a^{ZiM zqyy>z*s6m^YxROdot<5SgOPGB%&CS(pzI1!rr_r3=Naq)x+52&-YwL}ClWTuqM)Dv zF2gho;dj@g`X8Ed6kvuqdiuD!C@3l_BAE~z;t#vj9^7u?;!?1*G%!$b^AGZM3{lWf zSFp2#j4)e)3P8x{n~p+W5u_m0DAu%6P=|K!;iCzTraDFyI-bUQMmp*WsTBpO$t9^N zAazh7e{XeAKL(VZsAv(~R6}Yy-whmUVE2Mj7^r%HMmrbf1Nmf{kdl~`Nb3n8{PRBs zh9>4_42Fj0MrOuFCZ@*bp!pv|Q$q#?12X+YlD5*~lEfkf1%{l|e7yQfi&Kk=@v0b- zlHi1>P+Xc+lwVqsnU|^nNe~(pX{k9WI(Zd3d6ha@1^GFZn$(%Rpu?<CfS!Vvqpxc) z#A`T6(C`a3DI)^|16>0PT|-325t}lI7%oE+QxXfn#S}3URJaU*%uku=8c^aAh&zcS zsWRTB1#4`;CPy-LvY@3Lc!md@uryE-7F0SVU%|w{05T9&fhq>>rBy=36ciL7hGgnw z=@@F-A~^8M3q^?$vJzvYwgp0?F|ra9O)ii-6hK2IC7F4psW2ZErIwTy!RCHa^HR75 zuGpqpS(B2Oo0yqL+XVmw%70S>Q&Wuc-`r@l{HIzZ<1q+QG!zu&rxzvWDnL@hkSXci z^%TPWLma~$A-=#);woPaEiFxS4a{^6P-dmDn*o{%z$)XLpOTrD32KoNQS0Dx38c<3 z)-?hj7J=0sgdi?MMs}S;rDlbTYp`>WXF!Ojzn_&tNJeI{0xV~M#xIH$5|filb4zm) zOHxx5$`W%*Q;QYy(-3i^fHR#St0BmSMR87IQF^LEadKi#szO0gYI0^lW=SGw8ik+< z3J8~g$NQ5@GRw#?1MZ#T(xSA)<Wz;?)V$)%q?}ZRjMT&ug|wW~3L=~W^A6mQ{G7xh zg`&iiOrkx5@J^{haY<2XaWN70Vk&{Tq>LJdU>Z+?2*@RlNQtSiG%>Fvvm`UMSRt_} zRUsu6DW&P)G8beBsFhVzkPk_cCHV?k3W<3s-~oV=)I5cfe1-hdl7i9_@RACwfd(=J zVu6-|fq}k(nZBWszM%zZOeZU&D9x6b(h;6c6ciwa7=z3)uml@rs&8naZ)6BJ&`d!i zB{eOvG^YglJPM=~3vmsZB$e8*S_-g|U7;+ss2H@&q$sr@Cows-7&NV>kYALUo|%`J zqmYxCmzr3lkXV*ll$Z`$z>->Al9`)Wk_rx!{4}s?l;{L!o77^3^30M9g~UA2L|kfm zQDTm6a(-TMYEc=;5V+?-u><OT<>lvQCgv!lWtM>BH>oHyFCF3%B(p)TEGWuPPE9E- zN(GyrnFlfnWJpOyDtJU!Hzz;8Kt};Iw_XmiDJ{Q9p&-8`HLoNyF(;=|p)@ZiGdB}d zzU8FmrI%#D%QvtgnYpROsYRevT9U7j1S(PTlT(X}Q&YgU<(HNy<fi847gd6a&7_>v zT=W!2rP$$uj_YUUCFhi;q$;SxXLr>xq>}S<bMy1c5{uL!6J<fJjxGvrKA{n=!3u6c z{=N#HegUB&3NDTzj^HVkU@k2Mx6GpA5{2UI%mRfpFta2xHx(T41x2a4psGM2FSVjX z!B_z#QCyN*P|T&JP@Jz&l95;fj&Y<o%SbF%D9+DKEy)0dcS*iNd45s0LVg~XmV!@y zet|-MS!$6&Q7Whz4psmPV~~jo8X${wP|5-waL!KE<kC_Ig6lwZ-XVntXkH>UMFBKr z4~~}1JaEi|N^AI%g3{ttg|wWC#N=dH=LVz;p$?R66cma}@(ZAyu3^&M!P62RnNlf< zprksW{Xb(vV?#v$&%^*U{%2%3y8fFk2@;yok;nf)2?9F)S3IIe0Y`ge<S(m(E@Oox zFEU9`lLL2;45{T?j8aLaz*<<~t{KRX#5@I8XWwu)h1~p<)EosjcZIaf)SMKB(qd4J zo2Zannv|KW0801Jc2;qIPARyfRi2TVoB`>5K$~aK1|Z0GP^%5x0R%O!K-DX>RhOBk zkeZmB0cji*B!b&u(DrReMk=_$2XC@Ndy$|<KeVL|Z9ycb=9LsBf>xns=9Pe2VIWIP zz^zJn-vHF$1Ghj567$fTTKK{o6ejrOiISsMTMl9wI6Of+2ndZ9>wwE7$N(~IEEhbm zTu_;)Q&5?tQ&5?#Q&5?rQ<11sk)%_RtW%K!YvYhI!kmaSt_(kP4>Ycvgd~A7;GB#k zfildTf+S%AbF+eiLP2Gstwu$PZbhQDv7VMjMUrksvZkiKnI5#w1y+(|t5K1xU6H7% zZ=|PNk)&&>r&UmysBeU#DA^XIIZ@XfCaG%#V!`%0fDKBqtw_`bX*JQ)EvQV=HwID3 zC<Z}-Hd7}{)7Ao{KT+ERL?vm1O-t4;s7x6_L*sO*e+Sx<l*FQe9{)EsG%-SN{~4N% zw*TmoG$5rfq6?`2Nf4v$KLcF@6J0|CNci9-an+`yBl38Ijj$vrV5!^wb8}Y!6?bW% z?G&g@z+C7=4s1XV)&kT6I}_xR(WV<(ZvfV+qP*#b)Kt@{NKDqLNE)n7HqiRKibTDf z5<LSwO@)d?TLYwa7+5k1E}4WWnGBaq#*|EfOQxVmRwRNHn`%`cHRnK9X;dU?S0rod zrNbNpY6WUlB<n*Z5Ut3HB#?=wS{2C%F^CCC+7&4X6OvMFE0Q24fF%&Bky?foiOJfa z2pTzSB<NBR50E8kB}Iv8`2#urXKY|@0B!%7nVOjynu5pwj7HmkbV(7MzWy$uKCTLG zAwiCA{#;y~phJ!wJ^g~YxVX5SxtuvYa|?1(b3yY%sYRuE=?W>SMGD0Qso9{xiPSuW zkfOxA;<WstT<~0OF=(12KP6S6G_NGJNFgk>s5~_<r8F;{%b7DJwOFAjHKnvFGqngb zH|d^OT3oDNoDABe=AKznl3G;E<;=<Dtl*Sdl$xB82e%A7|6QJ$mr|^dSX!(QmS0qo znVeYynyX4taLFu7ElN+#tKxE2C{0aDElST!DpAM<&#Ng!`1&cNWTqk%>3}9_$}@{n zz}`rK>McoCaLg-7&CF3qNiF7bRtN{}izrsmhzRiTv<*$s0n=eAnhI5=MWw09+3Bh2 zsY$7MI%pPxY=S!uY!jEWLTXV)VrmY=MJcIy3Pt&lDg4x&oYXw9O$r(jK90V&VMX~R z5Sw&Ei}Fh}^|+iBf=hFAL7@fqPf}`TN~#Wqf$6EmiMgQg42Fjjmouk(c(7xbt3qaR zi9%{-o`OeaP8zrfS4b;OEdqy$n_CE%GiQK8YF-J%g&^lA78mDNWrD0s%~SA6O;62B zDN2Qoi>2x)cz}W}HBZ4YDJM0v1QM;jK8_)%hB)R`C1!xavPc0EuLY%f*(Kn~LItOy z)Xb99yzHXXOi*lt_kb&aqYPv{JY6X`mZs(8rxt_KKw_Q_moulIr-H2lvdI{!2gw$< zoW#`Rj8u>|(9IJ#v_ahhHr*T5bid59)Wp(aE(I>m;83R^|IiRmKUak?mk|HZFpUUb zKOIn%fn!St64E-JZjKQ;0Xm@2&;k2O$Iny8&r8S8Ta$~6ixYHMM}S9&zk3iD7bof| z9h}gE8Wa>1ymb8F+MuSmyL<Y%X!v>Q8)<UERC02HtkLlE(ga(pVQ8S^=cUQT3ED)? z$;lbv>!)F0r2%$@wxOmLlx3u;YY27@R9yf<kuhA6iKf1h4%9Y?aUKX|MsQ`unqc=p zRB(a<Lj&YpZ%uHRK-q8yL4rubLd(xf+t3u*cm+<*VCNv6U}sMqN9Q0NM`uqR-%yYU zhy<}gqQ0Sy&Yn=i6cmC&bUZ`2xHusJ1Kzm9>Ef?oq5z6%h}%KiZ$KEdjRvC3OVbw0 z&^6T528W)PuAwHE3AniP^b2+6QdIHx4NwSh4081GarFV6=N|0r;R-4nHC!V79DO~V zHMu|*nSw1c1p5MHfr2yWM$s^r(6Hc8Ck-zhe5nKK2H4$vS|Eo&;~5lu;M4-%WonA< zE>}MnWVeArBP2A)kBbu|fssVH(2^}NZiBS-w7^cpnv4}lNXFhezBrPyj*pLyk57P( zkB^6rk54d&4I(^(iAvqz&KPH?n}4XYhJlr@V}xU<o2HI0ngA$t9DNixIXT17RiX(% zR1Ud3;~M1Xq65k%q+}d7M{t;dPTkPdf#f0u1ujl5PLOE|whCs(X67d526`?AAVIKd zO<M>Te7BE+pRFMzv4WC4NZwD=Ru`mM-^IztRl`pcN^2Wxav2&SQZN@MB#*cR__+JI zKuRN>01X2jFHIc}O)gGQUNcqzmB66#31qmBkF5cO4uCN{APg6O1tSGt(6(5FQxt-o zgP;yoP*4bV_C#<Tk!2i_Wk3ZCk}ePzNgt@lL6Jq#>*Et_>*E7*pn{K20Eis`<#>QN z9$=2An}(5=uePC{Plz5UpKEw&B5xE_0QuTb!B4?f!588c9V4(lP!bOcu>}?4Mp`~T zI^LREkg$f!dLm@CLFdn-%Lh9LDcA-(2Wcw=g=ht6fN~qCb^sX+2_KNGr?!G87Fn>z z6>Py2Sigscj}JJKAlg9^o)CG6325>@KDItS+6bTc_ypMc_<*hq1r^93GkknJY<+w@ zw2inF454D6CMUQIhVsFN1cNq2f;1?A0vTioiU`;cBoR;&g$AcKG?`K@KpjB=>WC{q z9i2TDY#p5;!GRInpoA3!3NToNpamF69vq;-P!rJP!C^skfMN|%$gXlw*n$lU)`nz3 zU0+Z}g$RQq2}!~jlr2F44-ICx4kJx2a5{vPxJFvOnzp*WS{lL5p1O|Co)BGdIndTt zuw;;~qjL~M5>fyoYt)8ogv%i`YQr^xt%a8K5bYYEunW=!B}u5^2x*WBx?lyKU<FX8 z`NFNxw1r3qX(Q{0OC#wAD*#<2Y{aR6xVn#%lM`011-bc$289G^fHgz+FKR*CJXWAW z4%9Z(0JFetGH~sx;iajAJgo?BLxC$_Z9^*v4J|cvyftmXMuTcRAIA_4FVLP}bj!hk zPLbt)p1NRrb)oiZ8(P7HKu!Q#faV0uFn|Ow+3pDN@YDc10$U(J%tmtpq-udh0VDxX zWIfE!ID!FU1F9pqj5(2NJ4l%YzZ?j}#b~5~8)RJQecfUOchIWn)I3mkE;TbRwOAoI zJ25A*2-5LQNzGMo11(zs_fk1wQlL(5X0Ad&Mq+VlUQuFcuAV{^N<UShJhcea^#t{> zK>9%)z|<lxXHM_@+=Bc(h;^Xec}9LwW>tP(Ng}9gisTef+5|W36%tF+6hO|v?7Qm? zyH2M9sQXA{uM^yd1a&~D)zu8}a1U~H!Q0jJ0GA`Mv<@j*;JpacwmQBZ=V((M)>WoK z_ZF1-6+lg7NJoSC?k==}j@dc~H_pLDB&b0Q@A$&|qu}1?XiFP%EFP$F13Ea{Ujf=Q zB+$|Zw=qC*hTg=6OHi$C9TcL4*3tvDL%=OTSX&ZJ9^7~%x+MtpI=!3L@PNV@g2SRQ z4N4;r42~6~mNRmj4$*Oex1W*Mg(*P0LP)y7&1>lR2BeV-Za+gB*ZPox1R)J-q=Mxk z?Q57kq_K#s9o)pmkVa?+x3VGfT%4THCJw{^a2p!d$c89ERsk{t(vXI=v*BuxodGcg z+>#E`#8iP~3RsONR1KCv1XxQCY&xv+8*OYWD3IRc7@Cc3P{#|oz0C<335JaCLWg!y z26nkXbuZSzQb;3fv>9Fko)8+Ob3X&$40jF<A=D5Don#ChKu2zfgHI?2&j2A$0MW2D z4sr+BQcu{-5Oi7yTv<VDj=?r?4s{|YCn-}+;JFfTrxZNf1m=P=x}y&#C#Q#xqc7;> zWl(S!Y3g`@N;=47fevUI4LWTFtu;)vK<74VgARZP&y0bCif)Z|*f`DzZnA^sa7Nqf zkYqR7UPqp705`6Q?(*On{DuTBhy)vn)Z!j(uS0tk(9u=oRzJ8cPFi~%X&@BTP~+qT zk4NBXw1ev@Xtx|x4ub~8vFL=j4z<0HODiavVc5lA!A!x^)<DP4Qy2MMSC~BL++0UL zH*HTnA6GpEkOQETbT9?TG-w=D!&BQ3bdL&bOdeF*YI}m#5+JLDu|X?`5IP{9(7>m~ z75TV*m?<C{m)*J`H<RH2y!s$BMj&fJmn6W;Bs|S-$51!q#T1~L7<ZG~IWz>L(OraC zqy=8(1sY`rt-}IsKvmEP)d|z&a^@Tz=0+Z02CtbzTJ;27&qU(dDmu5XLCgCRlQT+E zbrez(i;F=7coiHto<VaS3Z=OUhM-k$`KcM8g?WgDV3~Oexuv>6naLTTrDqBmi6wey z3$#Ef)!j!UAXvvGAlStRO#14$c!ueO>V)Yy1-W{Lxaxqe0)e&FeH=q{9Ce)Fi>@@e zIKhPv+6pcB+7t!Y0J{$4G9~a-8E74r4`|H<s9mYxsNv_WZK$c^1ffAW!O=${AXvlC zQxohUA2`bw#DXet@eBhuWW6<YLSYQJh--)=R1B&b;uX*eFu1)go?#(|Aistf=>+&Y z=>&xOfvpSCarO^(;^KsOSwTSoytV=|aBK@2Hs%7A*}+b>8islXx=@3?G_~L?P?)&* zD;O(yg4TaPCLrO4fyxME>|^T#nz!fV1UtvpK+gaaq9BeDoC6w-^#)n(4U*#w@OQFx z)bQ5ScGB?H)CvgJ@B!J#$r%vp2NKsd1j~RHvLWQa8bPKS+JZ@KQ1F4*N@xUx`soJv zJ3-9IOw<FHTYbt&vv%t=I=$iGb7b2#<gaH3A!Lq^;qk0g6yvkn^DKgI>&`r4gzD zwiKM&G<-C*!w`I54IfQSeQ?+#%*D=voR$lggSd^86BOehqiuCTPB8?NMqGxRpt$l2 z0WX#Sg#pOo5L*qfG*pqMK0KJfDnJWnkU|@7FpQxKHbV>INoepJA=|^r$q6>m7NQW$ zMw#(MT13YQo%TdumIld~T%26aoS>_d92JrvYkX5n6u`$&D`e&>cvL18Wu|23=NF}9 z<|US-<`q{Km!#%`7O4h<7qWs@9y{fyfYzjzCTD}D+(0gZ=5mGN%)AuvI0pKxCelPE zXp++>KRvN1vm_(86trs`v<MYpCWr?uEfD4*&59z`QKcZ;5{ng(WnuLdmoq0M_duMT zSPYxCEmA<9IE9wiT+W=3g}UI7&_P|h2M#Sl1sY@`5L}MAdqPr>7N>%apSzciueZ0R z0w^7Da-k19fJ9(-z=2vcIzBpn?w&ARU^6xR+(9dcpoI>o40A^mVlbw!h98LOsNw4k z$|pKbPzF>NC})Dq1-S%Nw7GkN9i<Zn(gtC=!kJJ#kkCW59h?s^$~T<|ok(Z_2QGa< zs*J%70Cn`aIME6_cQ3L^J5EkcVhT3Tun=Pn(27)OsRt|Qe7(sp>0APAp(PqL7C9qr z!C8=`!iSU7(@n!0v=q%4xqZvY838Vp!9@=zC%EwmssJNwQ476Du-%YWA(#mYW{jfO zB>-G^azYA!Sn&xx*B_EBAyUTR0u{ArgE|4G4D4L@5IxuhS0Gopf(uvB+CM#0EsX$w zC+&bx(4xZttw?x*jN)!>4M(s|pu$a47gWc9SfC4|pf{RnxddqW_`8GZ41G|Y0jV_L z!N7@RBe)&|6>FYu;1B>g2*iLZfiScUKyCvCk1?o9gEBx?a-o*q$ZcsN3Q%x40IKUj zOG!|-Y*4mMBptMlp0?Y62;To{WMGc8|Jx9>|Hr^|bpH=!5lf_QaK2N3rYP{Gm5?k5 zUg-we2Lw@qw8-2w#1X7gBT5In%><%D3)a960k^h6x6$bM`|1P)!+P!D?zN7uV}uik z@X-PFgJC^?@XZ>qYcfFx`hzV6?V1P*2i?d9u|feP0Nq9bRsa@o4+`-Q@IX=l+sgz| zg4&jcDueC0u(E<)iwat=4!U>&Qy$d8200k!YN%5|>!_h#fLt<&sS{M~fhu9}O>IzV za4iM81``}|8c2iB5ZA)xp>-fAxL`+yz~!Pqdomz%%G$_#H$a;=uxbbajfTVSYlPku zieaihc+4DK6{x@DLX7rMY>IRg!mtUW2Sz|JF{&aAbs~)5_vwK`Lq`GWc2gY%7f)YT zzhF;)KLrgd9V_rnp#eGpuuCb3(*WAP;T++M<U%}_fUWTH3-I;R0h2~LuyjbkGO$K> zNF3{gyL!5NfIFhZ*$VYqh`WwLsJo6rm^(?@T-<dOKslHsO^~?~;<SMM25FirfGASJ zG9cJp$HUXd4Ys!&nokKu0jM7i(*i!oFu)0Pw<78tiRO^|tU$ROmi9qcDy0?`fj3@j zf{!~?P**@I=^(~fDYym&`3EV0j09cR2)T069Del)G+3Y(gNiGt#h!jnp>A$EUIC8I z-dYy0`;~Dx0CZyx=)gsME(mgUbU|?e)apq809VjuVd^e0M}aH>UE>2)03L<~xy&^} zLBliH)!9G?L>hugBb}&VS7#$I+ZfC?2D43|CATxAXo8X;wI(`V0ik{YI>;W>@eKD5 za?t@hMF(U(ERa3j6f{75JwI1H15E|cH8Be6!Tv!(kyen)E}i{dTtW3sm}?L?^MXSg zev_}K8`!}{8ityXi_A=5G3DkM;^<=qJ)#qGoI_@w0yK6MGNG3iYboUAmnh`tLHb^q ziFpd{MVTp>#v4P82T$N?!y2AYPeab#)X)N7r~~fAfeZp&JFMWR4h}3M4I@n*b%o4g zuyx7#xdn+Oprevu5dytH2x<iQ@YiC{Z8o4YzKT*|$4#h1Dn!JUgP_oY#v!!*4RMj5 zyO%B0rLcq#Eec%~G$6SZwBgPjvg6Jjw0{s5A4uvT1rWHS1uccZY)qA)3<j3cagOlS zFwp{4YoN{{rb_U(LL7CI9}af}1c1!eH_|b%(!j12ehC`F@wjJ;F&*Uyy?P8XFbBC> z4bmuwgeJ&)wxA4Qq+w)iWn`@F=MLT<2$A)3_p}WT_0<5W(u5r_>ki`C8i7IrCInIk z761!EV-1mfjWqR*bPXZ5wLzQ!>5CyEJ3PoU#1)!CpotrDT`B1NH^|v_;0x4?Vb>&S zLELNzF<M7mAtgT*k^mFai&7zH0ITajD|}Gu%u~oq%mrUMhe($gNetp^M_W)%H_|XP zv@$f*hB_GPDJQrbR6-l9$VdyK479NXsuB@jpdC%Pwxuc<Lv><_XK=*|YVbglJA4x= zXhSP5^+qIU2z3XKKR`oC6I7w12*8`82*0>Mv_O2T32Gvt2w>9z8juDV3mF8444Pn3 z7Z40KNfTTPg4Kie4?8P(=4FCTXwEFoOf5>y1MR~G4=SY=L3VVzxrHczhNNJ7wo6d9 z<#Rc6f>-V*7DEa_@UDC4=4`Mw=*D)1OpwWWNP7vmI3o;gbq&Fr0wauUAq+@m;uz}V z>aGE9lj)$fWI!bYmm*~D50p(j{XD^$2Q<K>$%SRBZ9tG`m}7{mhA(7~truu?7*tkp zK_?JFI|tnyAw>hsGSCj10PwaNP`BO1U%}VbKnJ1(rBSSJ#Kp;}pb!wC;icoNX&a#7 zs{<O;a`kg@@rOFaImk1_)7jAnW}UN}TL{F(AWNX7siBUSrY0v;2dEp4(1mOkNCs&a zF|2S_fNoTAb#w_1aCHs|a`e%F-ra1Z4rx3>ihdnK9YY-reM3_teN9a+NEm_^su>v? zYk;!?IAy@LoulqJcZUq$A<b!n+ETWz5dj(?2CQ6EPzVTiw*`qn&36w9@PM0dqyuV% zK|HM!5CE+gz~h0?_J9^RCxRjqJX&ao)tN>_xf5DSC@6qjV;d0ct_xxy0u96i3B%Qa z(_RpkP&9;>iJ%rd#D%a@MaLKvqQ(X~hQ@|EhQ{EKb>@U0T>;Bd#R{RipfOy~A^f0? zF0ky94xVWP4{m|2heZdtMAI>Z7G0paCDa{n#6ZgnRL=x>xI<T%X&9gy2I*bvM4<*d z#B0!Ash=CDYYOU1gL>8AuBj#$7goQ8k>NL_0$nGJQoo@XMoqsJDTJiv7Niy>mXsDL zzzRAa#}IuVe?Mp`hbPDlkm4_dY-d60Ogy>VSRH&c05tZ%F$K-&rl5?DCCZABCl~UN z<{n^P1h+%+Bu*U{;-U<cU{DTSLD`6gWzs|eY05-_3)VdVJ1aF8QpG@>1ubAeImXci zT7H50gwR<VSjvW#HagHvO^{H6jh`5TlQfD8!Dq{qWM(Jkq^A}qXMj$J$xP2q1znE- z%DJenfJQzz??Psxz{MeWdKBgm7k8adcW@eqw28rWI?Q>XIt(&T><%emVHp`T{|q)3 zR)T`c9#H2RUJMXXe!>icB_S7o1<-^YL>TIJkQ`{O3S_7W(uOq9gw!d)0dAf?A+AB7 zMXDNBI^LSlio_S97*Xm&swt3BAPjalqVNHE*oExm@63r5J!ScM3jUzmWg(dnEiyR4 z7J~=0H9$2Da&o{P3&_C_2@m-67C0Yif{vyDn>q}l!QYqcNPvV5Xv32$tf>k~=;*-= zPN6Q~<R0n{ZG1%d`XN$^3&Mba0NAlMXpKBbo&~i|L8(bW0Xp>y;ec8}NaH9V3mrp) zgJBgrNE&6#naI)VQDxK)f%Kw+4AAk}w44IMfB&DM5tjKMQ)AQ7`~RpN*VxR1WLH>T zgv_Ks%Mql>7N`iQ@&wNbIYR}IvN){hbp};|ZmvGCx&(Ciflic8IF=5CuVVy8%N6V% z7f)9O*r8i)u^vGo3a+5@w?cv({emI4NrT4tL1IDB)(6PKFvlQIM<*XwKZP)VUxfe< z$6!~#AjeS94L=GBF0OtG0UnXTp5Bf=o}iPR{Gd9)DjY-I6ud*-U46X${exUQ{TxGF z{S;h6gPc7;XW)U|1oD@Hf`Y9=aDb~fsQc#a@9O5}8RhBf2U6_mr{Llmq!8rl>EY_< z=I`U~3N;_B8ALco7#Qd{M;I9DI7b+Q2m>P>Jv}`=kim|jZr~;lmosSPO@uEer-H2l z=vWC)*C14TbQSVSi%`#WgIWX%0<Z(Y43J}dT|->`gZzE`-61|!fQJy+9`Fnl$VcJ% zMcJT>5FCq&5-XwO3HhZ(pkv_Bh7myiP>50hxz5Mc-PO+}$ki>>&l_}KUU0Z;P>3r$ zxWL{4DR=aXa`f;42M#t5K^+fD3Lw=A$jU=qgA`mGgB9F8Lqc4G6r5cBLPMfJf$ihy z>gVnXi$Tzg7ZG~>T|+$GLAoIgJh*Of6GA}&*=Dd%Flau>RRNypJY9oA6vADDTtF5> z(?5J}5j5SSpy8<Nq2sR`1*#K45lQS~P0+D}C`TiLqX*o&2anX`K|3+Uh;@jdCJ|`L z%t=$nGuSiA6}%Q2bPyaUFhJuWpo0_@6cpfT0Tx{W{yvd@{=TjXZlKTwWg!JfctCvw z@`#p&LKN6=yd$zu4bTWw0Hrc#M;|Ri(44G`hK7cbp_!JEp}D5M5oqn6p_u`Ev<op! z2TJ?6M(T7R4PaQK1mrNVcR()lL6bz72u{=*7FwWi039|5qCscXffI-V$Pg_Hg>aA= zPMWZRSA=fRS$iNIkPrm*_#yf@K@y;qJy1`Bmz8_j8i6|BPM`rM1(1R)O<NEJ8aak; zL<Fx32d$w7O>aP!?Gba%9K=%4kw#_;KHycCu3@e|P`jahOi+0XI&scN$J5URG%D|> z1Bz^D<B_CN*AU%>`MCuOsd*_1plj7~a#C{?Qu2|eUBL^xAx;Ff<1p(0E*#YZm7EJr zaif(4s2IjprYek960Uv<gTImh51fE9E$-S8lFdNHmV$GHZ?J|5>@-h9_{;}P(h--W z4zx1}Y8!!8o`7cXK+7XQ!#<pxG^nIFVF#5epjT6%6?2g63->lD6%%c%C0Ib>K0TF$ z8VPI|{>litwm|_@RwJrzq!@=*Q_ylBt{ilRqGJSPg*#LZ8pEy{ptw~4Eh+*H2ZI!W zPhE5IS1?roO{#$EHhm+gCWuYoWMyatjwvrqO<PdJXn?CRO>ILfC<7|116rC7(gq%E z0qyE?3kd?*84Rg*G(dACkfsQM<IWTmK<U|01Kna!J5U#5DbfL4NTN8M;0PP6g9JJu zmw?Vk0UhUR0^ZhOgveHq6HGWk0qLpZrD+QeA5Tqf=Lla%4d^j)3Q%cKaB3UsB2?+Z zRGEO<@&3@2`k)XqRX`jO2I7M-I23){LxMnaFOa5?j*lj&E=P2j!0l*oGXv3lLJZD0 zNBF{p@r}Pg8w>D?Spj*G3$hDvTMlwC2;*w<g5*FLmQ2A(1{6TB2Al%Y@+?s38dyQn zsjeZ^dm!B)jA)KQ!o<o*O9Qqnz)%x1`2=cJf`djAG}jE$1;U_AM^fVzG-~DOgJ==z zI0xxCdxB@K;F$#4uvKsk12_D^g|>o=r)w~xkLu(a<m&9<=NbYMSMYXo^DYJ@Z$B<) zP=N<I&6JZ9bQY!o)L2m44!kcB><Or#f`YfNEkp(ACU|dOTW?=&#I8lq_%CStjkm8R zXt$z~mM3KW09?0%f`Yq$h`)j*Tm-UY1QawN3_d*7%hnSzJ`7i+pa41v6`AV^bp=S1 z0@&lWzWy#6p4whIMw)uAfqD=}LZm(2G(bUv=@!rlr^X82w%)$r2u3P*I6)J#;HkZE z(4L<t4R6pnz=(tb%ABAQBFNS`2$b<OjI=yK2cd$rz}*Q`<Z0{d2~z|)4;8Kqa(6Xm z##2xLuknVsA3}mRL{ZJHpmeWosOzn%1$PU`8XQi>qS^$c97~a*pn!-{Q?MFv9s!*c zt7+>T1P>f=@#?1m5(gcw;|$#v0@eZE0*#ceK<9jd4*-RV8G(Wxx$FYz0wrF^L9QU4 zA)-G6;({<r@dI`ymNJIR8FZ-tNI6OggjAF0gamoI2ZQSnNHPVb9Uo99*WFJO(sWQj z&2G>ZaB!%vud9NuCuFS1SHaCKMAy;B-9N}P#KSi<7#cG8OD~j?N5jC%2-J=A0e9lS zZbrz1Ye`VGqzQ2_=&WDI2p?DyMks{TMv%iNV6w0x5?b+thYJ+^{DXWwU4ugX-1YQe zcgjFC8-gn#P?r_#6sS)?MW`X@2y7pSH272xkOFu<1F103w1pX>Zv<PX1g>{LYaHCb zhJwp{uqv1X!3x~mLM$yol{=(vhxii`F`y+1AkXU<>L3CKB>|vy451N>ZTKHD<cMu( za#V~CA&_2Fl3$RKM$6%U0{cHqjLpqWk@kNWf%box7#WU^|I;D*8NlTleE$a|GeS!k zJmddR6&OQ5CZO`d4_u&tN=RtQF*^DWs*XoT|3ib&r!$}xI;buIC&ZyL`VUS2NI3-T zd<9(13y42KS%T0|52ED&?s$S*AfN-1pf;jNJ3?9=xTL|Gi(umbbRFyg^?J~}Ov*41 zxC@7KDLAM>=mZ+l#}*_=V>igh`GWeG;7J`=3kTFwr1ES6tZ@UL8^9Q~2hAXWPV7}s z-~<gjpbW==y9Lmdu5SLJ@G%uodI1f^Xd8lt1;8yd$OsF#(+HkW1+7m7t-k~%KMWHb z!7~EjHXdk91u>ukG7b`YT11!%?izs(f503i;e-x^AVxqyJu#$l5|{#L7YCsZWuye@ zR0GhyT5wo-`nf<SQ6O<fU;qVD^Jo}=yyhI?i+unE6iQ}@t_vgx@Ge{d4V)Mmn&2Ba zf!GYL^WYU7G=e|_a8OGWaFz`qM}aV`S3t#q6X<Ga)SLhbPLPeDOh9B_11Se#s21qR zBxJY*KIcpHpa{q$=mjXCvzfr5g$O4<7uN_|4bZVknp&Qk@a_y)gOLJ!`~uorg_z|D z)&wTCz2HU>8rc9JYXV+t=NJK+#)Fsz%A(-gTRf3&Z}EoR-U3qtqCvar(FR7)hCw); z(Z?{LBOYL<>Ubj}gVPyvAOn|Lu-zy_7-;rDvzxc37A_+&tRt)iVymBvryEiLgM0c= z5!}Nq&_N2Yr?HPyfTfUzDli5i$Q*J&WL=ELsxhRo3Myqs8>*nl1>@0WD$oHXlyx_d z){MfCYp8;w6lc{#*G3^|3@^%+8cjn`Q8l_W1zHG$8cX0qXP|s=^K&pSO@TL(AP$Di z=YSgZXlnrnepL#wE`=5jqYF|-7o-G1*3}KsRg2)cO;CG?&?p6{8vvT&99@tC>Rmh0 zs4{|uGSZ+1+I7CvU62B{58AbZ6wV5;PAO<f2B_MFER2M-DhMn(A$^=f!%LG&Lmi+y z^1%IQn28YY47$+{P(TtG*nsp>2n=jMyr+P)ZD(|4$mq%tKWMT5rLxhLAt(z-a1T|W z46A@b4m|uhx-tY56c~dtAVI3F4B;#;O)APSEy>JFRREt~QJ|5QSX87_TAZ4qlb5NJ zm!-+YnVDOVlbM`ZqL7!Lm&(PNnOBmUo?4`ksgtFXnU|7UkqDvkAXI))W;#TxP7W6* zXrG&wg#yS>jl4{)yev(f;_}3TJe`cpoHQ=Zoc#36<is2;Lj{nHP!*sv7jtY4K{lnN zR)Ea2HR3Yl%uLhB(Mv7V0~@1jtf^3xT2fk+$HisLnVg?jl9^Wua$K4Q*d(ySKw335 z6~G4&b1Epn#cbg$(80+H3hDVJ`3lBdoRC9-IiVIOB9w7)f*oxO_6AsUq9&IS+*(d9 z&MaFEh`6qyrhZ-~$lOeb{zP4kEL}rQt-MT_!FjeCnP8DD?JO=%gmV)$ZS_iuN>lZ? zICE@sz(%A&Ow9xN8*Dz<OK=|{+>@ti3kgxEZw%qSL3eqcCKo3bePGj}Ue4p<1P6%` zXkjMUAmnvLkaPl@dO;iF^K*ub@PXz7K&{##Kgy>EI;@@eCEHdCM&RbDwvnbnie3ij zidImD^>cO&(DlqM$Vtsj%`3@FEh^1RhmYZdMry&k$VRuhjc#*;?c*72)7r394H`9a z0v`@Re5N2_vmLg54AdCEq<CtZ{9Yhp{QzX**Fp;xmV`FT!OB?h_~PjFHgwJ&I{yvo z8spvwK=Jf8v?3$W2?Ukxq|a{qIpdz(hT2Q#xoudA)TP130K!=h6pA1W8VsT3#sH8V z;3;iGEc*b!v!O)Hfg^SBAX>mA2{YiJmHT+s_ER!J4!VcW)5pyg*9<f$06-JyASV!< zHAh`Wk7cSHMFH4ol#U$E`Ee9|cqYYB)IrQ2QZwO5*&L;n3_3bH6ugHE>#|Kq0>e2+ zGdlAD+UG@=^BTbQ_2_90;8lFoKCOZ1c@ISMiSpH%;H90AIZsd%7F4EyI;r5P7b>on zgw&>nnnbLaB&k^mKE@v$8?ZG@h`<4-Rmk#FAMnMhAkU%iwL|O#0&Q$_jPL<%Y6C9? zL#qvtPsN39>UIou^YM2L4)t?ahzeD35At`ybDS-t3<K>(Lpe=B3*smUiDZWlXrKXo z$1J$H2iX>bzCaUn9iWdUbZi0aeo(i>2Yits$Z#}W&_$V$whgGw2wJfS4lv~XPOvqd z;K4`iYcE0Dd#JlZRROUy66A0Y20Pxz)g8Jf)eo%+3cUmYdW;VwA&}Yxh15Ve8lecA z5sgr6mV(@htCtFr17Sq^1O**pcNZwSoFHz;PzIWMBYpcR?p7vpZUk8d!q{4x@bMV> zuBn7(6_BgIElJRMCaw`Av?p;j7{MmGY2aThN%UGtEbTvhtxS}bAgU$MjvJnZlIV63 z)&cS>VwWalrU7(v7WmdSkR$|yM%q9dTR|&V>9!^koS)!%4XGuFSa%LyG>%!Ec?Nq9 z(jA!4M2pDY;L=n>3-`WC(C%w!x63iY2kBy1P{9D&R}DP{LEBJMAGG8TX$>+|1!$!z z=yF2^1qDN-m8p=!ec%T}LnGSJ$43GCc1wtQ&}K<AJ@__LLZS-V^yYHrL_Qk4G%p=I zz~z>j13I@AGzZS*%n70tQu9hO5>s;^m*f$B>Id{tS1xDHqSTbqD$to=snDwwP|l_T z+v@7<8}0_O4|Jpy<np`BR0U+aK(|dn^+B({Q_#rEFUn2KNi8Z*%`8q;Fg7v(UG?f& zT%zC$HYPg<bS-F+jzW26Q409vv!c}W)STSJ)Z*gI^i=4P=8*GdK?j}ZrKjfQ=jNv7 zq28ni3Io)0$dN9<14)7tjI#oGbR2y47Q{%9DmTzU?4W(`h86}U7SQGi=$<ow1w$hP z1yKELX#yG<1c$VSr>3o;r4g5*kpc3^52Q!{U4aM=CS4>uxIq12KX*@%6{dzp1_r2B z7(lErG=p4126n8crmeA&0hgfxHak2K4mLJ1FoL-lk{rR>4K-~IVdsE=1&lOp4b7lA z2`pf&X=?=A<_{Jy(X=%(K~`a^X={w4!c5cF1VzAH)7HckS&N0HttpBMOHErd6ahm6 zO<OY*YYYuFZOu{KYG|ZsYmQ>Bp|Pf|1*$nFnzojxBBq+QmMC5{G}E*-G(c5k4id6J zcC(=cD6CLbSz-to8GwXPG#Y^d*%-y0MxbCeLGhlEv8JsdnvjX6ts!bS8JU9O2gMOa zAlIV?o)O6PsNrA)ay^<5$n~f~#vs>Qq6D%r$n|JKMxZo-;s|3<GC@l?poD@ZWU6Uv zgeGLBX=`MJ5;(@@pcIB`yalF^C5DiRfu^mIDN59u7-9;6Tn|?Tssa=|ZB2}IOw73q zAvr?<a$b?Armc|$EGEHcW_a3~Sm>A<aDnE(K}x~-0h9ybi3i;7@w7EH)G;;Yf>ikk z(?A&&qzx)!Y68l;utWfD;hUQ3m>F_Gj(vct16cr%UvP)S)7H#L$IOHaa`FR`GSu8) z2FjThNEU#uKsPhfF|*_XpY*1H&}jnq0oYIG2B0hqixn4t1#<;YTXRDlb5kyJh!5aF zWMT|UE-wBG79eG2I_8#K7U;_0>Da|z!BWA~*1|x?!i)=az6nSr*j7(XTN8MC1Vs#} zyt6RZu{7i|GythWxYrc!UXVIa9d2o)V`;)=2#rFRd8Y8v4W!OU!PC~#RL9T&R4Ahv z2rscf3c;5g8yM>t8k%q!LZcCGq&X~wfmDLe4Kg&<F*GvaGK5AOOr;r$BTYf|gORBY zsQ5O7#vEKFitV6iGSo3PGSD~TGBo3a`WnpF_SCcmYl83$bv-q?xHw@|3R3l9Xl!9@ zVg{{0kh}`Y&9F2LHVB*>kjpt^O<QA_55X!-KxqM4g(-S*ZiZf*o1+)!7U-q9B}QRx zfFWXtQJ5QH6z0YlBA@~v#r=k$GSdLX)8G;xwOTU-m6>QlpfVG+Y%&CunMNpPflGX} z;vE#qXk|I5#E0hraJYg?e0au&2!Tp`G$D}d;kg2$3RL2w34vUXCIoUlYQb#;ay_aL zsKhsdr&F-;pb{Uwlm?{|w1OK{;-dzRF{s2x69Sd^@Wc%<9#rC^34u#|W8^eu3@Y(a z!^;>{;=>DWuvy>|-yEf?0GIf1Ay5`I02L1=Mmi=YT!seF@&THs(2ICO15goRVya_e z#sy*{WgJi`3=b!;v7kc2#2i!~7#cv!2zaT8Uep_+74?P&pn}8HNXOKi3&cjV2%ZGM z7J*6*Qwtq4P%{r&a3Cy#7x@sSAhl+OI%Y;(h6bh>ijgY=LjzDbV`i*lX37O(qdEbt zLNEij>5wV}LjzEiU}mmk4l11SRtkm&;A+7LRC|EfXcoaE8SDX2)nIO>V*zqM{>s4+ zTss)+SeSDe5~v<P3BbZa$HJ1!5Pt<>2#S771073{nb2AuoX|WqZB5~67UWPvQ0!Y; z=olJ+ltQB)t`wz;Fa$-lp@D^tp`jU<A^u9j5EOrghUSo30)I7O2#P;=Jwa|oVQgw{ zh@)eGTFikOQYbl;ym|uG907+Fed`I-S^-ql!ZS43H5679D8U7;D9~yJP~#e{Rv7vf z1!@o)<ESXm>JCsvfhGj1DA4K-P(^_z1g<Dh%6o7{0neJ?cm!7za3N639a04t=$IID z8DXgc;FStkEvO7IG0`zK;xaOTmI3hM7PUiQ04fAbjde`TxQsBX0C>oNO$8MKrsg^p z23$r4&~_r+R77n7Rtm}2hGwAlpOFE)0SFd=Hvl0#)CM4Qv<TE5L|z;T3KUO2PuR*G z&@dC~LH`U43|XZ)DTyVi19<+EfvK^90fV8Dk%5W1nTe5!Iq3W+V>5%%^PlK<{*zm% zpEKwXe+6iA(1?tTjP&(&anbSc@bwH1*5uMspf2P>nSO&b4JaVBpyoLz<|LQqB$lKW zgVrT0c$MaW?r8<3aMBEinMax~+^S*bIfjOK_y<`jIOe4kr6v|D1efGz<S1wunkx7w zm*gj<7AY87S{iHOHV7&MGY`t8n1Y!XmROXTn3R)RY(<%oF!NkoP|R^jtVH1x&4HQc z;en#XBfqo=MSxfi!aPv&hU)^Er=yUYnO9nps-Ue<oSK}Umjai?!+@FR<*4K3tK$_3 zRhp5SQ=m`=3sa~dF%;aqP#+h^5LcKMXnJ-@EJ=k45l5q#2Xmc*0*d>HGYO&!W}dGn zgbyWsAt49lkwC%C^F`6*o1a&bfg(aA2WDPyFp7p?q9YVVn}Pz&JW#oaBo&#ONLl&= znFlIoq3IeNv59#p3L%-fB*ieyeMoMjhzT>#IX|zsBr&gqTIGSKdyuO;!e!v}mkhN7 zAxxMBb01-q#Hj$8N976*+Gm2VO7QddbA>g<VB2b8(XRty==l2TfNNYGUr(LjU})6~ zGsZ8()!j8n!3$I%MCy1&g3B349dLj`)wuYFI{CON1O&M{dx9@g2P+P7g-U~Nr3GCH z6r`X5)@5sGs%>njrD15GZD^!rXlh}k2|r96<Q`iP0ZN?uhM*g~pr-ix+QM50x?l+{ zkUC9}BB&A<7r0g=6(FXTuP;=MhleesX#vs)Z!!CN+G;?AL8=W5v^+eJ4Gs>5YJ$sx z7+SvYCNAizd5~*B6KU|P=0h@4i&7yMvnzlzY*cDdz8-AB5L}B-2<UctkZ!Q+;m1pX z6!`k;xrgW(p$w}kD0oGJRYHBFpy1_e>x($B8)el2R4LL_GgL8b@C!1O3rVctXp6M< z^b652HZ#>TGS%{m)YJxZ4fM<m3=Flrd^NRQT(k|%jSMU;VWTr3hq}0cqZH%}BS^gH zxx4CtqZ{4vj$jK6^gzZ%B9^~EEr(FrM!H^(V4DrV&TxdOgE$xJbFkVFS6de+A6E@G zAAiRX4X{w8rlvNM7$`1{O!PFhA=;3od_6Vw4NXi8^iVVe2W#qEn3)(D=)uz^w5J0J zCs#igE_$?)hqE088K4^gjSP)x*aHNW9%d#63<id#hM<leh;L|O0zMbmz`(%7%nbSb zUt>`J&&14VwEstsbjOLb1_*RZZ-58r8d;qPA4gxEhyV}hT>(0N-kMxoT2uhgei|eL zlSzUqYiwE_OG`5Hi>wrU^b|ZCJ$;>AgFrPVHkAs979F~@k%57MuAz}GY`_>@9)*v~ zC5b7C1tqB|Rtk=K3Qn%h-YA;TIk*flGB7aKH87>jCFqvn<!ezVin%yZ8$F;UG|=V? zWPPlkw~n`tuZ|z$K0EMgL(olTt`T7n%8!eS6S^`Ie9yWS^e{`bMarOr30LRi=!^3< zITVEf9-jCW!tHhqa&!Uh0f#!pH6U2WH6Yj!Bm|PORWLI)2epFq3_wEQWdNW9CH=g) zz~`SBDflYbDi}bP_JURjfjz2VtDxblrQxe>s0ljX61tK|!B4?f!55)a0d%RHYeX1i z5hh48=&Uc-2nAb+gti|-%nzbS+Yl<~8W3z792gV=t&aV){B(V_d^PnUwX=y9NC0$& z6zI5BkbjUBYxsdK>;sdin!rL@U{V*R8MM?0ec?99P)<+@0$bjw<E^P+tDx(v1&T={ zEpQlsuj<eTg(27%DC)s-puj-ZpyREHP!4H-fGmPIAVd$GvY>4okT|CTsQ5y2frf@3 zXtTR(Krph&VLINLx{yW*$ahAXTA(07R^g}Pt%+nis@X8t>f$gREKk6Euo@&Az>P;- z-het4mwm*zm4Fc#&H?XrG6ZdQfn5w@gtWHJ7;(i4C$xnI8jA+y2&C!-v<BAQM<XB@ z_2PBUFr84HFdfiZzYtf@E#x|Wo;rSBI)2`uE7!pX4uJ{~-vA#^XU`A?a5oAh04-7A ziam9_bi6@ULbIx)hM%{#p{9-#gofwnfM5-<9!-cdkU73k4qUB^XBb2XQ~~OQBC(Oh zT|*oZGH|^R4{7*$X(Bnw#WO6#PzOXB=>+&Y=>&xOft?Ye<Ln>o1X2iI4+Ofa%g+mR z4Jb$$k~t0a40NGpdTDCGS)c#{7dxO;h<=`+%mgyt&=#~j6;!f#hJ_fxIsOWU;LGK~ z<r61ofWMQiqlUMpwiD<co`7Ht(1rq#5u5>`ejpibL$DmEKtPrSD}h)8CbdBU1&#ns zEscOsKivR-$o*uTAZa68FsZHKqydT%U65s(T2S+}ph;096l6K*kQVTT@F0$+b{L3) ziTQ#!nwt7B4LAb?T*pCFadLtp2jVhYU63;j!K4uvN@5222V`xCtp->csz_5G>PV10 z2!p0+ki!qja0F8qY?2nlvoLRR86jsLPEJm!$+i&1P#%{tQm!(=nX9PSFa)*#LFb~- zu=x*e=i_ew8ylM#nSkbhOiay8%?%AqLG6E26XVhLKNX`Hr%~X%0=xesz$3)pJqT@( zN=E@PaAai#Is(@*)Xmn|%)r0^rV>=LgYN~0WIE(INKl^wcD)_)&H~WgM><j9GwdNP z9@zDLp!N3P9XaqTexWPf2jqB7&_Rwtt}dZbpxd8a72F*|gM-yU*N4L{r5=z=!oiUS z-Yf{(5DI1xyzd*lDFUQ?^tNvwO81X~+aRFY8RzY(pluUbsVS+s3eas1*+r?D#n9{l z8~p{%&x1FFf%ayC;}m}0qBkfDKsJX$^8qB6pqYR;mJy;IR7XLw3p`PfvXxXJ3e+ot zcC?H&VV7c>fO;t)2O(d(0cvG|jsOMikb~+#>zYyba7tL9Sy^GdFcls!E=Y$VgKpX| zSMWyM(+vqF1yDaq!y9s2x3{jLCgh?C5R1!P0jUP&g6z)$m47}yu0EhGq@cX-66)is z;S%ZR=<DeW9S{ZCWC*efvaeGgwl*4iS$BX(aHOw>H>hU|+Q$gJsyhn0%L-f;f)WF~ z3`E`H2u%T+TwI1I&V#rPw5$Wkg|IRiwA~izrf%>#{a6ZS&_+XO*daC5spVcsc%zO6 zKy8D?C&=G8Gl7o|sOje86AZc^5=4M#P)Z~{YryQom3}~%y%W6;9Gv*AtU&2MSOa|X zo@1z+t|9pDR!3w3E?VbCNC<=7<LDfu<LK<E6YLzM6YLD169LPCHyaw@7(<~}Muo;K zC@-Mww1&8mQvrMtDuNS$e9I_kZ6%h2P!tq`L6?*2xxm(bfwTuZd)gYH3OQn`a>P{S z;}dM_;{$aj$Rr=10FX!kk`V5jKR`R}@=}Y6OHvhrlQVKsGt*KP5=+z4Q;Q1{b4pV4 z6iRayGShS&lhTS3(^D0yN)?I=5{pvvkPL?$_+o*$#6$;CP=MS6@ounlkam=Yk52%o z=L3#8BP|~v(9OpXH82ts4#CczSk!`#(M7Qrbjhc!kB>HNVH?;C3>A=TKvC5g!nSl^ zyA~8=4ER3LU~R-jwGctDS?I!`Xto4-U)vB;p<x67C?*|=3;<9RJJLP?VC#{w2LNO! z3gl-9h6V?uPSo{8zMmKr3D97HOB+LL5U^(GsS=)=wxBfNh<>4KFlaanwDlAe>y9Xw zx`HpB25(&rb`H|T&<VOK4CEBsU}sNVm`?DTcu?CNyfYbG_(5C&+OP_`1p{`uH>fcI zx`;|68|8pzD;;l5Xe>gCIR!0nY3{8FI{W~qdC(IOKn;CePy;4g6LK?^H`H*LS>P6{ z29hO6hJ)P+BESa}fUXw}f;kpR8>nJMHUN^|ksS##0)kQe2)_5+8`dt+)PdZw3NGrw zH!y1=t~~`M3Q%|<xdH7ea<C83or29TU?*S=7Vtf<(7=K^23*Y`9D@jLq@yfAcW4=c zdtIQ|gA@v83djQykPrb~Dva7T2#)lHH6&1)1@6wFA&^5gL5@XkzeK?rFOc9wCc#6q zI=;S+5jwt(p>8_9j(#8ldTIosbp!DON<S~u)guUUqpw0pkfUF)n}3k6BY35vtEZo9 z5HzWP+!E#(<mu?-<Lajn=I^Tz;NckT>KEh~>Z{=Cr=Z~C>ZcIk5gF|1?danPYQp(J zb%IqmhPo+uhq}A^c>DVYxp?|HhPe7EfID`23a-Tp*@=01;C;s-shK&T4a~_Id6^|8 z;P$^uYLS9#QA(;pVqSV`dTLT?o<ezQQA%o_o`OqeYH_MU5cELX%;FM-oW#8J;>6t4 zB89}9Vz745=u1Hcs0{`VFHl)ehr>6)c7ehSY!{e8sQU=k0vU5uuvG~5^a~9JA5`P+ z>hB)p=mrT>1&9LBwdati1V=nbEAqXL{&=o|40QvkRzOk?J@7>#)XxQMA*fiwd5feU zOuL(-pSyyKYp?=TJLtw}PiK!{^xGM9pveGiD~JFk1yG+K)LIM*@b>|A`xU}ngFp!= z*x$zosveX{LCTR`>K5u6qyW<E?imu|8l>Rl>K7Uk1xiX#M<Db%5uw-LHN?{$q#GWn zU`>#=8krqf+?UWn+y+kySVI|24Y3_dP)Eek2iCRpb&Svk_bfpSM8^`oz(YX+agGBh zJAgW*pppYL0<8gN7-{Mn!pjVBm?%K4068Djl|bnnz^Ye-v5*SFL<>|FA)QVHigI_? zAVmKFrW0C5`uMwhIy?F(fQv?FNMI-^low@|q-tpCXldpqmZs_C=7Gt?yfmHM#EKkf z845K)K>>WyQK%czgc(w4tsdg<ui)(O7!>TP;N$P-?imv5;;Inj8tm^A3M%qoE0#ch z_H@(G02QNpJ|TLBntJ|0dSH(uxDYF0i>x7P-9z+1enwIb6M@c~flP*BWQT<Z`TMye zyUEed-Ble?jzcVi>I@F?M{Z9;nnzsD3IRo>scES?3i(M2j-|!viAkxD0~QpDD|2&G zONug!lQR^mN^=z)QwvKIOY)0A2S{)^D}<-!<tbz(Dir7E<R}C~)ut+>q!uaoq^75W z7E%}F=Tzq9=YpE!#p$Ver6pA*3XozL>N0S+M>r{fR&gnqVE8sT($`imBq-EX4|Mhu zq>*l@;ALy7V+s)f$DE^6um%W6X&4$9=y+*r>LPg1Q(?R`H8nwY7`o~j8bZ?#I1a!z zxH<X+yTVRkR!~3+VT3_mnwmNY9>Q2ILqkrC^O=xLP=|#~adL*0g1QbUl|mu}Je3Gx zDu5ENtsc}J5HV={aB^{ib`b|h`a(koGPr;=u%G}9OHlU?G(QDOa895TQjoha;N}>3 z^Z?XQ@WM6N0Wk`k1ECE_P>Bla*gHY9HaKx1l?twYE-wDi@fh?G4^B?7A91=E9HAg5 zgMt%cHN@`<Q0KY__yr@iYEZ^yAnLWe;O@lTfPoqcYE9vEE5taE5>GcSXz>6pzX*)g zIERKHRHHP>f+KyY9M<sh8t~A8hNG^Bj=ydc#vygsD+yR2fb~L#NRS6aKq&&;bajk? z44H6|J46C4^a%}FLUSQFj6tP0WN<_WI#_}TQ$+m$uXaGAaFBWj%%WAr16t<+S=@_U z_dpX0IPDseHJk$4s0&+p0*e*M00Y|K31}PvO$gKr#}L98b-_KJLWQvs&`^Peg10Sf z2^w-S1Mvo^j|>?n@zT@+#~QYA5|Hme{bfv*kPZ<dXh7X_{9`2WyDpG5aUn)X;GJoN zJajk!d2|G73hLMh$h(#x@8TF40mTSnTm+wop`#)S&~YJTrBw4Vd`JYhkHL+9(D(;D zC4<5jI{X2Xge`vtg%|W_EgWMX)EoLRgzZ|#bUVVS;F<xcPmkQy1v?(nm4#LEAoqh7 z2Y|M48i49C<Wt2Iz|99xb4}Y5-1Gz8*sc)b;fiuWj{@XAa!+l@fs(eM;DG2s8EjBc z09SS(3*i{t@Ws%m3u^3Xd!p+GFXb_U9R!0J2IxL_B+l!`)bTo~iiVzw2?_y6aLX0b z6F$MPT@BDcfCm9q1MmffF-A}r5<NzOR4b#@$y91kz>_1qMh4G3LcI)|EYtyAf|FOG zk(sBd0Ggl&RaTJH2}(XXUf|>iB4BMRxUo3uXcT!g(+O9%_;iB{X+qNw_zb}4yP+rs zc^{k*&|8y;MgX*z2T}<hk~1_wYGlGBJ#~B#4FhlujB()sBo4rN#mChhGWO`FVFfzO z6?EN9l!ld#7i@48ln)Uu0O<tlBdv5%fVICt`oV4jU!9J6ej!8-M1p%fes1^+9FRf< zqRSnqYRuvXDgh38B1<8t7D(p<$^lc5c0QO1CXo4{c0Wco<APmMqJTVtiHH+WgA=sS z1fDApF@ZN%DIk^dpvf1X0MJ|{YH|Y=(MYp@7?L>W#u07+XF)uf3QeW6r;c+Fe7q3f z;jq|R=b-sYr0_zTkAqarh)Fh3YXs|boPq-8Oq+rN=2ROvg&KiodLSJqc-Vkr6=Vo( zjt8mfhVU#@m8UIib_Yon>Wm6VCAf`+HUS0kk&jORR2(v?g<0JxKwD$l$n8r|#DXVN z&}U#^tq|zk3)0b_Aa{T;bp0!c3BqV;7Mw2O@du9!q*RSuDue`ix(Dlk$|*=7f(mgT z&^_7%a1yI8yu$|a7PRwaWu*Wqks*hfYwCbqtO4ag;~ZY9x;aK@AeFZ+{tBM9;9Lf3 z@}d`H@F)PSV})1=BB8>dNic*2av=dOTHV}2EG<DjdT84P>?}w?8tQ<TX!z(Df+ndz zMuL+nmckTdm8T}C6`}!}I)nNKVi%Ny64_``4UI_XKp~8RScnwg?v9~8uI?HUhB^^O zIuSbII)0i^wV*+3XAeKu5Czbb2zcq4HhAs=KF$s?4ELxmOdip<jnMGZ)Ct${gXJ{P z_zrYWC}_)ov7U>rp$SaV*A~3iAHJ9+!q?V7&(y_0OC!QaI|APHjqpJT>mr0fMF{9f z6+<1^o=*jZC|eh2|6mPcJwp>iQ%fT=QxlMBp1OKQrY;7W`Wk-PAoDdf;U_X;$*%#1 zwuY#a{{f)&%_u7bKz4%$@C<cOo7e%ywgJfbTtOkg$Tk4EZ>FFSU}&qMVWj6`pyj0t zvPe@aN-MxfR|CciFxJ%ff*&}DF(wBJ^MC+bKP`<YtpG#a03%I(jVP@sh*8jF15y)Z zXd8vhwT&{=4KUOXK#ZMwx<Q5;b)yWygNm*J!J6*=3L*Xq2nR=i4x5ee)s67cLYNi- ziZ)$OP1^`xZ4`-ckZQ2kB7F2UG(f)7jnazJ)CvgD3J8EjyMjVE%m9!EE<<q9i53(1 zQa&U}gGxEL2aytdfRDSMo1=!0k4}V6lqN`(0!YZkPXUqO9esRU75w~zd_nUsu6_!R z!NLAfo)8X~vjS}D!7bF!8#FQwp7irm2rw|vh|pAU@(fl8@bS@z0A(c5yiu^TN06(h zQ;0&arz>bW5Hv{xYOE+kaXEvg=@bHB<HyCBc_|9znW+kyxeDM@dO`OzW`a*W)`4E3 z2eL&cz|cS^z|c@9z{o%+zz9Se>FDW!hISqEib31iQ}aNh*9s|_sqh)V#Jt3u{B+Q= z5QulVoE0JzJcC2P(^}5{usOA0g(z1)&ya9WKW|r`U<H2{_$()A8Z(H%+#9?`A*E1& zG(UWNz!Nh*KHA`E8BolC(y4-i4|q%j8kL^5u*4Uo0Xo+TkrUk<okNgwW`I8mH`w1d z!pPPIyeSEs@FKJ#5Gf9nVNDdgYz=gfm*=>6LG~1TAryMLX?TG~*kMN`L!1aA!S;g) zElBQlfo52J7#Cp(NIA%P0sbLcV0S@12NI70<q?Q8VH&kT?$y)+nXRc6;2(md+SAq( z+P(nkMQ_f69qSXK=K~#62dRN!ussp5-49R;O+dwti<g#*m$n6jscozWE*ZhO*2N3r z6iuxt4fKA!0;*HM>-{|4keuq`ZR_Ht4KfEV2nls>TQ6-R)Npt4w$*U))^hRI1v>^g z<e=_GaWGgVIFR&RT)bhfgKc>N`53Ak8lv71Z)j<NEr1k_AdWUH&fuFoKzgC2v5U7Z zI4rb4RzU19LUtI)e-MM={!@Sk3gqlP5=t;o4s~;ckIy5OUM?Uh7s%=zohTg_XbA=p zMk>KTRW@ijf@cWmk`mDLI_--y7jSvz37RwX^l<fa^Y?Lg1(h(M$v1G(s1smds1czF zD!Rawff1N8giuCcN>2|~cEW=Z-cJH|RuJ<6pvVDXMDqetl0e#Y;8|W!uM1Y5fRutT zLb(gFdL#IHV`I>IV^H}6+5qS2rU5Ex^!!})z$pweZpO*Ui9GoQ34SZkB(tVMZfS9e zLQ<-Np`L*{XhAe5CwNK{WEdoaf>>Y)P}3iBrn--h2hwUpP`*I)evmRa*!lhnNc|c# zN$^M?_#AgHEO}l*fipZbD9Y8x(H0W8T9AAJJ|scI3q02VB6U5rJT>*fq9$6%;-FoZ zAU7am7tp}AhbF9~)PmZe1riRx>?>jEzH>rd<wOHl!Tbq28p2Bx>NqF3<8;BE1o;^% z<p`024_boa3g$jXTZrGBV3V@2LJoX84=7AP(dgsjp$%Ty1`>c^h$FykP?SSDg+@?a zXvG3@ztIr;4lLw>21v@|;^gAeQV1?cO)e=)%u#U5%qdANQpitJ2u>_YNiELEEzQnQ z0G;dOkzbshnOCf!VQ6V#qNCs&9t1jC&DYl!uD7J9G%q=^Br`t`q(3b)H7A8jO98a< z!4_cwx+0KuT+q4%*>%AIZk|3Nu0a~0=8mr)=!6-NN$?>rc+LioD?)<_)?f4Wg{;{E zEy4DN*AL(_0Ad_uZ3Z~i`ub{vrpI9AF<6l|Xu(%7h;VcChK;9z__hXmuto$(jjgVu zkH5PHNCu`KEDR#_HPUkO6HCA=KQy%vY|zeWEiEIiWN@S+O{J@Y8d=4;i52QPAeIJ* zsi~t5GRsO`2Sh=Asi2U9l;czK6*6rNbl}I+fQ(JaSIDx>1c^ay0SO}3dw}m8PfN{7 z(a6@+fzn#36$Ki)AX~IFva~d^pw5JO3uJ(TLS~vqmV#bRsvbC2p;v+<Spim+mY8iz zjA0523LvG1dWf+buzm#vkdt!rG>o)zG;NXCT4{;d@F2iY3hGxQ6oaA`U3qFwaVl>8 znzjadxMe}6qsc?AIfuFfOhK+22Q$G$YF<i8KHN-X9$JSRme^rQ4I~Xc?-IJP4P+h{ zVSsb9+%S|V$SBEAFG{23_D=%)KTXWcj4{uDF&aJplP;+ZlqD1fVE-q|)=$jo8t4!h zs1+UL9~$E6=c?cqOQ)s4py7ehJ)gE1qb$MUu0bKL-~k&@ssXq1K@6nTy4WTipiv2m zW02}0wqzEqh2+eM`=<HPJ)h|7a>30&P+JkSR?r8!vJci60!u<>4=l7Gv-YN-2@dck zQ*cUw&3J+~i5P0aT5F*7hoGI7Mo`7DrokZF)Ct<)fjnyi@*z9~2FXTFup1%ahx>|W zNK~NZ1E?VM3>J_%peRO)I#?&dTZf8!I6<9uNO1y6RN#SAtR)V_b>IXBS%C=NxdWTP z0?i1cEkOitSAd%d8(t3Z_lflL_jQHr8USrLfzG@@f=mHy0rC(A+K>k{fubaM=(@wv zO`4E60<Bd;TW5%SQ6WSNh#cLdiMEjwu>=w8gcN8{!`8<Kb;Th_5V{->)*T0hEqFTA zaCDPqK(IDsm{-?Rd(dpsghUW*&mpMrgDgD?hVSyjvquxG8SCyx$fUV{D0CAg!5x|q zlOUBhczYwbF$k{nG|+c{B8}71U_WAzpEGElA9|t!*hQe#K0b~ixGP_9X%C)MAMIN> zhPpv&RPgFk;x`0xf`fYWJQ*L?FjtDtlL0p*5c4YFt)a-b=4O_Zq!tyF=4F?Fwm79J zU^!WalamwH<U(nUk#wvDVrB-s5goR)4c34`kw&zjFgAt^K>G>BX*ieN!Q0>9@(a>_ z1GV}<ZCCW}3Bp8hO4qQ^0;zJ+Hqz8KMDM2{)PlMypq4%?$e=AnkTBUj7)^qQ(gXx~ zhB=0~g3ia&@zH^<R)ih{q60rY1={q4It|o~!ggW}NSv(gCWr|$sHZ`JJbHSEub&3C zT`8a)ES{j#7@)f}yipc7VxIK@S>gy@i318(5Jn1S5EnMHg{o$>VF=%<g0*D~nGpts z9|VKL8L8z5U*!gph6XW`^iXOT!p_%#lxNtRZ6IHQF@YALH~N_!U`<;1j7Hm3LFJ>Y z{G34pld!2Dqy-xR9$3$;7(K3H^tcN6$qLXGFt`%~O31{HXpbIO0YB<u^tcMp<_bv5 z6Lho%_$)*a1GFpxt=$P-Jdf1!bc}%Q&4RYhkWRsXl&KiURX}Thv{NZSsh7HkQa}$c zaSV0y@pladEoO@fRd5gTcN)0kC_v{IID5DTp`Gr6>>vdN@R~13aDYfiJr7z5H-N`b zfKP#-_Bj)<MUVq`&IIV#auN@Z0QHgJ`wBqu18#5NJvaiA;Hh_J1dR@jfI4$Xo)-ai zJ7~Wmj?pvpV>#f{LKs6BphyLkaJXk_Ahy8{W`Io8;5{lr$HNoU2M6t*9?7Rhz{3r+ zOqHyz`sm3Jpwy`_Qcs3}4mpe-3}K`N+Smsgg#n+5iRWMlaP@?kZqf1ZgzhW^_Zc9& z?U9EHsC*U#xZnfr=7u#7!RZ%sDL1IV1#MQ;@dBL^3DpHX`~X!eQKvv4JnTq}k7;lO z1k?-Ko~W)T?)V3&X59X#<IxY0LYt^#q##N`hlZfsc>|7ekSJu)1=_g`Na>KwQy&x* zK?@^-9m8BT46MLAcpXFCkoOOOt9UCb1rJZ~2H#LOO$9|A4^OZTP?JF$))IwQ>1Zw_ zv`_-RC>_#0Leo8PCr5B8!a^Pv0N~xkurSaG_Yd-haS&=@lQGCgI>F3=$<gGP3Ak%P zwt=Q`5D^MKq8zlJ8J@zxYCxygB62#xjIN-7@Fhq;GzA!0fzyDYrmcr3Rs~=g4Ui&D ztnwfkZ6lC&4MQ{);L<nP6||=t9QKf%+@J#&u_=UX{)RXU96OL*=@3nj?cbqpI)*x+ zJtpX(1#W-B!wH<UL9<|B5nYIp8irt>qS=fz%k8D(18S)nTA>UMgO^oc*<}t2LI@`R z$PQ>hhgM2LOvQ3s5LANb$^xn$(uGC|F^EiNng(dkfJUaap-z@gj;4ZMdWoKbp@9K( zZvz%B$YT`XjTAYMEfg>#P*VuR8qBQ%kiGa2SrCcL2d(}`9R?2Y3r5-=izEj=lmW7e z0DN`}yzdk0hNyPnJst2?8IWxt49m($#V>UF%~Qt<p3T4o2k1BfP+EeWdk4}E!Z1n5 z*b#Wc9C+{u%mR%bA>05~il-b!Q#pEAh>s6)1qKRj(4r^MerD7aPask7QYh$lKFAyz z#?CN=GUP)9KoLvR!$KhLMoO?qr8OuMqcue%2Fnp4h-q<<D?wd%A6N<nrDPpY=J5;B z@bm+pTZI_sjPOA^mKUTFbXt=ShCJ*HUPr$G$KYVlk=?Gr;8iTHkh7^lp@e=^w2nfk zFLbmYw70;`EkqZ#1}MxmDBRT#bkK8DsDih@tDm2%A8bAeV!18Y2{18G@0&UYm|&bD z1HaD?T&%#05e3i?Gw1{wO<N;91JH?wU=F4{XrC353RoU6R)D8yMStG_1?M2o5YUmv zPy@iVth1Y2h!Z%fK&?R?h{rX#!0JIoDw-ZpAQ(bs{!tHb0mnGFcLmEHAX^MEyo&D} z2~Y%vz|MFFX;(lw<H-dg4=T99tKSAoHUPJseL$@XNXEsJ4G>b`q@|$++Vu=so<_@5 z4Rx2l0x0UhX^g-LJSc~&KqC~C$lyzNG2)e&B<w;s4I`9bNyHFufRn8YTDk=XC#<lc zX(ENDLTI6anMxstp^TpI13txK^n9O@alVg>+u%9hhid0x48`MmKu2fTA~uJEj<7-E zDky+X!9hra&%#06HcZ3`J)X82kn<_LH1&<N5j`I8$v5sHdiaj%f!sxI1UhC5b}_k; z7Sd5apyD0mKAflYfX@<wn*!Rb4)P!B5j~JjE66Aa20IMvkvvfvp4y;;C~PCNkPJ4_ z^3w9sw$Sp@Hb!zJcway0BphgY4>B9WCUDSzwgh=;8-Y$V(M5C`KsAzy0_MRxkOOPH zkxT_yg6<-3Eznhk(7W7094{>|O~{Ejh>OfYPD1jBhLINN?qw|vZ(T3Y73dn?+8`R` zpdCn1f>i2)oDDY_Vl>16F0#(jadCsSno(MC;Inl6MvIC;ak3Y*sDL;1KzRxIJTF*b z0apMiEg&b@fR5(TC8E5*a-tU~&68h<Ku?sS{aIfa*&B2a8KHs%l98dO{AiGJx)-eN z3d+V9R#T;9QBVM#m<2kQ#~ax)1qBx>oc@Jc4nfig{2VW8o&E(b(a0>2;9Yx+0%`PY zLKo2OXrpHng0db6Ln`ahvk4&w5{{lts1GgGL1_bCrj4FW2)?2Z=TWO8_H07f1(4;X zplc%25_3S;oPn<mE-Fn+%>x~2FnT~CC@aA*=BgG2*a3i}2NZ$>3AznQ+mLJYfI`sm zf};l%BAp&cs{;zbDGxz_4jm-+e8SY6l+l9-{ar$RTonf0L4*bQ#d(RjG(G;0!1;d$ zhDIia42Fj0MrOuFCZ;AP3<idVMn<L#3I_Bz0k5>UB(X?AfgvX~AFp+##i>QbcvTEZ zNl1=HT3Zm{AMEGotKl8$<LBtB<Lu(+=<B1&rKn2`-~y{tD9A6)1Rr3VnWvDKn46jd zy8JpV6LjJ!WL-~UX-P(Yk(GjiZ(>QYf=6O*QE7?}<iLH{I3Z|lfV*pu4)~HQ=pq4# zTdk}VAdZ7H!xfx89D^L4LtKNjG_*8P)PuGZfZdOw($L62!P&>t4|a(d!VE(NXP*$) zVAvV&L9XGTz55UgVZ$VzKCXVYKCXTmu+UL3G%&*0T?{tgR$T$MEh)&=(FGQ)>Kcxk z>Y6A{@bq&rwDt6JagERb>(o(KQ`gsr+W_{vryJ-VcSAkbK+wQC^ezYk*swCh;kIDi zV0GFchiV&wF0(g;vf*BE)6np7ch!LC(NQ;0*VJ?LbJ6qhL5NwZYl5!|hJ>D)f`S5y z7Dp^vqSQ4tH5Jeu=H%$?9US23><aZhe5EJ8$$v;X<l-8VxoYS*x}YdEIX|x~wWvfd z&5}k1u7QDpftiT`gMp!`p|P0(xIQohmGdA812Yp7Q*#DGBO?=YLqj7|149M_Ln9;e z(ej@zi3nV-C<Fxgy9YV?Dg*?%I{W*Dxdw%BDN+s~g+0UuGD$@)MJ$d}&;_|Pz%j@* zSi#dTAT&h5#WBQD!OcHNA;3QXbegTJj{@jgBmW>>1qF~9SgrSmZJrGXat#RbcXka9 z_7B3U61N%Hm17lE97JL2?C9eh>f;EyJV(LbO~Ez9F~Hx`FGRuLPr*?k$kjd6#}Tx> z*4M>RKfuFN!9B>+MZwX}1$@xDr=L4GJVJHCbYL2FLUaOxbpmyQU37edeRM*coplTi zLUj}j4Z?I3j6!sbTy%Vb19Y4Nbb^CD+;oD2gLJ@VxP}J@>-Yr+2ZOFPa`aR14-ElD zr<<pbtAd7mkf)P^p+bI<f)OZgeH}wI_0U3A5p6L#nly1-Py%rb4e{^~3bs=4(Npkn z^z?Od4FWem-1QW~{X-nX9d#58EiFxS4NS0`2{HqlOkzr6K}l+gm4c(5f|IMWH#Rje zF<fRC85kJr8kp)DqFrkM(}zr>m;v%jVrFhqYEgP>k%EzdftfDkGN&*jJp*K2sB9E7 z5K_7MDVb@RsVNF2`3f0{c_}%m3W-HYnI%PuMU@Igsp+LTiA4(OMVTqZ3OF+z=njMs zb4yEwqSWI2oKkQrF(t7i5n&4w3&kDielaxAH82J#4l|+9FX=^@NeZbckS42<0{F@W zkQYFPgE5Lbz#?D*>=#2LbD}(h!wj%N#1ez40C8~*b`J6kfE6HquC6YwE|9|5iWvV; zDLfQH{X9by6u{*L*jo67b{fH&AOUd204m;HgI)bXAO#*s9EPdo4oKci%P%U?12aQ( zLUqDmmMAE|^G8l%Zc3s;K}IGxryvx7+yTj(5Hmn4&|MJHU=}Qo;WY!CCm?2km_B~N z0btEw0xn)$kda!HnVguTkdauFo1d4NjFRHPWiw=@2Sf{~)I%@Z!6xD%Kwd(Z2Gs}P z>HsQ1l$XF4G(+40Vj@>0P-E~?*xUiCfDm;Lk<kObHyq*)5Hk?XR$}~uriEngAT9zR zRX0(YAL4Cn@dA+{o&=dOXo>(+kh>x21H^>3k04DWkQ4z7@(a2Wlol1bBo;n4Ge8Y7 zc)rsiF0G>*O^ZB-ZU;Ian_tk?5aLrQzraSNLW5C;a1|6l0`5T}{sA74Q4+9#TS$<j zn?I63P&lY53md0_=<#%lcMR}^8H~ES45}5h^+iX)(Z|Q%*)arknVb&Nu|OJDI#%F) zGd_L+!6a#bT@*^tc&G&-Itrm-3LpaJ17dXsI_miQ>iGKx5$isvjV_*HI-ouYsCz-Q zUT|Qz1O&VI=qP|F*sZg~IyN9!2c!)#^5^J-H}Iiu4Gs-*({b|&jnMHA^7jcQ(pIoz z!J8CxJamFR{d{zs{eyiVJ6MPeWv~&DBg}LZ+@TCdZyg0EZ=HfNE-pm{$D*Rd%3_7I z{2~SS#M0v8%)~rMt0OrvC%H5Se92fbECqssNddIc3UU*1kZ-V#Z@5mdr@M}iBZ{Yx z(j!Q@bEqRIDe72h>NtnNn8=3W4Meaf0(1fb6clyfH}is=LReRXub+;Gr;l4`7;&i! zY?Y5+fUlnpm^6Y=#w6$tclC7lAUc77Eev%Jb0^LQXnJyS2Pb{fG`WM55^?r`ofQ!5 z4h}p}GD*!#QAi{usldnPk&*&x(FC>wbPlnOZvZ%h_y&Nph;M*@kiU*^fFmqdV>1er zs@y@Bo`cdA(pa&hk3xVaD4#g#xHx+2xHx(11Q@`sJp-i~h0q`$#~=$GFJDhTLmeL< zFb8zf6qq028DyaYx_;UTmO7!9D?sOubv#{zf^>X!z~lcqzTP^1?w&e+?yyDeFx9>g zpFq6j9|SAsVbVUJ=7<iMG(xusbO(-(0?0)=3clczqjeN~T*LfBLv(yx!+bscz?5SI zG$LU}`uh92x;yGXC>KvRHyvMh$I#$l9p7MIfBz5<9R=_nE*)Rj5JxZpQiE=WOMnYZ z8WH^9Pz&<$H_%ZC^6@tWk&a-tBW!;xVrInHzyRuK&)^VDpM|=CeCFo{-e!+{%{$B& zo}fBV!%$NvvnaJhCm+=7hM9t}#KHjFm-BP<b%jZS*gl|plJ)%@ecfIC^cB>genYDK zkwX@nG$gPgVeT0m0^8vY8oqK2(!pjT_E5p96cRCb;s+&Sbg;P(5<4(2gHxcbA&i@x zn3DsVRLe`uRnRceQHO+sI&3bdC^az!Bn}aVXBg0V3bvkpAsWVJ26|c=pr{7#>(taW z)YH`00L8a1$dj7d26_et28c5k0)jmKLbO1!846#v4?0r>Y#7v-P&Z9|h`AtA8)A+j z)Er2>K#wzk90mY#jHUwE6c7PEl7)+lrURnT!pT)3%rVFl)OrerxC@h{P9qVTDB;#> zfEs4tD>A`5`BC@u>ws=@#n9n_P>y^XuD+2bELJhJ`1^t*6%<<$POwr1t{m2QbXCxB z4RM611Q$P$oPbSTKrloZq?j_)gfxm!#bB<1UC@N^Gq@hoKpa*HZP6f!!1W?DLE0`L zE1WcS9KAIlj?*^O)Nw-Q6qIQgY31gmmZj!^Hq=0a0!krF1Jy1Xh!8^x0#FkRWQ&g` zxXA@!YI1RMVweGH)EMcQz|QRiw``F3ketU!h2#sJA^{iY3c(?vZf>BV7mBA|;5S!; zG9kop(4?_~A<Cu1;7SU1troo8wN;07VJ*~A${$d99iLy2nimh6$=3ku)lmou^7PdJ zjlO|OX-ysVB2cLW4Nh>e1=g0AS{|QPl%I>NH4`KQsty!D^?@cAXdu5lRUtVsPa!!c zzc^K)BqLP;WEF;KU}+?yAbP>s8ewI6YKaEi3U$z^bVy}Es=AIs7CZs^xqI1yD^6{A zNsCBDkQSAOg_fVY7wEu$KX)&1HUwJ(Pg5F@c8Z|^sGXn*NfrulSp^Mfvs}Z^-Ahvk z(s~55F;#*ZOE{zgK&1lYDjIFjzAT8FO+Z`9K-OY$mV!n=0LU<XBOL=P4eVO6xE9aJ zBH*j65XA+qaLy|QO*Z(a1>|Sul@vSX<maV3`lc3Trer4Osp}|!f`JQGXh2SdNlz_N zNGw)JRLIOLNli~J!ia6uh%Cra2NiOTAxN?4X&W5ss{sl?xF8|-g{2mifJQ%^^Ye>R zGV>BkQo|B+N>hu~b#k-ehIqPZ<Ywy|=^85N<$*5i1-Bs}83^VF1@MHJtA>`2mZpNb zn`4NhkClQSI1oU$H|OT3q~<7qODwR_sI3Qeg_Qi%Vuif?5{1O{qSRD{^30M9u=hZB zis+~-AT6JPEh0fV*A{tS5H24Vl&R|!l)=)Qf`X&BZ9$oap_QRFq?AR-IDuu1pyHqt zz`z~`o$3XR6h!U-cc4JY5|S2C>ozPY3#{IV1P!2WlLn~$tze`Dbtt&M5*h|RYAeD= z2VBBqI1JQ-_W^5!)?B_&4m?&7o(Kqb2T5vz4F<Ddfq_sH8V0T<VAU(!G4Ru$kd+$Y zQj6it2w$A1{pcWkjOiQ~u#4f<l52<~ihw4lJLj2~S(2HUlUbaZT9lfnpx~35o|>0Z zlv+}hm{**ZUz7{(_j4(7g6^wKNi0_INet2V@%K}3&jejF11t0cJZ&AF{ev}hL0kJY zxfE4ECx(D#SA2Y2eH2_^-5$_EhXx8>wuaym0;U;SqkC!E27CHxXaxB<8tQ65_vmRs zxIsRS2AcYy5OdNs)YQ~c2=LT5v;Z9_0go#1$qt}BqHd0mGE4_<u1=JOfsPlbKr#YP zWFihW0lO1)QVFtKL4zS>`I#x8R&;S@QckKuKz>fDLP1e}Qch|vv=UbEbOSlfKmlA; z>RK9r7Fj`U1T~s8ZHqJWG;}R2^(-y5psr0ZfTskAZbOJ}h-T<@ff|Motr$AF6cymH z1&$R^p#hzL1dZA#xVeRZuZ@Srp#nxEmgFm-4eo%ZC6f}9vq96e1sRFOsS3pfiOH#4 zoDqh$;K=0Sj4*<1?BoQ8Fv<xP&>9O`S%K;oP@)0{DpG(dz;2xJ)#L(Q7z2uba19Af z>5y6yc1;;d6hbY~@Y2)?(69o>At%TPUt0qmNGzjNa{5MGoSX^@0Rb9bI=-5=0UEwK zUYcB-kdwZk6eMk8#5pWl6~HY*Lrq&lQ`pcNWX2HGW`VVKj1VO(I8cII9bJM0T%ALL z9DU#o9LR_fwDSnN>{LfX-_X=ZAJlTyaq@;IhxGiCd<8>8SU*}p0c<Sf5Ib-y8Qf9U zfgEB73oo!5=#3TNG843_0!eigq6Pt%yilirdRO3+nL(M*2ShmOz)vFun;8t6`h>RZ zL1|gXP{%bQKqDYnQwK592P<!2XW6N1I2s!17`qu7>6w6*E2=|G3Gs9ewo*_>(g@4; z;4|*9r3Hu^zz6t28&-xoUYa`4))R;cs=hTq85$N8&=>~m4DfIdGBPv<^{AkOemW3i zASUPpfN!3I1_r3s@N@S<1b~7<K(M<lXsD12n&5*1JmAI|>43(<P>l<KC4Z2s(1RSw ze28%<t}_DHCd4@p5o{pG*@BkS2L!uo>Vg;`5!8YZ68NBcN(Xd^AxHsI6yS_IL!#pj z6iSdp;SMuRK>=iqZ9p(=I1(HkG<1ofA!3aStXl!gq6Y9R3U&qd910)G0SymB@(8Tb zhE|)P{Az5dV`z-XvkF{_oFTC45mIfYq!ufLXXb$@SUm|ILr(`+lAO?#1dDo*WuPVt z5%CUl4Lpcl{1v=G)hD>M#igj=mtRzp0j{4=3RAG3y@CS*{C!+CK<x+c1wMw*M6U<F zRX_*SZ?)0^$-s>V=O-+hA+0KH&~1%qW<W>ry){8)S#W+S@vhOu>KtP$6CIFYV3$A% zybi)J2J9j<V<6=N$T)Z~K|>N2!f<f~P|Xe<D}}V>4K$&}ae$krPl#&}B0wQY2C5hl zhzQ$2HiBIbEvCUy9|jrcfE4K@6w)xKYJxiKhLH6iAPdlwzA-H6gKfs1@<9%Px*nXA zkdnKpDN^->nbM0CGV+TutMc<o5_3}X6kIaPKnuq5suZxLd`@g>-^HDXln+U9Ag?NN zI;9q+CTHZ8=A|ouvY2~OVoGLeUP)>mnCp|Do>-Jwl95|l4CXuKr+}KUrODaFpkV?~ z2q`Fl9haI5Y5ibkOGg)Ibph@YfJd=>(H-f5qu$^`b6}AIxWky8n3JAboSadfnU|88 zo}HRmg3S@oWCxBZP_xwCM*~!df?ePPCVh2W+;u?3g@%=mp(cz42_Dd>7rYFEwv|BB zpzaW-I(q9k!6zo5F$}6ExD+6Dkvp_%10@Df?*PrmL{)4Mhal2EG+RN0p}qq}0cdOq zG66x8Oa+>)Kxz6w6E|oy6>{J@Xe1fb*nzfqAP&^zf|kw5K>>~cymdUpaHP5&?olGW zX{ZS;Mls3`a7sWbEkFq}1hv3`*bXHfL*1}6<{-l*3JUK2A^r-6h9<Da1K4zEjSQXz zfi~|Twh+;{!)zdcr_V!hH1R;e0iKTnO)|kFKE%V-4>i}6<>x8*=ccA7V$CCv)Cx97 z1JwQkxt4mFLjlxpf#nVbYzcy3-hfTgK;i_JE?`Lvl>9+>fU<_aFKNjK=4@D+1`ix5 zC_?6~umuk&O7LYD)KGzUHK3gwq_iFoOqxp#L4_G8WTEvlX166Em`bf)L(uw07gyK- z4y2F<c^o+{g42nMJEY?W>IsA0hBU&9XMhNj#*vF5P??XnM22=*wNS$s(Mo_70t(QC z2a|#713M0sLCGqX;f6yRJ8&+zgh7haP_)(#)N-h!Ax_8EBZWB@sb)chen5au0JtWE z)N`<!4>D#B3$qAcKSUfr6B{UoK$GDbQIM1da}9K?NGBA$NddGDDIiz}CJA*O=+-sI z2vGIm=LRdip=~Ef2*Oh%_)r2aisxk%QP#A9+Hs)G6#j0o?JO?PT`TaNDQ=#wJ}zhz zmndd{qnvaC#f%USR|PkJA0Pj4kZYh;ItIBaxJH0RKwMq0FX}`wgLEf=b)c95S~;O$ zXlSK?vUpkpwjBku2?e~S8>|ySU@^noN&#hcE;(ixTPdI{z$V8GBP#`z1=t$F0UoYF zpfi^hJRF03{rx<hA<NWZzQN)b6DtMKS`$ZSSI90Wa@=8Nr2tyB0x<xzk&}opr9827 zDMBk8SQ)DTo}~eg`NAg&Ktn9HpoR;ET71({py_i+m?6vtm)ju2K^Z#22{LmHogN1@ zir`ivwBRbebzD551OFh6u$Ba<?4d@eKpc)tB9#QNxDE(%4Gs<saz$1KV^ej(0(xJQ z=#kK1XpxC)Ae7q0CCv9A8Y#d~_gR1>p_n?M1j>>A0j_?aqS4<?A=J;w$KTo8)djRC z&Ivqe4o~LjAqgL_0@t7*C;K>t`1t!F#*;(CkoqsM`Vo163e;PMcn57h1|sO<k1_S4 z0Go6mW%30&o8e-BsPOz;T>J;?v<ckvpn)@3utCcY_!u-O=fcH6yYqvc5J%f;K<9Np z=cXdD5ls{Dm=S1>3NoJqo()m}Z;@B<f(U`kSJ3kh(t~%`A<j|&&2~YQfM$VEH5o#$ zM1d*=Q=ws?c@Q0MO<Ooi-%!uR49W4SImM|+Tm=QVN`xLQXa8U)Bt^*Ar9fJAVA~WR zY#L@xP(p|17I5X44_$Q(u^vuRCwp=!D!AnrDWs$(m8Pd>=A|p-=jBvFn|a{e37O;p zImA8QT@SPe(!ki*K+nv;Kpm#c(=Ra8GsqR3Ep1_$SjRQOGdRT7H3BpW3U)NkTpZ|# z)UX6MCnKD|WAxCOA==d&kejw#prP&J83x+5>gVhVb}uGDr67kG4C-gNhB!h}x&b67 zfEGGJ#syph_0U!uVa~b1M>U~Mc~HVZFCjr&0YI$-P&o;^BN<dcf`&9<xfR@<rSfV* zTpOfyb?p>F{6idl6hb_GT|t+ddWJcMc!s%xwoyX@22^8!S+35$;cg0`-SprVpR>Pz zkc+3EV~8tgZ-atws85JzfRCrEi-J=mvOyrda5Er%14v82(+{lC#WTp&8NBflq!Kr# zQfwp5QA4IiNM2E(s1Tl6l969p0vW5twhaMpCTQZLGA}<jGcl)FA+ZRwAPllsAvJ|d z5uCZf`x)}{QWZcO7)nZ0QWZ+_6^awfVDsG2A`olU2+qPN)6wvH0KB3A)U1T+ho(tr zzZbNYQzsx8Tu>WoLVB98(SB%;7u&d`A!rs7Hc|(!Qb0Kbo@Mfj^gtaxN2DyH09jxJ zcLc&2L5|L$A)qmB$UYSxkXvAFT+lo^s-rw0L!|J!3F=5tZx^&w!_N)mGFaMyWFQC+ zQaym#P)7s=+d`%VLFE{>(iW^3&wveR9Y1KGo2<b|v|&hyT~L=nDe&|Tcq|bTkf7CC zu!HAeN}%BgR;2;m>H{Be^bFGhSE!KTcu;k01#R=A497##3TP++)M?RyjKzZrCoNE0 z0J((Hgf9?73R;*`@E4rOj)!<wK>;!#YYX4!1zT7Fon8QSd_ur83uO8TG}KPeOEBj{ zd<5lzISPsjkPQi-<wwpzuAmYQRE@%mK0Q}w1?UcOr%1#R9k7f6T2-oHWT*pL?P;qH zD=+n2ok5F9!C?S7)XvCIM_nUP6PKt0T&seMXRvdSYlvqQWWzV85QUu!0-H%AXk@0b z4#+O(o(COu1qB7j@<z}iot(tV)S_ad%>o;wuBG6p;pgKTrfsN+UuR0bf{}r#LMD7# zSlf^bB!C_kX@(YhhDM;J8IIl>@GDXY`V8h8C*oaWXn^J#Lj$m56p$=KxW);|HQ?2{ z8b+XjUCR5;@M;laIh+Kw9H5OLa1Mt{pfadbBSH)XWn+kCdVa2Y3I?!}8#I**QGvV? z*xxq@GBg2MR}W29pdkrpPEx>ZA6ddu2`s;ZyougG^7jn_l{}C!4``_cY9JY#>VuZY zL0kfNE2Mx#buUB-bVM04RRDJrxWdFTy9C-z09j~&JQ@!%NdaE?!B@vZRuXv{gBBCP z=9{33T|*o}MZ7nXIRtG71tv9Y2S*<nwu37)Z%th)xC8721yHo$a0jG5h6V|^xJ6;p zrymDu=R@NQjiP#%0$GKYq2N{`2JT!#90}*A00RSCLjyx&BU3$Sm|<ozBST^`8OS<p zxy;-gDU&HEC}gH-_(HaFLE3nz`z=8Jz@E)ORlK9Ot)sUF=#my)5Dn|xfHWz%IC<MT zK_x*nswC1N5Lh*gaPe301XUr95k3h2LnJ{S(g5#!)U-9yLgHx!1cSvvOS)Ygz4hT- zZ5JnRO{{zGASQxFmBAVe48Tg!ZS-{0@K(@s4*_=zku0=DV(TK<x=53XU<)Am0L+9C z=mKbbNLGQn0#pLJhCo}|*vdap6rilcg4hBgDJ%pLn*_)#2BB?N?8R^pv@k*{KjD)k zaNiT*1W?f9D1wL!14!f%Q7q$k3@HEODGn7BpaWPSM}aY}9EDiL>S?TF<Yox1cf3KX zX*586pa>^@BOPx|5I+c601;}aNeVm%2(}VTxP~}_(=J>&B*lT{KyLJeZ=OUHTOl~w z0ANiBWr5JGdgyHh+BKjQKurs13n~Qc8VrIuB|WGGN9J%kyrc%_N05Wj+d?7O%4kDl z18^ZtyTAiE1sZmsCF7oMp3Vv$p}w9jo*|Lw!APA@gr+%ACkryZ3E8q|4y(&>hESj* z_8>B*aS(xy)J0BXp<xQ34S@>2jzPf+8sO1e@Zb)p=%P{(LDw&!g^`gFeApLfAcck* zA%zlbenH0w+^mMK90pCy(5~$TF1w)TSb`TMKxS@3{6T|XC3=RS<AvZUi>l$}j5rzu z)Xz;VNleKv0qsPCj5R3arKYB&rYICAC+4K4D1cT%7At6!Cg&FyWMt};L1@^BxnF*{ zLOJM=z*NM(70?iU5_ES8XoqKMacN=>#2h_XzX5xR4j#}0M~ss$Vpjzj6FcCc9xv4S z7PPq&s1itLNE<OT0~gRo(EzC@6cvgKQj;?ia}-L7QWHyZQ}aqd(WOw3pOadwqmY@V zke8aAT3no1R0;Pg%4`)V(NXBP%rp%{Jp*0HNR@_{rWTw9*@q7sr-$wd1~r7RO-Vua zG9mATLY>9}jdwvt{9)_lpsA76xi72}S!k1A3h?PJc<{q!z2E{`7<w?K%&=L78jWB- zkQntKJ;*a{U_Sb69b_9tXqbkn6==9n$4b-I0I5p?(gWUT5gMjpXk~;&8hmS|YoHz| z+@S-+iVDG{sVN2dIncTQY={EfCeUhmLrq)Ah5*p|d)&&5G;JX#_h2Xkw|Kxi5{R@2 z)Se>3A`E57O(&Q~AjLEEj&INcUU1By4!(mz6SPAYlyiJ^F!~IjWpbXj24Go~G6P}< zs88VN=cetc=i>?rS|4c8LS&K2&@c^8Z9^S!p#gOYXz{VOC-NvdOanO7U>pRE!wg-J zA8;7t=i=#x7Mzfx24O0Qg*~K<P^KwBw$L@C;8_#A^9sDs1{BmfMksw(kn<G?1sGPN zVBv<%JR-skInN@8DTEE0YAQ(0Q^+qZDJU($ehdL<)Eem&0v+hF38v~g>gDR-sgm+k zg;LN#2C2CPsYQt;rA4U<`FWseEB&1OJP;Fke>i9td`W6<K~7>xD!AG}l2ia4kqb=- z;DZ;8;HNeq_I;zd#|Y*iLv`q}4B)UvsK;_BgOLvW$OPD_3}~9bqq#`FHUhPSz-l1# zKj4N7v{?>zDZ)hXi9bm5ET9w#%9-$4T}U*8PUkU%w6wr&QZfvO7zCQSA!vsYk{zJp z05*67nuRfh)_IV*4ak6wfr4IQUJ7K^PC+lV5ImXzUi=PmC$y_hFc`oyE}+RcP>Bv3 zwS~AF766d3C5W*oIRu>DsbK?XE;7I|2owZRYrq)?n$U=|21}O<)f=$x7sLkQ3=Ied zB@F10wxN!?p}GzvNtl4$3UweNDHkIj_MrqmZvk}Lhmwv`ZjKVHyuqcsq_QB@Kg|bp ztc;S5QbuJ`QDzEU6LIdv)~iAf1xODIJ~j?YY>=^E@NRSTfkK31ab#;FSUCd;S6t~1 zDMv%{AJ*vtbhjc;9YAKS!A=DY%RsUL%(>8*0J#BsNMYCynX5$POQhH}wE)E~+(>_4 zTYq2B5IbCiNGtq(kx~!DYtS49%UT8oh9Ijz&Q?%B1T~hz4Wa}*<^->bA&nKNt3dGx z8nS}KB2wvq8CWp05EkN!TQg`K0@FdH$3a7QguHGDofm@kjt4S!T|*qfV}{U>Bq0eC z@+9%`3l9cJq(TB5!iLRGBccmEeSqpdF3_?11`5F;{s9W=!J*EeOC;PveS9Jn+&uj} zgFReb6reY1#0LbqT7fw3L5?BNyBC7hxfF~I3}E_${6j-L{aitcK(pWw9j-w^{z2+o z3YM0ZmI}os`2`B<c-4XZ;OgfBb3av1SpyHAK_d!wpr2c)A7mMlr=x-fc-MfTj-RKF zpO=oGw~jk}B`NCBwqVzRFLiQv4N`zB2Tw&n%?BMZrvNce1Ev60h=b)|o6*6XAkeXi zL7-~@BS3_sj-#QDBmCq=kc2JNEYPlb_^bj*8&(OZBS4q_8W@0gX8U=gih&O}fSn2n z?!X%w7=UM5{5+v5LB8~KgM|usLd9DXH2DE?k0ywK*$wtM%y-ze`Gn|!T&oEp(6oUp z291FDg?Rdf!cR;D+3e^PtO3#hw-vNf6(Q&vs0VTdN{0s&eztHWP@f>RJiziGT`(zd zYXRhDq*_fu1EdU88p2lKKood7D%dI@4(kjF4f4ZnjH98gkH5R2fr5sHyS|};UW$RH zKFC;DI5`@@<Q3e(5(+RGPd5!mLvqY;Yl6cik79bxBxfP4iTZ30Wc29zLKAL3-F z`@o?IiaP^M1y4utA&8C$>l8E`^?X7=C&j?zbPe?kVDeBS(C@i|3PUNR%hw=NJPPn+ zuM^<mi9E5x#R<<%;KZ-tsOzEQuNwu=Y+%s<4^OxWn&2aReZ#?~1i%m9^0W2x)bjJv z0;O%JGlG1BL8B6!zTqGW7CPX3fSR}=LfCQvEW2<*0x-Z9<PwY&4zei7H&{DBD}YOZ z6J(!nxOM;+WJL*Rm=QTGgA@k`28Cz@`3CFzX>vi7>-%wWa&dx2seFUAf_#H@eZ#eU z!@&`u2Z?n~1qCin1%+TwcUuEJ11?TbjKc(A<{@-KPLu)F@UXyeMNOel;o)~18S4FC zbu_ti3UtjEG53F&nwgmy7#V@?|1vcgz5k0Qae;0qG^dW<|22C5*XaFUqxXM-iv!Rc zJ(z(?jNbo+8Xlm7_CiMQ|MCOve1Wd+24BXAeYZGj*nv(tMiU{O3reTpJ>%ewUJ(7D zLkdARKL(B7|7AFO{}(t-fRYKAfkcen|AiD7WH3Qt>VkR&;OPBd;8i)0l~^F==>1=) z2@5^Xp~_<NKxqt9lr$0Qtc_BHjirLF?h5b-@pp&aUjq^tz5mNq2kl}q=v_vm_kZEK zyA6Cn66AEd(fhwf@Bi{s0IlK&CyLSgzeex>f{r%BCfXq9^x?T*YV`gu@PY#9b_uj4 zsh|b}#wq~lcKFfzzx)kG@BgAsBN3Wu5xaOmXGY+<@?`Y>FQhXxp=;DZOW{DbD2(3! z1zv4I2?5`O4qBcBUF(l|A`f_hCVV9++C~|}(fhx`Ts21T|I&tBGzQL`@MQ*wHBqS7 zb3qQs7`^{1DYXc+dkSd@_t3rn3v_Y^s11dDng#f78eDZ7=uiu=29&DM*KhRxFUV+s zD`<_>=>1=#_kV$oOB%iZ3v>aii@(C?{a>(Ceh^2_`TC9C|K;f8qX4^R30&=vaKRS1 z7E&0!|4Us{frz`?M(_UuUylhn<Pvl%(dhkOiVCCme}M}T$hJ^06RnsA-L!;$BL@1Z zo7j#91$C%&U}sB!c9JNJ-v2dv|CbMF*D5^uz-~bS-EjiB7X@<WDEf6opk@7-x6Occ z;k(5LZVzNM9Nkn{YR7&Y2W00M<eC)tHBjJ<YQfaGR1dU87BWNX>E;-r69v6(0OD5Y z1umd#ThMmVj^6*}2tIurveA;PBX=Rk&4LaCLuiMsfWUXwF3PQWqxXOL`um4?&?IY& z-v6cJ8xGpo1lwl?-VLvzr2{!&&lrB#8@^WW=>1>Nq7+hw!wzkNAFv1C8VfGep`B7} ztsUq!3ZwUb5i?^04J>foiga#VK#*&IW033U{a>T^e}R(*m;kSBHypkHE7VQfSW`;_ zTwFn?qd*rmfWruB8X45$@qrw$3F=(I?nVGF4FL<lY74}?1o&8@2p=8j$`N>XZ1nyw zaNvSVeo!d|I@U5I$k7LUMGol1NzjFuqxXM}-v0$kCZKKDK90zT1!}_XAOmMR+v3bT z4P6UMJxfb1=tW~G2Jq$vM7JU2Tp7@XS(@-0%nUWbS}}A&SK2`PrLas36$Ky20NR`m zvKuZ2IwWEA{x48$fsQ72@u$k6AjoYQu+b0#RA4}l!v$Tt1v=;~y(lvUB8ecWwCZZ~ z{x8ST`@cZvBvLm?kKX?U>CK?bQA4Ii;CFSE6eZ??r%Vz{GV}Ae6gd-1(-cw?ixqql zL-c+8{S@3YOG;9UxJK{)f|h!q)p+p3!VDDjM(_U$@(gh$Y1{@9lF)h`O5q!mgeifZ zE(SiwZuI^y*b;fj%3IJ42*}e5pdJ(Em1eMzgdC9s<$*b)_kR^-mZXAiFvEX6+35XW zkUE6|l5mp~oWmid1O`c^CMU#PP+<<S4DGri_*4n<ib>E_QJ{PU8)|^;NC7RCgytm7 ztBDLp@BacV{(+o{h8Wk;G1LJCCJ`6Spw0?lxqS>AeV}<R5^o;^ZPwEnz5ff852&7{ z!0jW@y#$C0^+5K3F=F5jbkr#%NkE70u;r)G`@g^k_koHXL?HtXNYFjPLC|9<NALfF z1POTH2y~%5Bq<?<7<d>IOEE;`C5Q@?UV{j2yJC02=>1<fZf!%9{-gJQAzEBG8c@i0 zGmYN=g$OQG7LLF}8t?>7l#Jg01uIYy^yvLxs3{4~!=9wTW!LEaU#?-Uh?`4C@Bh+( z4A*FQX=-XAv0>BNpxick{}(6}KzQ{2FP+i*zrZ&jkKX^~7y-U9WAy$nP{9DfqxXM} z-v6a<XgqrV*XaFUqxXM7M!aCRW5KS7f)tdHeLmokau-iGH^@4z(fhw(lRThVAn=ei z_;{Vs`@e!+kZ%OUd%N4{{a=2g_kTgJ3j<#g1RZh*-(dv3vupJJFHO*`M&O&gK*Z?% zU!YoP^!~39(15*<!sz{9qxXNI-{?ddU%4o;Bvmg>nKWIbsm6c*mw}mqkuigzp}CQn zv9Y<4fdPYop@F&C=>1=$1u~hcLB*+pLUCzQQGRJjW?rfSC_QLoW>x6qRp{hZ>SPt< z=Tz$C6(knvK&od$u#TMK0-c=V0!t8Krpd*nMFqg61vZ)@LJNl>j-@3T`9)R=0eT8v zj=rwJcrC$Yh>?MTfv%yEt|250@S353%aFvB#DbF46e|TsJq0IMXK%cw;4;L>z`$77 zz)aVG5|`k$8C_CqP(?A))gx94AsLy)3I#>^=|zdT3d#9-WvN9a#R`cE#i=ErLl_g2 zlS^|;a}rBZQxwv2N-I)}6%@d+<Lc}i?xv8NpOTuR;O4B5mYJH9Qml}fSCX%gT3DJ{ zmY9>8SE3N)7~&eNkXWKnl9`*TkeOA12pLf9_yh;&I0t~lqH}ZgGm2tCOj0n&5YWvS z!NDGG3JTHT`Wm@fxtb&z12V)lJUCd#FE}_@A=-~@L%?BKmReMtnV+YSmR|%5mBh4? z)FK5#BV7YaT~Ibq$jnnH&&W*9P{_~AsYD7skW0!lOEMISOHvDpLE&$#qhO|^V5tDQ zF3ZqJAtS%Es8}JfC{-b`EHN`DF)1fiA*D1`p(I}c93imSF>%o?ODs}IEH2K>&CCJs zFi<G2EG|jS1%<9gW~!b-UcQ2xJJf}mAW;+yatVq6IUFh_dq~j<N?WPvsYRevq?4Id zU;-j?bux9bbTSi@OTeWpRAo_WVh%V6bwJ@*l$e<ZW)y3HN@DmitYB3+#RVGZWwj=_ zT!spRwSWXHkp*A_7@*ypKAyoL3i^JIzHSjl`VbeO6fAxbItqS~I?y{|jgSM<*D)f* z)7MqUE5P3;5?V!o?wx|G@$v|AgNmEL1r-z&f_(f9bQFSo91V07Tq1N7Tq0pE0v|40 zkYAjan5&>+qN5IRmpW{kvnVw&1tbm;hKB_xoNSHF3=H(NvNDR&Aie+xAt>~0L1Oxb z1_lOtFl#^>iZu+aj5KXQOpq!hO~o3<R%Q?xn1;-(0^8jD6maEeXrvD^5#}aP^x0-+ zRX`2MOjFPR3F)Pm=$U9LfS9%>Fk=deGV@BbbQD1PbritK07T~MfYrfNrQ|E**%~4z z39zAA1qynpg?b>pnhGTusd-#l3T}`>4V>%JGK-2!z`oW2Wsl^H#Ju!Wg}l_%l++Zc z;}jG?DF(EB7UV9SJWX3PzCI{8iZ$|Jo&(LKDnM;F0oiVZ)#~67*8p1sGmwM8j>u0_ zNX*I60bN;MlnQdILSBARZemVmacYVJRIx%?VoqslF|y0dz>90~xk^hRBqKEs)MhCu zN=z<MC@4xT%giq=Rxs8D6)riIP*b7FRe^X9>mrAQuAvU@ATY)g1eT-(fhE+j$U$I9 zeh{FBD|sORivg&UK+zBK5mG7x+hS<MrKJ#DnuHb!U^xSrx5#q=EC66G$V*Ykgym?M zbMlK6%wX}Il30=mRSQk0xuA4vh$oVashdBr1rRtdU<MEkQz=R~p>b03p&?Y1T2fk+ z2j!&ZrGPRLa^rva-EmE3*Jwm&19kWG(rD{dLj8XuGb3pK-^j$p;H#0Y8P%xma zvmmCI7MCOzDJU@Hq~=2eaFC_NsYS&&<c6>?q)9f~|A&MFgv8Zz0Cjvu`~Q@T^xzns zfdo5|Bq(-9`~Rqc1qzeV{y%1zpo);e8}0vt0&OVt|3M9ZP`4P=@Q3xzKyC+PP>&Wm zIAE*?ZTc!Gfcwdye!s1;9&~H~tXcuw$AB=Qs-T+9uxU0!(+p{NLu~=sOzJ3u34EBr z1l9-7%qqx*iyFa26O&8mG3<aIu38Fi`9+BCHfHw=JWN2x?$_w>L@G)Uz%l^p;1INH z4(h8CJ3<5N$3s&ycqj$dJI6h4gmZ)j;sP`1m<M@-1Ea$e#RcF2A`*u0Kv9l9elt2e zF@(EqRC79LG#xZ6M$0h({QZAp0~0d?216qw6H{|zb0ZVb{J){8$>{t))#4bRL6BBX zZhlH>PO3s$PDNsJGHePWIX|x?F*C0iewiflC_!ps3MknOs##%(Ur<RZPW&6{8lp^n zp;`pzf%;-_4iaN@;vXq6$YFv47I()VRFD-bAW!x~=9WNH&`7p{3_;?O$AlRY80zR3 z;u#W&)f8XHpkM_@C#N8gth2w1D~LwIFhh`pNN2(f$w@3qPgN*RPRvOK&4(pt7G#z{ z=FA~x`UHd5C@3f>7@A-tVwfS|wG+uDnPu3`P=Ks+02yd#f-=Vo5`r00Tw0Wtn4GFm zoSIjh37Xu`NKGsOFT4P$Qc!@ba{#doP0T<PGR80@KPRzBp(rsW6WKE$L%^X5@{T!9 zLrN8jONvs9K?@3y?SQjE111oTp@jj2fgoWnDI;JAc)<l&o1q2DoH<BLOMzMgULeyb z!qgqePzVinRd5gTbc%Nj@PySDnRzAP)eYIDd6^{|hDMq?nW;rZIytF%=@}(DndSLK zDUh`epp`Vx4h2k4W=VQ#F=#mix_FjOX0A?VicV&RPG(AKj!tG?icV&-PF8M;PDXCA zPF8+tiB2YHby^O(&XmMTolMY#uudkZ6Ap7_az-L();P6D%MiTw2PU49UkXaC1x2aJ znc&qgS*1BTS*1BCi6yD<8W6PLLI*Uhou8ao0$RGFqmYuB3rgwvdEhp=m5!CBf|V6$ ziXF7#0#utqqK&Xlm_9S8M~K&9NwSViqI7^=1Sv%!t50BI1&uYG#GD+g0Rh&S2@W}k z?+IyuhFWHNQDzd<X;3Yoz${2CO3W?RFw;a{4uKSp2KXJ4mY0~D3Uj)jqp#~=S?=P@ z<*eWgS)q}VS(KVwl3!G*keQd3uaK0QlV7f*0QaK;C=-=rDCCwFmvA{NB&CAZxfO%b zbzX@Ac;QD$Mq-IVVp4utDrDIf$j^ofsU^vJT+T4RL&DKkL*LNENXO8`SjW)BOvli| zK*!L+P{+{ROkYz$5wx%~xj?75I3rCbwY<1kC$G4;Sf{wS2xbU*t8+3T*~B)lLMyKl z8pEJ<Nw#J%bD?P|RRbJdpyC5I%9WC@kZEhEV`v1`r=U;{K5r4CFjG@UT_e#{$J0p9 zNGH))6Li-hs1Ax(*U8jTk1tJ9hiXgBOG(Mcunn~017r0R%x1Woa*7KQlary#rw~hG zHQ}p|kX2?v)q(tnMFlutXyhhVfQmtFBP=RF#T6*IgKmX`IvyefUaSNfjDw6;Dkvx_ zfQBy>qH}faa&u!*)Pk2UA=X2I)aI9Dq!xjz;?!b=XfOTTI3opJyKoR43kw*~a!6Zs z7g(SvDCEE|h*wYm$Ap27p^*;A5m4(uIXp8>BU8c70J`1+Bm%?W<O0gp@%aU*dGTqP zIjI_u3L;Ze2N8os@a0_)jR<YY`K5U!@tNpa;Y)Ks>XA2dD=0uB8YB+F@R$J?F5vZZ zI-uJl;I7Zfu{DHqQt}nDLGfa1r~{25eNdxcQNbrazd#|sEVW1>C9x8*U<ni=VD+E? zfdvf6S_Nb+;Mh~pFw`;DF@vQo1%;e~#3C!OS_N>>W}&Y4g2-edISwQOcPWU22qo0b z+|U39IZRUr;_ob-Oidky%%ap1gabfEpqK}W#-h{`1zTGMUD)U?ND%_3R%Did9gd<8 z68<Pc2&W-#hzGktsQ^@(d!{IXt8G-rfb1_wEP~vb1y)zAk)??xRVgS0hxi95sF&uY zRurTrgO>J!m8X`Z79o-@$k`C5fmkq%+hw2%OGzg)C9x9KS-5q8LRbmX${<z?C@lnm zR^=%{+9mKJ1meD|(i~f8t3w0i5{Thih6V<x7C_Z$rzGX1YJe(&0!@7|+sH%@O)1#< z$%){Wj0U(>18F>=8VD(ta&k0nvvN~F_GxG27K6(f19<ZX;zY1{;4Gb<S`uHJS(U1R zl*ZH{4F+|cywcpH)FS`1Fz^yTP2`p^r2N*>(b7~<M^$Evt`BszA;elR3D3<CTQpF0 zYl2oACYIPDCv(U(R_UoF3ZQ8U=*TltQbq9%R*yieLJqB*oJ89kSc4PfuFN!zoSZ~E z6HNt>lnIjYpaKPyuVIxQNHsXO=YT|E3q~QL&{`%(CtD{cCs8L$(-va2MqY)MMqZ_E zwx)KDCUkXX7P5QL%RCsLOA)j-R3WV>KUX0$FS8^Qx~Nzozeph^Gc7H(C^auRRUs+0 zq&zh>52f=A8r%V|l!rJ?0WnsuppcoS0bU0SO3FHhMw+1V0#yEC$*7>}6|~e8>K~{N z5h6$-g*xemv}zNVUeIbyP^}C#P1jHdB~TzaANhPOq-2)`E`7jx9g@Q!nGqcBAU7N8 z7=qbICW5OKNZAK>HK@QULKK*w(vgcx3n~px6bhg<zzW9DpwUwB%qvMPD#!<IM^H#f zMINqzhB&x2m#C0jnv|KW3)*~>m!AucxBQ$^@G<*ZpxA?|%FR#7Ov_A7QOL>6OHC|N zD26Hmw*f&-gS13=It5i#wuU;0RunkprzC=uX@L9;3P&qYHIY+XkO}V1WNISs0)nMD za6mx)2sYFhxm~WH05uoncCyU{r8=bOQuoX&u~G;1s4_J`QDdbE3T7>Za8N@~A-}W) zytEz~t|<!okf7Cr?hOF%-T-Y90TtJvL<@C1*r8xs@=HrJGC{JC+7h~69Wqb?3Jo1_ z?NSU%FD0oOIXSvUnou>6aS%ug653+Wfi`x*p`yvf<*cBkrKJ#@k(mY^2Z8Q1NlHx4 zR>;pwRRHyuK^rPS4uCoh9Il376QCmSa0O`tg)1!SgQE=M0C39`7EKr$z)^}zH6&7@ zcA;cNXfjSM)I%g=F65wxtT_jJN<pJE57cpk#RSYPM29rkjfOf_nv{e%DDi+Wqyzx5 zzy)Gv8my6<lVh8cqiqP|g8i<br~pm@upj{S78DdAtwESVyh~?cBjPZ{NTcPXr!k^a z7bUB)V0w|OW=Lp}PQu2^&~=WEzoUl;iF_&z+)-(7CFb}$dNMBt7sn+TsgN=lzV!~Y z{R_JB4kZMTiwnpOFz|*Jg~HOrypqh4%+zAg*04kcP=iwe)P2Ne2xzBTYFTPgr2?o7 z)dw}?^-yfV!of(fe)%P-RtkQp>51SWa7fz=yi*OdldvRTp(?c~A6&C0=Hx)D77RmD zE0R+SN{~jmvDl0*gkcD}0%G_WhJeBfGzw&;0PgZ<Wo2dM=BA`%WZ*Fk!w@`baY|7s z#X<|>(&AM3NV5X0Yy~A6@J2eFEXWWrXsiXQ0WJqh1sSP11v<#(I$}r-B&}s=paTmh zEfWhJ(CCMjp-ypSadLjHmW2VDkvX868a%2E@jO%-Zl;#8fdY6;1Kw)^4dQ|ZgHgtW zbRbC!)U3~gcQsL*4XypaqZP0^6s`c26TmV$hVafK$l<o?&g$^SC%DSd0QpfzT_e-b zK+n(sG&Bb8<#8bmJc2T6T7FJWetBkIx&rDjBxHCJGFpy20*P(>F(oxQC$R`TOT*<1 z&Lm2(fK`HwOL93wg9|2Zs}5@Ns_TQZD=cQgEd`Jdk;aRBKo_CH<4H%o9C@$^d7~WE z0&wIY3@T17f%fb2bPP3hlt6(3?&g=Ig8H|x@Fk!NRIn(45(ubUUXrQ<>XC!G$wX=g zH9M7b4B!z)z&3Du6EsKyW`H*1A=^Vrr&0mh<prfScqbCHbSqN>)X_v4M*}yL;2VWN zP6RiNkb)I=s6x`T5;Se&@+Tx&LWT>#vEc*CQb>M7wh&=ia!!76DrE2woEShOqaf!g zC}1?nkhe2|ZObn$fh8`ax+*0R+&`&EOU+5qDF%}$ZD?5Ah!T2ew5tq^b&V_`fr*#I zRX2>TYrq?9ge5@%i`lM%9cTb5_MzRWVzed|sQ63;@3Ds*Xpoo(Z9su)gB<wYc!knp zP}vS0Q&0e<d$chH=vIF4sR+sWdBv$kWuRtPMk=^lonDlf1GWWRS0I)VX67lRCMIWq zn_R^OiFr_;g1i#~)e3cZ3bYIYH>UDSOA1O$Abs*wh2+${lA^>Mg@XLdJn(T1AWKZZ zE`bk@fX*TS6~7=$aL(pKZAYd+E<xs##inj+1{9mnh6}V*1-B5u#SnDb2-1m%lt~aF zSn&u}T2Ps&Q&5?tQ&5?#Q&5?rQ<11sk)%_RtW%K!E9O%26-*2az>{Wqun|V67<i5W zX)LlL(H3Gi=nw)!m_-T-3KdC667U7*Ac<ro31eg(DM%9Vh3g6m3I&ykwi*>Fx)q7q z#(G*B6-l}k$(ow_$ZP2fDwAwADw4G;5;gUW^mHqdbS?F?3Mv!zjgS`H7gQ$Of;1=U zn!_Y@jX*5elrh+@6x)hKU6582J>7!JBz<ELm5gE#xVYEI1P!oSfb=J7n}Db!ZLn#{ z+69#<T%Z6{0L`+NWagE^XOA&z8;lwS76&L2;2|4uIHQiIQBt|U^bV0q#$xo;99WEz zOvBO?(S-+012ofvX3q&01fV7mC{KV+jRz-HFb5^)!<86mB4u@yG61f`7+HylCb9Vm zx%HNk2+B7wzo29&@R&8&m5_3B#AYiKT|<neYgno|Ts7fn+YL)#ks<^NSn9Uj+}y!y zIzSUQkTE8B^9|Qz4`ieZ<dV^57h2g0D?ErUIU&UfmSz`HGfSr;F<GY~X|Oi8KpP<| z67_OQ^bGVg6)F;K4UpPUV96x7WD=%iGF&nlQ!)iEnSvr&kqA<3s#Ss16a!hMQIV)! zk*o=t1BEyS)PmEhNY;l+K-<8eW@Qq{L{qJbWP}*Rge2{X6od&$DYg|!5EH->2-Qff zx{AbPZBPV}(})9AE${^opyN?;QT9gQ+e<MN<%-Hd%Xp3S(ku;V=6wA7e+*4cLFa!M z8JU=y8<-e?&;K+uGBq1L|AS@`f@CnHvh($K3H5PR2nq)$23V=-?C%%i=;;>>;|GU2 z1^I`Dc>1}5P9JvhaSZYC_tS9m^l=5Ps?~9G^>G2;GXo-=bRd@s==cUW2Ej)Iu`L_- z^bPRwboLBU@bmX`g;}Kl8F@%8g18SmX=Mdki;|g>3NHj;<ve!vU{SE9qSO+Q9wL?J z>EvdEM&vV7bn<dZ(3h!`jig#91+h|G6M4n5f&yrfvjTWf6iGeUwKxcnCtypT0ze}t z#f~}odFhS;iA9MyIjP{KNyK^%x=ah%7~j;Q%#_ST@F7v4K?jso?wTkI;6V-qxdt-) zONR3y%fmn#!8RcRDL1hq2eb$?NhdcawJbFUbiyOZCQugxvK$HOLn|u<bhSFU#U(|V zDXBWS1&Ku(R+>7QMXALlIw_fDAd8^-K%t(a0baibQU<z<TLH1;T1!Jq)5;1w;|Q8X z1Njpt2B%uYXf<M`YbI!}Lq{Pb$kP{|Pc(JZ!K+<CE>TnfFK-2(j+dKST%4Gm3Oa!l z%m--&sX>?vRtsMW3o#oqeh*(32Tnv9c@V#VIkvinkl85Eg4Dzmu+ea<z$?Q*BW@te zz|8~~f5^BI$YurT5)$xqOkQevJV-fY6dqzZ*aD4A<b|cKel7|w{xBQMQx%dE^Ay0t z_h6er_JE8=@)TldA8e>5M6ZH^LSC*dB62{QK+9w^%WNUZK_8M8LF>e9Ve@n#MIdj2 zmg?q#wrPOvg!?u#Pa!uoH@^rp{*{@NpI=}FzVjE{J%+6l15X)fK$a#J6y+zU7J~;* zp=KyRGM$3D4r~VnVtHXA=*(GY(gHaICG-%BU_tBEA*T4JA?G<*)>YS0P=jg*r#F0R z5n)9&XTY*PG0uRgg%|ILSjFz&u+*ZG%;dxz=luMll+3)ul2l0USJ%nS#%>7m@={R9 zL5dmlMWUM6Vh<K@5G!ymEQRMCh}je_Da9285X05cr^j$92T%KXrl>=z9cb8OL(?p5 z`VU+effGq)nnpolQDzGGa8LzMX{M2lv2Hp?BU{rJL}(+{yDNZ7Q}CiIjci>*O|6v7 zGHs9&P1~Z>;*7+CR1Jv3bu{$hWvsp?JiI|8u8`wQQME&yjY!6zg^>zi=flO&7H5I{ z1o9qKJ~K@t8?tmVFBf{L4%CBrsd^9(=H;UM5Gn6w>*VD^9092U@^TR))kw<JU4w%B zgA_n}M{^QOa`N-66u==5T1Tz`4SXH-%wmPS{1SDrNl^EJ&W_11fN~&Sfu%v{`L5ss z0#X_(fD0RtVq~k4Emhaa)HT#mS13wN&M!(S20KU{QV^mR$cXe(l$w*8SPWZwoe3%N zA@)Hurlg{!Y;Xu5iGoXSXwp(p0BObAzynuq3JMBHlHluUq0PTc&;%}Y*<?Pbrohn- zgcWL#W+CXVDc|6bAWs)pGFynAej%>zu0aZ(;G1ILtxZ42P&Xa$Z8ADOIxrhNU4w#j zy!=B$Kyjd;pa9bgYMW|66={N6tv(>aNyo=E%-7QoOgToN>G1?FMgWJM4%oj?dGM_@ zQNgaxCK|qu5k6YJjuB4a5C@%g?CR(P%BP?fGFTR34J0UFikv+hgB+bhT!TO@4+V&v zXE3^xJ$*oz;%Y#oHFbP_JpEi;BcOb3LronYA6Gv}lqrJJa&aoEQBc={RN3aF=4q4^ zW#&S4dj^L<Qjr3vS*?+omy%k6kkU~v$ye8eY|SuG(918<Q@~IW;tyA$sSx7f>Ibz= zK_Sx?L$N;6Dh^OyKv<<=XqBmJs0rF00Er3w#^~sk6qTmx!NL)=CLl2d$+S#uLo1Mf z;ReFv6wB@=h=r(84~n`RThM}05DS8#@sOiw3(n|ZLFBayC`)KTJB&DCQDvwJZ?Awi z0)UzyAm_n72@ZWo1bYUDXk=PtYC_6&b$xYcuyTUzgE$GygqaO?4kvgSM`juqC&WQ; zn{%`cHElswX&Z8JLRT2)aB*S;7|gUxO>ILfI7i!16B;Q{zh`Q~Yyi0iYAJk)mW#ha zwymKKxGMsdM-*M~1vxrO;Fi6T4%EbKc=`i3%s`Ws(A<d#9IVEG3vJMH8E}ryLaCrK z(=?!>kWjQRhc3p4w3)zegREHxm0s~kjw{Z{FDmg%%uQ9&QA#aIOvx`%LazCcTgOPc zK;>bvl8#b9qE4}vmaZX+9!OPzuo>NP=5%r#E|+nFHh1Jeayg`(4Gk<vFoDUc;?!gl z4MQtXgFq`cu_8&+Hpn&D!!f{B16;s?_7NZ=6xwnCD+IM1I3cI2fs!pT24!nvF(5Am zejGGPD;p^mAk7vf9k3nnN)AOeq%ww-<ltHiNtvsk3#b<Z_Ai7D9}`5YD3R(yNU@7j zQwF&@x&#NfI)?-~`oMdDI?fTkemcJ3stS_Nbzrrlf&!@Wa18@jiaL%uPH;C7F?0gY zB+y<6*!4IFP){1%-vVhORy`TRCMlU^pr#n|KnM;OfrY`&(#e7}-H@C{^xz425CM5p zK23%zK;sfQso=o`aJ_G3rQisz*j>Xwb+8i>yP!<N2-FzxaShXk%%*~LSXn865`l(+ zl?FH+Xd7y3L0Lwcx`xo^j3yT}W{4T$$jwVEP1DKDPfIIKg`SC!nUh+kgF3{4SgT6P z_y&0Q7oy}H9pHd8u@x047~p_ztR`~20@8=DQb6twC@MgTFdC0m6r|>rB&O%*CFTUB z!Zw(JMk{hby(BMn9fd4-A%#dHXj?<^_1zUfd(&Z?`XPQHw(pK&A9Rr~$SSygk_Q}+ z3<0-I)OA3a2<|~x5s%B_f--fTf-<;rv>q6}#ulLM3r~MHw_w*0$ho1QLIu*{($vz( z%?8~CkJ^|4mq%7QP)*ukZ^JgA8e%J^;J(Be7?7Rb(0(+eeU3S(mx3{*2OcP}0ymC9 zO-T4aAGl!*9R>hxM<ZpNBe^0MbV3X2Fa>;rEe`)d!;wm(9FRe41#m-oz=u1ELEGkw z5_70I-~p<yL9HWD83i880SO=%QJ`)f!r}oP^nhh#1qDajf-((5D?@Ea%L|fBL5&e7 zkc1Ib*b2E42l-0@>yQbotp_t66dY)iYe<uCgMf)N|64~Z=MX*rYiMX>YGle_U}$J! zW;i<kORM-mHW!r86%^2tC^UVK&i_JYW=H3LY2Kj%r8sccZFK$@d=fxLDtP7@6fB6= z)#&`M0%l_oc?=g6TtxP#z*91#^S|H|dXT4~VRO2p^S_XJV^WV4LgZG|DR9Vm<mmh_ zD2syI9FUQ4FcWfO8_N9f==^WW==?9N6NPn!AZ!kIbpF?6bpCgA{ui<gV08XBz%dAP zWF%}c4rD3A==?8aSX)O4HaR^y|C<yK8JQfN|0RB{{pkEJ^fc4a`CsUH%-|&iqYK>0 zSl~|NIK}9^FL;Oo(iw-$x}z-OLG5La&ijHo)X*v1Avf;}T@e8p2pFCJ1+V9))pB>l zG%R@SBxorI#S7j+V>_S;&(Zl`AK1_ZC^*n2*N|u52A&O>|E1;ae+&!+=6}r$49pk| z4b6?rjEzh{7ylU;8X6cIjn4nlBXxl43$*!PSlWe+uz3YII(zGQ1%&zq=s-u?Jj4Bi zTtL|!X)^_A1VYEh)z94{L?<V;tR%lAF$c7c9^E+4U{_}Y4aibRWbMJO&W0MMX7E)- zQ0sLR9DRKJogG6QoqSw%6kI%gUHyVR{rwa)AU7?6j5ES!hcR|LOf<|)5SJ-H{Qz2$ zsbxXPDh1H?4!B(qJzz1gRZyddb+(^VsGA$i-4L?~*$=YbL<dBg!dpU!T_c7Hk^TX$ zK`<lnOx}Ywd3*YKf)}YmccOrH&43r8!dITcyn}6bHq?*cwaPdQ;G)LOkkGTOK<-rt z4heO01Dy+pcEkr6Tv!l+le8^#*)8${TrDGQV*>*N1x1C#f`X#_3O&&2!zl`&-Ke1J z1l<!$i;FW8^T498aB>3&CupUwlY*Xmh@Jx2bWI3l3tC$QmIE6M)#C-qShiqwFegFN zx~qZ)I9+QPLDnCE79lxl8yOfFAg&8SC<UbmBMmbHZ6htna&m1$94bA*sZIlIF)ou# zG{7#>gd{X52c9cI6&lh`Fi_NZ`oXV&Ly`fle1~okBXB|hBs8?3J3YWF-{IC#KJ*V+ z1F7Q~<chJE3Op<bwHA5%7ihZ}#8I%FVp=8&;B!ZzqKHgqVW0r>9aIjKl|h9ncq;@b z+MyW)yl)HcFYq*BfRlfKtDgqgWF7EEESOo~J>ohbcfgjTdAezUxZv|wpqqd|wtz8s z3j$=%vVuDDK0Sy9Rtk_^jv&iC{oEDQbzs&&oebLC7vdiP<+=K~c)G#TBj|RCoD}$m zB^Q5%a1T!(R}H<8pioymxObq+Ae6Qt7w9k|kki~#OBC`_D@q_I85P4%Cx&_-lzO1v zhonp$aLUxOfYl=)FKco+gN&jghI$k!*dPvv+6t8h-R+TDRHT<$sHbZP+3*Ib-4yh4 zQuP!J(PII$a|TTT#8_Jh1=@!X_k?SNX9#%Rv#Y<Gf{Sa2t8<7etU^Ve8HG6_r$i5Q zBNIfMA~Ztb`k*cbm;Va33W)2wK;frgs{q^Y>+I;`13paKH3Cw=80dhC8AC8>1kUhA zV74)sZ473cK<^?zjRjDdV*+awfJ+rf-06Uu20CD;Koc<3b)IetkR<Hqs%M}Hy}&8h zKPV{D3hX8Y@Exhn{(fPuLEs7=oNCo!DG`(bf?b`BG>kO$K%F8`)&lK91bM(n!x$_G z-g61s^AA3`0utDeQC`Th@_-<J_aH}KUxk1mSBOO+3c8TMM7lK!SqCVmV9hYdihLYH z^nLvOK)!H+M<)DcFLiJzg4_*dARm~A(-_wX(5@j@7bIgqJ_Z*i&;V6HT{9ox<LVgf zs^IM5=;!XL5a1Z(=<6Ed8l(^$;uzxU>*^PR<i+9=^v%nVz=8)d=vE(aFhlQj18)EU zt3erD0AKonva%c!9fn4lkOk&oEudB&sQ85pNTBP1`UYjgBy<-GyxdU$-CR~&f}WEg zIR$C}IDLT|k!H|ss^Ib+T<~ifYNBOV%*?M2KGX&gaFBR21YJ7`u|Z267AflBN=gG} zG(;L}DGFUdj$|98hDK~nhSX2m8n8k_Qy*F*!FTC{YZCCLIy`DMZ6U7Ef^EeEXHX48 zD^RKdw>&@_=|CKC64FQ1{?P4hkeC7`0N0=(1wEe-J@6fHD7$!(yrJ$|RFq!?ItT-F z$E&(ResXeYQECe4B;lM?@cwnsnZt;x29bb3H@89D3fgmysA|B4Q-G7RkAJW$tWt0d zLYy50avFHAH>h<52}QIxMcEERdS3Sn^>uO$Qt)?E2y+bz@pN|dQ2<xk!3wZ=w^C4t z9!3N809qCd3G#GxQ3&yeq$FSeAXk_PdU|?9WIwdV6`~0RD+H0+SKzpSHn70E7jf*n zhqzP=WnVKq^?`B-yb`CptwrKCdry!bLR=vm?Q!h4*D_H6@3@C}0~E0McG5#tfeIl* z4Py&UTSL&^BG9#spwoa9T!S1T7jR|fDkSG57Q^mwgsL}3S09#G<Qfo+VyKacrmX>r zp%{uxG>kND4b4D`49$`<OB7P`lJiqC^U`6l2;Lfv5+P746civXvCy;yZ<qw<Nf&<w zY#X5=D$O))L2;;obWfQAc*`q+{kfRiYGJpQDJVetk>J}TzzzTr;LHhXu94GnPy?BO zjKO6Sag7JKHqcGawjfU%Xds_c4Q)w+Qj)6%Bp*PVk{}H_nV<@`BsC9wX$Pz=4OtWb zx||xa(b+�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 literal 0 HcmV?d00001 diff --git a/preprocessing/flex_extract_ecgate_V6.0/submit_examples.ksh b/preprocessing/flex_extract_ecgate_V6.0/submit_examples.ksh new file mode 100755 index 00000000..1d2f08ab --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/submit_examples.ksh @@ -0,0 +1,43 @@ +#!/bin/ksh + +echo 'submitting ECMWFDATA example scripts ..' + +SERVER=`uname -n | cut -c 1-4` +if [[ ${SERVER} != ecgb ]] ; then +# submit via gateway from local server + + +for FILE in `ls CONTROL_ERA__*` ; do + + name=`echo $FILE | sed s,CONTROL_ERA__,,` + echo submitting example on demand script flex_ecmwf_$name + if [ ! -f flex_ecmwf_$name ] ; then + echo flex_ecmwf_$name does not exist + echo run update_script.ksh before running this script. + exit + fi + ecaccess-job-submit -queueName ecgb flex_ecmwf_$name +done + +echo submitting example operational script ecmwf_idc_ops_ecgate +ecaccess-job-submit -queueName ecgb ecmwf_idc_ops_ecgate + +else +# submit on ecgate + +for FILE in `ls CONTROL_ERA__*` ; do + + name=`echo $FILE | sed s,CONTROL_ERA__,,` + echo submitting example on demand script flex_ecmwf_$name + if [ ! -f flex_ecmwf_$name ] ; then + echo flex_ecmwf_$name does not exist + echo run update_script.ksh before running this script. + exit + fi + sbatch flex_ecmwf_$name +done + +echo submitting example operational script flex_ecmwf_$name +sbatch ecmwf_idc_ops_ecgate + +fi diff --git a/preprocessing/flex_extract_ecgate_V6.0/update_script.ksh b/preprocessing/flex_extract_ecgate_V6.0/update_script.ksh new file mode 100644 index 00000000..97fc3a2a --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/update_script.ksh @@ -0,0 +1,106 @@ +#!/bin/ksh + +if [[ $# -ne 4 && (-z "$GATEWAY" || -z "$DESTINATION" || -z "$ECUID" || -z "$ECGID" ) ]] ; then + + echo Syntax: update_script.ksh Gateway Destination EC_user_ID EC_group_ID + echo e.g. update_script.ksh srvx7.img.univie.ac.at leo@genericSftp lh0 spatlh00 + echo or set environment variables GATEWAY DESTINATION ECUID ECGID +exit +else + if [[ $# -eq 4 ]] ; then + export GATEWAY=$1 + export DESTINATION=$2 + export ECUID=$3 + export ECGID=$4 + fi +fi + +########### Just two examples ############### +# Please modify for your environment # +############################################## + +#[ -z "$GATEWAY" ] && GATEWAY=srvx7.img.univie.ac.at +#[ -z "$DESTINATION" ] && DESTINATION=leo@genericSftp +#[ -z "$ECUID" ] && ECUID=lh0 +#[ -z "$ECGID" ] && ECGID=spatlh00 + +#[ -z "$GATEWAY" ] && GATEWAY=ctbto4.ctbto.org +#[ -z "$DESTINATION" ] && DESTINATION=atmops@ops +#[ -z "$ECUID" ] && ECUID=cbb + +export VERSION=6 +export SUBVERSION=0 +echo 'ECMWFDATA V'${VERSION}.${SUBVERSION}' is installed for:' +echo Gateway $GATEWAY +echo Destination $DESTINATION +echo ECMWF user ID $ECUID +echo ECMWF group ID $ECGID +echo Output will be written into '$SCRATCH' directory of user $ECUID - /scratch/ms/$ECGID/$ECUID + +echo 'Note: These settings can be changed via environment variables' +echo '$GATEWAY $DESTINATION $ECUID $ECGID' + +cat flex_ecmwf_header_template | sed "s,xxx,${ECUID}," | sed "s,ggg,${ECGID}," >flex_ecmwf_header + +cat CONTROL_OPS_TEMPLATE | sed "s,xxx.xxx.xxx.xxx,${GATEWAY}," | sed "s,xxx@xxx,${DESTINATION}," | sed "s,xxx,${ECUID}," | sed "s,ggg,${ECGID}," | sed "s,v.v,${VERSION}.${SUBVERSION}," > CONTROL_OPS_V${VERSION}.${SUBVERSION} +cat CONTROL_OPS_TEMPLATE | sed "s,xxx.xxx.xxx.xxx,${GATEWAY}," | sed "s,xxx@xxx,${DESTINATION}," | sed "s,xxx,${ECUID}," | sed "s,ggg,${ECGID}," | sed "s,v.v,${VERSION}.${SUBVERSION}," | sed "s,M_TYPE AN FC FC FC FC FC FC FC FC FC FC FC AN FC FC FC FC FC FC FC FC FC FC FC 12,M_TYPE AN FC FC FC FC FC AN FC FC 4V FC FC 4V FC FC FC FC FC AN FC FC 4V FC FC 4V," | sed "s,M_TIME 00 00 00 00 00 00 00 00 00 00 00 00 12 12 12 12 12 12 12 12 12 12 12 12 12,M_TIME 00 00 00 00 00 00 06 00 00 09 00 00 09 12 12 12 12 12 18 12 12 21 12 12 21," | sed "s,M_STEP 00 01 02 03 04 05 06 07 08 09 10 11 00 01 02 03 04 05 06 07 08 09 10 11 12,M_STEP 00 01 02 03 04 05 00 07 08 00 10 11 03 01 02 03 04 05 00 07 08 00 10 11 03," | sed "s,DTIME 1,DTIME 3," | sed "s,M_ETA 1,M_ETA 0," | sed "s,M_GAUSS 0,M_GAUSS 1," | sed "s,M_SMOOTH 0,M_SMOOTH 179," > CONTROL_OPS_V${VERSION}.${SUBVERSION}_4V + +cat ecmwf_idc_ops_header_template | sed "s,xxx,${ECUID}," | sed "s,ggg,${ECGID}," | sed "s,v.v,${VERSION}.${SUBVERSION}," >ecmwf_idc_ops_header +cat ecmwf_idc_ops_header ecmwf_idc_ops_body >ecmwf_idc_ops_ecgate + +cat ecmwf_idc_ops_multi_header_template | sed "s,xxx,${ECUID}," | sed "s,ggg,${ECGID}," | sed "s,v.v,${VERSION}.${SUBVERSION}," >ecmwf_idc_ops_multi_header +cat ecmwf_idc_ops_multi_header ecmwf_idc_ops_body ecmwf_idc_ops_multi_footer >ecmwf_idc_ops_multi_ecgate + + +cat CONTROL_ERA_TEMPLATE | sed "s,xxx.xxx.xxx.xxx,${GATEWAY}," | sed "s,xxx@xxx,${DESTINATION}," | sed "s,PREFIX EN,PREFIX EG," | sed "s,v.v,${VERSION}.${SUBVERSION}," > CONTROL_ERA__GLOBALGAUSS +cat CONTROL_ERA__GLOBALGAUSS | sed "s,GAUSS 1,GAUSS 0," | sed "s,M_ETA 0,M_ETA 1," | sed "s,PREFIX EG,PREFIX EE," | sed "s,v.v,${VERSION}.${SUBVERSION}," > CONTROL_ERA__GLOBALETA +cat CONTROL_ERA__GLOBALETA | sed "s,M_GRID 1000,M_GRID 200," | sed "s,M_RESOL 159,M_RESOL 799," | sed "s,M_LEFT -179000,M_LEFT -10000," | sed "s,M_RIGHT 180000,M_RIGHT 30000," | sed "s,M_LOWER -90000,M_LOWER 30000," | sed "s,M_UPPER 90000,M_UPPER 60000," | sed "s,DTIME 3,DTIME 3," | sed "s,PREFIX EE,PREFIX EH," | sed "s,v.v,${VERSION}.${SUBVERSION}," > CONTROL_ERA__HIRES +cat CONTROL_ERA__GLOBALETA | sed "s,M_GRID 1000,M_GRID 200," | sed "s,M_RESOL 159,M_RESOL 799," | sed "s,M_LEFT -179000,M_LEFT 113000," | sed "s,M_RIGHT 180000,M_RIGHT 190000," | sed "s,M_LOWER -90000,M_LOWER 00000," | sed "s,M_UPPER 90000,M_UPPER 30000," | sed "s,DTIME 3,DTIME 3," | sed "s,PREFIX EE,PREFIX EH," | sed "s,v.v,${VERSION}.${SUBVERSION}," > CONTROL_ERA__HAIYAN +# ERA-Interim Template +cat CONTROL_ERA__GLOBALGAUSS | sed "s,CLASS OD,CLASS EI," | sed "s,PREFIX EG,PREFIX EI," | sed "s,M_LEVEL 137,M_LEVEL 60," | sed "s,M_LEVELIST 1\/TO\/137,M_LEVELIST 1\/TO\/60," | sed "s,201311,201211," | sed "s,v.v,${VERSION}.${SUBVERSION}," > CONTROL_ERA__EI +# ERA-Interim Template +cat CONTROL_ERA__GLOBALGAUSS | sed "s,M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC,M_TYPE CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV CV," | sed "s,M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12,M_TIME 00 00 00 00 00 00 00 00 00 00 00 00 12 12 12 12 12 12 12 12 12 12 12 12," | sed "s,M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11,M_STEP 00 01 02 03 04 05 06 07 08 09 10 11 00 01 02 03 04 05 06 07 08 09 10 11," | sed "s,STREAM OPER,STREAM ENFO," | sed "s,M_NUMBER OFF,M_NUMBER 1," | sed "s,M_LEVEL 137,M_LEVEL 62," | sed "s,M_LEVELIST 1\/TO\/137,M_LEVELIST 1\/TO\/62," > CONTROL_ERA__CV + +SERVER=`uname -n | cut -c 1-4` +if [[ ${SERVER} != ecgb ]] ; then +# submit via gateway from local server + +echo Software copied from server `uname -n | cut -c 1-4` to ecgate + +ksh upload_source V${VERSION}.${SUBVERSION} + +for FILE in `ls CONTROL_ERA__*` ; do + + name=`echo $FILE | sed s,CONTROL_ERA__,,` + cat flex_ecmwf_header $FILE flex_ecmwf_body >flex_ecmwf_$name + ecaccess-file-put flex_ecmwf_$name flex_extract_ecgate_V${VERSION}.${SUBVERSION}/flex_ecmwf_$name + +done + +ecaccess-file-put CONTROL_OPS_V${VERSION}.${SUBVERSION} flex_extract_ecgate_V${VERSION}.${SUBVERSION}/CONTROL_OPS_V${VERSION}.${SUBVERSION} +ecaccess-file-put ecmwf_idc_ops_ecgate flex_extract_ecgate_V${VERSION}.${SUBVERSION}/ecmwf_idc_ops_ecgate +ecaccess-file-put ecmwf_idc_ops_multi_ecgate flex_extract_ecgate_V${VERSION}.${SUBVERSION}/ecmwf_idc_ops_multi_ecgate +ecaccess-file-mkdir scratch:ms_sms_output_V${VERSION}.${SUBVERSION} + +else + +for FILE in `ls CONTROL_ERA__*` ; do + + name=`echo $FILE | sed s,CONTROL_ERA__,,` + cat flex_ecmwf_header $FILE flex_ecmwf_body >flex_ecmwf_$name +done + + +set +e +mkdir $SCRATCH/ms_sms_output_V${VERSION}.${SUBVERSION} +set -e + +fi + +echo ' ' +echo !! NOTE !! NOTE !! +echo ' ' +echo Scripts are now generated and uploaded but not yet submitted. +echo Run submit_examples.ksh to submit them to ecgate. +echo ' ' +echo !! NOTE !! NOTE !! diff --git a/preprocessing/flex_extract_ecgate_V6.0/upload_source b/preprocessing/flex_extract_ecgate_V6.0/upload_source new file mode 100644 index 00000000..84350b89 --- /dev/null +++ b/preprocessing/flex_extract_ecgate_V6.0/upload_source @@ -0,0 +1,8 @@ +#!/bin/ksh + +#$1 should be V4.1 or V6.0 or .. + +ecaccess-file-mkdir flex_extract_ecgate_$1 >/dev/null +ecaccess-file-put source.tar flex_extract_ecgate_$1/source.tar +ecaccess-file-dir "flex_extract_ecgate_$1/*" +ecaccess-file-mkdir scratch:ms_sms_output_$1 >/dev/null -- GitLab